结合大量纹理图集使用OpenGL ES绘制调用

时间:2009-07-01 19:37:44

标签: iphone opengl-es

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

GLfloat coordinates[] = {
        bla, bla,
        bla, bla,
        bla, bla,
        bla, bla
};

GLfloat vertices[] = {
        bla, bla, bla,
        bla, bla, bla
        bla, bla, bla
        bla, bla bla
};


glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, name);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

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

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

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

5 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

你可以使用退化带。

在这种情况下,它几乎没有任何意义,因为每个条带只保存两个顶点, 但是如果你得到更长的条带和更少的停留,那么在你的武器库中使用这种武器是件好事。

简并条带是基于硬件跳过零区域的三角形这一事实,对于具有两个相同顶点的三角形也是如此。

(恐怖的编码器ascii艺术救援。)

A--D
| /|
|/ |
B--C

   E--H
   | /|
   |/ |
   F--G

三角形

ABD DBC EFH HFG  -> 12

Va = f(Q)= 6xQ

Trianglestrips

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开始,您只需使用“原始重启”即可让您的生活更轻松。

答案 2 :(得分:0)

更改

glVertexPointer(3, GL_FLOAT, 0, vertices);  

glVertexPointer(2, GL_FLOAT, 0, vertices);

它应该工作,假设三角形条带coords 你被遗弃是正确的。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

将glDrawElements与GL_TRIANGLES一起使用,包含4个顶点和6个索引。现代硬件将缓存重复顶点的内存提取,因此性能几乎等于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 );