着色器对象和程序对象是使用着色器渲染的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 == )
{
return ;
} glShaderSource ( shader, , &shaderSrc, NULL );
glCompileShader ( shader );
glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled );
if ( !compiled )
{
GLint infoLen = ;
glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen );
if ( infoLen > )
{
char* infoLog = malloc ( sizeof ( char ) * infoLen );
glGetShaderInfoLog ( shader, infoLen, NULL, infoLog );
esLogMessage(“Error compiling shader:\n%s\n”, infoLog);
free ( infoLog );
}
glDeleteShader ( shader );
return ;
} 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 == )
{
return ;
}
glAttachShader ( programObject, vertexShader );
glAttachShader ( programObject, fragmentShader ); glLinkProgram ( programObject );
glGetProgramiv ( programObject, GL_LINK_STATUS, &linked );
if ( !linked )
{
GLint infoLen = ;
glGetProgramiv( programObject, GL_INFO_LOG_LENGTH, &infoLen);
if ( infoLen > )
{
char* infoLog = malloc ( sizeof ( char ) * infoLen );
glGetProgramInfoLog ( programObject, infoLen, NULL,infoLog );
esLogMessage ( “Error linking program:\n%s\n”, infoLog );
free ( infoLog );
}
glDeleteProgram ( programObject );
return FALSE;
} glUseProgram ( programObject );