Ich lade die Vertexdaten(+Texturkoordinaten) eines Terrains in ein VBO im VRAM. Nun hab ich das Octree-Verfahren so implementiert, dass es ein Indexarray mit den Indizes der sichtbaren Vertices des Vertexarrays berechnet. Diese Indizes zeichne ich dann mit glDrawElements. Hier der Code:
Code:
glPushMatrix;
TerrainVBO.BindBuffer;
// Die sichtbaren Vertices werden in Indexlist geschrieben
Die Geschwindigkeitseinbuße liegt also nicht beim Octree, sondern bei glDrawElements.
Sollte ich lieber glDrawArrays verwenden und den Octree jedesmal das Vertexarray mit den sichtbaren Vertices schreiben lassen? Ich dachte mir, dass glDrawElements, vor allem was LOD angeht, viel flexibler ist und wollte es deshalb so implementieren.
Naja, vielleicht kann mir ja jemand helfen :)
DIe batches sollten nicht zu klein sein, 10000 vertices pro Octreezelle sind kein problem. Eigendlich macht es nur noch Sinn große Bereiche zu entfernen...
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Das Problem liegt wohl eher darin, dass glDrawElements einen clientseitigen Speicherbereich benutzt wärend glDrawArrays einen Speicherbereich auf der Grafikkarte benutzen kann.
Dabei entstehen 2 Probleme.
1. Der Clientspeicher ist wesentlich langsamer, da der komplette Speicher erst einmal über den Bus geschickt werden muss. Und der Speicher auf der Grafikkarte hat einen wesentlich kürzeren und schnelleren weg.
2. OpenGL arbeitet asynchron. Das bedeutet, dass der Aufruf von glDrawArrays schon wieder zurückkehren kann wärend die Grafikkarte noch die Dreiecke zeichnet. Bei glDrawElements ist es aber so, dass du einen clientseitigen Speicherbereich hast und auf den kann OpenGL nur so lange zugreifen wie die Fuktion noch ausgeführt wird. Mit anderen Worten OpenGL muss an dieser zwingend synchron arbeiten. (warten)
Und evtl kann es auch noch problematisch sein, wenn man veraltete VertexArrays (VA) mit VertexBufferObjects (VBO) mischt. Ich weiß nicht ob das unbedingt so reibungslos klappt.
Aber wie oc2k1 schon sagte. Ich denke es ist besser, wenn du einzelne Bereiche in VBOs verpackst und dann nur die sichtbaren Bereiche. So wie bei einem Schachbrett. Die einzelnen Quadrate wären dann Teilstücke der Landschaft.
@oc2k1: Wenn sich die Zellengröße in gewissen Grenzen bewegt(Ich glaube etwa zwischen 5000-100000) macht das kaum was an der Renderperformance, aber natürlich ändert sich die Erstellungszeit am Anfang sehr stark :)
@Lossy:
Zitat:
Und evtl kann es auch noch problematisch sein, wenn man veraltete VertexArrays (VA) mit VertexBufferObjects (VBO) mischt. Ich weiß nicht ob das unbedingt so reibungslos klappt.
Also im Moment mach ich das so, dass ich ein Vertexarray gegeben habe, dieses ins VBO packe und dann später nur noch binde und glDrawElements aufrufe. Ich guck mal, ob ich das irgendwie so umgestellt bekomme, dass ich glDrawArrays anwenden kann. Aber sind VA's veraltet? Im VBO-Tutorial werden ja auch VA's benutzt, oder? Wie könnte ich sonst das VBO "füllen? Hab ich da was falsch verstanden?[/quote]
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Ja okay. Das stimmt. Das sieht wirklich etwas verwirrend aus. Denn das ganze hat einen geschichtlichen Hintergrund. Früher waren die Karten noch nicht in der Lage Vertexdaten im Speicher halten zu können. Und da waren VAs das flexible Gegenstück zu den Displaylisten. Und mit Einführung der VBOs können die Karten aber VertexDaten im ihrem Speicher halten. Die Daten haben sich nicht verändert. Es hat sich mehr oder weniger nur die Position davon verändert. Und zwar vom Client (Anwendung) auf den Server (Grafikkarte).
Da VAs und VBOs sich sehr sehr ähnlich sind hat man einfach die bereits bestehenden Methoden der VAs für die VBOs benutzt. Es muss halt ein Buffer gebunden werden damit OpenGL weiß, dass essich um ein VBO handelt. Sonst ist es ziemlich gleich. Bzw bei den Methoden wird bei bei einem VA ein Pointer auf die Daten übergeben und bei einem VBO handelt es sich dabei um ein Offset innerhalb der Daten.
Im Übrigen kannst du glDrawElements auch mit einem VBO benutzen. Du musst halt nur die Daten für den IndexBuffer auch hochladen. (glIndexPointer) Also du musst nicht zwingend mit glDrawArrays arbeiten, da die beiden Funktionen ja schon ihre Daseinsberechtigung haben, denn mit Indexbuffern kannst du sich überlappende Vertices auch mehrfach benutzen. Wärend glDrawArrays für jedes Primitiv entsprechend viele Einzelpunkte erwartet.
PS: Ich muss aber gestehen, dass ich schon länger nichts mehr mit VBOs gemacht habe. Deswegen weiß ich gerade aus dem Kopf nicht so 100%tig wie das mit dem IndexBuffer auf der Grafikkarte funktioniert.
Ich glaube, dass ich jetzt die Fehlerquelle gefunden habe, die das ganze so verlangsamt. Naja, eigentlich habe ich sie noch nicht gefunden, aber ich weiß jetzt in etwa, woran es liegt.
Mein VBO scheint irgendwie im Hauptspeicher zu sein. Die Benutzung von glDrawArrays bringt bei der gesamten Szene schon die doppelte Framerate im Vergleich zu glDrawElements. Die Geschwindigkeit bleibt aber bei beiden gleich, wenn ich
Wie ihr vielleicht seht, benutze ich als Vorlage das VBO-Tutorial aus dem Wiki. glEnableClientState(GL_Vertex_Array) usw. brauche ich komischerweise nicht. Ob ich das setze oder nicht, hat keinen Einfluss. Ich kann jetzt auch die ganze Pointergeschichte einfach weglassen Und
glBufferData(GL_ARRAY_BUFFER, VertexCount*SizeOf(TVertex), @Vertices[0], GL_STATIC_DRAW); benutzen. Ist genauso schnell :/
Rendern tue ich so (Ich schreibe hier jetzt mal nur die VBO betreffenden Befehle hin und lasse Octree etc. weg) :
Code:
glBindBuffer(GL_ARRAY_BUFFER, Number);
// IndexList enthält die Indizes des Arrays im VBO, die gerendert werden sollen
Registriert: Di Nov 07, 2006 13:37 Beiträge: 83 Wohnort: Partenheim
Hi,
wie erzeugst du deine IndexList? Ist sie ein statisches Array, oder setzt du bei jedem Renderdurchlauf die Größe neu? Das nämlich kann 'ne Menge Performance kosten.
Soll nicht außerdem glDrawRangeElements schneller sein als glDrawElements? Irgendwie soll da der Treiber den Speicherbedarf besser planen und regulieren können ...
Mitglieder in diesem Forum: 0 Mitglieder und 14 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.