glVertexAttribDivisor和索引输入

9

各位好,我正在尝试在我的OpenGL实例绘图中使用glVertexAttribDivisor。

在NV显卡中它可行,但在ATI显卡中无效,没有进行任何绘制。

从GlExtensionViewer中可以看到这两个显卡都支持glVertexAttribDivisor/ InstancedStream,运行时也没有出现错误。

我不知道这是否是由于我的错误用法造成的。

我将实例数据放在单独的顶点数组缓冲区中,然后将其映射到gl_MultiTexCoord0~3中。实例数据是世界矩阵。

代码如下。

    for( int i=0;i<3;i++)
    {
        glClientActiveTexture(kGL_TEXTURE0 + i);
        glTexCoordPointer(size, type, stride, i*4*sizeof(float));

        int instanceVertexAttribIndex = i + 8;
        glVertexAttribDivisorARB(instanceVertexAttribIndex, 1);
    }

重点问题是,如果我尝试将实例数据放在gl_MultiTexCoord0上,那么我应该给glVertexAttribDivisorARB哪个正确的“index”?
1个回答

13

它对 NVIDIA 显卡有效,因为 NVIDIA 没有正确地实现 OpenGL 规范。

glVertexAttrbDivisorARB 仅适用于 通用属性。也就是用户定义的着色器属性。它不能在除了由 glVertexAttrib(I)Pointer 指定的属性之外的任何属性上工作。

NVIDIA 一直在实现属性别名的行为。例如,gl_MultiTexCoorc[0] 还具有属性索引 8 。例如,输入顶点位置的 gl_Vertex 具有属性索引 0。

问题?OpenGL 规范禁止使用这种方式。如果您尝试这样做,它会明确要求实现失败并报错。当您使用这些数组设置调用 glDraw* 时,您的实现应该会给出错误信息。

遗憾的是,您被困在 NVIDIA 的陷阱中:使用不符合规范但恰好在他们的驱动程序上运行的行为。我想您肯定是从某个 NVIDIA 论文中得到了这个想法。所以现在您必须改变所有代码,使用用户定义的属性而不是内置属性。

哦,如果您想知道在规范的哪里说这个,可以查看 OpenGL 3.3 兼容性概要文件,第 94 页的最底部:

不能使用常规属性别名通用属性。


再问一句,您的意思是顶点位置gl_Position不应该有属性索引0吗?还是传统顶点属性(如gl_Position、gl_Normal)的索引信息不应该对外显式或固定? - giggle
@giggle:我的意思是你不能使用任何通用属性命令来影响内置属性的值,比如gl_Position、gl_Normal等。 - Nicol Bolas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接