Problems rendering a different camera view to texture

Hi people,

  I'm having a problem with rendering a scene to a texture for displaying an 'objects eye view of the scene'. The following code has the same problem as my main code but is made up from the  TestCameraMan test program in the source code.



The problem is that the textures disappear from the scene which is rendered to the Quad using render to texture, and setup for rendering Ortho so that the quad is always displayed in the same position on the screen.



I can't see why the textures disappear from the ground! It must just be a parameter or some other setup detail missing! 



The cameraNode which is used for the render to texture view takes input from the mouse in this example, but I have tried setting the camerNode translation and rotation parameters by hand with the same problem. When I rotate the view so that the model which is being loaded is no longer in view, the floor texture (and any other textures) are not rendered in the scene.





public class TestCameraManTest extends SimpleGame {

   

    /

    * Physics objects

    */

    private Node model;

    private Node monitorNode;

    private CameraNode camNode;

   

    private TextureRenderer tRenderer;

    private Texture fakeTex;

    private float lastRend = 1;

    private Node hudNode;

    /


    * Entry point for the test,

    * @param args

    */

    public static void main(String[] args) {

        TestCameraManTest app = new TestCameraManTest();

        app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);

        app.start();

    }

   

    protected void cleanup() {

        lastRend++;

        simpleRender();

        super.cleanup();

    }

   

    protected void simpleUpdate() {

        //camNode.setLocalTranslation(new Vector3f((float)Math.random(),50f+(float)Math.random()*5f,-70f + (float)Math.random()*5f));

        monitorNode.updateGeometricState(0.0f, true);

    }

   

    protected void simpleRender() {

        lastRend += tpf;

        if (lastRend > .03f) {

            tRenderer.render(rootNode, fakeTex);

            lastRend = 0;

        }

        display.getRenderer().draw(monitorNode);

    }

   

    private void setupScene(){

        MilkToJme converter=new MilkToJme();

       

        URL MSFile=TestMilkJmeWrite.class.getClassLoader().getResource(

                "jmetest/data/model/msascii/run.ms3d");

        ByteArrayOutputStream BO=new ByteArrayOutputStream();

       

        try {

            converter.convert(MSFile.openStream(),BO);

        } catch (IOException e) {

            System.out.println("IO problem writting the file!!!");

            System.out.println(e.getMessage());

            System.exit(0);

        }

        JmeBinaryReader jbr=new JmeBinaryReader();

        URL TEXdir=TestMilkJmeWrite.class.getClassLoader().getResource(

                "jmetest/data/model/msascii/");

        jbr.setProperty("texurl",TEXdir);

        model=null;

        try {

            model=jbr.loadBinaryFormat(new ByteArrayInputStream(BO.toByteArray()));

        } catch (IOException e) {

            System.out.println("darn exceptions:" + e.getMessage());

        }

        model.getChild(0).getController(0).setActive(false);

       

        Box newBox = new Box("box",new Vector3f(0,0,0),10,10,10);

        model.attachChild(newBox);

        rootNode.attachChild(model);

       

        Box floorGraphics = new Box("Floor", new Vector3f(0f,-0.5f,0f), 500, 0.5f, 500); //a 100x1x100 plane

        TextureState texture = TextureLoader.loadTexture("jmetest/data/texture/dirt.jpg", true);

        floorGraphics.setRenderState(texture);

        floorGraphics.setModelBound(new BoundingBox());

        floorGraphics.updateModelBound();

        model.attachChild(floorGraphics);

        floorGraphics.updateWorldVectors();

        //model.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);

       

        CullState cs = display.getRenderer().createCullState();

        cs.setCullMode(CullState.CS_BACK);

        cs.setEnabled(true);

        rootNode.setRenderState(cs);

        model.setRenderState(cs);

    }

   

 

    protected void simpleInitGame() {

        cam.setLocation(new Vector3f(0.0f, 50.0f, 100.0f));

       

        cam.update();

       

        tRenderer = display.createTextureRenderer(256, 256, false, true, false, false,

                TextureRenderer.RENDER_TEXTURE_2D,

                0);

        camNode = new CameraNode("Camera Node", tRenderer.getCamera());

       

        camNode.setLocalTranslation(new Vector3f(0, 50, -50));

        camNode.updateGeometricState(0, true);

       

        // Setup the input controller and timer

        input = new NodeHandler(camNode, 10, 2 );





        setupScene();



        rootNode.attachChild(camNode);

       

        monitorNode = new Node("Monitor Node");

        Quad quad = new Quad("Monitor",512,512);

        quad.setRenderQueueMode(Renderer.QUEUE_ORTHO);

        quad.setLocalTranslation(new Vector3f(properties.getWidth()-256, properties.getHeight()-256, 0));

        monitorNode.attachChild(quad);





        // Ok, now lets create the Texture object that our scene will be rendered to.

        tRenderer.setBackgroundColor(new ColorRGBA(0f, 0f, 0f, 1f));

        fakeTex = new Texture();

        fakeTex.setRTTSource(Texture.RTT_SOURCE_RGB);

        tRenderer.setupTexture(fakeTex);

        TextureState screen = display.getRenderer().createTextureState();

        screen.setTexture(fakeTex);

        screen.setEnabled(true);

        quad.setRenderState(screen);

       

        monitorNode.updateGeometricState(0.0f, true);

        monitorNode.updateRenderState();

    }

}



The scene geometry is attached to the node called model, I noticed that if I used model.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT); then textures are shown but other strange things happen, such as making the original scene render flash. I don't know if that helps point to the problem I'm having? I would like for the textures to always be rendered on the objects which are in view in both camera views.



Thank you for your time!




Is this a problem with the render to texture in openGL or does someone know the easy way to solve this problem? It's sending me bonkers! 

It definately is not a general bug/shortcoming of gl or jme - I have used it in some apps for rear and side views including textures.

I don't have the time currently for debugging your app. But it's likely that some render state update or something is missing.

What did you change on TestCameraMan - can you post only those lines?

Hi Irrisor,

  I went back to the TestCameraMan code to see if I could cut to the main problem I seem to be having, there seem to be various problems going on. In the following code I have simply:


  1. set the quad used in TestCameraMan to the Ortho render mode, and positioned it on the screen
  2. commented out the line to set the input as a NodeHandler. There when running, if you move the mouse the image rendered onto the texture attached to the quad should stay the same right? Moving the mouse around just moves the rootNode view…



    However as shown in the screen capture below, if I move the mouse so that the view of the model is not in the main scene, then the models body disaperes or the texture becomes corrupted on the quad -render to texture view- as well.



    The first image is from when the app starts, with the whole model in view, the ortho view on the quad renders fine (the back view is on the quad):









    The second image is having moved the mouse so that the view of the model is moved with the head off the screen, the body texture on the render to texture rendered version on the quad shows corruption:









    Finally, same sort of problem, but this time nothing of the body is rendered, just a bit of the face having moved the mouse so that view of the model is almost all off the screen.









    The only lines of the original TestCameraMan which have been changed are:


  3. Setting the quad up for rendering Ortho:

        Quad quad = new Quad("Monitor", 256,256);

        quad.setRenderQueueMode( Renderer.QUEUE_ORTHO);   

        quad.setLocalTranslation(new Vector3f(128, 128, 0));



    2)  Disabling the camera view input:

      // Setup the input controller and timer

      //    input = new NodeHandler(camNode, 10, 1 );





    I really appreciate any help you can give me! I'm sure it's just some small thing I don't know to call! Thank you.







    Edit: It seems that setting the culll mode of the model Node to CULL_NEVER, solves the above problem. I think the previous problem is therefore a combination of incorrectly set render states used to set the textures up, and not setting the cull mode to CULL_NEVER. Does this sound likley? Cheers.


Hmm, I stepped through the rendering to debug this. The strange thing is that the DM_BASE is still drawn but it's not visible if only the face is culled in the main view :?

It is visible again if the whole model is culled in the main scene. Any body else any clues?



Good that you found a workaround for you, ranewc.