天天看點

OpenGL着色器基礎

着色器:着色器是提供給使用者定制自己特殊渲染需求的一套機制。常用接口如下:

1.

GLuint glCreateShader(GLenum type)

:建立指定類型的着色器。建立成功時會傳回一個目前着色器的唯一标志。

.type指着色器類型。通常取GL_VERTEX_SHADER(頂點着色器),GL_FRAGMENT_SHADER(片段着色器),GL_GEOMETRY_SHADER(幾何着色器)等類型中的一種。

2.

void glShaderSource(GLuint shader, GLsizei count, const GLchar *const*string, const GLint* length)

:将着色器源碼附加到着色器對象上。

.shader表示着色器唯一标志。

.count表示着色器源碼字元串的個數。

.string表示着色器源碼字元串的内容數組。

.length表示着色器源碼字元串的長度數組,當為NULL時表示每個源碼字元串以NULL結尾。

3.

void glCompileShader(GLuint shader)

:編譯着色器。

.shader表示着色器唯一标志。

4.

void glGetShaderiv(GLuint shader, GLenum pname, GLint* params)

:檢測着色器操作狀态是否成功。

.shader表示着色器唯一标志。

.pname表示操作狀态類型。可以是GL_COMPILE_STATUS(編譯狀态),GL_LINK_STATUS(連結狀态),GL_DELETE_STATUS(删除狀态)等操作狀态中的一種。

.params就是檢測的結果。成功就會傳回GL_TRUE,否則就會傳回GL_FALSE。

5.

void glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog)

:擷取着色器錯誤消息。

.shader表示着色器唯一标志。

.bufSize表示錯誤消息容器大小。

.infoLog表示錯誤消息容器。

.length表示錯誤消息長度大小。當為NULL時就不傳回錯誤消息長度。

6.

void glDeleteShader(GLuint shader)

:删除着色器。當着色器以及連結到一個或者多個激活的着色器程式上時,此時着色器就被标記為“可删除”狀态,直到着色器程式不再使用時,目前的着色器才會被自動删除。

.shader表示着色器唯一标志。

7.

GLboolean gllsShader(GLuint shader)

:判定指定着色器是否存在。

.shader表示着色器唯一标志。

着色器程式:着色器程式是多個着色器合并之後并最終連結完成的版本。已激活着色器程式的着色器将在我們發送渲染調用的時候被使用。常用接口如下:

1.

GLuint glCreateProgram(void)

:建立着色器程式。建立成功時會傳回一個目前着色器程式的唯一标志。

2.

void glAttachShader(GLuint program, GLuint shader)

:将着色器附加到着色器程式上。

.program表示着色器程式唯一标志。

.shader表示着色器唯一标志。

3.

void glDetachShader(GLuint program, GLuint shader)

:從着色器程式中移除指定的着色器。

.program表示着色器程式唯一标志。

.shader表示着色器唯一标志。

4.

void glLinkProgram(GLuint program)

:連結着色器程式中的着色器。此時每個着色器的輸出會連結到下個着色器的輸入。當輸出和輸入不比對的時候,你會得到一個連接配接錯誤。

.program表示着色器程式唯一标志。

5.

void glGetProgramiv(GLuint program, GLenum pname, GLint* params)

:檢測着色器程式操作狀态是否成功。

.program表示着色器程式唯一标志。

.pname表示操作狀态類型。可以是GL_COMPILE_STATUS(編譯狀态),GL_LINK_STATUS(連結狀态),GL_DELETE_STATUS(删除狀态)等操作狀态中的一種。

.params就是檢測的結果。成功就會傳回GL_TRUE,否則就會傳回GL_FALSE。

6.

void glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog)

:擷取着色器程式錯誤消息。

.program表示着色器程式唯一标志。

.bufSize表示錯誤消息容器大小。

.infoLog表示錯誤消息容器。

.length表示錯誤消息長度大小。當為NULL時就不傳回錯誤消息長度。

7.

void glUseProgram(GLuint program)

:激活着色器程式對象,預設情況下是非激活狀态的。

.program表示着色器程式唯一标志。當為0時,那麼所有目前使用的着色器都會被清除。

8.

void glDeleteProgram(GLuint program)

:删除着色器程式。當着色器程式被某一個環境所使用時,着色器程式就被标記為“可删除”狀态,直到沒有環境使用該着色器程式時,就會自動被移除。

.program表示着色器程式唯一标志。

9.

GLboolean gllsProgram(GLuint program)

:判定指定着色器程式是否存在。

.program表示着色器程式唯一标志。

着色器子程式:類似于C語言中的函數指針,主要用來實作子程式的動态選擇。

聲明着色器子程式集合流程如下:

1.通過關鍵字subroutine來定義着色器子程式類型。

原型如下所示:

subroutine returnType subroutineType(type param, ...);
其中returnType表示函數傳回類型,subroutineType表示函數名稱,param表示指定類型type的函數參數名。
           

參考定義如下所示:

subroutine vec4 LightFunc(vec3);
           

2.通過關鍵字subroutine并結合第一步中定義好的着色器子程式類型來定義着色器子程式内容。

原型如下所示:

subroutine (subroutineType1, subroutineType2, ...) returnType funcName(...);
其中subroutineType1和subroutineType2代表的是不同的着色器子程式類型,returnType代表函數傳回類型,funcName表示函數名。
           

參考定義如下所示:

subroutine (LightFunc) vec4 ambient(vec3 n);
subroutine (LightFunc) vec4 diffuse(vec3 n);
           

3.通過關鍵字subroutine和uniform來定義一個儲存選擇着色器子程式資訊的變量。

原型如下所示:

subroutine uniform subroutineType varName;
其中subroutineType表示着色器子程式類型,varName表示着色器子程式變量名
           

參考定義如下所示:

subroutine uniform LightFunc materialShader;
           

選擇着色器子程式流程如下:

1.

GLint glGetSubroutineUniformLocation(GLuint program, GLenum shadertype, const char* name)

:擷取指定着色器子程式uniform變量名稱的索引位置。

.program代表着色器程式。當不可用時傳回GL_INVALID_OPERATION。

.shadertype代表着色器類型。通常是GL_VERTEX_SHADER(頂點着色器),GL_FRAGMENT_SHADER(片段着色器),GL_GEOMETRY_SHADER(幾何着色器)等類型中的一種。

.name代表着色器子程式uniform變量名稱。當該變量不可用時傳回-1。

2.

GLint glGetSubroutineIndex(GLuint program, GLenum shadertype, const char* name)

:擷取指定着色器子程式函數名稱的索引位置。

.program代表着色器程式。當不可用時傳回GL_INVALID_OPERATION。

.shadertype代表着色器類型。通常是GL_VERTEX_SHADER(頂點着色器),GL_FRAGMENT_SHADER(片段着色器),GL_GEOMETRY_SHADER(幾何着色器)等類型中的一種。

.name代表着色器子程式函數名稱。當該函數不可用時傳回GL_INVALID_INDEX。

3.

GLuint glUniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint* indices)

:設定着色器子程式uniform變量的值為指定的着色器子程式函數。

.shadertype代表着色器類型。通常是GL_VERTEX_SHADER(頂點着色器),GL_FRAGMENT_SHADER(片段着色器),GL_GEOMETRY_SHADER(幾何着色器)等類型中的一種。

.count表示着色器子程式個數。

.indices表示着色器子程式uniform變量索引為key,着色器子程式函數索引為value的數組。

獨立的着色器對象:由于着色器對象在同一時刻隻能連結一次,這樣當多個不同片段着色器需要處理同一個頂點着色器時,就必須把頂點着色器複制多分,然後多次綁定着色器程式,這樣就造成資源的浪費和代碼的重複。此時獨立的着色器對象結合程式管線就可以解決上述問題。

使用流程如下:

1.

GLuint glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar* const strings)

:建立獨立的着色器程式對象,并傳回唯一标志。

2.

void glCreateProgramPipelines(GLsizei n, GLuint* pipelines)

:建立程式管線。

.n表示建立程式管線的個數。

.pipelines表示建立程式管線的标志數組。

3.

void glDeleteProgramPipelines(GLsizei n, GLuint* pipelines)

:删除程式管線。

.n表示程式管線的個數。

.pipelines表示程式管線的标志數組。

4.

void glBindProgramPipelines(GLuint pipelines)

:綁定指定的程式管線。

.pipelines表示程式管線的标志。

5.

void glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)

:将獨立的着色器程式附加到程式管線上,用來處理指定的着色階段。

.pipeline表示程式管線的标志。

.stages表示着色階段。

.program表示獨立着色器程式标志。