2015-05-26 298 views
0

我想加載紋理PNG(由photoshop導出)並將其用於Android中的OpenGL ES 2.0,但純色看起來像透明(png中的黑色圓圈完全是黑色)OpenGL ES 2.0 Alpha

Error PNG

我已閱讀,如果您縮放一個PNG超過50%這個bug出現(我用縮放更多,同樣的測試,所以我認爲事實並非如此)

我也讀了BitmapFactory不要讀預乘alpha PNG,我嘗試了另一個功能,假設做的工作,但沒有工作(也許這是錯的)

任何方法來實現正確的阿爾法?

這是我的片段着色器:

precision mediump float;  // Set the default precision to medium. We don't need as high of a 
          // precision in the fragment shader. 
uniform vec3 u_LightPos;  // The position of the light in eye space. 
uniform sampler2D u_Texture; // The input texture. 

varying vec3 v_Position;  // Interpolated position for this fragment. 
varying vec3 v_Normal;   // Interpolated normal for this fragment. 
varying vec2 v_TexCoordinate; // Interpolated texture coordinate per fragment. 

// The entry point for our fragment shader. 
void main()       
{        
    // Will be used for attenuation. 
    float distance = length(u_LightPos - v_Position);     

    // Get a lighting direction vector from the light to the vertex. 
    vec3 lightVector = normalize(u_LightPos - v_Position);     

    // Calculate the dot product of the light vector and vertex normal. If the normal and light vector are 
    // pointing in the same direction then it will get max illumination. 
    float diffuse = max(dot(v_Normal, lightVector), 0.0);                     

    // Add attenuation. 
    diffuse = diffuse * (1.0/(1.0 + (0.25 * distance))); 

    // Add ambient lighting 
    diffuse = diffuse + 0.7; 

    // Multiply the color by the diffuse illumination level and texture value to get final output color. 
    gl_FragColor = (diffuse * texture2D(u_Texture, v_TexCoordinate));          
} 

這是我的繪製調用:

GLES20.glEnable(GLES20.GL_BLEND); 

    GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 
    GLES20.glUseProgram(mMagiaProgramHandle); 

    mMagiaTextureCoordinateHandle = GLES20.glGetAttribLocation(mMagiaProgramHandle, "a_TexCoordinate"); 
    mTexturePruebaUniformHandle = GLES20.glGetUniformLocation(mMagiaProgramHandle, "u_TextureVec"); 


    coordinate.drawMagia(mPositionHandle, mNormalHandle, mMagiaTextureCoordinateHandle); 

    // This multiplies the view matrix by the model matrix, and stores the 
    // result in the MVP matrix 
    // (which currently contains model * view). 

    Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0); 
    // Pass in the modelview matrix. 
    GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0); 


    // This multiplies the modelview matrix by the projection matrix, and 
    // stores the result in the MVP matrix 
    // (which now contains model * view * projection). 
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0); 

    // Pass in the combined matrix. 
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0); 

    // Pass in the light position in eye space. 
    GLES20.glUniform3f(mLightPosHandle, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1], mLightPosInEyeSpace[2]); 

    GLES20.glUniform2f(mTexturePruebaUniformHandle, Magia.posTextureX, Magia.posTextureY); 
    // Draw the square. 
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6); 
    GLES20.glDisable(GLES20.GL_BLEND); 

這是我的加載功能;

public static int loadTexture(final Context context, final int resourceId) 
{ 
    final int[] textureHandle = new int[1]; 

    GLES20.glGenTextures(1, textureHandle, 0); 

    if (textureHandle[0] != 0) 
    { 
     final BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inScaled = false; // No pre-scaling 


     // Read in the resource 
     final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options); 

     // Bind to the texture in OpenGL 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]); 

     // Set filtering 
     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); 

     // Load the bitmap into the bound texture. 
     GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 

     // Recycle the bitmap, since its data has been loaded into OpenGL. 
     bitmap.recycle();      
    } 

    if (textureHandle[0] == 0) 
    { 
     throw new RuntimeException("Error loading texture."); 
    } 

    return textureHandle[0]; 
} 

回答

1

不知道是否有可能是與本身的質感,以及一個問題,但肯定有東西在你的着色器代碼,可以給你帶來意想不到的結果:

gl_FragColor = (diffuse * texture2D(u_Texture, v_TexCoordinate)); 

既然你乘以所有顏色組件(包括alpha)與diffuse,則只要diffuse的值小於1.0,結果顏色就會部分透明。由此產生的阿爾法將是diffuse乘以你從紋理獲得的阿爾法。

如果您想使用從紋理採樣的alpha作爲片段的alpha值,則不應該將其與diffuse相乘。只將RGB分量與diffuse相乘的代碼可能如下所示:

vec4 texVal = texture2D(u_Texture, v_TexCoordinate); 
gl_FragColor = vec4(diffuse * texVal.rgb, texVal.a); 
+0

這是問題所在,謝謝! – D4rWiNS