FengGUI inherits texture transformations

Unfortunately FengGUI seems to be inheriting any texture transformations left behind by jme. So, if the scene has objects with textures that have transformations applied to them, FengGUI graphics gets all messed up.



So far I have figured out a work around by resetting the texture matrix before rendering feng gui.


GL11.glMatrixMode(GL11.GL_TEXTURE);
GL11.glLoadIdentity();
fengDisplay.display();



Do I have to invalidate states if I do that? Is there a way to fix this without calling OpenGL directly?

If you want to test this, just copy paste FengGui - jME example from jME wiki and then add a texture state to the the box and scale the texture.


... initialization code
      // Rotate the box 25 degrees along the x and y axes.
      Quaternion rot = new Quaternion();
      rot.fromAngles(FastMath.DEG_TO_RAD * 25, FastMath.DEG_TO_RAD * 25, 0.0f);
      box.setLocalRotation(rot);
      
// this is the added part
      try {
         ResourceLocatorTool.addResourceLocator(
               ResourceLocatorTool.TYPE_TEXTURE,
               new SimpleResourceLocator(
                     this.getClass().getClassLoader().getResource(
                           "jmetest/data/images/Monkey.jpg")));
      } catch (URISyntaxException e) {
         e.printStackTrace();
      }
      
      Texture tex = TextureManager.loadTexture(
            "Monkey.png",
            Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR, 1.0f, true);
      float scale = 0.5f;
      tex.setScale(new Vector3f(scale, scale, scale));
      TextureState ts = display.getRenderer().createTextureState();
      ts.setTexture(tex);
      box.setRenderState(ts);
// end of the added part

      // Attach the box to the root node
      rootNode.attachChild(box);
... the rest of the initialization code

It seems that FengGUI also inherits GLSL program left behind… so now my fix is:



GL11.glMatrixMode(GL11.GL_TEXTURE);
GL11.glLoadIdentity();
GL20.glUseProgram(0);
fengDisplay.display();



DisplaySystem.getCurrentContext().invalidateStates() only invalidates the jme idea of what the states are. It is possible to actually reset the states in OpenGL to some defauls?
glPushAllAttribs() doesn't seem to work here, because that's the first thing FengGUI does.

You could apply the default jME states… I guess one way to do that would be to make some very simple TriMesh with no applied states (remember to updateRS on it after creating though) and force it to draw right before the UI.

This might also work


for (int i = 0; i < RenderState.RS_MAX_STATE; i++){
     Renderer.defaultStateList[i].apply();
}

Yep, (well at least until we get rid of the static defaultStateList.)

You could apply the default jME states... I guess one way to do that would be to make some very simple TriMesh with no applied states (remember to updateRS on it after creating though) and force it to draw right before the UI.


But then the treemesh would show up on the screen. Would it still work if i hide that treemesh behind the camera or will it be culled by jme and hence no OpenGL commands are going to be issued?

Yep, (well at least until we get rid of the static defaultStateList.)

Are there plans to actually remove the default state list? Because that seems to be a more straightforward solution than a triMesh with default states.

It's possible that the default list will be per renderer object rather than static when we move to supporting multiple displays/canvases, etc.  You could still use them, it would just be accessed through the current renderer object.

Then how about a method to apply default states on using a renderer instance?

For example: DisplaySystem.getDisplaySystem().getRenderer().applyDefaultState(StateEnum.TextureState).

I've just tested with applying default texture states:


for (int i = 0; i < RenderState.RS_MAX_STATE; i++){
     Renderer.defaultStateList[i].apply();
}
fengDisplay.display();



The gui still gets bugged by objects with scaled textures present in the scene.

I have fixed this by applying another texture state as follows:


TextureState defaultTextureState;
Texture defTex = TextureState.getDefaultTexture().createSimpleClone();
defTex.setScale(new Vector3f(1, 1, 1));
defaultTextureState = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
defaultTextureState.setTexture(defTex);
defaultTextureState.apply();



It seems that applying defaultStates[RS_TEXTURE_STATE] does not reset texture transformations, which is somewhat counterintuitive, but makes sense one you look at the code.

meh, yeah.

awesome, accidentally stumbled across this and lex's workaround fixed it.

jME forums have saved me countless hours of figuring out what goes wrong. The greatest thing about the open source is the community. And I'm glad to be a part of it, thanx!  :slight_smile: