glew工作原理

81 篇文章 2 订阅
33 篇文章 1 订阅
2017-02-16

  在C/C++程序中使用OpenGL时,需要使用glew/glad这样的第三方库来加载OpenGL函数。不像一般的第三方lib,通过头文件,直接就能够找到函数的指针地址。很多同学不明白为什么需要这么做。本文,就来分析一下。
  因为gl.h这个头文件在windows平台是最原始的版本,微软并不更新,一些最新的函数接口并不能暴露出来,不知为何,在Linux上同样不更新了,最新的OpenGL函数原型在glext.h文件中被声明。Khronos官方解释如下

Because extensions vary from platform to platform and driver to driver, OpenGL developers can't expect interfaces for all extensions to be defined in the standard gl.hglx.h, and wgl.h header files supplied with the OS / graphics drivers. Additional header files are provided here, including:

  • <GL/glext.h> - OpenGL 1.2 and above compatibility profile and extension interfaces.
  • <GL/glcorearb.h> - OpenGL core profile and ARB extension interfaces, as described in appendix G.2 of the OpenGL 4.3 Specification. Does not include interfaces found only in the compatibility profile.
  • <GL/glxext.h> - GLX 1.3 and above API and GLX extension interfaces.
  • <GL/wglext.h> - WGL extension interfaces.

  在windows平台上,opengl无法做静态链接,opengl32.dll 是微软提供的。只能通过第三方的lib,动态的获取lib中这样的函数的指针地址。比如说,OpenGL 3 提供的glDrawElementsInstanced() 函数,原本是在glext.h中声明的,如果要使用glew,就不能在glew.h文件前include glext.h。在glew.h 中这个符号被定义为。,而#define GLEW_GET_FUN(x) x,所以,OpenGL的函数名字glDrawElementsInstanced,在内部就变为了__glewDrawElementsInstanced,在头文件中声明了这个函数指针的存在,这也是不需要使用glext.h的原因。所以,从这个时候开始,glDrawElementsInstanced这个函数的指针就存在了,只是值为NULL。在glew.c 中, ,这才是好的编程习惯,否则release 版本时,glDrawElementsInstanced这个函数的指针不一定指向哪儿去了。

这一句经过预处理就是: r = ((__glewDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)glewGetProcAddress((const GLubyte*)"glDrawElementsInstanced")) == NULL) || r;所以,到此时,glDrawElementsInstanced()这个3.0版本以后的函数就被天骄到OpenGL中了。,这个WINGDIAPI PROC  WINAPI wglGetProcAddress(LPCSTR); 是wingdi.h 定义的,应该是显卡driver 实现的,在显卡driver在中,保留了OpenGL 标准函数名字与其函数指针的表格。
其实,glew 也不是必需的,你也可以使用glcorearb.h这个文件,只是上面的类似的过程都需要手工来做一遍,这样并没有必要。

  因为OpenGL虽然是单核时代的产物,但是,OpenGL也支持多线程,只是这个特性被使用的场合较少。这个多线程支持的特性,就是由glew/glad这样的lib来负责的,
 在windows上,多线程使用OpenGL时,这个glewGetContext() 是需要自己来实现的,每个线程都有自己GLContext,每个GLContext必须要和一个窗口的handle绑定,那么需要自己写代码把每个GLContext和UI线程联系起来。单线程使用OpenGL时,glew和这个GLContext 就无关了,是窗口系统绑定的。

线程之间可以共享GLContext。

ref:

  1. http://stackoverflow.com/questions/38948159/about-function-loader-in-vulkan
  2. https://software.intel.com/en-us/articles/api-without-secrets-introduction-to-vulkan-part-1    ****
  3. http://stackoverflow.com/questions/17809237/what-does-glew-do-and-why-do-i-need-it
  4. https://khronos.org/registry/OpenGL/index_gl.php#headers
如果有任何意见,欢迎留言讨论。 


[ 主页 ]
  • 9
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Glew(OpenGL Extension Wrangler Library)是一个开源的C/C++库,用于管理OpenGL扩展。它可以帮助我们在使用OpenGL时轻松地加载和使用各种扩展功能。VSCode(Visual Studio Code)是一个轻量级的代码编辑器,支持多种编程语言和丰富的插件生态系统。 如果你想在VSCode中使用Glew,你可以按照以下步骤进行配置: 1. 确保你已经安装了VSCode和C/C++扩展。你可以在VSCode的插件市场中搜索并安装"C/C++"扩展。 2. 创建一个新的C/C++项目或打开一个已有的项目。 3. 在项目中创建一个文件夹用于存放Glew相关的文件。 4. 下载Glew库文件。你可以从Glew的官方网站(http://glew.sourceforge.net/)下载最新版本的Glew。 5. 将下载的Glew库文件解压到步骤3中创建的文件夹中。 6. 打开VSCode的设置,可以通过菜单栏中的"文件"->"首选项"->"设置"来打开设置面板。 7. 在设置面板中搜索"C++",找到"C++: Include Path"设置,并在其值中添加步骤3中创建的文件夹路径。这将告诉VSCode在编译时将该文件夹添加到包含目录中。 8. 在你的C/C++代码中,使用`#include <GL/glew.h>`来包含Glew的头文件。 9. 在链接过程中,将Glew的库文件添加到链接器选项中。具体方法取决于你所使用的构建系统。 完成以上步骤后,你就可以在VSCode中使用Glew库来管理OpenGL扩展了。请确保在编译和链接过程中正确设置了相关的选项和路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值