一个最新的OpenGL应用程序是否必须使用GLEW?

12

我一直在阅读我所用的Visual Studio版本中包含的gl.h标头文件,但它似乎非常过时。

我不想使用GLUT或任何其他中间件/实用库来为我完成脏活,这包括GLEW。有人可以详细说明一下如何获取/查询4.0规范的现代特性集以及GLEW背后的思想是什么吗?


1
如果您愿意自行编写函数入口代码,那么您就不需要使用GLEW。 - Mārtiņš Možeiko
11
我不想使用GLUT或其他中间件/实用库来完成我所需要的工作,包括GLEW。为什么不呢?您认为编写数百行甚至数千行的OpenGL初始化代码能带来收益吗?相信我:这不会使您成为更好的程序员。您也不会因此而获得启示。这不会将您带到涅磐或完美幸福状态。重新发明[OpenGL Loading wheel](http://www.opengl.org/wiki/OpenGL_Loading_Library)是浪费时间的,无论您的技能水平如何。只需使用现有的库即可。 - Nicol Bolas
4个回答

16

在MSVC++中提供的gl.h仅涵盖Windows自带的opengl32.dll导出的功能。这个DLL通常只是一个“跳板”,指向实际的驱动程序。但它只导出了一个非常旧的版本的OpenGL,即OpenGL-1.1。

任何超出该版本的功能必须通过扩展机制访问。

我不想使用GLUT或其他中间件/实用库来为我完成脏活,包括GLEW在内。

GLUT与GLEW没有任何关系。

有人能详细说明一下为什么以及如何获取/查询4.0规范的现代功能集,以及GLEW背后的想法是什么吗?

您可以通过前面提到的扩展系统获取现代功能集。

有一个函数?glGetProcAddress(确切的名称取决于操作系统环境,在Windows中为wglGetProcAddress)。使用此函数,您可以检索扩展程序的函数指针用于当前的OpenGL上下文(在GLX中,函数指针对所有上下文都相同,但在Windows中可能会有所不同)。

加载扩展程序的步骤如下:

typedef (*OGLEXTP_SOMEEXTENSIONFUNCTION)(...)
OGLEXTP_SOMEEXTENSIONFUNCTION oglextp_glSomeExtensionFunction = NULL;
#define glSomeExtensionFunction oglextp_glSomeExtensionFunction;


struct Extensions
{
    bool SomeExtensionFunction;
}

errorcode initGLExtensions(){
    Extensions available;

    GLubyte extensions = glGetStrings(GL_EXTENSIONS);
    parse_extension_string(extensions, available);

    if( available.SomeExtensionFunction ) {
        oglextp_glSomeExtensionFunction = wglGwtProcAddress("glSomeExtensionFunction");
        if( !oglextp_glSomeExtensionFunction )
             return errorcode;
    }
}

你必须为每个函数编写大量的代码。 没有人想要这样做。 所以 GLEW 的开发人员想出了一组脚本,从 opengl.org 获取扩展规范并自动创建整个扩展加载并将其封装到一个小型库中,不会创建任何其他依赖关系。

如果您想使用更高级的OpenGL功能:请使用GLEW。 这不是强制性的,而是因为这是最简单的方式。


6
@FractalResurgence:不,它们没有关联。它们是完全独立的项目,具有不同的目标。GLUT为简单的OpenGL开发提供了基本框架,但还有许多其他框架可用。GLEW是一个库,可以完成OpenGL扩展加载的重要工作。你可以在没有GLFW的情况下使用GLUT,也可以在没有GLUT的情况下使用GLFW。声称GLUT和GLFW有关系就像声称Microsoft Word和Quark Express有关系一样。 - datenwolf
1
GLUT在教育目的上很有用,但作为一个严肃的窗口管理器来说,它是垃圾。 - TheBuzzSaw
1
@TheBuzzSaw:我知道你的意思,但GLUT不是窗口管理器,而是应用程序框架。窗口管理器是那个程序,负责管理屏幕上窗口的位置,并绘制它们的装饰、边框和标题栏。 - datenwolf
@datenwolf 没有人说它们在设计上相似,但它们大多数都是用于通用目的。它们处理人们因懒惰或其他原因不想处理的事情。它们简化和抽象了各自API的部分及其与底层操作系统的连接。它们在目的上是相关的 - 简化和抽象。这就是我所说的相关性。 - Fractal Resurgence
没有人想要编写这个 - 没什么太乏味的事情,只需一些简单的元编程/代码生成 :) - vexe
显示剩余2条评论

3
不要害怕使用GLEW。首先,我已经在Nvidia OpenGL SDK示例中看到了GLEW的使用。显然,它是一个可靠的工具,而且许可证友好。其次,您可以将库进行静态链接,并将其作为依赖项轻松移除。(个人建议,将源代码添加到项目中并定义 GLEW_STATIC 来使其正常工作。)

0

你想访问OpenGL 4.0扩展,是吗?你可能需要创建一个OpenGL 4.0上下文,并要求GLEW绑定相应的函数。

这里有一个使用GLEW和GLFW的示例,可从我的项目中复制。

  ...

  if (!glfwInit()) {
    exit(EXIT_FAILURE);
  }

  glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 2);   // I requested OpenGL 2.1 context
  glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 1);

  if(!glfwOpenWindow(640, 480, 8, 8, 8, 0, 24, 0, GLFW_WINDOW)) {  // get OpenGL context
    glfwTerminate();
    exit(EXIT_FAILURE);
  }

  if (glewInit() != GLEW_OK) {   // init glew, and bind gl* Extension functions
    glfwTerminate();
    exit(EXIT_FAILURE);
  }

  // now gl* extensions is available here

  ....

-1

GLee是另一个用于加载OpenGL扩展的库,它的源代码非常简单明了(代码生成器则是另一回事)。因此,您可以看到如何加载扩展函数。

请使用SVN主干版本,而不是“发布”版本,因为我与作者合作添加了对OpenGL 4.x扩展的支持。

我喜欢GLee的原因是它只加载您使用的扩展,而GLEW会加载200多个不同的扩展,这会减慢程序启动速度,尤其是OpenGL分析速度。


将GLEW转换为GLEE容易吗?更改库后性能提升了多少? - xiaoyi
谢谢提供信息!我可以问一下为什么OpenGL的设计如此晦涩吗?它似乎是一个相当丑陋的方法,应该由Khronos Group完成(除了那些应该被避免的特定于供应商的内容)? - Fractal Resurgence
@Fractal:我并不是真正的专家,但到目前为止,扩展方法已经防止了任何坏点子进入核心配置文件,因为它们首先必须作为扩展经过测试阶段。此外,硬件支持差异很大...使用扩展会使您的程序与旧卡不兼容,因此您必须明确选择使用这些功能。 - Ben Voigt
请使用SVN主干版本,而不是“发布”版本,因为我与作者合作添加了对OpenGL 4.x扩展的支持。难道这不是他们发布的原因吗?在SVN中的活动很好,但如果它不在实际发布中,那就没有意义。OpenGL维基页面说它已经过时,这是有原因的。如果它仍在积极维护,则还需要积极发布。 - Nicol Bolas
1
@Nicol: 为了这个问题的目的,学习扩展程序的加载,简单的代码比整齐打包的代码更好。GLee并不以二进制形式发布,它只是一个.c和.h文件,需要与您自己的代码一起编译。 - Ben Voigt
这是一个已经停止维护的项目。可以考虑使用以下替代方案:https://github.com/cginternals/glbinding 或 https://github.com/nigels-com/glew。 - Jens A. Koch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接