0
votes

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

1 Answers

0
votes

Whoops my mistake! The UV_COORD constant was 1 instead of 2 for some reason. Good way to spend 4 hours!