【发布时间】:2014-01-16 10:22:42
【问题描述】:
在这个问题中,我对 OpenGL 中的缓冲区绘图很感兴趣,特别是在每个数据集使用一个缓冲区与为多个数据集使用一个缓冲区的权衡。
上下文:
考虑一个包含 N 个顶点的数据集,每个顶点由一组属性(例如颜色、纹理、法线)表示。 每个属性都由一个类型(例如 GLfloat、GLint)和许多组件(2、3、4)表示。我们想绘制这些数据。示意图,
(non-interleaved representation)
data set
<-------------->
a_1 a_2 a_3
<---><---><---->
a_i = attribute; e.g. a2 = (3 GLfloats representing color, thus 3*N Glfloats)
我们想将其映射到 GL 状态,使用 glBufferSubData。
问题
映射时,我们必须跟踪内存中的数据,因为glBufferSubData 需要start 和size。这听起来像是一个分配问题:我们想要分配内存并跟踪它的位置。由于我们希望快速访问它,我们希望数据位于相同的内存位置,例如带有std::vector<char>。示意图,
data set 1 data set 2
<------------><-------------->
(both have same buffer id)
我们承诺 gl 状态为:
// id is binded to one std::vector<char>, "data".
glBindBuffer(target, id);
// for each data_set (AFTER calling glBindBuffer).
// for each attribute
// "start": the start point of the attribute.
// "size": (sizeof*components of the attribute)*N.
glBufferSubData(target, start, size, &(data[0]))
(non non-interleaved for the sake of the code).
当我们想要添加或删除顶点时,就会出现问题,例如当 LOD 改变时。因为每个数据集必须是一个块,例如允许交错绘制(即使在非交错中,每个属性都是一个块),我们最终会在我们的std::vector<char> 中产生碎片。
另一方面,我们也可以为每个缓冲区设置一个块:我们不是将块分配给同一个缓冲区,而是将每个块(现在是 std::vector<char>)分配给不同的缓冲区。示意图,
data set 1 (buffer id1)
<------------>
data set 2 (buffer id2)
<-------------->
我们将数据提交到 gl 状态:
// for each data_set (BEFORE calling glBindBuffer).
// "data" is the std::vector<char> of this data_set.
// id is now binded to the specific std::vector<char>
glBindBuffer(target, id);
// for each attribute
// "start": the start point of the attribute.
// "size": (sizeof*components of the attribute)*N.
glBufferSubData(target, start, size, &(data[0]))
问题
我正在学习这个,所以,在以下任何一个之前:这个推理是否正确?
假设是,
- 拥有任意数量的缓冲区是否有问题?
- “glBindBuffer”是否会随着缓冲区的数量而扩展?
- 在此决定中需要考虑哪些要点?
【问题讨论】:
标签: opengl