opengl 当调用glDraw*Instanced()时,primcount大于顶点属性可以更新的次数时,会发生什么情况?

wyyhbhjk  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(113)

在我的opengl程序(opengl 3.3核心配置文件)中,我有一个包含N浮点元素的数组。我将该数组传递给VBO,并将其指定为索引为0的顶点属性数组。这里data是该数组:

glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, sizeof(float), (void*)0);

我希望每个示例更新一次属性,因此

glVertexAttribDivisor(0, 1);

问题是,当程序被告知通过调用glDraw*Instanced()来绘制对象的N * N示例时,会发生什么?
数组中只有N元素,所以我猜第一个N示例将按预期绘制。但之后会发生什么?它会再次循环数组以绘制另一组N示例,然后再次绘制另一组,然后再绘制另一组,依此类推,直到绘制完所有的示例吗?或者,它是否只是将属性0当作它被设置为NULL或其他值来处理剩余的N * (N - 1)示例?如果是这样,是否有办法让它像上面描述的那样在数组中循环?
我能想到的唯一解决方案是不将数组示例化,并将其大小更改为N * N,其中的值重复N次,但这将占用不必要的内存量。

niwlg2el

niwlg2el1#

如果渲染的顶点数超过缓冲区对象中的存储空间,则会出现完全相同的情况:越界读取。如果在您的上下文中启用了可靠的内存访问,则此值将为零或缓冲区对象存储中的某个其他值。但是,如果没有可靠的访问,越界读取将导致未定义的行为,并且“可能导致GL中断或终止”。
所以......别这样。
如果是这样,是否有办法让它像上面描述的那样在阵列中循环?
一定要这样吗?
你传递给glVertexAttribDivisor的除数是一个 divisor。如果它不为零,它会取示例索引并除以除数,结果会作为示例数组的索引。所以如果你传递N作为除数,这意味着第一个N示例从索引0处得到值,接下来的N示例从索引1处得到值。等等。
这将以与您想要的“循环”行为不同的顺序进行迭代,但它最终会执行相同的操作。
请注意,除非有其他示例数组涉及不同的除数,或者顶点着色器使用gl_InstanceID,否则所有这一切都将是渲染相同的东西N次。这可能是无用的。

相关问题