這三個玩意全面取代舊社會的glBegin/glEnd,顯示列表,頂點數組。
VBO為頂點緩沖區對象,用於存儲頂點坐標/頂點uv/頂點法線/頂點顏色,也可以用於其他用途,比如tangent。
IBO為索引緩沖區,里面的值可以是unsigned int或者unsigned short。
最后用VAO將多個VBO,IBO綁定到一起。
一個常規的網格模型就是VAO.attach(PositionVBO,TexcoordVBO,NormalVBO,IBO)
以下為VBO的創建,分配100字節的空間,未初始化:
GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER,100,0,GL_STATIC_DRAW);
以下為IBO的創建,分配100字節的空間,未初始化:
GLuint ibo; glGenBuffers(1, &ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER,100,0,GL_STATIC_DRAW);
以下為VAO的創建:
GLuint vao; glGenVertexArrays(1,&vao); glBindVertexArray(vao);
以下用VAO綁定VBO與IBO,
vt指綁定到的頂點着色器的input,通過glBindAttribLocation預先綁定
vs指該vbo中頂點的成分數,比如法線為3個float,uv為2個float
GLuint vt=0;
GLuint vs=3;
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBindBuffer(GL_ARRAY_BUFFER,vbo); glEnableVertexAttribArray(vt); glVertexAttribPointer(vt,vs,GL_FLOAT,GL_FALSE,0,0);
以下是繪制VAO,其中num為頂點數量。
int num=50;
glBindVertexArray(vao); if(ibo){ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo); glDrawElements(GL_TRIANGLES,num, GL_UNSIGNED_INT, 0); }else{ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glBindBuffer(GL_ARRAY_BUFFER,vbo); glDrawArrays(GL_TRIANGLES,0,num); }
以下是向VBO提交數據,無論提交全部還是部分都用這個,ibo類似
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glBufferSubData(GL_ARRAY_BUFFER,size,len,src);
以下為從VBO讀取數據,雖然該行為也能提交數據,但不推薦
float* data=(float*)glMapBuffer(GL_ARRAY_BUFFER,GL_READ_ONLY); memcpy(dest,data,mSize); glUnmapBuffer(GL_ARRAY_BUFFER);
可以用glBufferData重新分配空間,相當於c++的delete/new操作。
需要特別注意的是,在stackoverflow發現了這句話,如果你的VAO不能繪制出東西:
If you're on OpenGL-4 core, you need to create a VAO first, otherwise nothing will draw。