关于glew:在Windows上使用OpenGL扩展

关于glew:在Windows上使用OpenGL扩展

Using OpenGL extensions On Windows

我想使用OpenGL扩展中公开的功能。 我在Windows上,该怎么做?


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

硬解:
如果您确实有理由不使用GLEW,请按照以下方法在没有GLEW的情况下实现相同的目的:

确定您要使用的OpenGL扩展和扩展API。 OpenGL扩展注册表中列出了OpenGL扩展。

Example: I wish to use the capabilities of the EXT_framebuffer_object extension. The APIs I wish to use from this extension are:

1
2
3
4
5
glGenFramebuffersEXT()
glBindFramebufferEXT()
glFramebufferTexture2DEXT()
glCheckFramebufferStatusEXT()
glDeleteFramebuffersEXT()

检查您的图形卡是否支持您要使用的扩展名。如果是这样,那么您的工作就快完成了!下载并安装适用于您的图形卡的最新驱动程序和SDK。

Example: The graphics card in my PC is a NVIDIA 6600 GT. So, I visit the NVIDIA OpenGL Extension Specifications webpage and find that the EXT_framebuffer_object extension is supported. I then download the latest NVIDIA OpenGL SDK and install it.

您的图形卡制造商会提供glext.h头文件(或类似名称的头文件),其中包含使用受支持的OpenGL扩展所需的所有声明。 (请注意,并非所有扩展名都受支持。)可以将该头文件放在编译器可以选择的位置,也可以将其目录包含在编译器的包含目录列表中。

在代码中添加#include 行,以将头文件包含在代码中。

打开glext.h,找到您要使用的API并获取其相应的看上去丑陋的声明。

Example: I search for the above framebuffer APIs and find their corresponding ugly-looking declarations:

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

这意味着您的头文件具有2种形式的API声明。一种是类似wgl的丑陋函数指针声明。另一个是理智的函数声明。

对于您希望使用的每个扩展API,在函数名称的代码声明中添加外观难看的字符串。

Example:

1
2
3
4
5
PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;

尽管看起来很丑,但是我们要做的只是声明与扩展API对应类型的函数指针。

使用其应有的函数初始化这些函数指针。这些功能由库或驱动程序公开。我们需要使用wglGetProcAddress()函数来执行此操作。

Example:

1
2
3
4
5
glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) wglGetProcAddress("glGenFramebuffersEXT");
glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) wglGetProcAddress("glBindFramebufferEXT");
glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) wglGetProcAddress("glFramebufferTexture2DEXT");
glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) wglGetProcAddress("glCheckFramebufferStatusEXT");
glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) wglGetProcAddress("glDeleteFramebuffersEXT");

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

Example:

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

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

Example:

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

参考:Dave Astle撰写的超越Windows的OpenGL 1.1 —本文有点陈旧,但是包含了您需要了解为什么Windows上存在这种可悲情况以及如何解决它的所有信息。


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

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


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

https://github.com/skaslev/gl3w

GL3W需要Python 2.6才能为OpenGL生成库和头文件;在那之后不需要Python。


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

但是,这两个库的用法对我来说几乎相同。 (GLEW有一个init(),但需要在其他任何东西之前调用。)因此,除非发现GLEE不支持某些扩展名,否则无需切换。


推荐阅读