views:

1742

answers:

3

Is it possible to have openGL in 2 windows? as in 2 different windows (lets say the first is 640x480 and the other is 1024x768) rendering different things (lets say one window is an editor and the other is the main/normal window display)

+5  A: 

If you're using GLUT you can use the glutSetWindow() / glutGetWindow() calls to select the correct window (after creating them with glutCreateSubWindow()). However sometimes GLUT might not be the right tool for the job.

If you're working on Windows you'll want to look into the wglMakeCurrent() and wglCreateContext(). On OS X there is aglSetCurrentContext() et cetera, and X11 requires glXMakeCurrent().

Those functions activate the current OpenGL context to which you can render. Each platform specific library has it's own ways of creating a window and binding an OpenGL context to it.

On Windows, after you've acquired your HWND and HDC for a window (after a CreateWindow and GetDC call). You generally do something like this to set up OpenGL:

GLuint l_PixelFormat = 0;

// some pixel format descriptor that I generally use:
static PIXELFORMATDESCRIPTOR l_Pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, 
 PFD_DRAW_TO_WINDOW + PFD_SUPPORT_OPENGL + PFD_DOUBLEBUFFER, 
 PFD_TYPE_RGBA, m_BitsPerPixel, 0, 0, 0, 0, 0, 0, 
 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0};

if(!(l_PixelFormat = ChoosePixelFormat(m_hDC, &l_Pfd))){
 throw std::runtime_error("No matching pixel format descriptor");
}

if(!SetPixelFormat(m_hDC, l_PixelFormat, &l_Pfd)){
 throw std::runtime_error("Can't set the pixel format");
}

if(!(m_hRC = wglCreateContext(m_hDC))){
 throw std::runtime_error("Can't create rendering context");
}

wglMakeCurrent(m_hDC, m_hRC);

You use that code to create multiple windows and bind OpenGL to it, then each time you want to draw to a specific window you have to call wglMakeCurrent before you do anything and you pass in the parameters corresponding to that window.

As a side-note, OpenGL allows you to share certain data between different contexts, however as per spec the data that you can share is pretty limited. However, most OSes allow you to share more data than specified in the specification.

Jasper Bekkers
+2  A: 

Yes, this is possible. For each window you will need to create a unique device context and render context.

HDC hDC = GetDC( hWnd ); /* get the device context for a particular window */
/* snip */
HGLRC hRC;
hRC = wglCreateContext( hDC ); /* get a render context for the same window */
/* repeat with hDC2 and hRC2 with another window handle*/

Before making GL calls to the window you must call wglMakeCurrent like this:

wglMakeCurrent( hDC, hRC );
/* GL calls for first window */
wglMakeCurrent( NULL, NULL);

wglMakeCurrent( hDC2, hRC2 );
/* GL calls for second window */
wglMakeCurrent( NULL, NULL);
postfuturist
+1  A: 

On Windows you can share OpenGL objects such as textures and shaders with wglShareLists(). It typically does share everything you'd care about, despite what MSDN says.

richard_nz