2012-12-24 148 views
0

Android的OpenGL ES的對象feeze我已成立了一個項目的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) { 

    } 

} 

隨着矩形類我只是畫出矩形,所以我認爲這個問題是在此代碼。所以問題是我如何能夠以某種方式在屏幕鎖定中「保存」應用程序的狀態並防止凍結屏幕上的對象。所以基本上是在屏幕鎖定的狀態下繼續應用程序。

謝謝!

回答

0

任何時候,您的應用程序失去焦點,或者說已經在onPause叫時,OpenGL會破壞你的資源,他們將不得不重拍。 (至少在我上次使用opengl的時候是這樣),所以我認爲你的引擎正在試圖處理這個,我們應該處理它,而不是。

0

的Android方面的損失可能會產生奇怪的事情,如果你不知道發生了什麼。當您在暫停後返回到您的應用程序時,您的onSurfaceCreated會再次被調用,以便您可以重建您的GL上下文。

你指出的行爲是很可以解釋。您將您的身體添加到靜態列表中,該列表在暫停期間不會被銷燬(僅限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); 

    }