gt:             cam = display.getRenderer().createCamera(width, height);
context: /*
   * Copyright (c) 2003-2009 jMonkeyEngine
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are
   * met:
   *
   * * Redistributions of source code must retain the above copyright
   *   notice, this list of conditions and the following disclaimer.
   *
   * * Redistributions in binary form must reproduce the above copyright
   *   notice, this list of conditions and the following disclaimer in the
   *   documentation and/or other materials provided with the distribution.
   *
   * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 
   *   may be used to endorse or promote products derived from this software 
   *   without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   */
  
  package jmetest.flagrushtut.lesson7;
  
  import java.io.BufferedInputStream;
  import java.io.ByteArrayInputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.net.URL;
  import java.util.HashMap;
  import java.util.logging.Level;
  import java.util.logging.Logger;
  
  import javax.swing.ImageIcon;
  
  import jmetest.renderer.TestSkybox;
  import jmetest.terrain.TestTerrain;
  
  import com.jme.app.BaseGame;
  import com.jme.bounding.BoundingBox;
  import com.jme.image.Texture;
  import com.jme.input.ChaseCamera;
  import com.jme.input.InputHandler;
  import com.jme.input.KeyBindingManager;
  import com.jme.input.KeyInput;
  import com.jme.input.thirdperson.ThirdPersonMouseLook;
  import com.jme.light.DirectionalLight;
  import com.jme.math.FastMath;
  import com.jme.math.Vector3f;
  import com.jme.renderer.Camera;
  import com.jme.renderer.ColorRGBA;
  import com.jme.renderer.Renderer;
  import com.jme.scene.Node;
  import com.jme.scene.Skybox;
  import com.jme.scene.state.CullState;
  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.TextureManager;
  import com.jme.util.Timer;
  import com.jme.util.export.binary.BinaryImporter;
  import com.jmex.model.converters.MaxToJme;
  import com.jmex.terrain.TerrainBlock;
  import com.jmex.terrain.util.MidPointHeightMap;
  import com.jmex.terrain.util.ProceduralTextureGenerator;
  
  /**
   * <code>Tutorial 7</code> adds additional graphical pizzazz. The terrain now has a detail 
   * texture, and we are no longer driving a box around, but loading a futuristic bike model 
   * (thanks to 3D Cafe :) ). Additionally, terrain following is improved by taking the terrain
   * normals and applying it to the bike, so it orients itself based on the slope.
   * 
   * @author Mark Powell
   */
  public class Lesson7 extends BaseGame {
      private static final Logger logger = Logger.getLogger(Lesson7.class
              .getName());
      
      // the terrain we will drive over.
      private TerrainBlock tb;
      // fence that will keep us in.
      private ForceFieldFence fence;
      //Sky box (we update it each frame)
      private Skybox skybox;
      //the new player object
      private Vehicle player;
      //private ChaseCamera chaser;
      protected InputHandler input;
      
      //the timer
      protected Timer timer;
  
      // Our camera object for viewing the scene
      private Camera cam;
      //The chase camera, this will follow our player as he zooms around the level
      private ChaseCamera chaser;
  
      // the root node of the scene graph
      private Node scene;
  
      // display attributes for the window. We will keep these values
      // to allow the user to change them
      private int width, height, depth, freq;
      private boolean fullscreen;
      
      //store the normal of the terrain
      private Vector3f normal = new Vector3f();
  
      /**
       * Main entry point of the application
       */
      public static void main(String[] args) {
          Lesson7 app = new Lesson7();
          // We will load our own "fantastic" Flag Rush logo. Yes, I'm an artist.
          app.setConfigShowMode(ConfigShowMode.AlwaysShow, Lesson7.class
                  .getClassLoader().getResource(
                          "jmetest/data/images/FlagRush.png"));
          app.start();
      }
  
      /**
       * During an update we look for the escape button and update the timer
       * to get the framerate. Things are now starting to happen, so we will 
       * update 
       * 
       * @see com.jme.app.BaseGame#update(float)
       */
      protected void update(float interpolation) {
          // update the time to get the framerate
          timer.update();
          interpolation = timer.getTimePerFrame();
          //update the keyboard input (move the player around)
          input.update(interpolation);
          //update the chase camera to handle the player moving around.
          chaser.update(interpolation);
  
          fence.update(interpolation);
          
          //we want to keep the skybox around our eyes, so move it with
          //the camera
          skybox.setLocalTranslation(cam.getLocation());
          
          // if escape was pressed, we exit
          if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit")) {
              finished = true;
          }
          
          //We don't want the chase camera to go below the world, so always keep 
          //it 2 units above the level.
          if(cam.getLocation().y < (tb.getHeight(cam.getLocation())+2)) {
              cam.getLocation().y = tb.getHeight(cam.getLocation()) + 2;
              cam.update();
          }
          
          //make sure that if the player left the level we don't crash. When we add collisions,
          //the fence will do its job and keep the player inside.
          float characterMinHeight = tb.getHeight(player
                  .getLocalTranslation())+((BoundingBox)player.getWorldBound()).yExtent;
          if (!Float.isInfinite(characterMinHeight) && !Float.isNaN(characterMinHeight)) {
              player.getLocalTranslation().y = characterMinHeight;
          }
          
          //get the normal of the terrain at our current location. We then apply it to the up vector
          //of the player.
          tb.getSurfaceNormal(player.getLocalTranslation(), normal);
          if(normal != null) {
              player.rotateUpTo(normal);
          }
          
          //Because we are changing the scene (moving the skybox and player) we need to update
          //the graph.
          scene.updateGeometricState(interpolation, true);
      }
  
      /**
       * draws the scene graph
       * 
       * @see com.jme.app.BaseGame#render(float)
       */
      protected void render(float interpolation) {
          // Clear the screen
          display.getRenderer().clearBuffers();
          display.getRenderer().draw(scene);
      }
  
      /**
       * initializes the display and camera.
       * 
       * @see com.jme.app.BaseGame#initSystem()
       */
      protected void initSystem() {
          // store the settings information
          width = settings.getWidth();
          height = settings.getHeight();
          depth = settings.getDepth();
          freq = settings.getFrequency();
          fullscreen = settings.isFullscreen();
          
          try {
              display = DisplaySystem.getDisplaySystem(settings.getRenderer());
              display.createWindow(width, height, depth, freq, fullscreen);
  
  