I'm trying to use OpenGL ES 2.0 for Android to display a simple cube with normals and colors. To do so, I create a shader program, attach my vertex and fragment shaders, and link my program, as follows:
// Create empty OpenGL ES Program
mProgram = GLES20.glCreateProgram();
MyGLRenderer.checkGlError("glCreateProgram");
// Add the vertex shader to program
vertexShaderCode = Utilities.convertResourceToString(context, R.raw.vert_shader_hw3);
int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
GLES20.glAttachShader(mProgram, vertexShader);
MyGLRenderer.checkGlError("glAttachShader");
// Add the fragment shader to program
fragmentShaderCode = Utilities.convertResourceToString(context, R.raw.frag_shader_hw3);
int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
GLES20.glAttachShader(mProgram, fragmentShader);
MyGLRenderer.checkGlError("glAttachShader");
// Bind attributes
GLES20.glBindAttribLocation(mProgram, 0, "aPosition");
MyGLRenderer.checkGlError("glBindAttribLocation");
GLES20.glBindAttribLocation(mProgram, 1, "aNormal");
MyGLRenderer.checkGlError("glBindAttribLocation");
GLES20.glBindAttribLocation(mProgram, 2, "aColor");
MyGLRenderer.checkGlError("glBindAttribLocation");
// Create OpenGL program executables
GLES20.glLinkProgram(mProgram);
MyGLRenderer.checkGlError("glLinkProgram");
// Add program to OpenGL ES environment
GLES20.glUseProgram(mProgram);
MyGLRenderer.checkGlError("glUseProgram");
And it crashes right there at the end, printing to the LogCat: glUseProgram: glError 1281
and I checked the documentation, and glError 1281, i.e. GL_INVALID_VALUE
is generated if program is neither 0 nor a value generated by OpenGL.
After Googling this for ~10 hours now, I've decided to turn to StackOverflow for assistance. Any idea what could be wrong with my vertex shader code to make glUseProgram behave this way?
Here is my vertex shader code, my attempt to implement phong lighting:
uniform mat4 uMVPMatrix;
uniform mat4 uMVMatrix;
uniform vec3 uLightPosition;
uniform vec4 uAmbient;
uniform vec4 uDiffuse;
uniform vec4 uSpecular;
uniform vec4 uEmission;
uniform float uShininess;
attribute vec4 aPosition;
attribute vec3 aNormal;
attribute vec4 aColor;
varying vec4 vColor;
vec4 phong()
{
// P is the vertex coordinate on body
vec3 P = vec3(uMVMatrix * aPosition);
// N is the object normal at P
vec3 N = vec3(uMVMatrix * vec4(aNormal, 0.0));
// Light Position for light 0
vec3 LightPos = uLightPosition;
// L is the light vector
vec3 L = normalize(LightPos - P);
// R is the reflected light vector R = 2(L.N)N - L
vec3 R = reflect(-L, N);
// V is the view vector (eye at the origin)
vec3 V = normalize(-P);
// Diffuse light intensity is cosine of light and normal vectors
float Id = max(dot(L,N) , 0.0);
// Shininess intensity is cosine of light and reflection vectors to a power
float Is = (Id>0.0) ? pow(max(dot(R,V) , 0.0) , uShininess) : 0.0;
// Vertex color
return uEmission + uAmbient + Id*uDiffuse + Is*uSpecular;
}
void main()
{
gl_Position = uMVPMatrix * aPosition;
vColor = phong() * 0.5*(gl_Position/gl_Position.w + 1.0);
}