dkfans / keeperfx

Open source remake and Fan Expansion of Dungeon Keeper.
https://keeperfx.net/
GNU General Public License v2.0
776 stars 77 forks source link

Can't switch to 640x480x32 resolution #573

Closed mefistotelis closed 9 years ago

mefistotelis commented 9 years ago

Originally reported on Google Code with ID 573

In r1721 it is not possible to switch to the 640x480x32 screen resolution. I have the
default keeperfx.cfg (INGAME_RES=640x480x32 1024x768x32) but when I use Alt+R I switch
between 1024x768 and 1280x1024. In this resolution the game looks very pixelated, noticably
worse from 640x480.

Strangely enough, it does say this in the log file:
Sync: LbScreenSetup: Mode 640 x 480 setup succeeded
Sync: LbMouseChangeMoveRatio: New ratio 256x256

Reported by Loobinex on 2015-04-19 08:10:59

mefistotelis commented 9 years ago
what is your frontend resolution? can you paster your cfg in reply?

Game resolution and windows size does not always match each other, and when mismatch
happens, game graphic get stretched to fill the full window.
"Sync: LbScreenSetup: Mode 640 x 480 setup succeeded" means the game is painting on
a 640*480 canvas, but it is streched to a larger window so you find it ugly.

Reported by HeMeng86 on 2015-04-19 08:24:00

mefistotelis commented 9 years ago
Like I said, it is original. And no, I've always had 640x480, and I compared it to 0.4.5.
When I make a screenshot and paste the result it is 1280x1024.

; Path to the DK files. Usually leaving it as "./" will work.
INSTALL_PATH=./
; How many of the game files are on disk; irrelevant option.
INSTALL_TYPE=MAX
; Language definition; sets options for displaying texts.
LANGUAGE=ENG
; Keyboard definition; irrelevant.
KEYBOARD=101
; File format in which screenshots are written; BMP or HSI.
SCREENSHOT=BMP
; Three frontend resolutions: failsafe, movies and menu resolution.
FRONTEND_RES=640x480x32 640x480x32 640x480x32
; Original DK resolutions were FRONTEND_RES=320x200x8 320x200x8 640x480x8
; List of in-game resolutions. ALT+R will switch between them.
INGAME_RES=640x480x32 1024x768x32
;Original DK resolutions were INGAME_RES=320x200x8 640x400x8
; Mouse pointer movement speed; 100 percent means normal OS speed
POINTER_SENSITIVITY=100
; Censorship - originally was ON only if language is german.
CENSORSHIP = OFF

Reported by Loobinex on 2015-04-19 10:43:53

mefistotelis commented 9 years ago
I tested with your cfg and everything seems working correctly. you can change all the
x32 to w32 to confirm.

you get a screenshot of 1280*1024 because that is the resolution of your monitor. In
SDL2, various resolutions is not achieved by actually chaning the physical resolution
of your monitor, but by simulating(stretching) low resolution with the power of your
GPU(You may notice this by no longer seeing 'changing resolution' message while entering
the game, and your background windows layout is not messed up anymore), so getting
a 1280*1024 screenshot is expected result. 

Reported by HeMeng86 on 2015-04-19 13:18:53

mefistotelis commented 9 years ago
Ok, I'll focus on my key concern: The game now looks a whole lot worse in 640x480 resolution.
And I used that resolution because that looked the best. In 0.4.6 it is a lot more
pixelated, in 0.4.5 it was smoothed out.

I've attached two comparison pictures to show the difference, zoomed in to make it
easy to see the difference.

Reported by Loobinex on 2015-04-19 14:09:47


mefistotelis commented 9 years ago
If I get this correct, your screenshot in 0.45 should be 640*480 and screenshot in latest
build should be 1280*1024? Why they look the same size?

Reported by HeMeng86 on 2015-04-19 14:51:16

mefistotelis commented 9 years ago
your first picture is scaled using 'nearest pixel sampling' algorithm,
your second picture is scaled using 'linear filtering' algorthm.
you can google them respectly to understand the difference. 
Generally second one is considered better.

We fixed a 'heap overflow while switching resolution' bug yesterday which was caused
by SDL2.0 library when using GPU accerleration, so I turned off this option to avoid
the crash. Unforunately this make us unable to use linear filtering option of scaling.

For now, I can turn on GPU accerleration anyway and leave the crash fix later because
the crash only happens in rare case that user alt+r for many times; or you can try
play in higher resolution like 1280*1024?

To solve this compeletely, I will need to find newer verion of SDL, or report bug to
SDL developer directly.

Reported by HeMeng86 on 2015-04-19 15:07:42

mefistotelis commented 9 years ago
in short term, it is a tradeoff of graphic quality and stability. Actually I prefer
former one.

Reported by HeMeng86 on 2015-04-19 15:14:34

mefistotelis commented 9 years ago
Playing in high resolutions doesn't solve anything, as that scales the game using nearest
pixel sampling as well, which really doesn't look too hot. Issue #431 is in progress
but a long way away to make playing in high resolution worthwhile.

For me I’d much prefer having better scaling over fixing the heap overflow(issue #565)
–perhaps mefisto feels otherwise – as the crash is almost self-inflicted and the game
looks a lot worse now. 
If a proper fix to the crash cannot be found(quickly) I suggest a tradeoff in switching
resolutions.

I think the main reason why people would switch resolutions a lot is because they have
difficulty telling the difference. If you quickly display the new resolution after
the switch and limit the amount of times people may switch to for example 6 times you
perhaps have a workable alternative.

Reported by Loobinex on 2015-04-19 17:12:45

mefistotelis commented 9 years ago
KeeperFX on its side (so not taking SDL into account) can only use nearest neighbour
to scale sprites. And I'm not planning to change it, that would damage the structure
of the engine. Adding bigger sprites will give better results.

Still, in 640x480 there should be no scaling whatsoever - in that resolution most sprites
are not scaled at all, just displayed 1:1. There should be no pixel doubling nor blur
visible.

If you see anything like this, this is most likely processing done by your monitor.
Try finding an info screen in the monitors OSD - it will tell you which resolution
you are really in.

Reported by mefistotelis on 2015-04-19 20:47:33

mefistotelis commented 9 years ago
I'll leave the discussion on the why and how to you, but in all builds before r1721
the game looked fine in 640x480 and worse in higher resolutions.
In r1721 the game looks a lot worse in 640x480. You can take a look at the attached
images above, my monitor can't process images on your pc.

The info screen on my monitor displays 640x480 in 0.4.5, 1024x768 when I press Alt+R.
In r1721 it will always display 1280x1024.

Reported by Loobinex on 2015-04-19 22:44:01

mefistotelis commented 9 years ago
HeMeng86, is it possible to force SDL2 to always show KeeperFX graphics canvas 1:1,
without any sort of scaling?

I think it would be best to disable this feature completely.

Reported by mefistotelis on 2015-04-19 23:01:19

mefistotelis commented 9 years ago
quote
"Still, in 640x480 there should be no scaling whatsoever - in that resolution most
sprites are not scaled at all, just displayed 1:1. There should be no pixel doubling
nor blur visible.
If you see anything like this, this is most likely processing done by your monitor.
Try finding an info screen in the monitors OSD - it will tell you which resolution
you are really in." <- this is no longer true in SDL2.

I need to separate the 2 steps of rendering to explain this, scaling is happening in
both steps:

Step 1:
The core of KeeperFX has always supposed it is painting on a canvas of given size(the
resolution we set in cfg), then the painted graphic to SDL and tell it to show it fullscreened,
without caring about how it is done.

Step 2:
SDL get the graphic and show it fullscreened somehow.

Step 1 didn't change in recent changes, if you set a resolution different than 640*480,
scaling will happen using nearest neighbour method. This is the manual scaling that
you implemented and not plan to change. If you set 640X480, "there should be no scaling
whatsoever"--in step 1.

Step 2 is done in different way in SDL1 and SDL2. In SDL1, you monitor resolution is
actually changed to align with the canvas size, so no additional scaling happens. In
SDL2, a second scaling is applyed to the canvas to stretch it to full screen of current
monitor resolution. This second scaling is what I was talking about: handled by GPU
and can use linear filter(or not) to blur the pixels.

For example: you have set 1024*768 in cfg and play on a 1920*1080 monitor, game graphics
will be scaled twice, first time, by game itself, to 1024*768 with nearest neighbour,
and second time, by SDL, to 1920*1080, with nearest neighbour or linear filtering(smoothed.)

In our case mentioned above, linear filtering is not available so we get 2 nearest
neighbour scaling, this by nature will get worse result than 1 big nearest neighbour
scale.

To answer your question, SDL2 doesn't support changing actual resolution of monitor,
as long as 
1. you want to get a resolution different from monitor resolution
2.actual resolution of your monitor is not changed 
Some kind of scaling in step 2 must be done to get full screen graphics. 

if you your actual resulotion in cfg file, at least you can get clear render of 3D
part and UI will be scaled only once, which is slightly better than 2 times in a row.

OFF TOPIC: can you take a look at my question in issue # 570 ?

Reported by HeMeng86 on 2015-04-20 03:53:35

mefistotelis commented 9 years ago
If it is as you're saying, then I'm having serious doubts if moving to SDL2 was a good
idea.

I can't imagine a game having no option to set screen resolution.
What would you think of a game, in which you can set any resolution you want - but
it doesn't really change resolution, just does different blitting?

What I can see from the current implementation doesn't look promising:
- no 1:1 displaying of full screen resolution
- issues with switching resolution in windowed mode (sometimes no window size change,
sometimes a crash)
- unacceptable weight of the library (KeeperFX with all the sprites and rendering takes
less than 30MB, while SDL2 takes over 70MB just to copy a pre-rendered picture into
window)
- flashes of a white-filled canvas between screens

At least the issues with mouse seem to be resolved now.

Maybe if we'd get a custom compiled, lightened, fixed and improved version of the library,
then this could work. Otherwise, this library seem to be a total fail with design flaws.
SDL1 footprint was ~20MB, so it's more that 3x increase with no gain (at least for
our use case).

The only thing that is baffling me is why I can't see many negative opinions about
it on the net...

btw., the SDL1 library used previously in KeeperFX, was a custom-compiled, lightened
version (some config flags were disabled to default config).

Reported by mefistotelis on 2015-04-20 10:58:20

mefistotelis commented 9 years ago
I agree with the stability part(although I think it is fixable) and weight part, I don't
get the flash part yet, and I don't agree about the graphic part. SDL2 enables possibility
of getting better graphic(linear filter and anisotropic filtering, GPU accerlerated)
while retained the possibility of getting exactly the same graphic as SDL1.

When we talk about 'good graphic', I think we 3 all mean different things:

Loobinex thinks smoother (with anti-aliasing) is better, this effect can only be done
in SDL2 with linear filtering, as you said, older KeeperFX does only does nearest neighbour
scaling.

Mefisto thinks sharp and archaic feeling(without anti-aliasing) is better, we can get
this effect in both SDL1 and 2. If you  set game resolution to 640*480, nearest neighbour
scaling will only be done once(in step 2) and you will get EXACTLY the same result
as SDL1.

I think, while getting same final result, resizable window, GPU acceleration and optional
antialiasing  is cool. The only minor concern is if two nearest neighbour is done in
a row, entrophy may increase and details may deform slightly. But this can be avoided
by using 640*480 resolution or monitor resolution. As long as scaling happens only
once, you will get exactly the same graphic as SDL1. Or if you enable anti-aliasing,
nothing can be noticeable worse.

SDL2 does not change actual resolution of monitor but simulate it, I take this as an
advantage because it is smoother and does not mess up your background windows layout.

One other important reason I upgraded to SDL2 is that it has better mouse support.
With SDL1 I cannot implement wheel feature.

Switching to new engine will always come with initial cost. But it does bring benefit
in long term. The only real problem currently is the memory leak which I think is solvable.
As soon as we can enable GPU again, anti-aliasing option will be back. If you are not
in a hurry of releasing something, let us give it some more time.

Reported by HeMeng86 on 2015-04-20 13:14:58

mefistotelis commented 9 years ago
I just checked in a workaround for this issue: avoided using the memory leak method
so we get linear filter with no crash problem anymore. The workaround is ugly from
persepective of engineering, but it works perfectly.

Reverting SDL is not cheap either at this point, and if you still plan to make KeeperFX
cross platform, you will need newer SDL eventually. Let's use this workaround for now
and fix SDL or make it smaller later when we have nothing more shiny to do.

Reported by HeMeng86 on 2015-04-20 14:28:45

mefistotelis commented 9 years ago
Is there a better place to discuss more generalized ideas like publishing cycle, what
everyone is planning to do, howtos ,or new feature concept?

BTW I still need infomation about issue #570: 

Reported by HeMeng86 on 2015-04-20 14:44:53

mefistotelis commented 9 years ago
How come for you the memory footprinth only doubled? For me it went from 36MB in 0.4.5
to 1080MB now. I have enough memory to spare so it doesn't really bother me, but still,....

Furthermore, I do not think blurred is by defenition better, but this is the case for
KeeperFX since the images are distorted by the game somehow in high resolution. They
need blurring to be somewhat tolerable.
To see what I mean look at an enlarged screenshot of the creature tab attached, and
the image file that is used for it. Notice the base image looks fine even low res,
but ingame at high resolution it is no longer 'straight'

Reported by Loobinex on 2015-04-20 17:03:18


mefistotelis commented 9 years ago
Footprint - wow, I also get over 1GB mem taken now.. either older revision was better,
or I misread the value.

Additional blur is a bad way of covering artifacts related to scaling. But - these
artifacts can't be eliminated unless the resolution will be exactly x2, x3, x4 etc.
of the original 640x400.

Note that the higher the resolution, the less visible these artifacts are - so you'll
get better picture using your monitors native resolution in KeeperFX, than by using
smaller one and forcing to scale two times. Try that, I'm pretty sure in 1600x1024
or more you won't even see that some lines are copied one more time due to fractional
part of scale factor.

Either way, blitting is not a way to change resolution. This is unacceptable.
I want SDL to be used only for displaying the screen 1:1 and anything beyond that collides
with my work on scaling within the game engine.

Finally, I looked at the SDL2 API, and FULLSCREEN_DESKTOP is just a one way of displaying.
The correct way is still there.

I think FULLSCREEN_DESKTOP could be an interesting addition to the game, but just as
option, not replacement of the real screen control.

Reported by mefistotelis on 2015-04-20 23:01:33

mefistotelis commented 9 years ago
- The 1GB memory has been like this since the first nightly after the 0.4.6 release.

- In 0.4.5 the game looked fine in 640x480 resolution. Higher resolutions made it look
worse. More pixelated and more artifacts.

- My monitors native (and maximum) resolution is 1280x1024. In both 0.4.5 and 0.4.6
configuring KeeperFX to this resolution made the game look worse.

- I've just tried 1280x960x32 and 1280x800x32, both still show the artifacts.

Reported by Loobinex on 2015-04-20 23:38:29

mefistotelis commented 9 years ago
yes, I confirmed SDL_WINDOW_FULLSCREEN can change actual resolution of monitor(SDL_WINDOW_FULLSCREEN_DESKTOP
was what I used), whether the graphic is better or worse is quite subjective though.
I can change the parameter within seconds If both of you think SDL1 graphic was better.
 I will do that by default this night.

1GB memory for DK1 is ridiculous, what was the memory consume before you make custom
build of SDL1? maybe we can do similar thing for SDL2. But this is not urgent.

Another unurgent discussion: about the scalling result in #17, actually I think it
can be improved without changing the thing that you don't want to change. Judging from
the final result, I think you are doing the nearest neighborhood scaling in some recursive(multiple
step) way? As you said, unless the multipiler is exactly x2, x3, x4... artifacts will
appear. And if we do the scaling in multiple steps(like x1.5 then 2.1x then etc) artifacts
in previous step will be amplified and accumulated. On the other hand, if we can do
the amplifying in one step, the artifacts should be kept minimal and average distributed.

Reported by HeMeng86 on 2015-04-21 04:22:37

mefistotelis commented 9 years ago
In r1724 the game now looks fine again in 640x480. The same as it did in 0.4.5 and r1716.

Reported by Loobinex on 2015-04-21 07:48:32

mefistotelis commented 9 years ago
Footprint:
I was sure the build options which reduced memory usage were commited into repository
with the rest of SDL1, but I can't seem to find them.
Looks like I was doing that build on some Linux machine - I don't have it locally.

What I used there was just a specific set of parameters to "configure" and/or "make"
scripts, so it shouldn't be hard to check the effect of each parameter in new SDL even
without having the old config.

Reported by mefistotelis on 2015-04-21 14:26:15

mefistotelis commented 9 years ago
I just checked in the change of parameter which makes the game actually change monitor
resolution(so we don't do second scaling). 

Actually I think the graphic gets worse. If you 2 feel the same way, I can easily get
this reverted.

Reported by HeMeng86 on 2015-04-21 14:50:19

mefistotelis commented 9 years ago
I cannot tell the difference in graphics between r1724 and r1726 in 640x480. I have
to make screenshots and go back and forth to see a very minor difference that could
just as well be explained by having to make the new screenshot larger for comparison.

However, in higher resolutions the game indeed looks worse in r1726. Too such an extent
that for example it makes it hard to read the number of creatures in the creature panel.

Reported by Loobinex on 2015-04-22 10:13:35

mefistotelis commented 9 years ago
Keepd3d still looks best by the way, but even keeper95.exe still looks better than keeperFX.
KeeperFX for example still has the artifacts in 640x480, but K95 looks flawless.

Reported by Loobinex on 2015-04-22 11:45:11

mefistotelis commented 9 years ago
I will try world's most fancy resizing algorithm after more urgent issue is addressed(and
I get a job)
http://en.wikipedia.org/wiki/Lanczos_algorithm
http://dsp.stackexchange.com/questions/707/what-are-the-practically-relevant-differences-between-various-image-resampling-m

For now, we can close this issue if graphic is not worse than before, I will make the
different parameter in r1724 and r1726 optional in config.

Reported by HeMeng86 on 2015-04-23 02:41:48

mefistotelis commented 9 years ago
Sure, it looks no worse than before.

Reported by Loobinex on 2015-04-23 07:16:43