引擎提供了CCGLProgram类来处理着色器相关操作,对当前绘图程序进行了封装,其中使用频率最高的应该是获取着色器程序的接口:const GLuint getProgram();
该接口返回了当前着色器程序的标识符。后面将会看到,在操作OpenGL的时候,我们常常需要针对不同的着色器程序作设置。注意,这里返回的是一个无符号整型的标识符,而不是一个指针或结构引用,这是OpenGL接口的一个风格。对象(纹理、着色器程序或其他非标准类型)都是使用整型标识符来表示的。
CCGLProgram提供了两个函数导入着色器程序,支持直接从内存的字符串流载入或是从文件中读取。这两个函数的第一个参数均指定了顶点着色器,后一个参数则指定了像素着色器:
[cpp] view plaincopy
- /** Initializes the CCGLProgram with a vertex and fragment with bytes array */
- bool initWithVertexShaderByteArray(const GLchar* vShaderByteArray, const GLchar* fShaderByteArray);
- /** Initializes the CCGLProgram with a vertex and fragment with contents of filenames */
- bool initWithVertexShaderFilename(const char* vShaderFilename, const char* fShaderFilename);
仅仅加载肯定是不够的,我们还需要给着色器传递运行时必要的输入数据。在着色器中存在两种输入数据,分别被标识为attribute和uniform。
attribute变量是应用程序直接传递给顶点着色器的变量,在段着色器中不能访问。它描述的是每个顶点的属性,如位置、法线等,被限制为向量或标量这样的简单结构。必须为每个顶点指定对应的值,这类似于C中的函数参数。
uniform变量是全局性的,可以同时在顶点着色器和段着色器中访问。在整个渲染流水线中,每个uniform变量都是唯一的,不存在每个像素或顶点需要单独定义的问题,这一点是和C的全局变量类似的。uniform变量的可定义类型会更丰富一些,还可以包括纹理矩阵和纹理,甚至可以通过uniform block自定义复杂的数据类型。
uniform变量是全局性的,可以同时在顶点着色器和段着色器中访问。在整个渲染流水线中,每个uniform变量都是唯一的,不存在每个像素或顶点需要单独定义的问题,这一点是和C的全局变量类似的。uniform变量的可定义类型会更丰富一些,还可以包括纹理矩阵和纹理,甚至可以通过uniform block自定义复杂的数据类型。
int glGetUniformLocation(GLuint program, const GLchar* name);
对uniform变量的设置存在着一系列以"glUniform"为前缀的函数,这些函数的第一个参数为需要设置的参数标识,后面跟若干参数值.
shader配置文件 .vsh 和 .fsh
initWithVertexShaderFilename(const char* vShaderFilename, const char* fShaderFilename) 这里我们可以用到shader配置文件 .vsh 和 .fsh
可以参考quick-lua3.3 quick\lib\quick-src\extra\filters\shader目录下的部分例子,如
example_MultiTexture.vsh:
attribute vec4 a_position; attribute vec2 a_texCoord; attribute vec4 a_color; #ifdef GL_ES varying lowp vec4 v_fragmentColor; varying mediump vec2 v_texCoord; #else varying vec4 v_fragmentColor; varying vec2 v_texCoord; #endif void main() { gl_Position = CC_PMatrix * a_position; v_fragmentColor = a_color; v_texCoord = a_texCoord; }
example_MultiTexture.fsh:
#ifdef GL_ES precision mediump float; #endif varying vec4 v_fragmentColor; varying vec2 v_texCoord; uniform sampler2D u_texture1; uniform float u_interpolate; void main() { vec4 color1 = texture2D(CC_Texture0, v_texCoord); vec4 color2 = texture2D(u_texture1, v_texCoord); gl_FragColor = v_fragmentColor * mix( color1, color2, u_interpolate); }
http://www.58player.com/blog-2534-93050.html
使用例子:http://www.cnblogs.com/U-tansuo/p/quick2-25_shader.html
http://4gamers.cn/blog/categories/opengl-es/