2013-07-26 171 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)