One can now change the depth test function throught the additional renderstate of a material.

You can also do this for the alpha test function, but alpha test is deprecated in gl 3.0 and opengl es 2.0 so it's there only for compatibility and consistency reason.
This setting can be directly set in the j3m file in the RenderState statement.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10779 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
experimental
rem..om 12 years ago
parent 8f307f8fa5
commit f8be6cf686
  1. 30
      engine/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java
  2. 4
      engine/src/core-plugins/com/jme3/material/plugins/J3MLoader.java
  3. 126
      engine/src/core/com/jme3/material/RenderState.java
  4. 12
      engine/src/core/com/jme3/renderer/RenderContext.java
  5. 12
      engine/src/jogl/com/jme3/renderer/jogl/JoglRenderer.java
  6. 14
      engine/src/lwjgl/com/jme3/renderer/lwjgl/LwjglRenderer.java
  7. 176
      engine/src/test/jme3test/model/anim/TestSkeletonControlRefresh.java
  8. 90
      engine/src/test/jme3test/renderer/TestDepthFuncChange.java

@ -31,7 +31,6 @@
*/
package com.jme3.renderer.android;
import android.opengl.GLES10;
import android.opengl.GLES20;
import android.os.Build;
import com.jme3.asset.AndroidImageInfo;
@ -419,7 +418,7 @@ public class OGLESShaderRenderer implements Renderer {
*/
if (state.isDepthTest() && !context.depthTestEnabled) {
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthFunc(GLES20.GL_LEQUAL);
GLES20.glDepthFunc(convertTestFunction(context.depthFunc));
RendererUtil.checkGLError();
context.depthTestEnabled = true;
} else if (!state.isDepthTest() && context.depthTestEnabled) {
@ -427,6 +426,10 @@ public class OGLESShaderRenderer implements Renderer {
RendererUtil.checkGLError();
context.depthTestEnabled = false;
}
if (state.getDepthFunc() != context.depthFunc) {
GLES20.glDepthFunc(convertTestFunction(state.getDepthFunc()));
context.depthFunc = state.getDepthFunc();
}
if (state.isDepthWrite() && !context.depthWriteEnabled) {
GLES20.glDepthMask(true);
@ -1016,6 +1019,29 @@ public class OGLESShaderRenderer implements Renderer {
shader.resetObject();
}
private int convertTestFunction(RenderState.TestFunction testFunc) {
switch (testFunc) {
case Never:
return GLES20.GL_NEVER;
case Less:
return GLES20.GL_LESS;
case LessOrEqual:
return GLES20.GL_LEQUAL;
case Greater:
return GLES20.GL_GREATER;
case GreaterOrEqual:
return GLES20.GL_GEQUAL;
case Equal:
return GLES20.GL_EQUAL;
case NotEqual:
return GLES20.GL_NOTEQUAL;
case Always:
return GLES20.GL_ALWAYS;
default:
throw new UnsupportedOperationException("Unrecognized test function: " + testFunc);
}
}
/*********************************************************************\
|* Framebuffers *|
\*********************************************************************/

@ -330,6 +330,10 @@ public class J3MLoader implements AssetLoader {
renderState.setColorWrite(parseBoolean(split[1]));
}else if (split[0].equals("PointSprite")){
renderState.setPointSprite(parseBoolean(split[1]));
}else if (split[0].equals("DepthFunc")){
renderState.setDepthFunc(RenderState.TestFunction.valueOf(split[1]));
}else if (split[0].equals("AlphaFunc")){
renderState.setAlphaFunc(RenderState.TestFunction.valueOf(split[1]));
} else {
throw new MatParseException(null, split[0], statement);
}

@ -296,6 +296,12 @@ public class RenderState implements Cloneable, Savable {
boolean applyPolyOffset = true;
boolean stencilTest = false;
boolean applyStencilTest = false;
TestFunction depthFunc = TestFunction.LessOrEqual;
//by default depth func will be applied anyway if depth test is applied
boolean applyDepthFunc = false;
//by default alpha func will be applied anyway if alpha test is applied
TestFunction alphaFunc = TestFunction.Greater;
boolean applyAlphaFunc = false;
StencilOperation frontStencilStencilFailOperation = StencilOperation.Keep;
StencilOperation frontStencilDepthFailOperation = StencilOperation.Keep;
StencilOperation frontStencilDepthPassOperation = StencilOperation.Keep;
@ -341,6 +347,10 @@ public class RenderState implements Cloneable, Savable {
oc.write(applyAlphaTest, "applyAlphaTest", true);
oc.write(applyAlphaFallOff, "applyAlphaFallOff", true);
oc.write(applyPolyOffset, "applyPolyOffset", true);
oc.write(applyDepthFunc, "applyDepthFunc", true);
oc.write(applyAlphaFunc, "applyAlphaFunc", false);
oc.write(depthFunc, "depthFunc", TestFunction.LessOrEqual);
oc.write(alphaFunc, "alphaFunc", TestFunction.Greater);
}
@ -367,6 +377,8 @@ public class RenderState implements Cloneable, Savable {
backStencilDepthPassOperation = ic.readEnum("backStencilDepthPassOperation", StencilOperation.class, StencilOperation.Keep);
frontStencilFunction = ic.readEnum("frontStencilFunction", TestFunction.class, TestFunction.Always);
backStencilFunction = ic.readEnum("backStencilFunction", TestFunction.class, TestFunction.Always);
depthFunc = ic.readEnum("depthFunc", TestFunction.class, TestFunction.LessOrEqual);
alphaFunc = ic.readEnum("alphaFunc", TestFunction.class, TestFunction.Greater);
applyPointSprite = ic.readBoolean("applyPointSprite", true);
applyWireFrame = ic.readBoolean("applyWireFrame", true);
@ -378,6 +390,9 @@ public class RenderState implements Cloneable, Savable {
applyAlphaTest = ic.readBoolean("applyAlphaTest", true);
applyAlphaFallOff = ic.readBoolean("applyAlphaFallOff", true);
applyPolyOffset = ic.readBoolean("applyPolyOffset", true);
applyDepthFunc = ic.readBoolean("applyDepthFunc", true);
applyAlphaFunc = ic.readBoolean("applyAlphaFunc", false);
}
/**
@ -427,6 +442,11 @@ public class RenderState implements Cloneable, Savable {
if (depthTest != rs.depthTest) {
return false;
}
if (depthTest) {
if (depthFunc != rs.depthFunc) {
return false;
}
}
if (colorWrite != rs.colorWrite) {
return false;
@ -439,6 +459,11 @@ public class RenderState implements Cloneable, Savable {
if (alphaTest != rs.alphaTest) {
return false;
}
if (alphaTest) {
if (alphaFunc != rs.alphaFunc) {
return false;
}
}
if (alphaFallOff != rs.alphaFallOff) {
return false;
@ -515,6 +540,12 @@ public class RenderState implements Cloneable, Savable {
* <p>If the pixel's alpha value is greater than the
* <code>alphaFallOff</code> then the pixel will be rendered, otherwise
* the pixel will be discarded.
*
* Note : Alpha test is deprecated since opengl 3.0 and does not exists in
* openglES 2.0.
* The prefered way is to use the alphaDiscardThreshold on the material
* Or have a shader that discards the pixel when its alpha value meets the
* discarding condition.
*
* @param alphaFallOff The alpha of all rendered pixels must be higher
* than this value to be rendered. This value should be between 0 and 1.
@ -536,6 +567,13 @@ public class RenderState implements Cloneable, Savable {
* otherwise it will be discarded.
*
* @param alphaTest Set to true to enable alpha testing.
*
* Note : Alpha test is deprecated since opengl 3.0 and does not exists in
* openglES 2.0.
* The prefered way is to use the alphaDiscardThreshold on the material
* Or have a shader that discards the pixel when its alpha value meets the
* discarding condition.
*
*
* @see RenderState#setAlphaFallOff(float)
*/
@ -666,7 +704,7 @@ public class RenderState implements Cloneable, Savable {
offsetUnits = units;
}
cachedHashCode = -1;
}
}
/**
* Enable stencil testing.
@ -717,6 +755,42 @@ public class RenderState implements Cloneable, Savable {
cachedHashCode = -1;
}
/**
* Set the depth conparison function to the given TestFunction
* default is LessOrEqual (GL_LEQUAL)
* @see TestFunction
* @see RenderState#setDepthTest(boolean)
* @param depthFunc the depth comparison function
*/
public void setDepthFunc(TestFunction depthFunc) {
applyDepthFunc = true;
this.depthFunc = depthFunc;
cachedHashCode = -1;
}
/**
* Sets the alpha comparision function to the given TestFunction
* default is Greater (GL_GREATER)
*
* Note : Alpha test is deprecated since opengl 3.0 and does not exists in
* openglES 2.0.
* The prefered way is to use the alphaDiscardThreshold on the material
* Or have a shader taht discards the pixel when its alpha value meets the
* discarding condition.
*
* @see TestFunction
* @see RenderState#setAlphaTest(boolean)
* @see RenderState#setAlphaFallOff(float)
* @param alphaFunc the alpha comparision function
*/
public void setAlphaFunc(TestFunction alphaFunc) {
applyAlphaFunc = true;
this.alphaFunc = alphaFunc;
cachedHashCode = -1;
}
/**
* Check if stencil test is enabled.
*
@ -1008,6 +1082,30 @@ public class RenderState implements Cloneable, Savable {
return alphaFallOff;
}
/**
* Retrieve the depth comparison function
*
* @return the depth comparison function
*
* @see RenderState#setDepthFunc(com.jme3.material.RenderState.TestFunction)
*/
public TestFunction getDepthFunc() {
return depthFunc;
}
/**
* Retrieve the alpha comparison function
*
* @return the alpha comparison function
*
* @see RenderState#setAlphaFunc(com.jme3.material.RenderState.TestFunction)
*/
public TestFunction getAlphaFunc() {
return alphaFunc;
}
public boolean isApplyAlphaFallOff() {
return applyAlphaFallOff;
}
@ -1048,6 +1146,16 @@ public class RenderState implements Cloneable, Savable {
return applyWireFrame;
}
public boolean isApplyDepthFunc() {
return applyDepthFunc;
}
public boolean isApplyAlphaFunc() {
return applyAlphaFunc;
}
/**
*
*/
@ -1059,9 +1167,11 @@ public class RenderState implements Cloneable, Savable {
hash = 79 * hash + (this.cullMode != null ? this.cullMode.hashCode() : 0);
hash = 79 * hash + (this.depthWrite ? 1 : 0);
hash = 79 * hash + (this.depthTest ? 1 : 0);
hash = 79 * hash + (this.depthFunc != null ? this.depthFunc.hashCode() : 0);
hash = 79 * hash + (this.colorWrite ? 1 : 0);
hash = 79 * hash + (this.blendMode != null ? this.blendMode.hashCode() : 0);
hash = 79 * hash + (this.alphaTest ? 1 : 0);
hash = 79 * hash + (this.alphaFunc != null ? this.alphaFunc.hashCode() : 0);
hash = 79 * hash + Float.floatToIntBits(this.alphaFallOff);
hash = 79 * hash + Float.floatToIntBits(this.offsetFactor);
hash = 79 * hash + Float.floatToIntBits(this.offsetUnits);
@ -1132,6 +1242,11 @@ public class RenderState implements Cloneable, Savable {
} else {
state.depthTest = depthTest;
}
if (additionalState.applyDepthFunc) {
state.depthFunc = additionalState.depthFunc;
} else {
state.depthFunc = depthFunc;
}
if (additionalState.applyColorWrite) {
state.colorWrite = additionalState.colorWrite;
} else {
@ -1147,6 +1262,11 @@ public class RenderState implements Cloneable, Savable {
} else {
state.alphaTest = alphaTest;
}
if (additionalState.applyAlphaFunc) {
state.alphaFunc = additionalState.alphaFunc;
} else {
state.alphaFunc = alphaFunc;
}
if (additionalState.applyAlphaFallOff) {
state.alphaFallOff = additionalState.alphaFallOff;
@ -1205,19 +1325,21 @@ public class RenderState implements Cloneable, Savable {
+ "\ndepthWrite=" + depthWrite
+ "\napplyDepthWrite=" + applyDepthWrite
+ "\ndepthTest=" + depthTest
+ "\ndepthFunc=" + depthFunc
+ "\napplyDepthTest=" + applyDepthTest
+ "\ncolorWrite=" + colorWrite
+ "\napplyColorWrite=" + applyColorWrite
+ "\nblendMode=" + blendMode
+ "\napplyBlendMode=" + applyBlendMode
+ "\nalphaTest=" + alphaTest
+ "\nalphaFunc=" + alphaFunc
+ "\napplyAlphaTest=" + applyAlphaTest
+ "\nalphaFallOff=" + alphaFallOff
+ "\napplyAlphaFallOff=" + applyAlphaFallOff
+ "\noffsetEnabled=" + offsetEnabled
+ "\napplyPolyOffset=" + applyPolyOffset
+ "\noffsetFactor=" + offsetFactor
+ "\noffsetUnits=" + offsetUnits
+ "\noffsetUnits=" + offsetUnits
+ "\n]";
}
}

@ -263,6 +263,16 @@ public class RenderContext {
* Use vertex color (GL1 only)
*/
public boolean useVertexColor;
/**
* depth tets function
*/
public RenderState.TestFunction depthFunc = RenderState.TestFunction.LessOrEqual;
/**
* alpha tets function
*/
public RenderState.TestFunction alphaFunc = RenderState.TestFunction.Greater;
/**
* Reset the RenderContext to default GL state
@ -314,5 +324,7 @@ public class RenderContext {
ambient = diffuse = specular = color = null;
shininess = 0;
useVertexColor = false;
depthFunc = RenderState.TestFunction.LessOrEqual;
alphaFunc = RenderState.TestFunction.Greater;
}
}

@ -517,17 +517,21 @@ public class JoglRenderer implements Renderer {
if (state.isDepthTest() && !context.depthTestEnabled) {
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glDepthFunc(GL.GL_LEQUAL);
gl.glDepthFunc(convertTestFunction(context.depthFunc));
context.depthTestEnabled = true;
} else if (!state.isDepthTest() && context.depthTestEnabled) {
gl.glDisable(GL.GL_DEPTH_TEST);
context.depthTestEnabled = false;
}
if (state.getDepthFunc() != context.depthFunc) {
gl.glDepthFunc(convertTestFunction(state.getDepthFunc()));
context.depthFunc = state.getDepthFunc();
}
if (state.isAlphaTest() && context.alphaTestFallOff == 0) {
gl.glEnable(GL2ES1.GL_ALPHA_TEST);
if (gl.isGL2ES1()) {
gl.getGL2ES1().glAlphaFunc(GL.GL_GREATER, state.getAlphaFallOff());
gl.getGL2ES1().glAlphaFunc(convertTestFunction(context.alphaFunc), state.getAlphaFallOff());
}
context.alphaTestFallOff = state.getAlphaFallOff();
} else if (!state.isAlphaTest() && context.alphaTestFallOff != 0) {
@ -536,6 +540,10 @@ public class JoglRenderer implements Renderer {
}
context.alphaTestFallOff = 0;
}
if (state.getAlphaFunc() != context.alphaFunc && gl.isGL2ES1()) {
gl.getGL2ES1().glAlphaFunc(convertTestFunction(context.alphaFunc), state.getAlphaFallOff());
context.alphaFunc = state.getAlphaFunc();
}
if (state.isDepthWrite() && !context.depthWriteEnabled) {
gl.glDepthMask(true);

@ -482,22 +482,30 @@ public class LwjglRenderer implements Renderer {
}
if (state.isDepthTest() && !context.depthTestEnabled) {
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glDepthFunc(convertTestFunction(context.depthFunc));
context.depthTestEnabled = true;
} else if (!state.isDepthTest() && context.depthTestEnabled) {
glDisable(GL_DEPTH_TEST);
context.depthTestEnabled = false;
}
if (state.getDepthFunc() != context.depthFunc) {
glDepthFunc(convertTestFunction(state.getDepthFunc()));
context.depthFunc = state.getDepthFunc();
}
if (state.isAlphaTest() && context.alphaTestFallOff == 0) {
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, state.getAlphaFallOff());
glAlphaFunc(convertTestFunction(context.alphaFunc), state.getAlphaFallOff());
context.alphaTestFallOff = state.getAlphaFallOff();
} else if (!state.isAlphaTest() && context.alphaTestFallOff != 0) {
glDisable(GL_ALPHA_TEST);
context.alphaTestFallOff = 0;
}
if (state.getAlphaFunc() != context.alphaFunc) {
glAlphaFunc(convertTestFunction(state.getAlphaFunc()), state.getAlphaFallOff());
context.alphaFunc = state.getAlphaFunc();
}
if (state.isDepthWrite() && !context.depthWriteEnabled) {
glDepthMask(true);

@ -0,0 +1,176 @@
/*
* Copyright (c) 2009-2012 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 jme3test.model.anim;
/**
*
* @author Nehon
*/
import com.jme3.animation.*;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.font.BitmapText;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.ssao.SSAOFilter;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Quad;
import com.jme3.shadow.DirectionalLightShadowFilter;
import com.jme3.shadow.DirectionalLightShadowRenderer;
import java.util.ArrayList;
import java.util.List;
import jme3test.post.SSAOUI;
public class TestSkeletonControlRefresh extends SimpleApplication implements ActionListener{
private AnimChannel channel;
private AnimControl control;
private String[] animNames = {"Dodge", "Walk", "pull", "push"};
private final static int SIZE = 10;
private boolean hwSkinningEnable = true;
private List<SkeletonControl> skControls = new ArrayList<SkeletonControl>();
private BitmapText hwsText;
public static void main(String[] args) {
TestSkeletonControlRefresh app = new TestSkeletonControlRefresh();
app.start();
}
@Override
public void simpleInitApp() {
viewPort.setBackgroundColor(ColorRGBA.White);
flyCam.setMoveSpeed(10f);
cam.setLocation(new Vector3f(3.8664846f, 6.2704787f, 9.664585f));
cam.setRotation(new Quaternion(-0.054774776f, 0.94064945f, -0.27974048f, -0.18418397f));
makeHudText();
DirectionalLight dl = new DirectionalLight();
dl.setDirection(new Vector3f(-0.1f, -0.7f, -1).normalizeLocal());
dl.setColor(new ColorRGBA(1f, 1f, 1f, 1.0f));
rootNode.addLight(dl);
Material m = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
TextureKey k = new TextureKey("Models/Oto/Oto.jpg", false);
m.setTexture("ColorMap", assetManager.loadTexture(k));
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
Spatial model = (Spatial) assetManager.loadModel("Models/Oto/Oto.mesh.xml");
//setting a different material
model.setMaterial(m.clone());
model.setLocalScale(0.1f);
model.setLocalTranslation(i - SIZE / 2, 0, j - SIZE / 2);
control = model.getControl(AnimControl.class);
channel = control.createChannel();
channel.setAnim(animNames[(i + j) % 4]);
channel.setLoopMode(LoopMode.DontLoop);
SkeletonControl skeletonControl = model.getControl(SkeletonControl.class);
//This is a workaround the issue. this call will make the SkeletonControl gather the targets again.
//skeletonControl.setSpatial(model);
skeletonControl.setHardwareSkinningPreferred(hwSkinningEnable);
skControls.add(skeletonControl);
rootNode.attachChild(model);
}
}
rootNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
setupFloor();
inputManager.addListener(this, "toggleHWS");
inputManager.addMapping("toggleHWS", new KeyTrigger(KeyInput.KEY_SPACE));
// DirectionalLightShadowRenderer pssm = new DirectionalLightShadowRenderer(assetManager, 1024, 2);
// pssm.setLight(dl);
// viewPort.addProcessor(pssm);
FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
DirectionalLightShadowFilter sf = new DirectionalLightShadowFilter(assetManager, 1024, 2);
sf.setLight(dl);
fpp.addFilter(sf);
fpp.addFilter(new SSAOFilter());
viewPort.addProcessor(fpp);
}
public void setupFloor() {
Quad q = new Quad(20, 20);
q.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(10));
Geometry geom = new Geometry("floor", q);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.White);
geom.setMaterial(mat);
geom.rotate(-FastMath.HALF_PI, 0, 0);
geom.center();
geom.move(0, -0.3f, 0);
geom.setShadowMode(RenderQueue.ShadowMode.Receive);
rootNode.attachChild(geom);
}
@Override
public void onAction(String name, boolean isPressed, float tpf) {
if(isPressed && name.equals("toggleHWS")){
hwSkinningEnable = !hwSkinningEnable;
for (SkeletonControl skControl : skControls) {
skControl.setHardwareSkinningPreferred(hwSkinningEnable);
hwsText.setText("HWS : "+ hwSkinningEnable);
}
}
}
private void makeHudText() {
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
hwsText = new BitmapText(guiFont, false);
hwsText.setSize(guiFont.getCharSet().getRenderedSize());
hwsText.setText("HWS : "+ hwSkinningEnable);
hwsText.setLocalTranslation(0, cam.getHeight(), 0);
guiNode.attachChild(hwsText);
}
}

@ -0,0 +1,90 @@
/*
* Copyright (c) 2009-2012 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 jme3test.renderer;
import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.material.Material;
import com.jme3.material.RenderState;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
public class TestDepthFuncChange extends SimpleApplication {
public static void main(String[] args) {
TestDepthFuncChange app = new TestDepthFuncChange();
app.start();
}
public void simpleInitApp() {
viewPort.setBackgroundColor(ColorRGBA.DarkGray);
flyCam.setMoveSpeed(20);
//top of the screen
//default depth func (less or equal) rendering.
//2 cubes, a blue and a red. the red cube is offset by 0.2 WU to the right
//the red cube is put in the transparent bucket to be sure it's rendered after the blue one (but there is no transparency involved).
//You should see a small part of the blue cube on the left and the whole red cube
Box boxshape1 = new Box(1f, 1f, 1f);
Geometry cube1 = new Geometry("box", boxshape1);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Blue);
cube1.setMaterial(mat);
rootNode.attachChild(cube1);
cube1.move(0, 1.5f, 0);
Geometry cube2 = cube1.clone(true);
cube2.move(0.2f, 0 , 0);
cube2.setQueueBucket(RenderQueue.Bucket.Transparent);
cube2.getMaterial().setColor("Color", ColorRGBA.Red);
rootNode.attachChild(cube2);
//Bottom of the screen
//here the 2 cubes are clonned and the depthFunc for the red cube's material is set to Less
//You should see the whole bleu cube and a small part of the red cube on the right
Geometry cube3 = cube1.clone();
Geometry cube4 = cube2.clone(true);
cube4.getMaterial().getAdditionalRenderState().setDepthFunc(RenderState.TestFunction.Less);
cube3.move(0,-3,0);
cube4.move(0,-3,0);
rootNode.attachChild(cube3);
rootNode.attachChild(cube4);
//Note that if you move the camera z fighting will occur but that's expected.
}
}
Loading…
Cancel
Save