Hi,
I'm using jME 2.0 for two months now and I finally came to a point where I need some help. I have a JFrame with a jME canvas (similar to the JMESwingTest.java). The canvas shows a scene with textured houses, a skybox and some transparency effects. I now wanted to add a minimap, using render to texture. But it seems as if the renderers are not able to share the textures: the textures seen in the minimap are replaced in the main view by other textures which are not visible in the minimap :?.
To make it more clear, I made two test classes: one uses a canvas inside a JFrame, while the other extends SimpleGame. There is a simple scene containing a textured box and a quad to which the texture from the TextureRenderer is applied. Everything looks good when I use the class that extends SimpleGame. But when I use the class with the canvas inside the JFrame, the texture on the box gets lost when I use the TextureRenderer.render() method. I only see "Texture Missing" on the box, while the texture in the minimap looks fine. (Vice versa, if I call the TextureRenderer.render() method not right at the beginning but after some seconds, the texture on the box is correct, but the minimap doesn't show the texture.) Both classes have identical code in the simpleRender() and simpleSetup()/simpleInitGame() methods.
Here are the two test classes. Just replace the picture used for the texture to test them.
First the Class with the canvas:
import javax.swing.JFrame;
import com.jme.image.Texture;
import com.jme.image.Texture2D;
import com.jme.input.InputHandler;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.TextureRenderer;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.system.canvas.SimpleCanvasImpl;
import com.jme.system.lwjgl.LWJGLSystemProvider;
import com.jme.util.TextureManager;
import com.jmex.awt.lwjgl.LWJGLAWTCanvasConstructor;
import com.jmex.awt.lwjgl.LWJGLCanvas;
public class TestRTTCanvas extends SimpleCanvasImpl {
private DisplaySystem display;
private LWJGLCanvas canvas = null;
private static int canvasWidth = 640;
private static int canvasHeight = 480;
private InputHandler input;
private Texture tex1 = TextureManager.loadTexture(
this.getClass().getClassLoader().getResource(
"main/testpic.gif" ),
Texture.MinificationFilter.BilinearNearestMipMap,
Texture.MagnificationFilter.Bilinear );
private Quad q;
private TextureRenderer tRenderer;
private Texture2D mapTexture;
private TextureState texState;
public static void main(String[] args) {
TestRTTCanvas test = new TestRTTCanvas( canvasWidth, canvasHeight );
}
private TestRTTCanvas(int width, int height) {
super( width, height );
display = DisplaySystem.getDisplaySystem( LWJGLSystemProvider.LWJGL_SYSTEM_IDENTIFIER );
display.registerCanvasConstructor( "AWT", LWJGLAWTCanvasConstructor.class );
canvas = (LWJGLCanvas)display.createCanvas( canvasWidth, canvasHeight );
canvas.setImplementor( this );
canvas.setBounds( 0, 0, canvasWidth, canvasHeight );
JFrame frame = new JFrame();
frame.getContentPane().add( canvas );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setVisible( true );
}
@Override
public void simpleRender() {
display.getRenderer().draw( q );
}
@Override
public void simpleSetup() {
input = new InputHandler();
cam.setLocation( new Vector3f( 2.0f, 0.0f, 12.0f ));
//Setup a simple scene (textured box)
Box box = new Box( "box", new Vector3f( 0, 0, 0 ), 1.0f, 1.0f, 1.0f );
box.setLocalTranslation( 5.0f, 0.0f, 0.0f );
TextureState ts = display.getRenderer().createTextureState();
ts.setTexture( tex1 );
ts.setEnabled( true );
box.setRenderState( ts );
box.updateRenderState();
rootNode.attachChild( box );
//Setup the quad to which the texture gets applied
q = new Quad( "Quad", 7.0f, 7.0f );
q.setCullHint( Spatial.CullHint.Never );
q.setLightCombineMode( Spatial.LightCombineMode.Off );
q.setRenderQueueMode( Renderer.QUEUE_ORTHO );
ZBufferState buf = DisplaySystem.getDisplaySystem().getRenderer().createZBufferState();
buf.setEnabled( true );
buf.setFunction( ZBufferState.TestFunction.LessThanOrEqualTo );
q.setRenderState( buf );
//Setup the texture, the texture state and the texture renderer
mapTexture = new Texture2D();
mapTexture.setWrap( Texture.WrapMode.Clamp );
mapTexture.setRenderToTextureType( Texture.RenderToTextureType.RGBA );
tRenderer = DisplaySystem.getDisplaySystem().createTextureRenderer( 512, 512,
TextureRenderer.Target.Texture2D );
tRenderer.setBackgroundColor( new ColorRGBA( 0.5f, 0.5f, 0.5f, 1.0f ));
if ( tRenderer.isSupported() ) {
tRenderer.setupTexture( mapTexture );
tRenderer.getCamera().setLocation( new Vector3f( 5.0f, 1.0f, 5.0f ));
tRenderer.getCamera().update();
} else {
System.err.println( "Render to texture not supported!" );
}
texState = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
texState.setTexture( mapTexture );
texState.setEnabled( true );
//Apply texture state to the quad
q.setRenderState( texState );
q.updateRenderState();
rootNode.updateRenderState();
//Render to texture
tRenderer.render( rootNode, mapTexture );
}
}
And here the class extending SimpleGame:
import com.jme.app.SimpleGame;
import com.jme.image.Texture;
import com.jme.image.Texture2D;
import com.jme.input.InputHandler;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.TextureRenderer;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
public class TestRTTSimpleGame extends SimpleGame {
private Texture tex1 = TextureManager.loadTexture(
this.getClass().getClassLoader().getResource(
"main/testpic.gif" ),
Texture.MinificationFilter.BilinearNearestMipMap,
Texture.MagnificationFilter.Bilinear );
private Quad q;
private TextureRenderer tRenderer;
private Texture2D mapTexture;
private TextureState texState;
public static void main(String[] args) {
TestRTTSimpleGame app = new TestRTTSimpleGame();
app.setConfigShowMode(ConfigShowMode.AlwaysShow);
app.start();
}
@Override
protected void cleanup() {
super.cleanup();
tRenderer.cleanup();
}
@Override
protected void simpleRender() {
display.getRenderer().draw( q );
}
@Override
protected void simpleInitGame() {
input = new InputHandler();
cam.setLocation( new Vector3f( 2.0f, 0.0f, 12.0f ));
//Setup a simple scene (textured box)
Box box = new Box( "box", new Vector3f( 0, 0, 0 ), 1.0f, 1.0f, 1.0f );
box.setLocalTranslation( 5.0f, 0.0f, 0.0f );
TextureState ts = display.getRenderer().createTextureState();
ts.setTexture( tex1 );
ts.setEnabled( true );
box.setRenderState( ts );
box.updateRenderState();
rootNode.attachChild( box );
//Setup the quad to which the texture gets applied
q = new Quad( "Quad", 7.0f, 7.0f );
q.setCullHint( Spatial.CullHint.Never );
q.setLightCombineMode( Spatial.LightCombineMode.Off );
q.setRenderQueueMode( Renderer.QUEUE_ORTHO );
ZBufferState buf = DisplaySystem.getDisplaySystem().getRenderer().createZBufferState();
buf.setEnabled( true );
buf.setFunction( ZBufferState.TestFunction.LessThanOrEqualTo );
q.setRenderState( buf );
//q.setLocalTranslation( -10.0f, -5.0f, 0.0f );
//rootNode.attachChild( q );
//Setup the texture, the texture state and the texture renderer
mapTexture = new Texture2D();
mapTexture.setWrap( Texture.WrapMode.Clamp );
mapTexture.setRenderToTextureType( Texture.RenderToTextureType.RGBA );
tRenderer = DisplaySystem.getDisplaySystem().createTextureRenderer( 512, 512,
TextureRenderer.Target.Texture2D );
tRenderer.setBackgroundColor( new ColorRGBA( 0.5f, 0.5f, 0.5f, 1.0f ));
if ( tRenderer.isSupported() ) {
tRenderer.setupTexture( mapTexture );
tRenderer.getCamera().setLocation( new Vector3f( 5.0f, 1.0f, 5.0f ));
tRenderer.getCamera().update();
} else {
System.err.println( "Render to texture not supported!" );
}
texState = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
texState.setTexture( mapTexture );
texState.setEnabled( true );
//Apply texture state to the quad
q.setRenderState( texState );
q.updateRenderState();
rootNode.updateRenderState();
//Render to texture
tRenderer.render( rootNode, mapTexture );
}
}
And here the results (left the class with the canvas, right the class extending SimpleGame):
Also, my notebook's graphic card doesn't seem to support the FBO and uses the PBuffer for the RTT (if this plays an important role?). By the way, all the RTT tests inside the jME project are running fine, but they all extend some kind of Game class.
Has anyone an idea how to fix my problem when using RTT and a canvas inside a JFrame?
Maybe I need to add something to the SceneImplementor that is otherwise already done by SimpleGame? But then, I already looked at the SimpleGame classes and couldn't find anything.
EDIT: I just noticed that the canvas program freezes when I press the arrow keys or the alt key. I commented out line by line until I found the line which is causing this problem:
tRenderer = display.createTextureRenderer( 512, 512,
TextureRenderer.Target.Texture2D );
Maybe this gives another hint on what is wrong with my canvas program?