【发布时间】:2012-03-28 15:04:04
【问题描述】:
前段时间我开始为 MFC 程序开发 OpenGL(3.3) 渲染器。一切都很好,直到我决定运行一些 OpenGL 调试工具来查看是否有一些无提示的错误。我使用 gDEBugger .Running gDebug 程序分析工具我立即开始收到以下类型的错误:
调试字符串:检测到错误:被调试进程向一个渲染上下文请求扩展函数指针(glGenBuffers),但在另一个渲染上下文(上下文#2)中调用了此函数指针
事实上每个 GLEW 方法都会出现这个错误。现在我开始在论坛和 MSDN 上寻找问题,我发现有人提到在 Windows 环境中应该重新定义一些 GLEW 方法指针。我也偶然发现了this tutorial这显示了使用 Windows OpenGL 方法重新定义的每个 GLEW 方法是多么漂亮:
void CGLRenderer::InitAPI()
{
// Program
glCreateProgram = (PFNGLCREATEPROGRAMPROC)wglGetProcAddress("glCreateProgram");
glDeleteProgram = (PFNGLDELETEPROGRAMPROC)wglGetProcAddress("glDeleteProgram");
glUseProgram = (PFNGLUSEPROGRAMPROC)wglGetProcAddress("glUseProgram");
...
....
我的 OpenGL 上下文设置如下所示:
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;
}
现在我真的很困惑,因为实际上程序在 VisualStudio 中运行良好,无需重新定义所有这些 GLEW 方法。但如果我直接运行可执行文件,它会显示空屏幕(无几何图形)。也在所有其他示例中和我读过的教程从来没有提到必须重置 GLEW API 方法的指针。所以我的问题是是否有人能指出将 OpenGL 3.3 集成到 Windows API 中的正确方法,因为似乎有很多方法正在做。
【问题讨论】:
-
在创建第二个上下文并使其成为当前上下文后再次尝试调用 glewInit。
-
这是一个很好的提示,现在我得到的错误要少得多。事实上现在只有 2 个:对于 glGenVertexArrays 和 glBindVertexArra
-
出于某种原因,如果我在调用
glewInit之前将glewExperimental设置为true,gDEBugger 不会抱怨函数指针来自不同的上下文。我什至不必再次致电glewInit来获取新的上下文。我不知道这是否能在不同的系统中始终如一地工作,但绝对值得一试!