2 * Copyright (c) 2003-2009 jMonkeyEngine
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 package jmetest.flagrushtut;
35 import java.util.logging.Level;
36 import java.util.logging.Logger;
38 import javax.swing.ImageIcon;
40 import jmetest.terrain.TestTerrain;
42 import com.jme.app.BaseGame;
43 import com.jme.bounding.BoundingBox;
44 import com.jme.image.Texture;
45 import com.jme.input.KeyBindingManager;
46 import com.jme.input.KeyInput;
47 import com.jme.light.DirectionalLight;
48 import com.jme.math.Vector3f;
49 import com.jme.renderer.Camera;
50 import com.jme.renderer.ColorRGBA;
51 import com.jme.scene.Node;
52 import com.jme.scene.state.LightState;
53 import com.jme.scene.state.TextureState;
54 import com.jme.system.DisplaySystem;
55 import com.jme.system.JmeException;
56 import com.jme.util.TextureManager;
57 import com.jme.util.Timer;
58 import com.jmex.terrain.TerrainBlock;
59 import com.jmex.terrain.util.MidPointHeightMap;
60 import com.jmex.terrain.util.ProceduralTextureGenerator;
63 * <code>Tutorial 3</code> Loads a random terrain for uses at the game level.
64 * framework for Flag Rush. For Flag Rush Tutorial Series.
68 public class Lesson3 extends BaseGame {
69 private static final Logger logger = Logger.getLogger(Lesson3.class
72 private TerrainBlock tb;
74 protected Timer timer;
76 // Our camera object for viewing the scene
79 // the root node of the scene graph
82 // display attributes for the window. We will keep these values
83 // to allow the user to change them
84 private int width, height, depth, freq;
86 private boolean fullscreen;
89 * Main entry point of the application
91 public static void main(String[] args) {
92 Lesson3 app = new Lesson3();
93 // We will load our own "fantastic" Flag Rush logo. Yes, I'm an artist.
94 app.setConfigShowMode(ConfigShowMode.AlwaysShow, Lesson3.class
95 .getClassLoader().getResource(
96 "jmetest/data/images/FlagRush.png"));
101 * During an update we only look for the escape button and update the timer
102 * to get the framerate.
104 * @see com.jme.app.BaseGame#update(float)
106 protected void update(float interpolation) {
107 // update the time to get the framerate
109 interpolation = timer.getTimePerFrame();
110 // if escape was pressed, we exit
111 if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit")) {
117 * draws the scene graph
119 * @see com.jme.app.BaseGame#render(float)
121 protected void render(float interpolation) {
123 display.getRenderer().clearBuffers();
125 display.getRenderer().draw(scene);
130 * initializes the display and camera.
132 * @see com.jme.app.BaseGame#initSystem()
134 protected void initSystem() {
135 // store the settings information
136 width = settings.getWidth();
137 height = settings.getHeight();
138 depth = settings.getDepth();
139 freq = settings.getFrequency();
140 fullscreen = settings.isFullscreen();
143 display = DisplaySystem.getDisplaySystem(settings.getRenderer());
144 display.createWindow(width, height, depth, freq, fullscreen);
146 cam = display.getRenderer().createCamera(width, height);
147 } catch (JmeException e) {
148 logger.log(Level.SEVERE, "Could not create displaySystem", e);
152 // set the background to black
153 display.getRenderer().setBackgroundColor(ColorRGBA.black.clone());
155 // initialize the camera
156 cam.setFrustumPerspective(45.0f, (float) width / (float) height, 1,
158 Vector3f loc = new Vector3f(500.0f, 150.0f, 500.0f);
159 Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f);
160 Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
161 Vector3f dir = new Vector3f(0.0f, 0.0f, -1.0f);
162 // Move our camera to a correct place and orientation.
163 cam.setFrame(loc, left, up, dir);
164 /** Signal that we've changed our camera's location/frustum. */
167 /** Get a high resolution timer for FPS updates. */
168 timer = Timer.getTimer();
170 display.getRenderer().setCamera(cam);
172 KeyBindingManager.getKeyBindingManager().set("exit",
173 KeyInput.KEY_ESCAPE);
177 * initializes the scene
179 * @see com.jme.app.BaseGame#initGame()
181 protected void initGame() {
182 scene = new Node("Scene graph node");
184 scene.attachChild(tb);
188 // update the scene graph for rendering
189 scene.updateGeometricState(0.0f, true);
190 scene.updateRenderState();
194 * creates a light for the terrain.
196 private void buildLighting() {
197 /** Set up a basic, default light. */
198 DirectionalLight light = new DirectionalLight();
199 light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
200 light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
201 light.setDirection(new Vector3f(1,-1,0));
202 light.setEnabled(true);
204 /** Attach the light to a lightState and the lightState to rootNode. */
205 LightState lightState = display.getRenderer().createLightState();
206 lightState.setEnabled(true);
207 lightState.attach(light);
208 scene.setRenderState(lightState);
212 * build the height map and terrain block.
214 private void buildTerrain() {
217 // Generate a random terrain data
218 MidPointHeightMap heightMap = new MidPointHeightMap(64, 1f);
220 Vector3f terrainScale = new Vector3f(20, 0.5f, 20);
221 // create a terrainblock
222 tb = new TerrainBlock("Terrain", heightMap.getSize(), terrainScale,
223 heightMap.getHeightMap(), new Vector3f(0, 0, 0));
225 tb.setModelBound(new BoundingBox());
226 tb.updateModelBound();
228 // generate a terrain texture with 2 textures
229 ProceduralTextureGenerator pt = new ProceduralTextureGenerator(
231 pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader()
232 .getResource("jmetest/data/texture/grassb.png")), -128, 0, 128);
233 pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader()
234 .getResource("jmetest/data/texture/dirt.jpg")), 0, 128, 255);
235 pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader()
236 .getResource("jmetest/data/texture/highest.jpg")), 128, 255,
238 pt.createTexture(32);
240 // assign the texture to the terrain
241 TextureState ts = display.getRenderer().createTextureState();
243 Texture t1 = TextureManager.loadTexture(pt.getImageIcon().getImage(),
244 Texture.MinificationFilter.Trilinear, Texture.MagnificationFilter.Bilinear, true);
245 ts.setTexture(t1, 0);
247 tb.setRenderState(ts);
251 * will be called if the resolution changes
253 * @see com.jme.app.BaseGame#reinit()
255 protected void reinit() {
256 display.recreateWindow(width, height, depth, freq, fullscreen);
260 * close the window and also exit the program.
262 protected void quit() {
268 * clean up the textures.
270 * @see com.jme.app.BaseGame#cleanup()
272 protected void cleanup() {