机器人的OpenGL ES简单的瓷砖产生性能问题

问题描述:

以下这个问题:Best approach for oldschool 2D zelda-like game机器人的OpenGL ES简单的瓷砖产生性能问题

感谢以前的答复,并与http://insanitydesign.com/wp/projects/nehe-android-ports/的主要灵感,我开始建立一个简单的瓷砖发生器我简单的2D塞尔达般的游戏项目。

我现在可以生成具有相同纹理图块的地图,使用2(...)重叠迭代绘制水平和垂直图块,并获得一些基本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风格感觉IM。

任何帮助? :)

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 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++) { 
     ... 
    } 
} 
+0

感谢元理念为我工作:) – Dullahx 2010-01-30 23:42:09

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

这意味着你正在用不起任何作用的参数调用gl函数。调用这些函数会消耗大量的CPU时间,并可能导致整个OpenGL管道停滞,因为它无法有效地工作。

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

底线是,在内部循环中,您应该只更改翻译并调用glDrawArrays。其他任何东西都只会耗尽资源。

还有更高级的事情可以加快速度。可以绘制平铺背景,以便只对glDrawArrays(或glDrawElements)进行一次调用。如果你有兴趣,你应该像谷歌主题像批处理和纹理地图集。