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.
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);
Your GLSurfaceView
also requires setZOrderOnTop(true);
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.
Code sample at the end is for enabling transparency with GLSurfaceView
. But before using transparency with GLSurfaceView
, consider the following negative points.
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.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.
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.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.
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>
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 );
}
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With