c++ - 在 Windows API 中重置 OpenGL 扩展指针

标签 c++ opengl mfc

前段时间我开始为 MFC 程序开发 OpenGL(3.3) 渲染器。一切都很好,直到我决定运行一些 OpenGL 调试工具来查看是否有一些静默错误。我使用 gDEBugger .运行 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 方法的指针。所以我的问题是是否有人可以指出在 Windows API 中集成 OpenGL 3.3 的正确方法,因为似乎有很多方法正在做。

最佳答案

您获得的函数指针基于当前上下文。也就是说,你完全有可能为不同的OpenGL上下文得到不同的函数指针。 gDEBugger 告诉您它检测到您正在使用与用于获取它们的上下文不同的函数指针。这不能保证有效。

话虽如此,它通常会起作用。如果这两个上下文不是来自同一供应商(并且可能用于相同的 GPU 或 SLI/CrossFire GPU 设置),它将不起作用。但如果是,应该没问题。

据我所知,GLEW 没有办法适应使用相同函数指针的两个不同上下文。每次更改上下文时都必须调用 glewInit

关于c++ - 在 Windows API 中重置 OpenGL 扩展指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9663262/

相关文章:

c++ - 我可以在 OpenGL (C++) 的缓冲区中混合数据类型吗?

c++ - 网络字节顺序和字节序问题

c++ - 如果我的键是我的值的一部分,我应该使用映射还是集合?

c++ - llvm如何知道一个成员函数指针是否指向了一个虚函数?

c++ - 成员函数回调

c++ - glDrawElements 和立即模式之间的 OpenGL 质量差异

opengl - glBlendEquationSeparate 和 glBlendFuncSeparate - 片段着色器实现

c++ - 无法检索正则表达式匹配结果 - MFC/C++

c++ - CTime初始化

c++ - 如何从堆栈中找到崩溃的代码行?