Schnellste Möglichkeit, viele texturierte Quads in OpenGL 3+ zu zeichnen

9

Seit GL_QUADS aus OpenGL 3.1 und höher entfernt wurde, was ist der schnellste Weg, um viele Quads zu zeichnen, ohne sie zu verwenden? Ich habe verschiedene Methoden ausprobiert (unten) und habe sie auf meiner Maschine nach Geschwindigkeit geordnet, aber ich habe mich gefragt, ob es einen besseren Weg gibt, da der schnellste Weg immer noch verschwenderisch und unelegant erscheint. Ich sollte erwähnen, dass ich bei jeder dieser Methoden VBOs mit verschachtelten Vertex- und Texturkoordinaten verwende, da ich glaube, dass dies die beste Praxis ist (obwohl ich falsch liegen kann). Außerdem sollte ich sagen, dass ich keine Scheitelpunkte zwischen getrennten Quads wiederverwenden kann, da sie unterschiedliche Texturkoordinaten haben.

  1. glDrawElements mit GL_TRIANGLE_STRIP unter Verwendung eines primitiven Neustartindex, so dass das Indexarray wie {0, 1, 2, 3, PRI, 4, 5, 6, 7, PRI, ...} aussieht. Dadurch werden die ersten 4 Scheitelpunkte in meinem VBO aufgenommen, als dreieckiger Streifen behandelt, um ein Rechteck zu erhalten, und dann werden die nächsten 4 Scheitelpunkte als separater Streifen behandelt. Das Problem hier ist nur, dass das Index-Array wie eine Verschwendung von Platz erscheint. Das Schöne an GL_QUADS in früheren Versionen von OpenGL ist, dass es alle vier Vertices automatisch neu startet. Trotzdem ist dies die schnellste Methode, die ich finden kann.

  2. Geometrie-Shader Ich gebe für jedes Rechteck einen Eckpunkt ein und konstruiere dann den passenden Dreiecks-Streifen mit 4 Eckpunkten im Shader. Dies scheint der schnellste und eleganteste zu sein, aber ich habe gelesen und gesehen, dass Geometrieshader im Vergleich zu redundanten Daten nicht so effizient sind.

  3. glDrawArrays mit GL_TRIANGLES. Ich zeichne einfach jedes Dreieck unabhängig und verwende keine Scheitelpunkte.

  4. glMultiDrawArrays mit GL_TRIANGLE_STRIP, ein Array aller Vielfachen von 4 für das "erste" Array und ein Array aus einer Menge von 4 für das "count" Array. Dies weist die Videokarte an, die ersten 4 beginnend bei 0 zu zeichnen, dann die ersten 4 beginnend bei 4 und so weiter. Der Grund dafür ist, glaube ich, so langsam, dass Sie diese Index-Arrays nicht in einem VBO platzieren können.

noumenon28 02.10.2012, 23:01
quelle

1 Antwort

3

Sie haben alle typischen guten Wege behandelt, aber ich möchte Ihnen ein paar weniger typische vorschlagen, von denen ich vermute, dass sie eine höhere Leistung haben. Basierend auf dem Wortlaut der Frage werde ich annehmen, dass Sie versuchen, ein m * n-Array von Kacheln zu zeichnen, und alle benötigen unterschiedliche Texturkoordinaten.

  • Ein Geometrieshader ist nicht das richtige Werkzeug zum Hinzufügen und Entfernen von Vertices. Es ist in der Lage, das zu tun, aber es ist wirklich für Fälle gedacht, in denen Sie tatsächlich die Anzahl von Primitiven ändern, die Sie dynamisch darstellen (z. B. Generierung von Schattenvolumen). Wenn Sie nur eine ganze Reihe benachbarter unterschiedlicher Grundelemente mit unterschiedlichen Texturkoordinaten zeichnen möchten, ist der schnellste Weg, Tessellations-Shader zu verwenden. Übergeben Sie einfach ein einzelnes Quad und lassen Sie den Tessellator Texturkoordinaten prozedural berechnen.
  • Eine ähnliche und portablere Methode wäre es, die Texturkoordinaten jedes Quads nachzuschlagen. Das ist trivial: Sagen Sie, Sie zeichnen 50x20 Quads, Sie hätten eine Textur von 50x20, die alle Ihre Texturkoordinaten speichert. Tippen Sie auf diese Textur in Ihrem Vertex-Programm (oder vielleicht effizienter in Ihrem Geometrie-Programm) und senden Sie das Ergebnis in einer Variation an das Fragment-Programm für das tatsächliche Rendern.

Beachten Sie, dass Sie in beiden oben genannten Fällen Scheitelpunkte wiederverwenden können. In der ersten Methode werden die Zwischenvertices im Flug erzeugt. In der zweiten werden die Texturkoordinaten der Scheitelpunkte im Shader durch zwischengespeicherte Werte aus der Textur ersetzt.

    
imallett 20.10.2012, 03:30
quelle

Tags und Links