【问题标题】:android OpenGL ES simple Tile generator performance problemandroid OpenGL ES simple Tile generator 性能问题
【发布时间】:2010-01-24 22:18:46
【问题描述】:

关注这个问题:Best approach for oldschool 2D zelda-like game

感谢之前的回复,并在http://insanitydesign.com/wp/projects/nehe-android-ports/ 的主要启发下,我开始为我的简单 2D 类似塞尔达的游戏项目构建一个简单的 Tile Generator。

我现在可以生成具有相同纹理图块的地图,使用 2 次 for(..) 叠瓦迭代来绘制水平和垂直图块,并让一些基本的 DPAD 键输入侦听器在 x 和 y 轴上滚动。

但现在我遇到了我的第一个性能问题,只有一个纹理和一个模型。

在尝试构建 10x10 地图时,滚动非常流畅。

尝试使用 50x50 时,情况会变得更糟,而使用 100x100 时,情况会变得不可接受。

有没有办法只告诉 OpenGL 渲染我的地图集的“可见”部分并忽略隐藏的图块?我对此完全陌生。

我正在使用

GLU.gluLookAt(gl, cameraPosX, cameraPosY, 10.0f,cameraPosX, cameraPosY, 0.0f, 0.0f, 1.0f, 0.0f);

设置相机和视角以获得 2D 风格的感觉。

有什么帮助吗? :)

for (int j = 0; j < 10; j++) {

        for (int i = 0; i < 10; i++) {

            gl.glPushMatrix(); // Sauvegarde la matrice sur le stack

            //Bind the texture according to the set texture filter
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[filter]);
            //Set the face rotation
            gl.glFrontFace(GL10.GL_CW);
            //Enable texture state
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
            //Enable vertex state
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            //Point to our vertex buffer
            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
            //point to our texture buff
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
            //Draw the vertices as triangle strip
            gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
            //Disable the client state before leaving
            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

            gl.glTranslatef(1.0f, 0.0f, 0.0f); // on avance d'une tile
        }
        // on va commencer a dessiner la 2e ligne
        gl.glPopMatrix(); // Rappelle la matrice sur le stack
        gl.glTranslatef(0.0f, -1.0f, 0.0f);
    }

【问题讨论】:

    标签: android opengl-es


    【解决方案1】:

    循环变慢的原因是它使 OpenGL 做了很多不必要的工作。这是因为有很多冗余的状态变化。

    这意味着您正在调用带有没有任何效果的参数的 gl 函数。调用这些函数会占用大量 CPU 时间,并且可能会导致整个 OpenGL 管道停止,因为它不能非常有效地工作。

    例如,仅当您想更改使用的纹理时才应调用 glBindTexture。上面的代码在内部循环中一遍又一遍地绑定相同的纹理,这是非常昂贵的。同样,您不需要在内部循环中启用和禁用纹理坐标和顶点数组。即使在内循环中设置纹理坐标指针和顶点指针也是不必要的,因为它们在后续循环之间不会改变。

    底线是,在内部循环中,您应该只更改翻译并调用 glDrawArrays。其他一切都白白消耗资源。

    您可以做一些更高级的事情来加快速度。可以绘制平铺背景,使其仅导致一次调用 glDrawArrays(或 glDrawElements)。如果您对批处理和纹理图集等主题感兴趣,您应该 Google 一下。

    【讨论】:

      【解决方案2】:

      您可以轻松地使您的循环仅绘制可见的咏叹调。 这是一些需要如何完成的示例。我不知道 android API,所以将我的示例作为元代码线程化。

      int cols = SCREEN_WIDTH / TILE_SIZE + 1;      // how many columns can fit on the screen
      int rows = SCREEN_HEIGHT / TILE_SIZE + 1;     // haw many rows can fit on the screen
      int firstVisibleCol = cameraPosX / TILE_SIZE; // first column we need to draw
      int firstVisibleRow = cameraPosY / TILE_SIZE; // first row we need to draw
      
      // and now the loop becomes
      for (int j = firstVisibleRow; j < rows; j++) {
          for (int i = firstVisibleCol ; i < cols; i++) {
              ...
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-23
        • 2011-11-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多