OpenGL渲染
双缓冲,循环渲染,管线
本章全部内容都来自于LearnOpenGL CN
循环渲染
让程序在我们主动关闭它之前不断绘制图像并能够接受用户输入。
1 |
|
glfwWindowShouldClose
函数在我们每次循环的开始前检查一次GLFW
是否被要求退出,如果是的话,该函数返回true,渲染循环将停止运行,之后我们就可以关闭应用程序。glfwSwapBuffers
函数会交换颜色缓冲(它是一个储存着GLFW
窗口每一个像素颜色值的大缓冲),它在这一迭代中被用来绘制,并且将会作为输出显示在屏幕上。glfwPollEvents
函数检查有没有触发什么事件(比如键盘输入、鼠标移动等)、更新窗口状态,并调用对应的回调函数(可以通过回调方法手动设置)。
双缓冲
- 应用程序使用单缓冲绘图时可能会存在图像闪烁的问题。 这是因为生成的图像不是一下子被绘制出来的,而是按照从左到右,由上而下逐像素地绘制而成的。最终图像不是在瞬间显示给用户,而是通过一步一步生成的,这会导致渲染的结果很不真实。为了规避这些问题,我们应用双缓冲渲染窗口应用程序。前缓冲保存着最终输出的图像,它会在屏幕上显示;而所有的的渲染指令都会在后缓冲上绘制。当所有的渲染指令执行完毕后,我们交换(Swap)前缓冲和后缓冲,这样图像就立即呈显出来,之前提到的不真实感就消除了。
管线
3D坐标转为2D坐标的处理过程是由
OpenGL
的图形渲染管线(Graphics Pipeline,大多译为管线,实际上指的是一堆原始图形数据途经一个输送管道,期间经过各种变化处理最终出现在屏幕的过程)管理的。- 第一部第二部分是把2D坐标转变为实际的有颜色的像素。
- 第二部分是把2D坐标转变为实际的有颜色的像素。
图形渲染管线接受一组3D坐标,然后把它们转变为你屏幕上的有色2D像素输出。图形渲染管线可以被划分为几个阶段,每个阶段将会把前一个阶段的输出作为输入。当今大多数显卡都有成千上万的小处理核心,它们在GPU上为每一个(渲染管线)阶段运行各自的小程序,从而在图形渲染管线中快速处理你的数据。这些小程序叫做着色器(Shader)。OpenGL着色器是用OpenGL着色器语言(OpenGL Shading Language, GLSL)写成的。
图形渲染的阶段
1. 顶点着色器(Vertex Shader)
渲染管线的第一阶段。
输入:单个顶点(包含位置、颜色、纹理坐标等属性)。
主要功能:
- 将 3D 模型空间坐标 转换为 裁剪空间坐标(后续将解释)。
- 对顶点属性进行基本处理(如变换、光照等)。
2. 几何着色器(Geometry Shader)(可选)
输入:一个完整图元(如一个三角形的 3 个顶点)。
功能:
- 可对图元进行进一步处理,例如生成更多顶点或其他图元。
- 可用于动态生成形状或实现特效。
示例:在一个三角形基础上生成另一个对称三角形。
3. 图元装配(Primitive Assembly)
- 输入:来自顶点着色器或几何着色器的所有顶点。
- 功能:根据指定的图元类型(如
GL_TRIANGLES
)将顶点组装为完整图元。 - 示例:将 6 个顶点组装为两个三角形。
4. 光栅化阶段(Rasterization)
功能:
- 将图元转换为片段(Fragment),即屏幕上的像素候选。
- 每个片段对应屏幕上的一个像素区域,并包含颜色、深度、纹理坐标等信息。
裁剪(Clipping):
- 在此阶段之前进行。
- 会丢弃超出视图范围的图元部分,以提高性能。
5. 片段着色器(Fragment Shader)
输入:每个片段的属性(如颜色、纹理坐标、法线等)。
功能:
- 计算每个片段的最终颜色。
- 可进行纹理映射、光照计算、阴影效果等。
片段(Fragment)是什么?
在 OpenGL 中,一个片段是用于生成一个最终像素所需的所有数据集合。
注意:片段 ≠ 像素。一个片段可能不会最终变成一个像素(例如被深度测试或模板测试丢弃)。
6. Alpha 测试与混合阶段(Blending)
作用:决定是否保留某个片段,以及如何将其颜色与已有像素进行混合。
包含两个关键处理:
深度测试(Depth Test)与模板测试(Stencil Test):
- 判断该片段是否在其他片段前面或后面。如果在后面,通常会被丢弃,以避免遮挡前面的物体。
Alpha 测试与混合(Alpha Blending):
- 根据片段颜色中的 alpha 值(透明度)决定像素的透明程度。与已有像素的颜色进行颜色混合,以实现半透明、玻璃等视觉效果。
图元
OpenGL 中的图元(Primitive)
OpenGL 仅知道你传入的是一组坐标和颜色等数据,但它不知道你希望这些数据如何组成图形。因此,你需要告诉 OpenGL:这些数据代表什么图形类型。
这些图形类型就叫做 图元(Primitive)。图元定义了 OpenGL 如何解释顶点数据,例如是绘制点、线,还是三角形。
常见图元类型:
图元名称 | 说明 |
---|---|
GL_POINTS |
每个顶点作为一个单独的点渲染 |
GL_LINE_STRIP |
顶点之间依次连接形成折线 |
GL_TRIANGLES |
每三个顶点组成一个三角形 |
图元的作用:
每次你调用绘制函数(如 glDrawArrays
或 glDrawElements
)时,都会指定一个图元类型。OpenGL 会按照你提供的图元类型来解释和绘制顶点数据。