Home | History | Annotate | Download | only in material
      1 /*
      2  * Copyright (c) 2009-2010 jMonkeyEngine
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  * * Redistributions of source code must retain the above copyright
     10  *   notice, this list of conditions and the following disclaimer.
     11  *
     12  * * Redistributions in binary form must reproduce the above copyright
     13  *   notice, this list of conditions and the following disclaimer in the
     14  *   documentation and/or other materials provided with the distribution.
     15  *
     16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
     17  *   may be used to endorse or promote products derived from this software
     18  *   without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 package com.jme3.material;
     33 
     34 import com.jme3.export.*;
     35 import com.jme3.scene.Mesh;
     36 import com.jme3.scene.Mesh.Mode;
     37 import java.io.IOException;
     38 
     39 /**
     40  * <code>RenderState</code> specifies material rendering properties that cannot
     41  * be controlled by a shader on a {@link Material}. The properties
     42  * allow manipulation of rendering features such as depth testing, alpha blending,
     43  * face culling, stencil operations, and much more.
     44  *
     45  * @author Kirill Vainer
     46  */
     47 public class RenderState implements Cloneable, Savable {
     48 
     49     /**
     50      * The <code>DEFAULT</code> render state is the one used by default
     51      * on all materials unless changed otherwise by the user.
     52      *
     53      * <p>
     54      * It has the following properties:
     55      * <ul>
     56      * <li>Back Face Culling</li>
     57      * <li>Depth Testing Enabled</li>
     58      * <li>Depth Writing Enabled</li>
     59      * </ul>
     60      */
     61     public static final RenderState DEFAULT = new RenderState();
     62 
     63     /**
     64      * The <code>NULL</code> render state is identical to the {@link RenderState#DEFAULT}
     65      * render state except that depth testing and face culling are disabled.
     66      */
     67     public static final RenderState NULL = new RenderState();
     68 
     69     /**
     70      * The <code>ADDITIONAL</code> render state is identical to the
     71      * {@link RenderState#DEFAULT} render state except that all apply
     72      * values are set to false. This allows the <code>ADDITIONAL</code> render
     73      * state to be combined with other state but only influencing values
     74      * that were changed from the original.
     75      */
     76     public static final RenderState ADDITIONAL = new RenderState();
     77 
     78     /**
     79      * <code>TestFunction</code> specifies the testing function for stencil test
     80      * function and alpha test function.
     81      *
     82      * <p>The functions work similarly as described except that for stencil
     83      * test function, the reference value given in the stencil command is
     84      * the input value while the reference is the value already in the stencil
     85      * buffer.
     86      */
     87     public enum TestFunction {
     88 
     89         /**
     90          * The test always fails
     91          */
     92         Never,
     93         /**
     94          * The test succeeds if the input value is equal to the reference value.
     95          */
     96         Equal,
     97         /**
     98          * The test succeeds if the input value is less than the reference value.
     99          */
    100         Less,
    101         /**
    102          * The test succeeds if the input value is less than or equal to
    103          * the reference value.
    104          */
    105         LessOrEqual,
    106         /**
    107          * The test succeeds if the input value is greater than the reference value.
    108          */
    109         Greater,
    110         /**
    111          * The test succeeds if the input value is greater than or equal to
    112          * the reference value.
    113          */
    114         GreaterOrEqual,
    115         /**
    116          * The test succeeds if the input value does not equal the
    117          * reference value.
    118          */
    119         NotEqual,
    120         /**
    121          * The test always passes
    122          */
    123         Always,}
    124 
    125     /**
    126      * <code>BlendMode</code> specifies the blending operation to use.
    127      *
    128      * @see RenderState#setBlendMode(com.jme3.material.RenderState.BlendMode)
    129      */
    130     public enum BlendMode {
    131 
    132         /**
    133          * No blending mode is used.
    134          */
    135         Off,
    136         /**
    137          * Additive blending. For use with glows and particle emitters.
    138          * <p>
    139          * Result = Source Color + Destination Color -> (GL_ONE, GL_ONE)
    140          */
    141         Additive,
    142         /**
    143          * Premultiplied alpha blending, for use with premult alpha textures.
    144          * <p>
    145          * Result = Source Color + (Dest Color * (1 - Source Alpha) ) -> (GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
    146          */
    147         PremultAlpha,
    148         /**
    149          * Additive blending that is multiplied with source alpha.
    150          * For use with glows and particle emitters.
    151          * <p>
    152          * Result = (Source Alpha * Source Color) + Dest Color -> (GL_SRC_ALPHA, GL_ONE)
    153          */
    154         AlphaAdditive,
    155         /**
    156          * Color blending, blends in color from dest color
    157          * using source color.
    158          * <p>
    159          * Result = Source Color + (1 - Source Color) * Dest Color -> (GL_ONE, GL_ONE_MINUS_SRC_COLOR)
    160          */
    161         Color,
    162         /**
    163          * Alpha blending, interpolates to source color from dest color
    164          * using source alpha.
    165          * <p>
    166          * Result = Source Alpha * Source Color +
    167          *          (1 - Source Alpha) * Dest Color -> (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    168          */
    169         Alpha,
    170         /**
    171          * Multiplies the source and dest colors.
    172          * <p>
    173          * Result = Source Color * Dest Color -> (GL_DST_COLOR, GL_ZERO)
    174          */
    175         Modulate,
    176         /**
    177          * Multiplies the source and dest colors then doubles the result.
    178          * <p>
    179          * Result = 2 * Source Color * Dest Color -> (GL_DST_COLOR, GL_SRC_COLOR)
    180          */
    181         ModulateX2
    182     }
    183 
    184     /**
    185      * <code>FaceCullMode</code> specifies the criteria for faces to be culled.
    186      *
    187      * @see RenderState#setFaceCullMode(com.jme3.material.RenderState.FaceCullMode)
    188      */
    189     public enum FaceCullMode {
    190 
    191         /**
    192          * Face culling is disabled.
    193          */
    194         Off,
    195         /**
    196          * Cull front faces
    197          */
    198         Front,
    199         /**
    200          * Cull back faces
    201          */
    202         Back,
    203         /**
    204          * Cull both front and back faces.
    205          */
    206         FrontAndBack
    207     }
    208 
    209     /**
    210      * <code>StencilOperation</code> specifies the stencil operation to use
    211      * in a certain scenario as specified in {@link RenderState#setStencil(boolean,
    212      * com.jme3.material.RenderState.StencilOperation,
    213      * com.jme3.material.RenderState.StencilOperation,
    214      * com.jme3.material.RenderState.StencilOperation,
    215      * com.jme3.material.RenderState.StencilOperation,
    216      * com.jme3.material.RenderState.StencilOperation,
    217      * com.jme3.material.RenderState.StencilOperation,
    218      * com.jme3.material.RenderState.StencilFunction,
    219      * com.jme3.material.RenderState.StencilFunction)}
    220      */
    221     public enum StencilOperation {
    222 
    223         /**
    224          * Keep the current value.
    225          */
    226         Keep,
    227         /**
    228          * Set the value to 0
    229          */
    230         Zero,
    231         /**
    232          * Replace the value in the stencil buffer with the reference value.
    233          */
    234         Replace,
    235 
    236         /**
    237          * Increment the value in the stencil buffer, clamp once reaching
    238          * the maximum value.
    239          */
    240         Increment,
    241 
    242         /**
    243          * Increment the value in the stencil buffer and wrap to 0 when
    244          * reaching the maximum value.
    245          */
    246         IncrementWrap,
    247         /**
    248          * Decrement the value in the stencil buffer and clamp once reaching 0.
    249          */
    250         Decrement,
    251         /**
    252          * Decrement the value in the stencil buffer and wrap to the maximum
    253          * value when reaching 0.
    254          */
    255         DecrementWrap,
    256 
    257         /**
    258          * Does a bitwise invert of the value in the stencil buffer.
    259          */
    260         Invert
    261     }
    262 
    263     static {
    264         NULL.cullMode = FaceCullMode.Off;
    265         NULL.depthTest = false;
    266     }
    267 
    268     static {
    269         ADDITIONAL.applyPointSprite = false;
    270         ADDITIONAL.applyWireFrame = false;
    271         ADDITIONAL.applyCullMode = false;
    272         ADDITIONAL.applyDepthWrite = false;
    273         ADDITIONAL.applyDepthTest = false;
    274         ADDITIONAL.applyColorWrite = false;
    275         ADDITIONAL.applyBlendMode = false;
    276         ADDITIONAL.applyAlphaTest = false;
    277         ADDITIONAL.applyAlphaFallOff = false;
    278         ADDITIONAL.applyPolyOffset = false;
    279     }
    280 
    281     boolean pointSprite = false;
    282     boolean applyPointSprite = true;
    283 
    284     boolean wireframe = false;
    285     boolean applyWireFrame = true;
    286 
    287     FaceCullMode cullMode = FaceCullMode.Back;
    288     boolean applyCullMode = true;
    289 
    290     boolean depthWrite = true;
    291     boolean applyDepthWrite = true;
    292 
    293     boolean depthTest = true;
    294     boolean applyDepthTest = true;
    295 
    296     boolean colorWrite = true;
    297     boolean applyColorWrite = true;
    298 
    299     BlendMode blendMode = BlendMode.Off;
    300     boolean applyBlendMode = true;
    301 
    302     boolean alphaTest = false;
    303     boolean applyAlphaTest = true;
    304 
    305     float alphaFallOff = 0;
    306     boolean applyAlphaFallOff = true;
    307 
    308     float offsetFactor = 0;
    309     float offsetUnits = 0;
    310     boolean offsetEnabled = false;
    311     boolean applyPolyOffset = true;
    312 
    313     boolean stencilTest = false;
    314     boolean applyStencilTest = false;
    315     StencilOperation frontStencilStencilFailOperation = StencilOperation.Keep;
    316     StencilOperation frontStencilDepthFailOperation = StencilOperation.Keep;
    317     StencilOperation frontStencilDepthPassOperation = StencilOperation.Keep;
    318     StencilOperation backStencilStencilFailOperation = StencilOperation.Keep;
    319     StencilOperation backStencilDepthFailOperation = StencilOperation.Keep;
    320     StencilOperation backStencilDepthPassOperation = StencilOperation.Keep;
    321     TestFunction frontStencilFunction = TestFunction.Always;
    322     TestFunction backStencilFunction = TestFunction.Always;
    323 
    324     public void write(JmeExporter ex) throws IOException {
    325         OutputCapsule oc = ex.getCapsule(this);
    326         oc.write(pointSprite, "pointSprite", false);
    327         oc.write(wireframe, "wireframe", false);
    328         oc.write(cullMode, "cullMode", FaceCullMode.Back);
    329         oc.write(depthWrite, "depthWrite", true);
    330         oc.write(depthTest, "depthTest", true);
    331         oc.write(colorWrite, "colorWrite", true);
    332         oc.write(blendMode, "blendMode", BlendMode.Off);
    333         oc.write(alphaTest, "alphaTest", false);
    334         oc.write(alphaFallOff, "alphaFallOff", 0);
    335         oc.write(offsetEnabled, "offsetEnabled", false);
    336         oc.write(offsetFactor, "offsetFactor", 0);
    337         oc.write(offsetUnits, "offsetUnits", 0);
    338         oc.write(stencilTest, "stencilTest", false);
    339         oc.write(frontStencilStencilFailOperation, "frontStencilStencilFailOperation", StencilOperation.Keep);
    340         oc.write(frontStencilDepthFailOperation, "frontStencilDepthFailOperation", StencilOperation.Keep);
    341         oc.write(frontStencilDepthPassOperation, "frontStencilDepthPassOperation", StencilOperation.Keep);
    342         oc.write(backStencilStencilFailOperation, "frontStencilStencilFailOperation", StencilOperation.Keep);
    343         oc.write(backStencilDepthFailOperation, "backStencilDepthFailOperation", StencilOperation.Keep);
    344         oc.write(backStencilDepthPassOperation, "backStencilDepthPassOperation", StencilOperation.Keep);
    345         oc.write(frontStencilFunction, "frontStencilFunction", TestFunction.Always);
    346         oc.write(backStencilFunction, "backStencilFunction", TestFunction.Always);
    347 
    348         // Only "additional render state" has them set to false by default
    349         oc.write(applyPointSprite,  "applyPointSprite",  true);
    350         oc.write(applyWireFrame,    "applyWireFrame",    true);
    351         oc.write(applyCullMode,     "applyCullMode",     true);
    352         oc.write(applyDepthWrite,   "applyDepthWrite",   true);
    353         oc.write(applyDepthTest,    "applyDepthTest",    true);
    354         oc.write(applyColorWrite,   "applyColorWrite",   true);
    355         oc.write(applyBlendMode,    "applyBlendMode",    true);
    356         oc.write(applyAlphaTest,    "applyAlphaTest",    true);
    357         oc.write(applyAlphaFallOff, "applyAlphaFallOff", true);
    358         oc.write(applyPolyOffset,   "applyPolyOffset",   true);
    359 
    360     }
    361 
    362     public void read(JmeImporter im) throws IOException {
    363         InputCapsule ic = im.getCapsule(this);
    364         pointSprite = ic.readBoolean("pointSprite", false);
    365         wireframe = ic.readBoolean("wireframe", false);
    366         cullMode = ic.readEnum("cullMode", FaceCullMode.class, FaceCullMode.Back);
    367         depthWrite = ic.readBoolean("depthWrite", true);
    368         depthTest = ic.readBoolean("depthTest", true);
    369         colorWrite = ic.readBoolean("colorWrite", true);
    370         blendMode = ic.readEnum("blendMode", BlendMode.class, BlendMode.Off);
    371         alphaTest = ic.readBoolean("alphaTest", false);
    372         alphaFallOff = ic.readFloat("alphaFallOff", 0);
    373         offsetEnabled = ic.readBoolean("offsetEnabled", false);
    374         offsetFactor = ic.readFloat("offsetFactor", 0);
    375         offsetUnits = ic.readFloat("offsetUnits", 0);
    376         stencilTest = ic.readBoolean("stencilTest", false);
    377         frontStencilStencilFailOperation = ic.readEnum("frontStencilStencilFailOperation", StencilOperation.class, StencilOperation.Keep);
    378         frontStencilDepthFailOperation = ic.readEnum("frontStencilDepthFailOperation", StencilOperation.class, StencilOperation.Keep);
    379         frontStencilDepthPassOperation = ic.readEnum("frontStencilDepthPassOperation", StencilOperation.class, StencilOperation.Keep);
    380         backStencilStencilFailOperation = ic.readEnum("backStencilStencilFailOperation", StencilOperation.class, StencilOperation.Keep);
    381         backStencilDepthFailOperation = ic.readEnum("backStencilDepthFailOperation", StencilOperation.class, StencilOperation.Keep);
    382         backStencilDepthPassOperation = ic.readEnum("backStencilDepthPassOperation", StencilOperation.class, StencilOperation.Keep);
    383         frontStencilFunction = ic.readEnum("frontStencilFunction", TestFunction.class, TestFunction.Always);
    384         backStencilFunction = ic.readEnum("backStencilFunction", TestFunction.class, TestFunction.Always);
    385 
    386         applyPointSprite =  ic.readBoolean("applyPointSprite",  true);
    387         applyWireFrame =    ic.readBoolean("applyWireFrame",    true);
    388         applyCullMode =     ic.readBoolean("applyCullMode",     true);
    389         applyDepthWrite =   ic.readBoolean("applyDepthWrite",   true);
    390         applyDepthTest =    ic.readBoolean("applyDepthTest",    true);
    391         applyColorWrite =   ic.readBoolean("applyColorWrite",   true);
    392         applyBlendMode =    ic.readBoolean("applyBlendMode",    true);
    393         applyAlphaTest =    ic.readBoolean("applyAlphaTest",    true);
    394         applyAlphaFallOff = ic.readBoolean("applyAlphaFallOff", true);
    395         applyPolyOffset =   ic.readBoolean("applyPolyOffset",   true);
    396     }
    397 
    398     /**
    399      * Create a clone of this <code>RenderState</code>
    400      *
    401      * @return Clone of this render state.
    402      */
    403     @Override
    404     public RenderState clone() {
    405         try {
    406             return (RenderState) super.clone();
    407         } catch (CloneNotSupportedException ex) {
    408             throw new AssertionError();
    409         }
    410     }
    411 
    412     /**
    413      * Enables point sprite mode.
    414      *
    415      * <p>When point sprite is enabled, any meshes
    416      * with the type of {@link Mode#Points} will be rendered as 2D quads
    417      * with texturing enabled. Fragment shaders can write to the
    418      * <code>gl_PointCoord</code> variable to manipulate the texture coordinate
    419      * for each pixel. The size of the 2D quad can be controlled by writing
    420      * to the <code>gl_PointSize</code> variable in the vertex shader.
    421      *
    422      * @param pointSprite Enables Point Sprite mode.
    423      */
    424     public void setPointSprite(boolean pointSprite) {
    425         applyPointSprite = true;
    426         this.pointSprite = pointSprite;
    427     }
    428 
    429     /**
    430      * Sets the alpha fall off value for alpha testing.
    431      *
    432      * <p>If the pixel's alpha value is greater than the
    433      * <code>alphaFallOff</code> then the pixel will be rendered, otherwise
    434      * the pixel will be discarded.
    435      *
    436      * @param alphaFallOff The alpha of all rendered pixels must be higher
    437      * than this value to be rendered. This value should be between 0 and 1.
    438      *
    439      * @see RenderState#setAlphaTest(boolean)
    440      */
    441     public void setAlphaFallOff(float alphaFallOff) {
    442         applyAlphaFallOff = true;
    443         this.alphaFallOff = alphaFallOff;
    444     }
    445 
    446     /**
    447      * Enable alpha testing.
    448      *
    449      * <p>When alpha testing is enabled, all input pixels' alpha are compared
    450      * to the {@link RenderState#setAlphaFallOff(float) constant alpha falloff}.
    451      * If the input alpha is greater than the falloff, the pixel will be rendered,
    452      * otherwise it will be discarded.
    453      *
    454      * @param alphaTest Set to true to enable alpha testing.
    455      *
    456      * @see RenderState#setAlphaFallOff(float)
    457      */
    458     public void setAlphaTest(boolean alphaTest) {
    459         applyAlphaTest = true;
    460         this.alphaTest = alphaTest;
    461     }
    462 
    463     /**
    464      * Enable writing color.
    465      *
    466      * <p>When color write is enabled, the result of a fragment shader, the
    467      * <code>gl_FragColor</code>, will be rendered into the color buffer
    468      * (including alpha).
    469      *
    470      * @param colorWrite Set to true to enable color writing.
    471      */
    472     public void setColorWrite(boolean colorWrite) {
    473         applyColorWrite = true;
    474         this.colorWrite = colorWrite;
    475     }
    476 
    477     /**
    478      * Set the face culling mode.
    479      *
    480      * <p>See the {@link FaceCullMode} enum on what each value does.
    481      * Face culling will project the triangle's points onto the screen
    482      * and determine if the triangle is in counter-clockwise order or
    483      * clockwise order. If a triangle is in counter-clockwise order, then
    484      * it is considered a front-facing triangle, otherwise, it is considered
    485      * a back-facing triangle.
    486      *
    487      * @param cullMode the face culling mode.
    488      */
    489     public void setFaceCullMode(FaceCullMode cullMode) {
    490         applyCullMode = true;
    491         this.cullMode = cullMode;
    492     }
    493 
    494     /**
    495      * Set the blending mode.
    496      *
    497      * <p>When blending is enabled, (<code>blendMode</code> is not {@link BlendMode#Off})
    498      * the input pixel will be blended with the pixel
    499      * already in the color buffer. The blending operation is determined
    500      * by the {@link BlendMode}. For example, the {@link BlendMode#Additive}
    501      * will add the input pixel's color to the color already in the color buffer:
    502      * <br/>
    503      * <code>Result = Source Color + Destination Color</code>
    504      *
    505      * @param blendMode The blend mode to use. Set to {@link BlendMode#Off}
    506      * to disable blending.
    507      */
    508     public void setBlendMode(BlendMode blendMode) {
    509         applyBlendMode = true;
    510         this.blendMode = blendMode;
    511     }
    512 
    513     /**
    514      * Enable depth testing.
    515      *
    516      * <p>When depth testing is enabled, a pixel must pass the depth test
    517      * before it is written to the color buffer.
    518      * The input pixel's depth value must be less than or equal than
    519      * the value already in the depth buffer to pass the depth test.
    520      *
    521      * @param depthTest Enable or disable depth testing.
    522      */
    523     public void setDepthTest(boolean depthTest) {
    524         applyDepthTest = true;
    525         this.depthTest = depthTest;
    526     }
    527 
    528     /**
    529      * Enable depth writing.
    530      *
    531      * <p>After passing the {@link RenderState#setDepthTest(boolean) depth test},
    532      * a pixel's depth value will be written into the depth buffer if
    533      * depth writing is enabled.
    534      *
    535      * @param depthWrite True to enable writing to the depth buffer.
    536      */
    537     public void setDepthWrite(boolean depthWrite) {
    538         applyDepthWrite = true;
    539         this.depthWrite = depthWrite;
    540     }
    541 
    542     /**
    543      * Enables wireframe rendering mode.
    544      *
    545      * <p>When in wireframe mode, {@link Mesh meshes} rendered in triangle mode
    546      * will not be solid, but instead, only the edges of the triangles
    547      * will be rendered.
    548      *
    549      * @param wireframe True to enable wireframe mode.
    550      */
    551     public void setWireframe(boolean wireframe) {
    552         applyWireFrame = true;
    553         this.wireframe = wireframe;
    554     }
    555 
    556     /**
    557      * Offsets the on-screen z-order of the material's polygons, to combat visual artefacts like
    558      * stitching, bleeding and z-fighting for overlapping polygons.
    559      * Factor and units are summed to produce the depth offset.
    560      * This offset is applied in screen space,
    561      * typically with positive Z pointing into the screen.
    562      * Typical values are (1.0f, 1.0f) or (-1.0f, -1.0f)
    563      *
    564      * @see <a href="http://www.opengl.org/resources/faq/technical/polygonoffset.htm" rel="nofollow">http://www.opengl.org/resources/faq/technical/polygonoffset.htm</a>
    565      * @param factor scales the maximum Z slope, with respect to X or Y of the polygon
    566      * @param units scales the minimum resolvable depth buffer value
    567      **/
    568     public void setPolyOffset(float factor, float units) {
    569         applyPolyOffset = true;
    570         offsetEnabled = true;
    571         offsetFactor = factor;
    572         offsetUnits = units;
    573     }
    574 
    575     /**
    576      * Enable stencil testing.
    577      *
    578      * <p>Stencil testing can be used to filter pixels according to the stencil
    579      * buffer. Objects can be rendered with some stencil operation to manipulate
    580      * the values in the stencil buffer, then, other objects can be rendered
    581      * to test against the values written previously.
    582      *
    583      * @param enabled Set to true to enable stencil functionality. If false
    584      * all other parameters are ignored.
    585      *
    586      * @param _frontStencilStencilFailOperation Sets the operation to occur when
    587      * a front-facing triangle fails the front stencil function.
    588      * @param _frontStencilDepthFailOperation Sets the operation to occur when
    589      * a front-facing triangle fails the depth test.
    590      * @param _frontStencilDepthPassOperation Set the operation to occur when
    591      * a front-facing triangle passes the depth test.
    592      * @param _backStencilStencilFailOperation Set the operation to occur when
    593      * a back-facing triangle fails the back stencil function.
    594      * @param _backStencilDepthFailOperation Set the operation to occur when
    595      * a back-facing triangle fails the depth test.
    596      * @param _backStencilDepthPassOperation Set the operation to occur when
    597      * a back-facing triangle passes the depth test.
    598      * @param _frontStencilFunction Set the test function for front-facing triangles.
    599      * @param _backStencilFunction Set the test function for back-facing triangles.
    600      */
    601     public void setStencil(boolean enabled,
    602             StencilOperation _frontStencilStencilFailOperation,
    603             StencilOperation _frontStencilDepthFailOperation,
    604             StencilOperation _frontStencilDepthPassOperation,
    605             StencilOperation _backStencilStencilFailOperation,
    606             StencilOperation _backStencilDepthFailOperation,
    607             StencilOperation _backStencilDepthPassOperation,
    608             TestFunction _frontStencilFunction,
    609             TestFunction _backStencilFunction) {
    610 
    611         stencilTest = enabled;
    612         applyStencilTest = true;
    613         this.frontStencilStencilFailOperation = _frontStencilStencilFailOperation;
    614         this.frontStencilDepthFailOperation = _frontStencilDepthFailOperation;
    615         this.frontStencilDepthPassOperation = _frontStencilDepthPassOperation;
    616         this.backStencilStencilFailOperation = _backStencilStencilFailOperation;
    617         this.backStencilDepthFailOperation = _backStencilDepthFailOperation;
    618         this.backStencilDepthPassOperation = _backStencilDepthPassOperation;
    619         this.frontStencilFunction = _frontStencilFunction;
    620         this.backStencilFunction = _backStencilFunction;
    621     }
    622 
    623     /**
    624      * Check if stencil test is enabled.
    625      *
    626      * @return True if stencil test is enabled.
    627      */
    628     public boolean isStencilTest() {
    629         return stencilTest;
    630     }
    631 
    632     /**
    633      * Retrieve the front stencil fail operation.
    634      *
    635      * @return the front stencil fail operation.
    636      *
    637      * @see RenderState#setStencil(boolean,
    638      * com.jme3.material.RenderState.StencilOperation,
    639      * com.jme3.material.RenderState.StencilOperation,
    640      * com.jme3.material.RenderState.StencilOperation,
    641      * com.jme3.material.RenderState.StencilOperation,
    642      * com.jme3.material.RenderState.StencilOperation,
    643      * com.jme3.material.RenderState.StencilOperation,
    644      * com.jme3.material.RenderState.TestFunction,
    645      * com.jme3.material.RenderState.TestFunction)
    646      */
    647     public StencilOperation getFrontStencilStencilFailOperation() {
    648         return frontStencilStencilFailOperation;
    649     }
    650 
    651     /**
    652      * Retrieve the front depth test fail operation.
    653      *
    654      * @return the front depth test fail operation.
    655      *
    656      * @see RenderState#setStencil(boolean,
    657      * com.jme3.material.RenderState.StencilOperation,
    658      * com.jme3.material.RenderState.StencilOperation,
    659      * com.jme3.material.RenderState.StencilOperation,
    660      * com.jme3.material.RenderState.StencilOperation,
    661      * com.jme3.material.RenderState.StencilOperation,
    662      * com.jme3.material.RenderState.StencilOperation,
    663      * com.jme3.material.RenderState.TestFunction,
    664      * com.jme3.material.RenderState.TestFunction)
    665      */
    666     public StencilOperation getFrontStencilDepthFailOperation() {
    667         return frontStencilDepthFailOperation;
    668     }
    669 
    670     /**
    671      * Retrieve the front depth test pass operation.
    672      *
    673      * @return the front depth test pass operation.
    674      *
    675      * @see RenderState#setStencil(boolean,
    676      * com.jme3.material.RenderState.StencilOperation,
    677      * com.jme3.material.RenderState.StencilOperation,
    678      * com.jme3.material.RenderState.StencilOperation,
    679      * com.jme3.material.RenderState.StencilOperation,
    680      * com.jme3.material.RenderState.StencilOperation,
    681      * com.jme3.material.RenderState.StencilOperation,
    682      * com.jme3.material.RenderState.TestFunction,
    683      * com.jme3.material.RenderState.TestFunction)
    684      */
    685     public StencilOperation getFrontStencilDepthPassOperation() {
    686         return frontStencilDepthPassOperation;
    687     }
    688 
    689     /**
    690      * Retrieve the back stencil fail operation.
    691      *
    692      * @return the back stencil fail operation.
    693      *
    694      * @see RenderState#setStencil(boolean,
    695      * com.jme3.material.RenderState.StencilOperation,
    696      * com.jme3.material.RenderState.StencilOperation,
    697      * com.jme3.material.RenderState.StencilOperation,
    698      * com.jme3.material.RenderState.StencilOperation,
    699      * com.jme3.material.RenderState.StencilOperation,
    700      * com.jme3.material.RenderState.StencilOperation,
    701      * com.jme3.material.RenderState.TestFunction,
    702      * com.jme3.material.RenderState.TestFunction)
    703      */
    704     public StencilOperation getBackStencilStencilFailOperation() {
    705         return backStencilStencilFailOperation;
    706     }
    707 
    708     /**
    709      * Retrieve the back depth test fail operation.
    710      *
    711      * @return the back depth test fail operation.
    712      *
    713      * @see RenderState#setStencil(boolean,
    714      * com.jme3.material.RenderState.StencilOperation,
    715      * com.jme3.material.RenderState.StencilOperation,
    716      * com.jme3.material.RenderState.StencilOperation,
    717      * com.jme3.material.RenderState.StencilOperation,
    718      * com.jme3.material.RenderState.StencilOperation,
    719      * com.jme3.material.RenderState.StencilOperation,
    720      * com.jme3.material.RenderState.TestFunction,
    721      * com.jme3.material.RenderState.TestFunction)
    722      */
    723     public StencilOperation getBackStencilDepthFailOperation() {
    724         return backStencilDepthFailOperation;
    725     }
    726 
    727     /**
    728      * Retrieve the back depth test pass operation.
    729      *
    730      * @return the back depth test pass operation.
    731      *
    732      * @see RenderState#setStencil(boolean,
    733      * com.jme3.material.RenderState.StencilOperation,
    734      * com.jme3.material.RenderState.StencilOperation,
    735      * com.jme3.material.RenderState.StencilOperation,
    736      * com.jme3.material.RenderState.StencilOperation,
    737      * com.jme3.material.RenderState.StencilOperation,
    738      * com.jme3.material.RenderState.StencilOperation,
    739      * com.jme3.material.RenderState.TestFunction,
    740      * com.jme3.material.RenderState.TestFunction)
    741      */
    742     public StencilOperation getBackStencilDepthPassOperation() {
    743         return backStencilDepthPassOperation;
    744     }
    745 
    746     /**
    747      * Retrieve the front stencil function.
    748      *
    749      * @return the front stencil function.
    750      *
    751      * @see RenderState#setStencil(boolean,
    752      * com.jme3.material.RenderState.StencilOperation,
    753      * com.jme3.material.RenderState.StencilOperation,
    754      * com.jme3.material.RenderState.StencilOperation,
    755      * com.jme3.material.RenderState.StencilOperation,
    756      * com.jme3.material.RenderState.StencilOperation,
    757      * com.jme3.material.RenderState.StencilOperation,
    758      * com.jme3.material.RenderState.TestFunction,
    759      * com.jme3.material.RenderState.TestFunction)
    760      */
    761     public TestFunction getFrontStencilFunction() {
    762         return frontStencilFunction;
    763     }
    764 
    765     /**
    766      * Retrieve the back stencil function.
    767      *
    768      * @return the back stencil function.
    769      *
    770      * @see RenderState#setStencil(boolean,
    771      * com.jme3.material.RenderState.StencilOperation,
    772      * com.jme3.material.RenderState.StencilOperation,
    773      * com.jme3.material.RenderState.StencilOperation,
    774      * com.jme3.material.RenderState.StencilOperation,
    775      * com.jme3.material.RenderState.StencilOperation,
    776      * com.jme3.material.RenderState.StencilOperation,
    777      * com.jme3.material.RenderState.TestFunction,
    778      * com.jme3.material.RenderState.TestFunction)
    779      */
    780     public TestFunction getBackStencilFunction() {
    781         return backStencilFunction;
    782     }
    783 
    784     /**
    785      * Retrieve the blend mode.
    786      *
    787      * @return the blend mode.
    788      */
    789     public BlendMode getBlendMode() {
    790         return blendMode;
    791     }
    792 
    793     /**
    794      * Check if point sprite mode is enabled
    795      *
    796      * @return True if point sprite mode is enabled.
    797      *
    798      * @see RenderState#setPointSprite(boolean)
    799      */
    800     public boolean isPointSprite() {
    801         return pointSprite;
    802     }
    803 
    804     /**
    805      * Check if alpha test is enabled.
    806      *
    807      * @return True if alpha test is enabled.
    808      *
    809      * @see RenderState#setAlphaTest(boolean)
    810      */
    811     public boolean isAlphaTest() {
    812         return alphaTest;
    813     }
    814 
    815     /**
    816      * Retrieve the face cull mode.
    817      *
    818      * @return the face cull mode.
    819      *
    820      * @see RenderState#setFaceCullMode(com.jme3.material.RenderState.FaceCullMode)
    821      */
    822     public FaceCullMode getFaceCullMode() {
    823         return cullMode;
    824     }
    825 
    826     /**
    827      * Check if depth test is enabled.
    828      *
    829      * @return True if depth test is enabled.
    830      *
    831      * @see RenderState#setDepthTest(boolean)
    832      */
    833     public boolean isDepthTest() {
    834         return depthTest;
    835     }
    836 
    837     /**
    838      * Check if depth write is enabled.
    839      *
    840      * @return True if depth write is enabled.
    841      *
    842      * @see RenderState#setDepthWrite(boolean)
    843      */
    844     public boolean isDepthWrite() {
    845         return depthWrite;
    846     }
    847 
    848     /**
    849      * Check if wireframe mode is enabled.
    850      *
    851      * @return True if wireframe mode is enabled.
    852      *
    853      * @see RenderState#setWireframe(boolean)
    854      */
    855     public boolean isWireframe() {
    856         return wireframe;
    857     }
    858 
    859     /**
    860      * Check if color writing is enabled.
    861      *
    862      * @return True if color writing is enabled.
    863      *
    864      * @see RenderState#setColorWrite(boolean)
    865      */
    866     public boolean isColorWrite() {
    867         return colorWrite;
    868     }
    869 
    870     /**
    871      * Retrieve the poly offset factor value.
    872      *
    873      * @return the poly offset factor value.
    874      *
    875      * @see RenderState#setPolyOffset(float, float)
    876      */
    877     public float getPolyOffsetFactor() {
    878         return offsetFactor;
    879     }
    880 
    881     /**
    882      * Retrieve the poly offset units value.
    883      *
    884      * @return the poly offset units value.
    885      *
    886      * @see RenderState#setPolyOffset(float, float)
    887      */
    888     public float getPolyOffsetUnits() {
    889         return offsetUnits;
    890     }
    891 
    892     /**
    893      * Check if polygon offset is enabled.
    894      *
    895      * @return True if polygon offset is enabled.
    896      *
    897      * @see RenderState#setPolyOffset(float, float)
    898      */
    899     public boolean isPolyOffset() {
    900         return offsetEnabled;
    901     }
    902 
    903     /**
    904      * Retrieve the alpha falloff value.
    905      *
    906      * @return the alpha falloff value.
    907      *
    908      * @see RenderState#setAlphaFallOff(float)
    909      */
    910     public float getAlphaFallOff() {
    911         return alphaFallOff;
    912     }
    913 
    914     public boolean isApplyAlphaFallOff() {
    915         return applyAlphaFallOff;
    916     }
    917 
    918     public boolean isApplyAlphaTest() {
    919         return applyAlphaTest;
    920     }
    921 
    922     public boolean isApplyBlendMode() {
    923         return applyBlendMode;
    924     }
    925 
    926     public boolean isApplyColorWrite() {
    927         return applyColorWrite;
    928     }
    929 
    930     public boolean isApplyCullMode() {
    931         return applyCullMode;
    932     }
    933 
    934     public boolean isApplyDepthTest() {
    935         return applyDepthTest;
    936     }
    937 
    938     public boolean isApplyDepthWrite() {
    939         return applyDepthWrite;
    940     }
    941 
    942     public boolean isApplyPointSprite() {
    943         return applyPointSprite;
    944     }
    945 
    946     public boolean isApplyPolyOffset() {
    947         return applyPolyOffset;
    948     }
    949 
    950     public boolean isApplyWireFrame() {
    951         return applyWireFrame;
    952     }
    953 
    954     /**
    955      * Merges <code>this</code> state and <code>additionalState</code> into
    956      * the parameter <code>state</code> based on a specific criteria.
    957      *
    958      * <p>The criteria for this merge is the following:<br/>
    959      * For every given property, such as alpha test or depth write, check
    960      * if it was modified from the original in the <code>additionalState</code>
    961      * if it was modified, then copy the property from the <code>additionalState</code>
    962      * into the parameter <code>state</code>, otherwise, copy the property from <code>this</code>
    963      * into the parameter <code>state</code>. If <code>additionalState</code>
    964      * is <code>null</code>, then no modifications are made and <code>this</code> is returned,
    965      * otherwise, the parameter <code>state</code> is returned with the result
    966      * of the merge.
    967      *
    968      * @param additionalState The <code>additionalState</code>, from which data is taken only
    969      * if it was modified by the user.
    970      * @param state Contains output of the method if <code>additionalState</code>
    971      * is not null.
    972      * @return <code>state</code> if <code>additionalState</code> is non-null,
    973      * otherwise returns <code>this</code>
    974      */
    975     public RenderState copyMergedTo(RenderState additionalState, RenderState state) {
    976         if (additionalState == null) {
    977             return this;
    978         }
    979 
    980         if (additionalState.applyPointSprite) {
    981             state.pointSprite = additionalState.pointSprite;
    982         } else {
    983             state.pointSprite = pointSprite;
    984         }
    985         if (additionalState.applyWireFrame) {
    986             state.wireframe = additionalState.wireframe;
    987         } else {
    988             state.wireframe = wireframe;
    989         }
    990 
    991         if (additionalState.applyCullMode) {
    992             state.cullMode = additionalState.cullMode;
    993         } else {
    994             state.cullMode = cullMode;
    995         }
    996         if (additionalState.applyDepthWrite) {
    997             state.depthWrite = additionalState.depthWrite;
    998         } else {
    999             state.depthWrite = depthWrite;
   1000         }
   1001         if (additionalState.applyDepthTest) {
   1002             state.depthTest = additionalState.depthTest;
   1003         } else {
   1004             state.depthTest = depthTest;
   1005         }
   1006         if (additionalState.applyColorWrite) {
   1007             state.colorWrite = additionalState.colorWrite;
   1008         } else {
   1009             state.colorWrite = colorWrite;
   1010         }
   1011         if (additionalState.applyBlendMode) {
   1012             state.blendMode = additionalState.blendMode;
   1013         } else {
   1014             state.blendMode = blendMode;
   1015         }
   1016         if (additionalState.applyAlphaTest) {
   1017             state.alphaTest = additionalState.alphaTest;
   1018         } else {
   1019             state.alphaTest = alphaTest;
   1020         }
   1021 
   1022         if (additionalState.applyAlphaFallOff) {
   1023             state.alphaFallOff = additionalState.alphaFallOff;
   1024         } else {
   1025             state.alphaFallOff = alphaFallOff;
   1026         }
   1027         if (additionalState.applyPolyOffset) {
   1028             state.offsetEnabled = additionalState.offsetEnabled;
   1029             state.offsetFactor = additionalState.offsetFactor;
   1030             state.offsetUnits = additionalState.offsetUnits;
   1031         } else {
   1032             state.offsetEnabled = offsetEnabled;
   1033             state.offsetFactor = offsetFactor;
   1034             state.offsetUnits = offsetUnits;
   1035         }
   1036         if (additionalState.applyStencilTest){
   1037             state.stencilTest = additionalState.stencilTest;
   1038 
   1039             state.frontStencilStencilFailOperation = additionalState.frontStencilStencilFailOperation;
   1040             state.frontStencilDepthFailOperation   = additionalState.frontStencilDepthFailOperation;
   1041             state.frontStencilDepthPassOperation   = additionalState.frontStencilDepthPassOperation;
   1042 
   1043             state.backStencilStencilFailOperation = additionalState.backStencilStencilFailOperation;
   1044             state.backStencilDepthFailOperation   = additionalState.backStencilDepthFailOperation;
   1045             state.backStencilDepthPassOperation   = additionalState.backStencilDepthPassOperation;
   1046 
   1047             state.frontStencilFunction = additionalState.frontStencilFunction;
   1048             state.backStencilFunction = additionalState.backStencilFunction;
   1049         }else{
   1050             state.stencilTest = stencilTest;
   1051 
   1052             state.frontStencilStencilFailOperation = frontStencilStencilFailOperation;
   1053             state.frontStencilDepthFailOperation   = frontStencilDepthFailOperation;
   1054             state.frontStencilDepthPassOperation   = frontStencilDepthPassOperation;
   1055 
   1056             state.backStencilStencilFailOperation = backStencilStencilFailOperation;
   1057             state.backStencilDepthFailOperation   = backStencilDepthFailOperation;
   1058             state.backStencilDepthPassOperation   = backStencilDepthPassOperation;
   1059 
   1060             state.frontStencilFunction = frontStencilFunction;
   1061             state.backStencilFunction = backStencilFunction;
   1062         }
   1063         return state;
   1064     }
   1065 
   1066     @Override
   1067     public String toString() {
   1068         return "RenderState[\n" + "pointSprite=" + pointSprite + "\napplyPointSprite=" + applyPointSprite + "\nwireframe=" + wireframe + "\napplyWireFrame=" + applyWireFrame + "\ncullMode=" + cullMode + "\napplyCullMode=" + applyCullMode + "\ndepthWrite=" + depthWrite + "\napplyDepthWrite=" + applyDepthWrite + "\ndepthTest=" + depthTest + "\napplyDepthTest=" + applyDepthTest + "\ncolorWrite=" + colorWrite + "\napplyColorWrite=" + applyColorWrite + "\nblendMode=" + blendMode + "\napplyBlendMode=" + applyBlendMode + "\nalphaTest=" + alphaTest + "\napplyAlphaTest=" + applyAlphaTest + "\nalphaFallOff=" + alphaFallOff + "\napplyAlphaFallOff=" + applyAlphaFallOff + "\noffsetEnabled=" + offsetEnabled + "\napplyPolyOffset=" + applyPolyOffset + "\noffsetFactor=" + offsetFactor + "\noffsetUnits=" + offsetUnits + "\n]";
   1069     }
   1070 }
   1071