0

I have set up a project with OpenGL ES and successfully imported the jBox2D library. I have made a test project which includes two rect falling down. Works great! However, when the screen goes to sleep or I lock the screen, the falling objects stop at the position I locked the screen and when I unlock the screen they will not even continue falling just freeze and other two rect will be created at the starting position. So it seems it resets the whole app but the previous object somehow freeze there.

Here is the code:

package com.example.opengltest;

import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;

public class MainActivity extends Activity {

    GLSurfaceView surface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        surface = new GLSurfaceView(this);
        surface.setRenderer(new SimpleRenderer());
        setContentView(surface);
    }


    protected void onPause() {
        super.onPause();
        surface.onPause();
    }

    protected void onResume() {
        super.onResume();
        surface.onResume();
    }
}

The renderer:

package com.example.opengltest;

import java.util.HashSet;
import java.util.Set;

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

import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.collision.shapes.Shape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.FixtureDef;
import org.jbox2d.dynamics.World;

import android.opengl.GLSurfaceView.Renderer;

public class SimpleRenderer implements Renderer {

    private static World world;
    private static Set <Body> bodies = new HashSet<Body>();
    private Rect r;

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig) {

        world = new World(new Vec2(0.0f, -9.8f), false);
        r = new Rect();
        createObject(300, 500, 0.75f, 0.75f, BodyType.STATIC);
        createObject(360, 1200, 0.75f, 0.75f, BodyType.DYNAMIC);

        gl.glViewport(0, 0, 600, 1024); 
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrthof(0, 600, 0, 1024, 1, -1);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    }

    private void createObject(int x, int y, float w, float h, BodyType bType) {
        BodyDef boxDef = new BodyDef();
        boxDef.position.set(new Vec2(x/30/2, y/30/2));
        boxDef.type = bType;
        PolygonShape shape = new PolygonShape();
        shape.setAsBox(w, h);
        Body box = world.createBody(boxDef);
        FixtureDef boxFixture = new FixtureDef();
        boxFixture.density = 1;
        boxFixture.shape = shape;
        box.createFixture(boxFixture);
        bodies.add(box);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        Vec2 vec;
        for(Body body : bodies) {

            vec = body.getPosition();
             r.draw(gl, vec.x * 30, vec.y * 30, body.getAngle());
        }
        world.step(1/60f, 8, 3);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int w, int h) {

    }

}

With the Rect class I just draw the rect so I think the problem is in this code. So the question is how I can manage to somehow 'save' the state of the app on screen lock and prevent to freeze object on the screen. So basically to continue the app in the state when the screen was locked.

Thank you!

stomseven
  • 157
  • 1
  • 2
  • 8

2 Answers2

0

Any time your app loses focus, or rather has onpause called, opengl will destroy your resources and they will have to be remade. (at least this was the case last time I used opengl), so I think your engine is trying to handle this, our you are supposed to handle it and are not.

WIllJBD
  • 6,144
  • 3
  • 34
  • 44
0

Android context loss may produce strange things if you don't know what's happening. When you return to your app after the pause, your onSurfaceCreated gets called again so you can rebuild your GL context stuff.

The behavior you are pointing out is pretty explainable. You add your bodies to the static list , which does not get destroyed during the pause (only GL objects are destroyed). But you do not re-add them to your world (which you do re-create, so it's empty). Do you see now why you get 4 objects and 2 are still? If you do, I'm sure now you could easily solve the problem yourself, but here's a snippet to get started and introduce you to the GL thread and management:

//e.g call this from MainActivity's onCreate. Note this will not be within the openGL
// thread, so you can't do opengl calls! (try it!)
  public void my_non_openGL_stuff_initialization(){
        world = new World(new Vec2(0.0f, -9.8f), false);
        r = new Rect();
        createObject(300, 500, 0.75f, 0.75f, BodyType.STATIC);
        createObject(360, 1200, 0.75f, 0.75f, BodyType.DYNAMIC);
}

 //Note this runs on the opengl thread. You should always recreate all your opengl related
 //things here. This gets called at the begining, and when coming back from a pause
  @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig) {
        gl.glViewport(0, 0, 600, 1024); 
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrthof(0, 600, 0, 1024, 1, -1);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    }
aacotroneo
  • 2,170
  • 16
  • 22