28

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

我知道这是一个棘手的问题,而且很可能是不可行的,但任何意见都值得赞赏。提前致谢。

4

5 回答 5

46

只是我做了一些简单的改变来让它工作。

在我的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);
于 2010-02-03T23:21:25.110 回答
23

GLSurfaceView还需要setZOrderOnTop(true);

于 2011-06-22T18:09:11.560 回答
9

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

<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

于 2012-07-15T20:40:43.253 回答
5

最后的代码示例用于启用透明度GLSurfaceView。但在使用透明度之前GLSurfaceView,请考虑以下负面因素。

  1. 启用透明度需要您使用setZOrderOnTopon GLSurfaceView。这将阻止您将任何其他视图(例如TextView)放在您的透明之上GLSurfaceView。即使是导航抽屉也不能在透明的上方滑动GLSurfaceView(忽略技巧)。透明与否,GLSurfaceView只能存在于其他 android 视图之上或之下,而不能存在于它们之间。
  2. 透明度要求您使用setEGLConfigChoosersetFormat,如下例所示。这意味着,您无法获得系统选择的最适合该特定设备的默认格式。更重要的是,您需要确保设备具有受支持的格式,并在不存在预期格式(如此 gsoc示例中)时选择替代格式。

透明度的其他选择

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

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

  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 文件。ALPHA将变量从 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 );
                }
            });
        }
    }
    
于 2014-11-29T15:06:19.547 回答
1

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

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

可以在声明的Android.manifest中设置activity的背景透明度,帮助查看官方API demo TranslucentGLSurfaceViewActivity

于 2013-11-29T09:02:00.767 回答