2015-12-01 80 views
1

我在Android上開發了一個OpenGLES 2.0應用程序,並且紋理映射到了一些我的對象。這些紋理從具有透明位圖位創建的,但有時渲染時的透明位是真正透明的,有時他們是黑人紋理的透明度有時會被忽略

Black is the new transparent

Transparent is actually transparent

在這兩種情況下,我使用相同的紋理製作和着色器代碼。

這裏的紋理加載...

Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), id); 
// If something went wrong delete the texture and return 0 
if (bitmap == null) { 
    return 0; 
} 


final int[] textureID = new int[1]; 
GLES20.glGenTextures(1, textureID, 0); 

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID[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_LINEAR); 

// Copy the bitmap to the texture 
android.opengl.GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 

// Unbind 
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); 

我渲染以下

GLES20.glUseProgram(mProgram); 

// Prepare the coordinate data 
GLES20.glVertexAttribPointer(
     mPositionParam, Mesh.XYZ_COORDS_PER_VERTEX, 
     GLES20.GL_FLOAT, false, 
     Mesh.XYZ_COORDS_PER_VERTEX * Mesh.BYTES_PER_FLOAT, mesh.getVertexBuffer()); 

// 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, mesh.getTextureId()); 

// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0. 
GLES20.glUniform1i(mTextureParam, 0); 

FloatBuffer textureBuffer = useAltTexture && mesh.hasStereoTexture() ? 
     mesh.getStereoTextureBuffer() : mesh.getTextureBuffer(); 
GLES20.glVertexAttribPointer(
     mTexturePosParam, Mesh.UV_COORDS_PER_VERTEX, 
     GLES20.GL_FLOAT, false, 
     Mesh.UV_COORDS_PER_VERTEX * Mesh.BYTES_PER_FLOAT, textureBuffer); 


GLES20.glUniformMatrix4fv(mModelViewProjectionParam, 1, false, modelViewProjection, 0); 
GLES20.glEnable(GLES20.GL_BLEND); 
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 
// Draw the shape 
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, mesh.getVertexCount()); 
GLES20.glDisable(GLES20.GL_BLEND); 

我的頂點着色器:

uniform mat4 u_MVPMatrix; 

attribute vec4 a_Position; 
attribute vec2 a_TexCoord; 

varying vec2 v_TexCoord; 

void main() { 
    // The matrix must be included as a modifier of gl_Position. 
    // Note that the u_MVPMatrix factor *must be first* in order 
    // for the matrix multiplication product to be correct. 
    v_TexCoord = a_TexCoord; 
    gl_Position = u_MVPMatrix * a_Position; 
} 

我的片段着色器:

precision mediump float; 

varying vec2 v_TexCoord; 

uniform sampler2D u_Texture; 

void main() { 
    gl_FragColor = texture2D(u_Texture, v_TexCoord); 
} 

任何線索爲什麼混合不一致?

+0

您是否僅爲它們使用了相同的混合選項? – Sung

+0

@SungWoo我對所有的紋理使用相同的混合選項。有時它起作用,有時它不起作用。 – ChrisJ

+0

如果您在後面的圖片後面繪製後面的圖片,則不會處理前面圖片後面的像素 – Sung

回答

0

因爲透明像素的靜態創建深度緩存條目,你必須遵循painter's algorithm

但是,你可以放棄使用「丟棄」關鍵字GLSL像素。

if (color.rgb == vec3(0.0,0.0,0.0)) 
    discard; 
else 
    fragColor = vec4(color, 1.0);