一、咱們先了解什麼是OpenGL對象(OpenGL Object)數組
根據OpenGL Wiki的定義:緩存
An OpenGL Object is an OpenGL construct that contains some state. When they are bound to the context, the state that they contain is mapped into the context's state. Thus, changes to context state will be stored in this object, and functions that act on this context state will use the state stored in the object.app
咱們知道OpenGL對象就是一個包含某些狀態的OpenGL結構。而當它們被綁定到上下文環境時,它們的所包含的狀態會被映射到上下文的狀態。也就是說,對上下文的狀態更改會存儲到該對象中,而且在這個上下文狀態下的函數將使用存儲在對象中的狀態。函數
OpenGL被定義爲狀態機(state machine),大部分API的調用會引發OpenGL的狀態發生變化,而OpenGL會使用當前的狀態進行渲染。前面所說的上下文,也便是OpenGL的上下文狀態。this
事實上,OpenGL Object就是封裝了一組特定的狀態以及相關能夠改變其狀態的函數。spa
二、VAO是什麼,以及它的做用?code
VAO全稱Vertext Array Object,意爲頂點數組對象,也是一個OpenGL Obejct。它是一個存儲了提供頂點數據所須要的全部狀態的OpenGL Object。orm
VAO存儲了頂點數據的格式,以及能夠提供頂點數據數組的緩存對象VBO。(It stores the format of the vertex data as well as the Buffer Objects providing the vertex data arrays.)對象
注意VAO並不存儲頂點數據,只是記錄了頂點相關的狀態(譬如頂點位置的格式以及頂點位置的數據、紋理座標的格式以及紋理座標的數據)。blog
做爲一個OpenGL Object,VAO也一樣有着對應的建立(glGenVertexArrays)、銷燬(glDeleteVertexArrays)、以及綁定(glBindVertexArray)函數。
另一個新建立的VAO默認對於全部屬性數組的訪問都是disable的,若是要啓用須要調用glEnableVertexArribArray,相反則是glDisableVertexAttribArray
(A newly-created VAO has array access disabled for all attributes. Array access is enabled by binding the VAO in question and calling)
頂點屬性的值在0到GL_MAX_VERTEX_ATTRIBS-1的範圍內。
VAO能夠想象爲鏈接頂點屬性數組以及VBO中的頂點數據的橋樑。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
三、咱們先了解什麼是Buffer對象(Buffer Object)
根據OpenGL Wiki的定義:
Buffer Objects are OpenGL Objects that store an array of unformatted memory allocated by the OpenGL context (aka: the GPU). These can be used to store vertex data, pixel data retrieved from images or the framebuffer, and a variety of other things.
由此咱們可得知,Buffer Object也是一種OpenGL Object,但它是指由OpenGl分配的內存區域,用來存儲頂點數據、從圖像或者幀緩存(framebuffer)取得的像素數據以及其餘數據。
四、VBO是什麼,以及它的做用?
VBO全稱是Vertext Buffer Object,是用來存儲頂點數組數據的緩存對象。
-----------------------------------------------------------------------
注意:The GL_ARRAY_BUFFER binding is NOT part of the VAO's state! 也就是說綁定到GL_ARRAY_BUFFER的類型不會影響到VAO的狀態,
以後須要調用glVertexAttribPointer纔會真正影響到VAO的狀態。
譬以下面代碼:
glBindBuffer(GL_ARRAY_BUFFER, buf1);// buf1被綁定到GL_ARRAY_BUFFER類型的緩存
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);// 頂點屬性索引0從buf1得到它的頂點數組
glBindBuffer(GL_ARRAY_BUFFER, 0);// OpenGL再也不綁定以前的GL_ARRAY_BUFFER類型緩存
那麼這樣以後,頂點屬性索引0與buf1之間如何聯繫呢?
咱們能夠這麼想,glBindBuffer設置了一個全局的變量,以後glVertexAttribPointer讀取了該全局變量而且將它存入VAO中。
因此改變了綁定的緩存對象以後,並不會影響到VAO裏的變量。事實上,OpenGL就是這麼工做的。
把頂點屬性索引index和緩存buffer聯繫起來的正是glVertexAttribPointer。這也是爲何GL_ARRAY_BUFFER不是VAO的狀態的緣由(This is also why GL_ARRAY_BUFFER is not VAO state)
可是注意若是當前是0綁定到GL_ARRAY_BUFFER時,調用glVertexAttribPointer會產生error。
2015.7.26
廣州