Combine lots of texture atlas draw calls with OpenGL ES

I have a large texture atlas and I'm drawing lots of textures on the screen from this. At the moment each texture from the atlas is drawn separately with code like this:

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);

So we're doing this with a triangle strip.

Now, I just tried to cache these kinds of calls by saving the coordinates/vertices, and drawing them all out in a single call. But OpenGL ES does not have quads so trying to use triangle strips means the operation will merge them all together and you get textures warping across the screen from the previous point.

I tried with both glDrawArrays and glDrawElements but I didn't get any success. Is this even possible?


Can you draw each quad as two triangles (GL_TRIANGLES)? Of course, you will have duplicated vertices and coordinates in your arrays.


You could using a degenerate strip.

In this case it makes (almost) no sense, since you only save two vertices per strip, but if you get longer strips and less stops it's good to have this weapon in your arsenal.

The degenerate strip is based on the fact that the hardware skips triangles with zero area, which is true for triangles with two identical vertices.

(Horrible coder ascii art to the rescue.)

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

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

Triangles

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

From OpenGL 3.1 you could simply use "Primitive Restart" which would make your life much easier.


Change

glVertexPointer(3, GL_FLOAT, 0, vertices);  

to

glVertexPointer(2, GL_FLOAT, 0, vertices);

and it should work, assuming that the triangle strip coords you elided are correct.

链接地址: http://www.djcxy.com/p/33890.html

上一篇: 关于在iPhone上加速OpenGL ES 1.1的建议

下一篇: 用OpenGL ES结合大量纹理图谱绘制调用