【问题标题】:Modern OpenGL context failure现代 OpenGL 上下文失败
【发布时间】:2013-10-20 01:54:55
【问题描述】:

好的,我设法在我的 attrib 结构中使用 3.2 版本的 wglcreatecontextattribARB 创建了一个 OpenGL 上下文(所以我已经初始化了一个 3.2 的 opengl 上下文)。

它有效,但奇怪的是,当我使用 glBindBuffer 时,例如我仍然得到未引用的链接器错误,更新的上下文不应该阻止这种情况吗?

顺便说一句,我在 Windows 上,Linux 不必处理新旧上下文(它直接支持其版本的核心)。 代码:

PIXELFORMATDESCRIPTOR pfd;
    HGLRC tmpRC;
    int iFormat;
    if (!(hDC = GetDC(hWnd)))
    {
        CMsgBox("Unable to create a device context. Program will now close.", "Error");
        return false;
    }
    ZeroMemory(&pfd, sizeof(pfd));
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = attribs->colorbits;
    pfd.cDepthBits = attribs->depthbits;
    pfd.iLayerType = PFD_MAIN_PLANE;
    if (!(iFormat = ChoosePixelFormat(hDC, &pfd)))
    {
        CMsgBox("Unable to find a suitable pixel format. Program will now close.", "Error");
        return false;
    }
    if (!SetPixelFormat(hDC, iFormat, &pfd))
    {
        CMsgBox("Unable to initialize the pixel formats. Program will now close.", "Error");
        return false;
    }
    if (!(tmpRC=wglCreateContext(hDC)))
    {
        CMsgBox("Unable to create a rendering context. Program will now close.", "Error");
        return false;
    }
    if (!wglMakeCurrent(hDC, tmpRC))
    {
        CMsgBox("Unable to activate the rendering context. Program will now close.", "Error");
        return false;
    }
    strncpy(vers, (char*)glGetString(GL_VERSION), 3);
    vers[3] = '\0';
    if (sscanf(vers, "%i.%i", &glv, &glsubv) != 2)
    {
        CMsgBox("Unable to retrieve the OpenGL version. Program will now close.", "Error");
        return false;
    }
    hRC = NULL;
    if (glv > 2) // Have OpenGL 3.+ support
    {
        if ((wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB")))
        {
            int attribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, glv, WGL_CONTEXT_MINOR_VERSION_ARB, glsubv,WGL_CONTEXT_FLAGS_ARB, 0,0};
            hRC = wglCreateContextAttribsARB(hDC, 0, attribs);
            wglMakeCurrent(NULL, NULL);
            wglDeleteContext(tmpRC);
            if (!wglMakeCurrent(hDC, hRC))
            {
                CMsgBox("Unable to activate the rendering context. Program will now close.", "Error");
                return false;
            }
            moderncontext = true;
        }
    }
    if (hRC == NULL)
    {
        hRC = tmpRC;
        moderncontext = false;
    }

【问题讨论】:

  • 我猜这个问题属于stackoverflow。

标签: c++ opengl


【解决方案1】:

你仍然需要

  1. 使用适当的名称和函数签名声明函数指针。
  2. 使用wglGetProcAddress 为这些指针获取正确的内存位置
  3. #将实际的 OpenGL API 名称定义为对应的函数指针。

没错,OpenGL API函数其实就是函数指针。

如果您没有时间和耐心执行此操作,则建议使用 OpenGL 加载程序库,例如 GL3W 或 GLEW。这也将让您免于先创建虚拟上下文,然后再创建“真实”上下文的负担。

另见OpenGL wiki page on loading function pointers

【讨论】:

  • 那我能问你,那么创建一个更新的上下文的全部用途是什么?如果需要对旧上下文做同样的事情(使用函数指针和扩展等声明访问新的 API 事物),创建新上下文不是完全没用吗?
  • @user209347 简短回答:不,它不是没用的。阅读wgl_create_context 的“概述”部分,了解其背后的简要动机。
  • 另见 wglGetProcAddress
  • 这些函数没有在opengl32.dll 中定义,它十多年来没有改变,但它们是 OpenGL 独立客户端驱动程序 (ICD) 的一部分。 wglGetProcAddress 只是 ICD 中实际实现的一个通道。顺便说一句,每个 OpenGL 函数也是如此(除了 opengl32.dll 中的后备 1.1 软件光栅器;您不想使用它)。
  • @user209347: 不,如果你想使用多重采样主帧缓冲区(你可以使用基于 FBO 的 MSAA 没有这个),你需要使用新的上下文创建 WGL API 扩展,创建一个与GL_ARB_debug_outputGL_KHX_DEBUG 一起使用的调试上下文,创建核心上下文等。如果不使用扩展的 WGL API,您也无法获得 WGL pbuffer 像素格式,但如果您有 PBO,您也可以忽略这一点..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-15
  • 1970-01-01
  • 1970-01-01
  • 2018-03-21
  • 1970-01-01
  • 2011-07-13
  • 1970-01-01
相关资源
最近更新 更多