I am working on rending a 2d texture on a quad made of 2 triangles. However it is rendering to black even though I am passing the texture and texture coordinates to the shaders. Any help is greatly appreciated!
Render function:
public void render(float[] mvpMatrix) {
// Add program to OpenGL environment.
GLES20.glUseProgram(mGLProgram);
// Get handle to vertex shader's aPosition member
// and enable a handle to the triangle vertices.
int mPositionHandle = GLES20.glGetAttribLocation(mGLProgram, "aPosition");
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the vertex coordinate data.
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false, vertexStride, vertexBuffer
);
// Pass the texture coordinates.
int mTextureCoordinateHandle = GLES20.glGetAttribLocation(mGLProgram, "aTexCoordinate");
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
// Prepare the uv coordinate data.
GLES20.glVertexAttribPointer(mTextureCoordinateHandle, UV_SIZE,
GLES20.GL_FLOAT, false, 0, uvBuffer
);
// Get handle to fragment shader's aColor member and set color for drawing the triangle.
int mColorHandle = GLES20.glGetUniformLocation(mGLProgram, "uColor");
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
// Tell the texture uniform sampler to use this texture
// in the shader by binding to texture unit 0.
int mTextureUniformHandle = GLES20.glGetUniformLocation(mGLProgram, "uTexture");
GLES20.glUniform1i(mTextureUniformHandle, 0);
// Get handle to shape's transformation matrix.
int mMVPMatrixHandle = GLES20.glGetUniformLocation(mGLProgram, "uMVPMatrix");
GLError.checkGlError("glGetUniformLocation");
// Apply the projection and view transformation.
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
GLError.checkGlError("glUniformMatrix4fv");
// Set the active texture unit to texture unit 0.
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
// Bind the texture to this unit.
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
// Render the sprite.
GLES20.glDrawElements(
GLES20.GL_TRIANGLES, indices.length,
GLES20.GL_UNSIGNED_SHORT, indiceBuffer
);
// Disable vertex array.
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mTextureCoordinateHandle);
}
UVs and indices:
private float uvs[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f
};
private short indices[] = {
0, 1, 2, 0, 2, 3
};
Creating UV byte buffer:
// Initialize byte buffer for the uvs.
ByteBuffer ub = ByteBuffer.allocateDirect(
// Number of uv values * 4 bytes per float.
uvs.length * 4
);
ub.order(ByteOrder.nativeOrder());
uvBuffer = ub.asFloatBuffer();
uvBuffer.put(uvs);
uvBuffer.position(0);
Texture loader:
public static int loadTexture(Context context, final int id, final int resource) {
final int[] texture = new int[1];
GLES20.glGenTextures(id, texture, 0);
if (texture[0] == 0) {
throw new RuntimeException("Error loading texture bro. " + texture[0]);
}
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
// Decode the bitmap automagically.
final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resource, options);
// Bind the texture as texture 2d.
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture[0]);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
return texture[0];
}
Vertex shader:
uniform mat4 uMVPMatrix;
attribute vec2 aTexCoordinate;
attribute vec4 aPosition;
varying vec2 vTexCoordinate;
void main() {
// Pass the texture coordinate.
vTexCoordinate = aTexCoordinate;
// Determine the position of the render.
gl_Position = uMVPMatrix * aPosition;
}
Fragment shader:
precision mediump float;
uniform sampler2D uTexture;
uniform vec4 uColor;
varying vec2 vTexCoordinate;
void main() {
gl_FragColor = texture2D(uTexture, vTexCoordinate);
}