Devsil
Devsil

Reputation: 598

OpenGL ES 2.0 Android Alpha Shows as black

I am able to successfully render an bitmap onto a Texture and display it on the phone screen no problem. What I am trying to do it render another texture from a PNG on top of it. The overlay png contains some transparent (alpha) pixels.

I can get the overlay to render on top of the background texture image but when I do that it appears that the transparent pixels are being rendered as a semi-translucent black? Unless the black is actually coming from the Texture background which I am setting as black... Does anyone have any suggestions as to what I may do doing wrong or another way to achieve this desired affect?

Vertex Shader:

private final String vertexTextureShaderCode =
                "attribute vec4 aPosition;"+ // Position of out Vertex
                "attribute vec2 aTexPosition;"+ // Position of our texture contained in the vertex
                "varying vec2 vTexPosition;"+ //
                "void main(){"+
                "    gl_Position = aPosition;"+
                "    vTexPosition = aTexPosition;"+
                "}";

Fragment Shader:

private final String fragmentTextureShaderCode =
            "precision mediump float;" +
            "uniform sampler2D uTexture;" + // Our Background Image  ( Our uploaded image)
            "uniform sampler2D uOverlay;"+ // Our Ovrelay image
            "varying vec2 vTexPosition;" +
            "void main() {" +
            "  vec4 colImage = texture2D(uTexture,vTexPosition);" +
            "  vec4 colOverlay = texture2D(uOverlay, vTexPosition);"   +
            "  gl_FragColor = mix(colImage, colOverlay, 0.7);" +
            "}";

draw frame method

 public void drawOverlay(Context context,int resourceId){
    BitmapFactory.Options opts = new BitmapFactory.Options();
    opts.inScaled = false;

    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId,opts);

    // Bind our TEXTURE_COORDS to the array
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,mTexturePointer[1]);

    // Create the nearest filter TEXTURE_COORDS
    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);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);

    // Use Android GL Utils to specify a 2d TEXTURE_COORDS image from our bitmap
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

    bitmap.recycle();

    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
    GLES20.glUseProgram(mProgram);

    // ENable bledning

//       GLES20.glEnable(GLES20.GL_BLEND);
//
//        // User SRC_OVE
//        GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);

    // get handle to vertex shader vPosition member
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
    mTextureHandle = GLES20.glGetUniformLocation(mProgram, "uTexture");
    mTextureOverlayhandle = GLES20.glGetUniformLocation(mProgram, "uOverlay");
    mTexturePositionHandle = GLES20.glGetAttribLocation(mProgram, "aTexPosition");

    GLES20.glVertexAttribPointer(mTexturePositionHandle, 2, GLES20.GL_FLOAT, false, 0, mTextureBuffer);
    GLES20.glEnableVertexAttribArray(mTexturePositionHandle);

    // ACTIVATING OUR FIRST TEXTURE, I.E our background image.
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexturePointer[0]);
    GLES20.glUniform1i(mTextureHandle,0);

    // ACTIVATE OUR SECOND SECOND I.E our overlay
    GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexturePointer[1]);
    GLES20.glUniform1i(mTextureHandle,1);

    // Prepare the triangle coordinate data
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 0, vertexBuffer);

    // enable a handle to the triangle vertice
    GLES20.glEnableVertexAttribArray(mPositionHandle);

    // clear the colors
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    GLES20.glDisable(GLES20.GL_DEPTH_TEST);

    GLES20.glEnable(GLES20.GL_BLEND);

    // User SRC_OVER
    GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
    // Draw the square
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, vertexCount);

    // Disbale the vertex array
    GLES20.glDisableVertexAttribArray(mPositionHandle);

}

Is using the mix method in my fragment shader the correct approach here? Should I instead be drawing the 2 images into 1 texture (sampler2D) rather then using the mix for the 2 sampler2D objects? if so, how would I do that. Everytime I attempt that the foreground texture is drawn directly over the background texture.

Upvotes: 4

Views: 1101

Answers (1)

Devsil
Devsil

Reputation: 598

OK, figured out my own issue.

I was attempting to draw 2 different bitmaps to one textures but was using the same texture handle to do so. The Fragment shader posted above is incorrect to achive this type of result. Using "mix" on the 2 textures was not the correct approach.

The correct approach was to use just 1 texture but have a handle for my background texture and my foreground texture. And in the draw() method I set up the back ground image first, just like usually and use glDrawArrays(...), then after that will set the Foreground image (using the correct pointer) to draw the foreground image with another glDrawArrays(...) call.

Upvotes: 2

Related Questions