2013-07-26 24 views
9

próbuję uczynić używając GLSurfaceView, a przez docs ustawić format:GLSurfaceView - jak zrobić półprzezroczyste tło

getHolder().setFormat(PixelFormat.TRANSLUCENT); 

The używam GLSurfaceView.Renderer, która zasysa onDrawFrame:

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

Jednak renderowanie GL w GLSurfaceView nie jest półprzezroczyste i jest w pełni niebieskie. Jeśli pominąć wywołanie funkcji glClear, oznacza to, że jest całkowicie czarny.

Jak sprawić, aby renderowanie GL miało przezroczyste tło, aby było mieszane z widokami narysowanymi za nim?

enter image description here

EDIT: tu jest mój 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); 
    } 
} 

Odpowiedz

6

OK, po kilku badań mogę odpowiedzieć na to pytanie sam.

W końcu udało mi się go narysować z przezroczystością za pomocą SurfaceView.setZOrderOnTop (true). Ale potem straciłem możliwość umieszczania innych widoków na moim GLSurfaceView.

skończyło z dwóch możliwych wyników:

behindon top

Na lewo jest średnia powierzchnia GL poniżej wszystkich innych widoków, których nie można wyciągnąć z przezroczystością, ponieważ GL powierzchnia jest sporządzony przed powierzchni okna aplikacji i GLSurfaceView tylko punches hole w swoim położeniu, dzięki czemu widoczna jest powierzchnia GL.

Po prawej stronie jest przezroczysta powierzchnia GL narysowana za pomocą setZOrderOnTop (true), a więc jej powierzchnia jest narysowana w górnej części okna aplikacji. Teraz jest przezroczysty, ale jest rysowany na innych widokach umieszczonych w hierarchii widoku.

Wygląda na to, że aplikacja ma jedno okno z powierzchnią dla swojej hierarchii widoku, a SurfaceView ma własną powierzchnię dla GL, która może znajdować się w górnej lub dolnej części okna aplikacji. Niestety, przejrzysty widok GL nie może być poprawnie uporządkowany w hierarchii widoków z innymi widokami na wierzchu.

+0

Dlaczego nie przyznałeś swojej nagrody? –

+2

Nie mogę wyrazić swojej własnej odpowiedzi, a inne odpowiedzi mnie nie zadowalały. –

0

Nie jestem pewien, co problem jest dokładnie ale alternatywą może być pokrycie ekranu z przezroczystego kolorowego prostokąta i tylko czyszczenie bitu bufora głębokości.

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

przeciwnym razie upewnij się, że nieco bufor głębokości 1

Wrócę później spróbować odtworzyć problem na moim telefonie w kawałku, kiedy tylko mogę.

Edit: Właśnie sobie sprawę, że przyczyną tego, że pojawia się niebieski może być, że można ustawić go .5f więc zajmuje tylko 2 połączenia na to, aby dostać się do pełnego 1f kryciem. co oznacza, że ​​potrzeba 30 klatek na sekundę 1/15 sekundy, aby przejść całkowicie na niebiesko.

Spróbuj zmniejszyć wartość alfa przezroczystości do 0.01f lub 0.05f

+0

Zła teoria, nawet ustawienie alfa na 0 nie spowodowało zmiany. Może myślisz, że wyczyszczenie dodaje wartości z wcześniejszego wyczyszczenia. Jednakże odrzutnik powierzchni powinien poprawnie komponować powierzchnie ekranu, w tym kanał alfa powierzchni GL. –

5

Trzeba RGBA 8888 formatu pikseli dla przezierności:

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

Jak widać z mojego pytania, ustawiłem PixelFormat.TRANSLUCENT. –

+0

Czy ustawiasz go na 8888? –

+0

Tak, spróbowałem również tego. Ale należy wspomnieć o dokumentach PixelFormat.TRANSLUCENT. –

1

Czy myślałeś o użyciu zestawu LayerDrawable z zestawem setAlpha? Oto przykład, w którym mam dwa obrazy ... jeden jest przezroczysty (przez setAlpha), a drugi nie. Komenda "calendar_cell" jest ciągła i znajduje się z tyłu, a następnie jest wyświetlane jako przezroczyste pole, aby wyświetlić komórkę kalendarza. W ten sposób możesz ułożyć tyle obrazów, ile chcesz, dając im inną przezroczystość.

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) 
Powiązane problemy