01-初识OpenGL ES

OpenGL ES 3.0

OpenGL ES是OpenGL的简化版本,它消除了冗余功能,提供了⼀个既易于学习又更易于在移动图形硬件中实现的库。

OpenGL ES 3.0实现了具有可编程着色功能的图形管线,由两个规范组成:OpenGL ES 3.0 API规范和OpenGL ES着色语言3.0规范(OpenGL ES SL)。下图展示OpenGL ES 3.0图形管线。图中带有黄色背景填充的方框表示OpenGL ES 3.0中管线的可编程阶段。

1276164-e0b96d0cfc3d088c.jpg
OpenGL ES 3.0 图形管线

1. 顶点着色器

顶点着色器实现了顶点操作的通用可编程方法。
顶点着色器的输入包括:

  • 着色器程序--描述顶点上执行操作的顶点着色器程序源代码或者可执行文件。
  • 顶点着色器输入(或者属性)--用顶点数组提供的每个顶点的数据。
  • 统一变量(uniform)--顶点(或者片段)着色器使用的不变数据。
    采样器--代表顶点着色器使用纹理的特殊统一变量类型。

顶点着色器的输出变量,在图元光栅化阶段,为每个生成的片段计算顶点计算顶点着色器输出值,并作为输入传递给片段着色器。用于从分配给每个图元顶点的顶点着色器输出生成每个片段值的机制称作插值

变换反馈:使顶点着色器输出可以选择性地写入一个输出缓冲区(除了传递给片段着色器之外,也可以代替这种传递)

1276164-5ab100b48fae1fbb.jpg
OpenGL ES 3.0 顶点着色器.jpg

顶点着色器可以用于通过矩阵变换位置、计算照明公式来生成逐顶点颜色以及生成或者变换纹理坐标等基于顶点的传统操作。此外,因为顶点着色器由应用程序规定,所以它可以用于执行自定义计算,实施新的变换、照明或者较传统的固定功能管线所不允许的基于顶点的效果。

2. 图元装配

顶点着色器之后,OpenGLES 3.0图形管线的下一阶段是图元装配。图元(Primitive)是 三角形、直线或者点精灵等几何对象。图元的每个顶点被发送到顶点着色器的不同拷贝。在 图元装配期间,这些顶点被组合成图元。

对于每个图元,如果图元没有完全在视锥体内(屏幕上可见的3D空间区域),则可能需要进行裁剪。之后,图元便准备传递给管线的下一阶段——光栅化阶段。

3. 光栅化

在此阶段绘制对应的图元(点精灵、直线或者三角形)。光栅化是将图元转化为一组二维片段的过程,然后,这些片段由片段着色器处理。这些二维片段代表着可在屏幕上绘制的像素。

1276164-80b475e6485dc8f3.jpg
OpenGL ES 3.0光栅化阶段.jpg

4. 片段着色器

片段着色器为片段上的操作实现了通用的可编程方法。如下图所示,对光栅化阶段生成的每个片段执行这个着色器,采用如下输人:

  • 着色器程序--描述片段上所执行操作的片段着色器程序源代码或者可执行文件。
  • 输人变置--光栅化单元用插值为每个片段生成的顶点着色器输出。
  • 统一变量--片段(或者顶点)着色器使用的不变数据。
  • 采样器--代表片段着色器所用纹理的特殊统一变量类型。
1276164-2c066963fa704bdd.jpg
OpenGL ES 3.0 片段着色器.jpg

片段着色器可以抛弃片段,也可以生成一个或者多个顔色值作为输出。一般来说,除了渲染到多重涫染目标之外,片段着色器只输出一个顔色值;
在多重渲染目标的情况下,为每个渲染目标输出一个顔色值。光栅化阶段生成的顔色、深度、模板和屏幕坐标位置(x,y)变成OpenGL ES 3.0 管线逐片段操作阶段的输人。

5. 逐片段操作

在片段着色器之后,下一阶段是逐片段操作。光栅化生成的屏幕坐标为(x, y)的片段只能修改帧缓冲区中位置为(x, y)的像素。

1276164-4dde13ad8ad4fed8.jpg
OpenGL ES 3.0 逐片段操作阶段.jpg

在逐片段操作阶段,在每个片段上执行如下功能(和测试)如上图所示:

  • 像素归属测试--这个测试确定帧缓冲区中位置(x, y)的像索目前是不是归 OpenGL ES所有。
    例如,如果一个显示OpenGL ES帧缓冲区窗口的窗口被另一个 窗口所遮蔽,则窗口系统可以确定被遮蔽的像素不属于OpenGL ES上下文,从而完全不显示这些像素。虽然像素归属测试是OpenGL ES的一部分,但是它不由开发人员控制,而是在OpenGL ES内部进行
  • 裁剪测试--裁剪测试确定(x, y)是否位于作为OpenGL ES状态的一部分的裁剪矩形范围内。如果该片段位于裁剪区域之外,则被抛弃。
  • 模板和深度测试--这些测试在输人片段的模板和深度值上进行,以确定片段是否应该被拒绝。
  • 混合--混合将新生成的片段顔色值与保存在帧缓冲区(x,y)位置的颜色值组合起来。

缓存:提供数据的最好方式

OpenGL ES为两个内存区域的数据交换定义了缓存(buffers)的概念。缓存是指图形处理器能够控制和管理的连续RAM。程序从CPU的内存复制数据到OpenGL ES的缓存。为缓存提供数据有如下7个步骤。
(1) 生成(Generate)--- 请求OpenGL ES为图形处理器控制的缓存生成一个独一无二的标识符。
(2)绑定(Bind)--- 告诉OpenGL ES为接下来的运算使用一个缓存。
(3)缓存数据(Buffer Data)--- 让OpenGL ES为当前绑定的缓存分配并初始化足够的连续内存(通常是从CPU控制的内存复制数据到分配的内存)。
(4)启用(Enable)或禁止(Disable)--- 告诉OpenGL ES在接下来的渲染中是否使用缓存中的数据。
(5)设置指针(Set Pointers)--- 告诉OpenGL ES早缓存中的数据的类型和所有需要访问的数据的内存偏移值。
(6)绘图(Draw)--- 告诉OpenGL ES使用当前绑定并启用的缓存中的数据渲染整个场景或者某个场景的一部分。
(7)删除(Delete)---告诉OpenGL ES删除以前生成的缓存并释放相关的资源。

OpenGL ES为一种类型的缓存在使用过程中的每一个步骤的执行定义了下面的C语言函数,同时为其他类型的缓存提供了类似的函数。

(1)glGenBuffers()--- 请求OpenGL ES为图形处理器控制的缓存生成一个独一无二的标识符。
(2)glBindBuffer()--- 告诉OpenGL ES为接下来的运算使用一个缓存。
(3)glBufferData() 或者 glBufferSubData()--- 让OpenGL ES为当前绑定的缓存分配并初始化足够的连续内存(通常是从CPU控制的内存复制数据到分配的内存)。
(4)glEnableVertexAttribArray()glDisableVertexAttribArray()--- 告诉OpenGL ES在接下来的渲染中是否使用缓存中的数据。
(5)glVertexAttribPointer()--- 告诉OpenGL ES早缓存中的数据的类型和所有需要访问的数据的内存偏移值。
(6)glDrawArrays()glDrawElements()--- 告诉OpenGL ES使用当前绑定并启用的缓存中的数据渲染整个场景或者某个场景的一部分。
(7)glDeleteBuffers()---告诉OpenGL ES删除以前生成的缓存并释放相关的资源。

转载于:https://www.jianshu.com/p/d5cffd5d9479

猜你喜欢

转载自blog.csdn.net/weixin_34133829/article/details/91161643