在为glMultiDrawElementsIndirect指定的命令结构中,firstIndex参数的含义是什么?

时间:2015-03-25 05:40:57

标签: opengl

我不明白这个命令结构是如何工作的。所有这些似乎都有意义(在文档中;我还没有实际调用过函数),除了firstIndex。它看起来好像文档中有一个拼写错误,实际上。

以下是我在每个查找相关文档的地方看到的文字:

  

间接寻址的参数被打包到一个采用(C)形式的结构中:

typedef  struct {
    uint  count;
    uint  instanceCount;
    uint  firstIndex;
    uint  baseVertex;
    uint  baseInstance;
} DrawElementsIndirectCommand;
     

对glMultiDrawElementsIndirect的单次调用是等效的,假设没有生成错误:

GLsizei n;
for (n = 0; n < drawcount; n++) {
    const DrawElementsIndirectCommand *cmd;
    if (stride != 0) {
        cmd = (const DrawElementsIndirectCommand  *)((uintptr)indirect + n * stride);
    } else {
        cmd = (const DrawElementsIndirectCommand  *)indirect + n;
    }

    glDrawElementsInstancedBaseVertexBaseInstance(mode,
                                                  cmd->count,
                                                  type,
                                                  cmd->firstIndex + size-of-type,
                                                  cmd->instanceCount,
                                                  cmd->baseVertex,
                                                  cmd->baseInstance);
}

但是这些页面没有说明“类型大小”是什么意思,或者为什么它被添加到firstIndex,而不是说,乘以它。似乎glDrawElementsInstancedBaseVertexBaseInstance在那里采用了一个字节偏移量,所以对于我来说,将firstIndex作为GL_ELEMENT_ARRAY_BUFFER顶点索引数组的索引是有意义的 - 因此,索引的索引 - 以及类型的大小是顶点索引的大小(以字节为单位),你需要将“索引转换为索引数组”转换为该数组的字节偏移量。

但......转换将表示为乘法,他们说+不是*。 :(

我是对的吗? firstIndex是顶点索引数组中条目的索引,而size-of-type是顶点索引的大小(以字节为单位),还是+ a拼写错误?如果没有,我错过了什么?

1 个答案:

答案 0 :(得分:5)

这只是man page中的拼写错误。虽然手册页在官方网站上,但它们不是官方文档。它们经常包含错误或遗漏。

官方文档是规范文档。它确实有一个乘法而不是一个加法。从OpenGL 4.5规范的第353/354页开始:

  

命令

    void DrawElementsIndirect( enum mode, enum type, const void *indirect );
  

相当于

    typedef struct {
        uint count;
        uint instanceCount;
        uint firstIndex;
        int baseVertex;
        uint baseInstance;
    } DrawElementsIndirectCommand;

    if (no element array buffer is bound) {
         generate appropriate error
    } else {
        DrawElementsIndirectCommand *cmd =
            (DrawElementsIndirectCommand *)indirect;
        DrawElementsInstancedBaseVertexBaseInstance(mode,
            cmd->count, type,
            cmd->firstIndex * size-of-type,
            cmd->instanceCount, cmd->baseVertex,
            cmd->baseInstance);
    } 

所以firstIndex几乎就是你已经猜到的。它是索引缓冲区(也称为元素数组缓冲区)的偏移量,非常类似于glDrawElements()的最后一个元素。唯一的轻微皱纹是,在这种情况下,偏移量是以指数为单位测量的,而对于glDrawElements(),它是以字节为单位测量的。这就是乘以size-of-type的地方。

例如,假设您有一个包含类型为GL_UNSIGNED_SHORT的索引的元素数组缓冲区。您希望绘制命令从第50个索引开始使用此缓冲区中的索引。对于glDrawElements(),您将为最后一个参数传入100,因为偏移量以字节为单位,每个索引是两个字节。对于firstIndex中的glDrawElementsIndirect()值,您将使用50,因为它是以索引来衡量的。规范中乘以size-of-type,在这种情况下为2,说明了这种差异,如果将firstIndex设置为50,则字节偏移将为100,因此匹配用于glDrawElements()