1

您好,我最近一直在 android ndk 上使用 OpenGL ES 1.1,但我遇到了一个问题。发生的事情是我在屏幕上呈现一个简单的红色方块,当我启动应用程序时,方块完美显示,但是当我点击主页按钮并返回应用程序时,方块不再显示。getError我在调用后尝试调用glDrawArrays以查看是否发生错误并且它总是返回GL_NO_ERROR。我在 android 网站上读到以下内容:

在某些情况下,EGL 渲染上下文会丢失。这通常发生在设备在进入睡眠状态后唤醒时。当 EGL 上下文丢失时,与该上下文关联的所有 OpenGL 资源(例如纹理)将被自动删除。为了保持正确渲染,渲染器必须重新创建它仍然需要的任何丢失的资源。onSurfaceCreated(GL10, EGLConfig) 方法是一个方便的地方。

我所做的是在活动的每个阶段都在 log cat 上打印,当点击主页按钮并返回应用程序时,系统没有调用onSurfaceCreated. 我还尝试在 log cat 中打印我的顶点,以检查它们是否以某种方式被破坏,我只是发送了错误的值,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

让我感到奇怪的一件事是,在我的手机上按主页按钮后再次运行该应用程序时,系统会调用该功能onSurfaceChanged两次。不知道它是否与任何事情有关,但它只是奇怪。

如果有人可以帮助我,我将非常感激: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这个时间时,值乘以在我的应用程序被中断之前设置的值。这会导致我的 Ortho 放大一个平方因子。使我的 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 回答