opengl中VAO,VBO,IBO用法小結


這三個玩意全面取代舊社會的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。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM