web-dev-qa-db-ja.com

Android OpenGLES透明な背景

OpenGLを利用するAndroidアプリを構築しています。現状では、GLSurfaceViewの背景はコードによって動的に生成され、テクスチャとして読み込まれ、glDrawTexfOESで描画されます。 「わかりました」が、画像を(OpenGLなしで)それ自体の表面にはるかにスムーズに表示することができます。GLSurfaceViewの背景を透明にする方法はありますか?これはsetEGLConfigChooserですが、確認が見つかりませんでした。最終的には、描画しているサーフェスを取得し、その上にGLSurfaceViewを置いて、レイヤー効果を実現したいと思います。

私はこれがトリッキーで、おそらく実行不可能であることを知っていますが、どんな入力でもありがたいです。前もって感謝します。

25
mattbasta

これを機能させるために私が行ったいくつかの簡単な変更。

私の〜の上に 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);
43
mattbasta

GLSurfaceViewにもsetZOrderOnTop(true);が必要です

21
Napalm

独自の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);     
    } 
}

私のレンダラークラスGLPieChartRendererglClearColorをまったく呼び出しません。

8

最後のコードサンプルは、GLSurfaceViewで透過性を有効にするためのものです。ただし、GLSurfaceViewで透明度を使用する前に、次の欠点を考慮してください。

  1. 透明性を有効にするには、setZOrderOnTopGLSurfaceViewを使用する必要があります。これにより、透明なTextViewの上に他のビュー(例:GLSurfaceView)を配置できなくなります。ナビゲーションドロワーでさえ、透明なGLSurfaceViewトリック を無視して)の上をスライドすることはできません。透過的であろうとなかろうと、GLSurfaceViewは他のAndroidビューの上または下にのみ存在でき、ビューの間に存在することはできません。
  2. 透明性を確保するには、以下の例のようにsetEGLConfigChoosersetFormatを使用する必要があります。つまり、特定のデバイスに最適な、システムによって選択されたデフォルトの形式を取得することはできません。さらに重要なことは、このgsoc example のように、デバイスがサポートされている形式であることを確認し、予期される形式が存在しない場合は代替を選択する必要があります。

透明度に対するその他のオプション

  1. Androidでopenglに対してTracerを実行すると、アクティビティの背景画像がopenglテクスチャとして描画されることが示されます。したがって、可能であれば、GLSurfaceViewを透明にする代わりに、GLSurfaceViewで背景をopenglテクスチャとしてレンダリングすることもできます。
  2. また、表面のアルファチャネルまたは透明度は、openglでのアルファブレンディングの前提条件ではありません。どちらも独立しています。
  3. TextureViewtrick )は、openglコンポーネントを他のビューの間に埋め込む場合に適しています。この breakout ゲームは、AndroidでのGLSurfaceView2D描画の非常に良い例です。

以下のサンプルは、レイアウト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ファイル。 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 );
                }
            });
        }
    }
    
3
Kiran

アクティビティの背景が透明であることを確認する必要があります。

アクティビティの背景が不透明な場合、たとえばデフォルトでは白の場合、コンテンツビュー(glsurfaceview)が半透明の場合でも、アクティビティの白い背景が背景として表示されます。

宣言されているAndroid.manifestでアクティビティの背景の透明度を設定できます。ヘルプについては、公式APIデモTranslucentGLSurfaceViewActivityを参照してください。

1
bismack163