Android OpenGL ES прозрачный фон - PullRequest
25 голосов
/ 09 января 2010

Я создаю приложение для Android, которое использует преимущества OpenGL. В его нынешнем виде фон для GLSurfaceView динамически генерируется моим кодом, загружается как текстура и рисуется с помощью glDrawTexfOES. Это нормально, но я могу просто более плавно отобразить изображение на собственной поверхности (без OpenGL). Есть ли способ сделать прозрачный фон GLSurfaceView? До меня дошли слухи, что это можно сделать с помощью setEGLConfigChooser, но я не нашел подтверждения. В конечном счете, я хотел бы взять поверхность, на которую я рисую, и нанести GLSurfaceView поверх нее, чтобы получить многослойный эффект.

Я знаю, что это сложно и вполне возможно, но любая информация приветствуется. Заранее спасибо.

Ответы [ 5 ]

40 голосов
/ 04 февраля 2010

Просто несколько простых изменений, которые я сделал, чтобы заставить это работать.

На моем 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);
21 голосов
/ 22 июня 2011

Ваш GLSurfaceView также требует setZOrderOnTop(true);

6 голосов
/ 16 июля 2012

Я использую свой собственный класс 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.

3 голосов
/ 29 ноября 2014

Пример кода в конце предназначен для включения прозрачности с GLSurfaceView. Но перед использованием прозрачности с GLSurfaceView рассмотрите следующие отрицательные моменты.

  1. Для включения прозрачности необходимо использовать setZOrderOnTop на GLSurfaceView. Это помешает вам разместить другие виды (например, TextView) поверх прозрачного GLSurfaceView. Даже ящики навигации не могут скользить над прозрачным GLSurfaceView (игнорируя трюки ). Прозрачный или нет, GLSurfaceView может существовать только над или под другими видами Android, но не между ними.
  2. Прозрачность требует, чтобы вы использовали setEGLConfigChooser и setFormat, как показано в примере ниже. Это означает, что вы не можете получить формат, выбранный системой по умолчанию, который был бы наилучшим для данного конкретного устройства. Что еще более важно, вам нужно убедиться, что устройство имеет поддерживаемый формат и выбрать альтернативы, если ожидаемый формат отсутствует, как в этом примере gsoc .

Другие варианты прозрачности .

  1. Запуск Tracer для opengl в Android покажет, что фоновые изображения для действий отображаются в виде текстур opengl. Таким образом, вместо того, чтобы сделать GLSurfaceView прозрачным, если возможно, вы также можете визуализировать свой фон как текстуру opengl в GLSurfaceView.
  2. Кроме того, альфа-канал или прозрачность на поверхности не является обязательным условием для альфа-смешивания в opengl. Оба независимы.
  3. TextureView ( трюк ) - хорошая альтернатива, если ваш компонент opengl должен быть встроен между другими представлениями. Эта игра breakout является очень хорошим примером для рисования GLSurfaceView 2d в Android.

Ниже приведен пример с макетом XML и кодом для прозрачного GLSurfaceView с фоном.

  1. Макет XML-файла с green цвет фона

    <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 );
                }
            });
        }
    }
    
1 голос
/ 29 ноября 2013

Вы должны убедиться, что фон деятельности прозрачен!

Если фон действия непрозрачен, скажем, белый по умолчанию, то даже если представление содержимого (glsurfaceview) является полупрозрачным, он будет отображать белый фон действия в качестве фона.

Вы можете установить прозрачность фона активности в Android.manifest, где он объявлен, см. Официальную демонстрацию API TranslucentGLSurfaceViewActivity для справки

...