Jump to content
  • Advertisement
Sign in to follow this  
0beron

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

This topic is 5071 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

I've had some success starting out with OpenGL using the basic code in NeHe's tutorials. ( http://nehe.gamedev.net/ ) This all works fine when rendering frame by frame, but I've now got to the stage where I would like to have two threads running, one to render, and the other to perform some real time analysis of data from a MIDI keyboard. My first attempt uses the _beginthread() function to start off a thread, the thread function contains an infinite loop with a call to the DrawGLScene() method which was working fine in the single thread case. All this does is put a blank window on the screen, and put my processor use to 100%. I didn't think it would be that simple heh. Is my rendering thread blocking other threads in the OS from actually updating the screen? How would I go about solving this issue? (I can tell the thread is actually working - if I put a OutputDebugStr() in the loop, I see it over and over in the output window in VisStudio) I am a beginner with C++, although I am very familiar with Java and OO in general. I am a beginner with the windows API also. I'm also trying to avoid using the MFC. Once this problem is solved there will be no more windows code to write, the rest will be analysis and openGL.

Share this post


Link to post
Share on other sites
Advertisement
Your problem probably comes from not having the opengl context active in the right thread.

I'm assuming you create your window and context at start up and then spawn a different thread to draw to it? This aint gonna work. Instead you need to release it from the orignal context (i forget how I admit, but its an important step, look at some window destruction code to get an idea of how) and then set it as current in the thread you want todo the drawing.

And having your threads yeild when they are done processing is a good idea [smile]

Share this post


Link to post
Share on other sites
Thanks - I'm rather clueless, I'm used to the soft fuzzy world of JAVA where you create a thread and it goes....

Is it possible to set up the rendering context when the thread gets created instead of doing it when creating the window? There's only ever going to be one rendering thread.

How do I set a context as current in a thread?

Share this post


Link to post
Share on other sites
Don't try to move contexts between threads, you'll run into all sorts of problems, at least when your app is running on windows. You should do all your opengl stuff in a single thread, however it sounds like that is what you want anyway.

Creating a rendering context is a seperate operation from creating a window, however whatever library you are using to set up your context may do both at the same time. Using the wgl commands in windows you would do something like:

hwnd = CreateWindow(...)
hdc = GetDC(hwnd)
format = ChoosePixelFormat(hdc, ...)
SetPixelFormat(hdc, format, ...)
hglrc = wglCreateContext(hdc)
wglMakeCurrent(hdc, hglrc)

That's how you do it in C/C++ using windows platform sdk to create the window and wgl to set up the context. I haven't done ogl with java before but I'm sure all that is happening under the hood somewhere, at least on a windows implementation. The problem is that java may do all that for you in one step so you can't jump in the middle with your seperate thread. You'll need to dig into the docs a bit and find out.

Share this post


Link to post
Share on other sites
Argh! Well I've made some progress - I can get some graphics back on the screen, and they render like they did before I tried adding threads, but I can't seem to find out how to get a win32 thread to yield as was suggested. Whenever I try and move the window/resize or do anything other than watch the graphics, the whole thing hangs.
Heres a rough outline of what is where in my code, it's a total mess cos I don't know what I 'm doing:


GLvoid ResizeGLScene(GLsizei width, GLsizei height) { NeHe's window resizing code }

GLvoid KillGLWindow() { NeHe's window killing code }

BOOL CreateGLWindow(params) { NeHe's window creatin code }

void ThreadFunc(void* m) {
CreateGLWindow("MidiLights",640,480,16,false); //Window created
(including Render context and device context) inside thread function as you suggested.
for(;;) { rend->DrawGLScene(); SwapBuffers(hDC); } //
}

int WINAPI WinMain(params) {
rend = new CRenderer;
MSG msg;
BOOL done = FALSE;

_beginthread(ThreadFunc,0,null); //Thread created here

while(!done) { message loop }

}

LRESULT CALLBACK WndProc(params) { message handlers }


The CRenderer class just holds a few methods full of OpenGL calls, including the main rendering routine, DrawGLScene(). This is so I can write several different rendering classes, that hopefully share all the windows boilerplate and threading code. (I'll only ever be using one at a time - I'm not trying to get two threads rendering at once, just one rendering with another thread doing some other processing).

Hopefully the above outline will at first make you scream in horror, but then make it obvious where i've messed it up...

Share this post


Link to post
Share on other sites
shove a Sleep(0); after the call to swap buffers and in the while loop at the bottom.

I dont know if there is another solution for win32 threads, I use the boost::thread system for my threading which comes with a boost::yeild() function [grin]

Share this post


Link to post
Share on other sites
Quote:
Original post by 0beron

while(!done) { message loop }



Does this message loop use GetMessage() or PeekMessage()? I agree with Phantom that it sounds like one thread is starving the other. You'll want to use GetMessage() here to get the message loop to yeild control. You'll also want to have the rendering thread yield (with sleep(0)) so that the message loop can handle events. What exactly do you mean by hang? Does the window stop responding to inputs and give you a "not responding" error? Or does it stop rendering into the window? Or both?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I'll make it REALLY easy on you.

http://www.geocities.com/player2366/GLaid.zip

That's basically everything I use for my GL test apps. It's far from perfect, and generally a mess. Most of the stuff isn't even used anymore, but it'll prove that you *CAN* split the rendering from the processing and window events. Just don't try to replicate it using SDL, because it wont work.

You'll notice there's very few comments in there, and the ones that are there are generally me complaining about something else. Ignore them. The doLookAt(...) function doesn't work quite right (gimbal lock). Fix it if you need to, or use doLookFromXY(...) function.

I don't think there's any major problems with it. If any of you spot any problems with it, I'd be more than happy to know about them. Just don't ask me how to use it. If you want to take the time to rewrite a few lines in Basic_GL_App.h, you can reintroduce unicode to it (just change the class name and window names to wchar_t* types, and make sure UNICODE is defined).

Tear out everything useful, stick that in a class, and use it as your template. Just make sure you find ways to block the rendering and updating threads if they're both fiddling with objects, or you could find your apps crashing. ;)

Share this post


Link to post
Share on other sites
@solias, yes it uses PeekMessage(), will change that. When I say it hangs, I mean both - the window goes white, including the menu bar, and it stops responding altogether.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • 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!