第二章说了如何创建一个三角形,也使用了android进行了绘制,我们在案例中使用了一个顶点着色器(这个好像有的地方叫片元)和一个片段着色器以及一个程序对象,这里就对如何创建着色器、编译他们以及连接到一个程序上。
着色器和程序
创建着色器,加载着色器,编译着色器,创建程序,附着在程序上,连接之后使用,从程序中得到句柄,通过句柄进行传值。
一个程序需要两个着色器,一个片元一个片段,然后编译成为可执行文件进行渲染,也就是一个程序可以附着多个着色器对象。
创建着色器和编译着色器
创建着色器
GLint glCreateShader(GLenum type);
根据传入的类型,返回一个顶点和一个片段着色器的句柄,完成之后,可以使用glDeleteshader删除。
void glDeleteshader(GLint shader)
如果执行了删除,但是它正好附着在程序上,就不会立即的删除,只会标记为删除,一旦不在附着就会立即删除
创建着色器就需要附着着色器代码。
void glshaderSource(shader,size,string,length)
一旦加载了程序,就可以进行编译操作,但是并不是所有的都提供了编译着色器的能力。
void glCompileShader(shader)
编译之后,查询是否成功,可以使用
glGetShaderiv(shader,name,param)
查询一些其他信息
- GL_COMPILE_STATUS 编译状态
- GL_DELETE_STATUS 查询删除状态
- GL_INFO_LOG_LENGTH :日志长度
- GL_SHADER_SOURCE_LENGTH
- GL_SHADER_TYPE
创建和连接程序
创建程序,程序作为一个容器对象,可以将着色器附着在该对象上最终连接到可执行文件上。
//创建程序
GLunit glCreateProgame()
它返回一个句柄,可以使用glDeleteProgram(progame)删除程序。
下来就是将着色器附加到它的上面,使用
void glAttachShader(progame,shader);
需要注意的是它是将一个着色器对象添加在它的上面,所以有没有数据,有没有编译成功与否都是无所谓的。
分离glDetachShader(program,shader)
下一步就是进行连接程序。
glLinkProgram(program)
uniform和属性
一旦链接结束之后,需要进行一些查询,得到句柄,uniform可以在一个程序之间共享。
获取和设置uniform
- 查询活动的:可以得到程序中活动的数量,一般的,使用之后的是活跃的,没有使用不能称之为活跃的
- 查询unoiform的相关信息:
glGetActiveUniform(program,index,bufSize,length,size,typr,name)
使用glGetActiveUniform,您可以确定制服的几乎所有属性。
- 统一变量的名称及其类型。
- 您可以找出变量是否是数组,如果是,数组中使用的最大元素是什么。
- 找到制服的位置需要制服的名称,类型和大小也需要弄清楚如何加载数据。一旦我们有了制服的名字,我们就可以使用glGetUniformLocation找到它的位置。
制服位置是一个整数值,用于标识制服在程序中的位置。该位置值被随后的调用用于加载带有值的制服(例如,glUniform1f)。
查询uniform的位置
glGetUniformLocation
查询uniform,如果不是活动,就返回-1,上面提到了可以查询数组的大小,类型,这个函数有查询到了位置,那么就可以根据不同的类型给uniform设置值了。
一般的自己写的shader就不需要查询,自己写,也可以知道类型和名称,直接调用getUniformLocation就可以得到位置了
查询属性和设置属性
同样的可以查询活跃的属性,,您可以使用glGetActiveAttrib找到属性的属性。然后有一组设置顶点数组的例程来加载顶点属性值。
得到属性的位置,然后设置属性值,后面会有专门的一章。
二进制文件
之前说不是每个设备都存在一个编译器的,目前使用并没有见到过,等之后回来补充。