Registriert: Fr Mai 16, 2008 20:26 Beiträge: 158 Wohnort: Berlin
Programmiersprache: c++,c#,java,ruby,php
Nur mal kurz eine Verständnisfrage:
Die Parameter Start, End und Count, wie sind die zu interpretieren?
Meine Annahme war: Ich hab ein VBO und will es in 3 Teile "zerlegen" und rendern.
Ich weiß, dass es z.B. 120 Faces gibt.
Also wären die Werte z.B.:
Code:
Teil Start End Count
115555
25610752
310812013
bzw. 0-119.
Weil aber mal zuviel, mal zu wenig, gerendert wurde, hab ich mal versucht die Werte ansich zu hinterfragen, ob Count nicht z.B. für die Anzahl der Gesamtfaces als Byte-Offset steht, oder etwas ähnliches.
Ich hab etliche Seiten gefunden, welche genau die gleiche Seite, wie das Wiki beinhalten, nur für andere Sprachen, aber keinen Hinweis, außer ein Forenbeitrag auf Englisch, der mich nur mehr verwirrte, deshalb würde ich das gerne nochmal in meinen Schädel getrichtert bekommen.
Eventuell könnte man das Wiki auch etwas anpassen und eine bessere Beschreibung als "count: Anzahl der zu rendernden Elemente." einfügen, weil Elemente ist etwas schwammig -> Elemente: Verticesanzahl? Facesanzahl? Gesamtfaces des VBOS? Irgendein ByteOffset? Eieranzahl im Himalaya? ^^
Also wie sind die 3 Werte genau zu intepretieren?
Außerdem bekomme ich manchmal einen "out of memory"-Fehler, obwohl die Limits eingehalten wurden, so weit ich das Überblickt habe.
mfg Revolte und danke für die Geduld ^^
Edit: Ich hab auch alle Forenbeiträge durchgelesen, die mit der Funktion etwas zu tun haben und hab ich nicht wirklich etwas hilfreiches gefunden :doh:
_________________ System: Phenom XII X4 955 3,21Ghz , GTX 560 TI, 4GB-Ram, Windows 7 64x
Registriert: Fr Mai 16, 2008 20:26 Beiträge: 158 Wohnort: Berlin
Programmiersprache: c++,c#,java,ruby,php
Also ich hab zwar herausgefunden, dass
start -> der kleinste Index und
End -> Der höchste Index ist.
Ich dachte das gibt den Bereich an, welcher gerendert werden soll.
Count würd ich dann aber eher Offset nennen, weil das ja die Position angibt, ab wo die Werte im Buffer genommen werden (oder?).
Aber irgendwie haut das immernoch nicht ganz hin.
Wenn ich 3 Teile hab, woher weiß er den, wann er aufhören muss zu Zeichnen?
Der höchste Index kann es ja nicht sein, weil es kann ja vorkommen, dass in einem teil des Meshes ja schon ein Index benutzt wird, welcher jedoch sehr Hoch ist, oder seh ich das Falsch? Jedenfalls sieht das in der.mtl-Datei so aus.
Vor allem kann ja ein Index mehrmals verwendet werden mhh.
Aus Manuals und Beschreibungen dazu bin ich nicht ganz so schlau geworden:
Hab schon mit vielen Möglichkeiten rumgespielt: ein Würfel mit 4 Materialien, jedoch wird entweder nur 1 Material angezeigt, oder 2 über alles verteilt, oder alle, dafür wird aber nicht der ganze Würfel gerendert..
Man wieso bin ich nur so begriffsstutzig vermutlich fällts mir wie schuppen vond en Augen wenn es mir jemand sagt xD
mfg^^
_________________ System: Phenom XII X4 955 3,21Ghz , GTX 560 TI, 4GB-Ram, Windows 7 64x
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Also ich benutze überwiegend glDrawElements. Die ist mit Range aber auch recht gleich. Wenn man mal von Start und End absieht. Und ja ich bin auch der Meinung, dass Start und End dazu da sind um den Vertexindex innerhalb des Indexbuffers begrenzen zu können. Also wenn du sagst Start = 10 und End = 30 und in dem Indexbuffer wird auf Vertex 31 verweisen, dann sollte das Vertex verworfen werden.
Zur Bestimmung des Bereiches innerhalb des Indexbuffers ist der letzte PointerParameter da. Sagen wir mal du hast Vertex und Indexdaten in zwei BufferObjects. Dann benötigst du bei glDrawElements folgende Werte. Mode gibt an welche Primitive du zeichnen willst (QUADS, TRIANGLE etc). Count ist die Anzahl an Vertices die gezeichnet werden sollen. Type ist der Typ des Indexbuffers (Vorzeichenlose 1, 2 oder 4 Byte Werte). Und Indices ist normal nil. Wenn du jetzt ab Index 100 loslegen willst müsstest du 100 * Indexgröße (1, 2, 4 Bytes) übergeben. Das ganze natürlich als Pointer casten.
Befindet sich Index und Vertex innerhalb eines BufferObjectes so musst du noch den Anfangsoffset der Indexdaten mit zu diesem Pointer hinzurechnen. Hast du den Index noch Lokal solltest du schauen, dass du den hoch lädst.
Also folgendes Beispiel für Vertex und Indexdaten in einem BufferObject.
Ich bin mir aber gerade nicht so recht sicher ob ich deine Frage so richtig verstanden habe. Falls nicht, dann wäre es gut, wenn du sie mir noch mal etwas detailierter erklärst. Und vor allem das was du damit erreichen möchtest.
Registriert: Fr Mai 16, 2008 20:26 Beiträge: 158 Wohnort: Berlin
Programmiersprache: c++,c#,java,ruby,php
Vorweg: Wenn ich von Objekt spreche meine ich ein in Blender erstelltes .obj-Objekt xD
Also erstmal danke, dann werd ich mir das nochmal genauer angucken, Aber:
mit gldrawelements hat ich bisher auch keinerlei Probleme und konnte auch alles darstellen.
Da war mir dass mit den übergebenen Daten irgendwie logischer als jetzt mh ^^
Was ich vor habe:
ich lade ein ein Level, dort werden dann natürlich alle statischen Objekte enthalten sein, welche das Level beinhaltet.
Dieses wird dann in ein einzelnes VBO gepackt.
Das schlussendlich folgenes dabei rauskommt:
Code:
binde das VBO ->
Vertex/Texturkoords/Normalen/Index -Buffer
für jedes Material ->
binde Textur/setze Farbe/setze Shader ..
für jedes "Objekt bzw. Teil des Objektes" mit dem Materialn ->
translate/rotate/scale (später eventuell per Matrix + nur wenn Objekt sichtbar(Octree))
gldrawrangeelements ->
nehme die im Objekt gespeicherten Daten für die Start/End/Count - Werte und rendere das Teil-Objekt
So hab ich das bisher immer gelesen, dass das am effizientesten sein soll ^^
Aktuell hab ich für jedes Objekt ein VBO und gebe das mit drawElements aus, was wunderbar klappt, aber mich stört dieser unnötige Datenüberfluss und VBO gebinde, außerdem kann ich so mehrere Materialien und Texturen für ein Objekt haben, ohne großartig etwas zu ändern.
Hoffe das Problem ist nun ein bisschen verständlicher geworden, wieso ich drawrangeelements nehmen möchte.
mfg revolte
P.S. ich arbeite mit Java deshalb ist mit PointerCasten nicht so viel möglich xO , aber mich stört es nicht wenn es PsuedoCode/Delphi/C++ ist, umsetzen kann ich das meiste irgendwie dann schon ^^
EDIT: Also ich hab jetzt nochmal anhand des Würfels und manueller eingabe der Werte irgendiwe gemerkt, dass nur Count einen Effekt hat, aber Start und End irgendwie nicht beachtet werden Ich bin von 0 bis 32 für Start und End durchgegangen und hab einige Kombinationen benutzt (Start < End), für jeweils konstante Count Werte.
Aber irgendwie beeinflusste nur Count das Erscheinungsbild, indem je nach höhe des Wertes mehr gezeichnet wurde ( was ja eigentlich auch sein soll, aber doch nicht immer anfang beim 1. vertice) mh.
Hab ich die Funktion vll total falsch verstanden? o.o
_________________ System: Phenom XII X4 955 3,21Ghz , GTX 560 TI, 4GB-Ram, Windows 7 64x
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Also Start und End dienen meiner Meinung nur dazu um den Index des Vertices zu beschränken. Folgendes Beispiel. Du hast ein VertexBuffer mit 8 Vertices. Also 2 Quads. Und du hast einen IndexBuffer mit ebenfalls 8 Einträgen. Der Index besteht eigentlich nur aus den Werten 1-8 und verweist auf die Vertices 1-8. Wenn du jetzt mit DrawElements 8 Vertices ausgibst sollten beide Quads entstehen. Und wenn du DrawRangeElements mit start = 0 und end = 7 und count = 8 aufrufst, dann sollten auch beide gezeichnet werden. Wenn du DrawRangeElements aber mit mit start = 0 und end = 3 und count = 8 aufrufst, dann sollten nur das erste Quad gezeichnet werden. Allerdings geht er trotzdem durch das ganze VBO. Wenn du in dem Index später noch mal vertex 1-4 benutzt, und das in count berücksichtigt ist, dann werden diese auch mit ausgegeben.
Um aber nur Vertex 5-8 auszugeben ist das vermutlich nicht so gut geignet. (Bei meinen Test hatte ich aber das Gefühl als ob start bei mir keine Auswirkung hatte sondern nur end.) Mir fehlt auch ein bisschen die Vorstellungskraft wozu das wirklich genau gut sein soll. Aber du kannst an dem letzten Parameter ein Offset angeben. Und zwar ist das ein Offset innerhalb des Indexbuffers. Wenn du also Vertex 5-8 ausgeben willst, dann genügt es, wenn du Count = 4 setzt und bei Index entsprechend ein offset wählst. Wenn dein Indexbuffer Bytes enthält ist es 4. bei 16 Bit Werten, 8 und bei 32 Bit Werten dann entsprechend 16. In Delphi ist dieser Wert ein Pointer. Java kennt zwar keine Pointer aber wichtig ist der Inhalt. Also wenn du dort ein Integer übergeben kannst ist das auch vollkommen genug.
Registriert: Fr Mai 16, 2008 20:26 Beiträge: 158 Wohnort: Berlin
Programmiersprache: c++,c#,java,ruby,php
Ahhhhhh Vielen Dank !!!
Dass der Offset ganz hinten angegeben werden kann, dass war des entscheidende. Also Start und End werden bei mir so oder so ignoriert, aber mit Count kann ich die Anzahl an Indicies rendern, ab dem Offset, welcher im letzten Parameter definiert ist.
Ich dachte im letzten Parameter kann ich nur einen ganzen Buffer übergeben, bzw. 0 wenn der Buffer vorher gebunden wurde. Dass muss man echt erstmal wissen vielen vielen dank =D
Hoffe das klappt nun auch weiterhin, so wie ich mir das vorstelle, aber bisher macht es dass, was es soll ^^
mfg revolte
edit:
Mh was ich nun merkwürdig finde, er rendert alles genau so wie er soll, sogar mit den richtigen Materialien, eigentlich Perfekt. Sogar die Framerate hat sich in der unoptimierten Fassung fast verdoppelt O.O
Aber nach wenigen Sekunden ca. 3-10, schmiert meine Graka mit einem schweren "Grafikartentreiber Ausnahmefehler" ab ohne irgendwelche Fehler, Infos oder Logs zu hinterlassen .-.
Aber auch nur wenn ich den Offset angebe. Aber da er ja eigentlich alles rendert ohne Fehler, dürfte es doch dadran nicht liegen?
Eventuell hängt es mit gl.glBindBuffer zusammen, das hat ich Testweise mal geändert?
gl.glBindBuffer(GL.GL_ARRAY_BUFFER,
gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB,
Das sollte doch Treibertechnisch eigentlich das gleiche sein oder?
edit2: Anscheinend ist das ein Problem mit Java, weil Java nur einen "Signed"-Int hat, OpenGl aber einen Unsigned-Int benötigt. Wenn ich
(("Signed"-Int -1) * Offset) rechne, dann kommt Natürlich Murks raus, aber der treiber schmiert nicht ab, vermutlich weil es kein OutOfBounce gibt dann. Aber vll lässt sich das in einem JavaForumbesser erfragen =)
Trotzdem danke soweit, das hat mich wirklich voran gebracht.
_________________ System: Phenom XII X4 955 3,21Ghz , GTX 560 TI, 4GB-Ram, Windows 7 64x
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Ja glBindBuffer und glBindBufferARB sollten eigentlich recht gleich sein, da die ARB Variante zur VBO Erweiterung gehört die in OpenGL 1.5 direkt zum Kern hinzugefügt wurde. Wenn der Treiber schlau ist, dann haben sie intern auch nur eine Methode. Hab gerade mal geschau. Bei mir haben glBindBuffer und glBindBufferARB die selbe Adresse. Und die Konstanten sind auch gleich. Ergo ist das wirklich sehr gleich.
Und ja. Bei BufferObjects sollte man vorsichtig sein. Wenn man unsachgemäß damit umgeht kann es schnell zu Zugriffsverletzungen kommen. Habe ich selber schon oft genug erlebt, dass mir eine ati_blah.dll Fehler geschmissen hat. Aber typischerweise passiert so etwas dann sofort und nicht erst nach ein paar Sekunden. Da solltest du evtl. mal schauen ob du nach ein paar Sekunden nicht irgendwas anderes machst. Das Vorzeichen kann da natürlich auch zu einem Problem führen. Wobei das aber nur spannend wird sobald du Werte unterhalb von 0 bekommst. Dann wird das höchste Bit gesetzt. Aber Werte unterhalb von 0 sollten selbst bei unsigned unschöne Ereignisse mit sich bringen.
Der Ursprung der Buffer Objects liegt schon ein Stück zurück. Nur damals wurden die Daten noch nicht zur Grafikkarte geschickt sondern lokal gehalten. Und dann musste an diese Methoden immer ein Pointer auf die Daten übergeben werden. Buffer Objects benutzen die gleichen Methoden wie die damaligen VertexArrays. Deswegen sind überall Pointer zu finden. Nur haben die Pointer jetzt die Aufgabe eines Offsets. VertexArays funktionien heute immer noch. Und bei DrawElements ist es auch bei Buffer Objects möglich lokale Indexdaten zu übergeben. Aber aus Sicht der Asynchronität und der Geschwindigkeit ist das ziemlicher quatsch. Aber das trägt halt leider nicht zum sauberen Verständniss dieser Technologie bei. Was das alles etwas konfus macht.
Registriert: Fr Mai 16, 2008 20:26 Beiträge: 158 Wohnort: Berlin
Programmiersprache: c++,c#,java,ruby,php
Ah das ist schonmal gut zu wissen. Hab es mit beiden Varianten getestet sicherheitshalber, kommt aber aufs gleiche Ergebnis raus.
Ähme.. mein Hirn ist irgendwie lustig.. da schreib ich hier eine Zeile und dann fällt ihm die Lösung ein ^^ deshalb hat es im Oberstübchen immer so gerattert.
Lösung: ich hab als Count einfach den Wert übergeben gehabt, welcher die Grenze angibt, was gerendert werden soll. Ohne Offset passiert da natürlich nichts, weil der Endwert maximal aufs Ende zeigt, aber mit einem Offset, kann der wert natürlich ins nirgendwoh geraten =O
Ich zieh jetzt vom Endwert den Startwert ab, und nun lief es ohne Fehlermeldung und nochmal 150fps schneller (insgesamt 550-650 nun).. krank ^^
Warum es erst nach unterschiedlich wenigen Sekunden Probleme gab lässt sich vermutlich auch erklären. Ich verteile die Objekte noch per Zufall zum testen und wenn das Face mit dem EndIndex, welcher ja dann im nirgendwo lag, zu sehen war, kam der Fehler, manchmal lief es und dann hab ich mich durch die Szene bewegt, bis anscheinend der Endpunkt zu sehen war.
*Lossy Ex Kekse und Milch hinstell wahlweise auch Gummibärchen**Alle anderen mit grimmigen Blick fernhalte* Vielen Dank, dass hat mir doch sehr geholfen alles =D
Aber Hintergrundwissen ist immer gut zu haben, vor allem weil man so auch leichter die Fehler nachvollziehen kann^^
mfg der Revolte, der bald mit Octrees nerven wird ^^
_________________ System: Phenom XII X4 955 3,21Ghz , GTX 560 TI, 4GB-Ram, Windows 7 64x
Mitglieder in diesem Forum: 0 Mitglieder und 3 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.