Vertexarray
Bitte haben Sie etwas Geduld und nehmen Sie keine Änderungen vor, bis der Artikel hochgeladen wurde. |
Inhaltsverzeichnis
Vertexarray
Bei einem Vertexarray werden die Vertexdaten in einem Array zur Grafikkarte geschickt.
Was sind Vertexarrays
Ein Vertexarray ist ein großes Array, in dem die Vertexdaten stehen. Idealerweise existiert dabei jeder Vertex nur einmal in diesem Array. Daneben wird noch ein Indexarray erstellt, dass auf die Vertices in dem Vertexarray verweist. Anhand dieses Indexarrays wird gezeichnet. Natürlich können auf einzelne Vertices aus dem Indexarray heraus mehrfach verwiesen werden.
Wie helfen Vertexarrays bei der Performance
Dadurch, dass alle Daten an einem Block liegen und die GPU stumpf die Daten abarbeiten kann, sind die Vertexarrays weitaus schneller als die glBegin/glEnd-Methode. Werden die Daten dann auch noch als Displayliste an die Grafikkarte geschickt, kommt Freude auf. :) Außerdem wird Speicher gespart, indem durch die Indirektstufe, die man durch das Indexarray hat, einen Vertex mehrfach zeichnen kann.
Verwendung
Prinzip
Wie wird nun so ein Vertexarray aufgebaut und gezeichnet?
Beispiel, wie es intern abläuft für zwei nebeneinanderliegende 2D-Quads:
Vertexarray vertices: {(0.0f, 0.0f), (0.0f, 1.0f), (1.0f, 0.0f), (1.0f, 1.0f), (2.0f, 0.0f), (2.0f, 1.0f)}
Indexarray indices: {0, 2, 3, 1, 2, 4, 5, 3}
Beim Zeichnen wird nun folgendermaßen vorgegangen:
int vertexCount = length(indices); glBegin(GL_QUADS); for (int i = 0; i < vertexCount; ++i) { int vIndex = indices[i]; Vertex2F v = vertices[vIndex]; glVertex2f(v[0], v[1]); } glEnd();
Dieses Minimalbeispiel soll nur verdeutlichen, wie Vertexarrays prinzipiell funktionieren. Pro Vertex gibt es natürlich noch andere interessante Informationen wie dessen Normale, dessen Farbe und Texturkoordinate. Dazu später mehr.
Umsetzung in C
Das Beispiel von eben soll nun in wirklichen Code umgesetzt werden. Dazu sind zwei Schritte nötig:
1. Die Initialisierung.
2. Das eigentliche Zeichnen
Die Initialisierung
Als erstes definieren wir einen Vertex:
typedef struct { GLfloat x, y, z; GLfloat r, g, b; } Vertex;
Dieser Typ besteht aus zwei Teilen: Einmal 3 Floats für die Koordinate und einmal 3 Floats für die Farbe. Das Vertexarray besteht eben aus einem Array mit diesem Typen. Bei einer Zeile sind die ersten drei Zahlen die Koordinate und die nächsten drei die Farbe
static const Vertex vertices[18] = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 2.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 2.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
Nun müssen noch die Indices aufgebaut werden: GLuint *indices;
static const GLuint indices[8] = { 0, 2, 3, 1, 2, 4, 5, 3 }; static int indexCount = 8;
Damit hätten wir alle Daten beisammen. Nun muss nur noch OpenGL davon wissen.
void initVertexArray(void) { glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glVertexPointer(3, /* Komponenten pro Vertex (x,y,z) */ GL_FLOAT, /* Typ der Komponenten */ sizeof(Vertex), /* Offset zwischen 2 Vertizes im Array */ &(vertices[0].x)); /* Zeiger auf die 1. Komponente */ glColorPointer (3, GL_FLOAT, sizeof(Vertex), &(vertices[0].r)); }
Was geschieht hier?
Als erstes wird das Vertex-Array eingeschaltet sowie das zugehörige Farbarray.
Dann wird als erstes der Vertexpointer gesetzt. Der erste Parameter sagt, dass es 3 Komponenten pro Vertex sind (x, y, z), der zweite, dass es sich um Floats handelt, der dritte der Offset zwischen zwei Vertices im Array (Wie viele Bytes er überspringen muss um zum nächsten Vertex zu gelangen) und der Dritte ist ein Pointer auf das erste Vertex.
Genau so sieht der Colorpointer aus.
Das eigentliche Zeichnen
Nun, da alles initialisiert ist, sollen die Quads auch auf den Bildschirm. Dazu folgende Funktion:
void drawVertexArray(void) { glDrawElements(GL_QUADS, /* Primitivtyp */ indexCount, /* Anzahl Indizes */ GL_UNSIGNED_INT, /* Typ der Indizes */ indices); /*Index-Array*/ }
Als erstes wird gesagt, dass die gezeichneten Elemente Quads sind. Dann kommt die Anzahl der Indices sowie deren Typ. Als letztes das eigentliche Indexarray.