Help with jme anf fengGUI

Hi,



i have a problem with jme and fenggui. im using jme with several gamestates to display the menu, the game gui and the game(map, …). but when i pause the gui for the game and activate the menu, the game gui disappears and the menu appears but i can still click on the non existing game gui buttons.

i thing i had to clear a buffer but i dont know which.



thanks for the help



theplayer

i think i had similar problem, but i don't remeber exactly what i did.

Do you keep both GameStates active, or are you disabling the game when you display the Menu?

i leave the game enabled (for test its a rotating cube). only the game gui is paused and the menu started. should i remove in pause the feng input handler from the game gui???

later i will create a gameControlState and a gameDisplayState. in pause i will only pause the control state and leave the display state enabled. so you can see the game and on top the menu.



theplayer

you dont have to remove it, but when you display the GUI, you could disable the game inputhandler.



additionally in FengJMEInputHandler you have to check if the handler is enabled or not:

If not enabled, don't forward any button actions.



FengJMEInputHandler:


line 171
    private class MouseListener implements MouseInputListener {

        private boolean down;
        private int lastButton;

        public void onButton(int button, boolean pressed, int x, int y) {
            if (isEnabled() == false) {   // new
                return;                  // new
            }                            // new





btw:
recently i wrote a small FengGUI example using GameStates and StandardGame to show the problems that can appear with them.
-> FengGUI and GameStates

thanks for your help core-dump. ive readed (read?) your tutorial but i think ive forgotten the isEnabled if. tomorrow i will try it.



cool community and great help



theplayer



p.s. "my" rotating cube is your cube, but i dont copy & paste code so i can make mistakes and learn something.

I have a similar problem, my main menu GameState has a couple of GameMenuButtons that have IButtonPressedListener's attached to them.

When i enter my inGame GameState i disable the main menu via setActive(false), however i can still click on the invisible buttons because somehow the IButtonPressedListener's are still active.



How/where  do i disable them ?



edit

i checked the fengjmeInputhandler and this is not being updated anymore

Core-Dump said:


FengJMEInputHandler:


line 171
    private class MouseListener implements MouseInputListener {

        private boolean down;
        private int lastButton;

        public void onButton(int button, boolean pressed, int x, int y) {
            if (isEnabled() == false) {   // new
                return;                  // new
            }                            // new



so i dont think this would make any difference

I think you need to call setActive(false) on the fengGUI display also to stop it from intercepting clicks. Here is how it is done in my fengGUI gamestate:



public class GalaxyUIGameState extends GameState {
    private Display disp = null;

    public void buildUI() {
        disp = new Display(new LWJGLBinding());
        // Do stuff
        disp.layout();
    }

    public void render(float tpf) {
        // Do stuff
        disp.display();
    }

    public void setActive(boolean active) {
        super.setActive(active);
        disp.setEnabled(active);   // Necessary to stop the UI from intercepting events
    }
}

hmm i dont have a setEnabled(boolean) function for the fengGUI display  :expressionless:



im using this version of FengGUI 

http://user.cs.tu-berlin.de/~schabby/FengGUI/2007-08-15/

I guess you should update.



Might get a few errors though at first - I think they have refactored stuff a bit since then

I have found a very powerful way to use fengGUI is to create custom widgets for everything but the more robust built in widgets (scrollpane, text editor, etc).



Heres a snippet that may help get you going.


    private class CustomWidget extends Widget {
       
        Point tempPoint = null;
        Pixmap widgetTexture = null;
       
        private CustomWidget() throws Exception {
           
            String textureLocation = Utils.getTexturePath( Utils.TextureType.GUI_TEXTURE );
            widgetTexture = new Pixmap( Binding.getInstance().getTexture( textureLocation ) );
        }
       
       
        @Override
        public void paint(Graphics g) {
            // do draw stuff here, ex: g.drawScaledImage( widgetTexture, 0, 0, getWidth(), getHeight() );
        }
       
       
       
        @Override
        public void mousePressed( MousePressedEvent mp ) {

            // Set the coordinates relative to the object
            tempPoint.setXY( mp.getDisplayX() - this.getDisplayX(), mp.getDisplayY() - this.getDisplayY() );
        }
       
       
        @Override
        public void mouseEntered(MouseEnteredEvent mouseEnteredEvent) {
            // This is a custom method I added to the core-dumps FengHandler, to check for mouse over GUI elements
            getInputControl().getFengHandler().setMouseOverGui( true );
        }
       
        @Override
        public void mouseExited(MouseExitedEvent mouseExitedEvent) {
            getInputControl().getFengHandler().setMouseOverGui( false );
        }
       
    }

basixs said:

I have found a very powerful way to use fengGUI is to create custom widgets for everything but the more robust built in widgets (scrollpane, text editor, etc).

Heres a snippet that may help get you going.


So far I have only made the simplest use of FengGUI. Could you perhaps elaborate on what you have achieved (or one could achieve) with this method? Why is this superior to just using pre-built widgets?

Ok so i updated fengGUI from the svn from sourceforge i guess the one from java.net that is mentioned in the sticky post here is no longer valid



good news is disabling the display prevents it from receiving any mouseclicks



bad news is i now have the bug with fenggui textures that are overridden by jme



http://www.jmonkeyengine.com/jmeforum/index.php?topic=7347.0



I tried

   /**
     * Reset RenderStates before rendering FengGUI,
     * especially the TextureState.
     */
    @Override
    public void render(float tpf) {
        // set a default TextureState, tis is needed to not let FengGUI inherit
        // wrong Texture coordinates and stuff.
        Texture defTex = TextureState.getDefaultTexture().createSimpleClone();
        defTex.setScale(new Vector3f(1, 1, 1));
        TextureState defaultTextureState = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
        defaultTextureState.setTexture(defTex);
        defaultTextureState.apply();
        
        // render the GUI
        disp.display();
    }


as was mentioned  but this does not help.

I also tracked down the issue to the rendering que which i have set to opaque for my ingame state.
If i remove this statement fengGui is happy, my skybox ingame however is not as it is no longer rendered behind everything but instead is rendered like a normal box.

I might give those custom widgets a go but i don't think this will solve my current problem.

Any ideas ?

I have found that the best way to use fengGUI is through the pass system, it has less of an impact on transparency and such.  Also, make sure that it is the last thing to be rendered, if you are using a shadow pass that may have to be last with fengGUI being second to last.



Also, what are you placing in the opaque render queue? I have found that placing the rootNode in that queue can cause issues with fengGUI.





mindgamer: One huge thing that I have done is too make widgets can 'grow' and 'shrink', in my billiards game part of the GUI expands from the edge in much the same manner as the OSX dock icons.  This is facilitated by the Widget knowing about itself and not having to rely on logic at a higher level to perform this kind of task.  It looks and works very nice and smooth.  Another issue this solves is using multiple images in a widget, with a standard widget there can only be the background (and borders), with this method you can layer images any which way you want.





The simple fengGUI game menu buttons, for instance, can be replaced with an image that has transparent text and then an animated 'fire' effect image could be placed behind it.  Creating a much more animated button, perhaps the flames could even partially 'engulf' the button on 'roll-overs' by placing another animated fire image in front. (And thats just off the top of my head)

Its indeed the rootNode i place in the opaque que.



Right now the fengGUI part is just a simple main menu with a background image all contained in its own GameState, no other jme stuff is involved (yet).

basixs said:

I have found that the best way to use fengGUI is through the pass system, it has less of an impact on transparency and such.  Also, make sure that it is the last thing to be rendered, if you are using a shadow pass that may have to be last with fengGUI being second to last.

So how would i set this up ?

Right now the only thing that the render method does is display the fengGUI display  how can i render this in  a pass ?

I have

public class MainMenuState extends GameState implements IButtonPressedListener
{

   public MainMenuState()
   {
      this.setName("menu");
      MouseInput.get().setCursorVisible(true);
      disp = new Display(new LWJGLBinding());
      input = new MainMenuHandler(disp, this);
      buildGUI();

   }

@Override
   public void render(float tpf)
   {
      disp.display();
   }
}



So i have no rootNode that i can add to a renderpass ?
basixs said:

The simple fengGUI game menu buttons, for instance, can be replaced with an image that has transparent text and then an animated 'fire' effect image could be placed behind it.  Creating a much more animated button, perhaps the flames could even partially 'engulf' the button on 'roll-overs' by placing another animated fire image in front. (And thats just off the top of my head)


That does sound like a nice effect if i may so :)

Ohh man, thats rough.  The developers made it really difficult to switch :P  (happy sarcasm here)



use:

public class MainMenuState extends Pass {}

(you will need to override doRender( Renderer ), instead of render( tpf ) )

instead of:

public class MainMenuState extends GameState {}




I think working with jME maybe spoiling me, stuff like that is amazingly simple to work with.  It's just so... unnaturally easy :D
Completely different systems and you can change it almost as fast as snapping your fingers.

Thanks  ill give it a try