c++ - 使用 glDrawArrays 绘制多个模型

标签 c++ opengl 3d

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

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

我创建 vbo 并像这样生成它们的缓冲区:

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 将一次遍历所有传递的几何体。

我还尝试制作了 2 组从 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,而不是使用旧的类变量我用于存储句柄。

最佳答案

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

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

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

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

调用 glBufferData (...) 的大小字段应该是顶点数据的大小(以字节为单位)。现在您正在传递顶点数。您很可能打算对单个顶点的大小使用 sizeof (YourVertexDataStructure)(在本例中为 sizeof (float [3])),以及类似 sizeof (cubeVerts)/sizeof (YourVertexDataStructure) 来计算这个数组中实际存储的顶点数。那么您传递给 glBufferData (...) 的大小将是:_size * count_

关于c++ - 使用 glDrawArrays 绘制多个模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18662756/

相关文章:

c++ - 围绕某个点旋转对象,即使原始枢轴不同?

unity-game-engine - 如何构造十二面体并对其侧面进行纹理处理

c++ - std::ofstream 构造函数阻塞

C++如何在DLL中存储程序的初始状态/识别未初始化的变量

c++ - 在 OpenGl 中旋转一个正方形

javascript - Three.js 水平 PlaneGeometry at x=0 y=0 z=0

math - 可微正交向量

c++ - get函数的stringstream不删除字符

带模板的 C++ Lambda

opengl - 如何使一个部分的颜色在 3D 对象上不同