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
;
}
}