We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 162

Summary: Can't create a dialog box with OpenGL active
Product: SDL Reporter: Sam Lantinga <slouken>
Component: videoAssignee: Ryan C. Gordon <icculus>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2    
Version: HG 1.2   
Hardware: x86   
OS: Windows (All)   
Attachments: Test case
fixes for Windows based backends

Description Sam Lantinga 2006-03-13 19:15:32 UTC
Date: Mon, 13 Mar 2006 15:31:51 +0000
From: John Popplewell <john@johnnypops.demon.co.uk>
Subject: Re: [SDL] Dialog boxes.

Hi,

I've had a look at it and it is caused by the creation of a temporary
window in Init_WGL_ARB_extensions() in SDL_wingl.c which injects some
messages into the application message queue.

I tried a few things, like changing:

  hwnd = CreateWindow(SDL_Appname, SDL_Appname, WS_POPUP|WS_DISABLED, ...

into:

  hwnd = CreateWindow("STATIC", NULL, WS_POPUP|WS_DISABLED, ...

but I'm not confident that a static text control window will always be
happy having an OpenGL context attached to it :o) so I also tried a call
to FlushMessageQueue() after the DestroyWindow() call at the end of
Init_WGL_ARB_extensions().

They both worked, but I finally settled on using the existing device
context, GL_hdc, and just removing the window and dc creation /
destruction functionsr: see the attached patch.

Is there any good reason NOT to just use this existing DC?

I've attached a test program that reproduces the problem and allowed me
to determine that it happens with both windib and directx drivers and
doesn't happen unless OpenGL is enabled.

A quick comment/compile/test binary search through the source led me to
Init_WGL_ARB_extensions(),

cheers,
John Popplewell.
Comment 1 Sam Lantinga 2006-03-13 19:17:09 UTC
Created attachment 78 [details]
Test case
Comment 2 Sam Lantinga 2006-03-13 19:18:41 UTC
(In reply to comment #0)
> FlushMessageQueue() after the DestroyWindow() call at the end of
> Init_WGL_ARB_extensions().

This is probably the best approach.

> Is there any good reason NOT to just use this existing DC?

Yes, once you've set an OpenGL context on the window in some drivers, you can't re-set different basic attributes of the context.
Comment 3 John Popplewell 2006-03-13 20:34:11 UTC
(In reply to comment #2)
>
> > Is there any good reason NOT to just use this existing DC?
> 
> Yes, once you've set an OpenGL context on the window in some drivers, you can't
> re-set different basic attributes of the context.
> 

OK, I didn't know that - thanks.
Comment 4 Peter Mulholland 2006-03-13 21:37:26 UTC
I have traced this sample code on MSVC and found out the cause of the issue.

I noticed, that the SDL window was not being displayed until MessageBox() had been called. What this means is, although SDL called CreateWindow() to open the main app window, it doesn't actually do it until something runs the message loop. In this case, it happens to be the message loop inside MessageBox(), which is task modal and therefore runs its own message loop. This obviously dislikes having to handle SDL's message stuff, and fails.

Modify the sample so that it calls SDL_PumpEvents() after SDL_SetVideoMode(). Then the second assert appears just fine.

The fix is that every time SDL calls functions to do with window opening/closing or any function that will result in window messages being generated, it needs to run the message loop to actually make them happen. In the SDL_dx5video.c code, there is a FlushMessageQueue() function which does just that. It's being called when the window is destroyed but not when it's been created. Similar patches will be needed in the windib driver.

I will try and add these but please bear with me - I don't really know how to use CVS and diff as I'm 90% a Windows guy who doesn't touch these tools.
Comment 5 Peter Mulholland 2006-03-13 22:32:05 UTC
Created attachment 79 [details]
fixes for Windows based backends

Some patches that should fix the issues
Comment 6 Sam Lantinga 2006-03-14 01:18:34 UTC
Your fix (slightly tweaked) is in CVS, thanks!
Comment 7 John Popplewell 2006-03-14 05:18:50 UTC
(In reply to comment #6)
> Your fix (slightly tweaked) is in CVS, thanks!
> 

I've just tested CVS on my set of machines - works great!

My evil FlushMessageQueue() function will one day rule the earth! Ha-Ha!
Comment 8 Peter Mulholland 2006-03-14 08:04:57 UTC
There was already FlushMessageQueue() in the SDL drivers. It was being called when a window was destroyed, presumably someone found that if you don't do a message queue pump, it doesnt close the window and Bad Things Happen.

The same applies when you open a window or change its settings, these all cause window messages to be issued and *none* of them will execute until the message loop runs. So therefore, the message loop needs to be pumped after extensive window wrangling has taken place when initing/changing video mode