Hallo,
VBOs bieten ja einige Vorteile. Im moment arbeite ich an einem Leveleditor (outdoor) und wollte evetuell VBOs nutzen um erformance zu steigern.
1)Wie aber Funktioniert Selektion und VBOs miteinander ?
2)Wie sieht es mit LOD und VBOs miteinander ? Ich kann ja nicht bei jeden rendervorgang die VBOs neu beschreiben. und den Rendervorgang kann ich nicht beeinflussen, da dieser durch 1 Befehl durchgeführt wird.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Selektion: Die klassische Selektion funktioniert nur so, dass du jedes selektierbare Objekt einzeln rendern musst. Also Name setzen. Zeichnen. Name setzen. Zeichnen. Dazu musst du nicht zwingend alles neu initialisieren etc sondern es sollte genügt wenn du bei glDrawRangeElements andere Werte für Start/Count etc setzt.
Eine andere Möglichkeit für die Selektion wäre dein Objekt jeweils mit einer Farbe zu zeichnen diese dann aus dem Framebuffer auszulesen. Und anhand der Farbe wüsstest du um welches es sich handelt. Die Farbe könntest du auch ins VBO packen allerdings ist es etwas unpraktisch, wenn du für 1 Mio Vertices jeweils eine Farbe abspeichern müstest wenn es sich dabei lediglich um 10 Objekte handelt.
Aber keine Sorge. Es wird nicht wehtun wenn du 10-1000 Renderaufrufe hast. Bzw wird das kaum Warnehmbar sein. Bei VBOs ist es wichtig so viel möglich mit einem Mal zeichnen zu lassen. Du solltest aber drauf achten, dass du nicht jede kleine Objekt in ein eigenes VBO packst. Denn das initialisieren der VBOs auf der Grafikkarte ist laut NV wohl mitunter das teuerst. Evtl ist dieses Thema für dich noch interessant. Da habe ich auch den Link auf ein Dokument von NVidia gepostet.
LOD: Könntest du auch mit glDrawRangeElements machen, da du dabei noch einen zusätzlichen IndexBuffer angeben musst. Das heißt du würdest so einfach ein paar Elemente auslassen. Das einfach so auszutauschen würde aber dazu führen, dass sich das urplötzlich ändert. Da gibts es aber auch Techniken für. Kenne mich aber nicht so gut damit aus.
D.h. Wenn ich jedes einzelne dreieck per glDrawRangeElements rendere macht es keinen unterschied zu Befehl glDrawElements, der den ganzen Vertex rendern würde? .. ich könnte somit jedem einzelnen Polygon einen Namenzuweisen.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Nein also das nicht. Ich denke das wird einen gehörigen Unterschied machen.
Weil du hast ja für jede OpenGL Funktion einen gewissen Aufwand. Also Parameter übergeben und OpenGL muss auch einen Befehl an die Grafikkarte schicken etc. Auch wenn das alles ziemlich kostengünstig ist aber um so mehr du aufrufst umso mehr Zeit benötigt das. Das bremmst das rendern wieder aus.
Also wenn du das 1000 Mal aufrufst ist das wohl kaum messbar aber wenn du das für jedes Dreieck aufrufst. (1 Mio Mal) dann wird man das schon merken. Ich tippe darauf, dass es unwesentlich schneller sein wird als wie wenn man es itterativ zeichnet. Also alles direkt selber. Aber in jedem Fall ist es zu klein um den Vorteil von VBOs nutzen zu können.
Vielleicht kann man das problem ja auch anders lösen.
Also ich habe eine Karte und mittels Maus will ich dann Berge hochziehen können. Um das realisiern zu können muss ich eben wissen auf welchem Dreieck sich die Maus befindet. Gäbe es noch eine andere Möglichkeit das zu realisieren?
Jedes Dreieck muss dann eine eigene Farbe bekommen. Die Farben kann man im Vertex speichern. Das Problem hierbei ist nur, dass die Farbe auf dem Dreieck konstant und nicht zwischen allen Eckpunkten interpoliert sei soll. Jedes Dreieck benötigt dann eine eigene Kopie der Eckpunkte mit der entsprechenden Farbe. Das ist natürlich langsamer und verbraucht ca 6x mehr Speicher. Es könnte jedoch auch mit glShadeModel(GL_FLAT) funktionieren, wenn man Quads statt Dreiecken nimmt und das Quad durch glShadeModel(GL_FLAT) jeweils die Farbe des letzten Punktes erhält.
Ok versteh ich noch nicht so ganz. Wenn jedes dreieck seine Farbe hat. Was mach ich dann damit ? Kann ich die auslesen ?
aber glShadelModel(glFlat) dürfte doch auch bei Dreiecken Funktionieren. Steht zumindest im Wiki.
Kann ich nicht einfach Die Mauskoordinaten in Weltkoordinaten umrechnen. Ich müsste nur wissen wo sich die Maus auf der x,z- Ebene befindet. Damit könnte ich das Dreieck finden.
Ich wollte ja VBOs nehmen, da sie Dynamisch sind und man sie verändern kann.
Nur muss jetz eine Selektion noch funktionieren. (oder eine andere Art).
Wäre folgendes eine Alternative:
Meine Map ist ja in mehrere Teile (arrays) unterteilt. Ich rendere jedes einzelne in einer Displaylist. Jetzt will ich ein dreieck in der 1. Display list verändern. Damit wird die erste Liste nicht mehr in einer Displaylist gerendert sondern direkt. Damit wäre wes auch dynamscih. Ist die veränderung abgeschlossen , wird wieder in displaylist gerendert.
Wär das ne alternative ? oder zu aufwending von performance her ?
Eig. wäre mit ne VBO auch lieber .. aber wenns nich anders geht , könnte man das mit den Displaylist machen ?
Die Farbe an der Mausposition kann man mittels glReadPixel auslesen. Die Position auf der XY Ebene zu bestimmten, funktioniert nur am Anfang wenn die Landschaft noch eine Ebene ist. Ansonsten trifft der Strahl die XY Ebene später als die eigentliche Landschaft darüber und das falsche Dreieck wird ausgewählt.
Jeder Punkt ist mit 6 Dreiecken verbunden. Er darf aber nur bei einem der letzte Punkt sein, weil der letzte Punkt die Farbe bestimmt. Beim Quad ist jeder Punkt mit 4 Quads verbunden und jedes Quad hat 4 Punkte, so dass die Rechnung aufgeht. Das ist aber nur eine mögliche Optimierung wenn die Auswahl funktioniert. Und es funktioniert nur bei regulären Dreiecksnetzen wie z.B. der Landschaft.
Zuerst kann man ja die Dreicke mit glBegin/glEnd zeichnen und schauen, ob die richtige Farbe ausgelesen werden kann und ob man das richtige Dreieck zur Farbe erhält. Das sollte auch schon schneller als die normale Selektion sein.
edit: Das geht auf jeden Fall mit VBO und da man die Geometrie ständig verändert sind sie hier auch besser.
Genauso in der Reihenfolge wie man die Dreiecke mit glBegin/glEnd zeichnen würde, kann man die Punkte auch im VBO speichern und den ganzen Buffer dann mit glDrawArrays zeichnen. Eine Indexliste ist hier nicht mehr nötigt, weil jeder Punkt ohnehin nur einmal verwendet wird. Bei der Aktualisierung muss man dann beachten, dass sich zu einem bestimmten Vertex mehrere Kopien mit den gleichen Koordinaten aber unterschiedlichen Farben im Buffer befinden und man alle aktualisieren muss.
Also ich muss Meine Landschaft in kleine Quads aufteilen , obwohl ich Dreiecke zeichne ?
Sprich ich hab immer zwei gleichfarbene Dreiecke
x1
_ _ X3;X6
! /!
!/_! x5
x2
x4
(ich hoffe man kann meine Zeichnung erkennen. Ich zeichne von x1-x6)
Der Punkt X3 bzw x6 gibt dann die Farbe des Dreieckes an, und da dieser Identisch ist, haben 2 dreiecke = 1 Farbe ?
Mit einer Quadeinteilung kann man leben *g* ..
Noch ne zweite Frage. Was ist wenn ich OpenGL Licht nehme. Das verfälscht oder schaltet doch die Farbgebung der Dreiecke aus oder ?
Das mit den Quads war nur für den Fall gedacht, dass man glShaderModell verwenden möchte.
Ansonsten muß man so fein unterteilen, wie man die Auswahl haben möchte. Im Normalfall wäre dass auf Dreiecksebene. Also wie schon oben beschrieben, jedes Dreieck wird zu einem eigenen Objekt. Aber da trotzdem alle in einem Buffer liegen, braucht man weiterhin nur einen Aufruf.
Zitat:
D.h. Wenn ich jedes einzelne dreieck per glDrawRangeElements rendere macht es keinen unterschied zu Befehl glDrawElements, der den ganzen Vertex rendern würde? .. ich könnte somit jedem einzelnen Polygon einen Namenzuweisen.
Code:
for i :=0tomaxdo
begin//Namen vergeben
glDrawRangeElements //ein Dreieck Zeichnen
end;
Der Name wird mit der Farbe vergeben:
Code:
var color:Integer;
for i :=0tomaxdo
begin//Namen vergeben
color:=i+1;
glcolor4ubv(@color);
glDrawRangeElements //ein Dreieck Zeichnen
end;
Das ist so schon vom Prinzip her richtig, nur sind es noch zu viele Aufrufe:
Daher kopiert die Farbe direkt in die Punkte im Vertex Buffer:
Code:
for i :=0tomaxdo
begin
color:=i+1;
buffer[i*3]:= erste vertex des Dreiecks mit Farbe color
buffer[i*3+1]:= zweite vertex des Dreiecks mit Farbe color
buffer[i*3+2]:= dritte vertex des Dreiecks mit Farbe color
end;
glDrawArrays(GL_TRIANGLES,0,(max+1)*3);// keine Indizies mehr verwenden
Also kann ich beim Landschaftmoddeling kein Licht benutzen, falls ich diese Art der Selektion nutze?
Hm. stell ich mir etwas komisch vor, da noch ne landschaft erkennen zu können oder ? Führt auch kein Weg dran vorbe ?
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Bei der klassischen Selektion ist es ja auch so, dass du zu erst einmal die Ansicht verdrehst, dann alles zeichnest und zum Schluss die Szene noch mal richtig darstellst. Genau das Gleiche kannst du bei der Selektion über die Frabe auch machen. Zum herrausfinden welches Dreieck getroffen wurde zeichnest du die Dreiecke in der Farbe, ließt den Wert aus und anschließend stellst du die Szene für den Benutzer dar. So wie du es haben willst.
Achte aber darauf, dass du SwapBuffers nicht nach der Farbselektion aufrufst. Sondern erst nachdem die Szene so aussieht wie es für den Benutzer angedacht ist.
Man muss hier unterscheiden ob man die Landschaft zur Anzeige oder zur Selektion rendert. Wenn der Benutzer irgendwohin klickt, wird die Landschaft mit den speziellen Farben gerendert, aber am Ende nicht SwapBuffers(dc) aufgerufen, so dass die Farben im BackBuffer bleiben und von dort dann mit glReadPixel ausgelesen werden.
Registriert: Do Jun 19, 2003 10:44 Beiträge: 991 Wohnort: Karlsfeld (nahe München)
Ich nehme mal an das dein Level so aufgebaut ist, das du über die x,y Position deines Koordinatensystems jedes Dreieck identifizieren kannst.
Dann könntest du die Mauskoordinaten + Tiefenwert in eine 3D Position umrechnen. Mit dieser Position wiederum könntest du das geklickte Quadrat ermitteln. Das Umrechnen kann gluUnProject für dich machen.
MfG
Flo
_________________ Danke an alle, die mir (und anderen) geholfen haben. So weit... ...so gut
Mitglieder in diesem Forum: 0 Mitglieder und 5 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.