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
- http://stackoverflow.com/questions/5514149/capture-screen-of-glsurfaceview-to-bitmap
- http://blog.naver.com/ateon1/120145377162
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
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
- GLSurfaceView analysis
- Introducing GLSurfaceView 1
- Reference translation - GLSurfaceView.Renderer
- Introducing GLSurfaceView
- GLSurfaceView analysis-I 2
- GLSurfaceView analysis-II 3
References
Pages that link here