在Android上按下主页按钮后未绘制的三角形

时间:2012-07-04 05:27:17

标签: android opengl-es android-ndk java-native-interface

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

  

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

我所做的是在活动的每个阶段打印日志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

1 个答案:

答案 0 :(得分: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)乘以   这个矩阵和结果取代了当前的矩阵......

它突然袭击了我......因为从home中断回来后,我的应用程序正在使用之前创建的上下文。所以它实际上发生的是当我这次调用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