Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

package com.gebauz.bauzoid.graphics.shader;

public class Technique
{
        /** Connector class between Effect variables and Techniques.
         *
         * This class is used to store the actual shader's uniform handles, as well as a reference
         * to the actual Effect Variable to obtain the current value.
         *
         */

        public class TechniqueVariable
        {
                private ShaderUniform mUniform = null;
                private Effect.Variable mVariable = null;
               
                public TechniqueVariable(Effect.Variable var, ShaderUniform uniform)
                {
                        mVariable = var;
                        mUniform = uniform;
                }
               
                public void apply()
                {
                        // apply shader variable value
                        mVariable.apply(mUniform);
                }
               
        };
       
        private String mName;
       
        private Effect mEffect = null;
        private ShaderProgram mShader = null;
        private TechniqueVariable[] mTechniqueVariables = null;
       
        /** Constructor. */
        public Technique(Effect effect, String name, ShaderProgram shader)
        {
                mEffect = effect;
                mShader = shader;
                mName = name;
        }
       
        /** Destroy internal data. */
        public void dispose()
        {
                if (mShader != null)
                {
                        mShader.dispose();
                        mShader = null;
                }
        }
       
        /** Create the bindings of TechniqueVariables to actual Effect Variables. */
        public void connectVariables()
        {
                if (mShader == null)
                        return;
               
                // First, collect shader uniforms
                ShaderUniform[] uniforms = new ShaderUniform[mEffect.getVariableCount()];
                int existingUniformCount = 0;
               
                for (int i = 0; i < uniforms.length; i++)
                {
                        uniforms[i] = mShader.getUniform(mEffect.getVariable(i).getName());
                        if (uniforms[i] != null)
                                existingUniformCount++;
                }
               
                // Create actual connections
                mTechniqueVariables = new TechniqueVariable[existingUniformCount];
                int currentTechVar = 0;
                int nextFreeTextureStage = 0;
               
                for (int i = 0; i < uniforms.length; i++)
                {
                        if (uniforms[i] != null)
                        {
                                Effect.Variable var = mEffect.getVariable(i);
                               
                                // Existing connection
                                mTechniqueVariables[currentTechVar] = new TechniqueVariable(var, uniforms[i]);
                               
                                // if it's a texture, connect also the texture stage to use
                                if ((var.getType() == Effect.Variable.TYPE_TEXTURE2D) ||
                                        (var.getType() == Effect.Variable.TYPE_TEXTURE3D) ||
                                        (var.getType() == Effect.Variable.TYPE_TEXTURECUBE))
                                {
                                        Effect.VariableTexture texVar = (Effect.VariableTexture)var;
                                        texVar.setTextureStage(nextFreeTextureStage);
                                        nextFreeTextureStage++;
                                }
                               
                                currentTechVar++;
                        }
                }              
        }
       
        /** Activate technique. */
        public void activate()
        {
                if (mShader != null)
                {
                        mShader.activate();
                }
               
                if (mTechniqueVariables != null)
                {
                        for (TechniqueVariable v : mTechniqueVariables)
                        {
                                v.apply();
                        }
                }
        }
       
        /** Deactivate technique. */
        public void deactivate()
        {
                if (mShader != null)
                {
                        mShader.deactivate();
                }
        }
       
        /** Obtain name. */
        public final String getName()
        {
                return mName;
        }
}