疑问

在上一篇博客《试用GLFW并创建OpenGL和DX的环境》里创建OpenGL环境时,我将opengl32.lib加入了工程的“附加依赖项”,之后成功让程序编译成功。如果不加入,则会找不到OpenGL函数的实现:

1>main_GL.obj : error LNK2019: 无法解析的外部符号 __imp_glClear,函数 main 中引用了该符号

我注意到,opengl32.lib是在我的Windows操作系统环境中的(我在本地Windows10SDK的各个版本中都能看到它)

但我还是存有很大的疑问。首先这个加入opengl32.lib的做法,并不是来源官方的资料,是我看其他网友的方法;此外,这个32的后缀提示了它是对应32位的,而我的程序是64位的,却并没有找到对应64位的库。
在GLFW官方教程中是使用GLAD来加载OpenGL的库。因此我想这是否才是最“正确”的做法?

为什么要使用GLAD加载库

在这篇论坛中,也有人问了问题:“为什么要在OpenGL初始化阶段使用GLAD?”

回答:

翻译:

首先,你并没有指定OpenGL相关联的.obj文件,所以链接器找不到那些函数的实现。在Windows平台上,你可能会使用opengl32.lib,它是opengl32.dll的导入库,从Windows95开始就存在于每个Windows版本中。
然而,这个opengl32.dll实际上并没有包含你正在使用的那个OpenGL版本的实现,它包含的是微软的OpenGL 1.1 GDI 软件光栅化。你在Windows上真正使用的OpenGL实现是由显卡的驱动程序提供的。对于OpenGL1.0和1.1函数,opengl32.dll会扮演一个trampoline的角色,将调用转发到驱动的dll上。
如果你想调用OpenGL高于1.1版本(1997年)的函数,你就不得不在每次都使用OpenGL扩展机制,因为opengl32.dll并不提供他们的入口,编译器/链接器也自然找不到那些函数。


感觉这个回答很清晰,我觉得可信度极高。
那么答案很明白了:为了更方便使用OpenGL完整的功能,需要使用GLAD加载OpenGL的库,而不是使用opengl32.lib

OpenGL Loading Library 的概念

GLAD本质上是一个OpenGL Loading Library:

An OpenGL Loading Library is a library that loads pointers to OpenGL functions at runtime, core as well as extensions. This is required to access functions from OpenGL versions above 1.1 on most platforms. Extension loading libraries also abstracts away the difference between the loading mechanisms on different platforms.

Most extension loading libraries override the need to include gl.h at all. Instead, they provide their own header that must be used. Most extension loading libraries use code generation to construct the code that loads the function pointers and the included headers. Information is available if you wish to perform this manually, but you are encouraged to use one of these libraries yourself.

一个OpenGL Loading Library是一个库,可以用来在运行时读取OpenGL的函数地址,即包括【核心】也包括【扩展】。对于想要访问高于1.1的功能,使用OpenGL Loading Library都是必须的。而对于【扩展】的读取,它也抽象了在不同平台读取机制间的差异。
大多数 extension loading libraries 都不需要再包含gl.h了。作为替代,它们自己提供头文件。大多数 extension loading libraries 都使用“代码生成”来构建那些用来读取函数地址的代码。如果你希望手动操作,则需要提供一些信息,但建议你使用这些库之一。


随后,OpenGL Loading Library wiki页面上也提供了一些库,其中包括GLAD。

实践使用GLAD加载OpenGL的库

0. 使用GLAD生成读取函数地址的代码

GLAD的Git:https://github.com/Dav1dde/glad。
如果不想安装GLAD,也可以直接使用在线服务:

  • 选择语言为C/C++
  • 规范选择OpenGL
  • API版本选择4.6,这是当前我能选的最新版本
  • “Profile”可以选择“核心”或者“扩展”,这里我选择“核心”。
  • 最后,点击【Generate】按钮。


随后,读取函数地址的代码自动生成。
选择下载glad.zip

1. 配置工程

(注意,之前的opengl32.lib已经去掉了)

将在上一步中下载的\glad\src\glad.c拷贝到工程中,因为需要编译它:

当然,工程中也需要加入它:

随后,将在上一步下载的\glad\include添加到包含目录

2. 代码

随后,就是使用GLAD了,也很简单。
首先是include头文件,在GLFW官方教程中指出需要添加GLFW_INCLUDE_NONE宏来防止冲突,因此include部分变成了:

#define GLFW_INCLUDE_NONE
#include <glfw3.h>
#include <glad/glad.h>

然后,在初始化OpenGL上下文之后,使用GLAD来加载OpenGL的函数地址

/* Make the window's context current */
glfwMakeContextCurrent(window);//使用GLAD来加载OpenGL的函数地址
gladLoadGL();

随后,程序照常运行


完整代码:

#define GLFW_INCLUDE_NONE
#include <glfw3.h>
#include <glad/glad.h>int main(void)
{//必须先初始化该库,然后才能使用大多数GLFW函数。成功初始化后,GLFW_TRUE将返回。如果发生错误,GLFW_FALSE则返回。if (!glfwInit())return -1;//创建窗口(OpenGL上下文似乎也一并创建了)GLFWwindow* window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);if (!window){glfwTerminate();return -1;}/* Make the window's context current */glfwMakeContextCurrent(window);//使用GLAD来加载OpenGL的函数地址gladLoadGL();//循环直到用户关闭窗口while (!glfwWindowShouldClose(window)){//清理屏幕所用的颜色:glClearColor(0.4f, 0.5f, 0.6f, 1.0f);//清理屏幕glClear(GL_COLOR_BUFFER_BIT);//交换前后缓冲glfwSwapBuffers(window);//轮询并处理事件glfwPollEvents();}//使用GLFW完成操作后,通常是在应用程序退出之前,需要终止GLFWglfwTerminate();return 0;
}

使用GLAD加载OpenGL的库相关推荐

  1. 无法加载JNI共享库(JDK)

    当我尝试打开Eclipse时 ,弹出对话框指出: 无法加载JNI共享库" C:/JDK/bin/client/jvm.dll". 此后,Eclipse强制关闭. 我想提出几点: 我 ...

  2. 尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。...

    从10G开始,Oracle提供了一个较为轻量级的客户包,叫做Instant Client. 将它安装好后,就不用再安装庞大的Oracle Client了.  这样一来,只要客户端下载Instant C ...

  3. 尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题...

    开发环境:VS2010+ORACLE,今天换了64位WIN7 ,为了方便使用PL/SQL,装了32位oracle客户端,但是本地IIS调试程序的时候总是提示:尝试加载 Oracle 客户端库时引发 B ...

  4. 尝试加载 Oracle 客户端库时引发 BadImageFormatException

    尝试加载 Oracle 客户端库时引发 BadImageFormatException.问题记录 1公司电脑是win7 64位旗舰版,刚来时配的新电脑,4G+i5这个配置不装64位那算是浪费了.谁知道 ...

  5. arduino如何加载OLED屏幕库

    arduino如何加载OLED屏幕库 使用arduino之OLED显示篇包含(SSD1306.SH1106.UC1611及各种常用OLED) arduino之所以火爆,很大一部分原因是由于它拓展一款外 ...

  6. 使用OD加载微软符号库

    Windbg可以加载微软符号库,如果本地没有符号,可以自动去微软网站上下载对应的PDB文件辅助调试分析. PS:WingDbg下的符号加载,SRV*c:/windows/symbols*http:// ...

  7. php taglib.php,thinkphp5 taglib_pre_load预加载自定义标签库

    文章内容来自官方手册,需要查看详细的可以访问来源网址. 模板中加载标签库,预加载自定义标签库,扩展内置标签库的加载 下面以标签库放在common作为一个示例: namespace app\common ...

  8. Linux C++ libdl.so dlfcn.h使用方法(dlopen()、dlsym()、dlclose()、dlerror())(用于动态链接库操作)(懒加载、立即加载)共享库符号、动态库

    文章目录 dlfcn.h解析 - dlopen():打开一个动态链接库文件并返回一个句柄,该句柄用于后续的操作,如查找符号.关闭库等. - dlsym():在打开的动态链接库中查找指定的符号,并返回符 ...

  9. WinCE 调试某手写输入法时遇到的加载手写库失败的问题

    调试某手写输入法时遇到的加载手写库失败的问题 在 WinCE6.0 下使用此手写输入法 SDK 做了一个单独的手写输入程序A(MFC Dialog 框架).正常情况下,可以正常使用. 此 A 程序,采 ...

  10. Android查看当前应用已经加载的so库

    源代码: private static List<String> allSOLists = new ArrayList<String>();/** * 获取全部已加载的SO库* ...

最新文章

  1. 树形菜单 php,简单的树形菜单_php
  2. CodeForces - 1355C Count Triangles(数学)
  3. 锡山国土推行数据中心“在线变更”
  4. 迷茫在路口——致我的2014
  5. 线性表的各种基本操作
  6. 使用Gradle构建Java项目
  7. 多线程 之 生产者与消费者
  8. 中文核心期刊有哪些?
  9. 电脑长截图的操作方法
  10. 使用SQL查询分析器删除所有用户表
  11. vue3 ts three 动画 骨骼动画 人物动画 模型动画
  12. 计算机的运算符号,运算符号包括哪些
  13. 企业如何选择?网站建设中常见的几种类型
  14. info.plist 隐私权限 国际化
  15. 弗洛伊德求最小简单环
  16. arcgis注记详解
  17. 微信浏览器网页点击图片缩放
  18. vscode 删除的文件如何找回??
  19. 如何快速判断一个数是否为16的倍数
  20. 超级狗是集软件授权、课件保护和身份认证于一身的加密狗。

热门文章

  1. matlab怎么表示循环求和,matlab循环求和
  2. 分布式 | DBLE docker 部署遇到的简单问题修复过程
  3. 太阳高度角方位角计算
  4. 扒皮 || 优衣库X KAWS凭什么会被疯抢??!!!
  5. html select文字居中显示,用CSS将select/option文本居中
  6. xcode清理缓存瘦身方法整理
  7. 银行IT系统-整体架构
  8. 系统分析与设计方法---结构化分析与设计
  9. 什么是收缩压和舒张压?
  10. LED 点阵实验~点亮一个点、数字、汉字、图