PDA

View Full Version : Multiple OpenGL Windows, WIN 32 API (without MFC)



scalax
10-25-2008, 03:42 AM
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

scalax
10-26-2008, 05:46 AM
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

MarkS
10-26-2008, 08:01 AM
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.

scalax
10-26-2008, 11:04 AM
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

scalax
10-27-2008, 07:43 AM
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

_rockdino
09-22-2011, 08:04 AM
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);
}
}

V-man
09-22-2011, 12:18 PM
Why are you responding to a 3 year old thread?