2009-07-01 1 views
1

Ich habe eine große Textur Atlas und ich zeichne viele Texturen auf dem Bildschirm von diesem. Im Moment jede Textur aus dem Atlas wird separat mit Code wie folgt gezeichnet:Kombinieren Sie viele Texturatlas Aufrufe mit 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); 

So sind wir dies mit einem Dreiecksstreifen zu tun.

Jetzt habe ich gerade versucht, diese Art von Calls zwischenzuspeichern, indem ich die Koordinaten/Scheitelpunkte speichere und alle in einem einzigen Aufruf zeichne. Aber OpenGL ES hat keine Quads. Wenn Sie also versuchen, Dreiecksstreifen zu verwenden, bedeutet dies, dass der Vorgang alle zusammenführt und Sie Texturen vom vorherigen Punkt über den Bildschirm ziehen.

Ich habe mit GlDrawArrays und GlDrawElements versucht, aber ich habe keinen Erfolg bekommen. Ist das überhaupt möglich?

Antwort

2

Können Sie jedes Quad als zwei Dreiecke (GL_TRIANGLES) zeichnen? Natürlich haben Sie Vertices und Koordinaten in Ihren Arrays dupliziert.

+0

Ja, das ist, was ich getan habe. Anstatt einen Dreiecksstreifen mit 4 Punkten in meinen Arrays zu definieren, habe ich zwei Dreiecke (6 Punkte) definiert und glDrawArrays (GL_TRIANGLES, 0, totalSize * 6) verwendet. Das verhindert, dass sich alles in einen riesigen Dreiecksstreifen verwandelt. –

+0

Es gibt Leistungsvorteile, wenn die GL_TRIANGLE_STRIP-Version funktioniert. –

0

ändern

glVertexPointer(3, GL_FLOAT, 0, vertices); 

zu

glVertexPointer(2, GL_FLOAT, 0, vertices); 

und es sollte funktionieren, vorausgesetzt, dass die Dreiecksstreifen coords Sie richtig elided sind.

+0

Dies sollte keinen Unterschied machen. Es ist jetzt 3, nur weil ich einige z-Werte drin hatte, aber sie sind alle 0.0. –

0

Sie könnten sich für die Klasse TextureAtlas der Cocos 2D-Engine für iPhone interessieren.

+0

Danke, sie scheinen genau das zu tun, was ich versucht habe. Vielleicht habe ich irgendwo einen dummen Fehler gemacht. –

0

Verwenden Sie glDrawElements mit GL_TRIANGLES mit 4 Verts und 6 Indizes. Moderne Hardware speichert die Speicherabrufvorgänge für die wiederholten Verts, so dass die Leistung fast gleich GL_TRIANGLE_STRIP ist, und die Tatsache, dass Sie GL_TRIANGLES sehr viel effizienter stapelweise verarbeiten können, als für einzelne Quads, ist ein großer Gewinn. Stellen Sie sicher, dass die Dreieckswicklung korrekt ist, oder deaktivieren Sie die Rückseitenkeulung.

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

Sie könnten einen entarteten Streifen verwenden.

In diesem Fall macht es (fast) keinen Sinn, da Sie nur zwei Scheitelpunkte pro Streifen speichern, , aber wenn Sie längere Streifen und weniger Stopps bekommen, ist es gut, diese Waffe in Ihrem Arsenal zu haben.

Der entartete Streifen basiert auf der Tatsache, dass die Hardware Dreiecke mit Nullbereich überspringt, was für Dreiecke mit zwei identischen Vertices gilt.

(Horrible coder ASCII Art zur Rettung.)

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 

Von OpenGL 3.1 Sie könnten einfach "Primitive Restart" verwenden, die Ihr Leben viel einfacher machen würde.