着色器對象和程序對象是使用着色器渲染的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:\n%s\n”, 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:\n%s\n”, infoLog ); free ( infoLog ); } glDeleteProgram ( programObject ); return FALSE; } glUseProgram ( programObject );