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