BUG: nodePath.clearTexture() does not clear texture stages

all-in-all texture stage support is a bit iffy. I had problems with extra texture stages being passed onto text and stuff. But putting this aside a hard call to clear all the texture does not work either … there appears to be no way to remove a texture stage after is been given.

    print "before texture clean"
    tsc = node.findAllTextureStages()
    print tsc,type(tsc)
    node.clearTexture()
    print "after texture clean"
    tsc = node.findAllTextureStages()
    print tsc,type(tsc)
before texture clean
TextureStage glow
TextureStage color
 <type 'libpanda.TextureStageCollection'>
after texture clean
TextureStage glow
TextureStage color
 <type 'libpanda.TextureStageCollection'>

Then, How do you remove a texture stage???

the only way i found to do that is to check the sort of the stages found there and pick a lower sort

 p = 100
    tsc = node.findAllTextureStages()
    for i in range(tsc.getNumTextureStages()) :
        ts = tsc.getTextureStage(i)
        if ts.getSort() < p:
            p = ts.getSort()
    p-=1    
    colorTex = loader.loadTexture(rgba)
    #model.setTexture( colorTex)
    #return
    colorStage = TextureStage('color')
    colorStage.setSort(-1+p)
    #colorStage.setPriority(p)
    colorStage.setMode(TextureStage.MReplace)       
    node.setTexture(colorStage, colorTex)
            
    bstgTex = loader.loadTexture(bstg)
    bstgStage = TextureStage('glow')
    bstgStage.setSort(0+p)
    #bstgStage.setPriority(p)
    node.setTexture(bstgStage,bstgTex)
    
    tsc = node.findAllTextureStages()
    print "========",node,"======="
    for i in range(tsc.getNumTextureStages()) :
        print tsc.getTextureStage(i)
======== render/breeze-tb.egg/-PandaNode/Breeze/hull.26/tur-ballplasma.5 =======
TextureStage glow, sort = 99, priority = 0
  texcoords = texcoord, mode = modulate, color = 0 0 0 1, scale = 1, 1, saved_result = 0

TextureStage color, sort = 98, priority = 0
  texcoords = texcoord, mode = replace, color = 0 0 0 1, scale = 1, 1, saved_result = 0

TextureStage glow, sort = 97, priority = 0
  texcoords = texcoord, mode = modulate, color = 0 0 0 1, scale = 1, 1, saved_result = 0

TextureStage color, sort = 96, priority = 0
  texcoords = texcoord, mode = replace, color = 0 0 0 1, scale = 1, 1, saved_result = 0

BUT IT IS SUPPER SLOWWWWW!!!

triple post! i am special! … the best way i found so far is to use setShaderInput. Then it always properly overrides the texture stage.

    node.setShaderInput('rgba',loader.loadTexture(rgba))
    node.setShaderInput('bstg',loader.loadTexture(bstg))

simply clearTexture() works here.
But there are 2 clearTexture functions.
How about this :

      print "before texture clean"
      tsc = model4.findAllTextureStages()
      tsc.output(ostream)
      for ts in range(tsc.getNumTextureStages()):
          model4.clearTexture(tsc[ts])
      print "\nafter texture clean"
      tsc = model4.findAllTextureStages()
      tsc.output(ostream);print
////////////////////////////////////////////////////////////////////
//     Function: NodePath::clear_texture
//       Access: Published
//  Description: Completely removes any texture adjustment that may
//               have been set via set_texture() or set_texture_off()
//               from this particular node.  This allows whatever
//               textures might be otherwise affecting the geometry to
//               show instead.
////////////////////////////////////////////////////////////////////
void NodePath::
clear_texture() {
  nassertv_always(!is_empty());
  node()->clear_attrib(TextureAttrib::get_class_type());
}

////////////////////////////////////////////////////////////////////
//     Function: NodePath::clear_texture
//       Access: Published
//  Description: Removes any reference to the indicated texture stage
//               from the NodePath.
////////////////////////////////////////////////////////////////////
void NodePath::
clear_texture(TextureStage *stage) {
  nassertv_always(!is_empty());

  const RenderAttrib *attrib =
    node()->get_attrib(TextureAttrib::get_class_type());
  if (attrib != (const RenderAttrib *)NULL) {
    CPT(TextureAttrib) tsa = DCAST(TextureAttrib, attrib);
    tsa = DCAST(TextureAttrib, tsa->remove_on_stage(stage));
    tsa = DCAST(TextureAttrib, tsa->remove_off_stage(stage));

    if (tsa->is_identity()) {
      node()->clear_attrib(TextureAttrib::get_class_type());

    } else {
      int priority = node()->get_state()->get_override(TextureAttrib::get_class_type());
      node()->set_attrib(tsa, priority);
    }
  }
}

Note that clearTexture() only removes the TextureStages that have been applied at that particular node. If the TextureStage has been applied at a lower level, or if you applied it at that node and that moved it to a lower level with one of the flatten calls, then clearTexture() will not remove it.

The purpose of clearTexture() is not to turn off TextureStages. Its purpose is to remove any texture specification you have previously applied to that particular node.

If you want to turn off a TextureStage from a parent node, the method to use is:

node.setTextureOff(stage, priority)

where priority is whatever priority level you need to override the lower attribute.

David

it seems like domination is eating parts function headers

some thing has to be done about that.
i dont want to turn off a texture sage i just want to replace it with a new one.

The RenderState contains a TextureAttrib. The TextureAttrib defines a set of texture stages to be applied to the Geom.

The net RenderState (and hence the next TextureAttrib) to be applied to the Geom is accumulated by composing RenderStates from the root of the graph.

At any given node level, the RenderState might apply a new TextureAttrib. The new TextureAttrib is composed to the working TextureAttrib so far accumulated from the root. By the time you reach a Geom, the final TextureAttrib is the result of all of the accumulations of TextureAttribs at that node and above.

Each TextureAttrib can add a certain set of TextureStages and/or remove a certain set of TextureStages from those specified above. Also, a low-priority TextureStage will not affect a parent TextureStage with a higher priority.

So: at a particular node, you can turn off the TextureStage you don’t want and add the TextureStage you do want. Or, you can replace the texture associated with a particular TextureStage with a different texture.

If you also specify a priority on that node, then no lower TextureAttribs will further influence the resulting texture combination, by either adding or removing TextureStages. This is helpful when you want to shadow a TextureStage that is enabled at a lower level, but this trick cannot be used to shadow just one TextureStage while allowing other TextureStage changes to also be applied from a lower level.

So, if you want to remove just one particular TextureStage from the final state, but leave other TextureStages alone, it’s best to do it on the node that specifies this TextureStage, or somewhere below that node, and not specify a priority.

David

David,

After this texture stage complexity what do you have any thing against using:

    node.setShaderInput('rgba',loader.loadTexture(rgba))
    node.setShaderInput('bstg',loader.loadTexture(bstg))

Is there some performance problems i should be aware of? This works for me except when shader get disabled but that is ok because my game cant really be run without shaders any ways.

I don’t see a problem with that. You’re just telling the shader precisely which textures you want to use, stepping around Panda’s built-in mechanism. Only downside is that Panda won’t know which sets of UV coordinates to send down, if you are using multiple UV coordinates, but maybe that doesn’t matter to you.

David

Well i am not using multiple UV cords so i guess i am set. Could i also name my data tables so that i can get them through shader. Thanks David! You are awesome.