我想知道有关顶点缓存管理的最佳做法是什么。
实际上,我阅读了很多关于这个主题的文章,但我还不相信我应该使用的最佳选择。
我正在编写一个小型3D渲染引擎,我的目标是通过限制绘制调用的数量以及缓冲区绑定的数量来优化此渲染!
直到这里,我在一个批次内收集共享相同材料属性(相同的光照模型属性和纹理)的对象的所有顶点。如果VBO重新分配失败(GL_OUT_OF_MEMORY),那么我创建一个新的VBO来存储我的对象的顶点。最后,我将每个批次附加到VAO。
的伪代码:
for_each vbo in vbo_list
{
vbo->Bind();
for_each batch in vbo->getAttachedBatchList()
{
batch->BindVAO();
{
glDrawXXX(batch->GetOffset(), batch->GetLength());
}
}
}
一切运作良好,但我使用的技术是最有效的吗?
我看了下面的文章(OpenGL ES - Mac): https://developer.apple.com/library/ios/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html
本文建议存储 Interleaved Vertex Data ,如下所示(对于3个给定的顶点):
VNTVNTVNT
在我的情况下,我使用以下模式:
VVVNNNTTT
关于这个主题的另一篇文章:https://www.opengl.org/wiki/Vertex_Specification_Best_Practices
根据你的说法,我的最佳选择是什么?
最后我根据顶点数据对齐进行了另一次询问(该主题在第一篇文章中有所介绍)。它说"避免错位顶点数据"。显然,该建议只适用于案例 VNTVNTVNT 。
例如,如果这种情况是最佳选择,则以下结构声明应该是正确的:
struct Vertex
{
float x, y, z; //12 bytes
float nx, ny, nz; //12 bytes
float s, t; //8 bytes
};
在sizeof(Vertex)= 32字节的情况下,这是4个字节的倍数!
如果我添加颜色成分r,g,b:
struct Vertex
{
float x, y, z; //12 bytes
float nx, ny, nz; //12 bytes
float r, g, b; //12 bytes
float s, t; //8 bytes
};
我们现在有44个字节,也是4个字节的倍数!
所以根据这篇文章,如果我以这种方式存储我的数据,它就不应该有这个错位的数据问题。
总结:我的伪代码是正确的吗?等待GL_OUT_OF_MEMORY异常来创建新的VBO是否正确?尊重最大分配规模是否更好?最后哪个是存储数据的最佳方式(Interleaved与否),我的数据对齐命题是否正确?
更新
它在第二篇文章中说:“"根据一个nVidia文件" 1MB到4MB是一个不错的尺寸。它似乎太小了!我想知道是否存在错误,因为我知道它可以存储更大量的数据(远远超过100 Mo,而不会出现当前硬件上的任何问题)。另外,像Dragon这样的着名模型无法存储在单个VBO上(这意味着在最好的情况下,这个网格的几何形状应该在4到5个VBO之间共享,所以5个绘制调用来渲染它。我可以&# 39;想象一下,在这种情况下,真实视频游戏场景中分配的VBO数量!)。你觉得怎么样?