文章

为VS项目导入第三方库时的依赖配置

以导入GLFW库为例介绍如何为VS的工程导入第三方库,完成库导入后便可包含相关头文件并正常使用其功能了,本文中使用的是VS2022

为VS项目导入第三方库时的依赖配置

一、关于GLFW

  • GLFW(Graphics Library Framework)是一个专门针对OpenGL的C语言库
    • 其提供了一些渲染物体所需的最低限度的接口
    • 其允许用户创建OpenGL上下文、定义窗口参数以及处理用户输入
    • 其相比SDL(Simple DirectMedia Layer)更加轻量级
  • 官网Github可以下载到预编译的库版本或源代码,可按需自行编译,参考此处

二、项目平台选择

  • 右键解决方案下你要运行的项目,选择属性/Propertes选项进行头文件与lib库文件的配置,依据你的需求,选择对应的配置(Debug或Release等)以及平台Win32/x86x64),此处我以Win32为例(下载的库的版本必须与你此处所配置的相匹配,否则无法成功运行)

GLFWConfiguration.png

三、Include路径配置

  • C/C++/常规/附加包含目录的配置中(你需要已经创建了至少一个C/C++源文件,否则在属性中无法找到此配置选项),输入项目文件中的GLFW头文件所在的路径即可;其中Dependencies文件夹是我手动创建的用于存放外来库的,其内的GLFW/include文件夹内含有头文件,这是从下载好的文件里选取的

GLFWConfigC++General.png

  • $(SolutionDir)指代我们项目解决方案的路径,更多的这样的相对路径简写可以点击”附加包含目录”输入框最右侧的按钮选择“编辑”打开窗口,在“宏”中进行搜索

VSQuickDir.png

  • 如果有多个第三方库,则将其include路径都添加到上述配置中即可

添加多个附加包含目录.png

四、Linker路径配置

4.1 附加库目录

  • 接下来我们进行链接器/常规/附加库目录的配置,其中的lib-vc2022也是从我们下载好的文件中抽取的版本库文件夹(只保留了.lib后缀文件)

GLFWLinkerGeneral.png

  • 如果有多个库同样可以点击右侧按钮进入编辑模式增加多行库目录

4.2 附加依赖项

  • 然后是链接器/输入/附加依赖项的配置,先前配置的附加库目录相当于指定静态链接库的位置,而附加依赖项指定的则是应当从附加库目录中选取什么文件进行Linking,多个依赖项间(填写文件名)以分号间隔,填写完即可测试库的引入和程序编写测试,若报错则Debug即可
  • 下图中的glfw3.lib是我们在上述lib-vc2022文件夹中保留的文件,仅有此依赖项时运行使用了GLFW的程序会报错,依据报错信息搜索可在微软的MSDN网站中找到对应的解决方法,我们将官方(针对特定报错信息)提供的需添加的附加依赖项名称写到此处配置即可

LinkerConfigInputDependencies.png

  • 比如我们为了找出解决此条报错信息而需要添加的依赖库,直接在谷歌搜索红框内的CreateDCW即可找到微软的文章,并在Requirements栏目中找到|Library|Gdi32.lib|的提示,我们将Gdi32.lib添加即可,以此类推

ExampleDebugDependencyLib.png

4.3 动态链接库

  • 虽然我们在上述示例中选取的GLFW版本未使用.dll动态链接库,但若你需要引入的第三方库需要用到,你就直接将相关.dll文件放在VS对应项目目录下即可(不是VS解决方案根目录,而是项目目录),例如下图的SDL相关库的动态链接库

动态链接库放在项目目录下.png

五、测试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

OpenGLx86.png

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();
}
  • 输出结果如下图,可以看到一个三角形

OpenGLDrawTriangle.png

本文由作者按照 CC BY-NC-SA 4.0 进行授权