Skip to content
Search

Android.opengl.GLSurfaceView

lastmod 2018-08-17created 2016-05-148 edits

Methods

requestRender()
Call this when the screen needs to be rendered again.

GLSurfaceView.Renderer

Handles rendering.

onSurfaceCreated(GL10 gl, EGLConfig config)
Event fired when the Surface is created.
onSurfaceChanged(GL10 gl, int w, int h)
Event fired when the Surface changes.
onDrawFrame(GL10 gl)
Event fired when the screen is to be drawn.

Capture screen of GLSurfaceView to bitmap

Here is how to capture a GLSurfaceView and copy it to a Bitmap. Note that it must be applied in onDrawFrame(), so watch out for synchronization and bottlenecks.

private Bitmap createBitmapFromGLSurface(int x, int y, int w, int h, GL10 gl)
        throws OutOfMemoryError {
    int bitmapBuffer[] = new int[w * h];
    int bitmapSource[] = new int[w * h];
    IntBuffer intBuffer = IntBuffer.wrap(bitmapBuffer);
    intBuffer.position(0);

    try {
        gl.glReadPixels(x, y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, intBuffer);
        int offset1, offset2;
        for (int i = 0; i < h; i++) {
            offset1 = i * w;
            offset2 = (h - i - 1) * w;
            for (int j = 0; j < w; j++) {
                int texturePixel = bitmapBuffer[offset1 + j];
                int blue = (texturePixel >> 16) & 0xff;
                int red = (texturePixel << 16) & 0x00ff0000;
                int pixel = (texturePixel & 0xff00ff00) | red | blue;
                bitmapSource[offset2 + j] = pixel;
            }
        }
    } catch (GLException e) {
        return null;
    }

    return Bitmap.createBitmap(bitmapSource, w, h, Bitmap.Config.ARGB_8888);
}

How to make the GLSurfaceView background transparent

setEGLConfigChooser(8, 8, 8, 8, 16, 0);
getHolder().setFormat(PixelFormat.TRANSLUCENT);

Example

JniCanvasTest.java:

package com.example;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;

public class JniCanvasTest extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MapView(getApplicationContext()));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}

MapView.java:

package com.example;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.view.MotionEvent;
public class MapView extends GLSurfaceView implements Renderer {
    public MapView(Context context) {
        super(context);

        this.setRenderer(this);
        this.requestFocus();
        this.setRenderMode(RENDERMODE_WHEN_DIRTY);
        this.setFocusableInTouchMode(true);

//      try {
//          Thread.sleep(3000);
//      } catch (InterruptedException e) {
//          e.printStackTrace();
//      }
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // nativeCreated();
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // nativeChanged(width, height);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        // nativeUpdate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        requestRender();
        return super.onTouchEvent(event);
    }
}

Troubleshooting

IllegalStateException: setRenderer has already been called for this instance

This error can appear when setRenderer() is called in the wrong order. Corrected, it looks similar to the example below.

setEGLContextClientVersion(2);
setRenderer(this);

// 화면갱신요청이 있을 때 까지 대기.
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

// 화면을 지속적으로 갱신.
// setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
requestRender();

See also

Favorite site

References


  1. Introducing_glsurfaceview.pdf ↩

  2. Glsurfaceview_analysis_1.pdf ↩

  3. Glsurfaceview_analysis_2.pdf ↩