【发布时间】:2014-07-01 18:27:00
【问题描述】:
我使用 OpenGL 和 GLSL 开发了一个小型 3D 引擎。
我已经合并了一个顶点数据批处理系统,其目标是在一个唯一的顶点缓冲区对象 (VBO) 中收集共享相同着色器程序和相同转换的所有几何图形(所有对象),从而最大限度地减少状态更改(绑定)并绘制电话。
我目前使用函数 'glMultiDrawElements' 来渲染特定批次的数据(因此是一次绘制调用)。因此,例如,如果我的批次中有 3 个网格,我也有 3 个索引数组(每个网格一个),它们组织在一个“GLvoid **”数组(一个双数组)中。所以要渲染我的 3 个网格,我有一个独特的 glMultiDrawElements 调用,但我必须直接将参数中的双精度数组传递给函数。
但我想知道(关于性能问题)是否可以将所有元素(元素的双数组)存储在索引缓冲区对象 (IBO) 中(就像可以使用 glDrawElements 一样 -> 这里是一个简单的数组元素)并在 glMultiDrawElements 调用之前绑定它......我不这么认为,因为它是一个双数组而不是一个简单的数组,但也许(我希望如此)我错了。
这是一个使用 glDrawElements 的示例(伪代码):
[...]
//Setup data
[...]
#define OFFSET_BUFFER(offset) ((char*)NULL + offset)
foreach (pMeshGeometry from meshes) //iterates for each mesh of the scene
{
pMeshGeometry->GetIndexBuffer().Lock(); //Bind IBO
{
glDrawElements(pMeshGeometry->GetPrimitiveType(),
pMeshGeometry->GetIndexBufferSize(), pMeshGeometry->GetIndexBuffer().GetType(), OFFSET_BUFFER(0)); //Render a specific mesh eccording to indices
}
}
目前我以这种方式使用 glMultiDrawElement:
glMultiDrawElements(GL_TRIANGLES, &this->m_CountElementArray[0], GL_UNSIGNED_INT,
(const GLvoid **)&this->m_IndexAttribArray[0], this->m_CountElementArray.size()); //I enter the array of pointer directly in parameter
所以,也许下面的例子应该是可能的:
#define OFFSET_BUFFER(offset) ((char**)NULL + offset) //Something like this
glMultiDrawElements(GL_TRIANGLES, &this->m_CountElementArray[0], GL_UNSIGNED_INT,
OFFSET_BUFFER(0), this->m_CountElementArray.size()); //Something like this
因此,如果无法做到这一点,我想到了函数“glDrawRangeElements”。对于我将 3 个网格放入唯一 VBO 的示例,我只需要在每个 glDrawRangeElements 调用之前绑定一个 IBO(这里,每个网格有 3 个绘制调用 -> 所以是一个 glDrawRangeElements 循环)。所以这里显然可以使用 IBO。
这种方法肯定行得通,但我认为它不是最好的方法!我认为可以使用带有 IBO 的 glMultiDrawElements 来做到这一点,但我不知道该怎么做。
或许这真的不可能。也许在参数中直接输入索引数组的事实比使用 glDrawRangeElements 及其 IBO 的方法更快,因此在这种情况下使用 IBO 可能已被弃用,因此不适用。
你怎么看?
【问题讨论】:
-
请使用一些换行符。这个巨大的段落几乎无法阅读。
-
你到底在问什么?即使有换行符我也不确定。
-
对不起,我以为很清楚。总而言之,我想知道是否可以将 IBO 与 glMultiDrawElements 一起使用,而不是直接在参数中使用双索引数组。
-
@user1364743:没有“双数组”。有一组指针/偏移量。有ARB_multi_draw_indirect。但我不确定这是否是您要求的。
-
对不起,我想说的是指针数组而不是双数组。我已经使用“glDrawElements”方法更新了我的问题,添加了一个源代码(伪代码)示例。正如您在主循环之前看到的,我将所有顶点数据设置为 VBO,将所有索引数据设置为 IBO。之后,在主循环中我使用宏 OFFSET_BUFFER。这行得通。是否可以为函数“glMultiDrawElements”使用这样的宏(因此使用 IBO 而不是直接使用指针数组)?