繪制三角形
當我們把頂點數(shù)據(jù)發(fā)送給GPU后,我們還需要告訴GPU應該如何解讀這些數(shù)據(jù)。頂點的數(shù)據(jù)中包含頂點的各種屬性,這意味著我們必須手動指定輸入數(shù)據(jù)的哪一個部分對應頂點著色器的哪一個頂點屬性。
我們使用函數(shù)glVertexAttribPointer()告訴OpenGL該如何解析頂點數(shù)據(jù)。

index是頂點屬性的索引。在頂點著色器中,我們使用layout (location = index)來聲明對應的屬性變量。
size是每個頂點屬性的元素個數(shù),比如使用三維坐標(vec3)作為位置屬性,則size為3。
type是數(shù)據(jù)的類型,可以是GL_FLOAT、GL_INT等。
normalized指定是否將非浮點類型的數(shù)據(jù)規(guī)范化到范圍 [0, 1](如果是無符號整數(shù))或者 [-1, 1](如果是有符號整數(shù))。一般情況下,對于浮點類型的數(shù)據(jù),這個參數(shù)設置為GL_FALSE。
stride步長,即連續(xù)的頂點屬性組之間的間隔(字節(jié))。如果屬性緊密排列在一起,可以設置為0,OpenGL會自動計算步長。
pointer表示位置數(shù)據(jù)在緩沖中起始位置的偏移量,并進行強制類型轉換。
下一步要做的是啟用對應的頂點屬性——因為頂點屬性默認是禁用的,通過函數(shù)glEnableVertexAttribArray()。

當然,有啟用就有禁用,我們可以在不需要某個頂點屬性數(shù)組時將其禁用,通過函數(shù)glDisableVertexAttribArray()。

頂點數(shù)組對象
在傳統(tǒng)的固定渲染管線中,每次繪制之前都需要重新配置頂點屬性,這樣會導致重復的代碼,并且容易出錯。頂點數(shù)組對象的引入解決了這個問題。
頂點數(shù)組對象(Vertex Array Object,VAO)可以看作是一個容器,用于存儲指向頂點數(shù)據(jù)的指針以及頂點屬性的配置信息,它簡化了頂點數(shù)據(jù)的管理和繪制過程。我們可以將所有頂點屬性的配置信息存儲在VAO中,然后在需要繪制的時候,只需綁定對應的VAO即可,OpenGL會自動恢復為相應的配置狀態(tài)。
一個頂點數(shù)組對象會儲存以下這些內(nèi)容:
I. glEnableVertexAttribArray()和glDisableVertexAttribArray()的調用。
II. 通過glVertexAttribPointer()設置的頂點屬性配置。
III. 通過glVertexAttribPointer()調用與頂點屬性關聯(lián)的頂點緩沖對象。
使用VAO的基本流程如下:創(chuàng)建對象—綁定對象—配置頂點—解綁對象。
I.用glGenVertexArrays()生成VAO。

II.使用glBindVertexArray()綁定VAO。

III.使用glVertexAttribPointer()等函數(shù)配置頂點屬性數(shù)組。
IV.解綁VAO。
一個完整的流程示例:

繪制圖形
我們使用函數(shù)glDrawArrays()繪制基本圖元。

mode表示繪制的基本圖元類型,包括點、線段、三角形等。繪制三角形我們使用GL_TRIANGLES。
first指定從哪個頂點開始繪制,即頂點數(shù)組的起始索引。
count是要繪制的頂點數(shù)量。
我們使用之前創(chuàng)建的vertices數(shù)組來繪制一個三角形:

收尾
在渲染循環(huán)結束后,我們需要調用glDeleteVertexArrays()、glDeleteBuffers()以及glDeleteProgram()進行資源清理,它們分別用來刪除VAO、VBO和著色器程序對象。
