Hello,
I’m having a hard time creating a pbuffer. I know how to set them up, I’ve used them before, but only in single-windowed apps.
This time I have a non-OpenGL app running and I need to create a pbuffer “on top” of it. OK, I need an OpenGL DC/RC in order to query for the WGL_xxx_ARB pointers. So, I created a dummy window with GLUT, and used glutHideWindow() to hide it as I don’t like it being shown. wglGetProcAddress works fine now, gets all the pointers for the ext string, WGL_ARB_pbuffer, WGL_ARB_pixel_format and WGL_ARB_render_texture. So far, so good…
The problem is with wglCreatePbufferARB(). It complains about an invalid handle. I am not very good at MFC and all that M$ Window creation stuff, someone please advise what’s wrong…
Here’s the code:
—8<–8<— snip snip —8<–8<—
GLUT creates a window, hidden with glutHideWindow();
—8<–8<— snip snip —8<–8<—
// Get the entry point for the OpenGL extensions string.
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress(“wglGetExtensionsStringARB”);char* ext = NULL;
if( wglGetExtensionsStringARB ) {
ext = (char*)wglGetExtensionsStringARB( wglGetCurrentDC() );
} else {
return FALSE;
}// WGL_ARB_pbuffer
if( strstr( ext, “WGL_ARB_pbuffer” ) == NULL ) {
return FALSE;
} else {
wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress(“wglCreatePbufferARB”);
wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)wglGetProcAddress(“wglGetPbufferDCARB”);
wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)wglGetProcAddress(“wglReleasePbufferDCARB”);
wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)wglGetProcAddress(“wglDestroyPbufferARB”);
wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)wglGetProcAddress(“wglQueryPbufferARB”);if( !wglCreatePbufferARB | | !wglGetPbufferDCARB | | !wglReleasePbufferDCARB | | !wglDestroyPbufferARB | | !wglQueryPbufferARB ) { return FALSE; }
}
// WGL_ARB_pixel_format
if( strstr( ext, “WGL_ARB_pixel_format” ) == NULL ) {
return FALSE;
} else {
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress(“wglChoosePixelFormatARB”);
if( !wglChoosePixelFormatARB ) {
return FALSE;
}
}// WGL_ARB_render_texture
if( strstr( ext, “WGL_ARB_render_texture” ) == NULL ) {
return FALSE;
} else {
wglBindTexImageARB = (PFNWGLBINDTEXIMAGEARBPROC)wglGetProcAddress(“wglBindTexImageARB”);
wglReleaseTexImageARB = (PFNWGLRELEASETEXIMAGEARBPROC)wglGetProcAddress(“wglReleaseTexImageARB”);
wglSetPbufferAttribARB = (PFNWGLSETPBUFFERATTRIBARBPROC)wglGetProcAddress(“wglSetPbufferAttribARB”);
if( !wglBindTexImageARB | | !wglReleaseTexImageARB | | !wglSetPbufferAttribARB ) {
return FALSE;
}
}// Get current OpenGL Device and Rendering Contexts
m_hGLDC = NULL;
m_hGLRC = NULL;m_hGLDC = wglGetCurrentDC(); // THESE WORK FINE,
m_hGLRC = wglGetCurrentContext(); // No errors with GetLastError() at least…if (m_hGLDC == NULL | | m_hGLRC == NULL) {
return FALSE;
}// Choose the a suitable pixel format.
int pf_attr[] = {
WGL_SUPPORT_OPENGL_ARB, TRUE, // pbuffer will be used with OpenGL
WGL_DRAW_TO_PBUFFER_ARB, TRUE, // Enable rendering to pbuffer
WGL_BIND_TO_TEXTURE_RGBA_ARB, TRUE, // Texture binding wanted
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, // Full hardware acceleration needed
WGL_RED_BITS_ARB, 8, // Red channel : Number of bits needed
WGL_GREEN_BITS_ARB, 8, // Green channel : Number of bits needed
WGL_BLUE_BITS_ARB, 8, // Blue channel : Number of bits needed
WGL_ALPHA_BITS_ARB, 8, // Alpha channel : Number of bits needed
WGL_STENCIL_BITS_ARB, 8, // Stencil buffer: Number of bits needed
WGL_DOUBLE_BUFFER_ARB, FALSE, // No double-buffering needed.
0 // Zero terminates the list.
};unsigned int count = 0;
int pixelFormat;
wglChoosePixelFormatARB(m_hGLDC, (const int*)pf_attr, NULL, 1, &pixelFormat, &count);
if (count == 0) {
return FALSE;
}// Define some attributes for the pbuffer.
int pAttrib[] = {
WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB, // Pbuffer texture format: RGBA
WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, // Texture type: GL_TEXTURE_2D
0 // Zero terminates the list.
};// Create the pbuffer.
m_pbuffer.hPBuffer = NULL;
m_pbuffer.hDC = NULL;
m_pbuffer.hRC = NULL;
m_pbuffer.nWidth = 512;
m_pbuffer.nHeight= 512;====> m_pbuffer.hPBuffer = wglCreatePbufferARB(m_hGLDC, pixelFormat, m_pbuffer.nWidth, m_pbuffer.nHeight, pAttrib); // Gives error “6”
error = GetLastError();
====> m_pbuffer.hDC = wglGetPbufferDCARB(m_pbuffer.hPBuffer); // Gives error “6”
error = GetLastError();
m_pbuffer.hRC = wglCreateContext(m_pbuffer.hDC); // No error (0)
error = GetLastError();// Enable the pbuffer.
wglMakeContextCurrentARB(m_pbuffer.hDC, m_pbuffer.hDC, m_pbuffer.hRC);—8<–8<— snip snip —8<–8<—
The problematic line is marked with ====> wglCreatePbufferARB(m_hGLDC, pixelFormat, m_pbuffer.nWidth, m_pbuffer.nHeight, pAttrib);
wglCreatePbufferARB() gives the error code 6 (using GetLastError()), I looked it up and it means invalid handle.
wglGetPbufferDCARB() gives the same error, 6.
wglCreateContext() gives 0, so no error there…
I’ve tried getting the DC with GetDC(parent_window_handle) but that doesn’t work much better than with m_hGLDC = wglGetCurrentDC(); … both give a handle and a no error…
I’ve called GetLastError() after every single function call, only the two marked with ====> give an error.
Why is the handle invalid ? This might be trivial, but as I said I’m not very familiar with Windows programming…
Thanks for any help,
Andru