OpenGL 对象
在顶点数据定义好了之后,通常这些属性会作为输入发送给图形渲染管线的第一个处理阶段:顶点着色器。它会在GPU上创建内存用于存储顶点数据,同时还要告诉OpenGL如何去解释内存中的这些数据,并且指定如何发送到显卡。顶点着色器接下来会处理内存中指定数量的顶点。通常会采用VBO对象来管理这个GPU上分配的内存。
VBO对象
VBO,即顶点缓冲对象(Vertex Buffer Object),主要作用就是可以一次性发送大批顶点数据到显卡上,而不是每个顶点发送一次。原因是CPU传送数据给GPU其实是比较耗时的,所以尽可能的一次性把需要的顶点数据全部传给GPU,这样顶点着色器几乎能立即访问到顶点,有助于加快顶点着色器效率。
系列文章
- Android OpenGL基础1——常用概念及方法解释
- Android OpenGL基础2——Shader的使用流程
- Android OpenGL基础3——纹理的使用
- Android OpenGL基础4——变换
- Android OpenGL——Android Studio OpenGL开发的简单示例
创建步骤
- 生成一个(或多个)缓冲类型的id - 1 
 2
 3
 4
 5
 6
 7- // 生成一个vbo id 
 unsigned int vbo;
 glGenBuffers(1, &vbo);
 // 或者 生成3个 vbo id
 unsigned int vbos[3];
 glGenBuffers(3, &vbos);- glGenBuffers(GLsizei n, GLuint buffers),生成缓冲对象名字,n为缓冲对象名字个数, buffers为存放名字的数组,*n和数组长度需要一直 
- 将缓冲对象id绑定给指定的缓冲类型 - 1 - glBindBuffers(GL_ARRAY_BUFFER, vbo) 
缓冲类型通常有:GL_ARRAY_BUFFER, GL_COPY_READ_BUFFER,
GL_COPY_WRITE_BUFFER, GL_ELEMENT_ARRAY_BUFFER,
GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, GL_TEXTURE_BUFFER,
GL_TRANSFORM_FEEDBACK_BUFFER, or GL_UNIFORM_BUFFER.
注意:OpenGL中存在多种不同类型的缓冲对象(如上所述),所以只要缓冲对象类型不同,OpenGL是允许我们同时绑定多个缓冲的。
小结
创建VBO对称步骤:
- 生成VBO对象id(调用glGenBuffers);
- 为生成的id指定缓冲类型(调用glBindBuffers);
赋值操作
VBO 对象的赋值主要利用glBufferData函数来进行:
| 1 | /** | 
上面的usage参数,常用的有如下几个值:
- STREAM,modified once and used at most a few times;
- STATIC,modified once and used many times;
- DYNAMIC,modified repeatedly and used many times;
示例:
| 1 | // 定义顶点数据 | 
支持数据就已经推送到GPU中去了,一个VBO过程就结束了。
数据的处理
上面通过一些列的接口调用,最终完成了想GPU数据的推送,那么GL是怎么告诉GPU如何处理这些数据的呢,毕竟上面的vertices数组描述了顶点数据两种类型的信息:位置和颜色。要处理上面的数据(vertices),需要如下代码:
| 1 | // 位置属性 | 
- glEnableVertexAttribArray,开启对应位置的顶点属性;
- glDisableVertexAttribArray,关闭随影位置的顶点属性;
- glVertexAttribPointer,说明顶点属性数据的解析规则;
OpenGL中,主要通过glVertexAttribPointer这个函数来说明该如何解析传递给GPU的数据的。参数说明:
| 1 | void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, | 
- index,指定哪个顶点属性奖杯修改,通常对应如顶点Shader中layout(position = 0)这个position;
- size,表示顶点属性指的大小,上面vertices位置和颜色都是有三个float型数据组成的,所以是3;
- type,指的是数据的类型,上面vertices对应的时GL_FLOAT;
- normalized,是否希望数据标准化。如果我们设置为GL_TRUE,所有数据都会被映射到0(对于有符号型signed数据是-1)到1之间。我们把它设置为GL_FALSE;
- stride,表示一条完整顶点属性(包括location和color)的长度(这里需要6个数来表示),所以这里是6;
- pointer,表示偏移量,即在一段数据中,指定的数据偏移多少位置开始。在这里,坐标数据都是每段数据的起始位置,所以偏移量是0,而颜色数据在坐标数据之后,坐标数据有3个分量,所以每个颜色数据偏移三个float字节开始算;
VAO对象
VAO,即顶点数组对象(Vertex Array Object),VAO作用就是顶点属性调用都会存储在VAO中。这样的好处就是,当配置顶点属性指针时,你只需要将那些调用执行一次,之后再绘制物体的时候只需要绑定相应的VAO就行了。简单来说有点类似复用的概念。 那么VAO到底复用了哪些过程呢,先看物体绘制的一般过程:
| 1 | // 0. 复制顶点数组到缓冲中供OpenGL使用 | 
如果使用VAO,任何绑定VAO后的顶点属性调用都会储存在这个VAO中。这样的好处就是,当配置顶点属性指针时,你只需要将那些调用执行一次,之后再绘制物体的时候只需要绑定相应的VAO就行了。
创建及使用
生成一个id并绑定,然后进行VBO的复制操作,再进行顶点指针的设置操作,
| 1 | // 定义一个 id,用来存储生成的VAO对象名称 | 
Sample对象
Sample对象,即采样器对象,它是GLSL有一个供纹理对象使用的内建数据结构,在Shader定义好Sample对象后,后面这个对象就可以接收外面传递进来的纹理对象的值了。
根据纹理的类型,Sample对象也有相对应的类型:
- 1D->sample1D;
- 2D->sample2D;
- 3D->sample3D;
数学基础
要学习好OpenGL,就必须对基本的数学知识有所了解,这里先列出几个点:
- 向量
- 矩阵