Control render function Vs AppState render function

Hi guys,

I’m stucked with custom rendering. I’m trying to render a list of geometries without attaching anything to the scneegraph but i’ve found something i can’t understand…

Why my control render the sphere and my appState not? Do i need to do something special in an appstate? The render function is well called in both cases…

Control test case :

import com.jme3.asset.AssetManager;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import com.jme3.scene.control.Control;
import com.jme3.scene.shape.Sphere;
import java.io.IOException;

public class RenderControl extends AbstractControl {

    private AssetManager am;
    private Geometry geom;

    public RenderControl(AssetManager am) {
        this.am = am;
        geom = new Geometry("test", new Sphere(10, 10, 3));
        Material m = new Material(am, "Common/MatDefs/Misc/Unshaded.j3md");
        m.setColor("Color", ColorRGBA.Blue);
        m.getAdditionalRenderState().setWireframe(true);
        geom.setMaterial(m);
    }

    @Override
    protected void controlUpdate(float tpf) {
        geom.rotate(0, tpf, 0);
        geom.computeWorldMatrix();
    }

    @Override
    protected void controlRender(RenderManager rm, ViewPort vp) {
        rm.renderGeometry(geom);
    }

    @Override
    public Control cloneForSpatial(Spatial spatial) {
        RenderControl control = new RenderControl(this.am);
        return control;
    }

    @Override
    public void read(JmeImporter im) throws IOException {
        super.read(im);
        InputCapsule in = im.getCapsule(this);
    }

    @Override
    public void write(JmeExporter ex) throws IOException {
        super.write(ex);
        OutputCapsule out = ex.getCapsule(this);
    }
}

AppState test case :

import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Sphere;

public class TestRenderAppState extends AbstractAppState {

    private Geometry geom;

    @Override
    public void initialize(AppStateManager stateManager, Application app) {
        super.initialize(stateManager, app);
        geom = new Geometry("test", new Sphere(10, 10, 3.5f));
        Material m = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
        m.setColor("Color", ColorRGBA.Red);
        m.getAdditionalRenderState().setWireframe(true);
        geom.setMaterial(m);
    }

    @Override
    public void update(float tpf) {
        geom.rotate(0, tpf, 0);
        geom.computeWorldMatrix();
    }

    @Override
    public void render(RenderManager rm) {
        super.render(rm);
        rm.renderGeometry(geom);
    }
}

Well, you say that they aren’t attached to the scene graph but the first one must be or control render will never be called.

So, you are just missing a bunch of other setup, I guess.

Real question is what are you actually trying to do? Because this is very strange.

Edit: in the second case you never geom.updateLogicalState() or geom.updateGeometricState()… I’m surprised it isn’t spewing errors.

Ok, i’ve found the bulletAppStateDebugger and I got it, render control function does not take a viewport argument cause render is done is the same vp of attached spatial but render appState function is not attached to anything so i had to create my own viewport to render something. it’s working now.

Just for info, i’m trying to display some overlay things without modifying the scene graph :wink:

And yes, i’ve forgot the updateGeometricState() but it seems computeWorldMatrix() is enough to do the trick ^^

In the future, provide this sort of information up front because I could have pointed you to viewports right away and saved lots of time.

You should not count on that.

Call updateLogicalState() in your app state’s update() method and call updateGeometricState() in your app state’s render method. And that’s all you need to do. The viewport will render itself if you created it properly from the renderer.

Ok, thanks for your time (and the hints ;))

:grinning: