Resetting pointers to an OpenGL extension in Windows API
Some time ago I started working with the OpenGL renderer (3.3) for the MFC program. Everything was fine until I decided to run some OpenGL debugging tools to see if I had some quiet errors. I've used gDEBugger . Extracting the gDebug program analysis tool I immediately started getting errors of the following type:
Debug String: Bug encountered: The debugged process requested an extension function pointer (glGenBuffers) from one rendering context, but called that function pointer in a different rendering context (context # 2)
Virtually every GLEW method gets this error. Now I started looking for the problem in the forums as well as MSDN and I found that some people mention that in the Windows environment, some GLEW method pointers need to be overridden. Also I came across this tutorial which shows how pretty every GLEW method is overridden using Windows OpenGL methods like these:
void CGLRenderer::InitAPI()
{
// Program
glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram");
glDeleteProgram = (PFNGLDELETEPROGRAMPROC)wglGetProcAddress("glDeleteProgram");
glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram");
...
....
My OpenGL context setup looks like this:
bool OpenGLMain::create30Context(HDC device_context){
//this->hwnd=hwnd;
hdc=device_context;//GetDC(hwnd);
hdcGlobal=&hdc;
PIXELFORMATDESCRIPTOR kPFD;
memset(&kPFD,0,sizeof(PIXELFORMATDESCRIPTOR));
kPFD.nSize=sizeof(PIXELFORMATDESCRIPTOR);
kPFD.nVersion=1;
kPFD.dwFlags=
PFD_DRAW_TO_WINDOW|
PFD_SUPPORT_OPENGL|
PFD_GENERIC_ACCELERATED|
PFD_DOUBLEBUFFER;
kPFD.iPixelType=PFD_TYPE_RGBA;
kPFD.cColorBits=32;
kPFD.cDepthBits=32;
kPFD.cStencilBits=8;
kPFD.iLayerType=PFD_MAIN_PLANE;
int iPixelFormat=ChoosePixelFormat(hdc,&kPFD);
if(iPixelFormat==0){
// ReleaseDC(window,gs_hWindowDC);
return false;
}
BOOL bSuccess=SetPixelFormat(hdc,iPixelFormat,&kPFD);
if(!bSuccess){
// ReleaseDC(window,gs_hWindowDC);
return false;
}
/////////init opengl context
HGLRC tempOpenGLContext=wglCreateContext(hdc);/////Openggl 2.1
wglMakeCurrent(hdc,tempOpenGLContext);////male openGL 2.1 context current and active
GLenum error =glewInit();
if(error!=GLEW_OK){
return false;
}
/////////context setup///////
int attributes[]={
WGL_CONTEXT_MAJOR_VERSION_ARB,3,
WGL_CONTEXT_MINOR_VERSION_ARB,2,
WGL_CONTEXT_FLAGS_ARB,WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,0
};
if(wglewIsSupported("WGL_ARB_create_context")==1){
hrc=wglCreateContextAttribsARB(hdc,NULL,attributes);///create OpenGL 3x context based on the supplied attributes
wglMakeCurrent(NULL,NULL);//remove temp context
wglDeleteContext(tempOpenGLContext);
wglMakeCurrent(hdc,hrc);
}else{
hrc=tempOpenGLContext;////if no support for OGL 3x detected roll back to 2.0
}
/////////version check///////////////
int glVersion[2]={-1,-1};
glGetIntegerv(GL_MAJOR_VERSION,&glVersion[0]);
glGetIntegerv(GL_MINOR_VERSION,&glVersion[1]);
std::cout<<"Using openGL"<<glVersion[0]<<"."<<glVersion[1]<<
std::endl;
OutputDebugString(L"Using OPENGL version:"+glVersion[0]);
return true;
}
Now I am really confused at this point, because in fact the program works fine inside VisualStudio without overriding all those GLEW methods. But it shows blank screen (no geometry) if I run the executable directly. Also, all the other examples and tutorials I've ever read never mentioned to point to reset pointers to GLEW API methods. So my question is, can anyone point out the correct way to integrate OpenGL 3.3 into the Windows API, because it seems like there are many ways to do this.
source to share
The function pointers you get are based on the current context. That is, you can get different pointers to different OpenGL contexts. gDEBugger tells you that it has detected that you are using function pointers with a different context from the one used to retrieve them. Which is not guaranteed.
That being said, will usually work. It won't work unless the two contexts are from the same vendor (and probably for the same GPU or SLI / CrossFire GPU). But if so, everything should be fine.
GLEW, as I understand it, has no way to accommodate two different contexts that don't share the same pointers. You will have to call it glewInit
every time you change contexts.
source to share