Hi, first of all, these are great libraries, they made my life much easier.
Secondly, I am still a bit n00bish, but right now I am trying to make a Terrain thingy, with water and effects, I just started using this engine yesterday.
I saw the code for the water and I implemented it with my terrain, I had to make a pManager for it to work, and I made sure I put the necessary lines in render etc.
The problem is that my water is too dark, compared to the terrain, and I thought I tied to too the node for lighting. I even disabled lights one time, and the water was still just as dark, so my guess is that the directional lighting isn’t hitting my water!
Here is a shot, and thank you for the help!
Grrrr, well ok, I did get it to show light, but now when i look at certain directions my skybox turns black, and then my water looses lighting!!
Here is my code:
//imports removed for space...
public class Terrain3D extends BaseGame {
public static void main(String[] args) {
Terrain3D app = new Terrain3D();
// We will load our own "fantastic" Flag Rush logo. Yes, I'm an artist.
app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG, Lesson9.class
.getClassLoader().getResource(
"jmetest/data/images/FlagRush.png"));
app.start();
}
protected BasicPassManager pManager;
private WaterRenderPass waterEffectRenderPass;
private ProjectedGrid projectedGrid;
private float farPlane = 2500.0f;
//Sky box (we update it each frame)
private Skybox skybox;
//the terrain we will drive over.
private TerrainBlock tb;
/** The camera that we see through. */
protected Camera cam;
/** The root of our normal scene graph. */
protected Node scene;
/** Handles our mouse/keyboard input. */
protected InputHandler input;
/** High resolution timer for jME. */
protected Timer timer;
/** The root node of our text. */
protected Node fpsNode;
/** Displays all the lovely information at the bottom. */
protected Text fps;
/** Simply an easy way to get at timer.getTimePerFrame(). */
protected float tpf;
/** True if the renderer should display bounds. */
protected boolean showBounds = false;
/** A wirestate to turn on and off for the rootNode */
protected WireframeState wireState;
/** A lightstate to turn on and off for the rootNode */
protected LightState lightState;
/** Location of the font for jME's text at the bottom */
public static String fontLocation = "com/jme/app/defaultfont.tga";
/**
* This is called every frame in BaseGame.start()
* @param interpolation unused in this implementation
* @see com.jme.app.AbstractGame#update(float interpolation)
*/
protected final void update(float interpolation) {
/** Recalculate the framerate. */
timer.update();
/** Update tpf to time per frame according to the Timer. */
tpf = timer.getTimePerFrame();
/** Check for key/mouse updates. */
input.update(tpf);
/** Send the fps to our fps bar at the bottom. */
fps.print("FPS: " + (int) timer.getFrameRate() + " - " +
display.getRenderer().getStatistics());
/** Call simpleUpdate in any derived classes of SimpleGame. */
simpleUpdate();
pManager.updatePasses(tpf);
/** Update controllers/render states/transforms/bounds for rootNode. */
scene.updateGeometricState(tpf, true);
//we want to keep the skybox around our eyes, so move it with
//the camera
skybox.setLocalTranslation(cam.getLocation());
skybox.updateGeometricState(0, true);
/** If toggle_wire is a valid command (via key T), change wirestates. */
if (KeyBindingManager
.getKeyBindingManager()
.isValidCommand("toggle_wire", false)) {
wireState.setEnabled(!wireState.isEnabled());
scene.updateRenderState();
}
/** If toggle_lights is a valid command (via key L), change lightstate. */
if (KeyBindingManager
.getKeyBindingManager()
.isValidCommand("toggle_lights", false)) {
lightState.setEnabled(!lightState.isEnabled());
scene.updateRenderState();
}
/** If toggle_bounds is a valid command (via key B), change bounds. */
if (KeyBindingManager
.getKeyBindingManager()
.isValidCommand("toggle_bounds", false)) {
showBounds = !showBounds;
}
/** If camera_out is a valid command (via key C), show camera location. */
if (KeyBindingManager
.getKeyBindingManager()
.isValidCommand("camera_out", false)) {
System.err.println("Camera at: " +
display.getRenderer().getCamera().getLocation());
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit", false)) {
finish();
}
}
/**
* This is called every frame in BaseGame.start(), after update()
* @param interpolation unused in this implementation
* @see com.jme.app.AbstractGame#render(float interpolation)
*/
protected final void render(float interpolation) {
/** Have the PassManager render. */
pManager.renderPasses(display.getRenderer());
/** Reset display's tracking information for number of triangles/vertexes */
display.getRenderer().clearStatistics();
/** Clears the previously rendered information. */
display.getRenderer().clearBuffers();
/** Draw the rootNode and all its children. */
display.getRenderer().draw(scene);
/** If showing bounds, draw rootNode's bounds, and the bounds of all its children. */
if (showBounds)
Debugger.drawBounds(scene, display.getRenderer());
/** Draw the fps node to show the fancy information at the bottom. */
display.getRenderer().draw(fpsNode);
/** Call simpleRender() in any derived classes. */
simpleRender();
}
/**
* Creates display, sets up camera, and binds keys. Called in BaseGame.start() directly after
* the dialog box.
* @see com.jme.app.AbstractGame#initSystem()
*/
protected final void initSystem() {
try {
/** Get a DisplaySystem acording to the renderer selected in the startup box. */
display = DisplaySystem.getDisplaySystem(properties.getRenderer());
/** Create a window with the startup box's information. */
display.createWindow(
properties.getWidth(),
properties.getHeight(),
properties.getDepth(),
properties.getFreq(),
properties.getFullscreen());
/** Create a camera specific to the DisplaySystem that works with
* the display's width and height*/
cam =
display.getRenderer().createCamera(
display.getWidth(),
display.getHeight());
}
catch (JmeException e) {
/** If the displaysystem can't be initialized correctly, exit instantly. */
e.printStackTrace();
System.exit(1);
}
/** Set a black background.*/
display.getRenderer().setBackgroundColor(ColorRGBA.black);
/** Set up how our camera sees. */
cam.setFrustumPerspective(45.0f,
(float) display.getWidth() /
(float) display.getHeight(), 1, 1000);
Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
Vector3f left = new Vector3f( -1.0f, 0.0f, 0.0f);
Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);
/** Move our camera to a correct place and orientation. */
cam.setFrame(loc, left, up, dir);
/** Signal that we've changed our camera's location/frustum. */
cam.update();
/** Assign the camera to this renderer.*/
display.getRenderer().setCamera(cam);
/** Create a basic input controller. */
FirstPersonHandler firstPersonHandler = new FirstPersonHandler( cam, properties.getRenderer() );
/** Signal to all key inputs they should work 50x faster. */
firstPersonHandler.getKeyboardLookHandler().setActionSpeed(50f);
firstPersonHandler.getMouseLookHandler().setActionSpeed(1f);
input = firstPersonHandler;
/** Get a high resolution timer for FPS updates. */
timer = Timer.getTimer();
/** Signal to the renderer that it should keep track of rendering information. */
display.getRenderer().enableStatistics(true);
/** Assign key T to action "toggle_wire". */
KeyBindingManager.getKeyBindingManager().set(
"toggle_wire",
KeyInput.KEY_T);
/** Assign key L to action "toggle_lights". */
KeyBindingManager.getKeyBindingManager().set(
"toggle_lights",
KeyInput.KEY_L);
/** Assign key B to action "toggle_bounds". */
KeyBindingManager.getKeyBindingManager().set(
"toggle_bounds",
KeyInput.KEY_B);
/** Assign key C to action "camera_out". */
KeyBindingManager.getKeyBindingManager().set(
"camera_out",
KeyInput.KEY_C);
KeyBindingManager.getKeyBindingManager().set(
"exit",
KeyInput.KEY_ESCAPE);
}
/**
* Creates rootNode, lighting, statistic text, and other basic render states.
* Called in BaseGame.start() after initSystem().
* @see com.jme.app.AbstractGame#initGame()
*/
protected final void initGame() {
display.setTitle("Cosmic3D Terrain Demo v.1 NX");
pManager = new BasicPassManager();
/** Create scene rootNode */
scene = new Node("scene node graph");
/** Create a wirestate to toggle on and off. Starts disabled with
* default width of 1 pixel. */
wireState = display.getRenderer().createWireframeState();
wireState.setEnabled(false);
scene.setRenderState(wireState);
//Time for a little optimization. We don't need to render back face triangles, so lets
//not. This will give us a performance boost for very little effort.
CullState cs = display.getRenderer().createCullState();
cs.setCullMode(CullState.CS_BACK);
scene.setRenderState(cs);
/** Create a ZBuffer to display pixels closest to the camera above farther ones. */
ZBufferState buf = display.getRenderer().createZBufferState();
buf.setEnabled(true);
buf.setFunction(ZBufferState.CF_LEQUAL);
scene.setRenderState(buf);
setupFog();
Node reflectedNode = new Node( "reflectNode" );
buildSkyBox();
buildTerrain();
reflectedNode.attachChild( skybox );
//reflectedNode.attachChild( createObjects() );
scene.attachChild( reflectedNode );
waterEffectRenderPass = new WaterRenderPass( cam, 4, true, true );
waterEffectRenderPass.setClipBias( 0.5f );
waterEffectRenderPass.setWaterMaxAmplitude( 2.0f );
//setting to default value just to show
waterEffectRenderPass.setWaterPlane( new Plane( new Vector3f( 0.0f, 1.0f, 0.0f ), 0.0f ) );
projectedGrid = new ProjectedGrid( "ProjectedGrid", cam, 64, 64, 0.01f, new WaterHeightGenerator() );
waterEffectRenderPass.setWaterEffectOnSpatial( projectedGrid );
scene.attachChild( projectedGrid );
waterEffectRenderPass.setReflectedScene( reflectedNode );
waterEffectRenderPass.setSkybox( skybox );
pManager.add( waterEffectRenderPass );
RenderPass rootPass = new RenderPass();
rootPass.add( scene );
pManager.add( rootPass );
// -- FPS DISPLAY
// First setup alpha state
/** This allows correct blending of text and what is already rendered below it*/
AlphaState as1 = display.getRenderer().createAlphaState();
as1.setBlendEnabled(true);
as1.setSrcFunction(AlphaState.SB_SRC_ALPHA);
as1.setDstFunction(AlphaState.DB_ONE);
as1.setTestEnabled(true);
as1.setTestFunction(AlphaState.TF_GREATER);
as1.setEnabled(true);
// Now setup font texture
TextureState font = display.getRenderer().createTextureState();
/** The texture is loaded from fontLocation */
font.setTexture(
TextureManager.loadTexture(
SimpleGame.class.getClassLoader().getResource(
fontLocation),
Texture.MM_LINEAR,
Texture.FM_LINEAR));
font.setEnabled(true);
// Then our font Text object.
/** This is what will actually have the text at the bottom. */
fps = new Text("FPS label", "");
fps.setCullMode(SceneElement.CULL_NEVER);
fps.setTextureCombineMode(TextureState.REPLACE);
// Finally, a stand alone node (not attached to root on purpose)
fpsNode = new Node("FPS node");
fpsNode.attachChild(fps);
fpsNode.setRenderState(font);
fpsNode.setRenderState(as1);
fpsNode.setCullMode(SceneElement.CULL_NEVER);
// ---- LIGHTS
buildLighting();
/** Let derived classes initialize. */
//simpleInitGame();
/** Update geometric and rendering information for both the rootNode and fpsNode. */
scene.updateGeometricState(0.0f, true);
scene.updateRenderState();
fpsNode.updateGeometricState(0.0f, true);
fpsNode.updateRenderState();
}
private void setupFog() {
FogState fogState = display.getRenderer().createFogState();
fogState.setDensity( 1.0f );
fogState.setEnabled( true );
fogState.setColor( new ColorRGBA( 0.6f, 0.8f, 1.0f, 1.0f ) );
fogState.setEnd( farPlane );
fogState.setStart( farPlane / 10.0f );
fogState.setDensityFunction( FogState.DF_LINEAR );
fogState.setApplyFunction( FogState.AF_PER_VERTEX );
scene.setRenderState( fogState );
}
private void buildSkyBox() {
skybox = new Skybox( "skybox", 10, 10, 10 );
String dir = "jmetest/effects/water/data/";
Texture north = TextureManager.loadTexture(
TestProjectedWater.class.getClassLoader().getResource(
dir + "1.jpg" ),
Texture.MM_LINEAR,
Texture.FM_LINEAR );
Texture south = TextureManager.loadTexture(
TestProjectedWater.class.getClassLoader().getResource(
dir + "3.jpg" ),
Texture.MM_LINEAR,
Texture.FM_LINEAR );
Texture east = TextureManager.loadTexture(
TestProjectedWater.class.getClassLoader().getResource(
dir + "2.jpg" ),
Texture.MM_LINEAR,
Texture.FM_LINEAR );
Texture west = TextureManager.loadTexture(
TestProjectedWater.class.getClassLoader().getResource(
dir + "4.jpg" ),
Texture.MM_LINEAR,
Texture.FM_LINEAR );
Texture up = TextureManager.loadTexture(
TestProjectedWater.class.getClassLoader().getResource(
dir + "6.jpg" ),
Texture.MM_LINEAR,
Texture.FM_LINEAR );
Texture down = TextureManager.loadTexture(
TestProjectedWater.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 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 scene. */
LightState lightState = display.getRenderer().createLightState();
lightState.setEnabled(true);
lightState.setGlobalAmbient(new ColorRGBA(.25f, .25f, .5f, 1f));
lightState.attach(light);
scene.setRenderState(lightState);
}
private void buildTerrain() {
MidPointHeightMap heightMap = new MidPointHeightMap(256, 1.25f);
// Scale the data
Vector3f terrainScale = new Vector3f(4, 1.0f, 4);
// create a terrainblock
tb = new TerrainBlock("Terrain", heightMap.getSize(), terrainScale,
heightMap.getHeightMap(), new Vector3f(0, -100, 0), false);
tb.setModelBound(new BoundingBox());
tb.updateModelBound();
// generate a terrain texture with 2 textures
ProceduralTextureGenerator pt = new ProceduralTextureGenerator(
heightMap);
pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader()
.getResource("jmetest/data/texture/grassb.png")), -128, 0, 128);
pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader()
.getResource("jmetest/data/texture/dirt.jpg")), 0, 128, 255);
pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader()
.getResource("jmetest/data/texture/highest.jpg")), 128, 255,
384);
pt.createTexture(32);
// assign the texture to the terrain
TextureState ts = display.getRenderer().createTextureState();
Texture t1 = TextureManager.loadTexture(pt.getImageIcon().getImage(),
Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR, true);
ts.setTexture(t1, 0);
//load a detail texture and set the combine modes for the two terrain textures.
Texture t2 = TextureManager.loadTexture(
TestTerrain.class.getClassLoader().getResource(
"jmetest/data/texture/Detail.jpg"),
Texture.MM_LINEAR_LINEAR,
Texture.FM_LINEAR);
ts.setTexture(t2, 1);
t2.setWrap(Texture.WM_WRAP_S_WRAP_T);
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);
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);
tb.setRenderState(ts);
//set the detail parameters.
tb.setDetailTexture(1, 16);
tb.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
scene.attachChild(tb);
}
protected void simpleInitGame() {
scene.attachChild(new Box("my box",new Vector3f(0,0,0),new Vector3f(1,1,1)));
}
protected void simpleUpdate() {}
protected void simpleRender() {}
protected void reinit() {
}
protected void cleanup() {
LoggingSystem.getLogger().log(Level.INFO, "Cleaning up resources.");
KeyInput.destroyIfInitalized();
MouseInput.destroyIfInitalized();
JoystickInput.destroyIfInitalized();
waterEffectRenderPass.cleanup();
}
}
Looks like tar…I'd hate to try to swim in there.
Well thank doesnt help
Sorry, haven't touched the water code yet myself so I don't have anything to offer…just wanted to keep the thread alive.
FIXED!
I forgot to attach a reflection node to the terrain, and it ended up fixing my problems and made water prettier, i also edited the projected water file some more for a nicer blue effect…
my fps isnt so good though with a geForce 7600gs
… but my terrain i guess used too many triangles
you should set your farplane to the variable farPlane instead of 1000. other from that, great you got it working!
thanx that help things out, i also increased my farplane so the water looks less "cut out" near the skybox.
now im going to try to implement bloom from the sample files.
Sigh… i feel like such a noob, i cant get bloom to work! The way i have it, it doesnt do anything, the terrain does not "glow." I think my nodes may not be attaching right, can someone please help!
//imports removed for space
public class Terrain3D extends BaseGame {
public static void main(String[] args) {
Terrain3D app = new Terrain3D();
// We will load our own "fantastic" Flag Rush logo. Yes, I'm an artist.
app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG, Terrain3D.class
.getClassLoader().getResource(
"images/ctd.png"));
app.start();
}
private BloomRenderPass bloomRenderPass;
protected BasicPassManager pManager;
private WaterRenderPass waterEffectRenderPass;
private ProjectedGrid projectedGrid;
private float farPlane = 10000.0f;
//Sky box (we update it each frame)
private Skybox skybox;
//the terrain we will drive over.
private TerrainBlock tb;
protected Camera cam;
protected Node scene;
protected InputHandler input;
protected Timer timer;
protected Node fpsNode;
protected Text fps;
protected float tpf;
protected boolean showBounds = false;
protected WireframeState wireState;
protected LightState lightState;
public static String fontLocation = "com/jme/app/defaultfont.tga";
protected final void update(float interpolation) {
/** Recalculate the framerate. */
timer.update();
/** Update tpf to time per frame according to the Timer. */
tpf = timer.getTimePerFrame();
/** Check for key/mouse updates. */
input.update(tpf);
/** Send the fps to our fps bar at the bottom. */
fps.print("FPS: " + (int) timer.getFrameRate() + " - " +
display.getRenderer().getStatistics());
/** Call simpleUpdate in any derived classes of SimpleGame. */
simpleUpdate();
pManager.updatePasses(tpf);
/** Update controllers/render states/transforms/bounds for rootNode. */
scene.updateGeometricState(tpf, true);
//we want to keep the skybox around our eyes, so move it with
//the camera
skybox.setLocalTranslation(cam.getLocation());
skybox.updateGeometricState(0, true);
/** If toggle_wire is a valid command (via key T), change wirestates. */
if (KeyBindingManager
.getKeyBindingManager()
.isValidCommand("toggle_wire", false)) {
wireState.setEnabled(!wireState.isEnabled());
scene.updateRenderState();
}
/** If toggle_lights is a valid command (via key L), change lightstate. */
if (KeyBindingManager
.getKeyBindingManager()
.isValidCommand("toggle_lights", false)) {
lightState.setEnabled(!lightState.isEnabled());
scene.updateRenderState();
}
/** If toggle_bounds is a valid command (via key B), change bounds. */
if (KeyBindingManager
.getKeyBindingManager()
.isValidCommand("toggle_bounds", false)) {
showBounds = !showBounds;
}
/** If camera_out is a valid command (via key C), show camera location. */
if (KeyBindingManager
.getKeyBindingManager()
.isValidCommand("camera_out", false)) {
System.err.println("Camera at: " +
display.getRenderer().getCamera().getLocation());
}
if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit", false)) {
finish();
}
}
protected final void render(float interpolation) {
/** Have the PassManager render. */
pManager.renderPasses(display.getRenderer());
/** Reset display's tracking information for number of triangles/vertexes */
display.getRenderer().clearStatistics();
/** Clears the previously rendered information. */
display.getRenderer().clearBuffers();
/** Draw the rootNode and all its children. */
display.getRenderer().draw(scene);
/** If showing bounds, draw rootNode's bounds, and the bounds of all its children. */
if (showBounds)
Debugger.drawBounds(scene, display.getRenderer());
/** Draw the fps node to show the fancy information at the bottom. */
display.getRenderer().draw(fpsNode);
/** Call simpleRender() in any derived classes. */
simpleRender();
}
protected final void initSystem() {
try {
/** Get a DisplaySystem acording to the renderer selected in the startup box. */
display = DisplaySystem.getDisplaySystem(properties.getRenderer());
/** Create a window with the startup box's information. */
display.createWindow(
properties.getWidth(),
properties.getHeight(),
properties.getDepth(),
properties.getFreq(),
properties.getFullscreen());
/** Create a camera specific to the DisplaySystem that works with
* the display's width and height*/
cam =
display.getRenderer().createCamera(
display.getWidth(),
display.getHeight());
}
catch (JmeException e) {
/** If the displaysystem can't be initialized correctly, exit instantly. */
e.printStackTrace();
System.exit(1);
}
/** Set a black background.*/
display.getRenderer().setBackgroundColor(ColorRGBA.black);
/** Set up how our camera sees. */
cam.setFrustumPerspective(45.0f,
(float) display.getWidth() /
(float) display.getHeight(), 1, farPlane);
Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
Vector3f left = new Vector3f( -1.0f, 0.0f, 0.0f);
Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);
/** Move our camera to a correct place and orientation. */
cam.setFrame(loc, left, up, dir);
/** Signal that we've changed our camera's location/frustum. */
cam.update();
/** Assign the camera to this renderer.*/
display.getRenderer().setCamera(cam);
/** Create a basic input controller. */
FirstPersonHandler firstPersonHandler = new FirstPersonHandler( cam, properties.getRenderer() );
/** Signal to all key inputs they should work 100x faster. */
firstPersonHandler.getKeyboardLookHandler().setActionSpeed(100f);
firstPersonHandler.getMouseLookHandler().setActionSpeed(1f);
input = firstPersonHandler;
/** Get a high resolution timer for FPS updates. */
timer = Timer.getTimer();
/** Signal to the renderer that it should keep track of rendering information. */
display.getRenderer().enableStatistics(true);
/** Assign key T to action "toggle_wire". */
KeyBindingManager.getKeyBindingManager().set(
"toggle_wire",
KeyInput.KEY_T);
/** Assign key L to action "toggle_lights". */
KeyBindingManager.getKeyBindingManager().set(
"toggle_lights",
KeyInput.KEY_L);
/** Assign key B to action "toggle_bounds". */
KeyBindingManager.getKeyBindingManager().set(
"toggle_bounds",
KeyInput.KEY_B);
/** Assign key C to action "camera_out". */
KeyBindingManager.getKeyBindingManager().set(
"camera_out",
KeyInput.KEY_C);
KeyBindingManager.getKeyBindingManager().set(
"exit",
KeyInput.KEY_ESCAPE);
}
protected final void initGame() {
display.setTitle("Cosmic3D Terrain Demo v.1 NX");
cam.setLocation( new Vector3f( 100, 200, 500 ) );
cam.update();
pManager = new BasicPassManager();
/** Create scene rootNode */
scene = new Node("scene node graph");
/** Create a wirestate to toggle on and off. Starts disabled with
* default width of 1 pixel. */
wireState = display.getRenderer().createWireframeState();
wireState.setEnabled(false);
scene.setRenderState(wireState);
//Time for a little optimization. We don't need to render back face triangles, so lets
//not. This will give us a performance boost for very little effort.
CullState cs = display.getRenderer().createCullState();
cs.setCullMode(CullState.CS_BACK);
scene.setRenderState(cs);
/** Create a ZBuffer to display pixels closest to the camera above farther ones. */
ZBufferState buf = display.getRenderer().createZBufferState();
buf.setEnabled(true);
buf.setFunction(ZBufferState.CF_LEQUAL);
scene.setRenderState(buf);
setupFog();
Node reflectedNode = new Node( "reflectNode" );
buildSkyBox();
buildTerrain();
reflectedNode.attachChild( skybox );
reflectedNode.attachChild( tb );
scene.attachChild( reflectedNode );
waterEffectRenderPass = new WaterRenderPass( cam, 4, true, true );
waterEffectRenderPass.setClipBias( 0.5f );
waterEffectRenderPass.setWaterMaxAmplitude( 5.0f );
//setting to default value just to show
waterEffectRenderPass.setWaterPlane( new Plane( new Vector3f( 0.0f, 1.0f, 0.0f ), 0.0f ) );
projectedGrid = new ProjectedGrid( "ProjectedGrid", cam, 32, 32, 0.01f, new WaterHeightGenerator() );
waterEffectRenderPass.setWaterEffectOnSpatial( projectedGrid );
scene.attachChild( projectedGrid );
waterEffectRenderPass.setReflectedScene( reflectedNode );
waterEffectRenderPass.setSkybox( skybox );
pManager.add( waterEffectRenderPass );
RenderPass rootPass = new RenderPass();
rootPass.add( scene );
pManager.add( rootPass );
bloomRenderPass = new BloomRenderPass(cam, 4);
if(!bloomRenderPass.isSupported()) {
Text t = new Text("Text", "GLSL Not supported on this computer.");
t.setRenderQueueMode(Renderer.QUEUE_ORTHO);
t.setLightCombineMode(LightState.OFF);
t.setLocalTranslation(new Vector3f(0,20,0));
fpsNode.attachChild(t);
} else {
bloomRenderPass.add(scene);
bloomRenderPass.setUseCurrentScene(true);
//bloomRenderPass.setEnabled(true);
//bloomRenderPass.setExposurePow(bloomRenderPass.getExposurePow() + 2.0f);
pManager.add(bloomRenderPass);
}
// -- FPS DISPLAY
// First setup alpha state
/** This allows correct blending of text and what is already rendered below it*/
AlphaState as1 = display.getRenderer().createAlphaState();
as1.setBlendEnabled(true);
as1.setSrcFunction(AlphaState.SB_SRC_ALPHA);
as1.setDstFunction(AlphaState.DB_ONE);
as1.setTestEnabled(true);
as1.setTestFunction(AlphaState.TF_GREATER);
as1.setEnabled(true);
// Now setup font texture
TextureState font = display.getRenderer().createTextureState();
/** The texture is loaded from fontLocation */
font.setTexture(
TextureManager.loadTexture(
SimpleGame.class.getClassLoader().getResource(
fontLocation),
Texture.MM_LINEAR,
Texture.FM_LINEAR));
font.setEnabled(true);
// Then our font Text object.
/** This is what will actually have the text at the bottom. */
fps = new Text("FPS label", "");
fps.setCullMode(SceneElement.CULL_NEVER);
fps.setTextureCombineMode(TextureState.REPLACE);
// Finally, a stand alone node (not attached to root on purpose)
fpsNode = new Node("FPS node");
fpsNode.attachChild(fps);
fpsNode.setRenderState(font);
fpsNode.setRenderState(as1);
fpsNode.setCullMode(SceneElement.CULL_NEVER);
// ---- LIGHTS
buildLighting();
/** Let derived classes initialize. */
//simpleInitGame();
/** Update geometric and rendering information for both the rootNode and fpsNode. */
scene.updateGeometricState(0.0f, true);
scene.updateRenderState();
fpsNode.updateGeometricState(0.0f, true);
fpsNode.updateRenderState();
}
private void setupFog() {
FogState fogState = display.getRenderer().createFogState();
fogState.setDensity( 1.0f );
fogState.setEnabled( true );
fogState.setColor( new ColorRGBA( 0.6f, 0.8f, 1.0f, 1.0f ) );
fogState.setEnd( farPlane );
fogState.setStart( 500.0f );
fogState.setDensityFunction( FogState.DF_LINEAR );
fogState.setApplyFunction( FogState.AF_PER_VERTEX );
scene.setRenderState( fogState );
}
private void buildSkyBox() {
skybox = new Skybox( "skybox", 10, 10, 10 );
String dir = "jmetest/effects/water/data/";
Texture north = TextureManager.loadTexture(
TestProjectedWater.class.getClassLoader().getResource(
dir + "1.jpg" ),
Texture.MM_LINEAR,
Texture.FM_LINEAR );
Texture south = TextureManager.loadTexture(
TestProjectedWater.class.getClassLoader().getResource(
dir + "3.jpg" ),
Texture.MM_LINEAR,
Texture.FM_LINEAR );
Texture east = TextureManager.loadTexture(
TestProjectedWater.class.getClassLoader().getResource(
dir + "2.jpg" ),
Texture.MM_LINEAR,
Texture.FM_LINEAR );
Texture west = TextureManager.loadTexture(
TestProjectedWater.class.getClassLoader().getResource(
dir + "4.jpg" ),
Texture.MM_LINEAR,
Texture.FM_LINEAR );
Texture up = TextureManager.loadTexture(
TestProjectedWater.class.getClassLoader().getResource(
dir + "6.jpg" ),
Texture.MM_LINEAR,
Texture.FM_LINEAR );
Texture down = TextureManager.loadTexture(
TestProjectedWater.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 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 scene. */
LightState lightState = display.getRenderer().createLightState();
lightState.setEnabled(true);
lightState.setGlobalAmbient(new ColorRGBA(.25f, .25f, .5f, 1f));
lightState.attach(light);
scene.setRenderState(lightState);
}
/**
* build the height map and terrain block.
*/
private void buildTerrain() {
MidPointHeightMap heightMap = new MidPointHeightMap(128, 1.25f);
// Scale the data
Vector3f terrainScale = new Vector3f(8, 1.25f, 8);
// create a terrainblock
tb = new TerrainBlock("Terrain", heightMap.getSize(), terrainScale,
heightMap.getHeightMap(), new Vector3f(0, -100, 0), false);
tb.setModelBound(new BoundingBox());
tb.updateModelBound();
// generate a terrain texture with 2 textures
ProceduralTextureGenerator pt = new ProceduralTextureGenerator(
heightMap);
pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader()
.getResource("jmetest/data/texture/grassb.png")), -128, 0, 128);
pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader()
.getResource("jmetest/data/texture/dirt.jpg")), 0, 128, 255);
pt.addTexture(new ImageIcon(TestTerrain.class.getClassLoader()
.getResource("jmetest/data/texture/highest.jpg")), 128, 255,
384);
pt.createTexture(32);
// assign the texture to the terrain
TextureState ts = display.getRenderer().createTextureState();
Texture t1 = TextureManager.loadTexture(pt.getImageIcon().getImage(),
Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR, true);
ts.setTexture(t1, 0);
//load a detail texture and set the combine modes for the two terrain textures.
Texture t2 = TextureManager.loadTexture(
TestTerrain.class.getClassLoader().getResource(
"jmetest/data/texture/Detail.jpg"),
Texture.MM_LINEAR_LINEAR,
Texture.FM_LINEAR);
ts.setTexture(t2, 1);
t2.setWrap(Texture.WM_WRAP_S_WRAP_T);
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);
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);
tb.setRenderState(ts);
//set the detail parameters.
tb.setDetailTexture(1, 16);
tb.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
scene.attachChild(tb);
}
protected void simpleInitGame() {
scene.attachChild(new Box("my box",new Vector3f(0,0,0),new Vector3f(1,1,1)));
}
protected void simpleUpdate() { }
protected void simpleRender() {}
protected void reinit() {
}
protected void cleanup() {
LoggingSystem.getLogger().log(Level.INFO, "Cleaning up resources.");
KeyInput.destroyIfInitalized();
MouseInput.destroyIfInitalized();
JoystickInput.destroyIfInitalized();
waterEffectRenderPass.cleanup();
if (bloomRenderPass != null)
bloomRenderPass.cleanup();
}
}