前言

上一篇随笔介绍了我的电脑,同时也介绍了 Ubuntu 20.10 系统的安装和美化。这一篇,我将正式开始 OpenGL 之旅。使用 Ubuntu 来进行开发,不仅仅只是因为我对 Linux 桌面比较熟悉,其实我对 Windows 也很熟悉,主要还是因为在 Linux 系统下搭建 OpenGL 的开发环境确实是太方便了。在 Windows 下开发 OpenGL,每用到一个库,我们都要单独去搜索和下载,然后在 Visual Studio 中进行设置,很繁琐。在 Ubuntu 中,安装这些库,就是一条命令的事,下面详细论述。

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

#ifndef __APP_HPP__
#define __APP_HPP__ #include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream> 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 渲染一点有用的东西。

版权申明

该随笔由京山游侠在2021年01月27日发布于博客园,引用请注明出处,转载或出版请联系博主。QQ邮箱:1841079@qq.com

为什么说使用 Linux 系统学习 OpenGL 更方便的更多相关文章

  1. Linux系统学习笔记:文件I/O

    Linux支持C语言中的标准I/O函数,同时它还提供了一套SUS标准的I/O库函数.和标准I/O不同,UNIX的I/O函数是不带缓冲的,即每个读写都调用内核中的一个系统调用.本篇总结UNIX的I/O并 ...

  2. Linux系统学习优缺点

    Linux是一套操作系统,按照鸟哥的说法Linux提供了一个完整的操作系统当中最底层的硬件控制与资源管理的完整架构,这个架构是沿袭Unix良好的传统而来的,功能强大而且稳定性卓越.其实Torvalds ...

  3. 谈谈我对Linux系统学习的历程回顾

    ​​众所周知,Windows 和Linux 是目前最流行的2个操作系统.Windows系统适合普通用户,它的优势是图形化界面,简单易用,使用起来门槛很低,很容易上手,所以,windows占有了大多数普 ...

  4. 说一说本人对linux系统学习的方法和经验

    摘要: 相信大伙都听说过linux系统,然而对于这个系统,总使让新手感觉茫然,诺达的系统.下面是一段百度中的介绍: 相信大伙都听说过linux系统,然而对于这个系统,总使让新手感觉茫然,诺达的系统.下 ...

  5. Linux系统学习笔记(1)

    学习地址:http://www.runoob.com/linux/linux-tutorial.html 1.学习Windows和Linux哪个比较难? 前期是Windows容易学习,后期是Linux ...

  6. 网工的Linux系统学习历程

    偶遇篇作为一名通过思科CCNP认证的网络工程师,专注于网络技术.但在日常的工作中,难免不接触到服务器,对于大多数服务器来说,鉴于稳定性等因素的考虑,基本使用的都是Linux系统,包括RHEL.Cent ...

  7. 老司机浅谈linux系统学习技巧

    Linux起源于20世纪70年代,是一种优秀的操作系统系统.初次接触到linux这个系统是在大学期间,这样才发现除了windows外的另外一个有趣系统.开始抱着好奇的心态去了解,随着深入学习,笔者被它 ...

  8. Linux 系统学习梳理_【All】

    第一部分---基础学习 00.Linux操作系统各版本ISO镜像下载 00.Linux系统下安装Vmware(虚拟机) 00.Linux 系统安装[Redhat] 00.Linux 系统安装[Cent ...

  9. Linux系统学习之 一:新手必须掌握的Linux命令1

    2018-10-03 16:04:12 一.常用系统工作命令 1.wget 命令 作用:用于在终端中下载网络文件. 格式:wget [参数] 下载地址 参数及作用: -b : 后台下载模式 -d:显示 ...

随机推荐

  1. Linux 常用命令 随口说

    ls cd pwd du disk usage -h -s. 文件大小 df disk free -h 磁盘占用 fdisk mount top/htop + ps + grep + wc + pki ...

  2. 基于Ubuntu下以Docker方式gitlab软件的部署

    基于Ubuntu下以Docker方式gitlab软件的部署 目录 基于Ubuntu下以Docker方式gitlab软件的部署 1.安装Docker Compose 1.1 下载curl 1.2 安装c ...

  3. Qt:报文接收不完成,产生分帧的处理方法

    最近在设备的测试工装时,通过串口,向设备发送自定义规约,其报文的枕结构已经编写,使用串口助手调试,设备可正常回复,但是通过工装,接收报文会不完整,导致解析失败.使用qDebug打印出来却发现数据被分成 ...

  4. PyCharm 2020.1 激活教程

    本文内容皆为作者原创,如需转载,请注明出处:https://www.cnblogs.com/xuexianqi/p/14967434.html 免责声明:本方法只做学习研究之用,不得用于商业用途 若经 ...

  5. 线上BUG:MySQL死锁分析实战

    原文链接:线上BUG:MySQL死锁分析实战 1 线上告警 我们不需要关注截图中得其他信息,只要能看到打印得org.springframework.dao.DeadlockLoserDataAcces ...

  6. 乘风破浪,Windows11设计和开发指导,全新图标字体和云母材质

    Windows11全新的布局设计 Windows 11全新的布局设计已设计为支持现代应用体验.渐进的圆角.嵌套元素和一致的排水沟相结合,营造出柔和.平静.平易近人的效果,强调目的的统一和易用性. ht ...

  7. 14、WindowsServer修改NTP时间同步服务器

    1. 2. 3.

  8. 25、mysqlreport(my.cnf)调优工具

    25.1.mysqlreport介绍: mysqlreport以很友好的方式显示 MySQL状态变.事实上,它几乎报告了所有的状态.不像 SHOW STATUS 只是在显示 了100多个状态值,mys ...

  9. 删除有序数组中的重复项II

    题目描述 给你一个有序数组 nums ,请你原地删除重复出现的元素,使每个元素最多出现两次,返回删除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组 并在使用O(1)额外空间的条件下 ...

  10. MySql:mysql命令行导入导出sql文件

    命令行导入 方法一:未连接数据库时方法 #导入命令示例 mysql -h ip -u userName -p dbName < sqlFilePath (结尾没有分号) -h : 数据库所在的主 ...