2011-02-17 162 views
2

我使用相同的笑臉紋理渲染3個不同的多邊形。 紋理是放在透明背景上的黃色圓圈。Android opengl透明度問題

我的問題是,如果我在稍後繪製的另一個面前繪製一個笑臉,它會使後面的透明圖像在早期的背景透明的地方繪製。

那麼一張圖片勝過千言萬語! 查看圖片的問題和笑臉png here

如果我把最後繪製的笑臉放在另一個面前,這個問題就不會發生,所以問題似乎與繪圖順序有關。任何人有任何投入?

public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig) { 
    //Textures a loaded here See next section for the implementation of loadTextures method on the polygon class. 
    loadTextures(gl, context); 

    gl.glEnable(GL10.GL_TEXTURE_2D); 
    gl.glShadeModel(GL10.GL_SMOOTH); 
    gl.glClearColor(.5f, .5f, .5f, 1); 
    gl.glEnable(GL10.GL_DEPTH_TEST); 

    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); 

    gl.glEnable(GL10.GL_BLEND); 
    gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA); 
} 

public void onSurfaceChanged(GL10 gl, int w, int h) { 
    if(h == 0) { 
     h = 1; 
    } 

    gl.glViewport(0, 0, w, h); 
    gl.glMatrixMode(GL10.GL_PROJECTION); 
    gl.glLoadIdentity(); 
    float ratio = (float) w/h; 
    gl.glFrustumf(-ratio, ratio, -1, 1, 1, 30); 
    GLU.gluLookAt(gl, lookEyeX, lookEyeY, lookEyeZ, lookCenterX, lookCenterY, lookCenterZ, lookUpX, lookUpY, lookUpZ); 

    gl.glMatrixMode(GL10.GL_MODELVIEW); 
    gl.glLoadIdentity(); 
} 

public void onDrawFrame(GL10 gl) {  
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
    gl.glLoadIdentity(); 

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 

    draw(gl); 
} 

的loadTexture方法

public void loadTextures(GL10 gl, Context context) { 
    if(bitmap == 0) { 
     return; 
    } 
    //Get the texture from the Android resource directory 
    InputStream is = context.getResources().openRawResource(bitmap); 
    Bitmap bitmap = null; 
    try { 
     //BitmapFactory is an Android graphics utility for images 
     bitmap = BitmapFactory.decodeStream(is); 

    } finally { 
     //Always clear and close 
     try { 
      is.close(); 
      is = null; 
     } catch (IOException e) { 
     } 
    } 

    //Generate one texture pointer... 
    gl.glGenTextures(1, textureIDs, 0); 
    //...and bind it to our array 
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[0]); 

    //Create Nearest Filtered Texture 
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); 
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); 

    //Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE 
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); 
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); 

    //Use the Android GLUtils to specify a two-dimensional texture image from our bitmap 
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); 

    //Clean up 
    bitmap.recycle(); 
} 
+1

從未嘗試融合了深度測試相結合......怎麼樣完全去除深度測試?據我所知,如果你想在OpenGL ES中保持透明度,有一些缺陷 – WarrenFaith 2011-02-17 12:32:44

回答

2

即使透明片段被寫入深度緩衝區的選項有:。

  1. 禁用深度緩衝 - 要麼不寫它或禁用深度測試
  2. 啓用阿爾法測試,使得透明片段被拒絕例如:

    GLES10.glEnable(GLES10.GL_ALPHA_TEST);

    GLES10.glAlphaFunc(GLES10.GL_GREATER,0);

  3. 排序的幾何形狀和繪製四邊形的後端到前端爲了

+0

我想知道alpha測試......他不會仍然需要按照先後順序來繪製嗎?或者它是否做了某種布爾與深度測試? – 2011-02-17 13:32:16

1
實施

關閉深度測試。因爲最前面的笑臉已經填充了深度緩衝區,所以最後面的笑臉缺失的像素不見了。

很明顯,您需要按照正確的順序繪製您的表情,最後是第一個。

我想你會理想想讓你的深度緩衝區積累α值而不是Z值......不知道這有多可能。 :-(

+0

關閉深度測試並不能解決問題,因爲這使我通過其他笑臉看到了笑臉的嘴巴。我想我將不得不控制我繪製多邊形的順序。 Thx爲您的答案! – CoolMcGrrr 2011-02-17 14:01:45