代码之家  ›  专栏  ›  技术社区  ›  Rob

用opengles在二维空间中定位元素

  •  7
  • Rob  · 技术社区  · 15 年前

    在业余时间,我喜欢在iPhone上用OpenGL ES进行游戏开发。为了好玩,我准备了一个小的2D侧边卷轴演示,我对OpenGL比较陌生,我想获得一些经验丰富的开发人员在这方面的意见。

    所以我的问题是:在模型空间中指定每个2D元素的顶点,然后将每个元素转换为其最终视图空间,这有意义吗 每次 画框?

    例如,假设我有一组方块(正方形),它们构成了侧滚动条中的地面。每个正方形定义为:

    const GLfloat squareVertices[] = {
            -1.0, 1.0, -6.0,            // Top left
            -1.0, -1.0, -6.0,           // Bottom left
            1.0, -1.0, -6.0,            // Bottom right
            1.0, 1.0, -6.0              // Top right
        }
    

    glPushMatrix();
    {
        glTranslatef(currentSquareX, currentSquareY, 0.0);
        glVertexPointer(3, GL_FLOAT, 0, squareVertices);
        glEnableClientState(GL_VERTEX_ARRAY);
    
        // Do the drawing
    }
    glPopMatrix();
    

    在我看来,对场景中的每一个2D元素、每一帧都这样做会有点紧张,我想那些比我更聪明的使用OpenGL的人可能会有更好的方法。

    话虽如此,我希望听到我应该分析代码,看看瓶颈可能在哪里:对那些人来说,我说:我还没有写过任何代码,我只是在把我的思想包裹在它周围,这样当我去写它时,它会变得更流畅。

    在分析和优化的主题上,我并不是想在这里过早地进行优化,我只是想了解如何设置2D场景并进行渲染。就像我说的,我对OpenGL比较陌生,我只是想了解一下事情是如何完成的。如果有人对更好的方法有任何建议,我想听听你的想法。

    请记住,我对3D不感兴趣,现在只对2D感兴趣。谢谢

    3 回复  |  直到 15 年前
        1
  •  6
  •   Andrew Garrison    15 年前

    如果在世界坐标系中构建正方形的顶点,那么当然会更快,因为每个正方形将避免这三个函数(glPushMatrix、glPopMatrix和GLTRANSTEF)的额外成本,因为在渲染时不需要从模型坐标转换到世界坐标。我不知道这会快多少,我怀疑这不会是一个巨大的优化,而且你失去了将方块保持在模型坐标中的模块性:如果将来你决定让这些方块可以移动呢?如果将它们的顶点保持在世界坐标系中,那么这将非常困难。

    简言之,这是一种权衡:

    世界坐标

    • 更多内存-每个方块都需要它的 自己的顶点集。
    • 计算量更少-无需执行 glPushMatrix、glPopMatrix或 渲染时每个正方形的GLTRANSTEF。
    • 用于动态移动这些方块

    模型坐标

    • 内存更少-正方形可以共享相同的顶点数据
    • 更多计算-每个平方必须 渲染时间。
    • 更灵活-正方形可以很容易地 glTranslatef调用。

    我想知道什么是正确决策的唯一方法是做和分析。我知道你说你还没有写这篇文章,但我怀疑无论你的方块是在模型坐标还是世界坐标中,都不会有太大的区别——如果是的话,我无法想象你可以创建一个架构,在那里你很难将方块从模型坐标切换到世界坐标,或者反之亦然。

    祝你好运,祝你在iPhone游戏开发中历险!

        2
  •  4
  •   hyperlogic    15 年前

    OES Draw Texture 扩大然后你可以使用一个纹理来保存你所有的游戏“精灵”。首先,通过设置 GL_TEXTURE_CROP_RECT_OES 特克斯参数。这是较大纹理中精灵的边界。要呈现,请调用 glDrawTexiOES 通过所需位置&视口坐标中的大小。

    int rect[4] = {0, 0, 16, 16};
    glBindTexture(GL_TEXTURE_2D, sprites);
    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, rect);
    glDrawTexiOES(x, y, z, width, height);
    

    并非所有设备都可以使用此扩展,但它在iPhone上非常有效。

        3
  •  1
  •   mike mike    15 年前

    您也可以考虑使用静态图像,只是滚动,而不是绘制每一个单独的块,并转换其位置等。