As per the title, the GLSurfaceView is blank after resuming from a paused state. The Renderer's onSurfaceCreated
, onSurfaceChanged
, and onDrawFrame
get called after it resumes, but the screen is still blank!
Here's the relevant code:
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
boxWidth = 0.5f;
boxHeight = 0.5f;
boxCenter = new float[] { 0.5f, 0.5f };
Log.v("resume", "onSurfaceCreated");
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0, 1, 0, 1, -5, 5);
gl.glMatrixMode(GL10.GL_MODELVIEW);
viewHeight = height;
viewWidth = width;
Log.v("resume", "onSurfaceChanged");
}
@Override
public void onDrawFrame(GL10 gl) {
gl.glLoadIdentity();
float halfW = boxWidth/2.0f;
float halfH = boxHeight/2.0f;
float left = Math.max(boxCenter[0]-halfW, 0.001f);
float right = Math.min(boxCenter[0]+halfW, 0.999f);
float top = Math.min(boxCenter[1]+halfH, 0.999f);
float bottom = Math.max(boxCenter[1]-halfH, 0.001f);
boxHeight = Math.max(top - bottom, 0.05f);
boxWidth = Math.max(right - left, 0.05f);
boxCenter[0] = left + boxWidth/2.0f;
boxCenter[1] = bottom + boxHeight/2.0f;
float vertices[] = {
left, top, 0.0f,
left, bottom, 0.0f,
right, bottom, 0.0f,
right, top, 0.0f
};
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
gl.glTranslatef(0.001f, -0.001f, -3.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
vertexBuffer.position(0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
Log.v("resume", "drawing");
}
I've read that you need to recreate the GL context inside onSurfaceChanged, but I'm not sure how, or if I already did when onSurfaceCreated was called.
Please help!
Edit:
Here's the onResume
code from the Activity that contains the GLSurfaceView: (called GLSurface here)
public void onResume() {
super.onResume();
if (mGLSurface != null) {
if (mRenderer != null) {
float[] center = new float[2];
center[0] = settings.getFloat("renderer_boxCenter0", 0.5f);
center[1] = settings.getFloat("renderer_boxCenter1", 0.5f);
mRenderer.setBoxCenter(center);
mRenderer.setBoxWidth(settings.getFloat("renderer_boxWidth", 0.5f));
mRenderer.setBoxHeight(settings.getFloat("renderer_boxHeight", 0.5f));
}
mGLSurface.onResume();
}
I didn't do much in the onResume for the GLSurfaceView, and I didn't find any documentation that suggested that I need to do anything in particular to get my EGL context back either.
Edit 2:
I would also like to note that calling setPreserveEGLContextOnPause(true)
in the constructor of my GLSurfaceView did not, unfortunately, solve my problem.
setPreserveEGLContextOnPause(true) is only supported on devices with Android 3.X and up. (even then it is device specific whether it is supported)
The solution your looking for is in the parent activity of the GlSurfaceView you call GlSurfaceView.onPause() in the onPause method of the activity and GlSurfaceView.onResume() in the onResume method of the activity.
Note this causes all of your textures and buffers to be lost. You need to reload them at this point.
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