Package com.ardor3d.renderer.state

Source Code of com.ardor3d.renderer.state.StencilState

/**
* Copyright (c) 2008-2012 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/

package com.ardor3d.renderer.state;

import java.io.IOException;

import com.ardor3d.renderer.ContextCapabilities;
import com.ardor3d.renderer.state.record.StateRecord;
import com.ardor3d.renderer.state.record.StencilStateRecord;
import com.ardor3d.util.export.InputCapsule;
import com.ardor3d.util.export.OutputCapsule;

/**
* The StencilState RenderState allows the user to set the attributes of the stencil buffer of the renderer. The
* Stenciling is similar to Z-Buffering in that it allows enabling and disabling drawing on a per pixel basis. You can
* use the stencil plane to mask out portions of the rendering to create special effects, such as outlining or planar
* shadows. Our stencil state supports setting operations for front and back facing polygons separately. If your card
* does not support setting faces independently, the front face values will be used for both sides.
*/
public class StencilState extends RenderState {

    public enum StencilFunction {
        /** A stencil function that never passes. */
        Never,
        /** A stencil function that passes if (ref & mask) < (stencil & mask). */
        LessThan,
        /** A stencil function that passes if (ref & mask) <= (stencil & mask). */
        LessThanOrEqualTo,
        /** A stencil function that passes if (ref & mask) > (stencil & mask). */
        GreaterThan,
        /** A stencil function that passes if (ref & mask) >= (stencil & mask). */
        GreaterThanOrEqualTo,
        /** A stencil function that passes if (ref & mask) == (stencil & mask). */
        EqualTo,
        /** A stencil function that passes if (ref & mask) != (stencil & mask). */
        NotEqualTo,
        /** A stencil function that always passes. (Default) */
        Always;
    }

    public enum StencilOperation {
        /** A stencil function result that keeps the current value. */
        Keep,
        /** A stencil function result that sets the stencil buffer value to 0. */
        Zero,
        /**
         * A stencil function result that sets the stencil buffer value to ref, as specified by stencil function.
         */
        Replace,
        /**
         * A stencil function result that increments the current stencil buffer value.
         */
        Increment,
        /**
         * A stencil function result that decrements the current stencil buffer value.
         */
        Decrement,
        /**
         * A stencil function result that increments the current stencil buffer value and wraps around to the lowest
         * stencil value if it reaches the max. (if the renderer does not support stencil wrap, we'll fall back to
         * Increment)
         */
        IncrementWrap,
        /**
         * A stencil function result that decrements the current stencil buffer and wraps around to the highest stencil
         * value if it reaches the min. value. (if the renderer does not support stencil wrap, we'll fall back to
         * Decrement)
         */
        DecrementWrap,
        /**
         * A stencil function result that bitwise inverts the current stencil buffer value.
         */
        Invert;
    }

    private boolean _useTwoSided = false;

    // Front
    private StencilFunction _stencilFunctionFront = StencilFunction.Always;

    private int _stencilReferenceFront = 0;
    private int _stencilFuncMaskFront = ~0;
    private int _stencilWriteMaskFront = ~0;

    private StencilOperation _stencilOpFailFront = StencilOperation.Keep;
    private StencilOperation _stencilOpZFailFront = StencilOperation.Keep;
    private StencilOperation _stencilOpZPassFront = StencilOperation.Keep;

    // Back
    private StencilFunction _stencilFunctionBack = StencilFunction.Always;

    private int _stencilReferenceBack = 0;
    private int _stencilFuncMaskBack = ~0;
    private int _stencilWriteMaskBack = ~0;

    private StencilOperation _stencilOpFailBack = StencilOperation.Keep;
    private StencilOperation _stencilOpZFailBack = StencilOperation.Keep;
    private StencilOperation _stencilOpZPassBack = StencilOperation.Keep;

    @Override
    public StateType getType() {
        return StateType.Stencil;
    }

    /**
     * Sets the function that defines if a stencil test passes or not for both faces.
     *
     * @param function
     *            The new stencil function for both faces.
     * @throws IllegalArgumentException
     *             if function is null
     */
    public void setStencilFunction(final StencilFunction function) {
        setStencilFunctionFront(function);
        setStencilFunctionBack(function);
    }

    /**
     * Sets the stencil reference to be used during the stencil function for both faces.
     *
     * @param reference
     *            The new stencil reference for both faces.
     */
    public void setStencilReference(final int reference) {
        setStencilReferenceFront(reference);
        setStencilReferenceBack(reference);
    }

    /**
     * Convienence method for setting both types of stencil masks at once for both faces.
     *
     * @param mask
     *            The new stencil write and func mask for both faces.
     */
    public void setStencilMask(final int mask) {
        setStencilMaskFront(mask);
        setStencilMaskBack(mask);
    }

    /**
     * Controls which stencil bitplanes are written for both faces.
     *
     * @param mask
     *            The new stencil write mask for both faces.
     */
    public void setStencilWriteMask(final int mask) {
        setStencilWriteMaskFront(mask);
        setStencilWriteMaskBack(mask);
    }

    /**
     * Sets the stencil mask to be used during stencil functions for both faces.
     *
     * @param mask
     *            The new stencil function mask for both faces.
     */
    public void setStencilFuncMask(final int mask) {
        setStencilFuncMaskFront(mask);
        setStencilFuncMaskBack(mask);
    }

    /**
     * Specifies the aciton to take when the stencil test fails for both faces.
     *
     * @param operation
     *            The new stencil operation for both faces.
     * @throws IllegalArgumentException
     *             if operation is null
     */
    public void setStencilOpFail(final StencilOperation operation) {
        setStencilOpFailFront(operation);
        setStencilOpFailBack(operation);
    }

    /**
     * Specifies stencil action when the stencil test passes, but the depth test fails for both faces.
     *
     * @param operation
     *            The Z test operation to set for both faces.
     * @throws IllegalArgumentException
     *             if operation is null
     */
    public void setStencilOpZFail(final StencilOperation operation) {
        setStencilOpZFailFront(operation);
        setStencilOpZFailBack(operation);
    }

    /**
     * Specifies stencil action when both the stencil test and the depth test pass, or when the stencil test passes and
     * either there is no depth buffer or depth testing is not enabled.
     *
     * @param operation
     *            The new Z test pass operation to set for both faces.
     * @throws IllegalArgumentException
     *             if operation is null
     */
    public void setStencilOpZPass(final StencilOperation operation) {
        setStencilOpZPassFront(operation);
        setStencilOpZPassBack(operation);
    }

    /**
     * Sets the function that defines if a stencil test passes or not for front faces.
     *
     * @param function
     *            The new stencil function for front faces.
     * @throws IllegalArgumentException
     *             if function is null
     */
    public void setStencilFunctionFront(final StencilFunction function) {
        if (function == null) {
            throw new IllegalArgumentException("function can not be null.");
        }
        _stencilFunctionFront = function;
        setNeedsRefresh(true);
    }

    /**
     * @return The current stencil function for front faces. Default is StencilFunction.Always
     */
    public StencilFunction getStencilFunctionFront() {
        return _stencilFunctionFront;
    }

    /**
     * Sets the stencil reference to be used during the stencil function for front faces.
     *
     * @param reference
     *            The new stencil reference for front faces.
     */
    public void setStencilReferenceFront(final int reference) {
        _stencilReferenceFront = reference;
        setNeedsRefresh(true);
    }

    /**
     * @return The current stencil reference for front faces. Default is 0
     */
    public int getStencilReferenceFront() {
        return _stencilReferenceFront;
    }

    /**
     * Convienence method for setting both types of stencil masks at once for front faces.
     *
     * @param mask
     *            The new stencil write and func mask for front faces.
     */
    public void setStencilMaskFront(final int mask) {
        setStencilWriteMaskFront(mask);
        setStencilFuncMaskFront(mask);
    }

    /**
     * Controls which stencil bitplanes are written for front faces.
     *
     * @param mask
     *            The new stencil write mask for front faces.
     */
    public void setStencilWriteMaskFront(final int mask) {
        _stencilWriteMaskFront = mask;
        setNeedsRefresh(true);
    }

    /**
     * @return The current stencil write mask for front faces. Default is all 1's (~0)
     */
    public int getStencilWriteMaskFront() {
        return _stencilWriteMaskFront;
    }

    /**
     * Sets the stencil mask to be used during stencil functions for front faces.
     *
     * @param mask
     *            The new stencil function mask for front faces.
     */
    public void setStencilFuncMaskFront(final int mask) {
        _stencilFuncMaskFront = mask;
        setNeedsRefresh(true);
    }

    /**
     * @return The current stencil function mask for front faces. Default is all 1's (~0)
     */
    public int getStencilFuncMaskFront() {
        return _stencilFuncMaskFront;
    }

    /**
     * Specifies the aciton to take when the stencil test fails for front faces.
     *
     * @param operation
     *            The new stencil operation for front faces.
     * @throws IllegalArgumentException
     *             if operation is null
     */
    public void setStencilOpFailFront(final StencilOperation operation) {
        if (operation == null) {
            throw new IllegalArgumentException("operation can not be null.");
        }
        _stencilOpFailFront = operation;
        setNeedsRefresh(true);
    }

    /**
     * @return The current stencil operation for front faces. Default is StencilOperation.Keep
     */
    public StencilOperation getStencilOpFailFront() {
        return _stencilOpFailFront;
    }

    /**
     * Specifies stencil action when the stencil test passes, but the depth test fails for front faces.
     *
     * @param operation
     *            The Z test operation to set for front faces.
     * @throws IllegalArgumentException
     *             if operation is null
     */
    public void setStencilOpZFailFront(final StencilOperation operation) {
        if (operation == null) {
            throw new IllegalArgumentException("operation can not be null.");
        }
        _stencilOpZFailFront = operation;
        setNeedsRefresh(true);
    }

    /**
     * @return The current Z op fail function for front faces. Default is StencilOperation.Keep
     */
    public StencilOperation getStencilOpZFailFront() {
        return _stencilOpZFailFront;
    }

    /**
     * Specifies stencil action when both the stencil test and the depth test pass, or when the stencil test passes and
     * either there is no depth buffer or depth testing is not enabled.
     *
     * @param operation
     *            The new Z test pass operation to set for front faces.
     * @throws IllegalArgumentException
     *             if operation is null
     */
    public void setStencilOpZPassFront(final StencilOperation operation) {
        if (operation == null) {
            throw new IllegalArgumentException("operation can not be null.");
        }
        _stencilOpZPassFront = operation;
        setNeedsRefresh(true);
    }

    /**
     * @return The current Z op pass function for front faces. Default is StencilOperation.Keep
     */
    public StencilOperation getStencilOpZPassFront() {
        return _stencilOpZPassFront;
    }

    /**
     * Sets the function that defines if a stencil test passes or not for back faces.
     *
     * @param function
     *            The new stencil function for back faces.
     * @throws IllegalArgumentException
     *             if function is null
     */
    public void setStencilFunctionBack(final StencilFunction function) {
        if (function == null) {
            throw new IllegalArgumentException("function can not be null.");
        }
        _stencilFunctionBack = function;
        setNeedsRefresh(true);
    }

    /**
     * @return The current stencil function for back faces. Default is StencilFunction.Always
     */
    public StencilFunction getStencilFunctionBack() {
        return _stencilFunctionBack;
    }

    /**
     * Sets the stencil reference to be used during the stencil function for back faces.
     *
     * @param reference
     *            The new stencil reference for back faces.
     */
    public void setStencilReferenceBack(final int reference) {
        _stencilReferenceBack = reference;
        setNeedsRefresh(true);
    }

    /**
     * @return The current stencil reference for back faces. Default is 0
     */
    public int getStencilReferenceBack() {
        return _stencilReferenceBack;
    }

    /**
     * Convienence method for setting both types of stencil masks at once for back faces.
     *
     * @param mask
     *            The new stencil write and func mask for back faces.
     */
    public void setStencilMaskBack(final int mask) {
        setStencilWriteMaskBack(mask);
        setStencilFuncMaskBack(mask);
    }

    /**
     * Controls which stencil bitplanes are written for back faces.
     *
     * @param mask
     *            The new stencil write mask for back faces.
     */
    public void setStencilWriteMaskBack(final int mask) {
        _stencilWriteMaskBack = mask;
        setNeedsRefresh(true);
    }

    /**
     * @return The current stencil write mask for back faces. Default is all 1's (~0)
     */
    public int getStencilWriteMaskBack() {
        return _stencilWriteMaskBack;
    }

    /**
     * Sets the stencil mask to be used during stencil functions for back faces.
     *
     * @param mask
     *            The new stencil function mask for back faces.
     */
    public void setStencilFuncMaskBack(final int mask) {
        _stencilFuncMaskBack = mask;
        setNeedsRefresh(true);
    }

    /**
     * @return The current stencil function mask for back faces. Default is all 1's (~0)
     */
    public int getStencilFuncMaskBack() {
        return _stencilFuncMaskBack;
    }

    /**
     * Specifies the aciton to take when the stencil test fails for back faces.
     *
     * @param operation
     *            The new stencil operation for back faces.
     * @throws IllegalArgumentException
     *             if operation is null
     */
    public void setStencilOpFailBack(final StencilOperation operation) {
        if (operation == null) {
            throw new IllegalArgumentException("operation can not be null.");
        }
        _stencilOpFailBack = operation;
        setNeedsRefresh(true);
    }

    /**
     * @return The current stencil operation for back faces. Default is StencilOperation.Keep
     */
    public StencilOperation getStencilOpFailBack() {
        return _stencilOpFailBack;
    }

    /**
     * Specifies stencil action when the stencil test passes, but the depth test fails.
     *
     * @param operation
     *            The Z test operation to set for back faces.
     * @throws IllegalArgumentException
     *             if operation is null
     */
    public void setStencilOpZFailBack(final StencilOperation operation) {
        if (operation == null) {
            throw new IllegalArgumentException("operation can not be null.");
        }
        _stencilOpZFailBack = operation;
        setNeedsRefresh(true);
    }

    /**
     * @return The current Z op fail function for back faces. Default is StencilOperation.Keep
     */
    public StencilOperation getStencilOpZFailBack() {
        return _stencilOpZFailBack;
    }

    /**
     * Specifies stencil action when both the stencil test and the depth test pass, or when the stencil test passes and
     * either there is no depth buffer or depth testing is not enabled.
     *
     * @param operation
     *            The new Z test pass operation to set for back faces.
     * @throws IllegalArgumentException
     *             if operation is null
     */
    public void setStencilOpZPassBack(final StencilOperation operation) {
        if (operation == null) {
            throw new IllegalArgumentException("operation can not be null.");
        }
        _stencilOpZPassBack = operation;
        setNeedsRefresh(true);
    }

    /**
     * @return The current Z op pass function for back faces. Default is StencilOperation.Keep
     */
    public StencilOperation getStencilOpZPassBack() {
        return _stencilOpZPassBack;
    }

    public boolean isUseTwoSided() {
        return _useTwoSided;
    }

    public void setUseTwoSided(final boolean useTwoSided) {
        _useTwoSided = useTwoSided;
    }

    @Override
    public void write(final OutputCapsule capsule) throws IOException {
        super.write(capsule);
        capsule.write(_useTwoSided, "useTwoSided", false);
        capsule.write(_stencilFunctionFront, "stencilFuncFront", StencilFunction.Always);
        capsule.write(_stencilReferenceFront, "stencilRefFront", 0);
        capsule.write(_stencilWriteMaskFront, "stencilWriteMaskFront", ~0);
        capsule.write(_stencilFuncMaskFront, "stencilFuncMaskFront", ~0);
        capsule.write(_stencilOpFailFront, "stencilOpFailFront", StencilOperation.Keep);
        capsule.write(_stencilOpZFailFront, "stencilOpZFailFront", StencilOperation.Keep);
        capsule.write(_stencilOpZPassFront, "stencilOpZPassFront", StencilOperation.Keep);

        capsule.write(_stencilFunctionBack, "stencilFuncBack", StencilFunction.Always);
        capsule.write(_stencilReferenceBack, "stencilRefBack", 0);
        capsule.write(_stencilWriteMaskBack, "stencilWriteMaskBack", ~0);
        capsule.write(_stencilFuncMaskBack, "stencilFuncMaskBack", ~0);
        capsule.write(_stencilOpFailBack, "stencilOpFailBack", StencilOperation.Keep);
        capsule.write(_stencilOpZFailBack, "stencilOpZFailBack", StencilOperation.Keep);
        capsule.write(_stencilOpZPassBack, "stencilOpZPassBack", StencilOperation.Keep);
    }

    @Override
    public void read(final InputCapsule capsule) throws IOException {
        super.read(capsule);
        _useTwoSided = capsule.readBoolean("useTwoSided", false);
        _stencilFunctionFront = capsule.readEnum("stencilFuncFront", StencilFunction.class, StencilFunction.Always);
        _stencilReferenceFront = capsule.readInt("stencilRefFront", 0);
        _stencilWriteMaskFront = capsule.readInt("stencilWriteMaskFront", ~0);
        _stencilFuncMaskFront = capsule.readInt("stencilFuncMaskFront", ~0);
        _stencilOpFailFront = capsule.readEnum("stencilOpFailFront", StencilOperation.class, StencilOperation.Keep);
        _stencilOpZFailFront = capsule.readEnum("stencilOpZFailFront", StencilOperation.class, StencilOperation.Keep);
        _stencilOpZPassFront = capsule.readEnum("stencilOpZPassFront", StencilOperation.class, StencilOperation.Keep);

        _stencilFunctionBack = capsule.readEnum("stencilFuncBack", StencilFunction.class, StencilFunction.Always);
        _stencilReferenceBack = capsule.readInt("stencilRefBack", 0);
        _stencilWriteMaskBack = capsule.readInt("stencilWriteMaskBack", ~0);
        _stencilFuncMaskBack = capsule.readInt("stencilFuncMaskBack", ~0);
        _stencilOpFailBack = capsule.readEnum("stencilOpFailBack", StencilOperation.class, StencilOperation.Keep);
        _stencilOpZFailBack = capsule.readEnum("stencilOpZFailBack", StencilOperation.class, StencilOperation.Keep);
        _stencilOpZPassBack = capsule.readEnum("stencilOpZPassBack", StencilOperation.class, StencilOperation.Keep);
    }

    @Override
    public StateRecord createStateRecord(final ContextCapabilities caps) {
        return new StencilStateRecord();
    }

}
TOP

Related Classes of com.ardor3d.renderer.state.StencilState

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.