使用glDrawArrays绘制多个模型

时间:2013-09-06 16:51:48

标签: c++ opengl 3d

我有一个结构来存储2个不同模型的顶点数据,一个是立方体,另一个是金字塔。

struct Model{
    GLuint vboID;
    GLfloat* vbo;
    GLuint vaoID;
    GLfloat* vao; 
    GLuint vertexStart;
    GLuint vertexCount;
};

我创建了vbos并生成了这样的缓冲区:

Model cubeModel;
Model pyramidModel;

cubeModel.vbo = cubeVerts; //A GLfloat array I created earlier in code earlier. 
cubeModel.vertexCount= sizeof(cubeVerts);//size of the GLfloat array in bytes

pyramidModel.vbo = pyVerts; 
pyramidModel.vertexCount= sizeof(pyVerts);

glGenBuffers(1, &cubeModel.vboID); //Generate a buffer for the vertices
glBindBuffer(GL_ARRAY_BUFFER, cubeModel.vboID); //Bind the vertex buffer
glBufferData(GL_ARRAY_BUFFER, cubeModel.vertexCount, cubeModel.vbo, GL_STATIC_DRAW);

然后画我用:

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, cubeModel.vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);

哪个有效,我成功地绘制了立方体,但我也一直在尝试多种方式来绘制金字塔。

我需要做什么才能同时在屏幕上渲染?

编辑:这是我特意尝试的,重复glBufferData()调用并传入金字塔数据,然后制作glDrawArays(GL_TRIANGLES,0,cubeModel.drawcount + pyramidModel.drawCount),计算顶点数据将堆栈和glDrawArrays将仔细检查一次性传递的所有几何体。

我也尝试过从glGenBuffers()到glDisableClientState()的两组指令,而是使用所有金字塔模型的数据。这很有趣,因为我的glDrawArrays是:

glDrawArrays(GL_TRIANGLES, 0, cubeModel.drawCount);
glTranslatef(4.0f,0.0f,0.0f);
glDrawArrays(GL_TRIANGLES, 0, pyramidModel.drawCount);

它最终绘制了一个非常混乱的金字塔2次,让我相信当我第二次刷两次glBufferData()时覆盖之前传递的数据。

编辑2:在阅读Andon的评论后,我编辑了一些代码以澄清事情,drawCount现在是vertexCount,而m_vertexBuffer现在正确引用我存储在cubeModel,cubeModel.vboID中的句柄,而不是使用旧的类变量I用来存放手柄。

1 个答案:

答案 0 :(得分:2)

我不想混淆评论部分,因为你的代码有很多问题。但我现在也没有时间经历所有这些,所以这是一种临时的答案。

glBufferData (...)在技术上不会覆盖以前传递的数据,它会做得更糟。每次调用glBufferData (...)时,它都会创建一个您传递的大小的新数据存储,并(可选)使用您提供的数据填充它(如果您传递的内容为非NULL)。更像是调用free (...)然后调用malloc (...)delete [] ...new Type [...]

glBufferSubData (...)是将顶点附加到顶点缓冲区的首选技术。不幸的是,它没有调整数据存储的大小。有时,过度分配VBO并推迟提供数据直到稍后(使用glBufferSubData)。

如果使用一个VBO存储两个模型,则需要知道每个模型的起始顶点和顶点数,因为它与VBO的数据相关。现在你所知道的就是顶点的数量(并且你将它命名为drawCount而不是vertexCount)。对于大多数人来说,drawCount表示要绘制内容的次数,而不是它包含的顶点或元素的数量。

glBufferData (...)的调用的大小字段应该是顶点数据的字节大小。现在你传递了顶点的数量。您可能更倾向于使用sizeof (YourVertexDataStructure)作为单个顶点的大小(在这种情况下为sizeof (float [3])),以及类似sizeof (cubeVerts) / sizeof (YourVertexDataStructure)来计算顶点数实际上存储在这个数组中。然后传递给glBufferData (...)的大小为:_size * count _