I've basically just ported the flagrush tutorial into a standard game with game states.
Whenever I attach the skybox to the rootNode, the textures for the terrain disappear. Without the skybox, the terrain texture works fine.
import java.util.HashMap;
import javax.swing.ImageIcon;
import com.LastHaven.object.Player;
import com.LastHaven.util.InputHandler.IngameCameraHandler;
import com.LastHaven.util.InputHandler.IngameInputHandler;
import com.LastHaven.util.properties.Values;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
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.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Skybox;
import com.jme.scene.shape.Box;
import com.jme.scene.state.FogState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.MaterialState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jme.util.Timer;
import com.jmex.game.state.CameraGameState;
import com.jmex.terrain.TerrainBlock;
import com.jmex.terrain.util.MidPointHeightMap;
import com.jmex.terrain.util.ProceduralTextureGenerator;
/**
* This Gamestates shows a spinning Box, Size and Color attributes are read from
* the FengGUI
*/
public class IngameGameState extends CameraGameState
{
private Player player = null;
private TerrainBlock tb;
private Timer timer;
protected InputHandler inputHandler;
protected InputHandler cameraInputHandler;
private Skybox skybox;
public IngameGameState()
{
super("ingamestate");
this.initSystem();
this.initFog();
this.buildTerrain();
this.initLight();
this.buildPlayer();
this.buildInputHandler();
this.buildCameraInputHandler();
this.buildSkyBox();
rootNode.updateRenderState();
rootNode.updateGeometricState(0, true);
}
private void initSystem()
{
// initialize the camera
int width = DisplaySystem.getDisplaySystem().getWidth();
int height = DisplaySystem.getDisplaySystem().getHeight();
cam.setFrustumPerspective(45.0f, (float) width / (float) height, 1,
5000);
/** Signal that we've changed our camera's location/frustum. */
cam.update();
/** Get a high resolution timer for FPS updates. */
timer = Timer.getTimer();
DisplaySystem.getDisplaySystem().getRenderer().setCamera(cam);
KeyBindingManager.getKeyBindingManager().set("exit",
KeyInput.KEY_ESCAPE);
}
private void initFog()
{
// set up a FogState
FogState fs = DisplaySystem.getDisplaySystem().getRenderer()
.createFogState();
fs.setStart(1000);
fs.setEnd(3000);
fs.setColor(ColorRGBA.black);
rootNode.setRenderState(fs);
}
/**
* we are going to build the player object here. For now, we will use a box
* as a place holder
*/
private void buildPlayer()
{
Box model = new Box("player", new Vector3f(0f, 0f, 0f), 0.2f, 0.8f, 0.2f);
MaterialState ms = DisplaySystem.getDisplaySystem().getRenderer()
.createMaterialState();
ms.setAmbient(Values.getInstance().getColor());
model.setRenderState(ms);
// set the vehicles attributes (these numbers can be thought of as
// Unit/Second).
player = new Player("Player Node", model);
player.setModelBound(new BoundingBox(new Vector3f(1f, 1f, 1f), 0.2f, 0.8f, 0.2f));
player.updateModelBound();
player.updateWorldBound();
player.setAcceleration(15f);
player.setBraking(25f);
player.setTurnSpeed(2.5f);
player.setWeight(25f);
player.setMaxSpeed(25f);
player.setMinSpeed(15f);
player.setLocalTranslation(new Vector3f(100, 0, 100));
rootNode.attachChild(player);
rootNode.updateWorldBound();
player.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
}
/**
* create our custom input handler.
*/
private void buildInputHandler()
{
// Exit the Application with ESC
KeyBindingManager.getKeyBindingManager().set("exit",
KeyInput.KEY_ESCAPE);
inputHandler = new IngameInputHandler(player);
}
/**
* create our custom camera input handler.
*/
private void buildCameraInputHandler()
{
Vector3f targetOffset = new Vector3f();
targetOffset.y = ((BoundingBox) player.getWorldBound()).yExtent * 1.5f;
HashMap<String, Object> props = new HashMap<String, Object>();
props.put(ThirdPersonMouseLook.PROP_MAXROLLOUT, "30");
props.put(ThirdPersonMouseLook.PROP_MINROLLOUT, "10");
props.put(ThirdPersonMouseLook.PROP_ENABLED, "true");
props.put(ThirdPersonMouseLook.PROP_INVERTEDY, "false");
props.put(ThirdPersonMouseLook.PROP_MOUSEXMULT, "1.0");
props.put(ThirdPersonMouseLook.PROP_MOUSEYMULT, "1.0");
props.put(ThirdPersonMouseLook.PROP_MAXASCENT, "" + 45
* FastMath.DEG_TO_RAD);
props.put(IngameCameraHandler.PROP_INITIALSPHERECOORDS, new Vector3f(5, 0,
30 * FastMath.DEG_TO_RAD));
props.put(IngameCameraHandler.PROP_TARGETOFFSET, targetOffset);
props.put(IngameCameraHandler.PROP_STAYBEHINDTARGET, "true");
//props.put(ThirdPersonMouseLook.PROP_ENABLED, "false");
cameraInputHandler = new IngameCameraHandler(cam, player, props);
}
/**
* build the height map and terrain block.
*/
private void buildTerrain()
{
MidPointHeightMap heightMap = new MidPointHeightMap(128, 1f);
// Scale the data
Vector3f terrainScale = new Vector3f(1.5f, 0.0575f, 4);
// create a terrainblock
tb = new TerrainBlock("Terrain", heightMap.getSize(), terrainScale,
heightMap.getHeightMap(), new Vector3f(0, 0, 0), false);
tb.setModelBound(new BoundingBox());
tb.updateModelBound();
// generate a terrain texture with 2 textures
ProceduralTextureGenerator pt = new ProceduralTextureGenerator(
heightMap);
pt.addTexture(new ImageIcon(IngameGameState.class.getClassLoader()
.getResource("textures/grassb.png")), -128, 0, 128);
pt.addTexture(new ImageIcon(IngameGameState.class.getClassLoader()
.getResource("textures/dirt.jpg")), 0, 128, 255);
pt.addTexture(new ImageIcon(IngameGameState.class.getClassLoader()
.getResource("textures/highest.jpg")), 128, 255, 384);
pt.createTexture(32);
// assign the texture to the terrain
TextureState ts = DisplaySystem.getDisplaySystem().getRenderer()
.createTextureState();
Texture t1 = TextureManager.loadTexture(pt.getImageIcon().getImage(),
Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR, true);
t1.setApply(Texture.AM_COMBINE);
t1.setCombineFuncRGB(Texture.ACF_MODULATE);
t1.setCombineSrc0RGB(Texture.ACS_TEXTURE);
t1.setCombineOp0RGB(Texture.ACO_SRC_COLOR);
t1.setCombineSrc1RGB(Texture.ACS_PRIMARY_COLOR);
t1.setCombineOp1RGB(Texture.ACO_SRC_COLOR);
t1.setCombineScaleRGB(1.0f);
ts.setTexture(t1, 0);
Texture t2 = TextureManager.loadTexture(IngameGameState.class.getClassLoader()
.getResource("textures/detail.jpg"), Texture.MM_LINEAR_LINEAR,
Texture.FM_LINEAR);
t2.setWrap(Texture.WM_WRAP_S_WRAP_T);
t2.setApply(Texture.AM_COMBINE);
t2.setCombineFuncRGB(Texture.ACF_ADD_SIGNED);
t2.setCombineSrc0RGB(Texture.ACS_TEXTURE);
t2.setCombineOp0RGB(Texture.ACO_SRC_COLOR);
t2.setCombineSrc1RGB(Texture.ACS_PREVIOUS);
t2.setCombineOp1RGB(Texture.ACO_SRC_COLOR);
t2.setCombineScaleRGB(1.0f);
ts.setTexture(t2, 1);
tb.setDetailTexture(1, 16);
tb.setRenderState(ts);
tb.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
rootNode.attachChild(tb);
}
/**
* buildSkyBox creates a new skybox object with all the proper textures. The
* textures used are the standard skybox textures from all the tests.
*
*/
private void buildSkyBox()
{
skybox = new Skybox("skybox", 10, 10, 10);
Texture north = TextureManager.loadTexture(IngameGameState.class
.getClassLoader().getResource("textures/north.jpg"),
Texture.MM_LINEAR, Texture.FM_LINEAR);
Texture south = TextureManager.loadTexture(IngameGameState.class
.getClassLoader().getResource("textures/south.jpg"),
Texture.MM_LINEAR, Texture.FM_LINEAR);
Texture east = TextureManager.loadTexture(IngameGameState.class
.getClassLoader().getResource("textures/east.jpg"),
Texture.MM_LINEAR, Texture.FM_LINEAR);
Texture west = TextureManager.loadTexture(IngameGameState.class
.getClassLoader().getResource("textures/west.jpg"),
Texture.MM_LINEAR, Texture.FM_LINEAR);
Texture up = TextureManager.loadTexture(IngameGameState.class.getClassLoader()
.getResource("textures/top.jpg"), Texture.MM_LINEAR,
Texture.FM_LINEAR);
Texture down = TextureManager.loadTexture(IngameGameState.class
.getClassLoader().getResource("textures/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();
rootNode.attachChild(skybox);
}
/**
* Read the Values from our GUI and apply them to our Box.
*/
protected void stateUpdate(float interpolation)
{
// update the time to get the framerate
timer.update();
interpolation = timer.getTimePerFrame();
// update the keyboard input (move the player around)
inputHandler.update(interpolation);
cameraInputHandler.update(interpolation);
// we want to keep the skybox around our eyes, so move it with
// the camera
if (skybox != null)
{
skybox.setLocalTranslation(cam.getLocation());
}
// if escape was pressed, we exit
if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit"))
{
this.cleanup();
}
// 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.
if (player != null)
{
player.update(interpolation);
float characterMinHeight = tb.getHeight(player
.getLocalTranslation())
+ ((BoundingBox) player.getWorldBound()).yExtent;
if (!Float.isInfinite(characterMinHeight)
&& !Float.isNaN(characterMinHeight))
{
player.getLocalTranslation().y = characterMinHeight;
}
}
// Because we are changing the scene (moving the skybox and player) we
// need to update
// the graph.
rootNode.updateGeometricState(interpolation, true);
}
protected void onActivate()
{
}
/**
* Set up a basic Light to Illuminate the Scene.
*/
private void initLight()
{
/** 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, 1.0f));
light.setDirection(new Vector3f(1, -1, 0));
light.setEnabled(true);
/** Attach the light to a lightState and the lightState to rootNode. */
LightState lightState = DisplaySystem.getDisplaySystem().getRenderer().createLightState();
lightState.setEnabled(true);
lightState.attach(light);
rootNode.setRenderState(lightState);
}
public Node getPlayer()
{
return player;
}
public void cleanup() {
super.cleanup();
System.out.println("Exiting game");
System.exit(0);
}
}