Need help with OpenGL rendering thread, C++ and win32 API

Started by
23 comments, last by 0beron 19 years, 3 months ago
Multi-threading is always tricky to debug. Having both threads yield is a good first step. Are you using windows xp by any chance?

From MSDN on GetMessage():


Windows XP: If a top-level window stops responding to messages for more than several seconds, the system considers the window to be hung and replaces it with a ghost window that has the same z-order, location, size, and visual attributes. This allows the user to move it, resize it, or even close the application. However, these are the only actions available because the application is actually hung. When in the debugger mode, the system does not generate a ghost window.


If both the rendering thread and the message thread are hanging you might be getting into a deadlock situation somehow. Look for any dependencies between the threads.

You might also want to make sure that the message loop isn't doing anything to affect the client area of the window. Make sure the window is created with a NULL background brush and you don't do anything in response to WM_PAINT.

Personally I'm not really sure that having the window message handeling code in a seperate thread from the rendering code is all that useful. The main advantage is that you can prevent the window from hanging if your rendering loop takes too long, however if you hit the message queue every frame or so your game would be at unplayable frame rates long before you got in trouble with windows for missing messages. The main place I would see this being an issue is when doing resource loading. When I do a level load I'm careful to hit the message loop fairly often (this is a good time to update the progress bar too).
Advertisement
well, to me it makes sense, as it completely removes your windowing system from the scope of the game, with only a couple of functions needed to perform actions such as pausing/resuming and quiting, which means your game and its logic is free to carry on as it wants, free from any platform dependancies, like ye olde dos games [grin]
and from a cross platform stand point, once you've got the little... quirks.. removed your code is nicely parceled away and safe from any windowing changes [grin]
Yes - I run XP

Ok - after a bit more fiddling, it is definitely a starvation problem. Putting one OutputDebugStr() in the top of the message loop, and another in the render routine shows that the render routine is the only one getting run.

I'm only explicitly creating one thread at the moment - the one to do rendering. Does the message loop need a thread to run in or does the OS provide one?
When you run a program it techinically IS a thread, so when you create the 2nd thread to render you'll have the first one (main one) which handles the message pump and the 2nd one handles the drawing.

You need to make the render routine yeild so that the message pump gets a chance to run, as I said, sleep(0) or sleep(1) should do it, if it doesnt you'll have to see how to make it yeild via the system you are using.
Here's an interesting sample from Microsoft. Of course, it doesn't help that much on Linux, OSX, etc. :-) I've got multiple rendering threads in my new engine, up and running on Windows and Linux+X11, and using SDL to create the windows no less, but I tell you, if I never have to code against the X11 API again it'll be too soon. Anyway, it can be done pretty easily on Windows, as that sample demonstrates. The only problem is all the normal synchronization issues that come with multithreaded programs.
-bodisiw
ah, thats infact very helpfull and should save me some time multithread-safeing my window framework
Aha - I've got somewhere. I switched back to using Peek Message, and put a timer on the render routine to cap the frame rate. Now the threads interleave with one another - I can see that from the Output window in Vis studio.
Windows no longer complains that the application is not responding, but you can't move the window or use its menus. If the window is covered by another and then uncovered, the window frame never redraws itself. Is there another windows message that I need to handle or something?
not as far as I know, my own window framework only handles 3 msgs (the create and the two that go with destory) and while its only single threaded it works perfectly.

I've recently rigged it for multithread however, so I'm going to test that probably later today and see what issues I run into.
hi!
check this:
http://www.gamedev.net/community/forums/topic.asp?topic_id=290848
what gpu and driver versions are you using?
OK, I've just knocked up a quick multithread OpenGL Program via my window framework anmd using boost::thread for my threading work, and it works perfectly [grin], I'm not doing any special handling of messages, infact I'm only dealing with a create message and the message which are needed to destory it, everything is passing to the default handler.

Its two loops, one infinite which does the drawing (with a yeild at the end) and another which works the message pump via Peekmessage, also with a yeild in it.

For the reference of heeen, this is on an ATI 9800xt using the Cat4.12 drivers and this code was totally untested in a multithread enviroment before now [grin]

This topic is closed to new replies.

Advertisement