Android OpenGL ES对象冻结在睡眠/屏幕锁定



我已经用OpenGL ES建立了一个项目,并成功导入了jBox2D库。我做了一个测试项目,其中包括两个直坠。工作好了!然而,当屏幕进入睡眠状态或我锁定屏幕时,下落的物体在我锁定屏幕的位置停止,当我解锁屏幕时,它们甚至不会继续下落,只是冻结,另外两个矩形将在起始位置创建。它似乎重置了整个应用程序但之前的对象却冻结在那里。

代码如下:

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();
    }
}

渲染器:

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) {
    }
}

与矩形类,我只是绘制矩形,所以我认为问题是在这段代码。所以问题是我如何设法以某种方式"保存"应用程序的状态在屏幕锁定和防止冻结对象在屏幕上。所以基本上是在屏幕被锁定的状态下继续应用

谢谢!

任何时候你的应用失去焦点,或者更确切地说有onpause调用,opengl将破坏你的资源,他们将不得不重新制作。(至少这是我上次使用opengl的情况),所以我认为你的引擎正在试图处理这个,我们应该处理它,而不是。

如果你不知道发生了什么,Android上下文丢失可能会产生奇怪的事情。当你在暂停后返回到你的应用时,你的onSurfaceCreated会再次被调用所以你能重建你的GL context。

你指出的行为是可以解释的。您将您的主体添加到静态列表中,该列表在暂停期间不会被销毁 (只有GL对象被销毁)。但你不会将它们重新添加到你的世界中(你重新创造了世界,所以它是空的)。现在明白为什么有4个对象,2个静止了吗?如果您这样做了,我相信现在您可以轻松地自己解决这个问题,但这里有一个片段作为开始,并向您介绍GL线程和管理:

//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);
    }

最新更新