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

mjw*_*ach 3 opengl

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

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

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

typedef  struct {
    uint  count;
    uint  instanceCount;
    uint  firstIndex;
    uint  baseVertex;
    uint  baseInstance;
} DrawElementsIndirectCommand;
Run Code Online (Sandbox Code Playgroud)

假设没有生成错误,对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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Ret*_*adi 5

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

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

命令

    void DrawElementsIndirect( enum mode, enum type, const void *indirect );
Run Code Online (Sandbox Code Playgroud)

相当于

    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);
    } 
Run Code Online (Sandbox Code Playgroud)

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

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