簡體   English   中英

openGL 3.3-使用glDrawArrays / glDrawElements的VBO繪圖

[英]openGL 3.3 - VBO drawing with glDrawArrays / glDrawElements

我將VC ++ 2010與GLFW3和GLEW用於openGL。 我已經制作了一個OBJ-Loader,用於加載三角網格。 在某些時候,我將以下數組填充到VBOMesh2-object中。

GLfloat *vertices;
GLfloat *normals;
GLuint *indices;

因此,我得到了用於VBO的數據:

  • 頂點:頂點= [v0x,v0y,v0z,v1x,v1y,v1z,...]
  • (已排序)法線:法線= [n0x,n0y,n0z,n1x,n1y,n1z,...]
  • 指標:inices = {face0i0,face0i1,face0i2,face1i0,face1i1,face1i2,...]

下一步是將緩沖區與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個四邊形

不好了!!!

現在我還不知道為什么我的網格物體(不是全部,而是有些)破裂了……還是我做錯了……。代碼可以渲染一個四邊形而沒有任何可視化錯誤,但是當我創建時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] )。 使用VBOMesh2std::vector<VBOMesh2*>的簡單數組。

glDrawArrays(GL_TRIANGLES, indices[0], numIndices);

那不是繪制索引網格的方式。 第二個參數是您之前使用glVertexPointerglNormalPointer綁定的數組的偏移量。 在您的情況下,該值應始終為0。

您需要確定是否要使用索引網格,您的問題尚不清楚。 如果這樣做,則需要使用glDrawElements 但是,頂點和法線數據的大小不正確。 但是我懷疑你知道這一點。 有點像您首先為索引網格實現了代碼,但是當它不起作用時,您嘗試將其轉換為非索引網格。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM