Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Dragonskin

Multi-threading Question

This topic is 6115 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ok, I''ve searched around this forum (and a few others) and gone through the tutorials I''ve found on the net. I haven''t quite found what I''m looking for, though. I''m doing a test with multi-threading (so no "don''t use multi-threading" messages, please...I can''t believe HOW many I''ve read tonight already) to separate the message pump and the "game" loop. I read the tutorial here on Gamedev on how to do it, but it doesn''t seem to work with my implementation. I''m hoping someone here can either tell me what I''m doing wrong or confirm my suspicions. I start off by creating a thread that runs my RunGame function and then exits. The RunGame function just does a loop where it does stuff until the ESC key is pressed. The OpenGL window is created in that second thread (if I create it in the main thread, I can''t render to it). It will loop through and render properly, but it''s happily going along while ignoring any windows messages that come to it. This problem goes away if I put the message processing routines (PeekMessage, etc.) into RunGame''s loop. That isn''t what I''m going for. I''ve tried using the OpenGL window''s hWnd as a parameter for the main thread''s GetMessage or PeekMessage (tried both, only difference seems to be rendering performance). It still doesn''t get the messages, so I''m thinking messages can''t be gotten across threads (even with the proper window handle). After reading a lot (that search is HANDY!) of posts about message pumps and multi-threading, I''ve noticed some posts from people who are able to separate the message pump out and have it work. Anyone know what I might be missing? Or, if I can''t get messages from windows in other threads, anyone have a workaround that might work? Thanks in advance!

Share this post


Link to post
Share on other sites
Advertisement
The first thread should create the window and start the pump (it''s a good idea to have the thread that creates a window, pump it, and have that thread be the first one).
In one of the first message handlers (after WM_CREATE), create the second thread. You want to make sure the window is alive and valid before handing it off to the GL renderer.

Make a simple window app first, make sure it works, then add the second thread. In the first thread you can now hang in the message pump using GetMessage (this will keep that thread idle until it has work to do as well).

GL may need to be told it''s being used in a MT app in the initialization functions.
Render to the window in the second thread - this needs to work this way.

You have mild syncronization issues for window resizing, moving, and GL blitting. You can worry about those later, it shouldn''t crash, but it might ''bleed'' over the window''s border.

Also put a small sleep in the render thread, Sleep(0) or Sleep(1) is good. You might be starving the message pump thread... you can also try increasing the priority of the pump thread and decreasing the priority of the render thread.

Magmai Kai Holmlor

"Oh, like you''ve never written buggy code" - Lee

"What I see is a system that _could do anything - but currently does nothing !" - Anonymous CEO

Share this post


Link to post
Share on other sites
Like Magmai said, wait till you catch your WM_CREATE message then, create your thread.

Althought there afew other solutions also, am assumin you want to run OGL in its own thread and when windows executes a certain message you want to check for it and take appropriate action?

If you know C++ well enough you can use whats called a listener patern and have ogl listen for certain events and take action from there... It not that important to have high performance on catching windows events, more important catching input events, playing sound and plastering billions and billions of polygons on screen

Share this post


Link to post
Share on other sites
Also, you can create your rendering context on the main thread, but in order to render to the window from the worker/rendering thread, you must call wglMakeCurrent() with the render context associated with the window you created.

If you weren''t calling wglMakeCurrent() from the second thread, then that''s why when the window is created on the first thread, you can''t render to it.


-Brannon

Share this post


Link to post
Share on other sites
Thanks for the responses. I''m working on implementing some changes now.

This was a simple, working app before I started playing around with it.

I''ll get back to you all with the results of my typing.

Share this post


Link to post
Share on other sites
Ok, now THAT part''s running. I can''t get GetMessage to work yet, though. I''m still using PeekMessage because GetMessage won''t let my loop finish to get to where I''m checking to see if the thread is done. I''ve tried moving the checking code, but it doesn''t make a difference. Any ideas on how to get around that?

The only other problem I have is that going from fullscreen to windowed and back isn''t going to be nearly as easy. I''ll work on a way of synchronizing that sometime tomorrow night.

Thanks all!!

Share this post


Link to post
Share on other sites
I''ve got two threads, one for the window, one for OpenGL rendering as well. I plan on adding a third and fourth threads for user input and background loading of expected resources (models, maps, etc...) No problems except for resizing the window, but that''s not very crucial and I should have it fixed soon.

At first I had problems exiting the program. What I did was a made a global boolean g_Exit, and when g_Exit is true, it exits both threads. What I found VERY strange is that even though I created the window in the main thread, I had to destroy it in the rendering thread.

Currently I''m calling CreateThread directly after I make the window, I might need to change where I''m calling it from. All options in CreateThread are set to 0 except for the mandatory ones.

Share this post


Link to post
Share on other sites
Well I''ve got the threads working very well now, I just need to figure out the SuspendThread and ResumeThread functions... I can sure suspend the thread properly, but then I can''t get it back. Anyone ever get those two functions working properly?

Share this post


Link to post
Share on other sites
Well, I''m thinking my problem has something to do with the close message getting sent to the wrong thread (I''ll try PostThreadMessage when I get home). I use a variable to tell me when the thread is done, which worked in an earlier test that I tried.

As for destroying the window in the second thread, I tried it but it wouldn''t unregister the class. I tried destroying it in the main thread and it destroyed it without any problems.

I''m at work for another hour so I won''t be able to try anything until then, though. I''m hoping that''s all it is.

Share this post


Link to post
Share on other sites
Ok this is good, my code works perfectly now. It suspends and resumes the rendering thread exactly the way I want it to, shutdowns just fine and everything.

Just to make sure it was all perfect, I searched in the docs for threads, and found the ExitThread() function. Do I actually have to call this function to properly shutdown my program? Currently it just calls CloseHandle() on the thread with no problems, and when I call ExitThread() and I close the program, it is still running in the background without a window! (I have to close it with task manager). The docs aren''t very clear on how to manage threads, it just says that ExitThread() "exits the thread" =/.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!