
OpenGL着色語言(GLSL――OpenGL Shading Language)是用來在OpenGL中着色程式設計的語言,
也即開發人員寫的短小的自定義程式,他們是在圖形卡的GPU (Graphic Processor Unit圖形處理單元)
上執行的,代替了固定的渲染管線的一部分。比如:視圖轉換、投影轉換等。GLSL(GL Shading Language)
的着色器代碼分成2個部分:Vertex Shader(頂點着色器)和Fragment(片斷着色器)
,有時還會有Geometry Shader(幾何着色器)。負責運作頂點着色的是頂點着色器。
它可以得到目前OpenGL 中的狀态,GLSL内置變量進行傳遞。
先看下vertex shader,起設計目的是對應用層輸入的頂點資料做處理,我們可以以一個簡單的
代碼來看下定點處理的過程,可以把下面的過程看成是顯示卡處理定點資料的過程:
void process( const Vertex& position,Vertex& gl_Position)
{
gl_Position = gl_ModelViewProjectionMatrix * position;
}
for (int i = 0 ;i < vertexCnt ; ++ i )
{
Vertex gl_Position;
process( position[i],Vertex& gl_Position);
//! 對定點資料做其他的處理
}
上面的代碼中process函數,就是我們要寫的shader函數,裡面對頂點資料進行處理,處理完成
後交給下一個渲染流程。下面的for循環函數,是又顯示卡内部控制,當然也是在顯示卡内完成,即當
我們在應用層調用OpenGL的函數 glVertex**或者glNormal等函數的時候,就是把頂點資料從
cpu傳遞給GPU,就會調用Process函數進行處理(實際遠比我說的複雜)。假設應用層有10萬
個頂點做計算,那麼Process函數就會被調用10萬次。試想這該是多麼大的計算量,當然這個相比
紋理來說還是小意思,當我們繪制一個圖檔處理的時候,每一個像素的繪制都要調用一個類似的處理
過程函數進行處理,假設有一個1024 × 1024 的圖檔繪制出來,需要的計算量大家可想而知,說
這個的道理在于我們要認識到顯示卡的強大計算能力。
廢話不說,看下面的一個代碼片段,我們進行分析:
void main( void )
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
上述的代碼是一個最簡單的頂點shader:
gl_Position:是GLSL的一個内置變量,即輸出的丁點位置
gl_Vertex:是GLSL的一個内置變量,輸入的頂點位置。
gl_ModelViewProjectionMatrix:GLSL的内置變量:
儲存了 Project Matrix * View Matrix * Model Matrix的結果
Model Matrix:儲存了目前對頂點資料的縮放,旋轉,平移等操作
View Matrix :觀察矩陣 ,
Project Matrix:就是正交投影,或者透視投影的矩陣(調用 :glOrtho,或者 gluPerspective)
通過上面的介紹,想必大家已經多shader的工作原理已經有所了解了,下面介紹shader的使用步驟:
1.首先編寫一個shader,當然是文本方式(其實也可以是彙編方式,或者bin方式,後面介紹)
2.調用glCreateShaderObjectARB建立一個shader對象
3.将源檔案(就是shader 的程式)給shader對象
4.進行編譯
單獨的一個shader對象還不能使用,要想使用它,還需要建立一個shader program 對象,然後進行關聯
可以這樣來了解,shader object 類似我們編譯c++生成的obj檔案,将obj檔案連接配接生成一個exe.這個exe
就是shader program了。
5.建立一個shader program
6.關聯shader object 到 shader program
7.進行連結
8.使用這個程式。
const char *source[1];
source[0] = vertexShaderSource;
//1 建立一個定點shader,了解成對源碼進行編譯
g_vertexShader = glCreateShaderObjectARB( GL_VERTEX_SHADER_ARB );
//2 指定資料(就是代碼)
glShaderSourceARB( g_vertexShader, 1, source, NULL );
//3 編譯
glCompileShaderARB( g_vertexShader);
//4 看編譯成功了沒有
glGetObjectParameterivARB( g_vertexShader, GL_OBJECT_COMPILE_STATUS_ARB, &bVertCompiled );
//5 編譯失敗,列印錯誤的原因
if( bVertCompiled == false )
{
glGetInfoLogARB(g_vertexShader, sizeof(temp), NULL, temp);
MessageBoxA( NULL, temp, "Vertex Shader Compile Error", MB_OK|MB_ICONEXCLAMATION );
}
//6 建立一個程式對象,可以了解成exe
_programObj = glCreateProgramObjectARB();
//7 将頂點shader與程式綁定
glAttachObjectARB( _programObj, g_vertexShader );
//8 連結過程
glLinkProgramARB( _programObj );
glGetObjectParameterivARB( _programObj, GL_OBJECT_LINK_STATUS_ARB, &bLinked );
代碼下載下傳
我的QQ13697826