Pro Mesh einen Vertex+IndexBuffer?

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Pro Mesh einen Vertex+IndexBuffer?

Beitrag von Eisflamme »

Hey ho,

Ich habe jetzt ein Model geladen, welches allerdings 38 Meshes enthält. Eigentlich muss ich ja jetzt für jedes einzelne Mesh einen eigenen Vertex- und IndexBuffer anlegen, oder? Ich stelle mir das alles allerdings sehr grausam vor, wenn ich das Objekt jetzt 100 Mal rendern möchte. In dem Fall würde sich dann ja wiederum anbieten, erst 100 Mal Mesh 1 zu rendern, dann 100 Mal Mesh 2 zu rendern etc....

Ist so was jetzt nicht super inperformant? Wie render ich so was denn am Besten?
Benutzeravatar
Krishty
Establishment
Beiträge: 8248
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von Krishty »

Du kannst alle Meshes in einem gemeinsamen Vertex- und Index-Buffer batchen. Du schreibst sie einfach hintereinander und merkst dir in jedem Mesh, bei welchem Index jeweils die Vertex- und Indexdaten anfangen. Wenn du dann DrawIndexed() aufrufst, übergibst du als StartIndexLocation den Index, bei dem die Indexdaten des jeweiligen Meshes im Index-Buffer beginnen und als BaseVertexLocation den Index, bei dem die Vertexdaten im Vertex-Buffer beginnen. Da BaseVertexLocation auf alle Indizes aufaddiert wird, verweisen die Indizes beim Rendern wieder auf die richtigen Vertices.

So ein Batching ist weit verbreitet – man benutzt es, um Vertex-Buffer auf die optimale Größe von 65536 Vertices zu bekommen.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von Eisflamme »

Hi,

Danke für die schnelle Antwort!

Das klingt sehr interessant. Macht es denn dann Sinn, einen globalen VertexBuffer-Verwalter für alle Objekte überhaupt zu basteln und die Objekte dort einzutragen? Wenn Du sagst, man solle VertexBuffer immer auf 65536 Vertices auffüllen, sollte man ja offensichtlich Vertex- und IndexBuffer-Objekte weder anzahlig 1 : 1 zu den Meshes, aber doch auch nicht 1 : 1 zu den 3D-Modellen erstellen, oder?

Weiterhin klingt es für mich sinnvoll, wenn man Objekt A 10 Mal rendern möchte, jeweils Mesh 1 10 Mal zu rendern und dann Mesh 2. Das würde wiederum erfordern, dass wir uns irgendwo merken, wie oft Objekt A gerendet wird, damit wir das Rendern optimieren können, oder?
Benutzeravatar
Krishty
Establishment
Beiträge: 8248
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von Krishty »

Eisflamme hat geschrieben:Das klingt sehr interessant. Macht es denn dann Sinn, einen globalen VertexBuffer-Verwalter für alle Objekte überhaupt zu basteln und die Objekte dort einzutragen? Wenn Du sagst, man solle VertexBuffer immer auf 65536 Vertices auffüllen, sollte man ja offensichtlich Vertex- und IndexBuffer-Objekte weder anzahlig 1 : 1 zu den Meshes, aber doch auch nicht 1 : 1 zu den 3D-Modellen erstellen, oder?
Um das zu beantworten habe ich leider zuwenig Erfahrung. Batching war, insbesondere zu Direct3D8- und -9-Zeiten, Common Practice … heute ist das Ändern eines Vertex-Buffers, solange der neue Puffer dasselbe Input-Layout hat, nur das Ändern eines Zeigers … ich bezweifle, dass es noch den Schub bringt, für den es früher bekannt geworden ist.
Eisflamme hat geschrieben:Weiterhin klingt es für mich sinnvoll, wenn man Objekt A 10 Mal rendern möchte, jeweils Mesh 1 10 Mal zu rendern und dann Mesh 2. Das würde wiederum erfordern, dass wir uns irgendwo merken, wie oft Objekt A gerendet wird, damit wir das Rendern optimieren können, oder?
Ist das klassische Renderproblem … darauf gibt es genauso wenig eine universelle Antwort wie darauf, wie man mit transparenten Objekten umgeht. Ist immer stark implementationsabhängig und erfordert ein Abwägen, ob die GPU das nicht schneller runtergerendert kriegt (Instancing!) als du die Ausganslage auf der CPU optimieren kannst.

Bei beiden Fragen hängt die Antwort davon ab, ob das Problem überhaupt eine gewisse Relevanz besitzt (sind Vertex-Buffer-Switches Bottlenecks?), wieviel Zeit du zu investieren bereit bist und wie weit du gehen willst.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von Eisflamme »

Ein sehr philosophischer Post. :) Dann spar ich mir die Mühe von solch einer Verwaltungsklasse und mache es halt erstmal objektweise.

Ich bin allerdings auf ein Problem gestoßen: Ich nutze OpenGL. Wie kann ich bei der Verwendung von VertexBuffer-Objekten denn ein Offset festlegen? Wenn ich die Vertexdaten so vorliegen habe, addiere ich das Offset einfach zum Pointer, hier habe ich als letzten Parameter bei glVertexPointer aber die 0.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von kimmi »

Du übergibst beim Rendern als Vertexarray doch einen Pointer. Mittels Pointerarithmetik kannst du dir die jeweilige Position des Mesh-bezogenen VertexBatches ermitteln und den dann rendern.

Gruß Kimmi
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von Aramis »

addiere ich das Offset einfach zum Pointer, hier habe ich als letzten Parameter bei glVertexPointer aber die 0.
Wenn meine Erinnerung mich nicht trügt ist der letzte Parameter dann in der Tat der Offset (zum Pointer casten …). Außerdem haben einige der OpenGL-Zeichenfunktionen die Möglichkeit den Startindex anzugeben (ganz mal davon abgesehen dass der Offset ja auch im Indexbuffer hinterlegt sein kann …).
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von kimmi »

Stimmt, Aramis hat natürlich recht. Man legt einen großen VBO und rendert das Submesh dann einfach per IndicesRender-Calls.

Gruß Kimmi
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von Eisflamme »

Hi,

Also ich drawe ja über glDrawElements. Wenn das: "
Wenn meine Erinnerung mich nicht trügt ist der letzte Parameter dann in der Tat der Offset (zum Pointer casten …).
", dann ist das Problem natürlich gelöst. Aber anderenfalls habe ich jetzt keine Ahnung, wie ich vorgehen sollte.
Fred Feuerstein
Beiträge: 4
Registriert: 12.03.2010, 19:03
Benutzertext: Ahoi
Alter Benutzername: Fred Feuerstein

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von Fred Feuerstein »

Hio.
Ich weis nicht ob das hilfreich ist , aber Instancing ist ggf. auch ne Lösung.
Allerdings auch nur bis zu einem gewissen Grad.
Hab leider grad keinen guten Link parat:
http://blogs.msdn.com/manders/archive/2 ... ncing.aspx
Der veranschaulicht das ganze für 2D-Objekte, das Prinzip bleibt
davon unberührt.
MfG Fred
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von kimmi »

Da habe ich mal eine Frage: gibt es Instanting unter OpenGL? Ich habe bisher diesbezüglich noch nie Infos finden können. Vielleicht weiß hier ja einer mehr, wie man das dort anstellen beziehiungsweise implementieren könnte.

Gruß Kimmi
glassbear
Establishment
Beiträge: 324
Registriert: 08.04.2003, 18:09
Alter Benutzername: Enrico_
Echter Name: Enrico
Wohnort: San Diego
Kontaktdaten:

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von glassbear »

kimmi hat geschrieben:Da habe ich mal eine Frage: gibt es Instanting unter OpenGL?
Ja, gibt es. Sogar verschiedene Optionen
Dann hier noch eine Demo, die verschiedene Instancing-Methoden implementiert und vergleicht, mit Performance-Werten verschiedener Grafikkarten.
Ein Hoch auf uns Männer... Auf die Frau, die uns HAT ( oder hat, und nicht weiß, dass sie uns hat ) ...auf die Idiotinnen ... besser gesagt VOLLPFOSTINNEN ... die uns hatten und uns verloren haben ... und auf die GLÜCKLICHEN, die das Vergnügen & Glück haben werden uns kennenzulernen!
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von kimmi »

Cool, den Link kannte ich nicht. Vielen Dank dafür. @Eisflamme: Wäre das nichts für dich ;)?

Gruß Kimmi
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von Eisflamme »

Sieht auf alle Fälle interessant aus und ich hab's mir Mal abgelegt. :)

Ich würde gerne mein Problem mit den Buffern noch lösen. Also über "glDrawElements" sehe ich nach wie vor kein Offset, wenn der Pointer 0 ist. Einfach eine Zahl in einen Pointer zu konvertieren, würde ja auf Speicherbereiche jenseits von Gut und Böse führen bzw. müsste die Extension diese Bereiche ja als unsinnig identifizieren und dementsprechend das Offset auf das Vertexbuffer-Objekt anwenden - ich gehe nicht davon aus, dass das der Fall ist!?

Danke für eure Zeit und Mühe!
Dirk Schulz
Establishment
Beiträge: 130
Registriert: 01.03.2009, 14:21
Alter Benutzername: frittentuete

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von Dirk Schulz »

Hi,

hier nochmal die Doku zur Funktion, damit wir über dieselben Definitionen reden:
http://www.opengl.org/sdk/docs/man/xhtm ... ements.xml

der letzte Parameter "indices" will einen Pointer auf deinen Index-Array haben. Das heißt, du hast wahrscheinlich irgendwo ein unsigned int indices[num_indices], oder über new [] erstelltes Array mit den Indexwerten.

die Funktion erwartet von dir jetzt einen Pointer auf den ersten Eintrag im Indexarray, den du rendern willst.

Das wäre dann z.b: glDrawElements(GL_TRIANGLES, num_vertices, GL_UNSIGNED_INT, &indices[offset]);


Hoffe das war verständlich. :)
anonym
Beiträge: 79
Registriert: 15.07.2009, 07:35
Kontaktdaten:

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von anonym »

Eisflamme hat geschrieben:[...] bzw. müsste die Extension diese Bereiche ja als unsinnig identifizieren und dementsprechend das Offset auf das Vertexbuffer-Objekt anwenden - ich gehe nicht davon aus, dass das der Fall ist!?
Genau das ist der Fall: Wenn ein Index-Buffer mittels glBindBuffer gesetzt wurde, dann gibt der indices-Zeiger in glDrawElements den Offset (in Bytes) in den Index-Buffer an. Anonsten wird ein Zeiger auf den ersten Index im Speicher erwartet.
Genauso: Wenn ein Vertex-Buffer gesetzt ist, geben die pointer-Zeiger in gl(Color|Normal|Vertex|...)Pointer den Offset in den Vertex-Buffer hinein an.
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von Eisflamme »

Hi,

Dirk: Ja, aber das Ding ist 0, wenn ich ein Buffer-Objekt nutze, das war der Hintergrund.

anonym: Ehrlich? Das ist ja schick. Super, dann kann ich das ja umsetzen, danke :)
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von kimmi »

Hierzu kann ich den Rendercode der ZFXCE mal als beispiel anbringen:
http://zfxce.git.sourceforge.net/git/gi ... 56;hb=HEAD
Die DrawElement-Calls bekommen einen entsprechenden Pointer auf die Vertexdaten. Hier kann man per Offset den Pointer entsprechend an die gewünschte Stelle shiften.

Gruß Kimmi
Eisflamme
Establishment
Beiträge: 412
Registriert: 26.05.2002, 17:42
Wohnort: Köln

Re: Pro Mesh einen Vertex+IndexBuffer?

Beitrag von Eisflamme »

Okay, ich denke, ich komm jetzt klar, vielen Dank. :) Wenn noch was is, post ich wieder...
Antworten