使用OpenGL渲染具有唯一VAO / VBO / IBO的场景

时间:2014-05-22 16:57:09

标签: opengl vbo opengl-3 vertex-buffer vao

我编写了一个OpenGL应用程序,它运行正常,我只是想提高它的性能。当然,一个好方法是在一个独特的VBO中打包几个网格(当然要小心顶点的数量)。所以我不是在谈论巨大的场景,但在我的情况下,只有2个网格(一个平面和一个立方体)的简单场景。这是我的场景的快速概述:

enter image description here

现在这里是这两个独立网格的一些统计信息(以字节为单位):

Plane mesh :
 - Vertex buffer :
   - position(size=48)
   - texture(size=32)
   - normal(size=48)
     -> Total = 128 bytes

Box mesh :
 - Vertex buffer :
   - position(size=312)
   - texture(size=208)
   - normal(size=312)
     -> Total = 832 bytes

目前,我的2个网格包含在一个独特的VBO中(当然我有一个唯一的IBO,它包含两个网格的索引)。这是我用来将所有数据存储在一个数组中的模式:

[P(plane)][T(plane)][N(plane)]|[P(cube)][T(cube)][N(cube)]
|0        |48       |80       |128      |440     |648

Caption : P (all position vertices), T (all texture vertices) and N (all normal vertices)

这是一个非常好的方法,但它迫使程序员(当然属于我:)可能是错的)为每个网格声明一个特定的VAO因为渲染我的2个网格的几何我必须将缓冲区偏移更改为将数据发送到着色器程序。

发送平面网格的数据:

glEnableVertexAttribArray(scene::VERTEX_POSITION);
glVertexAttribPointer(scene::VERTEX_POSITION, 3,
    GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(0));

glEnableVertexAttribArray(scene::VERTEX_TEXTURE);
glVertexAttribPointer(scene::VERTEX_TEXTURE, 2,
    GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(48));

glEnableVertexAttribArray(scene::VERTEX_NORMAL);
glVertexAttribPointer(scene::VERTEX_NORMAL, 3,
    GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(80));

Remark : Here, the offsets are 0, 48 and 80

发送立方体网格的数据:

glEnableVertexAttribArray(scene::VERTEX_POSITION);
glVertexAttribPointer(scene::VERTEX_POSITION, 3,
    GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(128));

glEnableVertexAttribArray(scene::VERTEX_TEXTURE);
glVertexAttribPointer(scene::VERTEX_TEXTURE, 2,
    GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(440));

glEnableVertexAttribArray(scene::VERTEX_NORMAL);
glVertexAttribPointer(scene::VERTEX_NORMAL, 3,
    GL_FLOAT, GL_FALSE, 0, OFFSET_BUFFER(648));

Remark : Here, the offsets are 128, 440 and 648

正如您可以通过这种方法看到的,我需要知道每个网格的3个偏移量。因此它意味着2个VAO(每个网格一个)。这是真的吗? (我想确保用这种方法用一个独特的VAO绘制这两个网格是不可能的 - 提前感谢这一点。)

PS:要渲染几何体,我使用函数glDrawRangeElements。所以在这个例子中,函数在循环中被调用了2次,当然还有不同的元素范围:

for the plane mesh :

glDrawRangeElements(GL_TRIANGLES, 0, 0, 6, GL_UNSIGNED_INT, OFFSET_BUFFER(0));

And for the cube mesh :

glDrawRangeElements(GL_TRIANGLES, 0, 6, 36, GL_UNSIGNED_INT, OFFSET_BUFFER(0));

现在我提出另一种方法,这次使用独特的VAO渲染所有几何体。这是新模式:

[P(plane)][P(cube)]|[T(plane)][T(cube)]|[N(plane)][N(cube)]
|0        |48      |360      |392      |600      |648

正如您所看到的那样,我将需要JUST 3 OFFSETS(0,360和600)来渲染所有几何体(当然,IBO将与之前的方法不同,并且将相应地构建)。所以在这里我需要一个独特的VAO!但这次我需要掌握我所有场景(所有顶点)的知识才能构建我的VBO(填充一次),这与之前我可以通过网格填充VBO网格几次的情况不同。你同意我的意见吗?

另一个问题:如果我想删除例如立方体,我无法删除VBO。那么方法在这里呢?我是否需要将我的'Mesh'类的布尔值'm_IsVisible'变为false? (我的网格将不再可见,但顶点将不会自由!)或者我是否需要释放顶点?我怎么能这样做?

您如何看待我的主张?哪一个最好?

我的例子中是否可以使用独特的VAO?

0 个答案:

没有答案