索引opengl中的越界索引

out of bound index in indices opengl

如果我在索引缓冲区中使用越界索引,然后调用 glDrawElements,会发生什么情况?!似乎在 OpenGL es 中它将使用默认常量值,例如,如果提供了具有 4 个位置的 3 种颜色,当我使用索引 3 时,它将使用纯黑色作为颜色。但在 WebGL 中,它会抛出 invalid operation。然而,这些结果只是在我的设备中,我在官方文件中找不到与此相关的任何内容。请任何人解释所有 OpenGL API(核心、es、WebGL)中记录的行为。

out-of-bounds 缓冲区访问的行为在所有规范中都有明确的措辞:

WebGL

对于 WebGL,相关部分是 "6.6 Enabled Vertex Attributes and Range Checking":

It is possible for draw commands to request data outside the bounds of a WebGLBuffer by calling a drawing command that requires fetching data for an active vertex attribute, when it is enabled as an array, either directly (drawArrays), or indirectly from an indexed draw (drawElements). If this occurs, then one of the following behaviors will result:

  1. The WebGL implementation may generate an INVALID_OPERATION error and draw no geometry.
  2. Out-of-range vertex fetches may return any of the following values:
    • Values from anywhere within the buffer object.
    • Zero values, or (0,0,0,x) vectors for vector reads where x is a valid value represented in the type of the vector components and may be any of: 0, 1, or the maximum representable positive integer value, for signed or unsigned integer components 0.0 or 1.0, for floating-point components

因此,兼容的 WebGL 实现可以执行上述任一操作。您使用的实现似乎会引发错误(这是允许的)。其他实现的行为可能不同,return 获取的顶点属性的一些常量值。

OpenGL 桌面

对于 OpenGL 桌面,相关部分是 "6.4 Effects of Accessing Outside Buffer Bounds":

Most, but not all GL commands operating on buffer objects will detect attempts to read from or write to a location in a bound buffer object at an offset less than zero, or greater than or equal to the buffer’s size. When such an attempt is detected, a GL error is generated. Any command which does not detect these attempts, and performs such an invalid read or write, has undefined results, and may result in GL interruption or termination.

因此,在这里,实现可以完全自由地对 out-of-bounds 缓冲区访问执行任何操作,例如在执行索引绘制调用时使用元素缓冲区中的 out-of-bounds 索引。

还有“稳健的缓冲区访问”功能,之前作为扩展KHR_robust_buffer_access_behaviour/ARB_robust_buffer_access_behavior公开,但在OpenGL 4.3中成为核心,明确定义了索引输出的行为顶点缓冲区的边界:

Robust buffer access can be enabled by creating a context with robust access enabled through the window system binding APIs. When enabled, indices within the elements array that reference vertex data that lies outside the enabled attributes vertex buffer objects, result in reading zero.

另请参阅 OpenGL 4.6 核心规范中的“10.3.7 稳健的缓冲区访问”部分。

OpenGL ES

在 OpenGL ES 3.2 之前,从索引绘制调用访问 out-of-bounds 顶点似乎是完全未定义的行为,这也可能导致程序终止。

从 OpenGL ES 3.2 开始,可以启用与 OpenGL 4.3 或 ARB_robust_buffer_access_behaviour 相同的“稳健缓冲区访问”功能。请参阅 the OpenGL ES 3.2 specification:

中的“10.3.5 稳健的缓冲区访问”部分

Robust buffer access is enabled by creating a context with robust access enabled through the window system binding APIs. When enabled, indices within the element array (see section 10.3.8) that reference vertex data that lies outside the enabled attribute’s vertex buffer object result in undefined values for the corresponding attributes, but cannot result in application failure.

在 OpenGL ES 3.2 之前仍有扩展 KHR_robust_buffer_access_behaviour 可以使用。