我一直在想:OpenGL对象"名称",glGenTextures等生成的整数,似乎永远不会为零,所以我用零来指示未初始化的句柄并检查错误。到目前为止一切都还好。
我还被告知,在处理完一个对象后调用glBind*(0)是一种很好的做法,以确保延迟绑定的对象不会在之后被意外操纵。听起来很明智。
有没有任何情况下OpenGL对象ID为零,使我的测试无效,或者以这种方式使用零会产生令人惊讶的效果,因为它没有引用非对象?
附言:零作为非物体有符号名称吗?
p.p.S.大量使用绑定/解除绑定模式会对性能进行处罚吗?(由于封装,代码的某些部分大多具有冗余的重新绑定。)
来自OpenGL 4.4核心配置文件规范:
每个对象类型都有相应的名称空间。对象的名称由uint类型的无符号整数表示。零名称由总账保留;对于某些对象类型,zero命名该类型的默认对象,而在其他类型中为zero将永远不会对应于该对象类型的实际实例。
您可以依靠名称生成函数(例如GenBuffers
)从不将零作为生成的名称返回。您可以使用零来表示"无对象"。
纹理名称zero是一个保留的纹理名称,无论何时删除纹理,都将其绑定到纹理名称zer0。所以在这种情况下,它是一种特殊的纹理名称,一直在使用。
glGenTextures()
只检索当前未使用的名称,由于零正在使用,因此永远不应将其作为有效名称获取。
但是,请注意,在零上使用glIsTexture
将返回false,因此从技术上讲,它不被识别为纹理。
大多数检查GL对象(glIsTexture、glIsBuffer等)有效性的函数在给定值0时返回GL_FALSE。因此,为了回答你的第一个问题,我认为你的测试不会被破坏。
至于#2,是的。根据被绑定/未绑定的驱动程序和对象的不同,重复绑定/解除绑定可能会导致性能下降。通常,出于性能原因,最好避免OpenGL中的状态更改(冗余或其他)。
希望这能有所帮助。
有没有任何情况下OpenGL对象ID为零,使我的测试无效,或者以这种方式使用零会产生令人惊讶的效果,因为它没有引用非对象?
之后绑定零对象永远不会使代码无效,除非以后的代码仍然期望绑定该对象。至于任何令人惊讶的效果,只要你实际上没有对任何东西使用对象零,只要你没有对该对象执行任何操作,你就可以了。
话虽如此,以下是所有OpenGL对象的综合列表,其中零对象不是非对象:
-
帧缓冲区对象。零是默认的帧缓冲区,它与非默认帧缓冲区区别开来。您可能需要在某个时刻故意使用此默认对象;)
-
顶点阵列对象,但在兼容OpenGL中仅。在核心配置文件中,VAO零不是有效对象。
-
Transform Feedback对象,在GL-4.x之前的功能中有所扩展。
-
纹理对象。这些对象的行为非常奇怪,与常规纹理对象非常不同。切勿故意将数据放入其中;仅用于解除纹理绑定。这可能是你会看到的最大的"惊喜效应"。
p.p.S.大量使用绑定/解除绑定模式会对性能进行处罚吗?(由于封装,代码的某些部分大多具有冗余的重新绑定。)
这种使用模式可能会导致性能问题。但是,如果您的渲染代码是这样封装的,那么您可能会遇到许多其他性能问题。例如,基于状态变化进行排序一定非常困难。
有没有任何情况下OpenGL对象ID为零,使我的测试无效,或者以这种方式使用零会产生令人惊讶的效果,因为它没有引用非对象?
纹理。绑定纹理0
与glDisable(GL_TEXTURE_[1|2|3]D)
不完全相同。