天天看點

OpenGL12-shader(GLSL)着色語言1(代碼已上傳)

OpenGL12-shader(GLSL)着色語言1(代碼已上傳)

    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

繼續閱讀