Hey, sorry if I made my question unclear, my main question was about how would I go about replicating the outline effect that was shown in that LearnOpenGL page I linked in the original post (this one). I think figuring out how to replicate it in JME would be a great (practical) introduction to the stencil buffer for noobs like me.
Of course to begin, I’d create the 5 geometries (like in the guide page) and add them to the root node - box 1, box 2, enlarged outline geom for box 1, for box 2, and the floor geometry. I suppose the next steps would be to set the stencil parameters for each of their materials (3 materials in total - 1 for the 2 boxes, 1 for the outlines of the 2 boxes, and 1 for the floor), which is done via their additional render states, but at that point I’m kind of lost.
Here’s my test app code in it’s current state (which fails to replicate that outline effect, as I’m also sure I did something wrong here)
public class TestStencilOutline extends SimpleApplication {
public static void main(String[] args) {
TestStencilOutline app = new TestStencilOutline();
AppSettings settings = new AppSettings(true);
settings.setStencilBits(8);
app.setSettings(settings);
app.setShowSettings(false);
app.start();
}
@Override
public void simpleInitApp() {
flyCam.setMoveSpeed(24);
flyCam.setZoomSpeed(-5);
viewPort.setClearFlags(true, true, true);
// Change default render state? As I suppose each material uses this render state by default. //
RenderState.DEFAULT.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.Always, //front triangle stencil test function
RenderState.TestFunction.Always); //back triangle stencil test function
RenderState.DEFAULT.setFrontStencilMask(0);
RenderState.DEFAULT.setBackStencilMask(0);
RenderState.DEFAULT.setFrontStencilReference(1);
RenderState.DEFAULT.setBackStencilReference(1);
// Setup materials //
Material boxMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
boxMat.setTexture("ColorMap", assetManager.loadTexture("Common/Textures/MissingTexture.png"));
boxMat.getAdditionalRenderState().setStencil(true,
RenderState.StencilOperation.Keep, //front triangle fails stencil test
RenderState.StencilOperation.Keep, //front triangle fails depth test
RenderState.StencilOperation.Replace, //front triangle passes depth test
RenderState.StencilOperation.Keep, //back triangle fails stencil test
RenderState.StencilOperation.Keep, //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().setFrontStencilMask(-1);
boxMat.getAdditionalRenderState().setBackStencilMask(-1);
boxMat.getAdditionalRenderState().setFrontStencilReference(1);
boxMat.getAdditionalRenderState().setBackStencilReference(1);
Material boxOutlineMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
boxOutlineMat.setColor("Color", ColorRGBA.Yellow);
boxOutlineMat.getAdditionalRenderState().setDepthTest(false);
boxOutlineMat.getAdditionalRenderState().setStencil(true,
RenderState.StencilOperation.Keep, //front triangle fails stencil test
RenderState.StencilOperation.Keep, //front triangle fails depth test
RenderState.StencilOperation.Replace, //front triangle passes depth test
RenderState.StencilOperation.Keep, //back triangle fails stencil test
RenderState.StencilOperation.Keep, //back triangle fails depth test
RenderState.StencilOperation.Replace, //back triangle passes depth test
RenderState.TestFunction.NotEqual, //front triangle stencil test function
RenderState.TestFunction.NotEqual); //back triangle stencil test function
boxOutlineMat.getAdditionalRenderState().setFrontStencilMask(0);
boxOutlineMat.getAdditionalRenderState().setBackStencilMask(0);
boxOutlineMat.getAdditionalRenderState().setFrontStencilReference(1);
boxOutlineMat.getAdditionalRenderState().setBackStencilReference(1);
Material floorMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
floorMat.setTexture("ColorMap", assetManager.loadTexture("Common/Textures/MissingTexture.png"));
// Create geometries //
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(3);
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.setMaterial(boxMat);
rootNode.attachChild(box1);
rootNode.attachChild(box2);
// Create outlines //
Geometry box1OUTLINE = new Geometry("Box1Outline", new Box(0.5f, 0.5f, 0.5f));
box1OUTLINE.setLocalTransform(box1.getLocalTransform());
box1OUTLINE.setLocalScale(3.2f);
box1OUTLINE.setMaterial(boxOutlineMat);
Geometry box2OUTLINE = new Geometry("Box2Outline", new Box(0.5f, 0.5f, 0.5f));
box2OUTLINE.setLocalTransform(box2.getLocalTransform());
box2OUTLINE.setLocalScale(3.2f);
box2OUTLINE.setMaterial(boxOutlineMat);
rootNode.attachChild(box1OUTLINE);
rootNode.attachChild(box2OUTLINE);
}
}
I would really appreciate it if you could please provide some tips to get it working like in that guide. Thank you.