【问题标题】:Using OpenGL extensions On Windows在 Windows 上使用 OpenGL 扩展
【发布时间】:2015-01-16 19:57:24
【问题描述】:

我想使用在 OpenGL 扩展下公开的函数。我在 Windows 上,我该怎么做?

【问题讨论】:

    标签: opengl glew


    【解决方案1】:

    简单的解决方案:使用GLEW。看看如何here

    硬解: 如果您有非常充分的理由不使用 GLEW,以下是不使用 GLEW 的方法:

    确定您希望使用的 OpenGL 扩展和扩展 API。 OpenGL 扩展在OpenGL Extension Registry 中列出。

    示例:我希望使用EXT_framebuffer_object 扩展的功能。我希望从此扩展中使用的 API 是:

    glGenFramebuffersEXT()
    glBindFramebufferEXT()
    glFramebufferTexture2DEXT()
    glCheckFramebufferStatusEXT()
    glDeleteFramebuffersEXT()
    

    检查您的显卡是否支持您希望使用的扩展程序。如果是这样,那么你的工作就差不多完成了!为您的显卡下载并安装最新的驱动程序和 SDK。

    示例:我的 PC 中的显卡是 NVIDIA 6600 GT。于是,我访问了NVIDIA OpenGL Extension Specifications 网页,发现支持EXT_framebuffer_object 扩展。然后我下载最新的NVIDIA OpenGL SDK 并安装它。

    您的显卡制造商提供了一个 gext.h 头文件(或类似名称的头文件),其中包含使用支持的 OpenGL 扩展所需的所有声明。 (请注意,并非所有扩展都受支持。)要么将此头文件放在编译器可以拾取的位置,要么将其目录包含在编译器的包含目录列表中。

    在您的代码中添加#include <glext.h> 行以将头文件包含到您的代码中。

    打开glext.h,找到你想使用的API并获取它对应的ugly-looking声明。

    示例:我搜索上述帧缓冲区 API 并找到它们对应的丑陋声明:

    typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); for GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei, GLuint *);
    

    这意味着你的头文件有两种形式的 API 声明。一种是类似 wgl 的丑陋函数指针声明。另一个是看起来很理智的函数声明。

    对于您希望使用的每个扩展 API,将函数名称的代码声明添加为丑陋的字符串类型。

    例子:

    PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
    PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
    PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
    PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
    PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
    

    虽然看起来很丑,但我们所做的只是声明扩展 API 对应类型的函数指针。

    用它们的合法函数初始化这些函数指针。这些函数由库或驱动程序公开。我们需要使用 wglGetProcAddress() 函数来做到这一点。

    例子:

    glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) wglGetProcAddress("glGenFramebuffersEXT");
    glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) wglGetProcAddress("glBindFramebufferEXT");
    glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) wglGetProcAddress("glFramebufferTexture2DEXT");
    glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) wglGetProcAddress("glCheckFramebufferStatusEXT");
    glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) wglGetProcAddress("glDeleteFramebuffersEXT");
    

    不要忘记检查 NULL 的函数指针。如果偶然 wglGetProcAddress() 找不到扩展函数,它会用 NULL 初始化指针。

    例子:

    if (NULL == glGenFramebuffersEXT || NULL == glBindFramebufferEXT || NULL == glFramebufferTexture2DEXT
        || NULL == glCheckFramebufferStatusEXT || NULL == glDeleteFramebuffersEXT)
    {
        // Extension functions not loaded!
        exit(1);
    }
    

    就是这样,我们完成了!您现在可以像使用函数调用一样使用这些函数指针。

    例子:

    glGenFramebuffersEXT(1, &fbo);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorTex[0], 0);
    

    参考: Moving Beyond OpenGL 1.1 for Windows,作者是 Dave Astle — 这篇文章有点过时,但包含了您需要了解的所有信息,以了解 Windows 上为什么存在这种可悲的情况以及如何解决它。

    【讨论】:

    • 我一整天都在尝试让 OpenGL 与 GLEW 一起工作,但我一直遇到问题...您知道:OpenGL 的设置并不容易。但是当它运行时:P
    【解决方案2】:

    不使用 GLEW 的“非常充分的理由”可能是您的编译器/IDE 不支持该库。例如:Borland C++ Builder。

    在这种情况下,您可能希望从源代码重建库。如果它有效,那就太好了,否则手动加载扩展并没有听起来那么糟糕。

    【讨论】:

      【解决方案3】:

      @Kronikarz:从外观上看,GLEW 似乎是未来的方向。 NVIDIA 已经将它与 OpenGL SDK 一起提供。与 2006 年的 GLEE 相比,它的最新版本是 2007 年。

      但是,在我看来,这两个库的用法几乎相同。 (GLEW 有一个 init() 需要在调用之前调用它。)所以,除非你发现 GLEE 不支持某些扩展,否则你不需要切换。

      【讨论】:

      • 最新的 GLEW 版本是 2012 年 8 月 6 日的 1.9.0。
      • 从 2015 年 1 月 26 日起,最新的 GLEW 版本现在是 1.12.0。所以它显然得到了积极的支持 :)
      【解决方案4】:

      GL3W 是一个公共域脚本,它创建一个仅加载 OpenGL 3/4 核心功能的库。可以在 github 上找到:

      https://github.com/skaslev/gl3w

      GL3W 需要 Python 2.6 来为 OpenGL 生成库和头文件;之后就不需要 Python 了。

      【讨论】:

        猜你喜欢
        • 2021-08-27
        • 1970-01-01
        • 2012-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-10
        相关资源
        最近更新 更多