一 初识OpenGL
1.OpenGL是什么?有什么用途?
OpenGL是一个开放的图形库,可用于视频、图片、图形处理,2D/3D游戏开发,科学可视化,医学软件开发,CAD(计算机辅助技术),虚拟实境(AR VR),AI人工智能等领域。
2.OpenGL和OpenGL ES是什么关系?
OpenGL ES是OpenGL的子集,OpenGL ES即一个在移动平台上能够支持OpenGL最基本功能的精简规范。
3.为什么要用OpenGL ES?
让我们看一下常规的CPU与GPU交互流程:
![](https://i-blog.csdnimg.cn/blog_migrate/41877a59e4eab832935092ddc0975e10.png)
CPU与GPU之间是不能直接交互的,需要通过内存区传递数据,速度较慢,而且在内存复制过程中CPU和GPU为避免数据错误都不能操作此块内存,因此造成了所谓的“数据饥饿”。OpenGL为了提升渲染的性能,为两个内存区域间的数据交换定义了缓存。缓存是值GPU能够控制和管理的连续的RAM(Random-Access Memory(随机存取存储器))。程序从CPU的内存复制数据到OpenGL ES的缓存。通过独占内存,GPU能够尽可能以有效的方式读写内存。GPU把它处理数据的能力异步地应用在缓存上,意味着GPU使用缓存中的数据工作的同时,运行在CPU中的程序可以继续执行。
![](https://i-blog.csdnimg.cn/blog_migrate/ffbebfc26f9d0963d6d205e104982ef6.png)
二 着色器语言
1.名词解释
1)图元
图形软件中用来描述各种图形元素的函数,简单来说就是组成图像的基本单元。
2)OpenGL渲染管线(重点)
通俗来讲叫渲染流水线:显示芯片内部处理图形信号互相独立的并行处理单元,简单来说就是一系列有序的处理阶段的序列,用于把我们应用中的数据转化到OpenGL生成一个最终图像的过程。
![](https://i-blog.csdnimg.cn/blog_migrate/072aa3c44324c8745f64720620492a10.png)
3)简单分析顶点着色器
#version 330 code//版本
in vec4 vPosition; //in:输入 vec4:向量 vPosition 变量名
in vec4 vColor;
//Unifrom的作用:从宿主语言中通过OpenGl的函数给GLSL传值
Unifrom mat4 ModelViewProjectionMatrix;
void main(){
glPosition=modelViewProjectionMatrix*vPosition;
}
4) 基本语法
1.注释:单行注释"//“,多行注释”/*。。。*/“
2.main函数没有返回值
3.每条语句结尾都要加一个分号
2.GLSL变量认识
1)GLSL支持的基本数据类型
![](https://i-blog.csdnimg.cn/blog_migrate/0560381c556eadad4930efad1a6761fa.png)
Android上OpenGL ES2.0中的基本数据类型:浮点型float,布尔型bool,整型int,矩阵型matrix以及向量型vec2等。总体来说,这些数据类型可以分为标量、向量、矩阵、采样器以及数组等几种分类。
2)什么是标量
只有大小没有方向
3)变量命名规范
组成方式:字母、数字、下划线
注意:
1.数字和下划线不能作为变量名第一个字符
2.变量名不能包含连续的下划线
3.系统内变量名都是以"gl"开头,因此不允许使用"gl"作为变量名、类名、常量、方法名开头
4.起名需见名知意
4)变量的初始化
int i=150;
float g=9.0; (必须包含小数点,否则计算会出错)
bool: true或false(0或1)
3.聚合类型——向量
1)什么是向量
有大小有方向的量叫做向量,OpenGL ES着色语言中,向量可以看做是同样类型的标量组成的,其基本类型也分为int float bool三种,每个向量可以由2个、3个、4个标量组成
2)向量在着色器中的作用
可以很方便的存储和操作颜色、位置、纹理、坐标等不仅仅包含一个组成部分的量。
开发中有时候可能会需要单独获取某向量中的单个分量,基本语法为:"<向量名>.<分量名>"
![](https://i-blog.csdnimg.cn/blog_migrate/82946a24291c0a0bc12d63760433cb52.png)
3)向量的初始化
1.常规初始化:
vec3 xyz=vec3(0.0,1.0,2.0);
vec4 rgba=vec4(0.1,0.5,0.7,1.0);
vec3 xyz=vec3(1.0)和vec3 xyz=(1.0,1.0,1.0)语义相同。
2.加长操作:
vec3 xyz=vec3(0.0,1.0,2.0);
vec4 rgba=vec4(xyz,1.0);
3.取短操作:
vec4 rgba=vec4(0.1,0.5,0.7,1.0);
vec3 xyz=rgba.rgb;或vec3 xyz=rgba.xyz; (即后面的名称与取短无关,只代表了取几位,例如vec2 xy=rgba.xy意思即取向量rgba的前两个分量)
4 聚合类型——矩阵
1.矩阵在3D开发中的作用
在现实世界里存在三维空间的问题,比如当一架飞机从地面起飞,就会有平移、旋转等动作,如果要描述这架飞机上所有点的坐标变化,需要引入三维空间坐标,这样每一点的变化就需在三个维度上描述,引入线性变换的线性方程组,而处理这些线性方程组,就需要计算系数与三个变量的关系,再加上空间方向引入,就刚好是三维矩阵来处理了。由此可见,矩阵在描述三维物体的运动的变化是一个很合适的工具。
2.矩阵类型
![](https://i-blog.csdnimg.cn/blog_migrate/276b3ee5a73362350dc700820c76b7f5.png)
3.矩阵初始化
mat4*4是什么意思?第一个4表示4列,第二个4表示4行
单位矩阵:主对角线的分量均为1个单位,其余分量为0
规则:传入的数据首先填充列,然后填充行。
![](https://i-blog.csdnimg.cn/blog_migrate/f43b5ab82005f8a4d16a162b0ac69cc4.png)
矩阵的其他初始化方法
例1:
vec3 v1=vec3(1.0,2.0,3.0);
vec3 v2=vec3(4.0,5.0,6.0);
vec3 v3=vec3(7.0,8.0,9.0);
mat3 m=mat3(v1,v2,v3);
例2:
vec2 v1=vec2(1.0,2.0);
vec2 v2=vec2(4.0,5.0);
vec2 v3=vec2(7.0,8.0);
mat3 m=mat3(v1,3.0,v2,6.0,v3,9.0);
附:矩阵计算
矩阵的加减:矩阵内对应位置分量的加减(两矩阵行列数必须相等)
矩阵乘标量:矩阵内每一个分量乘以标量值
矩阵间相乘:第i行乘以第j列(A矩阵的行数必须等于B矩阵的列数,例:A:mat2*3,B:mat3*2)
矩阵相乘例:
![](https://i-blog.csdnimg.cn/blog_migrate/2adf59638c9303f968b2ee82f47fb727.png)