着色器对象和程序对象是使用着色器渲染的2种基本的对象类型。一个着色器对象可以当做是一个C编译器,而程序对象作为连接器。一个编译器生成目标代码(如.OBJ,.o文件),对象文件完成创建后,C连接器将该对象文件链接到最后程序。一个程序需要链接一个顶点着色器和片段着色器。
一般进程获取一个链接的着色器对象包括6个步骤
1.创建顶点着色器和片段着色器
2.将源码附加在每个着色器对象中
3.编译着色器对象
4.创建程序对象
5.将编译的着色器对象附加到程序对象中
6.链接程序对象
如果链接成功,我们就可以随时绘制。下面详细介绍执行这些进程的API
1.创建并编译着色器
GLuint glCreareShader(GLenum type) type
着色器类型【GL_VERTEX_SHADER,GL_FRAGMENT_SHADER】
返回对象为新着色器对象的句柄
void glDeleteShader(GLuint shader)
shader 删除该着色器对象(如果一个着色器对象在删除前已经链接到程序对象中,那么当执行glDeleteShader函数时不会立即被删除,而是该着色器对象将被标记为删除,器内存被释放一次,它不再链接到其他任何程序对象)。
void glShaderSource(GLuint shader,GLsizei count,const GLchar * const*string,const GLint *length)
glCompileShader(GLuint shader) 编译着色器对象
glGetShaderiv(GLuint shader,GLenum pname,GLint *params)
pname 【GL_COMPILE_STATUS GL_DELETE_STATUS GL_INFO_LOG_LENGTH GL_SHADER_SOURCE_LENGTH GL_SHADER_TYPE】
返回编译信息,YES表示编译成功,NO失败
GLuint LoadShader ( GLenum type, const char *shaderSrc ) { GLuint shader; GLint compiled; shader = glCreateShader ( type ); if ( shader == 0 ) { return 0; } glShaderSource ( shader, 1, &shaderSrc, NULL ); glCompileShader ( shader ); glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled ); if ( !compiled ) { GLint infoLen = 0; glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen ); if ( infoLen > 1 ) { char* infoLog = malloc ( sizeof ( char ) * infoLen ); glGetShaderInfoLog ( shader, infoLen, NULL, infoLog ); esLogMessage(“Error compiling shader: %s ”, infoLog); free ( infoLog ); } glDeleteShader ( shader ); return 0; } return shader; }
2.创建连接一个程序
program GLuint glCreateProgram()
删除一个程序
GLuint glDeleteProgram(GLuint program)
连接着色器到程序
void glAttachShader(GLuint program, GLuint shader)
取消连接
void glDetachShader(GLuint program, GLuint shader)
连接程序
void glLinkProgram(GLuint program)
日志信息
void glGetProgramiv(GLuint program, GLenum pname,GLint *params)
验证结果
void glValidateProgram(GLuint program) 激活程序 void glUseProgram(GLuint program)
programObject = glCreateProgram ( ); if ( programObject == 0 ) { return 0; } glAttachShader ( programObject, vertexShader ); glAttachShader ( programObject, fragmentShader ); glLinkProgram ( programObject ); glGetProgramiv ( programObject, GL_LINK_STATUS, &linked ); if ( !linked ) { GLint infoLen = 0; glGetProgramiv( programObject, GL_INFO_LOG_LENGTH, &infoLen); if ( infoLen > 1 ) { char* infoLog = malloc ( sizeof ( char ) * infoLen ); glGetProgramInfoLog ( programObject, infoLen, NULL,infoLog ); esLogMessage ( “Error linking program: %s ”, infoLog ); free ( infoLog ); } glDeleteProgram ( programObject ); return FALSE; } glUseProgram ( programObject );