Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android and OpenGL gives black frame at startup

I'm currently writing an Android app for one my customers that has a GLSurfaceView with a GLSurfaceView.Renderer.

My entire OpenGL stuff works just fine (it's basically a port of what another developer has written on iOS first). Except for one thing. When the view is loaded and thus the OpenGL stuff is getting loaded my background quickly flashes black, and then the OpenGL starts to render correctly (with my background). So what I do is:

In the onSurfaceCreated I start with this:

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    GLES20.glClearColor(0.9f + 0.1f * (21.0f / 255),
            0.9f + 0.1f * (36.0f / 255),
            0.9f + 0.1f * (31.0f / 255), 1.0f);

    // Here goes my other stuff, if I comment all my other stuff out I still get the flash at startup
}

In my onDrawFrame method I do this:

@Override
public void onDrawFrame(GL10 gl) {

    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);

    // My stuff, again, if I comment all this stuff out I still get the flash...
}

So if I remove all lines of code except for the glClearColor(..) in onSurfaceCreated I still see a black flash before my actual background color is set. If I only remove the glClearColor(..) from my code (and thus leave all other OpenGL stuff in place) everything is rendered on a black background.

What I would like to see is that I just get rid of the black flash and thus that my background color is initialised correctly at startup...

Any ideas how I can achieve that?

Dirk

like image 937
dirkvranckaert Avatar asked Nov 14 '13 06:11

dirkvranckaert


1 Answers

I just hit the same problem and have worked around it by using the GLSurfaceView's background property. Here's my XML :

<view class="android.opengl.GLSurfaceView"
    android:id="@+id/glview"
    android:background="@drawable/window_bg"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

Where window_bg is the same drawable as the window background specified in the activity theme.

Having done this you then remove the background drawable in the first call to onDrawFrame(), using a boolean to track whether it's already been done or not :

boolean initialRenderHack;

//
// GLSurfaceView.Renderer
//
@Override
public void onDrawFrame(GL10 gl10) {

       // ... drawing code goes here ...

       // Remove the initial background
       if (!initialRenderHack) {
       initialRenderHack = true;
       view.post(new Runnable() {
           @Override
           public void run() {
               view.setBackgroundResource(0);
           }                
       });
    }

Note that you can only touch a View's background property from the UI thread, not the rendering thread that onDrawFrame() runs on, hence the need to post a runnable.

On Android 4.4 this gives a perfectly fluid startup with no horrible jarring black frame. I haven't yet tried it with older Androids.

like image 167
Reuben Scratton Avatar answered Oct 20 '22 10:10

Reuben Scratton