2013-07-26 175 views
9

我嘗試使用GLSurfaceView來呈現,並通過docs我設置格式:GLSurfaceView - 如何使半透明背景

getHolder().setFormat(PixelFormat.TRANSLUCENT); 

的我用GLSurfaceView.Renderer,吸引在onDrawFrame:

GLES20.glClearColor(0, 0, 1, .5f); 
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); 

但是,GLSurfaceView中的GL渲染不是半透明的,而是完全藍色的。如果我忽略glClear調用,那麼它是完全黑色的。

我該如何讓GL渲染具有透明背景,以便將其與背後繪製的視圖混合?

enter image description here

編輯:這裏是我的GLSurfaceView:

class GLView extends GLSurfaceView{ 
    MyRenderer r; 
    public GLView(Context ctx){ 
     super(ctx); 
     setEGLContextClientVersion(2); 

     getHolder().setFormat(PixelFormat.TRANSLUCENT); 

     setEGLConfigChooser(8, 8, 8, 8, 16, 0); 
     r = new MyRenderer(getContext()); 
     setRenderer(r); 
    } 
} 

回答

6

OK,經過一番研究,我可以這樣回答自己。

我終於使用SurfaceView.setZOrderOnTop(true)繪製了透明度。但後來我失去了將其他視圖放在我的GLSurfaceView之上的可能性。

behindon top

左低於所有其他視圖,它不能與透明度繪製標準GL表面,因爲GL表面之前,應用程序的窗口表面繪製:

我有兩個可能的結果結束,並且GLSurfaceView只是在其位置punches hole,以便GL表面被看穿。

右邊是用setZOrderOnTop(true)繪製的透明GL曲面,因此它的曲面繪製在應用程序窗口的頂部。現在它是透明的,但在視圖層次結構中放置在其上的其他視圖之上繪製。

所以看起來應用程序有一個窗口,其視圖層次結構爲Surface,而SurfaceView具有GL的自己的表面,GL可能位於應用程序窗口的頂部或下面。不幸的是,透明GL視圖無法在視圖層次結構中正確排序,其他視圖在其頂部。

+0

爲什麼你沒有獎勵你的賞金? –

+2

我不能授予我自己的答案,其他答案並不滿足我。 –

0

我不知道問題到底是什麼,但另一種可能採用了半透明的彩色矩形,只是被覆蓋在屏幕清除深度緩衝位。

Is there any alternative for GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)?

否則,請確保您的深度緩衝位爲1

我會回來試試,當我可以重建我的手機上的問題了一下。

編輯:我只是意識到,之所以出現藍色可能是你將它設置爲.5f所以只需要2調用它去充分1F透明度。這意味着它需要30fps的1/15秒才能完全變藍。

嘗試Alpha透明度值降低到0.01F或0.05f

+0

錯誤的理論,即使將alpha設置爲0也沒有改變。也許你認爲清算增加了先前清算的價值。但是,表面拋油環應正確組成屏幕表面,包括GL表面的alpha通道。 –

5

你需要RGBA 8888像素格式爲半透明:

private void init(boolean translucent, int depth, int stencil) 
{ 
    /* By default, GLSurfaceView() creates a RGB_565 opaque surface. 
    * If we want a translucent one, we should change the surface's 
    * format here, using PixelFormat.TRANSLUCENT for GL Surfaces 
    * is interpreted as any 32-bit surface with alpha by SurfaceFlinger. 
    */ 
    this.getHolder().setFormat(PixelFormat.RGB_565); 
    if (translucent) 
    { 
     this.getHolder().setFormat(PixelFormat.TRANSLUCENT); 
    } 

    setEGLContextFactory(new ContextFactory()); 

    /* We need to choose an EGLConfig that matches the format of 
    * our surface exactly. This is going to be done in our 
    * custom config chooser. See ConfigChooser class definition 
    * below. 
    */ 
    setEGLConfigChooser(translucent ? 
         new ConfigChooser(8, 8, 8, 8, depth, stencil) : 
         new ConfigChooser(5, 6, 5, 0, depth, stencil)); 

    setRenderer(new Renderer()); 
} 
+0

正如你可以看到我的問題,我設置PixelFormat.TRANSLUCENT。 –

+0

你把它設置爲8888嗎? –

+0

是的,也試過這個。但文檔中提到應該設置PixelFormat.TRANSLUCENT。 –

1

您是否想過在setAlpha中使用LayerDrawable?這裏有一個例子,我有兩個圖像......一個是透明的(通過setAlpha),另一個不是。 'calendar_cell'是堅實的,在後面,然後是透明的盒子,以顯示它後面的日曆單元格。通過這種方式,您可以堆疊儘可能多的圖像,只要您想讓它們具有不同的透明度。

Drawable []layers = new Drawable [2]; 
int imageResource1 = mContext.getResources().getIdentifier("drawable/calendar_cell", null, mContext.getPackageName()); 
Drawable background = v.getResources().getDrawable(imageResource1); 
         layers [0]= background; 

int imageResource = mContext.getResources().getIdentifier("drawable/box_" + box, null, mContext.getPackageName()); 
Drawable boxImg = v.getResources().getDrawable(imageResource); 
    boxImg.setAlpha(100); 
    layers [1]= boxImg; 

LayerDrawable layerDrawable = new LayerDrawable (layers); 
v.setBackground(layerDrawable)