RenderState support for two sided Stencil Buffer operations (in order to support Shadow Volumes in the future)
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7286 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
53f5df5a3f
commit
9cc223c507
@ -130,6 +130,29 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
FrontAndBack
|
FrontAndBack
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public enum StencilOperation {
|
||||||
|
Keep, //keep the current value
|
||||||
|
Zero, //set the value to 0
|
||||||
|
Replace, //sets the buffer to
|
||||||
|
Increment,
|
||||||
|
IncrementWrap,
|
||||||
|
Decrement,
|
||||||
|
DecrementWrap,
|
||||||
|
Invert
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum StencilFunction {
|
||||||
|
Never,
|
||||||
|
Less,
|
||||||
|
LessEqual,
|
||||||
|
Greater,
|
||||||
|
GreaterEqual,
|
||||||
|
Equal,
|
||||||
|
NotEqual,
|
||||||
|
Always
|
||||||
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
NULL.cullMode = FaceCullMode.Off;
|
NULL.cullMode = FaceCullMode.Off;
|
||||||
NULL.depthTest = false;
|
NULL.depthTest = false;
|
||||||
@ -170,6 +193,15 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
boolean applyPolyOffset = true;
|
boolean applyPolyOffset = true;
|
||||||
float offsetFactor = 0;
|
float offsetFactor = 0;
|
||||||
float offsetUnits = 0;
|
float offsetUnits = 0;
|
||||||
|
boolean stencilTest = false;
|
||||||
|
StencilOperation frontStencilStencilFailOperation = StencilOperation.Keep;
|
||||||
|
StencilOperation frontStencilDepthFailOperation = StencilOperation.Keep;
|
||||||
|
StencilOperation frontStencilDepthPassOperation = StencilOperation.Keep;
|
||||||
|
StencilOperation backStencilStencilFailOperation = StencilOperation.Keep;
|
||||||
|
StencilOperation backStencilDepthFailOperation = StencilOperation.Keep;
|
||||||
|
StencilOperation backStencilDepthPassOperation = StencilOperation.Keep;
|
||||||
|
StencilFunction frontStencilFunction = StencilFunction.Always;
|
||||||
|
StencilFunction backStencilFunction = StencilFunction.Always;
|
||||||
|
|
||||||
public void write(JmeExporter ex) throws IOException {
|
public void write(JmeExporter ex) throws IOException {
|
||||||
OutputCapsule oc = ex.getCapsule(this);
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
@ -185,6 +217,15 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
oc.write(offsetEnabled, "offsetEnabled", false);
|
oc.write(offsetEnabled, "offsetEnabled", false);
|
||||||
oc.write(offsetFactor, "offsetFactor", 0);
|
oc.write(offsetFactor, "offsetFactor", 0);
|
||||||
oc.write(offsetUnits, "offsetUnits", 0);
|
oc.write(offsetUnits, "offsetUnits", 0);
|
||||||
|
oc.write(stencilTest, "stencilTest", false);
|
||||||
|
oc.write(frontStencilStencilFailOperation, "frontStencilStencilFailOperation", StencilOperation.Keep);
|
||||||
|
oc.write(frontStencilDepthFailOperation, "frontStencilDepthFailOperation", StencilOperation.Keep);
|
||||||
|
oc.write(frontStencilDepthPassOperation, "frontStencilDepthPassOperation", StencilOperation.Keep);
|
||||||
|
oc.write(backStencilStencilFailOperation, "frontStencilStencilFailOperation", StencilOperation.Keep);
|
||||||
|
oc.write(backStencilDepthFailOperation, "backStencilDepthFailOperation", StencilOperation.Keep);
|
||||||
|
oc.write(backStencilDepthPassOperation, "backStencilDepthPassOperation", StencilOperation.Keep);
|
||||||
|
oc.write(frontStencilFunction, "frontStencilFunction", StencilFunction.Always);
|
||||||
|
oc.write(backStencilFunction, "backStencilFunction", StencilFunction.Always);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void read(JmeImporter im) throws IOException {
|
public void read(JmeImporter im) throws IOException {
|
||||||
@ -201,6 +242,15 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
offsetEnabled = ic.readBoolean("offsetEnabled", false);
|
offsetEnabled = ic.readBoolean("offsetEnabled", false);
|
||||||
offsetFactor = ic.readFloat("offsetFactor", 0);
|
offsetFactor = ic.readFloat("offsetFactor", 0);
|
||||||
offsetUnits = ic.readFloat("offsetUnits", 0);
|
offsetUnits = ic.readFloat("offsetUnits", 0);
|
||||||
|
stencilTest = ic.readBoolean("stencilTest", false);
|
||||||
|
frontStencilStencilFailOperation = ic.readEnum("frontStencilStencilFailOperation", StencilOperation.class, StencilOperation.Keep);
|
||||||
|
frontStencilDepthFailOperation = ic.readEnum("frontStencilDepthFailOperation", StencilOperation.class, StencilOperation.Keep);
|
||||||
|
frontStencilDepthPassOperation = ic.readEnum("frontStencilDepthPassOperation", StencilOperation.class, StencilOperation.Keep);
|
||||||
|
backStencilStencilFailOperation = ic.readEnum("backStencilStencilFailOperation", StencilOperation.class, StencilOperation.Keep);
|
||||||
|
backStencilDepthFailOperation = ic.readEnum("backStencilDepthFailOperation", StencilOperation.class, StencilOperation.Keep);
|
||||||
|
backStencilDepthPassOperation = ic.readEnum("backStencilDepthPassOperation", StencilOperation.class, StencilOperation.Keep);
|
||||||
|
frontStencilFunction = ic.readEnum("frontStencilFunction", StencilFunction.class, StencilFunction.Always);
|
||||||
|
backStencilFunction = ic.readEnum("backStencilFunction", StencilFunction.class, StencilFunction.Always);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -282,6 +332,41 @@ public class RenderState implements Cloneable, Savable {
|
|||||||
offsetUnits = units;
|
offsetUnits = units;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStencil(boolean enabled,
|
||||||
|
StencilOperation _frontStencilStencilFailOperation,
|
||||||
|
StencilOperation _frontStencilDepthFailOperation,
|
||||||
|
StencilOperation _frontStencilDepthPassOperation,
|
||||||
|
StencilOperation _backStencilStencilFailOperation,
|
||||||
|
StencilOperation _backStencilDepthFailOperation,
|
||||||
|
StencilOperation _backStencilDepthPassOperation,
|
||||||
|
StencilFunction _frontStencilFunction,
|
||||||
|
StencilFunction _backStencilFunction){
|
||||||
|
|
||||||
|
stencilTest = enabled;
|
||||||
|
this.frontStencilStencilFailOperation = _frontStencilStencilFailOperation;
|
||||||
|
this.frontStencilDepthFailOperation = _frontStencilDepthFailOperation;
|
||||||
|
this.frontStencilDepthPassOperation = _frontStencilDepthPassOperation;
|
||||||
|
this.backStencilStencilFailOperation = _backStencilStencilFailOperation;
|
||||||
|
this.backStencilDepthFailOperation = _backStencilDepthFailOperation;
|
||||||
|
this.backStencilDepthPassOperation = _backStencilDepthPassOperation;
|
||||||
|
this.frontStencilFunction = _frontStencilFunction;
|
||||||
|
this.backStencilFunction = _backStencilFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStencilTest() {
|
||||||
|
return stencilTest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StencilOperation getFrontStencilStencilFailOperation(){ return frontStencilStencilFailOperation; }
|
||||||
|
public StencilOperation getFrontStencilDepthFailOperation(){ return frontStencilDepthFailOperation; }
|
||||||
|
public StencilOperation getFrontStencilDepthPassOperation(){ return frontStencilDepthPassOperation; }
|
||||||
|
public StencilOperation getBackStencilStencilFailOperation(){ return backStencilStencilFailOperation; }
|
||||||
|
public StencilOperation getBackStencilDepthFailOperation(){ return backStencilDepthFailOperation; }
|
||||||
|
public StencilOperation getBackStencilDepthPassOperation(){ return backStencilDepthPassOperation; }
|
||||||
|
|
||||||
|
public StencilFunction getFrontStencilFunction(){ return frontStencilFunction; }
|
||||||
|
public StencilFunction getBackStencilFunction(){ return backStencilFunction; }
|
||||||
|
|
||||||
public void setFaceCullMode(FaceCullMode cullMode) {
|
public void setFaceCullMode(FaceCullMode cullMode) {
|
||||||
applyCullMode = true;
|
applyCullMode = true;
|
||||||
this.cullMode = cullMode;
|
this.cullMode = cullMode;
|
||||||
|
@ -139,6 +139,19 @@ public class RenderContext {
|
|||||||
|
|
||||||
public int boundTextureUnit = 0;
|
public int boundTextureUnit = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stencil Buffer state
|
||||||
|
*/
|
||||||
|
public boolean stencilTest = false;
|
||||||
|
public RenderState.StencilOperation frontStencilStencilFailOperation = RenderState.StencilOperation.Keep;
|
||||||
|
public RenderState.StencilOperation frontStencilDepthFailOperation = RenderState.StencilOperation.Keep;
|
||||||
|
public RenderState.StencilOperation frontStencilDepthPassOperation = RenderState.StencilOperation.Keep;
|
||||||
|
public RenderState.StencilOperation backStencilStencilFailOperation = RenderState.StencilOperation.Keep;
|
||||||
|
public RenderState.StencilOperation backStencilDepthFailOperation = RenderState.StencilOperation.Keep;
|
||||||
|
public RenderState.StencilOperation backStencilDepthPassOperation = RenderState.StencilOperation.Keep;
|
||||||
|
public RenderState.StencilFunction frontStencilFunction = RenderState.StencilFunction.Always;
|
||||||
|
public RenderState.StencilFunction backStencilFunction = RenderState.StencilFunction.Always;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vertex attribs currently bound and enabled. If a slot is null, then
|
* Vertex attribs currently bound and enabled. If a slot is null, then
|
||||||
* it is disabled.
|
* it is disabled.
|
||||||
|
@ -324,6 +324,9 @@ public class LwjglGL1Renderer implements GL1Renderer {
|
|||||||
context.blendMode = state.getBlendMode();
|
context.blendMode = state.getBlendMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(state.isStencilTest())
|
||||||
|
throw new UnsupportedOperationException("OpenGL 1.1 doesn't support two sided stencil operations.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setViewPort(int x, int y, int w, int h) {
|
public void setViewPort(int x, int y, int w, int h) {
|
||||||
|
@ -471,7 +471,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
|
|
||||||
if (state.isDepthTest() && !context.depthTestEnabled) {
|
if (state.isDepthTest() && !context.depthTestEnabled) {
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LESS);
|
||||||
context.depthTestEnabled = true;
|
context.depthTestEnabled = true;
|
||||||
} else if (!state.isDepthTest() && context.depthTestEnabled) {
|
} else if (!state.isDepthTest() && context.depthTestEnabled) {
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
@ -603,6 +603,97 @@ public class LwjglRenderer implements Renderer {
|
|||||||
context.blendMode = state.getBlendMode();
|
context.blendMode = state.getBlendMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(context.stencilTest!=state.isStencilTest()
|
||||||
|
|| context.frontStencilStencilFailOperation!=state.getFrontStencilStencilFailOperation()
|
||||||
|
|| context.frontStencilDepthFailOperation!=state.getFrontStencilDepthFailOperation()
|
||||||
|
|| context.frontStencilDepthPassOperation!=state.getFrontStencilDepthPassOperation()
|
||||||
|
|| context.backStencilStencilFailOperation!=state.getBackStencilStencilFailOperation()
|
||||||
|
|| context.backStencilDepthFailOperation!=state.getBackStencilDepthFailOperation()
|
||||||
|
|| context.backStencilDepthPassOperation!=state.getBackStencilDepthPassOperation()
|
||||||
|
|| context.frontStencilFunction!=state.getFrontStencilFunction()
|
||||||
|
|| context.backStencilFunction!=state.getBackStencilFunction()
|
||||||
|
){
|
||||||
|
|
||||||
|
context.frontStencilStencilFailOperation=state.getFrontStencilStencilFailOperation(); //terrible looking, I know
|
||||||
|
context.frontStencilDepthFailOperation=state.getFrontStencilDepthFailOperation();
|
||||||
|
context.frontStencilDepthPassOperation=state.getFrontStencilDepthPassOperation();
|
||||||
|
context.backStencilStencilFailOperation=state.getBackStencilStencilFailOperation();
|
||||||
|
context.backStencilDepthFailOperation=state.getBackStencilDepthFailOperation();
|
||||||
|
context.backStencilDepthPassOperation=state.getBackStencilDepthPassOperation();
|
||||||
|
context.frontStencilFunction=state.getFrontStencilFunction();
|
||||||
|
context.backStencilFunction=state.getBackStencilFunction();
|
||||||
|
|
||||||
|
if(state.isStencilTest()){
|
||||||
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
glStencilOpSeparate(GL_FRONT,
|
||||||
|
glStencilOpFromStencilOp(state.getFrontStencilStencilFailOperation()),
|
||||||
|
glStencilOpFromStencilOp(state.getFrontStencilDepthFailOperation()),
|
||||||
|
glStencilOpFromStencilOp(state.getFrontStencilDepthPassOperation())
|
||||||
|
);
|
||||||
|
glStencilOpSeparate(GL_BACK,
|
||||||
|
glStencilOpFromStencilOp(state.getBackStencilStencilFailOperation()),
|
||||||
|
glStencilOpFromStencilOp(state.getBackStencilDepthFailOperation()),
|
||||||
|
glStencilOpFromStencilOp(state.getBackStencilDepthPassOperation())
|
||||||
|
);
|
||||||
|
glStencilFuncSeparate(GL_FRONT,
|
||||||
|
glStencilFuncFromStencilFunc(state.getFrontStencilFunction()),
|
||||||
|
0,Integer.MAX_VALUE
|
||||||
|
);
|
||||||
|
glStencilFuncSeparate(GL_BACK,
|
||||||
|
glStencilFuncFromStencilFunc(state.getBackStencilFunction()),
|
||||||
|
0,Integer.MAX_VALUE
|
||||||
|
);
|
||||||
|
}else{
|
||||||
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private int glStencilOpFromStencilOp(RenderState.StencilOperation s){
|
||||||
|
switch(s){
|
||||||
|
case Keep:
|
||||||
|
return GL_KEEP;
|
||||||
|
case Zero:
|
||||||
|
return GL_ZERO;
|
||||||
|
case Replace:
|
||||||
|
return GL_REPLACE;
|
||||||
|
case Increment:
|
||||||
|
return GL_INCR;
|
||||||
|
case IncrementWrap:
|
||||||
|
return GL_INCR_WRAP;
|
||||||
|
case Decrement:
|
||||||
|
return GL_DECR;
|
||||||
|
case DecrementWrap:
|
||||||
|
return GL_DECR_WRAP;
|
||||||
|
case Invert:
|
||||||
|
return GL_INVERT;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Unrecognized front stencil operation: " + s);
|
||||||
|
} //end switch
|
||||||
|
}
|
||||||
|
|
||||||
|
private int glStencilFuncFromStencilFunc(RenderState.StencilFunction s){
|
||||||
|
switch(s){
|
||||||
|
case Never:
|
||||||
|
return GL_NEVER;
|
||||||
|
case Less:
|
||||||
|
return GL_LESS;
|
||||||
|
case LessEqual:
|
||||||
|
return GL_LEQUAL;
|
||||||
|
case Greater:
|
||||||
|
return GL_GREATER;
|
||||||
|
case GreaterEqual:
|
||||||
|
return GL_GEQUAL;
|
||||||
|
case Equal:
|
||||||
|
return GL_EQUAL;
|
||||||
|
case NotEqual:
|
||||||
|
return GL_NOTEQUAL;
|
||||||
|
case Always:
|
||||||
|
return GL_ALWAYS;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Unrecognized front stencil functin: " + s);
|
||||||
|
} //end switch
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************\
|
/*********************************************************************\
|
||||||
|
Loading…
x
Reference in New Issue
Block a user