RTT, fengGUI and Standard Game

I am trying to render some balls to a texture then place it behind fengGUI.  The problem is the quad just comes up white, the balls are definitely getting rendered and when I use SimpleGame and no fengGUI everything works fine.  Below is my RTT initialization, update and render methods.  I use GameTaskQueueManager because createTextureRenderer() needs to be in the OpenGL thread, so maybe that could be the issue.  Any help or ideas would be very appreciated. :slight_smile:


    public void initJme() {
       
        initDefaultTextureState();
        rootNode = new Node( "Gui Root" );
       
        selectionBallNode = new Node( "Selection Balls" );
       
        int ballNumber = 0;
        for( int row=-1; row<2; ++row ) {
            for( int col=-1; col<2; ++col ) {
                Spatial ball = new Sphere( "", 16, 16, Globals.ballSize );
                Utils.color( ball, ColorRGBA.randomColor(), 0 );
                ball.setLocalTranslation( col*5, row*5, 0 );
                selectionBallNode.attachChild( ball );
                ++ballNumber;
            }
        }
       
        ZBufferState zBuffer = DisplaySystem.getDisplaySystem().getRenderer().createZBufferState();
        zBuffer.setEnabled( true );
        zBuffer.setFunction( ZBufferState.CF_LEQUAL );
        selectionBallNode.setRenderState( zBuffer );
       
        LightState lightState = jme_Driver.getJmeBase().getDisplay().getRenderer().createLightState();
        DirectionalLight light = new DirectionalLight();
        light.setDirection( new Vector3f( 0, 0, 1 ) );
        light.setAmbient( new ColorRGBA( 0.5f, 0.5f, 0.5f, 1.0f ) );
        light.setDiffuse( new ColorRGBA( 0.75f, 0.75f, 0.75f, 1.0f ) );
        light.setSpecular( new ColorRGBA( 1f, 1f, 1f, 1.0f ) );
        lightState.setGlobalAmbient( new ColorRGBA( 0.5f, 0.5f, 0.5f, 1 ) );
        lightState.setTwoSidedLighting( false );
        light.setEnabled( true );
        lightState.attach( light );
       
       
        selectionBallNode.setRenderState( lightState );
       
       
        selectionBallNode.updateGeometricState( 0.0f, true );
        selectionBallNode.updateRenderState();
       
       
        rootNode.attachChild( selectionBallNode );
       
        GameTaskQueueManager.getManager().update(new Callable<Object>() {
            public Object call() throws Exception {
               
                final Quad textureQuad = new Quad(" Quad", 25, 25 );
                textureQuad.setLocalTranslation(new Vector3f( -25,0,0 ) );
                textureQuad.setModelBound(new BoundingBox());
                textureQuad.updateModelBound();
                textureQuad.setLightCombineMode(LightState.OFF);
                rootNode.attachChild( textureQuad );
               
                rootNode.updateRenderState();
               
               
                textureRenderer = DisplaySystem.getDisplaySystem().createTextureRenderer( 512, 512, TextureRenderer.RENDER_TEXTURE_2D );
                textureRenderer.setBackgroundColor( new ColorRGBA( 0f, 0f, 0f, 1f ) );
                selectionBallTexture = new Texture();
                textureRenderer.setupTexture( selectionBallTexture );
                TextureState screen = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
                screen.setTexture( selectionBallTexture );
                screen.setEnabled( true );
               
                textureRenderer.getCamera().setLocation( new Vector3f( 0, 0, 50f ) );
                textureQuad.setRenderState( screen );
               
               
                jmeInited = true;
               
                return null;
            }
        });
       
    }
   
   
   
   
    private void initDefaultTextureState() {
        Texture defTex = TextureState.getDefaultTexture().createSimpleClone();
        defTex.setScale( Vector3f.UNIT_XYZ );
        defaultTextureState = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
        defaultTextureState.setTexture( defTex );
    }
   
   
   
    public void update( float timePerFrame ) {
        selectionBallNode.updateGeometricState( timePerFrame, false );
        rootNode.updateGeometricState( timePerFrame, false
    }
   
   
    public void render( float tpf ) {
        defaultTextureState.apply();
       
        if ( jmeInited ) {
            textureRenderer.render( selectionBallNode, selectionBallTexture );
            DisplaySystem.getDisplaySystem().getRenderer().draw( rootNode );
        }

        disp.display();
    }
   

Never mind, I forgot an updateRenderState(). 

Hmmm, so if I render the balls they are nicely light (real geom and RTT) however when I don't render that Node the balls show up in the RTT however they are 'flat' (not lite at all).



Any suggestions here?  I just want the real geometry to be only rendered (correctly) to the texture (just like TestRenderToTexture).



init, update and render methods follw:





    public void initJme() {
       
        initDefaultTextureState();
       
        selectionBallNode = new Node( "Selection Balls" );
       
        int ballNumber = 0;
        for( int row=-1; row<2; ++row ) {
            for( int col=-1; col<2; ++col ) {
                Spatial ball = new Sphere( "", 16, 16, 2*Globals.ballSize );
                //  Utils.textureSpatial( jme_Driver.getTableDriver().getBalls().getBallTextureState( ballNumber ), ball, true );
                Utils.color( ball, ColorRGBA.randomColor(), 0 );
                ball.setLocalTranslation( col*5, row*5, 0 );
                selectionBallNode.attachChild( ball );
                ++ballNumber;
            }
        }
       
       
        ZBufferState zBuffer = DisplaySystem.getDisplaySystem().getRenderer().createZBufferState();
        zBuffer.setEnabled( true );
        zBuffer.setFunction( ZBufferState.CF_LEQUAL );
        selectionBallNode.setRenderState( zBuffer );
       
        LightState lightState = jme_Driver.getJmeBase().getDisplay().getRenderer().createLightState();
        DirectionalLight light = new DirectionalLight();
        light.setDirection( new Vector3f( 0, 0, 1 ) );
        light.setAmbient( new ColorRGBA( 0.5f, 0.5f, 0.5f, 1.0f ) );
        light.setDiffuse( new ColorRGBA( 0.75f, 0.75f, 0.75f, 1.0f ) );
        light.setSpecular( new ColorRGBA( 1f, 1f, 1f, 1.0f ) );
        lightState.setGlobalAmbient( new ColorRGBA( 0.5f, 0.5f, 0.5f, 1 ) );
        lightState.setTwoSidedLighting( false );
        light.setEnabled( true );
        lightState.attach( light );
       
       
        selectionBallNode.setRenderState( lightState );
       
        selectionBallNode.setRenderQueueMode( Renderer.QUEUE_SKIP );
        selectionBallNode.updateGeometricState( 0.0f, true );
        selectionBallNode.updateRenderState();
       
       
        GameTaskQueueManager.getManager().update(new Callable<Object>() {
            public Object call() throws Exception {
               
                final Quad textureQuad = new Quad(" Quad", 25, 25 );
                textureQuad.setLocalTranslation(new Vector3f( -25,0,0 ) );
                textureQuad.setModelBound(new BoundingBox());
                textureQuad.updateModelBound();
                textureQuad.setLightCombineMode(LightState.OFF);
               
                textureRenderer = DisplaySystem.getDisplaySystem().createTextureRenderer( 512, 512, TextureRenderer.RENDER_TEXTURE_2D );
                textureRenderer.setBackgroundColor( new ColorRGBA( 0f, 0f, 0f, 1f ) );
                selectionBallTexture = new Texture();
                textureRenderer.setupTexture( selectionBallTexture );
                TextureState screen = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
                screen.setTexture( selectionBallTexture );
                screen.setEnabled( true );
               
                textureRenderer.getCamera().setLocation( new Vector3f( 0, 0, 20f ) );
                textureQuad.setRenderState( screen );
               
               
                textureNode = new Node();
                textureNode.attachChild( textureQuad );
               
                textureNode.updateRenderState();
               
                return null;
            }
        });
       
    }
   
   
   
   
    private void initDefaultTextureState() {
        Texture defTex = TextureState.getDefaultTexture().createSimpleClone();
        defTex.setScale( Vector3f.UNIT_XYZ );
        defaultTextureState = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
        defaultTextureState.setTexture( defTex );
    }
   
   
   
    public void update( float timePerFrame ) {
    }
   
   
    public void render( float tpf ) {
        defaultTextureState.apply();
       
        if ( textureNode != null ) {
            DisplaySystem.getDisplaySystem().getRenderer().draw( selectionBallNode );
            textureRenderer.render( selectionBallNode, selectionBallTexture );
            DisplaySystem.getDisplaySystem().getRenderer().draw( textureNode );
        }
       
        disp.display();
    }

Anouther question with same setup.  Is it possible to get a BufferedImage or java.awt.Image from a texture?  If not I would think it would be really helpful.  I am trying to create some animation in my GUI and using RTT seems like a logical choice.  However I would rather render the resulting image with fengGUI (as a pose to jME), so I thought a good solution would be do the RTT with jME, convert the texture to a BufferedImage (for fengGUI), then just draw the image with the rest of my GUI images.  Getting the bufferedImage is all thats holding me up with this.



As always, any ideas are very welcome

Found this thread after a lot of digging.



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



Is this still the case?? There is there really no way get the image back once it's been pushed down the OpenGL pipe? :slight_smile:

You can get framebuffer data with glReadPixels but prepare for a drastic performance loss, especially if you plan to do it every frame.

There's probably a better way to do this, if you could provide more information about what you're trying to do…

this is what I am trying to do (did)





However, there is a lighting issue





Notice how the light is on the GUI balls.  Basically as the camera moves around, the light on the ball moves also.  I don’t understand why this is, the light on the actual geometry is not changing and the texture.render camera is not changing…

Have I forgot something silly, 




   
    public void initJme() {
       
        initDefaultTextureState();
       
        selectionBallRealNode = new Node( "Selection Balls" );
       
       
        setBallOrder();
       
       
        for( int ballNumber=0; ballNumber<9; ++ballNumber ) {
            Sphere ball = new Sphere( "", 32, 32, 0.15f );
            ball.setTextureMode( Sphere.TEX_PROJECTED );
            textureBall( ball, ballNumber+1 );
           
           
            ball.setLocalTranslation( ballOrder[ ballNumber ][0]*0.33f, ballOrder[ ballNumber ][1]*0.3f, 0 );
            ball.setLocalRotation( new Quaternion().fromAngleAxis( FastMath.HALF_PI, Vector3f.UNIT_X ) );
            ball.setRenderQueueMode( Renderer.QUEUE_SKIP );
            selectionSpheres[ballNumber] = ball;
           
            selectionBallRealNode.attachChild( ball );
        }
       
        selectionBallRealNode.setLocalRotation( new Quaternion().fromAngleAxis( FastMath.PI, Vector3f.UNIT_Z ) );
       
        ZBufferState zBuffer = DisplaySystem.getDisplaySystem().getRenderer().createZBufferState();
        zBuffer.setEnabled( true );
        zBuffer.setFunction( ZBufferState.CF_LEQUAL );
        selectionBallRealNode.setRenderState( zBuffer );
       
        LightState lightState = jme_Driver.getJmeBase().getDisplay().getRenderer().createLightState();
        DirectionalLight light = new DirectionalLight();
        light.setDirection( Vector3f.UNIT_Z );
        light.setAmbient( new ColorRGBA( 0.5f, 0.5f, 0.5f, 1.0f ) );
        light.setDiffuse( new ColorRGBA( 0.75f, 0.75f, 0.75f, 1.0f ) );
        light.setSpecular( new ColorRGBA( 1f, 1f, 1f, 1.0f ) );
        light.setEnabled( true );
       
        lightState.setGlobalAmbient( new ColorRGBA( 0.5f, 0.5f, 0.5f, 1 ) );
        lightState.setTwoSidedLighting( false );
       
        lightState.attach( light ); );
        lightState.setLocalViewer( true );
       
        //selectionBallRealNode.setLocalTranslation( 2*Globals.maxDistance, 2*Globals.maxDistance, 0 );
        selectionBallRealNode.setLocalTranslation( 200, 200, 0 );
       
        selectionBallRealNode.setRenderQueueMode( Renderer.QUEUE_SKIP );
        selectionBallRealNode.setRenderState( lightState );
       
        selectionBallRealNode.updateRenderState();
        selectionBallRealNode.updateGeometricState( 0.0f, true );
       
       
       
        GameTaskQueueManager.getManager().update(new Callable<Object>() {
            public Object call() throws Exception {
               
                selectionBallRealNode.lock();
               
                final Quad textureQuad = new Quad(" Quad", leftBarWidth, leftBarWidth );
                textureQuad.setLocalTranslation(new Vector3f( 0,0,0 ) );
                textureQuad.setModelBound(new BoundingBox());
                textureQuad.updateModelBound();
                textureQuad.setLightCombineMode( LightState.OFF );
               
                textureRenderer = DisplaySystem.getDisplaySystem().createTextureRenderer( 256, 256, TextureRenderer.RENDER_TEXTURE_2D );
                textureRenderer.setBackgroundColor( new ColorRGBA( 0f, 0f, 0f, 1f ) );
                selectionBallTexture = new Texture();
                textureRenderer.setupTexture( selectionBallTexture );
                TextureState screen = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
                screen.setTexture( selectionBallTexture );
                screen.setEnabled( true );
               
                textureRenderer.getCamera().setParallelProjection( true );
                //textureRenderer.getCamera().setLocation( new Vector3f( 2*Globals.maxDistance, 2*Globals.maxDistance, -20f ) );
                textureRenderer.getCamera().setLocation( new Vector3f( 200, 200, -20f ) );
                textureRenderer.getCamera().lookAt( new Vector3f( 200, 200, 0.01f ), Vector3f.UNIT_Y );
                textureQuad.setRenderState( screen );
               
               
                selectionBallTextureNode = new Node();
                selectionBallTextureNode.attachChild( textureQuad );
                selectionBallTextureNode.setLocalTranslation(
                        DisplaySystem.getDisplaySystem().getWidth() - leftBarWidth/2,
                        displayVertCenter + guiLeftHeight/4 + leftBarWidth/2, 0 );
                selectionBallTextureNode.setLocalRotation( new Quaternion().fromAngleAxis( FastMath.PI, Vector3f.UNIT_X ) );
               
                selectionBallTextureNode.setCullMode( Spatial.CULL_NEVER );
                selectionBallTextureNode.updateRenderState();
                selectionBallTextureNode.updateGeometricState( 0, true );
               
                return null;
            }
        });
       
    }
   
   
   
   
    private void textureBall( Spatial spatial, int ballNumber ) {
       
        if ( ballTextures[ ballNumber ] == null ) {
           
            String location = Utils.getTexturePath( Utils.TextureType.GUI_TEXTURE, false );
            location += Globals.ballTextureFileNames[ ballNumber ];
           
            ballTextures[ ballNumber ] = Utils.getTextureState( location );
            ballTextures[ ballNumber ].getTexture().setWrap( Texture.WM_WRAP_S_CLAMP_T );
            ballTextures[ ballNumber ].getTexture().setScale( new Vector3f( 2, 1, 1 ) );
        }
       
       
        Utils.textureSpatial( ballTextures[ ballNumber ], spatial, false );
    }
   
   
   
   
    private void initDefaultTextureState() {
        Texture defTex = TextureState.getDefaultTexture().createSimpleClone();
        defTex.setScale( Vector3f.UNIT_XYZ );
        defaultTextureState = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
        defaultTextureState.setTexture( defTex );
    }
   
   
   
    public void update( float timePerFrame ) {
        selectionBallRealNode.updateGeometricState( timePerFrame, false );
    }
   
   
    public void render( float tpf ) {
       
        Renderer renderer = DisplaySystem.getDisplaySystem().getRenderer();
       
       
        if ( selectionBallTextureNode != null && powerBarVisiblePercent == 1f ) {
            if ( !selectionBallsRendered ) {
                DisplaySystem.getDisplaySystem().getRenderer().draw( selectionBallRealNode );
                textureRenderer.render( selectionBallRealNode, selectionBallTexture );
                //        selectionBallsRendered = true;
            }
           
            renderer.setOrtho();
            DisplaySystem.getDisplaySystem().getRenderer().draw( selectionBallTextureNode );
            renderer.unsetOrtho();
        }
       
       
        defaultTextureState.apply();
        disp.display();
    }
   
   
    public void cleanup() {
    }




Also, I have set the actual geometry with .setRenderQueueMode( Renderer.QUEUE_SKIP ); however it is still rendered.  Is there some gotcha I have missed when trying to set the Skip mode?