-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add mask/reference to hash function * Add mask/reference to copyMergedTo * Add mask/reference to set(RenderState state) * Add TestStencilOutline.java * Removed not used imports * Fixed spacing
- Loading branch information
Showing
2 changed files
with
169 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
151 changes: 151 additions & 0 deletions
151
jme3-examples/src/main/java/jme3test/stencil/TestStencilOutline.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
package jme3test.stencil; | ||
|
||
import com.jme3.app.SimpleApplication; | ||
import com.jme3.asset.AssetManager; | ||
import com.jme3.material.Material; | ||
import com.jme3.material.RenderState; | ||
import com.jme3.math.ColorRGBA; | ||
import com.jme3.post.FilterPostProcessor; | ||
import com.jme3.post.filters.BloomFilter; | ||
import com.jme3.renderer.RenderManager; | ||
import com.jme3.renderer.ViewPort; | ||
import com.jme3.renderer.queue.OpaqueComparator; | ||
import com.jme3.renderer.queue.RenderQueue; | ||
import com.jme3.scene.Geometry; | ||
import com.jme3.scene.control.AbstractControl; | ||
import com.jme3.scene.shape.Box; | ||
import com.jme3.system.AppSettings; | ||
import com.jme3.texture.Image; | ||
|
||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
public class TestStencilOutline extends SimpleApplication { | ||
|
||
class OutlineComparator extends OpaqueComparator { | ||
@Override | ||
public int compare(Geometry o1, Geometry o2) { | ||
boolean ol1 = o1.getUserData("Outline") != null; | ||
boolean ol2 = o2.getUserData("Outline") != null; | ||
if (ol1 == ol2) { | ||
return super.compare(o1, o2); | ||
} else { | ||
if (ol1) { | ||
return 1; | ||
} else { | ||
return -1; | ||
} | ||
} | ||
} | ||
} | ||
|
||
class OutlineControl extends AbstractControl { | ||
private Material outlineMaterial; | ||
|
||
public OutlineControl(AssetManager assetManager, ColorRGBA colorRGBA) { | ||
outlineMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); | ||
outlineMaterial.setColor("Color", colorRGBA); | ||
outlineMaterial.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Front); | ||
outlineMaterial.getAdditionalRenderState().setDepthFunc(RenderState.TestFunction.Always); | ||
outlineMaterial.getAdditionalRenderState().setStencil(true, | ||
RenderState.StencilOperation.Keep, //front triangle fails stencil test | ||
RenderState.StencilOperation.Keep, //front triangle fails depth test | ||
RenderState.StencilOperation.Keep, //front triangle passes depth test | ||
RenderState.StencilOperation.Keep, //back triangle fails stencil test | ||
RenderState.StencilOperation.Keep, //back triangle fails depth test | ||
RenderState.StencilOperation.Keep, //back triangle passes depth test | ||
RenderState.TestFunction.NotEqual, //front triangle stencil test function | ||
RenderState.TestFunction.NotEqual); //back triangle stencil test function | ||
outlineMaterial.getAdditionalRenderState().setFrontStencilReference(1); | ||
outlineMaterial.getAdditionalRenderState().setBackStencilReference(1); | ||
outlineMaterial.getAdditionalRenderState().setFrontStencilMask(0xFF); | ||
outlineMaterial.getAdditionalRenderState().setBackStencilMask(0xFF); | ||
} | ||
|
||
@Override | ||
protected void controlUpdate(float v) { | ||
|
||
} | ||
|
||
@Override | ||
protected void controlRender(RenderManager renderManager, ViewPort viewPort) { | ||
if (spatial instanceof Geometry) { | ||
Geometry geometry= (Geometry) spatial; | ||
Geometry clone = geometry.clone(); | ||
clone.scale(1.1f); | ||
clone.setUserData("Outline", true); | ||
clone.setMaterial(outlineMaterial); | ||
clone.updateGeometricState(); | ||
viewPort.getQueue().addToQueue(clone, RenderQueue.Bucket.Opaque); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void update() { | ||
super.update(); | ||
} | ||
|
||
@Override | ||
public void simpleInitApp() { | ||
flyCam.setMoveSpeed(24); | ||
flyCam.setZoomSpeed(-5); | ||
viewPort.getQueue().setGeometryComparator(RenderQueue.Bucket.Opaque, new OutlineComparator()); | ||
viewPort.setClearFlags(true,true,true); | ||
Material boxMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); | ||
boxMat.getAdditionalRenderState().setStencil(true, | ||
RenderState.StencilOperation.Keep, //front triangle fails stencil test | ||
RenderState.StencilOperation.Replace, //front triangle fails depth test | ||
RenderState.StencilOperation.Replace, //front triangle passes depth test | ||
RenderState.StencilOperation.Keep, //back triangle fails stencil test | ||
RenderState.StencilOperation.Replace, //back triangle fails depth test | ||
RenderState.StencilOperation.Replace, //back triangle passes depth test | ||
RenderState.TestFunction.Always, //front triangle stencil test function | ||
RenderState.TestFunction.Always); //back triangle stencil test function | ||
boxMat.getAdditionalRenderState().setFrontStencilReference(1); | ||
boxMat.getAdditionalRenderState().setBackStencilReference(1); | ||
boxMat.getAdditionalRenderState().setFrontStencilMask(0xFF); | ||
boxMat.getAdditionalRenderState().setBackStencilMask(0xFF); | ||
boxMat.setTexture("ColorMap", assetManager.loadTexture("Common/Textures/MissingTexture.png")); | ||
|
||
Material floorMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); | ||
floorMat.setTexture("ColorMap", assetManager.loadTexture("Common/Textures/MissingTexture.png")); | ||
|
||
Geometry floor = new Geometry("Floor", new Box(10f, 0, 10f)); | ||
floor.setMaterial(floorMat); | ||
rootNode.attachChild(floor); | ||
|
||
Geometry box1 = new Geometry("Box1", new Box(0.5f, 0.5f, 0.5f)); | ||
box1.setLocalTranslation(3, 1.5f, 0); | ||
box1.setLocalScale(4); | ||
box1.addControl(new OutlineControl(assetManager, ColorRGBA.Blue)); | ||
box1.setMaterial(boxMat); | ||
Geometry box2 = new Geometry("Box2", new Box(0.5f, 0.5f, 0.5f)); | ||
box2.setLocalTranslation(-3, 1.5f, 0); | ||
box2.setLocalScale(3); | ||
box2.addControl(new OutlineControl(assetManager,ColorRGBA.Red)); | ||
box2.setMaterial(boxMat); | ||
|
||
rootNode.attachChild(box1); | ||
rootNode.attachChild(box2); | ||
|
||
//This is to make sure a depth stencil format is used in the TestChooser app. | ||
FilterPostProcessor postProcessor=new FilterPostProcessor(assetManager); | ||
postProcessor.setFrameBufferDepthFormat(Image.Format.Depth24Stencil8); | ||
viewPort.addProcessor(postProcessor); | ||
postProcessor.addFilter(new BloomFilter()); | ||
} | ||
|
||
|
||
public static void main(String[] args) { | ||
Logger.getLogger("").setLevel(Level.FINEST); | ||
TestStencilOutline app = new TestStencilOutline(); | ||
AppSettings settings = new AppSettings(true); | ||
settings.setGraphicsDebug(true); | ||
settings.setDepthBits(24); | ||
settings.setStencilBits(8); | ||
app.setSettings(settings); | ||
app.setShowSettings(false); | ||
app.start(); | ||
} | ||
} |