【问题标题】:Combine lots of texture atlas draw calls with OpenGL ES将大量纹理图集绘制调用与 OpenGL ES 相结合
【发布时间】:2010-11-07 10:36:16
【问题描述】:

我有一个很大的纹理图集,我在屏幕上绘制了很多纹理。目前,图集中的每个纹理都是使用如下代码分别绘制的:

GLfloat 坐标[] = { 布拉,布拉, 布拉,布拉, 布拉,布拉, 呜呜呜 }; GLfloat 顶点[] = { 布拉, 布拉, 布拉, 布拉,布拉,布拉 布拉,布拉,布拉 呜呜呜 }; glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 名称); glVertexPointer(3, GL_FLOAT, 0, 顶点); glTexCoordPointer(2, GL_FLOAT, 0, 坐标); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

所以我们用三角条来做这个。

现在,我只是尝试通过保存坐标/顶点来缓存这些类型的调用,并在一次调用中将它们全部绘制出来。但是 OpenGL ES 没有四边形,因此尝试使用三角形条意味着该操作会将它们全部合并在一起,并且您会得到从前一点开始在屏幕上扭曲的纹理。

我尝试了 glDrawArrays 和 glDrawElements 但我没有获得任何成功。这甚至可能吗?

【问题讨论】:

    标签: iphone opengl-es


    【解决方案1】:

    你能把每个四边形画成两个三角形(GL_TRIANGLES)吗?当然,您的数组中会有重复的顶点和坐标。

    【讨论】:

    • 是的,这就是我最终要做的。我没有在我的数组中定义一个有 4 个点的三角形带,而是定义了两个三角形(6 个点)并使用了 glDrawArrays(GL_TRIANGLES, 0, totalSize * 6)。所以这可以防止所有东西都被扭曲成一个巨大的三角形条带。
    • 使用 GL_TRIANGLE_STRIP 版本有性能优势。
    【解决方案2】:

    你可以使用退化的条带。

    在这种情况下,它(几乎)没有意义,因为每个条带只保存两个顶点, 但是,如果您获得更长的条带并且更少的停止,那么将这种武器放在您的武器库中会很好。

    退化带基于硬件跳过面积为零的三角形这一事实,这对于具有两个相同顶点的三角形是正确的。

    (可怕的编码器 ascii 艺术来拯救。)

    A--D
    | /|
    |/ |
    B--C
    
       E--H
       | /|
       |/ |
       F--G
    

    三角形

    ABD DBC EFH HFG  -> 12
    

    Va = f(Q) = 6xQ

    三角带

    ABD     C     C     E     E     F     H     G -> 10
    ABD (BD)C (DC)C (CC)E (CE)E (EE)F (EF)H (FH)G
    CCW CW    CCW   CW    CCW   CW    CCW   CW
    NOR NOR   DEG   DEG   DEG   DEG   NOR   NOR
    

    Vb = f(Q) = 4+ (4+2)(Q-1)

    Q   | Va | Vb
     1  |  6 |  4
     2  | 12 | 10
     3  | 18 | 16
    10  | 60 | 58
    

    从 OpenGL 3.1 开始,您可以简单地使用 "Primitive Restart",这会让您的生活更轻松。

    【讨论】:

      【解决方案3】:

      改变

      glVertexPointer(3, GL_FLOAT, 0, vertices);  
      

      glVertexPointer(2, GL_FLOAT, 0, vertices);
      

      它应该可以工作,假设三角形带坐标 你省略的是正确的。

      【讨论】:

      • 这应该没什么区别。现在是 3,因为我有一些 z 值,但它们都是 0.0。
      【解决方案4】:

      您可能对TextureAtlas iPhone 的 Cocos 2D 引擎类感兴趣。

      【讨论】:

      • 谢谢,他们似乎正在做我正在尝试的事情。也许我只是在某个地方犯了一个愚蠢的错误。
      【解决方案5】:

      使用带有 4 个顶点和 6 个索引的 GL_TRIANGLES 的 glDrawElements。现代硬件将缓存重复顶点的内存获取,因此性能将几乎等于 GL_TRIANGLE_STRIP,而且对于单个四边形之类的东西,您可以比条更有效地批处理 GL_TRIANGLES 的事实是一个巨大的胜利。确保三角形缠绕正确,或关闭背面剔除。

      // triangle vertex order
      // 1--2
      // | /|
      // |/ |
      // 0--3
      
      vertex foo[4] = {
          {<vtx0>},
          {<vtx1>},
          {<vtx2>},
          {<vtx3>}
      };
      
      // same clockwise winding for both triangles
      GLushort idx[2][3] = {
          { 0, 1, 2 },
          { 0, 2, 3 }
      };
      
      <setup vertex array>
      // use a VBO for both the vertex and index array if possible...
      
      glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, idx );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-29
        • 1970-01-01
        • 2019-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多