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