搭建 OpenGL 的开发环境

学 OpenGL,C/C++ 应该是首选,所以先安装 C/C++ 的开发环境,无论是选择 GCC,还是选择 CLang,在 Ubuntu 中就是一条命令的事,我这里选 GCC。在 Ubuntu 中,可以直接安装 build-essential,更省事。命令如下:

sudo apt install build-essential

OpenGL 不提供和 GUI 相关的 API,所以 OpenGL 不能处理诸如创建窗口、处理用户的键盘鼠标输入这样的任务。这时,我们需要 GLFW。使用 GLFW 库,我们可以简化搭建 OpenGL 程序框架的任务,同时还可以轻松获得跨平台的功能。安装 GLFW 也是一条命令的事:

sudo apt install libglfw3 libglfw3-dev

除此之外,我们还需要 GLEW。有了GLEW 扩展库,就再也不用为找不到函数的接口而烦恼了,因为GLEW能自动识别平台所支持的全部 OpenGL 高级扩展涵数。安装命令如下:

sudo apt install libglew2.1 libglew-dev

另外,在写 OpenGL 程序的过程中,会经常需要进行向量、矩阵的计算,所以有一个顺手的数学库是很重要的,我这里选择 GLM。安装命令如下:

sudo apt install libglm-dev

学会了 OpenGL 的基本概念后,当然会忍不住想加载个 3D 模型看看效果,这时候,就可以考虑使用 Assimp 库了。安装命令如下:

sudo apt install assimp-utils libassimp5 libassimp-dev

assimp-utils 包提供了一个assimp命令,使用该命令可以显示 Assimp 库支持哪些格式的 3D 模型文件,也可以使用该命令显示 3D 模型文件的详细信息,如下图:

当然,3D 的东西,还是应该用可视化的方式看起来更直观一些。好在,Linux 中可用的 3D 建模动画软件有 Blender。安装起来也只是一条命令的事:
在这里插入图片描述

sudo apt install blender

下面,让大家看一下我的老婆,用的就是 Blender:
在这里插入图片描述
在这里插入图片描述
最简单的 OpenGL 程序框架

下面,开始写我们的第一个 OpenGL 程序,如下:

#include
#include <GL/glew.h>
#include <GLFW/glfw3.h>

const int SCR_WIDTH = 1920;
const int SCR_HEIGHT = 1080;

int main(int argc, char** argv){
glfwInit();
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, “StudyOpenGL”, nullptr, nullptr);
if (window == NULL)
{
std::cerr << “Failed to create GLFW window” << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);

if(glewInit() != GLEW_OK){
    std::cerr << "Failed to initalize GLEW" << std::endl;
    return -1;
}

while (!glfwWindowShouldClose(window))
{
    glfwSwapBuffers(window);
    glfwPollEvents();
}

glfwDestroyWindow(window);
glfwTerminate();
return 0;

}

这段程序比较短,使用任何编辑器如 vim、gedit 等等都可以。当后面程序变长之后,我选择使用 Visual Studio Code。我们将这个文件保存为 FirstStep.cpp。编译执行的命令也很简单:

g++ FirstStep.cpp -o FirstStep -lGL -lGLEW -lglfw
./FirstStep

就可以看到我们的第一个 OpenGL 窗口了,目前,它还只是空洞洞的漆黑一片,如下图:
在这里插入图片描述

因为我是 4K 屏,所以即使定义了SCR_WIDTH = 1920和SCR_HEIGHT = 1080,窗口看起来也不是特别大。上面那个程序是纯 C 版的,等程序变大之后,会在 main() 函数之外遗留很多全局的变量和函数,不是那么清爽,所以常规会使用 C++ 封装一下,建立一个 App 类,以后要添加鼠标键盘输入的功能也在这个类里面加,建立新程序时,只需要继承这个类就可以了。App 类的内容如下:

#ifndef APP_HPP
#define APP_HPP

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include

class App{
private:
const int SCR_WIDTH = 1920;
const int SCR_HEIGHT = 1080;

public:  
	static App* the_app;
	
    App(){

    }

    virtual void init(){
        
    }
    
    virtual void display(){
        
    }


    virtual void run(App* app){
        if(the_app != NULL){ //同一时刻,只能有一个App运行
            std::cerr << "The the_app is already run." << std::endl;
            return;
        }            
        the_app = app;
        
        glfwInit();
        GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "StudyOpenGL", NULL, NULL);
        if (window == NULL)
        {
            std::cerr << "Failed to create GLFW window" << std::endl;
            glfwTerminate();
            return;
        }
        glfwMakeContextCurrent(window);
        if(glewInit() != GLEW_OK){
            std::cerr << "Failed to initalize GLEW" << std::endl;
            return;
        }

        init(); //用来准备各种数据

        while (!glfwWindowShouldClose(window))
        {

            display(); //这里才是渲染图形的主战场 
                           
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
        glfwDestroyWindow(window);

        glfwTerminate();
        return;
    }

};

App* App::the_app = NULL;

#define DECLARE_MAIN(a)
int main(int argc, const char ** argv)
{
a *app = new a;
app->run(app);
delete app;
return 0;
}

#endif

把这个文件保存在 include 目录下,命名为 app.hpp,然后,把之前的 FirstStep.cpp 改成如下内容:

#include “…/include/app.hpp”

class MyApp : public App {
private:

public:
    void init(){

    }

    void display(){

    }

    ~MyApp(){

    }

};

DECLARE_MAIN(MyApp)

编译运行,结果是一样的。以后,只需要把初始化数据的代码放到 init() 方法中,把渲染图形的代码放到 display() 方法中即可。程序运行时,init() 方法只调用一次,而 display() 方法每渲染一帧图像就调用一次。

OK,到这里,我们的环境就搭建好了。在下一篇随笔中,我们争取使用 OpenGL 渲染一点有用的东西。

Logo

更多推荐