简单的vertex shader如下:
attribute vec a_position;
uniform mat4 u_ mvp;
void main()
{
gl_Position = u_mvp * a_position;
}
这些输入a_position和u_mvp是怎么从c语言映射到shader呢?
1,首先编译并链接shader。a:创建一个shader,glCreateShader(GL_VERTEX_SHADER);b:赋值shader,glShaderSource(shader, size, str, 0);c:编译,glCompileShader(shader);d:链接,glLinkProgram(shader)。
2,通过glGetActiveUniform获取shader中各个uniform的字符串,在这里就只有一个"u_mvp",然后通过glGetUniformLocation(shader, "u_mvp")获取uniform的位置,以后就用这个位置了。
3,attribute和uniform类似,函数分别为glGetActiveAttrib和glGetAttribLocation。
4,通过glUniformatrix4fv(location, mat)来设置u_mvp到shader里面。
5,设置a_position之类的attribute属性,这个步骤比较多,以vao为例:
5.1,创建和绑定vao;glGenVertexArrays(1, &vao);glBindVertexArray(vao)。
5.2,创建和绑定vbo;glGenBuffers(1, &vbo);glBindBuffer(GL_ARRAY_BUFFER, &vbo);分配vbo内存glBufferData(GL_ARRAY_BUFFER, ...)。
5.3,指出下面的数据流那些数据是表示顶点位置a_position的;glEnableVertexAttribArray(location);glVertexAttribPointer(location, 3, GL_FLOAT, ...);如果有颜色和纹理数据也一并指出。
5.4,把顶点数据流放到vbo中,使用glDrawElementArray函数。gpu在执行shader的时候根据5.3指定的位置信息可以正确取出a_position对应的数据。
6,5.4的glDrawElementArray函数放到最后执行的,在之前会先选择对应的shader,然后把uniform,attribute,texture,以及其它一些渲染状态比如混合函数一并设置到opengl中,这些参数可以看作材质,区别于上面的顶点,对于材质相同,顶点不同的多个模型,如果他们顶点z相邻,可以一并通过一次glDrawElementArray放到内存,这一步的opengl操作只需要调用一次,这成为批量渲染。
6.1,绑定纹理:glBindTexture(GL_TEXTURE_2D, 0);glBindTexture(GL_TEXTURE_2D, 1);
6.2,设置混合模式:glBlendFunc(sfactor, dfactor)
6.3,使用shader:glUseProgram(shader)
6.4,设置相关uniform的值glUniformatrix4fv(location, mat)。相关attribute的设置是在5.3中做的。
这样,所有的顶点和材质都放到了shader中了。
本文详细介绍了如何将数据从C语言映射到OpenGL ES的顶点着色器中,包括编译链接着色器、获取uniform变量位置、设置uniform矩阵值、创建和绑定VAO/VBO、设置顶点属性等步骤。
409

被折叠的 条评论
为什么被折叠?



