2016-05-20 142 views
3

我能夠成功將位圖渲染到紋理上,並將其顯示在手機屏幕上沒有任何問題。我正在嘗試做的事情是在PNG上渲染另一個紋理。疊加png包含一些透明(alpha)像素。OpenGL ES 2.0 Android Alpha顯示爲黑色

我可以在背景紋理圖像上獲取疊加層,但是當我這樣做時,看起來透明像素呈現爲半透明黑色?除非黑色實際上來自紋理背景,我將其設置爲黑色......有沒有人有任何建議,我可能做什麼做錯了或另一種方式來實現這種所需的影響?

頂點着色器:

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

片段着色器:

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);" + 
      "}"; 

牽伸方法

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

} 

是用我的片段着色器在這裏正確的方法混合方法?我是不是應該將2個圖像繪製成1個紋理(sampler2D),而不是使用2個sampler2D對象的混合?如果是這樣,我該怎麼做。每次我嘗試將前景紋理直接繪製在背景紋理上時。

+0

據我記得Bitmap對象(和底層skia庫)使用預先計算的阿爾法...所以png紋理與alpha通過BitmapFactory加載不工作...當我玩opengl我用本地libpng加載 – Selvin

+0

右,預乘α似乎是造成這個問題的原因。然而,無數資源指出使用GLES20.BLEND作爲解決方案。它似乎沒有在我的情況下工作 – Devsil

回答

2

好的,算出我自己的問題。

我試圖繪製2個不同的位圖到一個紋理,但使用相同的紋理句柄來這樣做。上面顯示的片段着色器對於實現這種類型的結果不正確。對2種紋理使用「混合」不是正確的方法。

正確的做法是隻使用1個紋理,但有一個處理我的背景紋理和我的前景紋理。在draw()方法中,我首先設置背景圖像,就像平常一樣,使用glDrawArrays(...),然後設置前景圖像(使用正確的指針)以繪製前景圖像與另一個glDrawArrays (...)呼叫。