Display mode implementation is 'broken'

DisplayMode implementation is ‘broken’. In version 0.3 of LWJGL it was possible for someone to create a DisplayMode structure and pass that to Display.create(); with the settings they wanted for their screen. In version 0.4 DisplayMode is private and you are stuck with the non-prduction mode loop which is actually kinda useless:


                  int mode = -1;
                  DisplayMode[] modes = Display.getAvailableDisplayModes();
                  for(int i = 0; i < modes.length; i ++)
                  {
                        if(modes[i].width == 800 && 
                           modes[i].height == 600 && 
                           modes[i].bpp >= 16)
                        {
                              mode = i;
                              break;
                        }       
                  } 


Why was DisplayMode’s constructor made private (I can’t see any syntactic or logical reason for this), or why isn’t there a more direct way to start the display? The above code fragment is really just a hard coded hack.

By making the DisplayMode constructor public, it will be possible to construct DisplayMode’s that are invalid. For that reason, we made the constructor private, and required you to get it from the supported displaymodes (getAvailableDisplayModes());

A user named marrcke posted an interesting suggestion in the sourceforge forums which has never received a (public, at least) response:

http://sourceforge.net/forum/forum.php?thread_id=800773&forum_id=196814

Matzon, you were active in the first part of this thread, but didn’t post your thoughts on his suggestions. It seems pretty clean to me :slight_smile:

must have missed that - odd I get notifications…
And now I don’t know where to reply :-/

I think that we could do such a thing… - will confer with the other devs…

Another dev pops up:

3000 objects is bugger all considering they’re about 100 bytes each and they get garbage collected 0.5 seconds later when you’ve discarded them all.

But one of the most typical newbie graphics programmer mistakes is

Oh no you don’t!
Oh no you don’t!
Oh no you don’t!

You can want a mode all you like but if it’s not on the system your code’s running on you can’t have it. Even something as trivial as making DisplayMode serializable and loading it back next session is fraught with pitfalls - what happens if the video card is changed between program invocations?

The only correct way to do this is to query the system for a list of available displaymodes, and use your own code to whittle away all the ones you aren’t interested in. Even that’s not 100% reliable although we might figure out a way to ensure all modes returned are guaranteed available. Elias has just put some code in which barfs on software modes in Win32 for example even though they’re valid display modes, because they’re effectively useless - although valid.

Ask yourself - why don’t you just allow the user to type in the width, height, bpp, depth, alpha, stencil and frequency?

Cas :slight_smile:

Its not a matter of knowing what display mode you want - its about knowing maybe 30 seconds before your program is launched that you have already gone through this process. Perhaps for those of you who are trying to do everything in game, that’s fine but most commercial applications these days have configuration programs outside the game to handle selecting display modes and the like and they DO serialize that to disk as I am doing now. The way this is currently being resolved is not ideal. There is absolutely nothing wrong with throwing an exception. What follows is the alternative that you would be stuck with using the current approach.

Your application launches expecting a mode to be available (in this case 800x600x16). If that mode is not available, your application crashes. In the case of the example code which I’ve seen floating about this can be partially solved by assuming that you would just start in mode = 1 and not mode = -1, but even that is not ideal.

[quote]Even that’s not 100% reliable although we might figure out a way to ensure all modes returned are guaranteed available.
[/quote]
Given that, passing in your own specified mode is no worse than selecting one from the list. Do you know what modes you should be presenting us with?

Oh no you don’t!
Oh no you don’t!
Oh no you don’t! :wink: :stuck_out_tongue:

Once the list of modes is guaranteed to be valid and the ONLY ones that are valid, then I’ll agree 100%. I have to say that I don’t mind having to select one at the moment, as I’m sure that eventually the list will be valid and the argument for not allowing the developer to create a mode will then be legit.

My only problem with it is that it’s a little clumsy. I still agree that you should pick a DisplayMode from a list, but the code to do so could probably be hidden behind a library method, no? ;D

What you need is a single method people can call which will allow them to pick the possible modes given a set of requirements/assumptions, and then for that set pick the best one that initialises. If they then want to specify 1024x768@32bpp/85Hz, that’s fine. Once they try it on a different computer and it fails, they’ll see the light.

As a matter of fact, we do - to a certain extent. On linux, I have implemented queries on glx versions that support that. So if your drivers are new/good enough the returned modes won’t be totally random. The same is very much possible on win32, but it just haven’t been implemented yet (/me prods the win32 coders)

Yep, I think that would be ideal. And I think cas might include the mode selection method from spgl. Maybe even in the next release of lwjgl.

  • elias

[quote]The same is very much possible on win32, but it just haven’t been implemented yet (/me prods the win32 coders)
[/quote]
That’s very much as I suspected! Methinks Cas has been busy recently… (how’s Mouse.getNumButtons() going? ;D)

[quote]Yep, I think that would be ideal. And I think cas might include the mode selection method from spgl. Maybe even in the next release of lwjgl.
[/quote]
Excellent! My opinion is that if you provide a simple system for selecting a mode that doesn’t require people to implement the check themselves and if it’s easier than “new DisplayMode(…)”, then most people will be happy.

The SPGL system is very good. It would nice to be able to specify a 4:3 screen ratio and a minimum width instead of a width and a height. I don’t need this personally, but I suspect some people might want it. On second thoughts, if you need something like that you can write it yourself!

Also, if anyone specifies a minimum refresh rate for their application, my laptop will refuse to run it - the LCD is detected as 0Hz… ;D

But hey, don’t think I’m complaining - this library is fantastic. Good job all around!

[quote](how’s Mouse.getNumButtons() going? )
[/quote]
Fine, I have added it - though only in CVS 8)

We will be releasing 0.5 soon…

Hm, this is actually quite an interesting discussion all round.
In other places I glean Wisdom from on the net there is a general feeling that a preconfiguration utility is clumsy and unprofessional and definitely off-putting to the end user. I’m inclined to agree; there’s no need for it if you code correctly. Even Jedi Knight resorted to an awful config utility.

This is surprising, because since the early days of 3D, Quake has managed just fine to do it in-game.

Imagine if Word required you to run a config utility before you could start writing documents. Can you see that getting past Microsoft quality control? No?

I will be looking at the win32 display mode selection soon to cut down the modes it tries to get. In particular we only bother trying to find out if GL is properly supported when it’s too late - we could easily do this at getAvailableDisplayModes time - I might have a go tonight but I’m working for The Man right now. Actually I’m not, I’m nerding away on the forum again :smiley:

There’s 1 more thing about this way of selecting display modes is that it absolutely forces you to do it right so it’ll run on as many systems as possible. Once you understand you don’t have full programmatic control of what display modes you can choose you’ll start to code appropriately for the fact - this ain’t no Amiga. A case in point is the 0Hz problem on laptops. It’s very easy to assume 60Hz is available on every system out there - it isn’t. My laptop runs at 52Hz. And so on.

More news later.

Cas :slight_smile:

[quote]A case in point is the 0Hz problem on laptops.
[/quote]
Not only on laptops. As mentioned in another post some weeks ago, i have the same problem on one of my machines running Win98 and a GF4MX440 using the 41.08 drivers. All i get is 0 Hertz, but that a dozen times.

You can either do it before the application starts or when the application starts. In either event unless you want the user to select the resolutions they want each time your application starts those preferences need to be stored somewhere so that the user doesn’t have to constantly have to deal with them each and every time the application starts. Preference management inside or out of the application isn’t really central to this debate so lets toss that for a moment. There will be many instances when you absolutely know what settings for DisplayMode you want because the user just told you. You’re not honestly suggesting that regardless of what the user says I should default my application to a specific displaymode everytime my application starts. I have coded around it at the moment and I have the mode loop spinning until it finds the resolution the user asked for.

i.e. you ignore what the user might want and force them to use what your code decides is the best resolution. I don’t agree with that because every game that has tried it has always gotten it wrong, especially when dealing with LCDs and refresh rates. I can’t count the number of applications I can’t run on my primary display because they’ve made that decision for me and left me with no way to change the configuration myself. If you want to default to a certain setting if all else fails (Display.getSafeDisplayMode() or similar), that’s fine but to assume that the application can decide something that the user cannot is just wrong and error prone.

Word uses the safety of the OS to know that it can draw stuff properly - OpenGL applications cannot rely on that knowledge and various pieces of hardware will have arcane capabilities that you shouldn’t set because they make the application slower. I used to hit this all the time with DirectX CAPBITS. Just because a driver tells you that it supports something doesn’t mean that you want to support it.

'snot true Greg, you’re missing what I’m saying.

By all means stash the user’s preference - but when it comes to loading the preference back again all you can do with it is use it to find the same displaymode in the list we give you, or a similar one. There is every possibility that this display mode no longer exists. This is why you can’t rely on users to choose one that works and insist upon it. You must choose from the list and you can never assume that a mode works. All you can be certain of is if the mode isn’t in the list, it’s definitely not supported; and if it is in the list, it still might not work and you might have to try a different one.

The reason we supply a list of modes is precisely so you can give the user a choice of modes that might work instead of presenting them with a list of modes that you think will work. It’s your job to filter out the modes that don’t interest you from what’s available. If you need 16 bit depth and 8 bit alpha you can throw away all modes with <16 bit depth and 0 bit alpha. When you present your list to the user, merely present the resolutions and colour depth; then pick the highest available combinations of alpha and depth from the list, in turn, until a mode works, or none work and you inform the user and remove that resolution from the list.

It’s quite complicated, but it’s foolproof, and foolproof is what we need. Especially cross-platform, where some of the complexity has come from.

We wouldn’t have this problem if there was a proper mechanism to get a true accurate list of screen modes guaranteed to work (ie. we didn’t throw Exception on setDisplayMode()). There’s WGL_ARB_pixel_format but it’s not yet widely supported on most drivers and it’s Win32 only. (So I can’t do much about that - sorry)

How many times have you seen the “Please try my game” thread somewhere on the net, followed by a bunch of “screen went black, then nothing happened” or “crashed my machine straight away” messages? Not knowing screenmodes is what causes it.

There is currently an unknown quirk in our screenmode code which will cause it to fail on dual-monitor systems. I’ll fix it soon.

Cas :slight_smile:

Why not code to support both paradigms? They don’t seem mutually exclusive.

Of course, and I’m not suggesting otherwise. What I’m saying is that the current methodology to getDisplayModes() and then loop through them until you find one that your application wants is just the incorrect behavior. I want to loop through all of the possible settings and then let the user choose what they want. Then I will store that and use that when the application starts again. If it doesn’t work, I should get an exception so that I can prompt the user for configuration information again - away from an OpenGL GUI where showing all of the possible settings that I would let the user configure is less than ideal.

When my framework starts it first checks to see if the user has specified any preferences for their display. If they have I want to use those. If I can’t get that, I wanted to get an exception - but since that’s not available and I keep going till I can’t find the mode they specified in their preferences I back out of GL and inform them of the error and display the configuration settings (which range from video through networking) because there are at that point no guarantees that I would even be able to get a mode where I could show a configurator on the screen that would actually be intelligible without a lot of GUI configuration layout managers and such.

The ideal solution would be:

Display.getDisplayMode( DisplayModePreferences )

If you can’t give me what I want don’t try to get something close, because there may be features that I expect in order for the application to work properly (and this is something I handle in the configuration utility). So unless this method has some way of prioritizing features (which from a code perspective becomes cumbersome given the alternative), its cleaner to just let the user - not the application - decide.