Lesson 2: Water

Note:To acheive water effect, your graphics hardware must support shader.

Water in Env3D is simply a 1x1 square with reflective quality.  To create an environment with water, we need to use the EnvAdvanced class for our environment, and we need to have a skybox set properly.  The following example shows a simple usage of EnvWater:

import env3d.advanced.EnvAdvanced;
import env3d.advanced.EnvSkyRoom;
import env3d.advanced.EnvWater;
import env3d.Env;
  
public class Game
{
    public Game() {        
    }
      
    public void play() {        
        // EnvAdvanced must be used for water to work
        Env env = new EnvAdvanced();
                 
        // Need to use a skybox for our environment, so the water
        // has something to reflect.
        env.setRoom(createSkyRoom());
                 
        // Create the water object
        EnvWater water = new EnvWater();
        
        // Add the wataer object into our environment.
        // By default, the size of the water plain is 1x1 and
        // the center of the water is located at 0,0,0
        env.addObject(water);        
        
        // Move the camera back a little to show the water plain
        env.setCameraXYZ(0, 0, 10);
          
        // Exit when the escape key is pressed
        while (env.getKey() != 1) {
            env.advanceOneFrame();
        }
        env.exit();
    }
    
    public EnvSkyRoom createSkyRoom() {
        // Create a the sky box.  The parameter specifies the directory 
        // that contains north.jpg, south.jpg, east.jpg, west.jpg, top.jpg,
        // and bottom.jpg
        
        EnvSkyRoom skyroom = new EnvSkyRoom("textures/skybox/");
         
        return skyroom;
    }
    
    public static void main(String [] args) {
        (new Game()).play();
    }
}

Compile and run this program, you'll notice that there is a small black square in front of you.  Use the first person camera control to inspect the square. You'll observe that the "front" side of the square reflects the skybox, while the "back" side of the squre is translucent.  Let make our water plain bigger and also rotates so you can see better. 

import env3d.advanced.EnvAdvanced;
import env3d.advanced.EnvSkyRoom;
import env3d.advanced.EnvWater;
import env3d.Env;
  
public class Game
{
    public Game() {        
    }
      
    public void play() {        
        // EnvAdvanced must be used for water to work
        Env env = new EnvAdvanced();
                 
        // Need to use a skybox for our environment, so the water
        // has something to reflect.
        env.setRoom(createSkyRoom());
                 
        // Create the water object
        EnvWater water = new EnvWater();
        
        // Make the water plain a 10x10 square
        water.setScale(10);
        
        // Add the wataer object into our environment.
        env.addObject(water);        
        
        // Move the camera into position
        env.setCameraXYZ(0, 5, 10);
        env.setCameraPitch(-15);
          
        // Exit when the escape key is pressed
        while (env.getKey() != 1) {
            // Rotate the water
            water.setRotateX(water.getRotateX()+0.5);
            env.advanceOneFrame();
        }
        env.exit();
    }
    
    public EnvSkyRoom createSkyRoom() {
        // Create a the sky box.  The parameter specifies the directory 
        // that contains north.jpg, south.jpg, east.jpg, west.jpg, top.jpg,
        // and bottom.jpg
        
        EnvSkyRoom skyroom = new EnvSkyRoom("textures/skybox/");
         
        return skyroom;
    }
    
    public static void main(String [] args) {
        (new Game()).play();
    }
}

Adding other objects into our environment

A water plain that reflects our skybox is fun, but it gets better if we have other objects in our environment.  Let's add a simple EnvObject:

import env3d.advanced.EnvAdvanced;
import env3d.advanced.EnvSkyRoom;
import env3d.advanced.EnvWater;
import env3d.Env;
import env3d.EnvObject;
   
public class Game
{
    public Game() {        
    }
       
    public void play() {        
        // EnvAdvanced must be used for water to work
        Env env = new EnvAdvanced();
                  
        // Need to use a skybox for our environment, so the water
        // has something to reflect.
        env.setRoom(new EnvSkyRoom("textures/skybox"));
                  
        // Create the water object
        EnvWater water = new EnvWater();
         
        // Make the water plain a 10x10 square
        water.setScale(10);
         
        // Add the wataer object into our environment.
        env.addObject(water);        
         
        // Add an object another our environment
        EnvObject o = new EnvObject();
        o.setScale(1);
        o.setZ(1);
        o.setX(5);
        o.setY(5);

        env.addObject(o);
         
        // Look at the water plain from the side
        env.setCameraXYZ(-10, 5, 5);
        env.setCameraYaw(-55);
           
        // Exit when the escape key is pressed
        while (env.getKey() != 1) {
            // Rotate the water
            env.advanceOneFrame();
        }
        env.exit();
    }     
     
    public static void main(String [] args) {
        (new Game()).play();
    }
}

Exercises

  1. Complete the above example by making our water plain reflect our sphere.
  2. Implement your scene to resemble the following: