RenderState support for two sided Stencil Buffer operations

Hi,



I’ve been working on a JME3 shadow volume scene processor, and hit a brick wall when I found that aside from clearing it, there is absolutely no way to use stencil buffer operations in JME3. I have made some modifications to RenderState.java, and LwjglRenderer.java to support two sided stencil operations. I also added an exception to LwjglGLRenderer.java in case someone tried to use two sided stencil operations with it (they are not supported AFIK).



Quick question: assuming nobody points out glaring errors in this code, or other reasons why it should be included, how should I commit this? Do I need to get some kind of authentication to do so, and if so where?



Here are the changes:



RenderState.java

[patch]

— Base (BASE)

+++ Locally Modified (Based On LOCAL)

@@ -130,6 +130,29 @@

FrontAndBack

}



+

  • public enum StencilOperation {
  •    Keep, //keep the current value<br />
    
  •    Zero, //set the value to 0<br />
    
  •    Replace,  //sets the buffer to<br />
    
  •    Increment,<br />
    
  •    IncrementWrap,<br />
    
  •    Decrement,<br />
    
  •    DecrementWrap,<br />
    
  •    Invert<br />
    
  • }

    +
  • public enum StencilFunction {
  •    Never,<br />
    
  •    Less,<br />
    
  •    LessEqual,<br />
    
  •    Greater,<br />
    
  •    GreaterEqual,<br />
    
  •    Equal,<br />
    
  •    NotEqual,<br />
    
  •    Always<br />
    
  • }

    +

    static {

    NULL.cullMode = FaceCullMode.Off;

    NULL.depthTest = false;

    @@ -170,6 +193,15 @@

    boolean applyPolyOffset = true;

    float offsetFactor = 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 {

    OutputCapsule oc = ex.getCapsule(this);

    @@ -185,6 +217,15 @@

    oc.write(offsetEnabled, "offsetEnabled", false);

    oc.write(offsetFactor, "offsetFactor", 0);

    oc.write(offsetUnits, "offsetUnits", 0);
  •    oc.write(stencilTest, &quot;stencilTest&quot;, false);<br />
    
  •    oc.write(frontStencilStencilFailOperation, &quot;frontStencilStencilFailOperation&quot;, StencilOperation.Keep);<br />
    
  •    oc.write(frontStencilDepthFailOperation, &quot;frontStencilDepthFailOperation&quot;, StencilOperation.Keep);<br />
    
  •    oc.write(frontStencilDepthPassOperation, &quot;frontStencilDepthPassOperation&quot;, StencilOperation.Keep);<br />
    
  •    oc.write(backStencilStencilFailOperation, &quot;frontStencilStencilFailOperation&quot;, StencilOperation.Keep);<br />
    
  •    oc.write(backStencilDepthFailOperation, &quot;backStencilDepthFailOperation&quot;, StencilOperation.Keep);<br />
    
  •    oc.write(backStencilDepthPassOperation, &quot;backStencilDepthPassOperation&quot;, StencilOperation.Keep);<br />
    
  •    oc.write(frontStencilFunction, &quot;frontStencilFunction&quot;, StencilFunction.Always);<br />
    
  •    oc.write(backStencilFunction, &quot;backStencilFunction&quot;, StencilFunction.Always);<br />
    

}



public void read(JmeImporter im) throws IOException {

@@ -201,6 +242,15 @@

offsetEnabled = ic.readBoolean("offsetEnabled", false);

offsetFactor = ic.readFloat("offsetFactor", 0);

offsetUnits = ic.readFloat("offsetUnits", 0);

  •    stencilTest = ic.readBoolean(&quot;stencilTest&quot;, false);<br />
    
  •    frontStencilStencilFailOperation = ic.readEnum(&quot;frontStencilStencilFailOperation&quot;, StencilOperation.class, StencilOperation.Keep);<br />
    
  •    frontStencilDepthFailOperation = ic.readEnum(&quot;frontStencilDepthFailOperation&quot;, StencilOperation.class, StencilOperation.Keep);<br />
    
  •    frontStencilDepthPassOperation = ic.readEnum(&quot;frontStencilDepthPassOperation&quot;, StencilOperation.class, StencilOperation.Keep);<br />
    
  •    backStencilStencilFailOperation = ic.readEnum(&quot;backStencilStencilFailOperation&quot;, StencilOperation.class, StencilOperation.Keep);<br />
    
  •    backStencilDepthFailOperation = ic.readEnum(&quot;backStencilDepthFailOperation&quot;, StencilOperation.class, StencilOperation.Keep);<br />
    
  •    backStencilDepthPassOperation = ic.readEnum(&quot;backStencilDepthPassOperation&quot;, StencilOperation.class, StencilOperation.Keep);<br />
    
  •    frontStencilFunction = ic.readEnum(&quot;frontStencilFunction&quot;, StencilFunction.class, StencilFunction.Always);<br />
    
  •    backStencilFunction = ic.readEnum(&quot;backStencilFunction&quot;, StencilFunction.class, StencilFunction.Always);<br />
    

}



@Override

@@ -282,6 +332,41 @@

offsetUnits = units;

}


  • public void setStencil(boolean enabled,
  •        StencilOperation _frontStencilStencilFailOperation,<br />
    
  •        StencilOperation _frontStencilDepthFailOperation,<br />
    
  •        StencilOperation _frontStencilDepthPassOperation,<br />
    
  •        StencilOperation _backStencilStencilFailOperation,<br />
    
  •        StencilOperation _backStencilDepthFailOperation,<br />
    
  •        StencilOperation _backStencilDepthPassOperation,<br />
    
  •        StencilFunction _frontStencilFunction,<br />
    
  •        StencilFunction _backStencilFunction){<br />
    

+

  •    stencilTest = enabled;<br />
    
  •    this.frontStencilStencilFailOperation = _frontStencilStencilFailOperation;<br />
    
  •    this.frontStencilDepthFailOperation = _frontStencilDepthFailOperation;<br />
    
  •    this.frontStencilDepthPassOperation = _frontStencilDepthPassOperation;<br />
    
  •    this.backStencilStencilFailOperation = _backStencilStencilFailOperation;<br />
    
  •    this.backStencilDepthFailOperation = _backStencilDepthFailOperation;<br />
    
  •    this.backStencilDepthPassOperation = _backStencilDepthPassOperation;<br />
    
  •    this.frontStencilFunction = _frontStencilFunction;<br />
    
  •    this.backStencilFunction = _backStencilFunction;<br />
    
  • }

    +
  • public boolean isStencilTest() {
  •    return stencilTest;<br />
    
  • }

    +
  • 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) {

    applyCullMode = true;

    this.cullMode = cullMode;

    [/patch]



    LwjglRenderer.java

    [patch]

    — Base (BASE)

    +++ Locally Modified (Based On LOCAL)

    @@ -585,8 +585,78 @@

    context.blendMode = state.getBlendMode();

    }


  •    if(state.isStencilTest()){<br />
    
  •        glEnable(GL_STENCIL_TEST);<br />
    
  •        glStencilOpSeparate(GL_FRONT,<br />
    
  •                glStencilOpFromStencilOp(state.getFrontStencilStencilFailOperation()),<br />
    
  •                glStencilOpFromStencilOp(state.getFrontStencilDepthFailOperation()),<br />
    
  •                glStencilOpFromStencilOp(state.getFrontStencilDepthPassOperation())<br />
    
  •                );<br />
    
  •        glStencilOpSeparate(GL_BACK,<br />
    
  •                glStencilOpFromStencilOp(state.getBackStencilStencilFailOperation()),<br />
    
  •                glStencilOpFromStencilOp(state.getBackStencilDepthFailOperation()),<br />
    
  •                glStencilOpFromStencilOp(state.getBackStencilDepthPassOperation())<br />
    
  •                );<br />
    
  •        glStencilFuncSeparate(GL_FRONT,<br />
    
  •                glStencilFuncFromStencilFunc(state.getFrontStencilFunction()),<br />
    
  •                0,Integer.MAX_VALUE<br />
    
  •                );<br />
    
  •        glStencilFuncSeparate(GL_BACK,<br />
    
  •                glStencilFuncFromStencilFunc(state.getBackStencilFunction()),<br />
    
  •                0,Integer.MAX_VALUE<br />
    
  •                );<br />
    
  •    }else{<br />
    
  •        glDisable(GL_STENCIL_TEST);<br />
    

}


  • }

    +
  • private int glStencilOpFromStencilOp(RenderState.StencilOperation s){
  •    switch(s){<br />
    
  •    case Keep:<br />
    
  •        return GL_KEEP;<br />
    
  •    case Zero:<br />
    
  •        return GL_ZERO;<br />
    
  •    case Replace:<br />
    
  •        return GL_REPLACE;<br />
    
  •    case Increment:<br />
    
  •        return GL_INCR;<br />
    
  •    case IncrementWrap:<br />
    
  •        return GL_INCR_WRAP;<br />
    
  •    case Decrement:<br />
    
  •        return GL_DECR;<br />
    
  •    case DecrementWrap:<br />
    
  •        return GL_DECR_WRAP;<br />
    
  •    case Invert:<br />
    
  •        return GL_INVERT;<br />
    
  •    default:<br />
    
  •        throw new UnsupportedOperationException(&quot;Unrecognized front stencil operation: &quot; + s);<br />
    
  •    }  //end switch<br />
    
  • }

    +
  • private int glStencilFuncFromStencilFunc(RenderState.StencilFunction s){
  •    switch(s){<br />
    
  •    case Never:<br />
    
  •        return GL_NEVER;<br />
    
  •    case Less:<br />
    
  •        return GL_LESS;<br />
    
  •    case LessEqual:<br />
    
  •        return GL_LEQUAL;<br />
    
  •    case Greater:<br />
    
  •        return GL_GREATER;<br />
    
  •    case GreaterEqual:<br />
    
  •        return GL_GEQUAL;<br />
    
  •    case Equal:<br />
    
  •        return GL_EQUAL;<br />
    
  •    case NotEqual:<br />
    
  •        return GL_NOTEQUAL;<br />
    
  •    case Always:<br />
    
  •        return GL_ALWAYS;<br />
    
  •    default:<br />
    
  •        throw new UnsupportedOperationException(&quot;Unrecognized front stencil functin: &quot; + s);<br />
    
  •    }  //end switch<br />
    
  • }

    +

    /********************************************************************

    |
    Camera and World transforms *|

    *********************************************************************/

    [/patch]



    LwjglGL1Renderer.java

    [patch]— Base (BASE)

    +++ Locally Modified (Based On LOCAL)

    @@ -280,6 +280,9 @@

    context.blendMode = state.getBlendMode();

    }


  •    if(state.isStencilTest())<br />
    
  •        throw new UnsupportedOperationException(&quot;OpenGL 1.1 doesn't support two sided stencil operations.&quot;);<br />
    

+

}



public void setViewPort(int x, int y, int w, int h) {

[/patch]

A small note about the patch:

Every time applyRenderState() is called for LwjglRenderer, it is going to call glDisable(GL_STENCIL_TEST), to reduce context switches, you can use the RenderContext class.

Good point. I’ll get on that and report back here with the new code :slight_smile:

Two weeks later >.> Here’s the code with the modified renderContext class.



Once this is critiqued, what are the best practices for committing this?



LwjglRenderer.java

[patch]# This patch file was generated by NetBeans IDE

It uses platform neutral UTF-8 encoding and n newlines.

— Base (BASE)

+++ Locally Modified (Based On LOCAL)

@@ -462,7 +462,7 @@



if (state.isDepthTest() && !context.depthTestEnabled) {

glEnable(GL_DEPTH_TEST);

  •        glDepthFunc(GL_LEQUAL);<br />
    
  •        glDepthFunc(GL_LESS);<br />
    

context.depthTestEnabled = true;

} else if (!state.isDepthTest() && context.depthTestEnabled) {

glDisable(GL_DEPTH_TEST);

@@ -594,8 +594,99 @@

context.blendMode = state.getBlendMode();

}


  •    if(context.stencilTest!=state.isStencilTest()<br />
    
  •            || context.frontStencilStencilFailOperation!=state.getFrontStencilStencilFailOperation()<br />
    
  •            || context.frontStencilDepthFailOperation!=state.getFrontStencilDepthFailOperation()<br />
    
  •            || context.frontStencilDepthPassOperation!=state.getFrontStencilDepthPassOperation()<br />
    
  •            || context.backStencilStencilFailOperation!=state.getBackStencilStencilFailOperation()<br />
    
  •            || context.backStencilDepthFailOperation!=state.getBackStencilDepthFailOperation()<br />
    
  •            || context.backStencilDepthPassOperation!=state.getBackStencilDepthPassOperation()<br />
    
  •            || context.frontStencilFunction!=state.getFrontStencilFunction()<br />
    
  •            || context.backStencilFunction!=state.getBackStencilFunction()<br />
    
  •            ){<br />
    

+

  •        context.frontStencilStencilFailOperation=state.getFrontStencilStencilFailOperation();   //terrible looking, I know<br />
    
  •        context.frontStencilDepthFailOperation=state.getFrontStencilDepthFailOperation();<br />
    
  •        context.frontStencilDepthPassOperation=state.getFrontStencilDepthPassOperation();<br />
    
  •        context.backStencilStencilFailOperation=state.getBackStencilStencilFailOperation();<br />
    
  •        context.backStencilDepthFailOperation=state.getBackStencilDepthFailOperation();<br />
    
  •        context.backStencilDepthPassOperation=state.getBackStencilDepthPassOperation();<br />
    
  •        context.frontStencilFunction=state.getFrontStencilFunction();<br />
    
  •        context.backStencilFunction=state.getBackStencilFunction();<br />
    

+

  •        if(state.isStencilTest()){<br />
    
  •            glEnable(GL_STENCIL_TEST);<br />
    
  •            glStencilOpSeparate(GL_FRONT,<br />
    
  •                    glStencilOpFromStencilOp(state.getFrontStencilStencilFailOperation()),<br />
    
  •                    glStencilOpFromStencilOp(state.getFrontStencilDepthFailOperation()),<br />
    
  •                    glStencilOpFromStencilOp(state.getFrontStencilDepthPassOperation())<br />
    
  •                    );<br />
    
  •            glStencilOpSeparate(GL_BACK,<br />
    
  •                    glStencilOpFromStencilOp(state.getBackStencilStencilFailOperation()),<br />
    
  •                    glStencilOpFromStencilOp(state.getBackStencilDepthFailOperation()),<br />
    
  •                    glStencilOpFromStencilOp(state.getBackStencilDepthPassOperation())<br />
    
  •                    );<br />
    
  •            glStencilFuncSeparate(GL_FRONT,<br />
    
  •                    glStencilFuncFromStencilFunc(state.getFrontStencilFunction()),<br />
    
  •                    0,Integer.MAX_VALUE<br />
    
  •                    );<br />
    
  •            glStencilFuncSeparate(GL_BACK,<br />
    
  •                    glStencilFuncFromStencilFunc(state.getBackStencilFunction()),<br />
    
  •                    0,Integer.MAX_VALUE<br />
    
  •                    );<br />
    
  •        }else{<br />
    
  •            glDisable(GL_STENCIL_TEST);<br />
    

}

  •    }<br />
    

+ }
+
+ 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
+ }
+
/*********************************************************************
|* Camera and World transforms *|
*********************************************************************/
[/patch]

RenderState.java
[patch]# This patch file was generated by NetBeans IDE
# It uses platform neutral UTF-8 encoding and n newlines.
--- Base (BASE)
+++ Locally Modified (Based On LOCAL)
@@ -130,6 +130,29 @@
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 {
NULL.cullMode = FaceCullMode.Off;
NULL.depthTest = false;
@@ -170,6 +193,15 @@
boolean applyPolyOffset = true;
float offsetFactor = 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 {
OutputCapsule oc = ex.getCapsule(this);
@@ -185,6 +217,15 @@
oc.write(offsetEnabled, "offsetEnabled", false);
oc.write(offsetFactor, "offsetFactor", 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 {
@@ -201,6 +242,15 @@
offsetEnabled = ic.readBoolean("offsetEnabled", false);
offsetFactor = ic.readFloat("offsetFactor", 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
@@ -282,6 +332,41 @@
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) {
applyCullMode = true;
this.cullMode = cullMode;
[/patch]

RenderContext.java
[patch]# This patch file was generated by NetBeans IDE
# It uses platform neutral UTF-8 encoding and n newlines.
--- Base (BASE)
+++ Locally Modified (Based On LOCAL)
@@ -140,6 +140,19 @@
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
* it is disabled.
*/
[/patch]

LwjglGL1Renderer.java
[patch]# This patch file was generated by NetBeans IDE
# It uses platform neutral UTF-8 encoding and n newlines.
--- Base (BASE)
+++ Locally Modified (Based On LOCAL)
@@ -291,6 +291,9 @@
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) {
[/patch]

Cool, I tried to commit your first patch but it was not working (i mean the patching)

There is something strange with your patches they start with “—BASE”

Usually it’s the name of the modified file…

Ok, I’ll try a different (no pun intended) method of creating the diff. It seems to give me filenames.



[patch]# This patch file was generated by NetBeans IDE

Following Index: paths are relative to: C:UsersJosephDocumentsNetBeansProjectsenginesrccorecomjme3renderer

This patch can be applied using context Tools: Patch action on respective folder.

It uses platform neutral UTF-8 encoding and n newlines.

Above lines and this line are ignored by the patching process.

Index: RenderContext.java

— RenderContext.java Base (BASE)

+++ RenderContext.java Locally Modified (Based On LOCAL)

@@ -140,6 +140,19 @@

public int boundTextureUnit = 0;



/**

  • * Stencil Buffer state<br />
    
  • */<br />
    
  • 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
  • it is disabled.

    */

    [/patch]



    [patch]# This patch file was generated by NetBeans IDE

Following Index: paths are relative to: C:UsersJosephDocumentsNetBeansProjectsenginesrclwjgl-oglcomjme3rendererlwjgl

This patch can be applied using context Tools: Patch action on respective folder.

It uses platform neutral UTF-8 encoding and n newlines.

Above lines and this line are ignored by the patching process.

Index: LwjglRenderer.java

— LwjglRenderer.java Base (BASE)

+++ LwjglRenderer.java Locally Modified (Based On LOCAL)

@@ -462,7 +462,7 @@



if (state.isDepthTest() && !context.depthTestEnabled) {

glEnable(GL_DEPTH_TEST);

  •        glDepthFunc(GL_LEQUAL);<br />
    
  •        glDepthFunc(GL_LESS);<br />
    

context.depthTestEnabled = true;

} else if (!state.isDepthTest() && context.depthTestEnabled) {

glDisable(GL_DEPTH_TEST);

@@ -594,8 +594,99 @@

context.blendMode = state.getBlendMode();

}


  •    if(context.stencilTest!=state.isStencilTest()<br />
    
  •            || context.frontStencilStencilFailOperation!=state.getFrontStencilStencilFailOperation()<br />
    
  •            || context.frontStencilDepthFailOperation!=state.getFrontStencilDepthFailOperation()<br />
    
  •            || context.frontStencilDepthPassOperation!=state.getFrontStencilDepthPassOperation()<br />
    
  •            || context.backStencilStencilFailOperation!=state.getBackStencilStencilFailOperation()<br />
    
  •            || context.backStencilDepthFailOperation!=state.getBackStencilDepthFailOperation()<br />
    
  •            || context.backStencilDepthPassOperation!=state.getBackStencilDepthPassOperation()<br />
    
  •            || context.frontStencilFunction!=state.getFrontStencilFunction()<br />
    
  •            || context.backStencilFunction!=state.getBackStencilFunction()<br />
    
  •            ){<br />
    

+

  •        context.frontStencilStencilFailOperation=state.getFrontStencilStencilFailOperation();   //terrible looking, I know<br />
    
  •        context.frontStencilDepthFailOperation=state.getFrontStencilDepthFailOperation();<br />
    
  •        context.frontStencilDepthPassOperation=state.getFrontStencilDepthPassOperation();<br />
    
  •        context.backStencilStencilFailOperation=state.getBackStencilStencilFailOperation();<br />
    
  •        context.backStencilDepthFailOperation=state.getBackStencilDepthFailOperation();<br />
    
  •        context.backStencilDepthPassOperation=state.getBackStencilDepthPassOperation();<br />
    
  •        context.frontStencilFunction=state.getFrontStencilFunction();<br />
    
  •        context.backStencilFunction=state.getBackStencilFunction();<br />
    

+

  •        if(state.isStencilTest()){<br />
    
  •            glEnable(GL_STENCIL_TEST);<br />
    
  •            glStencilOpSeparate(GL_FRONT,<br />
    
  •                    glStencilOpFromStencilOp(state.getFrontStencilStencilFailOperation()),<br />
    
  •                    glStencilOpFromStencilOp(state.getFrontStencilDepthFailOperation()),<br />
    
  •                    glStencilOpFromStencilOp(state.getFrontStencilDepthPassOperation())<br />
    
  •                    );<br />
    
  •            glStencilOpSeparate(GL_BACK,<br />
    
  •                    glStencilOpFromStencilOp(state.getBackStencilStencilFailOperation()),<br />
    
  •                    glStencilOpFromStencilOp(state.getBackStencilDepthFailOperation()),<br />
    
  •                    glStencilOpFromStencilOp(state.getBackStencilDepthPassOperation())<br />
    
  •                    );<br />
    
  •            glStencilFuncSeparate(GL_FRONT,<br />
    
  •                    glStencilFuncFromStencilFunc(state.getFrontStencilFunction()),<br />
    
  •                    0,Integer.MAX_VALUE<br />
    
  •                    );<br />
    
  •            glStencilFuncSeparate(GL_BACK,<br />
    
  •                    glStencilFuncFromStencilFunc(state.getBackStencilFunction()),<br />
    
  •                    0,Integer.MAX_VALUE<br />
    
  •                    );<br />
    
  •        }else{<br />
    
  •            glDisable(GL_STENCIL_TEST);<br />
    

}

  •    }<br />
    

+ }
+
+ 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
+ }
+
/*********************************************************************
|* Camera and World transforms *|
*********************************************************************/
[/patch]

[patch]# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: C:UsersJosephDocumentsNetBeansProjectsenginesrclwjgl-oglcomjme3rendererlwjgl
# This patch can be applied using context Tools: Patch action on respective folder.
# It uses platform neutral UTF-8 encoding and n newlines.
# Above lines and this line are ignored by the patching process.
Index: LwjglGL1Renderer.java
--- LwjglGL1Renderer.java Base (BASE)
+++ LwjglGL1Renderer.java Locally Modified (Based On LOCAL)
@@ -291,6 +291,9 @@
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) {
[/patch]

[patch]# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: C:UsersJosephDocumentsNetBeansProjectsenginesrccorecomjme3material
# This patch can be applied using context Tools: Patch action on respective folder.
# It uses platform neutral UTF-8 encoding and n newlines.
# Above lines and this line are ignored by the patching process.
Index: RenderState.java
--- RenderState.java Base (BASE)
+++ RenderState.java Locally Modified (Based On LOCAL)
@@ -130,6 +130,29 @@
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 {
NULL.cullMode = FaceCullMode.Off;
NULL.depthTest = false;
@@ -170,6 +193,15 @@
boolean applyPolyOffset = true;
float offsetFactor = 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 {
OutputCapsule oc = ex.getCapsule(this);
@@ -185,6 +217,15 @@
oc.write(offsetEnabled, "offsetEnabled", false);
oc.write(offsetFactor, "offsetFactor", 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 {
@@ -201,6 +242,15 @@
offsetEnabled = ic.readBoolean("offsetEnabled", false);
offsetFactor = ic.readFloat("offsetFactor", 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
@@ -282,6 +332,41 @@
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) {
applyCullMode = true;
this.cullMode = cullMode;
[/patch]

nope…I can’t add it, I have a “Patch cannot be applied in this context”…even if i select the correct file…

usually patch gives the version number of the file to patch too…



@Momoko_Fan maybe we could give him commit access?

Commit access would probably help for later given the interest in my work on shadow volumes. Either way, let me know :slight_smile:

yeah I’m eager to test you shadow Volume renderer :stuck_out_tongue:

nehon said:
@Momoko_Fan maybe we could give him commit access?

sure
1 Like