0

我将 VC++2010 与 GLFW3 和 GLEW 用于 openGL。我制作了一个 OBJ-Loader 来加载三角网格。在某些时候,我将以下数组填充到 VBOMesh2 对象中。

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();
}

顺便提一句。网格是一个向量:

vector<VBOMesh2> meshes;

我得到了以下结果:

500个四边形

不好了!!!

现在我不知道为什么我的网格(不是全部,而是一些)被破坏了......或者我做错了什么......代码可以渲染一个四边形而没有任何可视化错误,但是当我创建500 个具有相同 meshData 的四边形(来自 oneQuad 的相同数据)我的四边形坏了....

而不是使用

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

我试过了

glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, 0);

为此,我用另一种方法填充了数组顶点、法线、索引(如有必要,我可以发布),但我遇到了同样的问题......我可以绘制一个没有错误的 Quad 但是当我尝试绘制 500 Quads 我遇到访问冲突 0x000005。

顺便提一句。我更新了我的显卡驱动程序(但问题仍然存在)

有人可以给我一个提示吗?

4

1 回答 1

0

不要使用std::vector<VBOMesh2>,因为 vector 对值进行操作。如果您已实现~VBOMesh2删除数组,则可能正在绘制悬空指针(即indices[0])。使用一个简单的VBOMesh2's 或. 数组std::vector<VBOMesh2*>

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

这不是您绘制索引网格的方式。glVertexPointer第二个参数是您之前使用和绑定的数组的偏移量glNormalPointer。在您的情况下,它应该始终为 0。

您需要决定是否要使用索引网格,您的问题并不清楚。如果这样做,则需要使用glDrawElements. 但是,您的顶点和法线数据的大小不合适。但我怀疑你知道这一点。看起来您首先为索引网格实现了代码,当它不起作用时,您尝试将其转换为非索引网格。

于 2013-07-21T19:10:27.737 回答