Vertex Arrays (OGL)
-
Hi, ich habe probleme mit Vertexarrays in OpenGL:
1. Hab ich es richtig verstanden dass man der Funktion glDrawElements(); als lezten Parameter einen Pointer auf ein Array übergib in dem festgelegt wird in welcher Reihenfolge die Vertexe aus dem VertexArray zu rendern sind? Sind das Indicies?
Wenn ja dann bräuchte man ja genausoviele indicies im Array wie Vertexe im Vertexarray sind, wenn ich das so mache dann schmiert aber mein Prog beim aufruf von glDrawElements(); ab (Unbehandelte Ausnahme in ....)
Hier ist mein Code:
typedef struct vertex { float x, y, z; } vertex; simple_vertex *va = NULL; unsigned int *ind = NULL; // In der initialisation: glEnableClientState(GL_VERTEX_ARRAY); va = new simple_vertex[8]; ind = new unsigned int[8]; for(int i(0); i < 8; i++) ind[i] = i; /* Hier wird das Array va noch mit gültigen Vertexdaten gefüllt! */ // In der Draw-Routine: glVertexPointer(3, GL_FLOAT, 0, &va); glDrawElements(GL_QUADS, 8, GL_UNSIGNED_INT, &ind); // Hier stürzt das Prog ab!!
Ich vermute mein Fehler liegt bei den indicies, ich habs im redbook nachgelesen aber anscheinend nich so ganz kapiert
Könnte mir bitte nochmal jemand erklären was ich hier falsch mache?
-
ja, dein fehler liegt bei den indices:
du renders als quads, also brauchst du 4 mal soviele indices wie vertices, so funktioniert, aber ich muss zugeben dass ich das auch noch nicht ganz kapiert habe
-
oh, mir ist gerade aufgefallen, dass du eine struktur mit dem namen vertex hast, aber im code verwendest du simple_vertex, naja das wird wahrscheinlich nur ein fehler beim kopieren deinen source codes sein, und vielleicht ist auch das nur so ein fehler: du musst "va" nur einmal füllen (globale variable) und nicht immer neu wenn du renderst... naja weißt du wahrscheindlich eh
-
ja das mit dem simple_vertex war n kopier-Fehler, ich wollte das simple_ wegnehmen um das Code-Beispiel einfach zu halten.
Ich habs jetz probiert indem ich 4x so viele indicies erstellt habe wie vertexe und erhalte trotzdem einen absturz. Ausserdem kapier ich nich wieso im Fall von GL_QUAD 4x so viele indicies wie vertexe nötig sind wenn es darum geht mit den indicies die Reihenfolge der Vertexe zu bestimmen
Wie wäre dass dann bei GL_TRIANGLE_STRIP ??
-
aber wo füllst du va??
mit
glVertexPointer(3, GL_FLOAT, 0, &va);
gibst du ja an, dass er die eckpunktdaten(x,y,z) va bei den folgenden index(&ind) angaben verwenden soll.wenn also
va = {0.0,1.0,0.0,0.0,2.0,0.0}
hat, dann wird bei index 0 0.0,1.0,0.0 und index 1 0.0,2.0,0.0 genommendu kannst also va füllen mit eckpunkt angaben und dann in &ind nur die index speicher die du haben willst z.B. {1,8,2,3,5}
mit
glDrawElements(GL_QUADS, 8, GL_UNSIGNED_INT, &ind);
zeichnes du dann die elemente, also hier 8 indexe nach der indexliste &ind ergibt 2 quadrate.Am besten siehst du dir das folgende beispiel an
ein beispiel: (bemerkung, eigentlich sind es ja nicht würfel sondern vierecke, also ist die namensgebung nicht 1A, ist aber nur ein detail)
static GLfloat wuerfel[] = {-1.0,1.0 ,0.0, 1.0,1.0 ,0.0, 1.0,-1.0,0.0, -1.0,-1.0,0.0}; /****************************************************************/ // Array Vorbereitungen für die folgenden Würfel glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT,0, wuerfel); /****************************************************************/ // ArrayElemnt Version, Elemente werden nach einer Liste aufgerufen GLubyte punktenliste[] = {0,1,2,3}; glColor3f(1.0,1.0,0.0); glPushMatrix(); glTranslatef(-1.5,1.5,0.0); glDrawElements(GL_POLYGON,4, GL_UNSIGNED_BYTE, punktenliste); glPopMatrix();
[ Dieser Beitrag wurde am 27.03.2003 um 21:47 Uhr von Niels editiert. ]
-
//GLOBALS CVector3D *vertices; int *indices; int Size; //LADEN CODE Size = 4; vertices = new CVector3D[Size]; indices = new int[Size*4]; vertices[0] = CVector3D(-100,-100,0); vertices[1] = CVector3D(100,-100,0); vertices[2] = CVector3D(100,100,0); vertices[3] = CVector3D(-100,100,0); for (int idx=0; idx < Size*4; idx++) { indices[idx] = idx; } //RENDER CODE glLoadIdentity(); glPopMatrix(); glPushMatrix(); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(CVector3D), &vertices[0].x); glDrawElements(GL_QUADS, Size, GL_UNSIGNED_INT, &indices[0]); glDisableClientState(GL_VERTEX_ARRAY);
So gehts, wieso? I have no idea hab mir anfangs gedacht man müsst nur die anzahl der indices * 3 nehmen, weil indices Integer ist und Vertices von Type CVector3D (3 floats), naja durch probieren bin ich dann auf das hier gekommen und es hat immer funktioniert aber wie gesagt ich bin noch nicht wirklich dahinter gekommen wieso das so geht *g*
Egal ... achja bei Triangle Strip Size*6
cu, auch wenn ich dir glaub ich nicht wirklich helfen konnte
-
indices ist eine eckpunktliste
vertices beinhaltet die eckpunktdaten(x,y,z)Eckpunktdaten:
static GLfloat wuerfel[] = {-1.0,1.0 ,0.0,
1.0,1.0 ,0.0,
1.0,-1.0,0.0,
-1.0,-1.0,0.0};Eckpunktliste:
GLubyte punktenliste[] = {0,3,1,2};bei
glDrawElements(GL_POLYGON,4, GL_UNSIGNED_BYTE, punktenliste);wird also
index 0 (-1.0,1.0 ,0.0) mit
index 3 (-1.0,-1.0,0.0) mit
index 1 (1.0,1.0 ,0.0) mit
index 2 (1.0,-1.0,0.0) nach punktenliste[] mit GL_POLYGON verbunden
-
Hi, danke für eure Antworten jetz kapier ich wie das mit den indicies hinhaut, ich habe aber eine bessere Lösung für mich gefunden:
void glDrawArrays(GLenum mode, GLint first, GLsizei count);
Vorausgesetzt die Vertexe liegen in der richtigen Reihenfolge im Vertex-Array (was bei mir der Fall ist) ist glDrawArrays(); die optimale Lösung weil man kein zusätzliches indicies-Array anlegen muss und so auchnochmal ein wenig RAM spart
-
achja, was ich gesagt habe war totaler mist habs jetzt anders pribiert und es funzt auch so ich habs jetzt verstanden (danke für den thread :D)