2010-01-09 16 views
23

Estoy creando una aplicación para Android que aprovecha OpenGL. Tal como está, el fondo para el GLSurfaceView se genera dinámicamente por mi código y se carga como una textura y se dibuja con glDrawTexfOES. Lo cual está "bien", pero simplemente puedo mostrar la imagen mucho más suavemente en su propia superficie (sin OpenGL). ¿Hay alguna manera de que pueda hacer que el fondo de un GLSurfaceView sea transparente? He oído algunos rumores de que esto se puede hacer con setEGLConfigChooser, pero no he encontrado ninguna confirmación. En última instancia, me gustaría tomar una superficie que estoy dibujando y poner el GLSurfaceView sobre ella para lograr un efecto de capas.Android OpenGL ES Fondo transparente

Sé que esto es un truco y es muy posible que no sea factible, pero se agradece cualquier aportación. Gracias por adelantado.

+0

No sé mucho acerca de Open GL pero si se echa un vistazo en los ejemplos de la API Hay una clase llamada TranslucentGLSurfaceViewActivity en el paquete com.example.android.apis.graphics. ¿Eso ayuda? – Ally

Respuesta

39

Solo algunos cambios simples que hice para que esto funcione.

En mi 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); 
} 

En mi GLSurfaceView:

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

He configurado GLSurfaceView tal como lo escribió, y coloqué el código superior en mi procesador GL personalizado, y aún obtengo un fondo negro. ¿Tiene alguna idea sobre por qué podría ser así? – zidarsk8

+2

Esto funcionó para mí. Pero, el contenido de mi vista también se ha quedado en blanco. Solo hay un lienzo en blanco, pero nada se dibuja en él. ¿Alguna ayuda? – Umair

+1

Acabo de eliminar el código dado del método _onSurfaceCreated() _ y funcionó para mí como yo quería. Todo lo que estoy usando ahora son las dos líneas de códigos en mi método _init() _ de ** GLSurfaceView **. – Umair

20

Su GLSurfaceView requiere también setZOrderOnTop(true);

+0

y para este nivel sdk mínimo 6 es necesario. – efeyc

+0

Esto resolverá el problema, pero no podrá mostrar ninguna otra vista encima de GLSurfaceView si es necesario. –

+0

Pasé todo el día de ayer trabajando en una solución para eso. La solución es implementar la respuesta de Romain https://groups.google.com/forum/#!topic/android-developers/U5RXFGpAHPE y asegurarse de llamar a setOpacity (falso) en el constructor para la vista, así como también habilitar alfa a través de otra respuestas aquí (esta solución NO requiere setZOrderOnTop()) –

6

uso mi propia clase GLSurfaceView para mostrar gráficos (fondo transparente/recubrimiento) . Mi GLSurfaceView extendido se incrusta a través de XML en una ventana emergente.

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

Como parte de la actividad que añade este código:

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

Por último, pero no menos importante mi GLSurfaceView se ve así:

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);  
    } 
} 

Mi clase de procesador de GLPieChartRenderer no llama glClearColor en todas.

+1

No duplique sus respuestas a través de preguntas. Si una de las preguntas es un duplicado de la otra, a continuación, márquelo para que se cierre (o deje un comentario que indique que se trata de un duplicado; un usuario con una reputación superior marcará o votará para cerrarlo). Si las preguntas son realmente diferentes, entonces adapte su respuesta a cada pregunta planteada. –

1

¡debe asegurarse de que el fondo de la actividad sea transparente!

Si el fondo de la actividad es opaco, digamos blanco por defecto, incluso cuando la vista de contenido (la vista de la superficie del gráfico) sea translúcida, mostrará el fondo blanco de la actividad como fondo.

Usted puede establecer la transparencia actividad de fondo en el Android.manifest donde se declara, ver el TranslucentGLSurfaceViewActivity oficial de demostración API para ayuda

3

Ejemplo de código al final es para permitir la transparencia con GLSurfaceView. Pero antes de usar la transparencia con GLSurfaceView, tenga en cuenta los siguientes puntos negativos.

  1. Habilitar la transparencia requiere que use setZOrderOnTop en GLSurfaceView. Esto evitará que coloque otras vistas (por ejemplo, TextView) en la parte superior de su transparente GLSurfaceView. Incluso los cajones de navegación no pueden deslizarse por encima del transparente GLSurfaceView (ignorando tricks). Transparente o no, GLSurfaceView solo puede existir arriba o debajo de otras vistas de Android y no entre ellas.
  2. La transparencia requiere que use setEGLConfigChooser y setFormat como en el ejemplo siguiente. Eso significa que no se puede obtener el formato predeterminado elegido por el sistema que hubiera sido el mejor para ese dispositivo en particular. Lo que es más importante, deberá asegurarse de que el dispositivo tenga el formato compatible y elegir alternativas si el formato esperado no está presente como en este gsoc example.

Otras opciones para la transparencia.

  1. Al ejecutar Tracer para OpenGL en Android, se mostrará que, las imágenes de fondo para las actividades se dibujan como texturas opengl. Entonces, en lugar de hacer GLSurfaceView transparente, si es posible, también puede renderizar su fondo como una textura opengl en GLSurfaceView.
  2. Además, el canal alfa o la transparencia en la superficie no son requisitos previos para la mezcla alfa en OpenGL. Ambos son independientes.
  3. TextureView (trick) es una buena alternativa si su componente opengl debe integrarse entre otras vistas. Este juego breakout es un muy buen ejemplo para el dibujo 2D de GLSurfaceView en Android.

Muestra de abajo con el xml de presentación y el código para GLSurfaceView transparentes con el fondo.

  1. archivo xml diseño con el fondo de color 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. archivo MainActivity.java. Cambiar ALPHA la variable de 0.0 a 1.0 para ver color de la superficie red mezcla con el color de la actividad de fondo 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); 
          } 
         }); 
        } 
    } 
    
+0

'GLSurfaceView' ** es ** una subclase de' Ver'.Consulte la jerarquía de herencia en la parte superior de la página de documentación: http://developer.android.com/reference/android/opengl/GLSurfaceView.html. –

+0

Gracias. Estoy equivocado y lo corregiré. – Kiran