为VS项目导入第三方库时的依赖配置
以导入GLFW库为例介绍如何为VS的工程导入第三方库,完成库导入后便可包含相关头文件并正常使用其功能了,本文中使用的是VS2022
为VS项目导入第三方库时的依赖配置
一、关于GLFW
- GLFW(Graphics Library Framework)是一个专门针对OpenGL的C语言库
- 其提供了一些渲染物体所需的最低限度的接口
- 其允许用户创建OpenGL上下文、定义窗口参数以及处理用户输入
- 其相比SDL(Simple DirectMedia Layer)更加轻量级
- 从官网或Github可以下载到预编译的库版本或源代码,可按需自行编译,参考此处
二、项目平台选择
- 右键解决方案下你要运行的项目,选择
属性/Propertes
选项进行头文件与lib库文件的配置,依据你的需求,选择对应的配置
(Debug或Release等)以及平台
(Win32/x86
或x64
),此处我以Win32
为例(下载的库的版本必须与你此处所配置的相匹配,否则无法成功运行)
三、Include路径配置
- 在
C/C++/常规/附加包含目录
的配置中(你需要已经创建了至少一个C/C++源文件,否则在属性中无法找到此配置选项),输入项目文件中的GLFW头文件所在的路径即可;其中Dependencies
文件夹是我手动创建的用于存放外来库的,其内的GLFW/include
文件夹内含有头文件,这是从下载好的文件里选取的
$(SolutionDir)
指代我们项目解决方案的路径,更多的这样的相对路径简写可以点击”附加包含目录”输入框最右侧的按钮选择“编辑”打开窗口,在“宏”中进行搜索
- 如果有多个第三方库,则将其
include
路径都添加到上述配置中即可
四、Linker路径配置
4.1 附加库目录
- 接下来我们进行
链接器/常规/附加库目录
的配置,其中的lib-vc2022
也是从我们下载好的文件中抽取的版本库文件夹(只保留了.lib
后缀文件)
- 如果有多个库同样可以点击右侧按钮进入编辑模式增加多行库目录
4.2 附加依赖项
- 然后是
链接器/输入/附加依赖项
的配置,先前配置的附加库目录相当于指定静态链接库的位置,而附加依赖项指定的则是应当从附加库目录中选取什么文件进行Linking,多个依赖项间(填写文件名)以分号间隔,填写完即可测试库的引入和程序编写测试,若报错则Debug即可 - 下图中的
glfw3.lib
是我们在上述lib-vc2022
文件夹中保留的文件,仅有此依赖项时运行使用了GLFW的程序会报错,依据报错信息搜索可在微软的MSDN网站中找到对应的解决方法,我们将官方(针对特定报错信息)提供的需添加的附加依赖项名称写到此处配置即可
- 比如我们为了找出解决此条报错信息而需要添加的依赖库,直接在谷歌搜索红框内的
CreateDCW
即可找到微软的文章,并在Requirements
栏目中找到|Library|Gdi32.lib|
的提示,我们将Gdi32.lib
添加即可,以此类推
4.3 动态链接库
- 虽然我们在上述示例中选取的GLFW版本未使用
.dll
动态链接库,但若你需要引入的第三方库需要用到,你就直接将相关.dll
文件放在VS对应项目目录下即可(不是VS解决方案根目录,而是项目目录),例如下图的SDL相关库的动态链接库
五、测试GLFW功能
5.1 用于显示窗口的代码模板
- 官方提供了一个简单的模板,详见官方文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <GLFW/glfw3.h>
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}
- 代码详细解析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <GLFW/glfw3.h>
int main(void)
{
// 定义了一个GLFWwindow类型的指针变量window,这个指针将用来引用创建的窗口
GLFWwindow* window;
//调用glfwInit初始化GLFW库,如果初始化失败则函数返回-1,程序结束
if (!glfwInit())
return -1;
//glfwCreateWindow创建一个窗口以及与之关联的OpenGL上下文
//参数为窗口的宽度640像素、高度480像素、窗口标题"Hello World"、两个设置为NULL的参数用于指定OpenGL上下文的版本和属性
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
//如果窗口创建失败,则调用glfwTerminate清理GLFW库
glfwTerminate();
return -1;
}
//glfwMakeContextCurrent将之前创建的窗口的上下文设置为当前线程的当前上下文,这意味着后续的OpenGL调用都将在这个上下文中执行
glfwMakeContextCurrent(window);
//循环运行直到glfwWindowShouldClose返回true,即窗口被用户关闭
while (!glfwWindowShouldClose(window))
{
//glClear函数用于清除颜色缓冲区,GL_COLOR_BUFFER_BIT指定要清除的缓冲区
glClear(GL_COLOR_BUFFER_BIT);
//glfwSwapBuffers交换颜色缓冲区(通常是双缓冲区前后两部分),这样渲染的结果才能显示在屏幕上
glfwSwapBuffers(window);
//glfwPollEvents函数检查是否有事件(如键盘输入、鼠标移动等)被触发,并调用相应的回调函数处理这些事件
glfwPollEvents();
}
//当窗口关闭循环结束时,glfwTerminate被调用来清理所有GLFW资源,并正确地退出程序
glfwTerminate();
//main函数返回0,表示程序成功执行完毕
return 0;
}
- 注意,在属性配置中配置好了头文件依赖路径、库依赖路径后,如果代码仍然显示无法引入GLFW,那么你要检查一下这里,你选的是32-bit的GLFW就对应选x86,64-bit对应x64
5.2用GLFW画简单的图形
- 在模板中的
while
循环内进行代码的写 - 此处画三角形的方法是传统的OpenGL方法,在后面我们会用现代的方法来画三角形
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//循环运行直到glfwWindowShouldClose返回true,即窗口被用户关闭
while (!glfwWindowShouldClose(window))
{
//glClear函数用于清除颜色缓冲区,GL_COLOR_BUFFER_BIT指定要清除的缓冲区
glClear(GL_COLOR_BUFFER_BIT);
//只是规划一个区间方便管理而已,类似C#的#region
#pragma region LegacyDrawTriangles
//传统的OpenGL中,glBegin和glEnd函数用于指定顶点数据的开始和结束,此处告诉OpenGL接下来的顶点调用将定义一系列的三角形
//GL_TRIANGLES告诉OpenGL每个三角形由三个顶点组成,并且每个三角形都是独立的(不共享顶点)
glBegin(GL_TRIANGLES);
//glVertex调用用于指定组成图元的顶点
glVertex2f(-0.5f, -0.5f);
glVertex2f(0.0f, 0.5f);
glVertex2f(0.5f, -0.5f);
glEnd();
#pragma endregion
//glfwSwapBuffers交换颜色缓冲区(通常是双缓冲区前后两部分),这样渲染的结果才能显示在屏幕
glfwSwapBuffers(window);
//glfwPollEvents函数检查是否有事件(如键盘输入、鼠标移动等)被触发,并调用相应的回调函数处理这些事件
glfwPollEvents();
}
- 输出结果如下图,可以看到一个三角形
本文由作者按照 CC BY-NC-SA 4.0 进行授权