为什么说使用 Linux 系统学习 OpenGL 更方便
前言
上一篇随笔介绍了我的电脑,同时也介绍了 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 = 1920和SCR_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 更方便的更多相关文章
- Linux系统学习笔记:文件I/O
Linux支持C语言中的标准I/O函数,同时它还提供了一套SUS标准的I/O库函数.和标准I/O不同,UNIX的I/O函数是不带缓冲的,即每个读写都调用内核中的一个系统调用.本篇总结UNIX的I/O并 ...
- Linux系统学习优缺点
Linux是一套操作系统,按照鸟哥的说法Linux提供了一个完整的操作系统当中最底层的硬件控制与资源管理的完整架构,这个架构是沿袭Unix良好的传统而来的,功能强大而且稳定性卓越.其实Torvalds ...
- 谈谈我对Linux系统学习的历程回顾
众所周知,Windows 和Linux 是目前最流行的2个操作系统.Windows系统适合普通用户,它的优势是图形化界面,简单易用,使用起来门槛很低,很容易上手,所以,windows占有了大多数普 ...
- 说一说本人对linux系统学习的方法和经验
摘要: 相信大伙都听说过linux系统,然而对于这个系统,总使让新手感觉茫然,诺达的系统.下面是一段百度中的介绍: 相信大伙都听说过linux系统,然而对于这个系统,总使让新手感觉茫然,诺达的系统.下 ...
- Linux系统学习笔记(1)
学习地址:http://www.runoob.com/linux/linux-tutorial.html 1.学习Windows和Linux哪个比较难? 前期是Windows容易学习,后期是Linux ...
- 网工的Linux系统学习历程
偶遇篇作为一名通过思科CCNP认证的网络工程师,专注于网络技术.但在日常的工作中,难免不接触到服务器,对于大多数服务器来说,鉴于稳定性等因素的考虑,基本使用的都是Linux系统,包括RHEL.Cent ...
- 老司机浅谈linux系统学习技巧
Linux起源于20世纪70年代,是一种优秀的操作系统系统.初次接触到linux这个系统是在大学期间,这样才发现除了windows外的另外一个有趣系统.开始抱着好奇的心态去了解,随着深入学习,笔者被它 ...
- Linux 系统学习梳理_【All】
第一部分---基础学习 00.Linux操作系统各版本ISO镜像下载 00.Linux系统下安装Vmware(虚拟机) 00.Linux 系统安装[Redhat] 00.Linux 系统安装[Cent ...
- Linux系统学习之 一:新手必须掌握的Linux命令1
2018-10-03 16:04:12 一.常用系统工作命令 1.wget 命令 作用:用于在终端中下载网络文件. 格式:wget [参数] 下载地址 参数及作用: -b : 后台下载模式 -d:显示 ...
随机推荐
- win10下简单截图
win10 下面可以 win+shift+s 拖动截图,个人感觉是最简单的
- Elasticsearch查询文档总数
前言 在使用ES搜索的时候,或多或少都会面临查询数据总量的情况,下面介绍三种查询数据总量的方式. 其中,方案二解决了当结果数据总量超过1w时,由于ES默认设置(max_result_window:10 ...
- 不止Docker:8款容器管理开源方案
Docker诞生于2013年,并普及了容器的概念,以至于大多数人仍然将容器的概念等同于"Docker容器". 作为第一个吃螃蟹的人,Docker设置了新加入者必须遵守的标准.例如, ...
- ESCMScript(2)Module语法
严格模式 ES6 的模块自动采用严格模式,不管你有没有在模块头部加上"use strict";. 严格模式的限制如下 变量必须声明后再使用 函数的参数不能有同名属性,否则报错 不能 ...
- 13.7Cloneable接口
要点提示:Cloneable接口给出了一个可克隆对象.
- 计算机、程序和java简介
内存 计算机的内存是由一个有序的字节序列组成,用于存储程序及程序需要的数据.你可以将内存想象成计算机执行程序的工作区域.一个程序和它的数据在被CPU执行前必须移到计算机的内存中. 每个字节都是有一个唯 ...
- MySQL服务器 IO 100%的分析与优化方案
前言 压力测试过程中,如果因为资源使用瓶颈等问题引发最直接性能问题是业务交易响应时间偏大,TPS逐渐降低等.而问题定位分析通常情况下,最优先排查的是监控服务器资源利用率,例如先用TOP 或者nmon等 ...
- c盘爆满清理解决方案----Dism
前言:在以前windons操作系统,很容易导致c盘爆满,原因了就那么几个,升级,app默认安装,打补丁等等.还有种蛇皮现象,就是无缘无故c盘就标红了,进去看看,又个c盘的系统文件,不敢删了,怕系统就崩 ...
- SqlServer常用语句整理
先记录下来 以后整理 1.常用语句 1.1update连表更新 update a set a.YCaseNo = a.WordName + '['+ convert(varchar,a.CaseYea ...
- WSL中使用systemctl报错问题
Windows10里面自带的wsl中安装docker后不支持systemctl命令.需要更换命令,用Sysvinit的命令代替systemd,命令如下: Systemd command Sysvini ...