使用Visual Studio一劳永逸式配置OpenGL开发环境(GLFW3+GLAD)

时间:2021-04-14 00:22:12

引子

OpenGL版本众多,需要引入额外的第三方库才能很好的满足我们平时渲染的需求,对于刚开始学习的同学们比较麻烦。
我也多次遇到很多落后的配置教程,浪费了时间不说,也会自己技术和现代OpenGL的技术脱节。
在当前的时间点(2018年),学习OpenGL如果还从glBegin()和glEnd()那一套就太落伍了,这个教程是为了示范如何配置OpenGL3.3以上的环境。
另外推荐学习OpenGL的教程:LearnOpenGL,可能需要*,有中文翻译版。
如果你想快速的开始学习OpenGL,这里有配置好的环境:(直接使用VS2015及以上版本打开,Win7/10实测均可)
超链接:资源
(目录结构中用到的所有的头文件、lib、dll也都在该链接中)

目录结构

我们配置的这个环境不光是只负责存放代码和第三方lib,还有一些shader文件和资源文件,因此需要构建一个良好的目录结构。

配置完整的目录结构如下:

文件名 备注
src 存放代码
external\include 第三方库的头文件,包含stb_image.h, glad.h, glfw.h ,assimp.h等
external\lib 第三方库的lib
external\dll 第三方库的dll
resources 资源文件夹,里面包括image,model,audiod等文件夹
vsbuild 项目文件夹,表示一个vs项目,打开该目录下的vsbuild.sln即可

重点介绍一下external\include下的文件夹

  • glm OpenGL的数学库,定义了很多关于向量、矩阵的操作,简洁迅速。
  • glfw 跨平台的对窗口资源的一个抽象库。
  • glad 针对不同的显卡驱动有不同的OpenGL实现,glad帮助我们隐藏这些差别欢快的使用OpenGL。
  • stb_image 轻量级的读取图片的库
  • assimp 轻量级读取模型的库

可以说,我们包含了除了物理引擎和声音控制的所有常用组件。

现在我们从头开始构造这个目录结构。
首先找一个空白的文件夹,在其中新建如下目录结构:

使用Visual Studio一劳永逸式配置OpenGL开发环境(GLFW3+GLAD)
这里我们不创建vsbuild,而是由vs来帮我们完成这件事情。
打开Visual Studio,新建一个空项目,项目名称为vsbuild,项目的地址为创建src、resources、external的同级目录:

使用Visual Studio一劳永逸式配置OpenGL开发环境(GLFW3+GLAD)

创建完毕后:

使用Visual Studio一劳永逸式配置OpenGL开发环境(GLFW3+GLAD)

接下来我们就要配置lib、include引入到我们的项目中。

右键vsbuild项目,打开属性页面:
使用Visual Studio一劳永逸式配置OpenGL开发环境(GLFW3+GLAD)

找到C/C++ Genral
使用Visual Studio一劳永逸式配置OpenGL开发环境(GLFW3+GLAD)
(注意,仅当你新建一个.cpp文件之后才会出现C/C++选项)
编辑右侧的附加目录:

使用Visual Studio一劳永逸式配置OpenGL开发环境(GLFW3+GLAD)

注意 SolutionDir 是一个宏,表示的是vsbuild所在的目录,那么根据相对路径我们可以找到external\include。
(键入的信息是 $(SolutionDir)..\external\include)。

同理,选中Linker的General的附加库目录

使用Visual Studio一劳永逸式配置OpenGL开发环境(GLFW3+GLAD)

打开编辑:

使用Visual Studio一劳永逸式配置OpenGL开发环境(GLFW3+GLAD)

此外,还要打开Linker的Input的目录,输入下面的值:

使用Visual Studio一劳永逸式配置OpenGL开发环境(GLFW3+GLAD)

使用Visual Studio一劳永逸式配置OpenGL开发环境(GLFW3+GLAD)

表示我们需要
glfw3.lib
glad.lib
stb_image.lib
assimp.lib
这四个库,而这四个库的目录是在 $(SolutionDir)..\external\lib
(这里我把glad和stb_image编译成了静态库)
最后,因为assimp需要动态链接,我们需要把相应的dll引入到我们的项目中。
最简便的方法如下:

使用Visual Studio一劳永逸式配置OpenGL开发环境(GLFW3+GLAD)

选中调试,编辑环境条目:

使用Visual Studio一劳永逸式配置OpenGL开发环境(GLFW3+GLAD)

这行字符串的含义是在调试模式下,将external\dll目录临时添加到环境变量中,这样我们就可以成功的动态链接了。

在配置完毕后,粘贴下面的代码到Source.cpp,运行。

#include <glad\glad.h>
#include <glfw\glfw3.h>
#include <iostream>


void framebuffer_size_callback(GLFWwindow* window, int width, int height);

void processInput(GLFWwindow *window);



// settings

const unsigned int SCR_WIDTH = 800;

const unsigned int SCR_HEIGHT = 600;



int main()

{

    // glfw: initialize and configure

    // ------------------------------

    glfwInit();

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);

    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);



#ifdef __APPLE__

    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X

#endif



                                                         // glfw window creation

                                                         // --------------------

    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);

    if (window == NULL)

    {

        std::cout << "Failed to create GLFW window" << std::endl;

        glfwTerminate();

        return -1;

    }

    glfwMakeContextCurrent(window);

    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);



    // glad: load all OpenGL function pointers

    // ---------------------------------------

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))

    {

        std::cout << "Failed to initialize GLAD" << std::endl;

        return -1;

    }



    // render loop

    // -----------

    while (!glfwWindowShouldClose(window))

    {

        // input

        // -----

        processInput(window);



        // render

        // ------

        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);

        glClear(GL_COLOR_BUFFER_BIT);



        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)

        // -------------------------------------------------------------------------------

        glfwSwapBuffers(window);

        glfwPollEvents();

    }



    // glfw: terminate, clearing all previously allocated GLFW resources.

    // ------------------------------------------------------------------

    glfwTerminate();

    return 0;

}



// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly

// ---------------------------------------------------------------------------------------------------------

void processInput(GLFWwindow *window)

{

    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)

        glfwSetWindowShouldClose(window, true);

}



// glfw: whenever the window size changed (by OS or user resize) this callback function executes

// ---------------------------------------------------------------------------------------------

void framebuffer_size_callback(GLFWwindow* window, int width, int height)

{

    // make sure the viewport matches the new window dimensions; note that width and 

    // height will be significantly larger than specified on retina displays.

    glViewport(0, 0, width, height);

}

最后显示出如下窗口说明你配置成功了。