Multiple OpenGL Windows, WIN 32 API (without MFC)

Hey,

I’m trying to create two OpenGL windows and I couldn’t find any post with a related problem in this forum. Please give me a link if this question was answered earlier.

System: Windows XP, Visual Studio C++

Problem: I have created successfully one window with a triangle but now I want to create two windows and these are my first experiences with OpenGL.

I initialized for every window a seperate device context and a separate rendering context without an error message.

Result:

  • Both windows are displayed (no compiling errors).
  • The second window is working properly (drawings displayed).
  • I can’t do any changes in the first window (e.g. background color) after wglMakeCurrent(first_win, first_win).

Please have a look at the code:


// first window
HWND g_hWnd = NULL;
HDC g_hDC = NULL;
HGLRC g_hRC = NULL;

// second window
HWND hWnd2;
HDC hDC2=NULL;
HGLRC hRC2=NULL;

// First Window
if(!(hWnd2 = CreateWindowEx (
WS_EX_APPWINDOW | WS_EX_WINDOWEDGE,
“glwin”,
“Randbegrenzung”,
WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUPWINDOW,
ScreenX-225,
0,
225,
225,
NULL,
NULL,
hInstance,
NULL)))
{
MessageBox(hWnd2,“Create Window”,“ERROR”,MB_OK);
return false;
}

int nPixelFormat;
PIXELFORMATDESCRIPTOR pfdPixelFormat2 =
{

};

if(!(hDC2 = GetDC(hWnd2)))
{
MessageBox(…); return FALSE;
}
// Everything with a separate error message, but i deleted
// the stuff for a better understanding.

nPixelFormat = ChoosePixelFormat(hDC2, &pfdPixelFormat2);
SetPixelFormat(hDC2, nPixelFormat, &pfdPixelFormat2);
hRC2 = wglCreateContext(hDC2);
wglMakeCurrent(hDC2, hRC2);

ShowWindow(hWnd2,SW_SHOW);
glShadeModel(GL_SMOOTH);

//!!!
// Problem: First Window is active but if I do some changes
// e.g. background glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// nothing happen.

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
//!!!

// second window: is working properly, without any problems

if(!(g_hWnd = CreateWindowEx(
dwExStyle,
“glwin”,
“SR-2 OpenGL”,
dwStyle,
ScreenX-10-WindowRect.right-WindowRect.left,
ScreenY-70-WindowRect.bottom-WindowRect.top,
WindowRect.right-WindowRect.left,
WindowRect.bottom-WindowRect.top,
0,
NULL,
hInstance,
0)))
{MessageBox(…); return false;}

ShowWindow(g_hWnd,SW_SHOW);

int iPixelFormat;
PIXELFORMATDESCRIPTOR pfdPixelFormat =
{…};

// Device context…
g_hDC = GetDC(g_hWnd));
iPixelFormat = ChoosePixelFormat(g_hDC, &pfdPixelFormat;
SetPixelFormat(g_hDC, iPixelFormat, &pfdPixelFormat);
g_hRC = wglCreateContext(g_hDC);
wglMakeCurrent(g_hDC, g_hRC);

glShadeModel(GL_SMOOTH);

//!!!
// If I do here some changes (e.g. background color everything
// is fine.

glClearColor(.0f, .0f, 0.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LINE_SMOOTH);
//!!!

Sorry for the huge source code.

Thank ýou.
Scalax

Nobody? What’s wrong - posted source code to long or should I post in the expert forum?

How would you create two opengl windows with different input data? Do you have any source code?

Thanks,
Scalax

You can’t. Only one context can run in each thread. To do what you want to do, you need to place each context in its own thread.

Hello MarkS,

thank you for your comment. Sorry, I’m a fresher and therefore I need a few more words from you.

My Target: Two OpenGL windows with seperate input data

My “approach” which doesn’t work:

  1. Initialization of first window:
    1_a) CreateWindowEx…
    1_b) Getting an OpenGL Device Context for the first window
    1_c) Setting pixel format
    1_d) Getting Rendering Context for the first window

  2. Initialization of Second window:
    2_a) CreateWindowEx…
    2_b) Getting an OpenGL Device Context for the second window
    2_c) Setting pixel format
    2_d) Getting Rendering Context for the second window

I thought I could switch between these two windows in the main loop of my program like:

// main loop
{
// activate first window:
wglMakeCurrent(FirstWindow_hDC, FirstWindow_hRC);
// Now I could do some drawings in the first window.

// deactivate window:
wglMakeCurrent(NULL, NULL);

// activate second window
wglMakeCurrent(SecondWindow_hDC, SecondWindow_hRC);
// Now I could do some drawings in the second window.
}

This approach doesn’t work and you wrote that I should place each context in its own thread. Sorry, that I don’t understand the solution. How should I do this in my case?

Does that mean that the initialization stuff (DeviceContext, PixelFormat, Rendering Context) of 1_b to 1_d and 2_b to 2_d for both windows has to run in the main loop before I start the drawing in the correspond window?

Thank you very much.
Scalax

Hey guys,

After many hours, my understanding of MarkS comments & my approach the program is working properly. I don’t think that this is the fastest approach but it is working.

Solution:

// main function

  1. Initialization of first window:
    1_a) CreateWindowEx…
    1_b) Getting an OpenGL Device Context for the first window
    1_c) Setting pixel format
    1_d) Getting Rendering Context for the first window

  2. Initialization of Second window:
    2_a) CreateWindowEx…
    2_b) Getting separate OpenGL Device Context for the second window
    2_c) Setting pixel format
    2_d) Getting separate Rendering Context for the second window

// main loop:
{
// First I would like to draw something in the first window.
wglMakeCurrent(NULL,NULL);

// Activate First Window
wglMakeCurrent(FirstWindow_hDC,FirstWindow_hRC);
ReSizeGLScene();

// …ala Nehe: glShadeModel(); glClearColor;…

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// ################
// Now you can do the drawing in the first window.
// ################
SwapBuffers(FirstWindow_hDC);

// After that you can draw in the second window.
// Deactivate First Window
wglMakeCurrent(NULL,NULL);
// Activate Second Window
wglMakeCurrent(SecondWindow_hDC,SecondWindow_hRC);
ReSizeGLScene();

// …ala Nehe: glShadeModel(); glClearColor;…

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// #############
// Now you can do the drawing in the second window.
// #############
SwapBuffers(SecondWindow_hDC);
}

Fine.
Scalax

Is not neccessary create different thread for each window.
you can handle gdi context using scalax solutions:

MSG msg;
while(!exit)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message==WM_QUIT)
{
exit=true;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
wglMakeCurrent(hDC_1,hRC_1);
ReSizeGLScene_1();
render_1
SwapBuffers(hDC_1);

  wglMakeCurrent(hDC_2,hRC_2); 
  ReSizeGLScene_2();
   *****render_2*****
  SwapBuffers(hDC_2);
 }

}

Why are you responding to a 3 year old thread?