Search code examples
openglgraphicstexturesopengl-compat

Why doesn't binding to the default texture with GL_REPLACE actually replace the color drawn?


When GL_TEXTURE_ENV_MODE is set to GL_REPLACE, drawing a vertex will use the color of the current texture coordinate in the currently bound texture.

I found out that binding to the default texture with glBindTexture(GL_TEXTURE_2D, 0) has the same effect as calling glDisable(GL_TEXTURE_2D).

However a Stackoverflow answer here quotes the OpenGL spec that "(3.9.2.Texture Access) sampling from an incomplete texture will return (0,0,0,1)", where the default texture is initially an incomplete texture.

So I think I should always get black objects drawn in the given case, but in practice it behaves as if texturing is disabled.

Why doesn't binding to the default texture with GL_REPLACE actually replace the color drawn?


Solution

  • First of all, the "default texture object" only exists in compatibility profile (or legacy GL contexts < 3.2).

    It now depends whether you sample from a texture in a shader or use the legacy fixed function pipeline. And since you care about the texuture environment, it means you are using the fixed function pipeline. And for that, you'll have to look up the compatibility profile specification too. The GL 4.6 compatibility profile spec clearly states in section 8.17.2 "Effects of Completeness on Texture Application":

    For fixed-function texture access, if texturing is enabled for a texture unit at the time a primitive is rasterized, and if the texture image bound to the enabled texture target is not complete, then it is as if texture mapping were disabled for that texture unit.

    This behavior has been that way since the very beginning of OpenGL, and it can't be changed in compatibility profiles as existing applications may depend on it. However, using the fixed function pipeline in 2022 is something you should do only with a very good reason.