Android OpenGL ES透明背景

我正在构build一个利用OpenGL的Android应用程序。 就目前而言, GLSurfaceView的背景是​​由我的代码dynamic生成的,并作为纹理加载并使用glDrawTexfOES绘制。 这是“好”,但我可以简单地显示图像更顺利自己的表面(没有OpenGL)。 有什么办法可以使GLSurfaceView的背景GLSurfaceView透明吗? 我听到一些传言,这可以通过设置setEGLConfigChooser来完成,但我还没有find任何确认。 最终,我想要绘制一个表面,并将GLSurfaceView在其上以实现分层效果。

我知道这是一个棘手的,很可能是不可能的,但任何input是赞赏。 提前致谢。

只是一些简单的改变,我做了这个工作。

在我的GLSurfaceView.Renderer

 public void onSurfaceCreated(GL10 gl, EGLConfig config) { gl.glDisable(GL10.GL_DITHER); gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); gl.glClearColor(0,0,0,0); gl.glEnable(GL10.GL_CULL_FACE); gl.glShadeModel(GL10.GL_SMOOTH); gl.glEnable(GL10.GL_DEPTH_TEST); } 

在我的GLSurfaceView

 setEGLConfigChooser(8, 8, 8, 8, 16, 0); getHolder().setFormat(PixelFormat.TRANSLUCENT); 

你的GLSurfaceView也需要setZOrderOnTop(true);

我使用我自己的GLSurfaceView类来显示图表(透明背景/覆盖)。 我的扩展GLSurfaceView通过XMLembedded到popup窗口中。

 <com.dsignmatters.iq_fitfunlite.GLPieChartView android:id="@+id/gameprogress_chart" android:layout_height="wrap_content" android:layout_width="wrap_content" ... 

作为活动的一部分,我添加了下面的代码:

 mGamesuccessPieChart = (GLSurfaceView) gameprogressView.findViewById(R.id.gameprogress_chart); mGamesuccessPieChart.setZOrderOnTop(true); 

最后但并非最不重要的我的GLSurfaceView看起来像这样:

 public class GLPieChartView extends GLSurfaceView { public GLPieChartView(Context context) { super(context); initGL(); } public GLPieChartView(Context context, AttributeSet attrs) { super(context, attrs); initGL(); } void initGL() { setEGLContextClientVersion(2); setEGLConfigChooser(8,8,8,8,16,0); setRenderer(new GLPieChartRenderer()); setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); getHolder().setFormat(PixelFormat.TRANSLUCENT); } } 

我的渲染器类GLPieChartRenderer根本不调用glClearColor

最后的代码示例是用于启用GLSurfaceView透明度。 但是在使用GLSurfaceView透明度之前,请考虑以下几点。

  1. 启用透明度要求您在setZOrderOnTop上使用GLSurfaceView 。 这将阻止您将任何其他视图(例如TextView )放在透明GLSurfaceView顶部。 即使导航抽屉也不能在透明的GLSurfaceView之上滑动(忽略技巧 )。 透明与否, GLSurfaceView只能存在于其他android视图的上方或下方,而不能存在于它们之间。
  2. 透明性要求您使用setEGLConfigChoosersetFormat ,如下例所示。 这意味着,你不能得到系统所select的默认格式,这对于那个特定的设备来说是最好的。 更重要的是,您需要确保设备具有支持的格式,并且如果预期的格式不存在,则select其他格式,如在此gsoc 示例中 。

其他选项透明度

  1. 在Android中运行OpenGL的Tracer ,会显示活动的背景图像被绘制为opengl纹理。 因此,如果可能的话,而不是使GLSurfaceView透明,您也可以在GLSurfaceView中渲染您的背景作为opengl纹理。
  2. 此外,表面上的alpha通道或透明度不是opengl中alpha混合的先决条件。 两者都是独立的。
  3. 如果你的opengl组件被embedded在其他视图之间, TextureView ( trick )是一个很好的select。 这个突破游戏是Android中GLSurfaceView 2D绘图的一个很好的例子。

下面的示例与布局xml和代码为透明GLSurfaceView与背景。

  1. green背景布局xml文件

     <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:background="#00FFFF"> <android.opengl.GLSurfaceView android:id="@+id/mySurfaceView" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout> 
  2. MainActivity.java文件。 将ALPHAvariables从0.0更改为1.0,以查看表面颜色red与背景活动颜色green混合

     package com.example.transparentsurfaceview; import android.app.Activity; import android.graphics.PixelFormat; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.os.Bundle; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; public class MainActivity extends Activity { private GLSurfaceView mSurfaceView; private static float ALPHA = 0.5f; private static float RED = 1.0f; private static float GREEN = 0.0f; private static float BLUE = 0.0f; protected void onCreate( Bundle savedInstanceState ) { super.onCreate( savedInstanceState ); setContentView( R.layout.activity_main ); mSurfaceView = (GLSurfaceView)findViewById( R.id.mySurfaceView ); mSurfaceView.setEGLContextClientVersion( 2 ); mSurfaceView.setZOrderOnTop( true ); mSurfaceView.setEGLConfigChooser( 8, 8, 8, 8, 16, 0 ); mSurfaceView.getHolder().setFormat( PixelFormat.RGBA_8888 ); mSurfaceView.setRenderer( new GLSurfaceView.Renderer() { public void onSurfaceCreated( GL10 gl10, EGLConfig eglConfig ) { GLES20.glClearColor( RED, GREEN, BLUE, ALPHA ); } public void onSurfaceChanged( GL10 gl10, int i, int i2 ) {} public void onDrawFrame( GL10 gl10 ) { GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT ); } }); } } 

你应该确保活动背景是透明的!

如果活动的背景是不透明的(默认为白色),那么即使内容视图(glsurfaceview)是半透明的,它也会显示活动的白色背景作为背景。

您可以在声明的Android.manifest中设置活动背景透明度,请参阅官方API演示TranslucentGLSurfaceViewActivity以获得帮助