理解OpenGL渲染管线

理解渲染管线

之前我们简单提到了固定渲染管线和可编程渲染管线,他们有共同特点:渲染管线,那什么是渲染管线?

Contex为我们提供OpenGL的运行环境,而具体的操作则是在OpenGL的渲染管线中进行的。这里的渲染管线是一次完整的图形图像渲染过程 ,OpenGL1.0对应的渲染管线是固定渲染管线。意味着开发者只能做一些简单操作,后面OpenGL2.0之后渲染管线升级为可编程渲染管线。其中可编程的部分是顶点着色器(Vertex Shader)和片段着色器(Fragament Shader)。

我们从头一个一个理解:

  1. 创建填充顶点数组(所要绘制图形的坐标信息)然后OpenGL传递到该渲染管线的顶点着色器中,将坐标信息转换为OpenGL的内部坐标信息。
  2. OpenGL有了图形的坐标信息后就通过图元组装描绘出基本的图形。
  3. 通过光栅化将线性的图形映射到屏幕一个个像素(Pixel)上。
  4. 通过片段着色器给每个像素(Pixel)赋予颜色值。
  5. 最后将图像传递到帧缓冲(Framebuffer)中提供给屏幕进行刷新操作。

OpenGL在渲染一个画面的大体流程,绿色是我们可编程部分。

1. 顶点着色器(Vetex Shader)

负责坐标和图形的描述。在OpenGL中有三种基本的图形点、线、三角形,只能通过这三种基本图形去描述一个图形。其中在OpenGL中我们的显示区域位于x,y均为[-1,1]之内的空间。

  • :点存在于三维空间,坐标用(x,y,z)表示。
  • 线:由两个三维空间中的点组成。
  • 三角形:由三个三维空间的点组成。

如图,我们可以通过点、线、三角形创建出一个简单的3D模型。

2. 图元装配

负责将顶点着色器输出的坐标信息进行组装和裁剪,将所有3D的图元转化为屏幕上2D的图元。

具体的图元装配代码示例参考:图元装配和光栅化

3. 光栅化

图元装配后,将坐标数据裁剪映射为窗口上的像素数据,但是要转换为图像还需要颜色信息。在使用光栅化后基本图元被转换为供片段着色器使用的片段(Fragment),即实现通过插值运算将连续的值用一个个像素片段表示出来。

4. 片段着色器(Fragament Shader)

到了这一步我们已经有了一个个的像素片段(Fragament),我们在这个阶段给它涂上颜色值就可以变成一个完整的像素点。包括位置,颜色,纹理坐标等信息。同时我们可以编写Fragament Shader的脚本来实现对每个像素颜色的变换来达到一些效果,如纹理贴图,光照,环境光,阴影。

5. 片段测试

这个阶段是对每个像素点进行测试保证这些像素点是正确可用的。最后在输入到帧缓冲(Frambuffer)中。

6. 帧缓存 (Framebuffer)

经过上述处理流程,我们想要看到的图形图像数据最后都会存储到帧缓存区(Framebuffer) 中。我们可以同时存在很多帧缓存(Framebuffer),并且可以通过OpenGL让GPU把渲染结果存储到任意数量的帧缓存中(这里引申出一个离屏渲染的工作概念)。

但是,只有将内容绘制到视窗体提供的帧缓存(Renderbuffer) 中,才能将内容输出到显示设备。在实现上渲染缓存(Renderbuffer)是直接跟屏幕映射的,可以绕开CPU进行工作。

7. 渲染帧缓存(Renderbuffer)

基本工作原理是存在两个缓存(前缓存和后缓存),当屏幕的刷新同步信号到达时让系统将后缓存交换到前缓存区上。

这个刷新的时间是由系统决定的,比如屏幕刷新率是60fps即每16.75ms会发生一次前后缓存的交换。我们只需要准备好后缓存的数据提供给系统就能进行屏幕刷新渲染了。


总结:

理解OpenGL渲染管线,就是理解渲染流程,OpenGL是如何将一堆顶点数据,纹理数据,经过裁剪-透视变换-视觉变换,生成像素数据,最后绘制在屏幕上。

以上只是理论基础,我们在后续中进行实际开发,更加深入理解OpenGL。

相关推荐
怀澈12211 分钟前
高性能服务器模型之Reactor(单线程版本)
linux·服务器·网络·c++
chnming198734 分钟前
STL关联式容器之set
开发语言·c++
威桑1 小时前
MinGW 与 MSVC 的区别与联系及相关特性分析
c++·mingw·msvc
熬夜学编程的小王1 小时前
【C++篇】深度解析 C++ List 容器:底层设计与实现揭秘
开发语言·数据结构·c++·stl·list
yigan_Eins1 小时前
【数论】莫比乌斯函数及其反演
c++·经验分享·算法
Mr.131 小时前
什么是 C++ 中的初始化列表?它的作用是什么?初始化列表和在构造函数体内赋值有什么区别?
开发语言·c++
阿史大杯茶1 小时前
AtCoder Beginner Contest 381(ABCDEF 题)视频讲解
数据结构·c++·算法
C++忠实粉丝1 小时前
计算机网络socket编程(3)_UDP网络编程实现简单聊天室
linux·网络·c++·网络协议·计算机网络·udp
我们的五年2 小时前
【Linux课程学习】:进程描述---PCB(Process Control Block)
linux·运维·c++
程序猿阿伟2 小时前
《C++ 实现区块链:区块时间戳的存储与验证机制解析》
开发语言·c++·区块链