Quality of rendering different SimpleGame and JMECanvas

This is my first post and hopefully someone can help me. I am not a game developer and want only to create a small 3D animation inside my Swing application with JME.



I have created two applications:

1.) A SimpleGame Application with drawing a sphere and a box

2.) My Swing application with the 3D output in a JMECanvas. Adding the same sphere and box as in 1.)



The problem is that the sphere has in 1.) a 3D shape. In 2.) I got only a white circle on the screen. With the box the problem with the color is the same.



Here is the code from the swing application:



Code for adding the canvas into my window:


drawing= new ThreeDPanel(new Dimension(800,400));
AnimationViewTopComponent.this.add(drawing);



Code to create the JPanel:


public class ThreeDPanel extends JPanel {

    private static final long serialVersionUID = 1L;
    Canvas comp = null;
    JMECanvasImplementor impl;
    DisplaySystem display;

    ThreeDPanel(Dimension dimension) {
        setLayout(new BorderLayout());
        String renderer="LWJGL";
        display = DisplaySystem.getDisplaySystem();
        display.registerCanvasConstructor("AWT", LWJGLAWTCanvasConstructor.class);
        comp = (Canvas) display.createCanvas(
                dimension.width, dimension.height);
        display.setVSyncEnabled(true);
        // add a listener... if window is resized, we can do something about it.
        comp.addComponentListener(new ComponentAdapter() {

            @Override
            public void componentResized(ComponentEvent ce) {
                doResize();
            }
        });

        // MAKE SURE YOU REPAINT SOMEHOW OR YOU WON'T SEE THE UPDATES...
        new Thread() {

            {
                setDaemon(true);
            }

            @Override
            public void run() {
                while (true) {
                    comp.repaint();
                    yield();
                }
            }
        }.start();

        KeyInput.setProvider(KeyInput.INPUT_AWT);
        AWTMouseInput.setup(comp, false);

        impl = new SceneImpl(dimension.width, dimension.height);
        LWJGLCanvas jmeCanvas = ((LWJGLCanvas) comp);
        jmeCanvas.setTargetRate(60);
        jmeCanvas.setImplementor(impl);
        jmeCanvas.setUpdateInput(true);

        jmeCanvas.setBounds(0, 0, dimension.width, dimension.height);
        add(jmeCanvas);

    }

    protected void doResize() {
        impl.resizeCanvas(comp.getWidth(), comp.getHeight());
    }
}



Scene code:


class SceneImpl extends SimpleCanvasImpl {

    private Quaternion rotQuat;
    private float angle = 0;
    private Vector3f axis;
    private Box box;
    private Sphere s;
    long startTime = 0;
    long fps = 0;
    private InputHandler input;

    public SceneImpl(int width, int height) {
        super(width, height);
    }

    @Override
    public void simpleSetup() {

        // Make a box
        Box b = new Box("Mybox", new Vector3f(0, 0, 0), new Vector3f(5, 5, 5));
        b.setLocalRotation(new Matrix3f(0.5f, 0f, 0f, 0f, 0.70f, -0.7f, 0.5f, 0.7f, 0.7f));
        rootNode.attachChild(b); // Put it in the scene graph

        // Normal Scene setup stuff...
        rotQuat = new Quaternion();
        axis = new Vector3f(1, 1, 0.5f);
        axis.normalizeLocal();

        Vector3f max = new Vector3f(5, 5, 5);
        Vector3f min = new Vector3f(-5, -5, -5);

        box = new Box("Box", min, max);
        box.setModelBound(new BoundingBox());
        box.updateModelBound();
        box.setLocalTranslation(new Vector3f(0, 0, -10));
        box.setLocalRotation(new Matrix3f(0.5f, 0f, 0f, 0f, 0.70f, -0.7f, 0.5f, 0.7f, 0.7f));
        box.setRenderQueueMode(Renderer.QUEUE_SKIP);
        box.setRandomColors();
        rootNode.attachChild(box);

        s = new Sphere("Sphere", 100, 100, 5);
        s.setLocalTranslation(new Vector3f(-8,0,0));
        rootNode.attachChild(s);

        rootNode.updateRenderState();

        DirectionalLight dr = new DirectionalLight();
        dr.setEnabled(true);
        dr.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
        dr.setAmbient(new ColorRGBA(.6f, .6f, .5f, .5f));
        dr.setDirection(new Vector3f(0.5f, -0.8f, 0.5f).normalizeLocal());
        dr.setShadowCaster(true);
// Another light so there is no full darkness.
        PointLight pl = new PointLight();
        pl.setEnabled(true);
        pl.setDiffuse(new ColorRGBA(.2f, .2f, .23f, 1.0f));
        pl.setAmbient(new ColorRGBA(.25f, .25f, .28f, .25f));
        pl.setLocation(new Vector3f(20, 20, 20));

        startTime = System.currentTimeMillis() + 5000;
        rootNode.updateRenderState();
        /*input = new InputHandler();
        input.addAction(new InputAction() {

            @Override
            public void performAction(InputActionEvent evt) {
                // logger.info(evt.getTriggerName());
            }
        }, InputHandler.DEVICE_MOUSE, InputHandler.BUTTON_ALL,
                InputHandler.AXIS_NONE, false);

        input.addAction(new InputAction() {

            @Override
            public void performAction(InputActionEvent evt) {
                // logger.info(evt.getTriggerName());
            }
        }, InputHandler.DEVICE_KEYBOARD, InputHandler.BUTTON_ALL,
                InputHandler.AXIS_NONE, false);*/
    }

    /*@Override
    public void simpleUpdate() {
        input.update(tpf);

        // Code for rotating the box... no surprises here.
        if (tpf < 1) {
            angle = angle + (tpf * 25);
            if (angle > 360) {
                angle = 0;
            }
        }
        rotQuat.fromAngleNormalAxis(angle * FastMath.DEG_TO_RAD, axis);
        //box.setLocalRotation(rotQuat);
        //s.setLocalRotation(rotQuat);

        if (startTime > System.currentTimeMillis()) {
            fps++;
        } else {
            long timeUsed = 5000 + (startTime - System.currentTimeMillis());
            startTime = System.currentTimeMillis() + 5000;
            fps = 0;
        }
    }*/

    public Node loadMyColladaModel() {
        InputStream source = SceneImpl.class.getClassLoader().getResourceAsStream("/at/itarchitects/accidentsimulation/gui/view2d/probe.dae");
        if (source == null) {
        }
        ColladaImporter.load(source, "probe.dae");
        return ColladaImporter.getModel();
    }

    public Node loadMyDSModel() {
        URL modelURL=SceneImpl.class.getClassLoader().getResource("/at/itarchitects/accidentsimulation/gui/view2d/probe.3ds");
        Node gamemap = new Node();
        //BinaryImporter importer = BinaryImporter.getInstance();
        FormatConverter converter=new MaxToJme(); // com.jmex.model.XMLparser.Converters.*
        ByteArrayOutputStream BO=new ByteArrayOutputStream();
        try {
            converter.convert( modelURL.openStream(), BO );
            gamemap=(Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
            //gamemap.setCullMode(SceneBase.CULL_NEVER );
            gamemap.setModelBound( new BoundingBox() );
            gamemap.updateModelBound();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return gamemap;
    }

    public TriMesh loadMyOBJModel() {
        URL modelURL=SceneImpl.class.getClassLoader().getResource("/at/itarchitects/accidentsimulation/gui/view2d/probe.obj");
        TriMesh gamemap = new TriMesh();
        //BinaryImporter importer = BinaryImporter.getInstance();
        FormatConverter converter=new ObjToJme(); // com.jmex.model.XMLparser.Converters.*
        ByteArrayOutputStream BO=new ByteArrayOutputStream();
        try {
            converter.convert( modelURL.openStream(), BO );
            gamemap=(TriMesh) BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
            //gamemap.setCullMode(SceneBase.CULL_NEVER );
            gamemap.setModelBound( new BoundingBox() );
            gamemap.updateModelBound();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return gamemap;
    }
}



Some screen shots:

Swing application

Same scene in SimpleGame:



Thank you allot for your help!
cheers,
Clemens

a missing updateRenderSTate() ? at least it seems like that

I checked my code and in method simpleSetup() I have already at last command a rootNode.updateRenderState();.



Where should I put the rootNode.updateRenderState(); ?

One additional question:

Is JMECanvas the preferred way to integrate the rendering window into a swing application or should I use some sort of HeadlessWindow ?



In constructor ThreeDPanel if created the following statement:

Renderer r = display.getRenderer();

The contents of "r" is always null ?

I found the solution:



I forgot to include a light source into my scene. I added in simpleSetup() the following lines of code:


LightState ls = DisplaySystem.getDisplaySystem().getRenderer().createLightState();
            PointLight light = new PointLight();
            light.setEnabled(true);
            light.setDiffuse(new ColorRGBA(.2f, .2f, .23f, 1.0f));
            light.setAmbient(new ColorRGBA(.25f, .25f, .28f, .25f));
            light.setLocation(new Vector3f(20, 20, 20));
            DirectionalLight dr = new DirectionalLight();
            dr.setEnabled(true);
            dr.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
            dr.setAmbient(new ColorRGBA(.6f, .6f, .5f, .5f));
            dr.setDirection(new Vector3f(0.5f, -0.8f, 0.5f).normalizeLocal());
            dr.setShadowCaster(true);
            ls.attach(dr);
            ls.attach(light);
            ls.setTwoSidedLighting(true);
            rootNode.setRenderState(ls);



Thank you for your help!

cheers,
Clemens