0

OpenGL ES を使用してプロジェクトをセットアップし、jBox2D ライブラリを正常にインポートしました。2 つの四角形が落ちるテスト プロジェクトを作成しました。よく働く!ただし、画面がスリープ状態になるか画面をロックすると、落下するオブジェクトは画面をロックした位置で停止し、画面のロックを解除すると落下し続けることさえできず、フリーズするだけで、開始位置に他の 2 つの四角形が作成されます。 . したがって、アプリ全体をリセットするようですが、以前のオブジェクトが何らかの形でそこでフリーズします。

コードは次のとおりです。

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

    }

}

Rect クラスでは rect を描画するだけなので、問題はこのコードにあると思います。したがって、問題は、画面ロック時にアプリの状態をどうにかして「保存」し、画面上のオブジェクトがフリーズするのを防ぐ方法です。なので、基本的には画面ロック時の状態でアプリを継続します。

ありがとうございました!

4

2 に答える 2

0

アプリがフォーカスを失うか、onpause が呼び出されると、opengl はリソースを破棄し、再作成する必要があります。(少なくとも、私が前回openglを使用したときはそうでした)、あなたのエンジンはこれを処理しようとしていると思います。

于 2012-12-25T04:51:43.953 に答える
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);

    }
于 2012-12-27T19:49:14.217 に答える