Incorrect texture placement (and they move along with the camera)

Hello,



I have a problem with textures! I am using a pass manager that has a RenderPass and a DepthOfFieldRenderPass.

There are 3 boxes each one with the JME picture as texture.



If I develop a test based on the  TestDepthOfField example (which uses the create window method) i get the correct DOF effect. However, if i use the createCanvas method and and implementator I get the textures looking as the image in attachment. Besides as i move the camera the textures also move over the box surfaces.



Can anyone help on this issue?



Thanks.



EDIT: if I replace the DOFPAss by the bloom pass I get the result seen in the other picture(bloomproblem.jpg)



Here is my code for the implementator:



...
   ///////////////////////////////////////////////////////////////////////////////////
   public ActionImplementor3(int width, int height) {
      super(width, height);
      this.displayWidth = width;
      this.displayHeight = height;
   }
   ///////////////////////////////////////////////////////////////////////////////////
   public void simpleSetup() {
      {
         changing  = new Node("changing TDOI");         
         rootNode.attachChild(changing);
         
         stable = new Node("stable TDOI");
         rootNode.attachChild(stable);         
      }            

      setupDisplay();
      setupLights();
      setupCamera();
      setup1stPersonInput();
      setupPassManager();
      setupTest();   

      KeyBindingManager.getKeyBindingManager().set("1", KeyInput.KEY_1);
      KeyBindingManager.getKeyBindingManager().set("2", KeyInput.KEY_2);
      KeyBindingManager.getKeyBindingManager().set("3", KeyInput.KEY_3);
      KeyBindingManager.getKeyBindingManager().set("4", KeyInput.KEY_4);
      KeyBindingManager.getKeyBindingManager().set("5", KeyInput.KEY_5);
      KeyBindingManager.getKeyBindingManager().set("5", KeyInput.KEY_6);
      KeyBindingManager.getKeyBindingManager().set("6", KeyInput.KEY_7);
      KeyBindingManager.getKeyBindingManager().set("-", KeyInput.KEY_SUBTRACT);
      KeyBindingManager.getKeyBindingManager().set("+", KeyInput.KEY_ADD);
      KeyBindingManager.getKeyBindingManager().set("twopass_transp", KeyInput.KEY_2);
      KeyBindingManager.getKeyBindingManager().set("toggle_shadows",KeyInput.KEY_T);
      KeyBindingManager.getKeyBindingManager().set("light_update",KeyInput.KEY_9);
      KeyBindingManager.getKeyBindingManager().set("light_location_next", KeyInput.KEY_0);
      KeyBindingManager.getKeyBindingManager().set("camera_settings_record", KeyInput.KEY_INSERT);
      KeyBindingManager.getKeyBindingManager().set("camera_settings_next", KeyInput.KEY_PGUP);
      KeyBindingManager.getKeyBindingManager().set("camera_delete", KeyInput.KEY_DELETE);
      KeyBindingManager.getKeyBindingManager().set("camera_home", KeyInput.KEY_HOME);
      KeyBindingManager.getKeyBindingManager().set("render_config", KeyInput.KEY_9);
   }

   ///////////////////////////////////////////////////////////////////////////////////
   private void setupPassManager() {
      
      pManager = new BasicPassManager();
      pManager.clearAll();
      
      RenderPass rootPass = new RenderPass();
      rootPass.add( rootNode );      
      pManager.add( rootPass );
//                   
//      rootNode.updateGeometricState( 0, true );
      
      blurPass = new DepthOfFieldRenderPass( cam, 1 );
      blurPass.add( rootNode );               
      pManager.add( blurPass );
//      
////      BloomRenderPass bloomPass = new BloomRenderPass (cam, 4);
////      bloomPass.add( stable );
////      bloomPass.setUseCurrentScene(true);
////      pManager.add( bloomPass );
//      
//      RenderPass rootPass2 = new RenderPass();
//      rootPass2.add( rootNode );   
//      pManager.add( rootPass2 );
//          
   }
   ///////////////////////////////////////////////////////////////////////////////////
   protected void cameraPerspective() {
       cam.setFrustumPerspective( 45.0f, (float) width / height, 1, 1000 );
        cam.setParallelProjection( false );
        cam.update();
    }
   ///////////////////////////////////////////////////////////////////////////////////
    protected void cameraParallel() {
        cam.setParallelProjection( true );
        float aspect = (float) displayWidth / displayHeight;
        cam.setFrustum( -100, 1000, -50 * aspect, 50 * aspect, -50, 50 );
        cam.update();
    }   
   ///////////////////////////////////////////////////////////////////////////////////
   private void setupDisplay() {

      renderer.setBackgroundColor(ColorRGBA.black);
      startTime = System.currentTimeMillis() + 5000;
   }
   ///////////////////////////////////////////////////////////////////////////////////
   private void setupCamera() {

      /** Set up how our camera sees. */
        cameraPerspective();   
      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);
   }   
   ///////////////////////////////////////////////////////////////////////////////////
   protected void setup1stPersonInput() {

      if (firstPerson == null) {
         firstPerson = new FirstPersonHandler(cam, 300f, (.1f * FastMath.PI));
      }
      input = firstPerson;
   }   
   ///////////////////////////////////////////////////////////////////////////////////
   public void lookAtCenter(Renderer renderer) {

      BoundingBox bbox = null;
      rootNode.updateGeometricState(0f, true);
      rootNode.updateModelBound();
      BoundingVolume volume = rootNode.getWorldBound();

      if (volume instanceof BoundingBox) {
         bbox = (BoundingBox)volume;
         Vector3f center = bbox.getCenter();
         cam.lookAt(center, new Vector3f(0f, 1f, 0f));
         cam.setLocation(new Vector3f(center.x + bbox.xExtent, center.y + bbox.yExtent, center.z + bbox.zExtent));
         cam.update();
      }
   }   
   ///////////////////////////////////////////////////////////////////////////////////
   public void doUpdate() {

      timer.update();
      tpf = timer.getTimePerFrame();

      if (input.isEnabled()) {
         input.update(tpf);
      }
      
      if (KeyBindingManager.getKeyBindingManager().isValidCommand("twopass_transp", false)) {
         renderer.getQueue().setTwoPassTransparency(!renderer.getQueue().isTwoPassTransparency());
      }
      
      if (KeyBindingManager.getKeyBindingManager().isValidCommand("camera_settings_record", false)) {
         cameras.addCamera(getCamera());
      }

      if (KeyBindingManager.getKeyBindingManager().isValidCommand("camera_settings_next", false)) {
         cameras.nextCamera(renderer);
      }

      if (KeyBindingManager.getKeyBindingManager().isValidCommand("camera_delete", false)) {
         cameras.deleteCurrent(renderer);
      }

      if (KeyBindingManager.getKeyBindingManager().isValidCommand("render_config", false)) {
         setupPassManager();
      }

      if (KeyBindingManager.getKeyBindingManager().isValidCommand("camera_home", false)) {
         lookAtCenter(renderer);
      }


      if (KeyBindingManager.getKeyBindingManager().isValidCommand("light_update", false) || (currentLocation == FOLLOWCAMERA)) {
         setupLights();
      }

      if (KeyBindingManager.getKeyBindingManager().isValidCommand("light_location_next", false)) {
         currentLocation++;
         if (currentLocation > MAXLOCATIONS) currentLocation = 0;
         setupLights();
      }
      
       if (KeyBindingManager.getKeyBindingManager().isValidCommand("1", false)) {
               blurPass.setEnabled(!blurPass.isEnabled());
           }

           if (KeyBindingManager.getKeyBindingManager().isValidCommand("2", false)) {
               blurPass.setBlurSize(blurPass.getBlurSize() - 0.001f);
           }
           if (KeyBindingManager.getKeyBindingManager().isValidCommand("3", false)) {
               blurPass.setBlurSize(blurPass.getBlurSize() + 0.001f);
           }
           if (KeyBindingManager.getKeyBindingManager().isValidCommand("4", false)) {
              zbuffer  = ! zbuffer;
               //blurPass.setDisplayBuffer(zbuffer);
           }
           if (KeyBindingManager.getKeyBindingManager().isValidCommand("6", false)) {
              this.cameraParallel();
           }
           if (KeyBindingManager.getKeyBindingManager().isValidCommand("7", false)) {
              this.cameraPerspective();
           }

           if (KeyBindingManager.getKeyBindingManager().isValidCommand("-", false)) {
               float throttle = blurPass.getThrottle() - 1 / 200f;
               if (throttle < 0)
                   throttle = 0;
               blurPass.setThrottle(throttle);
           }
           if (KeyBindingManager.getKeyBindingManager().isValidCommand("+", false)) {
               float throttle = blurPass.getThrottle() + 1 / 200f;
               blurPass.setThrottle(throttle);
           }

      rootNode.updateGeometricState(tpf, true);
      pManager.updatePasses(tpf);
   }
   ///////////////////////////////////////////////////////////////////////////////////
   public void setupLights() {

      lightState = getRenderer().createLightState();
      lightState.setEnabled(true);
       
      DirectionalLight dl = new DirectionalLight();
      dl.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
      dl.setDiffuse(new ColorRGBA(0.2f, 0.2f, 0.2f, 1.0f));
      dl.setDirection(new Vector3f(1, -0.5f, 1));
      dl.setEnabled(true);
      lightState.attach(dl);

      PointLight pl = new PointLight();
      pl.setDiffuse(new ColorRGBA(.3f,.3f,.3f, 6f));
      pl.setAmbient(new ColorRGBA(.2f,.2f,.2f, 2f));
      pl.setShadowCaster(true);
      pl.setEnabled(true);
      pl.setLocation(new Vector3f(100,200,100));
      lightState.attach(pl);
      
      PointLight pl2 = new PointLight();
      pl2.setDiffuse(new ColorRGBA(.4f,.4f,.4f, 6f));      
      pl2.setShadowCaster(true);
      pl2.setEnabled(true);
      pl2.setLocation(new Vector3f(-100,0,200));
      lightState.attach(pl2);
            
        rootNode.setRenderState(lightState);
   }
....
///////////////////////////////////////////////////////////////////////////////////
   private Box getBox( final String name ) {
          
      Box node = new Box( name, Vector3f.UNIT_XYZ.clone().mult( 10 ).negateLocal(), Vector3f.UNIT_XYZ.clone().mult( 10 ) );
        TextureState ts = getRenderer().createTextureState();
       
        ts.setEnabled( true );
        ts.setTexture( TextureManager.loadTexture(
              RenderBlurAndTransparent.class.getClassLoader().getResource( "jmetest/data/images/Monkey.jpg" ),
                Texture.MinificationFilter.Trilinear,
                Texture.MagnificationFilter.Bilinear ) );
       
        node.setRenderState( ts );
       
        MaterialState ms = getRenderer().createMaterialState();       
      ms.setDiffuse(new ColorRGBA(1f, 0f, 1f, 0.5f));      
      ms.setEnabled(true);
        node.setRenderState( ms );           
      
        return node;
    }
   ///////////////////////////////////////////////////////////////////////////////////
   public void setupTest() {
       {
           box[0] = getBox( "box1" );
           box[0].getLocalTranslation().set( -25, -15, -20 );
           box[0].setUserData("blur", new BlurAmount(.2f));
        }
        {       
         box[1] = getBox( "box2" );
         box[1].getLocalTranslation().set( -26, -16, -60 );
        }
        {
           box[2] = getBox( "box3" );
           box[2].getLocalTranslation().set( -27, -17, -100 );
           box[2].setUserData("blur", new BlurAmount(.7f));
        }
        {              
           changing.attachChild( box[0]);
           stable.attachChild( box[1]);             
           changing.attachChild( box[2]);
          
        }          
        rootNode.updateGeometricState( 0, true );       
   }
   ///////////////////////////////////////////////////////////////////////////////////
   public void doRender() {
            
        // Clears the previously rendered information.
        renderer.clearBuffers();
       
        // Execute renderQueue item
        GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER).execute();
              
        pManager.renderPasses(renderer);

        Debugger.drawBounds( rootNode, renderer, true );
        Debugger.drawNormals( rootNode, renderer );
        Debugger.drawTangents( rootNode, renderer );
       
        renderer.displayBackBuffer();
   }



Dear forum,



I actually managed to find the problem but don't know if its anything that I am doing wrong or if it is a problem with common to some render passes.



I am using a glCanvas and an implementator. before the construction of the canvas I create the display system with a predefined width and height and have a listener to listen to window resizes. On resize I call the glCanvas resize (which does a render resize has I have seen in the source code).



However, I  realized through debug that the renderer and display system width and height values remain the original,  that have been passed during system creation, despite the resizes. More interestingly, there are two private variables in the renderer - oldWidth and oldHeight - that are updated!?



For this reason, in the render passes, the creation of texture that use display/renderer dimensions result in the artifacts thats can be seen in the pictures of the previous post.



Best regards,

citizen.x






Looks like you found a bug then.

If you can fix it and provide a patch that would of course be great :slight_smile:



If not, its best if you post a small test which shows the problem easily.

That way maybe someone with a bit spare time, can take a look at it.

Are you calling implementor.resizeCanvas( width, height ) when resizing your canvas?

Yes, i use implementator.resizeCanvas(width, height) .

Here is my JPanel containing the GLCanvas.



package avc.watch.jme;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelListener;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JPanel;

import avc.action.database.DBResultItem;
import avc.model.data.Cachable;
import avc.model.data.ChaserCamera;
import avc.model.data.Renderable3D;
import avc.model.data.attribute.GeometryAttribute;
import avc.watch.jme.implementators.ImplAlphaPseudoColor;
import avc.watch.jme.implementators.ImplBloomAlphaPseudoColor;
import avc.watch.jme.implementators.ImplBlurAlphaPseudoColor;
import avc.watch.jme.implementators.Implementable;

import com.jme.input.ChaseCamera;
import com.jme.input.InputHandler;
import com.jme.input.InputSystem;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.scene.Node;
import com.jme.system.DisplaySystem;
import com.jme.system.canvas.JMECanvas;
import com.jme.system.canvas.JMECanvasImplementor;
import com.jme.system.lwjgl.LWJGLSystemProvider;
import com.jmex.awt.input.AWTKeyInput;
import com.jmex.awt.input.AWTMouseInput;
import com.jmex.awt.lwjgl.LWJGLAWTCanvasConstructor;
import com.jmex.awt.lwjgl.LWJGLCanvas;

public class JMEAWTRenderDevice extends JPanel implements Renderable3D {

   private static final Logger logger = Logger.getLogger(JMEAWTRenderDevice.class.getName());

   private static final long serialVersionUID = 1L;
   private static final Dimension MIN_DIMENSION = new Dimension(400, 300);

   private int width = 640, height = 480;
   
   protected long now, startTime, fps;
   protected LWJGLCanvas glCanvas;
   protected Implementable impl;

   /////////////////////////////////////////////////////////////////////////////////////////////
   public JMEAWTRenderDevice() {

      setLayout(new BorderLayout());
      final JPanel testPanel = new JPanel();
      testPanel.setPreferredSize(new Dimension(50, 50));
      testPanel.setMinimumSize(new Dimension(100, 100));
      add(testPanel, BorderLayout.CENTER);
      testPanel.setLayout(new BorderLayout());
      try {
         testPanel.add(createCanvas(), BorderLayout.CENTER);
      }
      catch (Exception ex) {
         ex.printStackTrace();
      }
      testPanel.setBorder(null);

      addComponentListener(new ComponentListener() {

         public void componentHidden(ComponentEvent e) {
            glCanvas.repaint();
         }

         public void componentMoved(ComponentEvent e) {
            glCanvas.repaint();
         }

         public void componentResized(ComponentEvent e) {
            Component c = (Component)e.getSource();
            glCanvas.setSize(c.getSize());
            impl.resizeCanvas(glCanvas.getSize().width, glCanvas.getSize().height);

         }

         public void componentShown(ComponentEvent e) {
            glCanvas.repaint();
         }

      });

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

         public void run() {
            while (true) {
               if (glCanvas != null)
                  glCanvas.repaint();
               try {
                  sleep(10);
               } catch (InterruptedException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
               }
               yield();
            }
         }
      }.start();

      setVisible(true);
   }
   /////////////////////////////////////////////////////////////////////////////////////////////
   public Implementable getImplementable() {
      return impl;
   }
   /////////////////////////////////////////////////////////////////////////////////////////////
   public Dimension getMinimumSize() {
      return MIN_DIMENSION;
   }
   /////////////////////////////////////////////////////////////////////////////////////////////
   protected Canvas createCanvas() {

      if (glCanvas == null) {
               
         DisplaySystem display = DisplaySystem.getDisplaySystem(LWJGLSystemProvider.LWJGL_SYSTEM_IDENTIFIER);
           display.registerCanvasConstructor("AWT", LWJGLAWTCanvasConstructor.class);
          
         glCanvas = (LWJGLCanvas)display.createCanvas(width, height);
            glCanvas.setUpdateInput(true);
            glCanvas.setTargetRate(60);

          logger.setLevel(Level.WARNING);

         // add a listener... if window is resized, we can do something about it.
         glCanvas.addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent ce) {
               impl.resizeCanvas(glCanvas.getSize().width, glCanvas.getSize().height);
            }
         });

         glCanvas.addFocusListener(new FocusListener() {
            public void focusGained(FocusEvent arg0) {
               ((AWTKeyInput) KeyInput.get()).setEnabled(true);
               ((AWTMouseInput) MouseInput.get()).setEnabled(true);
            }
            public void focusLost(FocusEvent arg0) {
               ((AWTKeyInput) KeyInput.get()).setEnabled(false);
               ((AWTMouseInput) MouseInput.get()).setEnabled(false);
            }
         });

         // We are going to use jme's Input systems, so enable updating.
         ((JMECanvas)glCanvas).setUpdateInput(true);

         if (KeyInput.isInited() == false) {
            KeyInput.setProvider(InputSystem.INPUT_SYSTEM_AWT);
         }

         ((AWTKeyInput) KeyInput.get()).setEnabled(false);
         KeyListener kl = (KeyListener) KeyInput.get();
         glCanvas.addKeyListener(kl);

         if (MouseInput.isInited() == false) {
            MouseInput.setProvider(InputSystem.INPUT_SYSTEM_AWT);
         }
         ((AWTMouseInput) MouseInput.get()).setEnabled(false);
         ((AWTMouseInput) MouseInput.get()).setDragOnly(true);
         ((AWTMouseInput) MouseInput.get()).setRelativeDelta(glCanvas);

         glCanvas.addMouseListener((MouseListener) MouseInput.get());
         glCanvas.addMouseWheelListener((MouseWheelListener)MouseInput.get());
         glCanvas.addMouseMotionListener((MouseMotionListener)MouseInput.get());

         impl = new ImplBlurAlphaPseudoColor(width, height);
         JMECanvas canvas = (JMECanvas)glCanvas;
         canvas.setImplementor((JMECanvasImplementor)impl);
         canvas.setUpdateInput(true);
      }
      return glCanvas;
   }
   /////////////////////////////////////////////////////////////////////////////////////////////
   protected void updateFPS() {
      now = System.currentTimeMillis();
      if (startTime > now) {
         fps++;
      }
      else {
         startTime = now + 5000;
         fps = 0;
      }
   }
   /////////////////////////////////////////////////////////////////////////////////////////////
   public float getFPS() {
      long timeUsed = 5000 + (startTime - now);
      return fps / (timeUsed / 1000f);
   }
   /////////////////////////////////////////////////////////////////////////////////////////////
   public void dispose() {
      ((JMECanvas) glCanvas).setImplementor(null);
      glCanvas.removeMouseListener((MouseListener)MouseInput.get());
      glCanvas.removeMouseWheelListener((MouseWheelListener) MouseInput.get());
      glCanvas.removeMouseMotionListener((MouseMotionListener) MouseInput.get());
      glCanvas.removeKeyListener((KeyListener) KeyInput.get());
   }
}



Is this jME 1.0 or 2.0??



Because I don't believe the thread you have in there to render is needed for 2.0…



Also, the canvas is abstracted so you shouldn't need to use LWJGL canvas directly; just the jMECanvas.



check this thread: http://www.jmonkeyengine.com/jmeforum/index.php?topic=10391.0





(there is no way anyone can use this to test; there are a bunch of avc imports…)