Well, let me make sure that I’ve got the process correct then:
-
Set up your main context (GLUT is doing this for me at the moment). Get pointers to the HDC and HGLDC of this main context.
-
Get a pixel format that will work for your pbuffer, then create the pbuffer. Since this is a different context than the main one, you also need to get a new Cg context. Right now, I’m using:
void createLightPbuffer (void)
{
// pbufferage
gHDC = wglGetCurrentDC();
gHGLRC = wglGetCurrentContext();
int format = 0;
unsigned int numformats;
const int attributes[] = { WGL_DRAW_TO_PBUFFER_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_FLOAT_ARB,
WGL_RED_BITS_ARB, 32,
WGL_DEPTH_BITS_ARB, 24,
WGL_BIND_TO_TEXTURE_RGBA_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_FALSE,
0 };
const int cubemap_flags[] = { WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_CUBE_MAP_ARB,
//WGL_MIPMAP_TEXTURE_ARB, GL_TRUE,
0 };
if (!wglChoosePixelFormatARB(gHDC, attributes, NULL, 1, &format, &numformats))
{
std::cout << "Could not choose pixel format for pbuffer, GetLastError() returned" << GetLastError() << std::endl;
exit(1);
}
if (format == 0)
{
std::cout << "No suitable pixel format found for pbuffer!" << std::endl;
exit(1);
}
lightPbuffer.hPB = wglCreatePbufferARB(gHDC, format, SHADOWMAP_SIZE, SHADOWMAP_SIZE, cubemap_flags);
assert (lightPbuffer.hPB);
lightPbuffer.hDC = wglGetPbufferDCARB (lightPbuffer.hPB);
assert (lightPbuffer.hDC);
lightPbuffer.hGLRC = wglCreateContext (lightPbuffer.hDC);
assert (lightPbuffer.hGLRC);
if (!wglShareLists(gHGLRC, lightPbuffer.hGLRC))
{
std::cout << "Couldnt' share lists" << std::endl;
exit(1);
}
wglMakeCurrent(lightPbuffer.hDC, lightPbuffer.hGLRC);
lightPbuffer.glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
lightPbuffer.wglSetPbufferAttribARB = (PFNWGLSETPBUFFERATTRIBARBPROC)wglGetProcAddress("wglSetPbufferAttribARB");
// set up cg too
lightPbuffer.cgContext = cgCreateContext();
assert(lightPbuffer.cgContext);
lightPbuffer.cgVertProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
assert(lightPbuffer.cgVertProfile != CG_PROFILE_UNKNOWN);
cgGLSetOptimalOptions(lightPbuffer.cgVertProfile);
lightPbuffer.cgFragProfile = cgGLGetLatestProfile (CG_GL_FRAGMENT);
assert(lightPbuffer.cgFragProfile != CG_PROFILE_UNKNOWN);
cgGLSetOptimalOptions(lightPbuffer.cgFragProfile);
glEnable (GL_CULL_FACE);
glEnable (GL_DEPTH_TEST);
wglMakeCurrent(gHDC, gHGLRC);
}
To do this.
- Make the main context current again with wglMakeCurrent().
Actually USING the pbuffer:
-
Make the pbuffer’s context current. Set up everything required to render what you want (projection/modelview matrices, etc).
-
Render what you want into the pbuffer.
-
Make the main context current again, and bind the pbuffer to a texture with wglBindTexImageARB(). Draw using the texture bound to the pbuffer. Then unbind the pbuffer so that you can draw to it again.
-
You’re done!
Now, this is what I’m doing, but after setting up the Cg context for the pbuffer, when I try to make the main context current again, gDEBugger pops up an error about glGenProgramsARB, the error being:
Error code: AP_FOREIGN_CONTEXT_EXTENSION_FUNC_CALL_ERROR.
Error description:
The debugged process asked for an extension function pointer (glGenProgramsARB) from one render context, but called this function pointer in another render context (contex #2)
So I’m just confused.