Android OpenGL ES Transparent Background
Asked Answered
R

5

28

I'm building an Android app that takes advantage of OpenGL. As it stands, the background for the GLSurfaceView is dynamically generated by my code and loaded in as a texture and drawn with glDrawTexfOES. Which is "ok", but I can simply display the image much more smoothly to its own surface (without OpenGL). Is there any way that I can make the background of a GLSurfaceView transparent? I've heard some rumors that this can be done with setEGLConfigChooser, but I haven't found any confirmation. Ultimately, I'd like to take a surface which I'm drawing to and put the GLSurfaceView over it to achieve a layered effect.

I know this is a tricky and is quite possibly infeasible, but any input is appreciated. Thanks in advance.

Raleighraley answered 9/1, 2010 at 20:28 Comment(1)
I don't know much about Open GL but if you take a look in the API examples there's a Class called TranslucentGLSurfaceViewActivity in package com.example.android.apis.graphics. Does that help?Blastoff
R
46

Just some simple changes that I did to get this to work.

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

On my GLSurfaceView:

setEGLConfigChooser(8, 8, 8, 8, 16, 0);
getHolder().setFormat(PixelFormat.TRANSLUCENT);
Raleighraley answered 3/2, 2010 at 23:21 Comment(3)
I have set the GLSurfaceView as you wrote, and put the upper code in my custom GL renderer, and I still get a black Background. Do you have any ideas on why that might be.Veinule
This WORKED for me. But, the contents of my view have gone blank as well. There's only a white canvas but nothing draws on it. Any help?Interpol
I just removed the given code from onSurfaceCreated() method and it worked for me like I wanted. All I'm using now are the two lines of codes in my GLSurfaceView's init() method.Interpol
D
23

Your GLSurfaceView also requires setZOrderOnTop(true);

Ducktail answered 22/6, 2011 at 18:9 Comment(3)
and for this minimum sdk level 6 is needed.Blather
This will solve the issue, But you won't be able to display any other view on top of GLSurfaceView if needed.Smug
I spent all of yesterday working on a workaround for that. The solution is to implement Romain's answer groups.google.com/forum/#!topic/android-developers/U5RXFGpAHPE and making sure you call setOpacity(false) in the constructor for the view as well as enabling alpha via other answers here (this solution does NOT require setZOrderOnTop())Dorree
E
10

I use my own GLSurfaceView class to display charts (transparent background / overlay). My extended GLSurfaceView is embed via XML into a popover window.

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

As part of the activity I added this code:

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

Last but not least my GLSurfaceView looks like this:

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

My renderer class GLPieChartRenderer does not call glClearColor at all.

Erring answered 15/7, 2012 at 20:40 Comment(1)
Please don't duplicate your answers across questions. If one of the questions is a duplicate of the other, then flag it for closure (or leave a comment indicating that it's a duplicate -- a higher rep user will then flag or vote to close it). If the questions truly are different, then tailor your answer to each question posed.Durwood
R
5

Code sample at the end is for enabling transparency with GLSurfaceView. But before using transparency with GLSurfaceView, consider the following negative points.

  1. Enabling transparency requires that you use setZOrderOnTop on GLSurfaceView. That will prevent you from placing any other views ( e.g. TextView ) on top of your transparent GLSurfaceView. Even Navigation drawers cannot slide above the transparent GLSurfaceView( ignoring tricks ). Transparent or not, GLSurfaceView can only exist above or below other android views and not in between them.
  2. Transparency requires that you use setEGLConfigChooser and setFormat as in below example. That means, you cannot get what would have been default format chosen by system which would have been the best for that particular device. More importantly, you will need to ensure that the device has the supported format and chose alternatives if expected format isn't present as in this gsoc example.

Other options to transparency.

  1. Running Tracer for opengl in Android, will show that, background images for activities are drawn as opengl textures. So instead of making GLSurfaceView transparent, if possible, you can as well render your background as an opengl texture in GLSurfaceView.
  2. Also, alpha channel or transparency on the surface is not pre requirement for alpha blending in opengl. Both are independent.
  3. TextureView (trick) is good alternative if your opengl component is to be embedded between other views. This breakout game is a very good example for GLSurfaceView 2d drawing in Android.

Below sample with layout xml and code for transparent GLSurfaceView with background.

  1. Layout xml file with green color background

    <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 file. Change ALPHA variable from 0.0 to 1.0 to see surface color red mixing with background activity color 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 );
                }
            });
        }
    }
    
Redbud answered 29/11, 2014 at 15:6 Comment(1)
GLSurfaceView is a subclass of View. See the inheritance hierarchy at the top of the documentation page: developer.android.com/reference/android/opengl/….Girandole
S
1

you should make sure the activity background is transparent!

If the activity's background is opaque, say white by default, then even when the content view (the glsurfaceview) is translucent, it will display the activity's white background as its background.

You can set the activity background transparency in the Android.manifest where it is declared, see the official API demo TranslucentGLSurfaceViewActivity for help

Sheepdog answered 29/11, 2013 at 9:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.