在 Windows 上使用 OpenGL 扩展

发布于 2024-07-05 14:03:33 字数 50 浏览 7 评论 0 原文

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

I want to use the functions exposed under the OpenGL extensions. I'm on Windows, how do I do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

北方的韩爷 2024-07-12 14:03:33

简单的解决方案:使用GLEW。 请参阅此处

硬解
如果您有非常充分的理由不使用 GLEW,可以通过以下方法在不使用 GLEW 的情况下实现相同的目的:

识别 OpenGL 扩展以及您希望使用的扩展 API。 OpenGL 扩展列在OpenGL 扩展注册表中。

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

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

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

示例:我的 PC 中的显卡是 NVIDIA 6600 GT。 因此,我访问 NVIDIA OpenGL 扩展规范 网页,发现 EXT_framebuffer_object扩展。 然后,我下载最新的 NVIDIA OpenGL SDK 并安装它。

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

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

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

示例:我搜索上面的framebuffer 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);

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

Easy solution: Use GLEW. See how here.

Hard solution:
If you have a really strong reason not to use GLEW, here's how to achieve the same without it:

Identify the OpenGL extension and the extension APIs you wish to use. OpenGL extensions are listed in the OpenGL Extension Registry.

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

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

Check if your graphic card supports the extension you wish to use. If it does, then your work is almost done! Download and install the latest drivers and SDKs for your graphics card.

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.

Your graphic card manufacturer provides a glext.h header file (or a similarly named header file) with all the declarations needed to use the supported OpenGL extensions. (Note that not all extensions might be supported.) Either place this header file somewhere your compiler can pick it up or include its directory in your compiler's include directories list.

Add a #include <glext.h> line in your code to include the header file into your code.

Open glext.h, find the API you wish to use and grab its corresponding ugly-looking declaration.

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

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

All this means is that your header file has the API declaration in 2 forms. One is a wgl-like ugly function pointer declaration. The other is a sane looking function declaration.

For each extension API you wish to use, add in your code declarations of the function name as a type of the ugly-looking string.

Example:

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

Though it looks ugly, all we're doing is to declare function pointers of the type corresponding to the extension API.

Initialize these function pointers with their rightful functions. These functions are exposed by the library or driver. We need to use wglGetProcAddress() function to do this.

Example:

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

Don't forget to check the function pointers for NULL. If by chance wglGetProcAddress() couldn't find the extension function, it would've initialized the pointer with NULL.

Example:

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

That's it, we're done! You can now use these function pointers just as if the function calls existed.

Example:

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

Reference: Moving Beyond OpenGL 1.1 for Windows by Dave Astle — The article is a bit dated, but has all the information you need to understand why this pathetic situation exists on Windows and how to get around it.

诗化ㄋ丶相逢 2024-07-12 14:03:33

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

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

A 'Very strong reason' not to use GLEW might be that the library is not supported by your compiler/IDE. E.g: Borland C++ Builder.

In that case, you might want to rebuild the library from source. If it works, great, otherwise manual extension loading isnt as bad as it is made to sound.

恋你朝朝暮暮 2024-07-12 14:03:33

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

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

@Kronikarz: From the looks of it, GLEW seems to be the way of the future. NVIDIA already ships it along with its OpenGL SDK. And its latest release was in 2007 compared to GLEE which was in 2006.

But, the usage of both libraries looks almost the same to me. (GLEW has an init() which needs to be called before anything else though.) So, you don't need to switch unless you find some extension not being supported under GLEE.

高跟鞋的旋律 2024-07-12 14:03:33

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

https://github.com/skaslev/gl3w

GL3W 需要 Python 2.6生成 OpenGL 的库和标头; 之后就不需要Python了。

GL3W is a public-domain script that creates a library which loads only core functionality for OpenGL 3/4. It can be found on github at:

https://github.com/skaslev/gl3w

GL3W requires Python 2.6 to generate the libraries and headers for OpenGL; it does not require Python after that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文