上一次咱們在這裏分析了OpenGL的例子,可是最後還少分析最重要的部分:着色器相關的代碼。所以這一次做爲前一篇文章的續集。html
上一篇文章的地址 http://www.cnblogs.com/MyGameAndYOU/p/4609203.html編程
首先咱們回顧下以前的代碼數組
ShaderInfo shaders[] = { { GL_VERTEX_SHADER, "triangles.vert" }, { GL_FRAGMENT_SHADER, "triangles.frag"}, { GL_NONE, NULL} };
這裏的 triangles.vert 對應頂點着色器文件緩存
#version 430 core layout(location = 0) in vec4 vPosition; void main(){ gl_Position = vPosition; }
第一行#version 430 core 表示咱們所使用的4.3版本的OpenGL對應的GLSL語言,core表示使用OpenGL的核心模式。ide
若#version沒有設置,則默認使用110版本。函數
第二行layout(location=0) in vec4 vPosition 分配了一個着色器變量(着色器變量是着色器與外部世界的聯繫所在),就這麼一行也是包含了許多內容,咱們從右往左看:學習
一、vPosition指變量名稱,它所保存的是頂點的位置信息ui
二、vec4是GLSL中的一種數據類型,在這裏表示GLSL的四維浮點數向量,默認值爲(0,0,0,1),表示(x,y,z,w)。當有字段缺失時,會填充對應的默認值。spa
在第三篇,咱們將會進一步學習GLSL,這裏先淺嘗輒止。orm
三、in字段的話,表示設置這個變量,即vPosition爲着色器階段的輸入變量,指定了數據進入着色器的流向,在這裏表明數據從外部流入。
四、layout(location=0),這一字段很是重要,它將vPosition的位置屬性location設置爲0,爲它提供了元數據。
回顧以前的代碼,這一字段與glVertexAttribPointer以及glEnableVertexAttribArray產生了聯繫。使得咱們的着色器變量能夠得到相關聯的數據。
/** 函數原型:void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer); 以前咱們調用了glBindData所傳遞給緩存的只是數據,以後咱們要使用它,還必須指定數據類型。 因此該函數完成的主要任務是: 一、告訴OpenGL,該存儲數據的格式 二、由於咱們使用着色器來編程,所以在頂點着色器階段,咱們會使用該函數來給着色器中的in類型的屬性變量傳遞數據。 那麼它們是怎麼聯繫起來的呢? 即是經過第一個參數index,指明瞭着色器程序中變量的下標的做用。 例如:layout( location=index ) in vec4 position; 若是這個index和glVertexAttribPointer的第一個參數同樣,那麼相關緩存區的數據就會傳遞到這個position變量中去。 三、該函數執行以後,會影響改變VAO的狀態,VBO會被複制保存到VAO中。以後若是改變了當前所綁定的緩存對象,也不會改變到VAO裏的對象。 */ glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); /** 由於默認狀況下,頂點屬性數組是不可訪問的,因此咱們須要調用如下函數激活它。 範圍爲0到GL_MAX_VERTEX_ATTRIBS-1 */ glEnableVertexAttribArray(vPosition);
五、最後的main函數,不管是在哪個着色階段,都會有一個main函數。它所實現的就是將輸入的頂點位置複製到頂點着色器的指定輸出位置gl_Position中。
gl_Positon是一個內置變量,使用前不須要聲明。在OpenGL中,它表示輸出屬性-變換後的頂點的位置,用於後面的固定的裁剪等操做。全部的頂點着色器都必須寫這個值。
-------------------------------------------------------------------------------------------------------------------------------------------------------------
咱們再繼續看看片斷着色器的代碼
這裏的 triangles.frag 對應頂點着色器文件
#version 430 core out vec4 fColor; void main(){ fColor = vec4(0.0, 0.0, 1.0, 1.0); }
能夠看得出,幾乎全部着色器的基本結構都是這樣的。
咱們着重看看不一樣的地方
一、變量fColor使用的out類型的限定符,與以前的in相反,說明該着色器會將fColor所對應的數值輸出,這也是片斷所對應的顏色值。
二、fColor = vec4(0.0, 0.0, 1.0, 1.0)用一個四維向量設定了片斷的顏色值。事實上,OpenGL使用了RGBA的顏色空間,
-------------------------------------------------------------------------------------------------------------------------------------------------------------
自此,咱們完成了第一個OpenGL例子。仍是要再次說明的是
glVertexAttribPointer以及glEnableVertexAttribArray兩個函數指定了和頂點着色器的變量與存儲在緩存對象中數據的關係。
-------------------------------------------------------------------------------------------------------------------------------------------------------------
在學習過程當中,發現對VAO與VBO不是很明白的,能夠繼續看這一篇文章 【VAO與VBO】http://www.cnblogs.com/MyGameAndYOU/p/4678657.html
另外,若是有發現個人內容有錯誤,懇請告訴我,我會改正,謝謝!
過幾天,我會繼續寫第三篇 關於GLSL着色語言的。
2015.7.29
廣州