Hi there,
Just wondering if it is possible to incorporate the quad water effects in a game that extends basegame? I notice that all the tests extend simple pass game, does this mean that any game that uses the water effects has to also extend the simple pass game? If not then does anyone know any good tutorials that use the water in this way?
Thanks for your time
Have now managed to get some sort of quad water in the base game - it was the SimplePassManager I was lacking. However, now the water quad appears as some big black block - which is rather upsetting - when the same code on the same computer, in the SimplePassGame comes out nice and watery. Has anyone else run into this problem and got a solution?
Thanks
the important thing is that the waterrenderpass get to draw it's stuff before the rest.
can you post code on how you set it up?
Ah ok -
the init code is this:
protected void initGame() {
scene = new Node("Scene graph node");
/** 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);
CullState cs = display.getRenderer().createCullState();
cs.setCullMode(CullState.CS_BACK);
scene.setRenderState(cs);
buildLighting();
buildSkyBox();
buildPlayer();
buildChaseCamera();
buildInput();
l = new ModelLoader();
models = new ArrayList<Node>();
invisibles = new ArrayList<Node>();
l.loadBase();
l.loadGatesCourse1();
l.loadInvisibles();
loadAllModels();
loadAllInvisibles();
Quad hudQuad = new Quad("hud", 146f, 40f);
speedGauge = new Quad("gauge", 128f, 32f);
hudNode.setRenderQueueMode(Renderer.QUEUE_ORTHO);
hudNode.setLocalTranslation(new Vector3f(display.getWidth() -100 ,display.getHeight() - (display.getHeight() -40),0));
TextureState ts = display.getRenderer().createTextureState();
ts.setTexture(TextureManager.loadTexture(getClass().getClassLoader()
.getResource("assignment/models/testBarBig.png"), Texture.MM_LINEAR,
Texture.FM_LINEAR, 1.0f, true));
textureWidth = ts.getTexture().getImage().getWidth();
textureHeight = ts.getTexture().getImage().getHeight();
ts.setEnabled(true);
FloatBuffer texCoords = BufferUtils.createVector2Buffer(4);
texCoords.put(getUForPixel(0)).put(getVForPixel(0));
texCoords.put(getUForPixel(0)).put(getVForPixel(40));
texCoords.put(getUForPixel(136)).put(getVForPixel(40));
texCoords.put(getUForPixel(136)).put(getVForPixel(0));
hudQuad.setTextureBuffer(0, texCoords);
AlphaState as = display.getRenderer().createAlphaState();
as.setBlendEnabled(true);
as.setSrcFunction(AlphaState.SB_SRC_ALPHA);
as.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
as.setTestEnabled(false);
as.setEnabled(true);
hudNode.setLightCombineMode(LightState.OFF);
hudNode.updateRenderState();
hudNode.attachChild(hudQuad);
hudNode.attachChild(speedGauge);
hudNode.setRenderState(ts);
hudNode.setRenderState(as);
hudNode.updateRenderState();
setGauge(0);
scene.attachChild(hudNode);
//new watery stuff
setupFog();
Node reflectedNode = new Node( "reflectNode" );
reflectedNode.attachChild( skybox );
reflectedNode.attachChild( createObjects() );
scene.attachChild( reflectedNode );
waterEffectRenderPass = new WaterRenderPass( cam, 4, true, true );
//set equations to use z axis as up
waterEffectRenderPass.setWaterPlane( new Plane( new Vector3f( 0.0f, 0.0f, 1.0f ), 0.0f ) );
waterEffectRenderPass.setTangent( new Vector3f( 1.0f, 0.0f, 0.0f ) );
waterEffectRenderPass.setBinormal( new Vector3f( 0.0f, 1.0f, 0.0f ) );
waterQuad = new Quad( "waterQuad", 500, 500 );
waterQuad.setLocalRotation(waterQuad.getLocalRotation().fromAngleAxis(180f, new Vector3f(30.0f,25.0f,25.0f)));
waterEffectRenderPass.setWaterEffectOnSpatial( waterQuad );
scene.attachChild( waterQuad );
waterEffectRenderPass.setReflectedScene( reflectedNode );
waterEffectRenderPass.setSkybox( skybox );
pManager.add( waterEffectRenderPass );
RenderPass rootPass = new RenderPass();
rootPass.add( scene );
pManager.add( rootPass );
scene.setCullMode( SceneElement.CULL_NEVER );
scene.setRenderQueueMode( Renderer.QUEUE_OPAQUE );
//end of new watery stuff
// update the scene graph for rendering
scene.updateGeometricState(0.0f, true);
scene.updateRenderState();
}
I tried changing things round so that the water was rendering first, and it didn't seem to work. I also searched and it seems one person may have had this trouble before and they used a bit of code in their render method, so this is the modified render:
protected void render(float interpolation) {
// Clear the screen
/** Let the PassManager render. */
Callable<?> pManagerrender = new Callable() {
public Object call() throws Exception {
pManager.renderPasses(display.getRenderer());
return null;
}
};
GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER).enqueue(pManagerrender);
display.getRenderer().clearBuffers();
display.getRenderer().draw(scene);
}
Hope this helps explain my problem a little better, thank you :)
You can, instead, try to use this code that implements the TestIsland with StandardGame:
import java.nio.FloatBuffer;
import java.util.concurrent.Callable;
import java.util.logging.Logger;
import jmetest.effects.water.TestQuadWater;
import com.jme.image.Texture;
import com.jme.math.Plane;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.pass.BasicPassManager;
import com.jme.renderer.pass.RenderPass;
import com.jme.scene.PassNode;
import com.jme.scene.PassNodeState;
import com.jme.scene.SceneElement;
import com.jme.scene.Skybox;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.CullState;
import com.jme.scene.state.FogState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.RenderState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.util.GameTaskQueueManager;
import com.jme.util.TextureManager;
import com.jmex.effects.water.WaterRenderPass;
import com.jmex.game.StandardGame;
import com.jmex.game.state.GameStateManager;
import com.jmex.terrain.TerrainPage;
import com.jmex.terrain.util.RawHeightMap;
/**
* TestTerrainSplatting shows multipass texturesplatting(6 passes) through usage
* of the PassNode together with jME's water effect and a skybox. A simpler
* version of the terrain without splatting is created and used for rendering
* into the reflection/refraction of the water.
*
* @author Heightmap and textures originally from Jadestone(but heavily
* downsampled)
* @author Rikard Herlitz (MrCoder)
*/
public class TestIsland
{
private static final Logger logger = Logger.getLogger(TestIsland.class.getName());
private PassManagerGameState state;
private BasicPassManager pManager;
private StandardGame game;
private WaterRenderPass waterEffectRenderPass;
private Quad waterQuad;
private Spatial splatTerrain;
private Spatial reflectionTerrain;
private Skybox skybox;
private float farPlane = 10000.0f;
private float textureScale = 0.07f;
private float globalSplatScale = 90.0f;
public static void main(String[] args)
{
TestIsland app = new TestIsland();
}
public TestIsland()
{
game = new StandardGame( "Test Island" );
pManager = new BasicPassManager();
GameTaskQueueManager.getManager().update( new Callable<Object>() {
public Object call() throws Exception { simpleInitGame(); return null; } } );
game.start();
}
protected void simpleUpdate()
{
skybox.getLocalTranslation().set(game.getCamera().getLocation());
skybox.updateGeometricState(0.0f, true);
Vector3f transVec = new Vector3f(game.getCamera().getLocation().x,
waterEffectRenderPass.getWaterHeight(), game.getCamera().getLocation().z);
setTextureCoords(0, transVec.x, -transVec.z, textureScale);
setVertexCoords(transVec.x, transVec.y, transVec.z);
}
protected void simpleInitGame()
{
pManager = new BasicPassManager();
state = new PassManagerGameState() {
public void update( float tpf )
{
super.update(tpf);
simpleUpdate();
state.getRootNode().updateGeometricState(tpf, true);
pManager.updatePasses(tpf);
}
};
state.setPassManager( pManager );
GameStateManager.getInstance().attachChild( state );
//Activate game states
state.setActive( true );
game.getDisplay().setTitle("Test Island");
setupEnvironment();
createTerrain();
createReflectionTerrain();
buildSkyBox();
state.getRootNode().attachChild(skybox);
state.getRootNode().attachChild(splatTerrain);
waterEffectRenderPass = new WaterRenderPass(game.getCamera(), 6, false, true);
waterEffectRenderPass.setWaterPlane(new Plane(new Vector3f(0.0f, 1.0f,
0.0f), 0.0f));
waterEffectRenderPass.setClipBias(-1.0f);
waterEffectRenderPass.setReflectionThrottle(0.0f);
waterEffectRenderPass.setRefractionThrottle(0.0f);
waterQuad = new Quad("waterQuad", 1, 1);
FloatBuffer normBuf = waterQuad.getNormalBuffer(0);
normBuf.clear();
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
waterEffectRenderPass.setWaterEffectOnSpatial(waterQuad);
state.getRootNode().attachChild(waterQuad);
waterEffectRenderPass.setReflectedScene(skybox);
waterEffectRenderPass.addReflectedScene(reflectionTerrain);
waterEffectRenderPass.setSkybox(skybox);
pManager.add(waterEffectRenderPass);
RenderPass rootPass = new RenderPass();
rootPass.add(state.getRootNode());
pManager.add(rootPass);
// BloomRenderPass 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.setExposurePow(2.0f);
// bloomRenderPass.setBlurIntensityMultiplier(0.5f);
//
// bloomRenderPass.add(rootNode);
// bloomRenderPass.setUseCurrentScene(true);
// pManager.add(bloomRenderPass);
// }
//RenderPass fpsPass = new RenderPass();
//fpsPass.add(fpsNode);
//pManager.add(fpsPass);
state.getRootNode().setCullMode(SceneElement.CULL_NEVER);
state.getRootNode().updateGeometricState( 0f, true );
state.getRootNode().updateRenderState();
}
private void createTerrain()
{
RawHeightMap heightMap = new RawHeightMap(TestIsland.class
.getClassLoader().getResource(
"jmetest/data/texture/terrain/heights.raw").getFile(),
129, RawHeightMap.FORMAT_16BITLE, false);
Vector3f terrainScale = new Vector3f(5, 0.003f, 6);
heightMap.setHeightScale(0.001f);
TerrainPage page = new TerrainPage("Terrain", 33, heightMap.getSize(),
terrainScale, heightMap.getHeightMap(), false);
page.getLocalTranslation().set(0, -9.5f, 0);
page.setDetailTexture(1, 1);
// create some interesting texturestates for splatting
TextureState ts1 = createSplatTextureState(
"jmetest/data/texture/terrain/baserock.jpg", null);
TextureState ts2 = createSplatTextureState(
"jmetest/data/texture/terrain/darkrock.jpg",
"jmetest/data/texture/terrain/darkrockalpha.png");
TextureState ts3 = createSplatTextureState(
"jmetest/data/texture/terrain/deadgrass.jpg",
"jmetest/data/texture/terrain/deadalpha.png");
TextureState ts4 = createSplatTextureState(
"jmetest/data/texture/terrain/nicegrass.jpg",
"jmetest/data/texture/terrain/grassalpha.png");
TextureState ts5 = createSplatTextureState(
"jmetest/data/texture/terrain/road.jpg",
"jmetest/data/texture/terrain/roadalpha.png");
TextureState ts6 = createLightmapTextureState("jmetest/data/texture/terrain/lightmap.jpg");
// alpha used for blending the passnodestates together
AlphaState as = game.getDisplay().getRenderer().createAlphaState();
as.setBlendEnabled(true);
as.setSrcFunction(AlphaState.SB_SRC_ALPHA);
as.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
as.setTestEnabled(true);
as.setTestFunction(AlphaState.TF_GREATER);
as.setEnabled(true);
// alpha used for blending the lightmap
AlphaState as2 = game.getDisplay().getRenderer().createAlphaState();
as2.setBlendEnabled(true);
as2.setSrcFunction(AlphaState.SB_DST_COLOR);
as2.setDstFunction(AlphaState.DB_SRC_COLOR);
as2.setTestEnabled(true);
as2.setTestFunction(AlphaState.TF_GREATER);
as2.setEnabled(true);
// //////////////////// PASS STUFF START
// try out a passnode to use for splatting
PassNode splattingPassNode = new PassNode("SplatPassNode");
splattingPassNode.attachChild(page);
PassNodeState passNodeState = new PassNodeState();
passNodeState.setPassState(ts1);
splattingPassNode.addPass(passNodeState);
passNodeState = new PassNodeState();
passNodeState.setPassState(ts2);
passNodeState.setPassState(as);
splattingPassNode.addPass(passNodeState);
passNodeState = new PassNodeState();
passNodeState.setPassState(ts3);
passNodeState.setPassState(as);
splattingPassNode.addPass(passNodeState);
passNodeState = new PassNodeState();
passNodeState.setPassState(ts4);
passNodeState.setPassState(as);
splattingPassNode.addPass(passNodeState);
passNodeState = new PassNodeState();
passNodeState.setPassState(ts5);
passNodeState.setPassState(as);
splattingPassNode.addPass(passNodeState);
passNodeState = new PassNodeState();
passNodeState.setPassState(ts6);
passNodeState.setPassState(as2);
splattingPassNode.addPass(passNodeState);
// //////////////////// PASS STUFF END
// lock some things to increase the performance
splattingPassNode.lockBounds();
splattingPassNode.lockTransforms();
splattingPassNode.lockShadows();
splatTerrain = splattingPassNode;
}
private void createReflectionTerrain()
{
RawHeightMap heightMap = new RawHeightMap(TestIsland.class
.getClassLoader().getResource(
"jmetest/data/texture/terrain/heights.raw").getFile(),
129, RawHeightMap.FORMAT_16BITLE, false);
Vector3f terrainScale = new Vector3f(5, 0.003f, 6);
heightMap.setHeightScale(0.001f);
TerrainPage page = new TerrainPage("Terrain", 33, heightMap.getSize(),
terrainScale, heightMap.getHeightMap(), false);
page.getLocalTranslation().set(0, -9.5f, 0);
page.setDetailTexture(1, 1);
// create some interesting texturestates for splatting
TextureState ts1 = game.getDisplay().getRenderer().createTextureState();
Texture t0 = TextureManager.loadTexture(TestIsland.class
.getClassLoader().getResource(
"jmetest/data/texture/terrain/terrainlod.jpg"),
Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);
t0.setWrap(Texture.WM_WRAP_S_WRAP_T);
t0.setApply(Texture.AM_MODULATE);
t0.setScale(new Vector3f(1.0f, 1.0f, 1.0f));
ts1.setTexture(t0, 0);
// //////////////////// PASS STUFF START
// try out a passnode to use for splatting
PassNode splattingPassNode = new PassNode("SplatPassNode");
splattingPassNode.attachChild(page);
PassNodeState passNodeState = new PassNodeState();
passNodeState.setPassState(ts1);
splattingPassNode.addPass(passNodeState);
// //////////////////// PASS STUFF END
// lock some things to increase the performance
splattingPassNode.lockBounds();
splattingPassNode.lockTransforms();
splattingPassNode.lockShadows();
reflectionTerrain = splattingPassNode;
initSpatial(reflectionTerrain);
}
private void setupEnvironment()
{
game.getCamera().setFrustumPerspective(45.0f, (float) game.getDisplay().getWidth()
/ (float) game.getDisplay().getHeight(), 1f, farPlane);
game.getCamera().setLocation(new Vector3f(-320, 80, -270));
game.getCamera().lookAt(new Vector3f(0, 0, 0), Vector3f.UNIT_Y);
game.getCamera().update();
CullState cs = game.getDisplay().getRenderer().createCullState();
cs.setCullMode(CullState.CS_BACK);
state.getRootNode().setRenderState(cs);
( (LightState)state.getRootNode().getRenderState( RenderState.RS_LIGHT ) ).detachAll();
state.getRootNode().setLightCombineMode(LightState.OFF);
FogState fogState = game.getDisplay().getRenderer().createFogState();
fogState.setDensity(1.0f);
fogState.setEnabled(true);
fogState.setColor(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
fogState.setEnd(farPlane);
fogState.setStart(farPlane / 10.0f);
fogState.setDensityFunction(FogState.DF_LINEAR);
fogState.setApplyFunction(FogState.AF_PER_VERTEX);
state.getRootNode().setRenderState(fogState);
}
private void addAlphaSplat(TextureState ts, String alpha)
{
Texture t1 = TextureManager.loadTexture(TestIsland.class
.getClassLoader().getResource(alpha), Texture.MM_LINEAR_LINEAR,
Texture.FM_LINEAR);
t1.setWrap(Texture.WM_WRAP_S_WRAP_T);
t1.setApply(Texture.AM_COMBINE);
t1.setCombineFuncRGB(Texture.ACF_REPLACE);
t1.setCombineSrc0RGB(Texture.ACS_PREVIOUS);
t1.setCombineOp0RGB(Texture.ACO_SRC_COLOR);
t1.setCombineFuncAlpha(Texture.ACF_REPLACE);
ts.setTexture(t1, ts.getNumberOfSetTextures());
}
private TextureState createSplatTextureState(String texture, String alpha)
{
TextureState ts = game.getDisplay().getRenderer().createTextureState();
Texture t0 = TextureManager.loadTexture(TestIsland.class
.getClassLoader().getResource(texture),
Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);
t0.setWrap(Texture.WM_WRAP_S_WRAP_T);
t0.setApply(Texture.AM_MODULATE);
t0.setScale(new Vector3f(globalSplatScale, globalSplatScale, 1.0f));
ts.setTexture(t0, 0);
if (alpha != null) {
addAlphaSplat(ts, alpha);
}
return ts;
}
private TextureState createLightmapTextureState(String texture)
{
TextureState ts = game.getDisplay().getRenderer().createTextureState();
Texture t0 = TextureManager.loadTexture(TestIsland.class
.getClassLoader().getResource(texture),
Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);
t0.setWrap(Texture.WM_WRAP_S_WRAP_T);
ts.setTexture(t0, 0);
return ts;
}
private void buildSkyBox()
{
skybox = new Skybox("skybox", 10, 10, 10);
String dir = "jmetest/data/skybox1/";
Texture north = TextureManager.loadTexture(TestQuadWater.class
.getClassLoader().getResource(dir + "1.jpg"),
Texture.MM_LINEAR, Texture.FM_LINEAR);
Texture south = TextureManager.loadTexture(TestQuadWater.class
.getClassLoader().getResource(dir + "3.jpg"),
Texture.MM_LINEAR, Texture.FM_LINEAR);
Texture east = TextureManager.loadTexture(TestQuadWater.class
.getClassLoader().getResource(dir + "2.jpg"),
Texture.MM_LINEAR, Texture.FM_LINEAR);
Texture west = TextureManager.loadTexture(TestQuadWater.class
.getClassLoader().getResource(dir + "4.jpg"),
Texture.MM_LINEAR, Texture.FM_LINEAR);
Texture up = TextureManager.loadTexture(TestQuadWater.class
.getClassLoader().getResource(dir + "6.jpg"),
Texture.MM_LINEAR, Texture.FM_LINEAR);
Texture down = TextureManager.loadTexture(TestQuadWater.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 = game.getDisplay().getRenderer().createCullState();
cullState.setCullMode(CullState.CS_NONE);
cullState.setEnabled(true);
skybox.setRenderState(cullState);
ZBufferState zState = game.getDisplay().getRenderer().createZBufferState();
zState.setEnabled(false);
skybox.setRenderState(zState);
FogState fs = game.getDisplay().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 setVertexCoords(float x, float y, float z)
{
FloatBuffer vertBuf = waterQuad.getVertexBuffer(0);
vertBuf.clear();
vertBuf.put(x - farPlane).put(y).put(z - farPlane);
vertBuf.put(x - farPlane).put(y).put(z + farPlane);
vertBuf.put(x + farPlane).put(y).put(z + farPlane);
vertBuf.put(x + farPlane).put(y).put(z - farPlane);
}
private void setTextureCoords(int buffer, float x, float y, float textureScale)
{
x *= textureScale * 0.5f;
y *= textureScale * 0.5f;
textureScale = farPlane * textureScale;
FloatBuffer texBuf;
texBuf = waterQuad.getTextureBuffer(0, buffer);
texBuf.clear();
texBuf.put(x).put(textureScale + y);
texBuf.put(x).put(y);
texBuf.put(textureScale + x).put(y);
texBuf.put(textureScale + x).put(textureScale + y);
}
private void initSpatial(Spatial spatial)
{
ZBufferState buf = game.getDisplay().getRenderer().createZBufferState();
buf.setEnabled(true);
buf.setFunction(ZBufferState.CF_LEQUAL);
spatial.setRenderState(buf);
CullState cs = game.getDisplay().getRenderer().createCullState();
cs.setCullMode(CullState.CS_BACK);
spatial.setRenderState(cs);
spatial.setCullMode(SceneElement.CULL_NEVER);
spatial.updateGeometricState(0.0f, true);
spatial.updateRenderState();
}
}
And this is the restโฆ
import com.jme.image.Texture;
import com.jme.renderer.pass.BasicPassManager;
import com.jme.system.DisplaySystem;
import com.jme.util.geom.Debugger;
import com.jmex.game.state.DebugGameState;
public class PassManagerGameState extends DebugGameState
{
private BasicPassManager pManager;
public PassManagerGameState() { super(); }
public void setPassManager( BasicPassManager pManager )
{
this.pManager = pManager;
}
@Override
public void render( float tpf )
{
DisplaySystem.getDisplaySystem().getRenderer().clearBuffers();
pManager.renderPasses( DisplaySystem.getDisplaySystem().getRenderer() );
//Instead of calling super.render() which would cause everything to be double
//rendered, I do everything here myself.
if (showBounds) {
Debugger.drawBounds(rootNode, DisplaySystem.getDisplaySystem()
.getRenderer(), true);
}
if (showNormals) {
Debugger.drawNormals(rootNode, DisplaySystem.getDisplaySystem()
.getRenderer());
}
if (showDepth) {
DisplaySystem.getDisplaySystem().getRenderer().renderQueue();
Debugger.drawBuffer(Texture.RTT_SOURCE_DEPTH, Debugger.NORTHEAST,
DisplaySystem.getDisplaySystem().getRenderer());
}
}
}
Same problem here, almost the same code. My water is white, though. Must be something within the render method.
I extend GameState and then call renderPasses and updatePasses in the respective methods.
My error was caused by different nodes being attached in the wrong order. You really need to attach all the nodes before attaching the spatial with the watereffect.
Thlayli said:
My error was caused by different nodes being attached in the wrong order. You really need to attach all the nodes before attaching the spatial with the watereffect.
Indeed i got this error when i tried to attach the water to the rootnode and later attach another node to the rootnode that containend the reflections and stuff.
Seems like your Node containing the reflection has to be set up completely before attaching the water or initiating the RenderPass.
Sorry for bumping this thing up, but I have same problem and no idea how to fix it.
I was trying to create a water that would reflect only skybox, been trying different implementations I found in examples and on board (except for High-Performance Non-reflective Water by Trussell, but that's not what I want atm) and I keep on getting black quad >.<
So, if anyone could point me what do I do I would be grateful, here's code I use:
rootNode.attachChild(skybox);
waterEffectRenderPass = new WaterRenderPass(cam, 6, false, true);
waterEffectRenderPass.setWaterPlane(new Plane(new Vector3f(0.0f, 100f,
0.0f), 0.0f));
waterEffectRenderPass.setClipBias(-1.0f);
waterEffectRenderPass.setReflectionThrottle(0.0f);
waterEffectRenderPass.setRefractionThrottle(0.0f);
waterQuad = new Quad("waterQuad", 100, 100);
FloatBuffer normBuf = waterQuad.getNormalBuffer(0);
normBuf.clear();
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
normBuf.put(0).put(1).put(0);
rootNode.attachChild(waterQuad);
waterEffectRenderPass.setWaterEffectOnSpatial(waterQuad);
waterEffectRenderPass.setReflectedScene(skybox);
waterEffectRenderPass.setSkybox(skybox);
pManager.add(waterEffectRenderPass);
RenderPass rootPass = new RenderPass();
rootPass.add(rootNode);
pManager.add(rootPass);
RenderPass fpsPass = new RenderPass();
fpsPass.add(fpsNode);
pManager.add(fpsPass);
rootNode.setCullMode(SceneElement.CULL_NEVER);