Black water in baseGame

Hello i want to add some water to my scene… I am using baseGame and result of my “work” is this:







That big black thing is waterQuad and i dont know why it is black:(



my code:

package marosko;

import java.nio.FloatBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;

import jmetest.renderer.TestSkybox;

import com.jme.app.BaseGame;
import com.jme.image.Texture;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.light.DirectionalLight;
import com.jme.math.Plane;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.pass.BasicPassManager;
import com.jme.renderer.pass.RenderPass;
import com.jme.scene.Node;
import com.jme.scene.Skybox;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.CullState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.TextureManager;
import com.jme.util.Timer;
import com.jmex.effects.water.WaterRenderPass;

public class Water extends BaseGame{
   private Camera cam;
   private int width, height, depth, freq;
   private boolean fullscreen;
   private static final Logger logger = Logger.getLogger(Main.class
            .getName());
   protected Timer timer;
   private Node root;
   private BasicPassManager pManager;
   private Skybox skybox;
   
   private Quad waterQuad;
   private WaterRenderPass waterEffectRenderPass;
   private float farPlane = 10000.0f;
   private float textureScale = 0.02f;
      
   public static void main(String[] args) {
      Water water = new Water();
      water.start();
   }
   @Override
   protected void cleanup() {
      // TODO Auto-generated method stub
      
   }
   @Override
   protected void initGame() {
      root = new Node("Korenovy uzol");
      cam.update();
      pManager = new BasicPassManager();
      
      ZBufferState buf = display.getRenderer().createZBufferState();
        buf.setEnabled(true);
        buf.setFunction(ZBufferState.CF_LEQUAL);
        root.setRenderState(buf);
      
        CullState cs = display.getRenderer().createCullState();
        cs.setCullMode(CullState.CS_BACK);
        root.setRenderState(cs);
       
        buildSkyBox();
        buildLighting();
       
        waterEffectRenderPass = new WaterRenderPass( cam, 4, false, true );
      //setting to default value just to show
      waterEffectRenderPass.setWaterPlane( new Plane( new Vector3f( 0.0f, 1.0f, 0.0f ), 0.0f ) );

      waterQuad = new Quad( "waterQuad", 1, 1 );
      FloatBuffer normBuf = waterQuad.getNormalBuffer( 0 );
      normBuf.clear();
      normBuf.put( 0 ).put( 1 ).put( 0 );
      normBuf.put( 0 ).put( 1 ).put( 0 );
      normBuf.put( 0 ).put( 1 ).put( 0 );
      normBuf.put( 0 ).put( 1 ).put( 0 );

      waterEffectRenderPass.setWaterEffectOnSpatial( waterQuad );
      root.attachChild( waterQuad );
      waterEffectRenderPass.setSkybox( skybox );
      pManager.add( waterEffectRenderPass );
      
      waterQuad.getLocalTranslation().y -= 10;
      
      RenderPass rootPass = new RenderPass();
      rootPass.add( root );
      pManager.add( rootPass );
      
      root.updateGeometricState(0.0f, true);
      root.updateRenderState();
       
   }

   @Override
   protected void initSystem() {
      // TODO Auto-generated method stub
      width = properties.getWidth(); 
      height = properties.getHeight();
      depth = properties.getDepth();
      freq = properties.getFreq();
      fullscreen = properties.getFullscreen();
      
         try {
         display = DisplaySystem.getDisplaySystem(properties.getRenderer());
         display.createWindow(width, height, depth, freq, fullscreen);
         display.setMinStencilBits(8);
         cam = display.getRenderer().createCamera(width, height);
      } catch (JmeException e) {
            logger.log(Level.SEVERE, "Could not create displaySystem", e);
         System.exit(1);
      }
      display.getRenderer().setBackgroundColor(ColorRGBA.blue.clone());
      
      cam.setFrustumPerspective(45.0f, (float)width / (float)height, 1, 1000);
      Vector3f loc = new Vector3f(20.0f, 0.0f, 0.0f);
      Vector3f left = new Vector3f(0.0f, 0.0f, -1.0f);
      Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
      Vector3f dir = new Vector3f(-1.0f, 0f, 0.0f);
      cam.setFrame(loc, left, up, dir);
      cam.update();
      
      timer = Timer.getTimer();
       display.getRenderer().setCamera(cam);
      
       KeyBindingManager.getKeyBindingManager().set("exit",
            KeyInput.KEY_ESCAPE);
      
   }

   @Override
   protected void reinit() {
      // TODO Auto-generated method stub
      
   }

   @Override
   protected void render(float interpolation) {
      display.getRenderer().clearBuffers();
        pManager.renderPasses(display.getRenderer());
   }

   @Override
   protected void update(float interpolation) {
      skybox.getLocalTranslation().set(cam.getLocation());
        skybox.updateGeometricState(0.0f, true);

        Vector3f transVec = new Vector3f(cam.getLocation().x,
                waterEffectRenderPass.getWaterHeight(), cam.getLocation().z);
        setTextureCoords(0, transVec.x, -transVec.z, textureScale);
        setVertexCoords(transVec.x, transVec.y, transVec.z);
       
        if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit")) {
         finished = true;
      }
   }
   
   private void buildLighting() {
        /** Set up a basic, default light. */
        DirectionalLight light = new DirectionalLight();
        light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
        light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, .5f));
        light.setDirection(new Vector3f(1,-1,0));
        light.setShadowCaster(true);
        light.setEnabled(true);

          /** Attach the light to a lightState and the lightState to rootNode. */
        LightState lightState = display.getRenderer().createLightState();
        lightState.setEnabled(true);
        lightState.setGlobalAmbient(new ColorRGBA(.2f, .2f, .2f, 1f));
        lightState.attach(light);
        root.setRenderState(lightState);
    }
   
   private void buildSkyBox() {
        skybox = new Skybox("skybox", 10, 10, 10);

        Texture north = TextureManager.loadTexture(
            TestSkybox.class.getClassLoader().getResource(
            "jmetest/data/texture/north.jpg"),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR);
        Texture south = TextureManager.loadTexture(
            TestSkybox.class.getClassLoader().getResource(
            "jmetest/data/texture/south.jpg"),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR);
        Texture east = TextureManager.loadTexture(
            TestSkybox.class.getClassLoader().getResource(
            "jmetest/data/texture/east.jpg"),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR);
        Texture west = TextureManager.loadTexture(
            TestSkybox.class.getClassLoader().getResource(
            "jmetest/data/texture/west.jpg"),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR);
        Texture up = TextureManager.loadTexture(
            TestSkybox.class.getClassLoader().getResource(
            "jmetest/data/texture/top.jpg"),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR);
        Texture down = TextureManager.loadTexture(
            TestSkybox.class.getClassLoader().getResource(
            "jmetest/data/texture/bottom.jpg"),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR);

        skybox.setTexture(Skybox.NORTH, north);
        skybox.setTexture(Skybox.WEST, west);
        skybox.setTexture(Skybox.SOUTH, south);
        skybox.setTexture(Skybox.EAST, east);
        skybox.setTexture(Skybox.UP, up);
        skybox.setTexture(Skybox.DOWN, down);
        skybox.preloadTextures();
        skybox.updateRenderState();
        root.attachChild(skybox);
    }
   
   private void setVertexCoords(float x, float y, float z)
    {
        FloatBuffer vertBuf = waterQuad.getVertexBuffer(0);
        vertBuf.clear();

        vertBuf.put(x - farPlane).put(y).put(z - farPlane);
        vertBuf.put(x - farPlane).put(y).put(z + farPlane);
        vertBuf.put(x + farPlane).put(y).put(z + farPlane);
        vertBuf.put(x + farPlane).put(y).put(z - farPlane);
    }

    private void setTextureCoords(int buffer, float x, float y, float textureScale)
    {
        x *= textureScale * 0.5f;
        y *= textureScale * 0.5f;
        textureScale = farPlane * textureScale;
        FloatBuffer texBuf;
        texBuf = waterQuad.getTextureBuffer(0, buffer);
        texBuf.clear();
        texBuf.put(x).put(textureScale + y);
        texBuf.put(x).put(y);
        texBuf.put(textureScale + x).put(y);
        texBuf.put(textureScale + x).put(textureScale + y);
    }
}

Don't know that it will solve your problem but you appear to be missing a pass update:



pManager.updatePasses(interpolation);

Thanks a lot but water is still black… :frowning:

BaseGame.update(interpolation)

interpolation is always passed as -1 in BaseGame.

You need to calculate the time per frame yourself:



  @Override
    protected void update(float interpolation) {
        Timer.getTimer().update();
        interpolation = Timer.getTimer().getTimePerFrame();
        root.updateGeometricState(interpolation, true);
        pManager.updatePasses(interpolation);

....
....



then you didn't set a reflectedscene for your waterrenderpass:


waterEffectRenderPass.setReflectedScene(skybox);



now I'll get a EXCEPTION_ACCESS_VIOLATION in your example, i didn't look further into it.
Compare your code with TestIsland or another example if you also get the violation.

So finally i solved the problem with code from simplePassGame and BaseSimpleGame

Here it is, if someone needs


package marosko;

import java.nio.FloatBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.jme.app.BaseGame;
import com.jme.image.Texture;
import com.jme.input.FirstPersonHandler;
import com.jme.input.InputHandler;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.light.PointLight;
import com.jme.math.Plane;
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.Node;
import com.jme.scene.SceneElement;
import com.jme.scene.Skybox;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.CullState;
import com.jme.scene.state.FogState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.GameTaskQueue;
import com.jme.util.GameTaskQueueManager;
import com.jme.util.TextureManager;
import com.jme.util.Timer;
import com.jmex.effects.water.WaterRenderPass;

public class Water extends BaseGame {
   private WaterRenderPass waterEffectRenderPass;
   private Skybox skybox;
   private Quad waterQuad;
   private float farPlane = 10000.0f;
   private float textureScale = 0.02f;
   protected LightState lightState;
   
   protected Timer timer;
   private Camera cam;
   private static final Logger logger = Logger.getLogger(Main.class
            .getName());
   protected InputHandler input;
   private float tpf;
   boolean pause;
   private Node rootNode;
   protected BasicPassManager pManager;
   
   public static void main( String[] args ) {
      Water app = new Water();
      app.setDialogBehaviour( ALWAYS_SHOW_PROPS_DIALOG );
      app.start();
   }

   protected void cleanup() {
      waterEffectRenderPass.cleanup();
   }

   private void setVertexCoords( float x, float y, float z ) {
      FloatBuffer vertBuf = waterQuad.getVertexBuffer( 0 );
      vertBuf.clear();

      vertBuf.put( x - farPlane ).put( y ).put( z - farPlane );
      vertBuf.put( x - farPlane ).put( y ).put( z + farPlane );
      vertBuf.put( x + farPlane ).put( y ).put( z + farPlane );
      vertBuf.put( x + farPlane ).put( y ).put( z - farPlane );
   }

   private void setTextureCoords( int buffer, float x, float y, float textureScale ) {
      x *= textureScale * 0.5f;
      y *= textureScale * 0.5f;
      textureScale = farPlane * textureScale;
      FloatBuffer texBuf;
      texBuf = waterQuad.getTextureBuffer( 0, buffer );
      texBuf.clear();
      texBuf.put( x ).put( textureScale + y );
      texBuf.put( x ).put( y );
      texBuf.put( textureScale + x ).put( y );
      texBuf.put( textureScale + x ).put( textureScale + y );
   }

   private void setupFog() {
      FogState fogState = display.getRenderer().createFogState();
      fogState.setDensity( 1.0f );
      fogState.setEnabled( true );
      fogState.setColor( new ColorRGBA( 1.0f, 1.0f, 1.0f, 1.0f ) );
      fogState.setEnd( farPlane );
      fogState.setStart( farPlane / 10.0f );
      fogState.setDensityFunction( FogState.DF_LINEAR );
      fogState.setApplyFunction( FogState.AF_PER_VERTEX );
      rootNode.setRenderState( fogState );
   }

   private void buildSkyBox() {
      skybox = new Skybox( "skybox", 10, 10, 10 );

      String dir = "jmetest/data/skybox1/";
      Texture north = TextureManager.loadTexture(
            Water.class.getClassLoader().getResource(
                  dir + "1.jpg" ),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR );
      Texture south = TextureManager.loadTexture(
            Water.class.getClassLoader().getResource(
                  dir + "3.jpg" ),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR );
      Texture east = TextureManager.loadTexture(
            Water.class.getClassLoader().getResource(
                  dir + "2.jpg" ),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR );
      Texture west = TextureManager.loadTexture(
            Water.class.getClassLoader().getResource(
                  dir + "4.jpg" ),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR );
      Texture up = TextureManager.loadTexture(
            Water.class.getClassLoader().getResource(
                  dir + "6.jpg" ),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR );
      Texture down = TextureManager.loadTexture(
            Water.class.getClassLoader().getResource(
                  dir + "5.jpg" ),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR );

      skybox.setTexture( Skybox.NORTH, north );
      skybox.setTexture( Skybox.WEST, west );
      skybox.setTexture( Skybox.SOUTH, south );
      skybox.setTexture( Skybox.EAST, east );
      skybox.setTexture( Skybox.UP, up );
      skybox.setTexture( Skybox.DOWN, down );
      skybox.preloadTextures();

      CullState cullState = display.getRenderer().createCullState();
      cullState.setCullMode( CullState.CS_NONE );
      cullState.setEnabled( true );
      skybox.setRenderState( cullState );

      ZBufferState zState = display.getRenderer().createZBufferState();
      zState.setEnabled( false );
      skybox.setRenderState( zState );

      FogState fs = display.getRenderer().createFogState();
      fs.setEnabled( false );
      skybox.setRenderState( fs );

      skybox.setLightCombineMode( LightState.OFF );
      skybox.setCullMode( SceneElement.CULL_NEVER );
      skybox.setTextureCombineMode( TextureState.REPLACE );
      skybox.updateRenderState();

      skybox.lockBounds();
      skybox.lockMeshes();
   }

   
   private void setupKeyBindings() {
      KeyBindingManager.getKeyBindingManager().set( "g", KeyInput.KEY_G );
      KeyBindingManager.getKeyBindingManager().set( "e", KeyInput.KEY_E );

      KeyBindingManager.getKeyBindingManager().set( "lower", KeyInput.KEY_H );
      KeyBindingManager.getKeyBindingManager().set( "higher", KeyInput.KEY_Y );

      KeyBindingManager.getKeyBindingManager().set( "1", KeyInput.KEY_1 );
      KeyBindingManager.getKeyBindingManager().set( "2", KeyInput.KEY_2 );

   }

   @Override
   protected void initGame() {
      pManager = new BasicPassManager();
      rootNode = new Node( "rootNode" );

        ZBufferState buf = display.getRenderer().createZBufferState();
        buf.setEnabled( true );
        buf.setFunction( ZBufferState.CF_LEQUAL );
        rootNode.setRenderState( buf );

        PointLight light = new PointLight();
        light.setDiffuse( new ColorRGBA( 0.75f, 0.75f, 0.75f, 0.75f ) );
        light.setAmbient( new ColorRGBA( 0.5f, 0.5f, 0.5f, 1.0f ) );
        light.setLocation( new Vector3f( 100, 100, 100 ) );
        light.setEnabled( true );

        lightState = display.getRenderer().createLightState();
        lightState.setEnabled( true );
        lightState.attach( light );
        rootNode.setRenderState( lightState );

        timer.reset();
       
        cam.setFrustumPerspective( 45.0f, (float) display.getWidth() / (float) display.getHeight(), 1f, farPlane );
      cam.setLocation( new Vector3f( 100, 50, 100 ) );
      cam.lookAt( new Vector3f( 0, 0, 0 ), Vector3f.UNIT_Y );
      cam.update();

      setupKeyBindings();

      setupFog();

      Node reflectedNode = new Node( "reflectNode" );

      buildSkyBox();
      reflectedNode.attachChild( skybox );
      rootNode.attachChild( reflectedNode );

      waterEffectRenderPass = new WaterRenderPass( cam, 4, false, true );
      waterEffectRenderPass.setWaterPlane( new Plane( new Vector3f( 0.0f, 1.0f, 0.0f ), 0.0f ) );

      waterQuad = new Quad( "waterQuad", 1, 1 );
      FloatBuffer normBuf = waterQuad.getNormalBuffer( 0 );
      normBuf.clear();
      normBuf.put( 0 ).put( 1 ).put( 0 );
      normBuf.put( 0 ).put( 1 ).put( 0 );
      normBuf.put( 0 ).put( 1 ).put( 0 );
      normBuf.put( 0 ).put( 1 ).put( 0 );

      waterEffectRenderPass.setWaterEffectOnSpatial( waterQuad );
      rootNode.attachChild( waterQuad );

      waterEffectRenderPass.setReflectedScene( reflectedNode );
      waterEffectRenderPass.setSkybox( skybox );
      pManager.add( waterEffectRenderPass );

      RenderPass rootPass = new RenderPass();
      rootPass.add( rootNode );
      pManager.add( rootPass );

      rootNode.setCullMode( SceneElement.CULL_NEVER );
      rootNode.setRenderQueueMode( Renderer.QUEUE_OPAQUE );
       
        rootNode.updateGeometricState( 0.0f, true );
        rootNode.updateRenderState();
        timer.reset();
      
   }

   @Override
   protected void initSystem() {
      logger.info(getVersion());
        try {
            display = DisplaySystem.getDisplaySystem( properties.getRenderer() );
      
            display.createWindow( properties.getWidth(), properties.getHeight(),
                    properties.getDepth(), properties.getFreq(), properties
                    .getFullscreen() );
            logger.info("Running on: " + display.getAdapter()
                    + "nDriver version: " + display.getDriverVersion() + "n"
                    + display.getDisplayVendor() + " - "
                    + display.getDisplayRenderer() + " - "
                    + display.getDisplayAPIVersion());
           
            cam = display.getRenderer().createCamera( display.getWidth(),
                    display.getHeight() );

        } catch ( JmeException e ) {
            logger.log(Level.SEVERE, "Could not create displaySystem", e);
            System.exit( 1 );
        }
        display.getRenderer().setBackgroundColor(ColorRGBA.blue.clone());
      
      cam.setFrustumPerspective(45.0f, (float)display.getWidth() / (float)display.getHeight(), 1, 1000);
      Vector3f loc = new Vector3f(20.0f, 0.0f, 0.0f);
      Vector3f left = new Vector3f(0.0f, 0.0f, -1.0f);
      Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
      Vector3f dir = new Vector3f(-1.0f, 0f, 0.0f);
      cam.setFrame(loc, left, up, dir);
      cam.update();
        display.getRenderer().setCamera( cam );

        FirstPersonHandler firstPersonHandler = new FirstPersonHandler( cam, 50,
                1 );
        input = firstPersonHandler;

        timer = Timer.getTimer();

        /** Sets the title of our display. */
        String className = getClass().getName();
        if ( className.lastIndexOf( '.' ) > 0 ) className = className.substring( className.lastIndexOf( '.' )+1 );
        display.setTitle( className );
       
        display.getRenderer().enableStatistics( true );
       
        KeyBindingManager.getKeyBindingManager().set( "exit",
                KeyInput.KEY_ESCAPE );
    }
   @Override
   protected void reinit() {
      
   }
   @Override
   protected void render(float interpolation) {
      Renderer r = display.getRenderer();
        r.clearStatistics();
        r.clearBuffers();
       
        GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER).execute();
       
        pManager.renderPasses(display.getRenderer());
   }

   @Override
   protected void update(float interpolation) {
      timer.update();
        tpf = timer.getTimePerFrame();

        input.update( tpf );

        GameTaskQueueManager.getManager().getQueue(GameTaskQueue.UPDATE).execute();
       
        if ( KeyBindingManager.getKeyBindingManager().isValidCommand( "exit",
                false ) ) {
            finished = true;
        }
        skybox.getLocalTranslation().set( cam.getLocation() );
      skybox.updateGeometricState( 0.0f, true );

      Vector3f transVec = new Vector3f( cam.getLocation().x, waterEffectRenderPass.getWaterHeight(), cam.getLocation().z );

      setTextureCoords( 0, transVec.x, -transVec.z, textureScale );

      setVertexCoords( transVec.x, transVec.y, transVec.z );
      
      rootNode.updateGeometricState(tpf, true);
      
      pManager.updatePasses(tpf);
   }
}