cocos2D-X源碼分析之從cocos2D-X學習OpenGL(7)----GLSL

       上一篇博客介紹了cocos2d-x中的着色器類相關的結構,以及着色器的一些原理,這一篇將介紹着色器語言。

       GLSL(openGL shading langueage)openGL着色器語言可視爲一種類C語言幷包含某些擴展操作以及限制條件,從純語言觀點來看,GLSL語言包含了早期程序設計語言中的某些特徵,例如,某些特殊變量可訪問通過openGL應用程序設置的數據並置於板載寄存器中;針對於圖形需求,基於向量和矩陣的特定操作;特定變量類型,以反映基於變量實現、不同類型的操作;共享命名空間,以提供應用程序、頂點着色器以及片元着色器之間的通訊能力。

       廢話少說,我們從上一篇已經打開的着色器代碼中

#ifdef GL_ES
attribute mediump vec4 a_position;
attribute mediump vec2 a_texcoord;
attribute mediump vec4 a_color;

varying mediump vec4 v_color;
varying mediump vec2 v_texcoord;

#else

attribute vec4 a_position;
attribute vec2 a_texcoord;
attribute vec4 a_color;

varying vec4 v_color;
varying vec2 v_texcoord;

#endif

void main()
{
    v_color = vec4(a_color.rgb * a_color.a, a_color.a);
    v_texcoord = a_texcoord;

    gl_Position = CC_MVPMatrix * a_position;
}
       GLSL很類似於C代碼,它是一種強類型語言,所有變量都必須事先聲明,並且要給出變量的類型。變量名稱的命名規範與C語言相同,雖然所有的變量都需要聲明,但是我們可以在使用它們之前的任何時候聲明這些變量。這個頂點着色器的例子裏,我們在文件的開頭聲明瞭所需要的變量,首先用預編譯命令區分是否在openGL es下,我們可以發現,兩段聲明的不同之處,就是加入了mediump這個精度限定符,它使程序員可以指定着色器變量的計算精度,在較低的精度下,有些openGL es實現在運行着色器時可能更快,或者電源效率更高,當然,這種效率提升是以犧牲運算精度爲代價的,有可能會造成顯示的錯誤,精度限制符分爲高中低三檔,分別爲highp,mediump和lowp,我們可以在着色器開頭指定默認精度限制符,代碼如下:
precision mediump int;
       這樣一來,後面的所有int型的變量不用加精度限制符,就是中等的精度;如果不設置默認精度的情況下,頂點着色器中的int和float都是highp,也就是說都是高精度的;而在片段着色器中,就沒有默認精度了。

       attribute是一個類型限定符,它擴展了原有C語言功能集,它包括const,attrbute,uniform,varying等

       const:該變量爲編譯器常量,且無法在着色器外部使用,不可以被賦值。

       attribute:僅用於頂點着色器中,並以逐點方式通過應用程序進行設定,源自應用程序併發送到圖形卡中,比如例子中的位置a_position,貼圖a_texcoord和顏色a_color都是在上一篇中的應用代碼中傳入着色器中,並進行進一步處理,傳到圖形卡中。

       uniform:定義於着色器外部,不需要在着色器中傳遞,在使用它的着色器中聲明即可,它是隻讀類型,uniform變量通常被保存在硬件中,這個區域被稱爲“常量存儲”,是硬件中存儲常量的特殊空間,大小固定

       varying:是在着色器之間傳遞的變量,它可以由某一個着色器修改後傳遞給另外一個着色器,可以理解爲着色器間的傳遞值得變量,本例中的v_color和v_texcoord就是會傳遞給下一個片段着色器。

       在着色器之間傳遞的變量也用in或out來修飾,in變量是從着色器上一個管線中接收,並可視爲當前着色器的只讀變量。out變量從其定義的着色器獲取值,並把它傳遞到下一個着色器中,爲着色器中的只寫變量。另外這個修飾符也可以修飾函數的參數。

       着色器的控制流語句,函數和數組與c語言的使用別無二致,這裏就不再贅述了。

       片段着色器的代碼如下:

#ifdef GL_ES
varying mediump vec4 v_color;
varying mediump vec2 v_texcoord;
#else
varying vec4 v_color;
varying vec2 v_texcoord;
\n#endif\n

void main()
{
    gl_FragColor = v_color*step(0.0, 1.0 - length(v_texcoord));
}
       可以看到接受了頂點着色器傳來的數據並做了進一步處理,step和length都是內建函數,openGL有很多內建函數,處理通常在着色器中進行各種計算任務,具體的內建函數會在用到時詳細說明。

       下一篇將介紹貼圖

       能力不足,水平有限,如有錯誤,歡迎指出。

       

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章