头文件
opengl一般用到的头文件:
|
|
其中,glm 为转为opengl设计的矩阵运算库, glad 用于加载函数指针, GLFW 用于获得窗口。
头文件的引用的先后顺序是很讲究的,`glad` 必须 先于 `glfw` 导入!
工程上不使用 using namespace std; 命名空间,输出日志使用 std::cout
创建窗口
需要头文件 glfw3.h
|
|
-
初始化 glfw
glfwInit():初始化,返回0表示正常 -
创建窗口
glfwCreateWindow():创建窗口,接收窗口的长和宽,返回指向窗口对象的 指针。1GLFWwindow *window = glfwCreateWindow(1280, 720, "GED", nullptr, nullptr); -
设置窗口位置
glfwSetWindowPos():设置窗口出现在电脑屏幕的何处,视具体电脑而异。1glfwSetWindowPos(window, 1000, 150)
这一步最重要的是获得窗口对象的指针。之后要设置和操作这个窗口,就要传入指针。
初始化OPENGL
OPENGL的驱动一般包含在各个显卡的驱动中,不用额外下载。除非你电脑刚买或者完全不联网不玩游戏
需要一个库来获得OPENGL的函数指针,常用glad。
包含头文件 glad.h
|
|
-
确定opengl版本
这一步是对整个glfw操作,所以要在初始化glfw之后,
创建window之前。glfwWindowHint:多重载函数,接收不同的命令设置不同的参数。1 2 3glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // opengl大版本 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // opengl小版本 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); -
与window关联
glfwMakeContextCurrent:将设置的OPENGL信息与window关联。1glfwMakeContextCurrent(window); -
使用glad加载函数指针
gladLoadGLLoader():返回值应为0。1gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)
颜色
OPENGL有四个颜色通道:
- Red:红
- Green:绿
- Blue:蓝
- Alpha:透明度
传值可以用RGB,取值范围: $[0,255]$ ;也可以是将其归一化后的浮点数,取整范围 $[0.0,1.0]$
旧版本一些函数不支持整数类型,因此必须使用归一化后的浮点数。可自定义归一化函数,方便传入RGB常规色值。
-
设置window背景颜色
glClearColor():接收red、green、blue、alpha四个值。1glClearColor(1.0f, 0.5f, 0.7f, 0.2f); -
让设置生效
glClear():从颜色缓存里加载。1glClear(GL_COLOR_BUFFER_BIT);
上面的设置背景实际上不会生效,因为opengl使用双缓冲方案。
交换双缓冲
opengl使用双缓冲方案,在每生成下一帧时实际操作的是后缓冲区,要把后缓冲区交换成当前缓冲区。
交换缓冲的函数:
|
|
顶点
把所有顶点的三维坐标放在一个数组里。
|
|
上面的每个顶点只包含了 xyz的值,实际上可以是 “空间坐标+纹理坐标”,“空间坐标加法线”等。
数组是一维的,每个坐标都在 $[-1.0, 1.0]$。
VBO & VAO
一个常见的说法来理解 VBO/VAO是:VBO是顶点数据的快递箱,负责打包数据,运送至显存;VAO则是附在上面的说明书,告诉显卡如何解包这些顶点。
VBO & VAO 都是opengl对象,它们构建了cpu与gpu沟通的桥梁。
- 申请 VBO 和 VAO :
|
|
-
绑定 VAO
VAO 和 VBO 应当是捆绑在一起的。opengl是一个状态机,当我们执行某一条命令后,之后的操作默认与之绑定,直到解绑为止。
|
|
执行这条命令后,后面的操作与VAO绑定了,即便不是,也应当绑定。
- 把顶点数组复制到缓冲中
|
|
- 设置顶点属性指针
告诉 OpenGL 如何解析这些数据。 参数:属性位置(0), 组成元素个数(3), 类型, 是否标准化, 步长, 偏移量
|
|
- 解绑
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0); // 绑定结束
glBindVertexArray(0) 重新设置为0, 这一轮的VAO绑定结束了。
顶点着色器
着色器语言GLSL:
|
|
创建着色器对象:
|
|
把源码字符串附加给着色器对象:
|
|
检测是否编译成功:
|
|
片段着色器
片段着色器决定了像素最终显示的颜色。
抗锯齿发生在这一阶段。
GLSL:
|
|
|
|
着色器程序
创建了上面两个着色器对象之后,还需要着色器程序对象组装多个着色器对象。
创建着色器程序对象:
|
|
将之前的着色器对象附加到程序对象,然后链接:
|
|
检查:
|
|
激活程序对象:
|
|
删除着色器对象:
|
|
帧循环
要在 while 循环里生成 每一帧 画面。基本步骤是:
-
接收键盘等输入,执行逻辑
-
清除颜色缓冲、深度缓冲
-
激活着色器程序
-
绑定对应VAO
-
确定 uniform 变量
-
绘制
-
交换缓冲区