Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

package com.gebauz.bauzoid.graphics.renderstates;

import com.gebauz.bauzoid.app.BauzoidException;
import com.gebauz.bauzoid.math.Matrix4;

/** RenderStates
 * Manage render states, tracking changes, supporting locking, and applying state switches only if necessary.
 * Usage example:
 *    renderStates.blending.setBlendingMode(BlendingStates.BlendingMode.MULTIPLY);
 *    // ... set other render states
 *    renderStates.activate();
 *    // ...render object...
 *    renderStates.deactivate();
 *
 * All Render State Objects have three kinds of internal values: target, current, and default.
 *
 * Target values are those set by the user - those are the states the user wishes to set.
 *
 * Current values are those that the system is tracking, the current state. Each render state
 * compares the target with the current value and only performs a state change when they differ
 * to prevent unnecessary state changes.
 *
 * Default values are the base values that are set initially or when calling reset.
 *
 */

public class RenderStates
{
        public static final int NUM_TEXTURE_STAGES = 2;
        public static final int MAX_VERTEX_BUFFER_ID = 8;
       
        public BlendingStates blending = new BlendingStates(this);
        public CullingStates culling = new CullingStates(this);
        public DepthTestStates depthTest = new DepthTestStates(this);
        public ScissorStates scissor = new ScissorStates(this);
       
        private TextureStage[] mTextureStages = new TextureStage[NUM_TEXTURE_STAGES];
        private boolean mLocked = false;
       
        public static final int MATRIX_STACK_SIZE = 16;
       
        //public Matrix4 modelViewProjection;
        public Matrix4 model = Matrix4.createIdentity();
        public Matrix4 view = Matrix4.createIdentity();
        public Matrix4 projection = Matrix4.createIdentity();
       
        private Matrix4[] mModelStack = new Matrix4[MATRIX_STACK_SIZE];
        private Matrix4[] mViewStack = new Matrix4[MATRIX_STACK_SIZE];
        private Matrix4[] mProjectionStack = new Matrix4[MATRIX_STACK_SIZE];
       
        private int mModelStackCurrentIndex = 0;
        private int mViewStackCurrentIndex = 0;
        private int mProjectionStackCurrentIndex = 0;
       
        /** Constructor. */
        public RenderStates()
        {
                for (int i = 0; i < NUM_TEXTURE_STAGES; i++)
                {
                        mTextureStages[i] = new TextureStage(this, i);
                }
               
                for (int i = 0; i < MATRIX_STACK_SIZE; i++)
                {
                        mModelStack[i] = Matrix4.createIdentity();
                        mViewStack[i] = Matrix4.createIdentity();
                        mProjectionStack[i] = Matrix4.createIdentity();
                }
        }
       
        /** Initialize render states. */
        public void initialize() throws BauzoidException
        {
                blending.initialize();
                culling.initialize();
                depthTest.initialize();
                scissor.initialize();
               
                for (int i = 0; i < NUM_TEXTURE_STAGES; i++)
                {
                        mTextureStages[i].initialize();
                }
        }
       
        /** Activate renderstates - calls activate(false). */
        public void activate()
        {
                activate(false);
        }
       
        /** Activate render states with force parameter. */
        public void activate(boolean force)
        {
                blending.activate(force);
                culling.activate(force);
                depthTest.activate(force);
                scissor.activate(force);
        }
       
        /** Reset to default values. */
        public void reset()
        {
                blending.reset();
                culling.reset();
                depthTest.reset();
                scissor.reset();
        }
       
        /** Deactivate render states. */
        public void deactivate()
        {
                reset();
                activate(false);
        }
       
        /** Check if the renderstates are locked. */
        public boolean isLocked()
        {
                return mLocked;
        }
       
        /** Lock renderstates. */
        public void lock(boolean lock)
        {
                mLocked = lock;
        }
       
        /** Get a texture stage. */
        public final TextureStage getTextureStage(int index)
        {
                return mTextureStages[index];
        }
       
        /** Multiply matrices and return the full model-view-projection matrix. */
        public final Matrix4 getModelViewProjection()
        {
                Matrix4 mvpMatrix = Matrix4.multiply(model, view);
                mvpMatrix = Matrix4.multiply(mvpMatrix, projection);
                return mvpMatrix;
        }
       
        public final void getModelViewProjection(Matrix4 target)
        {
                Matrix4.multiply(target, model, view);
                Matrix4.multiply(target, target, projection);
        }
       
        /** Push current model matrix to stack. */
        public final void pushModelMatrix()
        {
                if (mModelStackCurrentIndex >= MATRIX_STACK_SIZE)
                        return;                
               
                // Create copy so that calling code can work on a different matrix without affecting anything
                mModelStack[mModelStackCurrentIndex].copyFrom(model);
                mModelStackCurrentIndex++;
        }
       
        /** Pop current model matrix from stack. */
        public final void popModelMatrix()
        {
                if (mModelStackCurrentIndex <= 0)
                        return;
               
                mModelStackCurrentIndex--;
                model.copyFrom(mModelStack[mModelStackCurrentIndex]);          
        }
       
        /** Push current model matrix to stack. */
        public final void pushViewMatrix()
        {
                if (mViewStackCurrentIndex >= MATRIX_STACK_SIZE)
                        return;                
               
                mViewStack[mViewStackCurrentIndex].copyFrom(view);
                mViewStackCurrentIndex++;
        }
       
        /** Pop current model matrix from stack. */
        public final void popViewMatrix()
        {
                if (mViewStackCurrentIndex <= 0)
                        return;
               
                mViewStackCurrentIndex--;
                view.copyFrom(mViewStack[mViewStackCurrentIndex]);             
        }
       
        /** Push current model matrix to stack. */
        public final void pushProjectionMatrix()
        {
                if (mProjectionStackCurrentIndex >= MATRIX_STACK_SIZE)
                        return;                
               
                mProjectionStack[mProjectionStackCurrentIndex].copyFrom(projection);
                mProjectionStackCurrentIndex++;
        }
       
        /** Pop current model matrix from stack. */
        public final void popProjectionMatrix()
        {
                if (mProjectionStackCurrentIndex <= 0)
                        return;
               
                mProjectionStackCurrentIndex--;
                projection.copyFrom(mProjectionStack[mProjectionStackCurrentIndex]);           
        }
       

}