我编写了一个OpenGL应用程序,它运行正常,我只是想提高它的性能。当然,一个好方法是在一个独特的VBO中打包几个网格(当然要小心顶点的数量)。所以我不是在谈论巨大的场景,但在我的情况下,只有2个网格(一个平面和一个立方体)的简单场景。这是我的场景的快速概述:
现在这里是这两个独立网格的一些统计信息(以字节为单位):
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?