4

我一直想知道:OpenGL 对象“名称”、由 glGenTextures 生成的整数等似乎永远不会为零,所以我使用零来表示未初始化的句柄并检查错误。到目前为止一切正常。

我还被告知,在完成一个对象后调用 glBind*(0) 是一种很好的做法,以确保之后不会意外操纵挥之不去的绑定对象。听起来很明智。

是否存在 OpenGL 对象 ID 为零的情况,使我的测试无效,或者以这种方式使用零会产生令人惊讶的效果,因为它不引用非对象?

PS 零作为非对象有符号名称吗?

PPS 是否会因大量使用绑定/解除绑定模式而受到性能损失?(由于封装的原因,代码的某些部分大多具有冗余的重新绑定。)

4

5 回答 5

7

来自OpenGL 4.4 核心配置文件规范

每个对象类型都有一个对应的名称空间。对象的名称由 uint 类型的无符号整数表示。名称 0 由 GL 保留;对于某些对象类型,零命名该类型的默认对象,而在其他对象类型中,零永远不会对应于该对象类型的实际实例。

您可以依靠名称生成函数(例如GenBuffers)永远不会返回零作为生成的名称。您可以使用零来表示“没有对象”。

于 2013-08-12T18:02:25.573 回答
2

纹理名称零是保留的纹理名称,每当您删除纹理时,就好像它已绑定到纹理名称零。所以在这种情况下,它是一种一直在使用的特殊纹理名称。

glGenTextures()仅检索当前未使用的名称,并且由于正在使用零,因此您永远不应将其作为有效名称。

但是请注意,glIsTexture在零上使用将返回 false,因此从技术上讲,它不会被识别为纹理。

于 2013-08-12T18:01:52.427 回答
1

大多数检查 GL 对象(glIsTextureglIsBuffer等)有效性的函数在给定值为 0 时返回 GL_FALSE。因此,要回答您的第一个问题,我认为您的测试不会被破坏。

至于#2,是的。根据驱动程序和被绑定/解除绑定的对象,冗余绑定/解除绑定可能会导致性能下降。通常,出于性能原因 - 最好避免 OpenGL 中的状态更改(冗余或其他)。

希望这可以帮助。

于 2013-08-12T18:03:47.447 回答
1

是否存在 OpenGL 对象 ID 为零的情况,使我的测试无效,或者以这种方式使用零会产生令人惊讶的效果,因为它不引用非对象?

之后将对象绑定为零将永远不会使您的代码无效,除非以后的代码仍然希望该对象被绑定。至于任何令人惊讶的效果,只要您实际上没有将对象零用于任何事情,只要您没有对该对象执行任何操作,就可以了。

话虽这么说,这里是对象零不是非对象的所有 OpenGL 对象的综合列表:

  • 帧缓冲对象。零是默认帧缓冲区,它与非默认帧缓冲区非常特殊地对待。您可能需要在某些时候故意使用此默认对象;)

  • 顶点数组对象,但在兼容 OpenGL 中。在核心配置文件中,VAO 零不是有效对象。

  • 转换反馈对象,源自 GL-4.x 之前的功能。

  • 纹理对象。这些对象的行为非常奇怪和怪异,与常规纹理对象非常不同。切勿故意将数据放入其中;仅使用它们来取消绑定纹理。这可能是您将看到的最大的“令人惊讶的效果”。

PPS 是否会因大量使用绑定/解除绑定模式而受到性能损失?(由于封装的原因,代码的某些部分大多具有冗余的重新绑定。)

这种使用模式可能会导致性能问题。但是如果你的渲染代码是这样封装的,你可能会有很多其他的性能问题。例如,基于状态变化的排序必须非常困难。

于 2015-12-01T04:57:43.517 回答
0

是否存在 OpenGL 对象 ID 为零的情况,使我的测试无效,或者以这种方式使用零会产生令人惊讶的效果,因为它不引用非对象?

纹理。绑定纹理0glDisable(GL_TEXTURE_[1|2|3]D).

于 2013-08-12T18:00:24.850 回答