1.什么是OpenGL ES?
OpenGL ES 是一个为便携或嵌入式设备例如:移动电话、PDAs、监视器等,发展的3D绘图APIs(应用编程接口)。
在桌面设备中有两个3D API接口,DirectX和OpenGL。DirectX是运行Window系统平台上的3D标准,在3D游戏平台中主要的标准。OpenGL是一个跨平台的3D API标准 ,能够运行在linux系统,各种UNIX系统,MacOS X和Wicrosoft系统等等。它是广泛接受的3D API。
因为OpenGL作为3D API的广泛使用,这是很自然的从桌面的OpenGL开始发展为手持设备和便携式开放标准的3D API;又因为使用OpenGL ES的设备地址空间和内存的限制,低的内存带宽,敏感的电源功耗,缺乏浮点运算硬件,所以修改它以适用与手持和便携设备领域。
OpenGL ES API是巨大的和复杂的,工作组的目标是建立一个适合设备驱动程序。例如:一个几何体,OpenGL中可以使用立即模式、显示列表、顶点矩阵,而在OpenGL ES中只能使用顶点矩阵。
OpenGL ES被设计成OpenGL的嵌入式子集,OpenGL也能运行 OpenGL ES的程序。原因是作为一个子集能够更好应用桌面程序的代码和工具。
手持和便携设备的限制被引入,例如减少电力消耗,减少着色器性能,渲染质量被引入着色器语言。
OpenGL ES的设计者,目标是确保最小的图像质量,但做到最好。
OpenGL ES 2.0来自OpenGL 2.0 API,确保了对游戏的支持
先对OpenGL ES 2.0的管线做一个介绍:
OpenGL ES 2.0包含两个部分:
- OpenGL ES 2.0 API说明
- OpenGL ES着色器语言说明
图像管线如下:
上图着色器盒子描述了OpenGL ES 2.0管道可编程阶段。
1.顶点着色器
顶点着色器的一般编程方法:
- 属性——顶点矩阵支持的Per_vertex数据
- Uniforms——顶点着色器使用的常量数据
- Samplers——被Uniforms使用的特殊类型,在顶点着色器的贴图中使用,是可选项
- 着色器编程——顶点着色器编程源码或可执行的部分
顶点着色器的输出叫做varying变量,在最初的光栅化阶段,这些变量被计算,作为片段着色器的输入,从顶点着色器的矩阵使用插补的方法产生片段着色器的变量,下图展示了输入和输出:
下面代码显示使用OpenGL ES编程语言编写顶点着色器,现在大致知道即可,顶点着色器需要一个位置和颜色数据作为输入属性,输入位置数据是4*4的矩阵,输出是变换后的位置和颜色。
一个顶点着色器例子
uniform mat4 u_mvpMatrix;
attribute vec4 a_position;
attribute vec4 a_color;
varying vec4 v_color;
void main()
{
v_color = a_color;
gl_Position = u_mvpMatrix * a_position;
}
- 首先定义了一个uniform变量 u_mvpMatrix用来存储模型的关联试图和投射矩阵;
- 再定义输入顶点矩阵和顶点属性;
- 定义顶点着色器输出变量是per_vertex 编译时
- gl_Position被编译器自动定义,片段着色器的唯一入口点是main函数;
- 读入顶点属性a_color 输出顶点颜色v_color 变换后的矩阵位置输出到gl_Position
基元装配
基元是能够被OpenGL ES绘制的几何物体,这些绘图命令描述了一个顶点属性和基元几何体及基元类型的几何。
顶点属性包括计算位置,颜色和贴图坐标的信息,他们将被输入到片段着色器中。
顶点着色求能绘制的几何图元包括三角形、直线、点,必须判断图元是否位于投影平截体内,如果不在,将被视图平截体剪贴 ,如果完全在之外,将被丢弃,定点位置转变为屏幕坐标,依据图元位于正面还是背面,剪切和剔除后,图元进入光栅化阶段。
光栅化
光栅化是转换图元为二维片段的过程,被片段着色器执行,二维的片段能够被绘制在屏幕上。
片段着色器
片段着色器使用以下输入,执行光栅化后形成片段。 - Varying变量——光栅化阶段使用插补技术为片段着色器产生,顶点着色器的输出
- Uniforms——常量数据
- Samplers——Uniforms中特殊的类型,在贴图时使用
- 着色器程序——片段着色器编程源码或可执行的部分
片段着色器的结构如下:
片段着色器也能丢弃片段或者产生一些颜色值像gl_FragColor,光栅化阶段产生的颜色、深度、模板、屏幕坐标(Xw,Yw)变成OpenGLES 2.0管线输入。
下面是一个片段着色器的例子,绘制一个三角形:
precision mediump float;
varying vec4 v_color;
void main(void)
{
gl_FragColor=v_color;
}
第一句设定显示质量,第二句描述片段着色器输入,之后是主函数。
片段着色器不需要定义输出,这是因为片段着色器仅仅输出是gl_FragColor,最后设定片段着色器的输入是v_color
Per-fragment操作
- 像素所有权测试——这个测试决定在帧缓冲区中某点(Xw,Yw)的像素当前是否被OpenGL ES所有,可以准许视窗操作系统去 控制帧缓冲区中的像素是否是OpenGL ES的内容,例如:视窗检测到OpenGL ES的帧缓冲区被另一个窗口遮挡,视窗系统可以决定遮挡OpenGL ES的内容,不显示。
- 剪切测试——测试(Xw,Yw)是否在剪切矩形内,如果在矩形外,片段被丢弃。
- 模板深度测试——决定输入的片段是否应该被拒绝
- 混合——混合新产生的片段颜色和存储在颜色缓冲区中的颜色
- 抖动——被使用在用几种颜色的组合模拟出大范围内的多种色彩模式
per-fragment阶段最后,片段颜色、深度值、模板值是否被写入帧缓冲区还要依靠各自的掩码位能否被使用,例如,颜色缓冲区能设定红色是否能被写入颜色缓冲区。
OpenGL ES 2.0支持缓冲区数据读回功能,但仅仅颜色缓冲区像素能够读回,深度和模板缓冲区数据不能读回。