Subversion Repositories AndroidProjects

Rev

Rev 188 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.gebauz.Bauzoid.graphics.shader;

import com.gebauz.Bauzoid.app.Consts;
import com.gebauz.Bauzoid.graphics.Graphics;
import com.gebauz.Bauzoid.graphics.GraphicsObject;
import com.gebauz.Bauzoid.graphics.model.SimpleGeometry;
import com.gebauz.Bauzoid.graphics.model.VertexAttribute;

import android.opengl.GLES20;
import android.util.Log;

public class ShaderProgram extends GraphicsObject
{
        public class Shader
        {
                private int mShaderID = 0;
                private int mShaderType;
               
                public Shader(int shaderType)
                {
                        mShaderType = shaderType;
                }
               
                public void loadShader(String shaderCode)
                {
                        if (mShaderID != 0)
                                unloadShader();
                       
                        mShaderID = GLES20.glCreateShader(mShaderType);
                       
                        GLES20.glShaderSource(mShaderID, shaderCode);
                        GLES20.glCompileShader(mShaderID);
                       
                        final int[] compileStatus = new int[1];
                        GLES20.glGetShaderiv(mShaderID, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
                       
                        if (compileStatus[0] != GLES20.GL_TRUE)
                        {
                                Log.e(Consts.LOG_TAG, GLES20.glGetShaderInfoLog(mShaderID));
                        }
                }
               
                public void unloadShader()
                {
                        GLES20.glDeleteShader(mShaderID);
                        mShaderID = 0;
                }
        };
       
        private Shader mVertexShader = null;
        private Shader mFragmentShader = null;
        private int mProgramID = 0;
       
        public ShaderProgram(Graphics graphics)
        {
                super(graphics);
               
                mVertexShader = new Shader(GLES20.GL_VERTEX_SHADER);
                mFragmentShader = new Shader(GLES20.GL_FRAGMENT_SHADER);
        }
       
        public void loadShaderProgram(String vertexShaderCode, String fragmentShaderCode)
        {
                mVertexShader.loadShader(vertexShaderCode);
                mFragmentShader.loadShader(fragmentShaderCode);
               
                mProgramID = GLES20.glCreateProgram();
               
                GLES20.glAttachShader(mProgramID, mVertexShader.mShaderID);
                GLES20.glAttachShader(mProgramID, mFragmentShader.mShaderID);
               
                // default attrib locations
                /*GLES20.glBindAttribLocation(mProgramID, SimpleGeometry.COORD_ATTRIB_INDEX, "vPosition");
                GLES20.glBindAttribLocation(mProgramID, SimpleGeometry.COLOR_ATTRIB_INDEX, "vColor");
                GLES20.glBindAttribLocation(mProgramID, SimpleGeometry.NORMAL_ATTRIB_INDEX, "vNormal");
                GLES20.glBindAttribLocation(mProgramID, SimpleGeometry.TEX_COORD_ATTRIB_INDEX, "vTexCoord");*/

               
                GLES20.glBindAttribLocation(mProgramID, VertexAttribute.POSITION, "vPosition");
                GLES20.glBindAttribLocation(mProgramID, VertexAttribute.COLOR, "vColor");
                GLES20.glBindAttribLocation(mProgramID, VertexAttribute.NORMAL, "vNormal");
                GLES20.glBindAttribLocation(mProgramID, VertexAttribute.TEXCOORD0, "vTexCoord0");
                GLES20.glBindAttribLocation(mProgramID, VertexAttribute.TEXCOORD1, "vTexCoord1");
                GLES20.glBindAttribLocation(mProgramID, VertexAttribute.BLENDINDICES, "vBlendIndex");
                GLES20.glBindAttribLocation(mProgramID, VertexAttribute.BLENDWEIGHTS, "vBlendWeight");
               
                GLES20.glLinkProgram(mProgramID);
        }
       
        public void unloadShaderProgram()
        {
                GLES20.glDeleteProgram(mProgramID);    
               
                mVertexShader.unloadShader();
                mFragmentShader.unloadShader();
               
                mProgramID = 0;
        }
       
        public void activate()
        {
                // TODO: state management!
                GLES20.glUseProgram(mProgramID);
        }
       
        public void deactivate()
        {
                GLES20.glUseProgram(0);
        }
       
        public ShaderUniform getUniform(String uniformName)
        {
                if (mProgramID == 0)
                        return null;
               
                int handle = GLES20.glGetUniformLocation(mProgramID, uniformName);
               
                if (handle == -1)
                {
                        Log.e(Consts.LOG_TAG, "Error getting uniform '" + uniformName + "'!");
                        return null;
                }
               
                return new ShaderUniform(handle);
        }

        public Shader getVertexShader()
        {
                return mVertexShader;
        }
       
        public Shader getFragmentShader()
        {
                return mFragmentShader;
        }
}