您的位置:首页 > 编程语言

OpenGL ES 2.0编程基础

2012-06-10 11:08 337 查看
本人在学WebGL,WebGL的资料很少,由于WebGL是OpenGL ES 2.0的子集,所以先学习一下OpenGL ES 2.0的基础知识。OpenGL中既有固定管线处理流程,也可以使用shader进行可编程的管线处理,OpenGL ES 2.0是完全可编程的管线流程,而没有固定管线流程,这给我们增加了更多的灵活度,以前可以让OpenGL替我们做的事情,现在必须要我们在shader中自己去实现,这可以使我们更深入的理解OpenGL ES 2.0图形绘图流程。
本文参考了http://blog.csdn.net/racehorse/article/details/6593719

1.OpenGL中的图形处理固定管线流程:




现在的显卡允许程序员自己编程实现上述流水线中的两个阶段:·顶点shader实现顶点变换阶段的功能·片断shader替代片断纹理化和色彩化的功能

2.OpenGL ES 2.0中的可编程管线流程:





3.顶点着色器:



4.片段着色器:



5.Shader开发流程:



        a.编写vertex Shader和fragment shader源码。
        b.创建两个shader 实例:GLuint glCreateShader(GLenum type); [gl.createShader]
        c.给Shader实例指定源码:glShaderSource [gl.shaderSource]
        d.编译shader源码: void glCompileShader(GLuint shader) [gl.compileShader]
        e.创建shader program:GLuint glCreateProgram(void) [gl.createProgram] 
        f.绑定shader到program: void glAttachShader(GLuint program, GLuint shader)。每个program必须绑定一个vertex shader 和一个fragment shader。 [gl.attachShader]  
        g.链接program:void glLinkProgram(GLuint program) [gl.linkProgram]
        h.使用porgram:void glUseProgram(GLuint program) [gl.useProgram]
        i.  对于使用独立shader编译器编译的二进制shader代码,可使用glShaderBinary来加载到一个shader实例中。

6.Uniforms变量:
Uniform变量是OpenGL ES着色器语言中的一种变量类型修饰符。Uniform变量用来存储只读值,这些值通过OpenGL ES 2.0 API传递给着色器。Uniforms常用于存储着色器需要的各种数据,比如变换矩阵、光线参数以及颜色等。输入着色器的常量参数(顶点或者片段)应该被作为Uniform类型传入进去。  如果顶点着色器和片段着色器被连接到同一个program对象中,它们会分享相同的uniform变量。因此,如果一个Uniform变量在顶点着色器中声明了,并且也在片段着色器中声明了,那么二者的声明必须匹配。当应用程序通过API装载uniform变量时,其值在顶点着色器和片段着色器中均可获得。 Uniform变量常用于在硬件中进行“常量存储”。
7.Attributes变量:Attribute变量只能够在顶点着色器中使用,用于逐个指定到顶点着色器的输入。Attributes典型的用来存储位置、法线、纹理坐标和颜色。理解的关键在于attributes存储着每个顶点绘制所需要的数据。下面这个例子中,a_position是位置属性,a_texCoord0是纹理坐标属性。uniform mat4 m_matModelViewProjection;attribute vec4 a_position;//position attributeattribute vec2 a_texCoord0;//texture coordinate attributevarying vec2 v_texCoord; void main(void){    gl_Position =matViewProjection* position;    v_texCoord =  a_texCoord0;}
注:gl_Position是内置的变量。

8.Varyings变量:
Varyings变量用来存储顶点着色器的输出,并且也是片段着色器的输入。每个顶点着色器输出需要传递给片段着色器的的数据,这些数据用一个或多个varying变量来声明。这些变量也同时在片段着色器中声明(有着相同的类型),并且在基元的光栅化过程中会进行线性插值。其声明如下所示:varying vec2 texCoord;varying vec4 color;必须在顶点着色器和片段着色器中同时声明varying,且其声明必须完全相同。



9.给shader中的uniform赋值:
uniform vec3 uAmbientColor;//这样给uAmbientColor赋值ambientColorLocation = gl.getUniformLocation(shaderProgram,"uAmbientColor");gl.uniform3f( ambientColorLocation, 1.0,1.0,1.0 );或 gl.uniform3fv(ambientColorLocation,[1.0,1.0,1.0 ]) uniform bool uUseLighting;//这样给uUseLighting赋值useLightingLocation = gl.getUniformLocation(shaderProgram,"uUseLighting");gl.uniform1i(useLightingLocation,要赋值的布尔值); uniform float uAlpha;//赋值用到的是alphaLocation = gl.getUniformLocation(shader, "uAlpha");gl.uniform1f(alphaLocation,0.7); uniform mat4 mv;//这样给mat4赋值mvLocation = gl.getUniformLocation(shaderProgram, "mv");gl.uniformMatrix4fv(mvLocation,false, new Float32Array([…]); 总结:uniform赋值时,先从shader中根据uniform变量的名称通过gl.getUniformLocation(shaderName,"uniformName")获取其地址,然后根据地址通过gl.uniform*(…)对其进行赋值。

10.给shader中的attribute赋值:
attribute vec3 position;var positionLocation = gl.getAttribLocation(shader,"position");gl.enableVertexAttribArray(positionLocation);//////////////////////////////////////////////////////////////////var positionBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);gl.bufferData(gl.ARRAY_BUFFER,newFloat32Array([…]), gl.STATIC_DRAW);gl.vertexAttribPointer(positionLocation,3, gl.FLOAT, false, 0, 0); 与uniform赋值不同,对attribute进行赋值时,在initShaders时,首先要通过gl.getAttribLocation(shader,"attributeName")获取attribute变量的地址,然后通过调用gl.enableVertexAtribArray(attributeLocation)来启用该attribute变量。上面的操作只需要调用一次即可。然后在循环drawScene的时候,如果buffer之前就已经通过gl.bufferData赋值(比如在initialBuffers()的时候对其赋值),并且如果buffer的值没有改变(比如坐标值未变)那么就不需要在每次渲染的时候再通过bufferData在对其赋值,只需在每次渲染的时候,通过gl.bindBuffer和gl.vertexAttribPointer将buffer的值传递给着色器中的attribute变量即可,对shader中的attribute变量进行赋值。可参见 一个使用drawElements绘图的简单Demo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: