Vec3-Array für Vertex_Array und co

Moderator: Graphische Datenverarbeitung 1

ChrizZz
Erstie
Erstie
Beiträge: 12
Registriert: 28. Mai 2007 09:18

Vec3-Array für Vertex_Array und co

Beitrag von ChrizZz » 19. Dez 2010 17:15

Hallo,

in der Übung wurde gesagt, dass wir für den Vertex-Array bzw den VBO-Mode kein extra GLFloat bzw. GLInt(für Triangles) anlegen müssen, um die Daten von dem Vec3f bzw. Vec3i Array in dem OpenGLAufruf glVertexPointer(...)zu verwenden.

Man könne auch folgendes verwenden:

Code: Alles auswählen

typedef std :: vector<Vec3f> Vertices;
Vertices vertices;
GLfloat * vp;
...

vp = &vertices[0].x;

Für Normalen und Triangles entsprechend. Der Aufruf zum Zeichnen müsste dann ja so aussehen:
Vertex-Array:

Code: Alles auswählen

		
glVertexPointer(3, GL_FLOAT, 0, vp);
		glNormalPointer(GL_FLOAT, 0, np);
		glDrawElements(GL_TRIANGLES, 3*nf, GL_INT, tp);
Allerdings wird bei uns dort nichts mehr gezeichnet, wenn wir die Daten in ein GL_Float-Array schreiben und benutzen funktioniert es einwandfrei.
Wo könnte der Fehler legen?

MatthiasBein
Moderator
Moderator
Beiträge: 130
Registriert: 15. Jun 2009 16:42

Re: Vec3-Array für Vertex_Array und co

Beitrag von MatthiasBein » 20. Dez 2010 13:06

füllt ihr die vertices erst nachdem ihr

Code: Alles auswählen

vp = &vertices[0].x;
macht? Das könnte eine Fehlerquelle sein. Denn wenn vertices verändert wird mit .push_back oder .resize, etc, dann kann sich die Speicheradresse ändern. Je nach Operation muss sich der std::vector neuen Speicher reservieren und kopiert das Vorhandne auch komplett an die neue Stelle. Der alte Speicher wird freigegeben und der alte Pointer vp dahin unbrauchbar.

Sicher könnt ihr gehen, indem ihr zB direkt beim Aufruf von gl...Pointer die Adresse bestimmt und übergibt:

Code: Alles auswählen

glVertexPointer(3, GL_FLOAT, 0, &vertices[0].x);
Sidenote: Falls man weiß, wie groß der std::vector wird, kann man ihr gleich in der richtigen Größe anlegen. Oder man reserviert manuell Speicher:

Code: Alles auswählen

std::vector<Vec3f> vertices(vSize); // legt einen array für vSize Vec3fs an. Die Elemente werden mit standard Constructor erstellt.
vertices[i] = Vec3f(1,2,3); // man kann direkt alle Elemente von 0 bis vSize-1 adressieren.
vertices.push_back(Vec3f(9,8,7));  // es könnte sein, dass sich vertices neuen Speicher reserviert, sich dort hin kopiert und alten Speicher freigibt.

std::vector<Vec3f> vertices(vSize,Vec3f(4,5,6)); // legt einen array wie oben an, jedes Element wird aber durch den Constructor mit Parametern 4,5,6 erstellt

std::vector<Vec3f> vertices; // legt nur die grundlegenden Daten an, wie zB die Größe = 0. Es wird kein Element erzeugt.
vertices.reserve(1000); // reserviert Speicher für 1000 Elemente. Falls die bisherige Speicheradresse nicht 1000 Elemente am Stück freigeben kann, wird vertices an eine andere Stelle geschoben.
Vec3f v = vertices[567]; // geht hier noch nicht, da keine Elemente angelegt sind, sondern nur Speicher für 1000 zur Verfügung stehen.
vertices.size(); // wird 0 zurück geben, falls bisher kein .push_back() stattgefunden hat
Wenn sich der std::vector verschieben muss, kostet das natürlich Rechenzeit. Entsprechend sollte man immer Speicher reservieren, wenn man gut abschätzen kann, wieviel benötigt wird. Beim Einlesen von .off Modellen wissen wir es genau und sollten daher vor dem füllen reservieren.

Antworten

Zurück zu „Graphische Datenverarbeitung 1“