Ich entwickle ein 2D-Sidescrolling-Spiel und ich muss meinen Tiling-Code optimieren, um eine bessere Bildrate zu erhalten. Im Moment verwende ich einen Texturatlas und 16x16 Kacheln für 480x320 Bildschirmauflösung. Die Ebene scrollt in beide Richtungen und ist deutlich größer als 1 Bildschirm (Tausende von Pixeln). Ich benutze glTranslate für das eigentliche Scrollen.
Bisher habe ich es versucht:
Zeichnen Sie die gesamte Karte als Anzeigeliste (groß auf einer kleinen Ebene, um eine große zu verlangsamen)
Partitionierung der Karte in die Anzeige Listet die halbe Bildschirmgröße auf und löscht dann die Anzeigelisten (bei 2-seitigem Scrolling wird die Geschwindigkeit immer noch verringert, Overdraw ist nicht effizient)
Jeder Rat wird geschätzt, aber vor allem frage ich mich:
Danke:)
So würde ich eine schnelle 2D-Tile-Engine codieren:
Zuerst würde ich eine saubere Trennung zwischen dynamischen Kacheln (Zeichen, Elemente ..) und statischen (Ebene) machen.
Zum Zeichnen der statischen (Kacheln, die die gesamte Ebene aufbauen) verwende ich einen statischen Puffer (in einem Pufferobjekt gespeichert), der jede Kachelposition (x, y, Ebene) und einen Index für die Atlastextur enthält Daten (i). Da Ihr Texturatlas Kacheln mit fester Größe von 16x16 Pixeln enthält, können Sie die Vertex-Koordinaten für jeden Scheitelpunkt einfach berechnen.
Zum Zeichnen der Ebene würde ich einen einzelnen Zeichnungsaufruf (unter Verwendung der Instanzierung) eines Dreieckstreifens verwenden, der ein Viereck bildet, Eckendaten werden in einem statischen VBO (aus 4 Eckpunkten) und Indexdaten in einem statischen IBO (aus 4 Indizes), wobei pro Instanz Werte für das Vertex-Attribut im Vertex-Shader verwendet werden.
Dies würde Ihnen fast "freies" Kachel-Culling auf der GPU ermöglichen, da Clipping-Hardware sehr schnell ist.
Selbst wenn Sie eine große Anzahl von Kacheln in Ihrem Level haben, sagen wir 30 * 20 (Kacheln / auf einem Bildschirm) und ungefähr ~ 50 Bildschirm / Level, würde es 30.000 Kacheln machen. Ich denke, es ist immer noch akzeptabel (auch auf Low-End-GPUs. Übrigens, zielen Sie auf iPhone / Android? Wenn ja, Instanziierung / Shadern sind nicht verfügbar für OpenGL ES 1.0 und OpenGL ES 2.0 hat keine Instanziierung Unterstützung, kann aber tun, Shader explodieren Kacheldaten in einem VBO / IBO und verwenden GL_TRIANGLES
. Sie können weniger Daten explodieren und den GPU-Speicher entlasten, indem Sie Vertices-Attribute in einem Shader berechnen.
In jedem Fall sollten Sie die Texturkacheldaten nicht duplizieren und einen Texturatlas und einen VBO und IBO behalten.
Ich würde einen dynamischen VBO (und einen statischen IBO, der GL_TRIANGLES
darstellt, also 0,1,2, 2,1,3, 0 + 4,1 + 4,2 + 4 ..) verwenden, die Kachelpositionen darstellen, Texturkoordinaten, Ebenen und aktualisiere sie mit sichtbaren dynamischen Kacheln in einem Bildschirm über glBufferSubData
und zeichne diese Kacheln über glDrawElements
.
Natürlich bedeutet dies, dass Sie eine maximale Anzahl an dynamischen Kacheln haben, die Sie pro glDrawElements
zeichnen können. Wenn Sie also auf dieses Limit stoßen, müssen Sie das VBO erneut aktualisieren / zeichnen.
Wenn Ihre OpenGL-Implementierung keine Unterstützung für VBO / IBO bietet (wie in OpenGL ES 1.0), verwenden Sie stattdessen VA. Ich empfehle nicht die Verwendung von DL oder Sofort-Modus (keine Unterstützung für OpenGL ES).
Verwenden Sie schließlich glOrtho
, um Ihre Kamera über die Ebene zu bewegen, zu vergrößern / verkleinern usw. Viel Glück!