getRenderer() always returns null

Hi!



My code sometimes works and sometimes not. The reason is that displaySystem.getRenderer() returns null. Here is my code. Please, if anyone can help. Thanks a lot.



Regards to all JMonkey Fans  :smiley:


package at.netcrystals.visualizer.dataobjects;

import at.netcrystals.visualizer.nodes.SceneImplementationNode;
import com.jme.bounding.BoundingVolume;
import com.jme.light.LightNode;
import com.jme.light.PointLight;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.pass.BasicPassManager;
import com.jme.renderer.pass.RenderPass;
import com.jme.scene.CameraNode;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.shape.AxisRods;
import com.jme.scene.state.LightState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.system.canvas.JMECanvasImplementor;
import com.jme.system.lwjgl.LWJGLSystemProvider;
import com.jme.util.NanoTimer;
import com.jme.util.Timer;
import com.jmex.awt.lwjgl.LWJGLAWTCanvasConstructor;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory;

/**
 *
 * @author Martinschitz
 */
public class SceneImplementation extends JMECanvasImplementor {

    // Items for scene
    private DisplaySystem displaySystem = DisplaySystem.getDisplaySystem(LWJGLSystemProvider.LWJGL_SYSTEM_IDENTIFIER);
    private static SceneImplementation sceneImplementation = null;
    public static final int CAMERA_DEFAULT = 0;
    public static final int CAMERA_YZ = 1;
    public static final int CAMERA_XZ = 2;
    public static final int CAMERA_XY = 3;
    protected Node rootNode;
    protected Timer timer;
    protected float tpf;
    protected Camera cam;
    private BasicPassManager basicPassManager;
    private StereoRenderPass stereoRenderPass = new StereoRenderPass();
    private RenderPass renderPass = new RenderPass();
    private CameraNode cameraNode = null;
    private Node rotationNode = null;
    private LightNode lightNode = new LightNode();
    private int cameraIndex = CAMERA_DEFAULT;

   
      
   

    /**
     * Not directly instantiated.
     * @param width canvas width
     * @param height canvas height
     */
    private SceneImplementation(int width, int height) {
        this.width = width;
        this.height = height;
        doSetup();
    }

    @Override
    public void doSetup() {
        displaySystem.registerCanvasConstructor("AWT", LWJGLAWTCanvasConstructor.class);//NOI18N
        if (width <= 0) {
            width = 600;
        }
        if (height <= 0) {
            height = 480;
        }

        renderer = displaySystem.getRenderer();
        /**
         * Create a camera specific to the DisplaySystem that works with the
         * width and height
         */
        cam = renderer.createCamera(width, height);

        /** Set up how our camera sees. */
        cam.setFrustumPerspective(45.0f, (float) width / (float) height, 1, 1000);
        Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
        Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f);
        Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
        Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);
        /** Move our camera to a correct place and orientation. */
        cam.setFrame(loc, left, up, dir);
        /** Signal that we've changed our camera's location/frustum. */
        cam.update();
        /** Assign the camera to this renderer. */
        renderer.setCamera(cam);

        /** Set a black background. */
        renderer.setBackgroundColor(ColorRGBA.black.clone());

        /** Get a high resolution timer for FPS updates. */
        timer = new NanoTimer();

        /** Create rootNode */
        rootNode = new Node("rootNode");//NOI18N

        /**
         * Create a ZBuffer to displaySystem pixels closest to the camera above
         * farther ones.
         */
        ZBufferState buf = renderer.createZBufferState();
        buf.setEnabled(true);
        buf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);

        rootNode.setRenderState(buf);

        //detach all children from default input
        rootNode.detachAllChildren();
        rotationNode = new Node();
        rootNode.attachChild(rotationNode);
        createLights();
        setCameraIndex(CAMERA_DEFAULT);
        basicPassManager = new BasicPassManager();
        renderPass.add(rootNode);
        basicPassManager.add(renderPass);

        /**
         * Update geometric and rendering information for both the rootNode and
         * fpsNode.
         */
        rootNode.updateGeometricState(0.0f, true);
        rootNode.updateRenderState();
        setup = true;
    }

    public void doUpdate() {
        timer.update();
        /** Update tpf to time per frame according to the Timer. */
        tpf = timer.getTimePerFrame();
        rootNode.updateGeometricState(tpf, true);
        rootNode.updateWorldBound();
    }

    public void doRender() {
        if (renderer != null && basicPassManager != null) {
            renderer.clearBuffers();
            basicPassManager.renderPasses(renderer);
            renderer.displayBackBuffer();
        }
    }

    public Camera getCamera() {
        return cam;
    }

    public Node getRootNode() {
        return rootNode;
    }

    public float getTimePerFrame() {
        return tpf;
    }

    public void setSpatials(Spatial[] spatials) {
        rotationNode.detachAllChildren();
        Node originNode = new Node();
        AxisRods axisRods = new AxisRods("AxisRods");
        originNode.attachChild(axisRods);
        for (Spatial spatial : spatials) {
            originNode.attachChild(spatial);
        }
        originNode.updateWorldBound();
        originNode.updateRenderState();
        BoundingVolume boundingVolume = originNode.getWorldBound();
        if (boundingVolume != null) {
            originNode.setLocalTranslation(boundingVolume.getCenter().mult(-1.0f));
        }
        rotationNode.attachChild(originNode);
        rootNode.updateRenderState();
    }

    private void createLights() {
        PointLight pointLight = new PointLight();
        pointLight.setDiffuse(ColorRGBA.white);
        pointLight.setLocation(new Vector3f(0, 0, 0));
        pointLight.setAttenuate(true);
        pointLight.setEnabled(true);
        lightNode.setLight(pointLight);
        lightNode.updateRenderState();

        LightState lightState = renderer.createLightState();
        lightState.detachAll();
        lightState.setEnabled(true);
        lightState.attach(pointLight);
        rootNode.setRenderState(lightState);
        rootNode.updateRenderState();
    }

    public void setCameraIndex(final int cameraIndex) {
        this.cameraIndex = cameraIndex;
        if (this.cameraIndex < CAMERA_DEFAULT) {
            this.cameraIndex = CAMERA_XY;
        } else if (this.cameraIndex > CAMERA_XY) {
            this.cameraIndex = CAMERA_DEFAULT;
        }
        rootNode.detachChild(cameraNode);
        rotationNode.detachChild(cameraNode);
        try {
            if (cameraIndex == CAMERA_YZ) {
                cameraNode = new CameraNode("YZ camera", cam);
                cameraNode.attachChild(lightNode);
                cameraNode.setLocalRotation(new Quaternion(new float[]{0f, -(float) Math.PI / 2.0f, 0f}));
                cameraNode.setLocalTranslation(25, 0, 0);
                rotationNode.attachChild(cameraNode);
                cameraNode.updateWorldData(0);
            } else if (cameraIndex == CAMERA_XZ) {
                cameraNode = new CameraNode("XZ camera", cam);
                cameraNode.attachChild(lightNode);
                cameraNode.setLocalRotation(new Quaternion(new float[]{(float) Math.PI / 2.0f, 0f, 0f}));
                cameraNode.setLocalTranslation(0, 25, 0);
                rotationNode.attachChild(cameraNode);
                cameraNode.updateWorldData(0);
            } else if (cameraIndex == CAMERA_XY) {
                cameraNode = new CameraNode("XY camera", cam);
                cameraNode.attachChild(lightNode);
                cameraNode.setLocalRotation(new Quaternion(new float[]{0f, 0f, 0f}).mult(new Quaternion(new float[]{0f, (float) Math.PI, 0f})));
                cameraNode.setLocalTranslation(0, 0, 25);
                rotationNode.attachChild(cameraNode);
                cam.lookAt(rotationNode.getWorldTranslation(), new Vector3f(0, 1, 0));
                cameraNode.updateWorldData(0);
            } else {
                cameraNode = new CameraNode("Space camera", cam);
                cameraNode.attachChild(lightNode);
                cameraNode.setLocalTranslation(0, 0, -25);
                rootNode.attachChild(cameraNode);
                cam.lookAt(rotationNode.getWorldTranslation(), new Vector3f(0, 1, 0));
                cameraNode.updateWorldData(0);
            }
        } catch (NullPointerException npe) {
        }
    }

    public Node getRotationNode() {
        return rotationNode;
    }

    public final int getCameraIndex() {
        return cameraIndex;
    }

    public Node getCameraNode() {
        return cameraNode;
    }

    public void setStereo(Boolean stereo) {
        if (stereo && !basicPassManager.contains(stereoRenderPass)) {
            basicPassManager.remove(renderPass);
            basicPassManager.add(stereoRenderPass);
        } else if (!stereo && basicPassManager.contains(stereoRenderPass)) {
            basicPassManager.add(renderPass);
            basicPassManager.remove(stereoRenderPass);
        }
    }

    public StereoRenderPass getStereoRenderPass() {
        return stereoRenderPass;
    }

    public Boolean getStereo() {
        return basicPassManager.contains(stereoRenderPass);
    }

    public DisplaySystem getDisplaySystem() {
        return displaySystem;
    }

    public org.openide.nodes.Node createNodeDelegate() {
        return new SceneImplementationNode(this);
    }

    @Override
    public final Renderer getRenderer() {
        return renderer;
    }

    public static SceneImplementation getDefault() {
        if (sceneImplementation == null) {
            ProgressHandle progressHandle = ProgressHandleFactory.createHandle("Initialising 3D environment. Please wait...");
            progressHandle.start();
            progressHandle.switchToIndeterminate();
            sceneImplementation = new SceneImplementation(300, 300);
            progressHandle.finish();
        }
        return sceneImplementation;
    }
}



I think you must wait until renderer creation, because Context ceration takes some time.

Just wait while renderer is null

Hi!



I tried this code. It is listed on many homepages around the net. My renderer is ALWAYS null. I looked at the source code and found out, that if I use the



canvas=(JMECanvas)displaySystem.createCanvas(680,400);



command, renderer is NEVER initialised. The corresponding createWindow methods initialise the renderer. Then I tried to use



((LWJGLDisplaySystem) displaySystem).initForCanvas(width, height);



(which is uncommented in the code) but this throws me a NullPointException in the createTextureRenderer method. It seems as if GLContext object is zero. I really don't understand it. It must have something to do with the queue of initialising different things.




displaySystem = DisplaySystem.getDisplaySystem(LWJGLSystemProvider.LWJGL_SYSTEM_IDENTIFIER);
        displaySystem.registerCanvasConstructor("AWT", LWJGLAWTCanvasConstructor.class);//NOI18N

        LOG.info("Running on: " + displaySystem.getAdapter() + "nDriver version: " + displaySystem.getDriverVersion() + "n" + displaySystem.getDisplayVendor() + " - " + displaySystem.getDisplayRenderer() + " - " + displaySystem.getDisplayAPIVersion());

        displaySystem.setMinDepthBits(8);
        displaySystem.setMinStencilBits(0);
        displaySystem.setMinAlphaBits(0);
        displaySystem.setMinSamples(0);

          //   ((LWJGLDisplaySystem) displaySystem).initForCanvas(width, height);
        canvas=(JMECanvas)displaySystem.createCanvas(680,400);

        renderer = displaySystem.getRenderer();

try this :



while(DisplaySystem.getDisplaySystem().getRenderer() == null) {
    Thread.sleep(50);
}
// Renderer created

Hi!



I still stuck at the same problem.

However, I found out, that



renderer = DisplaySystem.getDisplaySystem().getRenderer();



returns a renderer if, and only if it is called in the doSetup method of a JMECanvasImplementor. I have absolutely no chance to construct it outside doSetup!!!



Hmmm, can someone please explain this to me??



Regards and Thanks,

Equilibrium

Does really noone know how to contruct a renderer without a window or canvas object?

Well probably  I can't  really help, but I wonder what sense it makes to create a render, with nowhere to render to ? O.o

The reason is following.

I program a visual IDE for creating complete games / scenes using JME and Netbeans. A user can create / load a project. The project has got a project node A. Now, objects like, cameras, models, lights etc. are also node objects in my visual representation. Directly after the project node I want to create a renderer node. Of course, if a user loads a project, I don't want to display the canvas or window immidietely but I already want to have a renderer so that the createLightState, createTextureState methods and all other objects who have to get infos from renderer can already be executed to initialise my visual tree.

A solution of course would be to init a canvas in background to init the renderer. This is programatically a nonsense, if the user opens the canvas in 5 or 10 minutes. Of course I could immediately close the canvas again but this is no good programming style. Beside, I don't think that you need a canvas to render. A renderer only renders a scene, which can also be saved in memory, without needing any canvas

So, In my opinion it would be straight forward that you create a renderer and attach the renderer to a canvas. Perhaps this works in any way but I don't know how to do it.

Nevertheless, Thanks for help.



Regards,

Equilibrium