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