当前课程知识点:移动图形概论 > 第二章 图形编程入门 > 2.3 主要 API 介绍 > 主要 API 介绍
同学们 大家好
今天这节课主要介绍
上节课程序中所用到的相关api
今天的主要内容是详细说明一下
程序中用到的主要函数
还有虽然在程序中没有出现
但比较重要的几个概念
有些同学可能在上节课就已经注意到了
标准opengl函数都以小写gl开始
并没有两个冒号分隔
就像下面的函数原型定义中所展示的
而在程序中我们使用的是带有两个冒号的版本
这是由于我们的程序
并没有包含openGL相关的头文件
而直接使用了PowerVR的程序框架
在PowerVRl的程序框架中
在gl名字空间下
重新定义了所有的openg函数
这样程序中就不必担心
不同平台下的opengl库位置
而把加载相应库文件的工作
交给powervr程序框架来处理
相关的函数只是在使用时形势略有区别
参数含义都是一致的
我们介绍的第一个函数是genbuffers函数
它用于创建一个新的缓冲区对象
并将缓存区对象的句柄存储在数据成员vbo中
从这个原型中我们可以看到
这个函数可以指定多个缓冲区对象
对应的句柄会保存在数组里
如果像我们示例中只返回一个缓冲区
也可以使用指向一个整形数的指针
在建立了新的缓存区对象以后
我们还要指定这个缓冲区所对应的类型
这就要用到BindBuffer这个函数
它可以将缓存区对象绑定到不同的缓存区目标上
Opengl支持多种不同的目标
对于顶点数组
可以把它绑定为GL_ARRAY_BUFFER
每个目标只有一个活跃的缓冲区
当绑定新的对象到目标时
先前的绑定的对象就自动解绑
如果把缓冲区对象设置为0
那么这个缓冲区目标将不再使用
BufferData这个函数
为缓冲区对象创建新的存储空间
并将缓存区对象中的数据复制到该存储空间内
它包含四个参数
第一个参数指定缓存区目标
第二个参数指定新的缓冲区空间大小
第三个参数指定具体的数据保存的位置
也就是对应的数据指针
第四个参数指定数据空间存储的预期使用模式
现在我们看一下在示例代码中对这个函数的使用
第一个参数指定为数组缓存区
也就是之前我们绑定的缓冲区目标
第二个参数指定我们三角形数据尺寸
由于每个顶点由三个浮点坐标组成
总共占用空间就是
3×3再乘以浮点数所占用的空间
一共36个字节
接着第三个参数指定了要复制数据所在的位置
也就是afVertices数组
由于我们这里面是一次存储多次使用
所以我们第四个参数使用GL_STATIC_DRAW
这里的函数用来使能通用顶点的属性数组
这里的函数用来使能通用顶点的属性数组
它和顶点着色器代码中的变量直接相关
着色器代码中的输入变量都有一个索引
对于我们的简单示例代码中只有一个变量
它的索引就是0
我们这里定义为一个常量VertexArray
因此
这个代码使得我们顶点着色器的第一个变量被激活
vec4是一个四维矢量
这个细节要在后面课程中详细说明
VertexAttribPointer函数有一点点复杂
参数也比较多
它用来指定顶点数组中数据的排列方式
第一个参数是需要设置的顶点属性的索引
第二个参数是每个顶点属性分量的个数
第三个参数是每个分量的数据类型
而第四个参数指定是否要标准化定点数据值
第五个参数指定了
连续通用顶点数据之间的字节偏移量
最后一个参数指向数组中第一个通用顶点属性的
第一个分量的位置
这里是我们示例代码中VertexAttribPointer使用实例
它的第一个参数设置为我们顶点着色器中的
第一个变量的位置
也就是VertexArray常量
第二个参数指定有三个顶点
第三个参数指定数据类型为浮点
接着指定这些值不需要标准化
所以下面的参数设置为否
由于我们的顶点数据是紧凑保存
也就是第一个顶点的数据
后面就紧跟着第二个顶点数据
所以这里面步长可以设置为零
在后续的课程里面
我们可以看到其它的值的使用
最后一个参数
是指定我们数据起始位置
这里面依然是零
因为从第一个数据开始就是我们的顶点数据
DrawArray函数将根据先前绑定的数据对图源进行渲染
它包含三个参数
第一个是渲染的图形类型
第二个指定数据中的起始索引
第三个参数指定要渲染的所有索引数
从我们的代码中可以看到
我们指定了图元的类型为三角形
起始的顶点是第一个
索引号为零
我们定义了一个三角形
也就是3个顶点
如果对象由2个三角形组成
则会使用6个顶点
前面介绍的函数与我们在代码中使用的顺序相同
这也是openGL ES程序绘制图形的一般步骤
我们在initView中生成缓冲区对象
绑定缓冲区
然后为缓冲区写入数据
在randerFrame函数中绑定缓冲区
激活顶点属性数组
指定数据排列格式
然后绘制图形
这里介绍的函数由powervrr的utils模块提供
它大大简化了
我们编译和加载着色器程序的过程
如果没有这个函数
我们要对着色器代码进行编译
检查编译的结果
并把程序加载到gpu中
这些操作需要访问文件
调用相关OpenGL API
过程比较冗长和死板
因此这个函数就把相关的工作全部包括了
它包含多个参数
第一个参数是我们定义的PVRShell类的实例
第二和第三个参数指定了两个着色器程序的文件名
第四个参数指定了着色器中的属性列表
也就是它的输入变量的列表
第五个参数是着色器程序属性的索引列表
接下来指定了着色器程序中的属性的个数
最后两个参数可以在着色器程序中增加自定义宏变量
在我们的示例代码中
首先定义了两个常量数组
第一个是着色器名称的字符串数组
这里只有一个元素myVertex
另外一个是着色器属性的索引列表
这里也只有一个索引值是0
调用createShaderProgram的时候
第一个参数是this指针
然后是两个着色器的程序文件名
接着是两个前面定义的常量数组
着色器的属性个数为1
没有宏定义
函数的返回值是着色器的程序句柄
后面在绘图之前要使用UseProgram函数
利用这个句柄激活程序
在介绍程序的时候
我们并没有强调定义三角形顶点的顺序
但这个顺序确有它实际的意义
例如对于右面顺时针定义的三角形
按照右手规则
握拳的方向与顶点的定义方向一致
指尖指向箭头
那么大拇指方向就是三角形的正面
也就是它目前背对我们
为了提高效率
OpenGL ES 可以不绘制三角形的背面
与这个功能相关的有三个函数
刚才提到的规则可以灵活的设置
其中 glFrontFace 用来定义哪个面是正面
缺省的情况下就是刚才我们提到的右手规则
CCW也就是Counter-clockwise方向为正面
而不被绘制的面也可以用glCullFace来设置
缺省也是背面不进行绘制
最后这个功能是否有效还要用
glEnable(GL_CULL_FACE)来进行设置
缺省时正面和背面都是被绘制的
如果当绘制的对象多于一个的时候
比如在第11个示例代码中增加了立方体的显示
就可能存在遮挡现象
OpenGL具有进行深度测试的功能
也就是自动检测哪一个对象在前面
如果要打开这个功能只要使用
glEnable(GL_DEPTH_TEST)
不过由于进行这个测试要记录每个片元的深度信息
也要有一个缓冲区与之对应
因此每次绘制之前
除了要清除颜色缓冲区
还要用glClear清除深度缓冲区
实际代码如屏幕所示
可以同时将两个缓冲区清零
今天的课程就到这里
谢谢大家
-1.1 课程基本情况介绍
--课程基本情况介绍
-1.2 GPU 相关基础知识
-1.3 OpenGL ES 技术发展历史
-1.4 PowerVR SDK 安装和使用
-第一章测试
-2.1 OpenGL ES 基本概念
-2.2 编写第一个图形程序
-2.3 主要 API 介绍
-第二章测试
-3.1 矢量和矩阵知识基础
-3.2 旋转与位移变换
--旋转与位移变换
-3.3 OpenGL ES 变换基础
-第三章测试
-4.1 着色器编程语言介绍
-4.2 着色器编程实例
--着色器编程实例
-第四章测试
-5.1 颜色的基本概念
--颜色的基本概念
-5.2 纹理素材的使用
--纹理素材的使用
-5.3 立方体纹理
--立方体纹理
-第五章测试
-6.1 光照的基本概念
--光照的基本概念
-6.2 光源模型
--光源模型
-6.3 使用着色器渲染颜色
-6.4 反射与折射
--反射与折射
-第六章测试
-7.1 基于物理渲染的基本概念
-7.2 基于图像的照明
--基于图像的照明
-7.3 PBR 的实现
--PBR 的实现
-第七章测试
-8.1 Vulkan 介绍
-8.2 SDK 中的实用工具介绍
-综合测试



