[英]openGL 3.3 - VBO drawing with glDrawArrays / glDrawElements
我將VC ++ 2010與GLFW3和GLEW用於openGL。 我已經制作了一個OBJ-Loader,用於加載三角網格。 在某些時候,我將以下數組填充到VBOMesh2-object中。
GLfloat *vertices;
GLfloat *normals;
GLuint *indices;
因此,我得到了用於VBO的數據:
下一步是將緩沖區與VBOMesh2對象的init()方法綁定。 vertexVBOID,normalsVBOID和indexVBOID是GLuint。
void VBOMesh2::init(void)
{
vertexVBOID = 0;
glGenBuffers(1, &vertexVBOID);
glBindBuffer(GL_ARRAY_BUFFER, vertexVBOID);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*numFaces*3*3, vertices, GL_STATIC_DRAW);
normalsVBOID = 0;
glGenBuffers(1, &normalsVBOID);
glBindBuffer(GL_ARRAY_BUFFER, normalsVBOID);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*numFaces*3*3, normals, GL_STATIC_DRAW);
indexVBOID = 0;
glGenBuffers(1, &indexVBOID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBOID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*numFaces*3, indices, GL_STATIC_DRAW);
}
好的...,我用:
void VBOMesh2::draw(void)
{
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vertexVBOID);
glVertexPointer(3, GL_FLOAT, sizeof(float)*3, 0);
glEnableClientState(GL_NORMAL_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, normalsVBOID);
glNormalPointer(GL_FLOAT, sizeof(float)*3, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBOID);
glPushMatrix();
glTranslatef(x, y, z);
glRotatef(rx, 1, 0, 0);
glRotatef(ry, 0, 1, 0);
glRotatef(rz, 0, 0, 1);
glDrawArrays(GL_TRIANGLES, indices[0], numIndices);
glPopMatrix();
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
我可以用以下方式加載網格:
OBJLoader objLoader;
MeshData meshData;
objLoader.loadFile("temp/quad_smooth.obj");
meshData = objLoader.getMeshData();
VBOMesh2 tmpMesh(meshData);
並使用以下命令繪制(在openGL-Loop中):
tmpMesh.draw();
我得到以下結果:
精彩!
現在我想,讓我們用以下代碼繪制500個四邊形:
OBJLoader objLoader;
MeshData meshData;
objLoader.loadFile("temp/quad_smooth.obj");
meshData = objLoader.getMeshData();
for(int i = 0; i < 500; i++)
{
VBOMesh2 tmpMesh(meshData);
meshes.push_back(tmpMesh);
meshes[i].init();
// Do stuff for position and rotation like meshes[i].setX(x); and so on
}
在openGL循環中,我這樣做:
for(int i = 0; i < meshes.size(); i++)
{
meshes[i].draw();
}
順便說一句 meshes是一個向量:
vector<VBOMesh2> meshes;
我得到以下結果:
不好了!!!
現在我還不知道為什么我的網格物體(不是全部,而是有些)破裂了……還是我做錯了……。代碼可以渲染一個四邊形而沒有任何可視化錯誤,但是當我創建時500個具有相同meshData的四邊形(來自oneQuad的相同數據)我弄壞了四邊形。
而不是使用
glDrawArrays(GL_TRIANGLES, indices[0], numIndices);
我試過了
glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, 0);
為此,我用另一種方法填充了陣列的頂點,法線,索引(如有必要,可以將其張貼),但是我遇到了同樣的問題...我可以繪制一個沒有錯誤的四邊形,但是當我嘗試繪制500時Quads我遇到了訪問沖突0x000005。
順便說一句。 我更新了顯卡驅動程序(但問題仍然存在)
有人可以給我提示嗎?
不要使用std::vector<VBOMesh2>
,因為vector對值進行運算。 如果已實現~VBOMesh2
刪除數組,則可能正在繪制懸空指針(即indices[0]
)。 使用VBOMesh2
或std::vector<VBOMesh2*>
的簡單數組。
glDrawArrays(GL_TRIANGLES, indices[0], numIndices);
那不是繪制索引網格的方式。 第二個參數是您之前使用glVertexPointer
和glNormalPointer
綁定的數組的偏移量。 在您的情況下,該值應始終為0。
您需要確定是否要使用索引網格,您的問題尚不清楚。 如果這樣做,則需要使用glDrawElements
。 但是,頂點和法線數據的大小不正確。 但是我懷疑你知道這一點。 有點像您首先為索引網格實現了代碼,但是當它不起作用時,您嘗試將其轉換為非索引網格。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.