关于OPenGL,对于初学者来说,没有一套完整的教程,摸索很久都是一头雾水。因为新工作是做相机维护,OpenGL是主角,所以打算写一系列入门级的教程,尽量是站在初学者的角度,大牛请出门右拐。
1、什么是OpenGL?
全称是:Open Graphics Library
简单说就是图形库
2、OpenGL ES
(OpenGL for Embedded Systems) 是 OpenGL 三维图形 API 的子集,针对手机、PDA和游戏主机等嵌入式设备而设计。
OpenGL ES相对于OpenGL来说,减少了许多不是必须的方法和数据类型,去掉了不必须的功能,对代价大的功能做了限制,比OpenGL更为轻量。在OpenGL ES的世界里,没有四边形、多边形,无论多复杂的图形都是由点、线和三角形组成的
3、介绍一下顶点着色器和片元着色器
先知道有这个东西就行,第二篇文章我们将结合demo使用。
3.1 着色器语言
仅适合GPU编程,对于顶点着色器和片元着色器的开发都需要用到着色器语言进行开发。
着色语言中有许多内建的原生数据类型以及构建数据类型,如:浮点型(float)、布尔型(bool)、整型(int)、矩阵型(matrix)以及向量型(vec2、vec3等)等。总体来说,这些数据类型可以分为标量、向量、矩阵、采样器、结构体以及数组等。 着色器支持下面数据类型
float bool int 基本数据类型
vec2 包含了2个浮点数的向量
vec3 包含了3个浮点数的向量
vec4 包含了4个浮点数的向量
ivec2 包含了2个整数的向量
ivec3 包含了3个整数的向量
ivec4 包含了4个整数的向量
bvec2 包含了2个布尔数的向量
bvec3 包含了3个布尔数的向量
bvec4 包含了4个布尔数的向量
mat2 2*2维矩阵
mat3 3*3维矩阵
mat4 4*4维矩阵
sampler1D 1D纹理采样器
sampler2D 2D纹理采样器
sampler3D 3D纹理采样器
3.2 顶点着色器 (Vertex Shader)
顶点着色器(Vertex Shader)是在GPU上运行的小程序。从名称可以看出,可通过处理它们来处理顶点。此程序使用OpenGL ES SL语言来编写。它是一个描述顶点或像素特性的简单程序。下面是顶点着色器示例代码
uniform mat4 uMVPMatrix; //应用程序传入顶点着色器的总变换矩阵
attribute vec4 aPosition; // 应用程序传入顶点着色器的顶点位置
attribute vec2 aTextureCoord; // 应用程序传入顶点着色器的顶点纹理坐标
attribute vec4 aColor // 应用程序传入顶点着色器的顶点颜色变量
varying vec4 vColor // 用于传递给片元着色器的顶点颜色数据
varying vec2 vTextureCoord; // 用于传递给片元着色器的顶点纹理数据
void main()
{
gl_Position = uMVPMatrix * aPosition; // 根据总变换矩阵计算此次绘制此顶点位置
vColor = aColor; // 将顶点颜色数据传入片元着色器
vTextureCoord = aTextureCoord; // 将接收的纹理坐标传递给片元着色器
}
(1)attribute变量(属性变量)只能用于顶点着色器中,不能用于片元着色器。 一般用该变量来表示一些顶点数据,如:顶点坐标、纹理坐标、颜色等。
(2)uniforms变量(一致变量)用来将数据值从应用程其序传递到顶点着色器或者片元着色器。 该变量有点类似C语言中的常量(const),即该变量的值不能被shader程序修改。一般用该变量表示变换矩阵、光照参数、纹理采样器等。
(3)varying变量(易变变量)是从顶点着色器传递到片元着色器的数据变量。顶点着色器可以使用易变变量来传递需要插值的颜色、法向量、纹理坐标等任意值。 在顶点与片元shader程序间传递数据是很容易的,一般在顶点shader中修改varying变量值,然后片元shader中使用该值,当然,该变量在顶点及片元这两段shader程序中声明必须是一致的 。例如:上面代码中应用程序中由顶点着色器传入片元着色器中的vColor变量。
(4)gl_Position 为内建变量,表示变换后点的空间位置。 顶点着色器从应用程序中获得原始的顶点位置数据,这些原始的顶点数据在顶点着色器中经过平移、旋转、缩放等数学变换后,生成新的顶点位置。新的顶点位置通过在顶点着色器中写入gl_Position传递到渲染管线的后继阶段继续处理。
3.3 片元着色器 (Fragment Shader)
片元着色器计算每个像素的颜色和其它属性。它通过应用光照值、凹凸贴图,阴影,镜面高光,半透明等处理来计算像素的颜色并输出。它也可改变像素的深度(z-buffering)或在多个渲染目标被激活的状态下输出多种颜色。一个片元着色器不能产生复杂的效果,因为它只在一个像素上进行操作,而不知道场景的几何形状。下面是片元着色器简单实例代码。
precision mediump float; // 设置工作精度
varying vec4 vColor; // 接收从顶点着色器过来的顶点颜色数据
varying vec2 vTextureCoord; // 接收从顶点着色器过来的纹理坐标
uniform sampler2D sTexture; // 纹理采样器,代表一幅纹理
void main()
{
gl_FragColor = texture2D(sTexture, vTextureCoord) * vColor;// 进行纹理采样
}
此片元着色器的主要功能为根据接收的记录片元纹理坐标的易变变量中的纹理坐标,调用texture2D内建函数从采样器中进行纹理采样,得到此片元的颜色值。最后,将采样到的颜色值传给gl_FragColor内建变量,完成片元的着色
varying 指的是从顶点着色器传递到片元着色器的数据变量
gl_FragColor 为内置变量,用来保存片元着色器计算完成的片元颜色值,此颜色值将送入渲染管线的后继阶段进行处理。
3.4 编译和链接
着色器需要编译,然后链接到OpenGL程序中,一个OpenGL程序就是一个顶点着色器和一个片元着色器链接在一起变成单个对象。
着色器经过编译后链接成一个program,对于CPU来说,两个着色器是一体的,输入有Attribute、Unifroms和采样器(纹理/Textures),输出就是Framebuff,但这里我们关注一下gl_Position(位置)和gl_fragColor(颜色),因为这两个是两个着色器的主要输出(在什么位置显示什么颜色)。
Attribute:顶点属性,也就是存储顶点的坐标信息(对于着色器只读)
Unifroms:常量,一般存放矩阵变换或者光照之类(对于着色器只读)
Varying:顶点着色器和片元着色器间的通信接口变量,在顶点着色器中写入值(如颜色、纹理坐标等)在片元着色器中读出(对于片元着色器只读)
gl_Position、gl_PointSize、gl_FrontFacing、gl_FragColor、gl_FragCoord、gl_FrontFacing和gl_PointCoord:这些都是着色器内置的特殊变量,编译器已经定义好的,用到的时候再详细说明
4、坐标系
OpenGL的坐标系比较特殊,屏幕中间为原点,横x轴(左-1右1),竖y轴(上1下-1),垂直屏幕为z轴。
5、 OpenGL ES2.0 绘制过程
- 读取顶点数据
- 执行顶点着色器
- 组装图元
- 光栅化图元
- 执行片元着色器
- 写入帧缓冲区
- 显示到屏幕
OpenGL 作为本地库字节运行在硬件上,在java层定义的图像数据需要被OpenGL存取,需要把内存从java堆复制到本地堆
顶点着色器是针对每个顶点都会执行的程序,是确定每个顶点的位置。同理,片元着色器是针对每个片元都会执行的程序,确定每个片元的颜色。
着色器需要编译,然后链接到OpenGL程序中,一个OpenGL程序就是一个顶点着色器和一个片元着色器链接在一起变成单个对象。
第一节没看懂没关系,对这些概念有个印象就好,第二节从demo开始正式学习Andrid OpenGL,敬请期待
导读:
《OpenGL从入门到放弃02 》GLSurfaceView和Renderer
感谢:
整个系列文章的学习资源来自# 湖广午王
在洪洋的 玩安卓 网站上面搜索到的系列文章
一些概念的东西是直接copy,然后对于一些难理解的点加以注释和补充。