PDA

View Full Version : C++ Win32 multiple GL windows



Herr Bohm
03-28-2007, 07:19 AM
Hello,

I'm trying to create multiple opengl rendering contexts on different windows.
I tried it with using multiple HDC's and HGRLC's and in a single thread.

That didn't worked because opengl uses all its stuff globally?

Then i tried adding multi threading.
The threads run fine but only in 1 window a triangles is been drawn.

Here is the code for a single thread.
The other thread is the same except it draws a different colored triangle:


DWORD WINAPI DrawOne(LPVOID n)
{
while(true)
{
MSG msg;
BOOL MsgReturn = GetMessage(&msg, NULL, DRAWSCENE, QUITSCENE);

if (MsgReturn)
{
switch(msg.message)
{
case DRAWSCENE:
{
wglMakeCurrent(GlWindow1.hdc, GlWindow1.hrc);


glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

glTranslatef(0.0f, 0.0f, -5.0f);
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_TRIANGLES);
glVertex2f(0.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(1.0f, 1.0f);
glEnd();

SwapBuffers(GlWindow1.hdc);

}
break;
case QUITSCENE:
return 0;
break;
}
}
}
} And here is the main message loop which calls the threads to draw:


while(!done)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
done = true;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
wglMakeCurrent(GlWindow1.hdc, GlWindow1.hrc);
PostThreadMessage(thread_ids[1], DRAWSCENE , 0 , 0 );

wglMakeCurrent(GlWindow.hdc, GlWindow.hrc);
PostThreadMessage(thread_ids[0], DRAWSCENE , 0 , 0 );
}
} I create the opengl windows using the code from nehe.gamedev lesson 1 but i only get 1 triangle drawn.

jide
03-28-2007, 02:17 PM
It should work on a single thread. Each window should have its own context.

Herr Bohm
03-28-2007, 03:14 PM
Originally posted by jide:
It should work on a single thread. Each window should have its own context. I get the same result as with multiple threads for each GL window, I can only draw to 1 window.

robosport
03-28-2007, 08:58 PM
The DrawScene handler is forcing the current OpenGL context to GlWindow1.hrc at the beginning of the draw code (right above glClear).

Try taking that wglMakeCurrent out since you are setting the context before posting the DRAWSCENE message.

Even better pass the proper hdc and hrc as params in the message so the draw code always draws to the context requesting DRAWSCENE event.

Herr Bohm
03-29-2007, 01:42 AM
That is correct since i have 2 threads and for both threads i have to different functions.
In the other thread i call wglMakeCurrent to activate the other hdc (GlWindow.hdc) instead of GlWindow1.hdc.

robosport
03-29-2007, 01:54 AM
That detail wasn't in the description or the code posted.

Can you share the code for the place you are creating the hDC and hRC and setting the appropriate variables GLWindow and GLWindow1?

Is there a specific reason you aren't making it work with one thread then adding a second thread once this part of the messaging and state are debugged?

Herr Bohm
03-29-2007, 05:15 AM
Originally posted by robosport:

Can you share the code for the place you are creating the hDC and hRC and setting the appropriate variables GLWindow and GLWindow1?
Here i create the window with hdc and hrc:

Originally posted by robosport:

Is there a specific reason you aren't making it work with one thread then adding a second thread once this part of the messaging and state are debugged? Can you explain this to me?
I dont understand it.

robosport
03-29-2007, 05:22 AM
Can you explain this to me?
I dont understand it. I meant it is always harder to debug a multithreaded app than it is a single threaded app while stepping through with a debugger.

You had said previously that the results were the same with one thread so I'm curious why you aren't just creating both windows with one thread to debug it then add the extra thread once everything is in a known working state.

robosport
03-29-2007, 05:30 AM
You mentioned you have a separate drawing routine for the second window. Can you set a breakpoint in that drawing routine and see if it is ever reached using a debugger?

I just re-read your first post. It is not necessary to add another thread just to draw to two OpenGL windows. The OpenGL state is specific to the hRC context that is current, not global variables.

Herr Bohm
03-29-2007, 06:23 AM
I switched back to a single thread.
The code to create the windows remains the same.
This is the code that draws the scene:

bool DrawGLScene(float blue) // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix

glTranslatef(0.0f, 0.0f, -5.0f);
glColor3f(1.0f, blue, 0.0f);
glBegin(GL_TRIANGLES);
glVertex2f(0.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(1.0f, 1.0f);
glEnd();
return true; // Everything Went OK
}And i call it in the main message loop:

while(!done)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
done = true;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
wglMakeCurrent(GlWindow1.hdc, GlWindow1.hrc);
DrawGLScene(1.0f);
SwapBuffers(GlWindow1.hdc);


wglMakeCurrent(GlWindow.hdc, GlWindow.hrc);
DrawGLScene(0.0f);
SwapBuffers(GlWindow.hdc);
}
}I then add a breakpoint in the DrawGLScene to see what value float blue had.
Both calls to the DrawGLScene are executed but 1 opengl window has a yellow triangle which is good, but the other opengl window only draws a black background.

robosport
03-29-2007, 06:35 AM
First let me remind you the second parameter of glColor3f is green. I'm sure you knew that and it's not the issue here.

Next, are you setting up the projection matrix or modelview matrix somewhere? (other than the LoadIdentity and transform on Z)

Herr Bohm
03-29-2007, 06:40 AM
OOh my,

I only initialized 1 window and forgot about the other.

Now it works perfectly,
Thanks for the help