1

こんにちは、私は最近、Android ndk で OpenGL ES 1.1 をいじっていますが、問題が発生しています。アプリを起動すると正方形が完全に表示されますが、ホームボタンを押してアプリに戻ると、正方形が表示されなくなります。エラーが発生したかどうかを確認するために呼び出した後に呼び出してみましたが、常に が返されgetErrorます。Androidサイトで次のことを読みました:glDrawArraysGL_NO_ERROR

EGL レンダリング コンテキストが失われる状況があります。これは通常、デバイスがスリープ状態から復帰したときに発生します。EGL コンテキストが失われると、そのコンテキストに関連付けられているすべての OpenGL リソース (テクスチャなど) が自動的に削除されます。正しくレンダリングし続けるために、レンダラーはまだ必要な失われたリソースを再作成する必要があります。onSurfaceCreated(GL10, EGLConfig) メソッドは、これを行うのに便利な場所です。

私がしたことは、アクティビティのすべての段階でログ猫に出力し、ホームボタンを押してアプリに戻ると、システムが呼び出していませんonSurfaceCreated. また、log cat my vertices を印刷して、何らかの形で頂点が破壊され、間違った値を送信していることを確認しましたが、問題はなかっglVertexPointerたようです。コードは次のとおりです。

    static jint initialize(JNIEnv* env, jobject obj, jint width, jint height){
        glViewport(0, 0, width, height);

        glMatrixMode(GL_PROJECTION);
        glOrthof(0, width, height, 0, -1, 1);

        glClearColor(100.0f/255.0, 149.0f/255.0f, 237.0/255.0f, 1.0f);

    }

    struct Vertex {
         float Position[2];
         float Texture[4];
    };

    static void gameRun(JNIEnv* evn, jobject obj) {
         glClear(GL_COLOR_BUFFER_BIT);

         const Vertex Vertices[] = {
        {{ 0.0f, 100.0f },   { 1.0f, 0.0f, 0.0f, 1.0f }},
        {{ 0.0f,  0.0f },    { 1.0f, 0.0f, 0.0f, 1.0f }},
        {{ 100.0f, 100.0f }, { 1.0f, 0.0f, 0.0f, 1.0f }},
        {{ 100.0f,  0.0f },  { 1.0f, 0.0f, 0.0f, 1.0f }},
         };

         glMatrixMode(GL_MODELVIEW);
         glLoadIdentity();

         glEnableClientState(GL_VERTEX_ARRAY);
         glEnableClientState(GL_COLOR_ARRAY);

         glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &Vertices[0].Position[0]);
         glColorPointer(4, GL_FLOAT, sizeof(Vertex), &Vertices[0].Texture[0]);

         GLsizei vertexCount = sizeof(Vertices) / sizeof(Vertex);
         glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexCount);

         glDisableClientState(GL_VERTEX_ARRAY);
         glDisableClientState(GL_COLOR_ARRAY);
    }

注:関数initializeは と から呼び出さonSurfaceCreatedgameRunますonDrawFrame

私が奇妙に感じたことの 1 つは、ホーム ボタンの後に私の電話でアプリを再度実行すると、システムが関数をonSurfaceChanged2 回呼び出すことでした。それが何かと関係があるかどうかはわかりませんが、ただ奇妙です。

誰かが私を助けてくれたら、本当に感謝しています:D

4

1 に答える 1

1

さて、いくつかのテストを行い、いくつかのサンプルプロジェクトと比較した後、私は物事の束に気づきました。あるプロジェクトでは、glOrthofを呼び出すときに、左右の幅と高さの比率を渡し、上部と下部に-1と1を渡します。

float ratio = width / height;
glOrthof(-ratio, ratio, -1, 1, -1, 1);

そして、ホームボタンを押してアプリをもう一度実行すると、正方形が拡大縮小することに気づきました。

別のプロジェクトでは、単純に射影行列を作成し、gameRun関数でglLoadMatrixを使用して設定します。

mat4 projection = mat4::Frustum(-2, 2, -h / 2, h / 2, 5, 10);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(projection.Pointer());

そして、ホームボタンを押してアプリをもう一度実行すると、今回は問題なく正方形が表示されることがわかりました。次に、OpenGL ES 1.1のドキュメントを読み始め、次のことを発見しました。

glOrthoは、平行投影を生成する変換について説明します。現在の行列(glMatrixModeを参照)にこの行列が乗算され、その結果が現在の行列を置き換えます...

そして、それは突然私を襲います...ホーム割り込みから戻った後、私のアプリケーションは以前に作成されたコンテキストを使用しているためです。つまり、実際に起こっているのは、glOrthof今回呼び出すと、アプリケーションが中断される前に設定された値が値に乗算されるということです。これにより、私のオルソが二乗に拡大します。100 x 100の正方形を作成して、本当に本当に小さくレンダリングします。glLoadIndentityこれを修正するために、呼び出す前に単に追加しましたglOrthof

static jint initialize(JNIEnv* env, jobject obj, jint width, jint height){
   glViewport(0, 0, width, height);

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrthof(0, width, height, 0, -1, 1);

   glClearColor(100.0f/255.0, 149.0f/255.0f, 237.0/255.0f, 1.0f);
}

これglLoadIdentityは、以前に存在していた値を単位行列に置き換えるために機能します。

glLoadIdentityは、現在の行列を単位行列に置き換えます。 これは、単位行列を使用してglLoadMatrixを呼び出すことと意味的に同等です。

(1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1)

そして、このように問題を修正します!:D

于 2012-07-04T15:01:49.980 に答える