2013-07-26 7 views
9

cerco di rendere utilizzando GLSurfaceView, e docs I impostare il formato:GLSurfaceView - come rendere sfondo traslucido

getHolder().setFormat(PixelFormat.TRANSLUCENT); 

L'uso GLSurfaceView.Renderer, che attira in onDrawFrame:

GLES20.glClearColor(0, 0, 1, .5f); 
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); 

Tuttavia, il rendering GL in GLSurfaceView non è traslucido ed è completamente blu. Se ometto la chiamata glClear, allora è completamente nera.

Come faccio a rendere il rendering GL in modo da avere uno sfondo trasparente, in modo che si fonda con le viste disegnate dietro di esso?

enter image description here

EDIT: ecco la mia GLSurfaceView:

class GLView extends GLSurfaceView{ 
    MyRenderer r; 
    public GLView(Context ctx){ 
     super(ctx); 
     setEGLContextClientVersion(2); 

     getHolder().setFormat(PixelFormat.TRANSLUCENT); 

     setEGLConfigChooser(8, 8, 8, 8, 16, 0); 
     r = new MyRenderer(getContext()); 
     setRenderer(r); 
    } 
} 

risposta

6

OK, dopo alcune ricerche posso rispondere io stesso.

Ho finalmente realizzato il disegno con trasparenza utilizzando SurfaceView.setZOrderOnTop (true). Ma poi ho perso la possibilità di posizionare altre viste in cima al mio GLSurfaceView.

ho finito con due possibili risultati:

behindon top

Sulla sinistra è superficiale GL standard al di sotto tutte le altre viste, che non possono essere disegnate con la trasparenza, perché la superficie GL viene disegnato prima superficie della finestra dell'applicazione e GLSurfaceView è appena punches hole nella sua posizione in modo che la superficie GL sia visibile.

A destra è la superficie GL trasparente disegnata con setZOrderOnTop (true), quindi la sua superficie viene disegnata sopra la finestra dell'applicazione. Ora è trasparente, ma è tracciato sopra altre viste posizionate su di esso nella gerarchia della vista.

Quindi sembra che l'applicazione abbia una finestra con superficie per la sua gerarchia di viste, e SurfaceView ha una superficie per GL, che può essere sopra o sotto la finestra dell'app. Sfortunatamente, la vista GL trasparente non può essere ordinata correttamente all'interno della gerarchia delle viste con altre viste su di essa.

+0

Perché non hai assegnato la tua taglia? –

+2

Non posso assegnare la mia risposta, e altre risposte non mi soddisfano. –

0

Non sono sicuro di quale sia il problema esattamente, ma un'alternativa potrebbe essere coprendo lo schermo con un rettangolo colorato traslucido e proprio cancellazione del bit del buffer di profondità.

Is there any alternative for GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)?

In caso contrario assicurarsi che la profondità di bit del buffer è di 1

Torno più tardi per cercare di ricreare il problema sul mio telefono in un po 'quando posso.

Modifica: Mi sono appena reso conto che il motivo per cui appare blu può essere che lo impostate su .5f, quindi ci vogliono solo 2 chiamate per ottenere l'opacità completa. il che significa che a 30fps 1/15 di secondo è necessario diventare completamente blu.

provare a ridurre il valore di trasparenza alfa per 0.01f o 0.05f

+0

Teoria sbagliata, anche impostando l'alfa su 0 non ha apportato modifiche. Forse pensi che la compensazione aggiunga valori rispetto alla precedente. Tuttavia, il flinger di superficie dovrebbe comporre correttamente le superfici dello schermo, incluso il canale alfa della superficie GL. –

5

È necessario formato RGBA 8888 pixel per traslucenza:

private void init(boolean translucent, int depth, int stencil) 
{ 
    /* By default, GLSurfaceView() creates a RGB_565 opaque surface. 
    * If we want a translucent one, we should change the surface's 
    * format here, using PixelFormat.TRANSLUCENT for GL Surfaces 
    * is interpreted as any 32-bit surface with alpha by SurfaceFlinger. 
    */ 
    this.getHolder().setFormat(PixelFormat.RGB_565); 
    if (translucent) 
    { 
     this.getHolder().setFormat(PixelFormat.TRANSLUCENT); 
    } 

    setEGLContextFactory(new ContextFactory()); 

    /* We need to choose an EGLConfig that matches the format of 
    * our surface exactly. This is going to be done in our 
    * custom config chooser. See ConfigChooser class definition 
    * below. 
    */ 
    setEGLConfigChooser(translucent ? 
         new ConfigChooser(8, 8, 8, 8, depth, stencil) : 
         new ConfigChooser(5, 6, 5, 0, depth, stencil)); 

    setRenderer(new Renderer()); 
} 
+0

Come puoi vedere dalla mia domanda, ho impostato PixelFormat.TRANSLUCENT. –

+0

Impostalo su 8888? –

+0

Sì, ho provato anche questo. Ma i documenti parlano di PixelFormat.TRANSLUCENT dovrebbe essere impostato. –

1

Hai mai pensato di utilizzare uno LayerDrawable con setAlpha? Ecco un esempio che ho di due immagini ... una è trasparente (di setAlpha) e l'altra no. La 'calendar_cell' è solida ed è sul retro, quindi arriva la scatola che è trasparente per mostrare la cella del calendario dietro di essa. In questo modo puoi impilare tutte le immagini che desideri dando loro una trasparenza diversa.

Drawable []layers = new Drawable [2]; 
int imageResource1 = mContext.getResources().getIdentifier("drawable/calendar_cell", null, mContext.getPackageName()); 
Drawable background = v.getResources().getDrawable(imageResource1); 
         layers [0]= background; 

int imageResource = mContext.getResources().getIdentifier("drawable/box_" + box, null, mContext.getPackageName()); 
Drawable boxImg = v.getResources().getDrawable(imageResource); 
    boxImg.setAlpha(100); 
    layers [1]= boxImg; 

LayerDrawable layerDrawable = new LayerDrawable (layers); 
v.setBackground(layerDrawable)