GLShaderContext::disable_shader_texture_bindings

Unbinding a texture using glDisable(target) or glBindTexture(target,0) is equivalent right?

No, I don’t think so. The former disables the texturing engine altogether, the latter unbinds a particular texture.

David

So I think in this case GLP(BindTexture)(…) should be used instead of GLP(Disable)(…) ? Moreover texture arrays cannot be used with the fixed pipeline so they cannot be disabled, they can just be unbinded .

void CLP(ShaderContext)::
disable_shader_texture_bindings(GSG *gsg) {
  _last_gsg = gsg;
  if (!valid()) {
    return;
  }

#ifndef OPENGLES_2
  for (int i=0; i<(int)_shader->_tex_spec.size(); i++) {
    if (_shader->get_language() == Shader::SL_GLSL) {
      if (_shader->_tex_spec[i]._name == 0) {
        gsg->_glActiveTexture(GL_TEXTURE0 + _shader->_tex_spec[i]._stage);
      } else {
        gsg->_glActiveTexture(GL_TEXTURE0 + _shader->_tex_spec[i]._stage + _stage_offset);
      }
#ifdef HAVE_CG
    } else if (_shader->get_language() == Shader::SL_Cg) {
      CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
      if (p == 0) continue;
      int texunit = cgGetParameterResourceIndex(p);
      gsg->_glActiveTexture(GL_TEXTURE0 + texunit);
#endif
    } else {
      return;
    }
#ifndef OPENGLES
    GLP(Disable)(GL_TEXTURE_1D);
#endif  // OPENGLES
    GLP(Disable)(GL_TEXTURE_2D);
#ifndef OPENGLES_1
    if (gsg->_supports_3d_texture) {
      GLP(Disable)(GL_TEXTURE_3D);

Wait, I’m sorry. I was confused.

glDisable(target) is the correct way to unbind a texture. According to my OpenGL manual, glBindTexture(target, 0) actually binds texture 0, which is a special texture object created in the initial OpenGL state, and which is presumably rarely used in practice (so binding texture 0 may effectively disable texturing, but no guarantees).

David

mmh, but still glBindTexture(GL_TEXTURE_2D_ARRAY_EXT,0) is the only way to unbind a texture array. So probably I should have an “if else” somewhere.
By the way what happens when there is something like:

glActiveUnit(...)
glBindTexture(GL_TEXTURE_2D, id)
glBindTexture(GL_TEXTURE_3D, id)

Does the binding to the 3d texture automatically disable GL_TEXTURE_2D on that unit?

thanks a lot

I believe you still have to explicitly glEnable() the desired target, and glDisable() the no-longer-wanted target.

Reading the Texture Mapping chapter of the Redbook I just found out that, if more then one target is enabled on the same unit, the target with largest dimension, (in order: 1D,2D,3D,cubemap) will be actually disabled. But obviously for the sake of clarity target should be explicity disabled.

Mmh, I am not sure what to do at this point:

//glstuff/glShaderContext.cxx: line 933
    gsg->_glActiveTexture(GL_TEXTURE0 + texunit);

    GLenum target = gsg->get_texture_target(tex->get_texture_type());
    if (target == GL_NONE) {
      // Unsupported texture mode.
      continue;
    }
#ifndef OPENGLES_2
    GLP(Enable)(target);
#endif 

GL_TEXTURE_2D_ARRAY_EXT cannot be enabled or disabled so it seems like I have three options:

  1. if (target == TEX_ARRAY) continue;
  2. try { glEnable } catch ( is_a_tex_array ). should have better performances right?
  3. use the “Cg runtime way” to pass textures to the shader.
    4 never call glEnable/Disable and unbind from the active unit calling glBindTexture(…, 0) for any target.

It seems to me that the best option (and probably the correct one even without texture arrays issues) is the fourth one.

Any thoughts about it?

Thanks

I figured out that glEnable/glDisable do not have any effect when binding a texture to a shader. So I just got rid of them. Now the texture are unbinded through glBindTexture(target,0)