Laden...

DirectX: Tutorial

Erstellt von hauptmann vor 19 Jahren Letzter Beitrag vor 19 Jahren 62.277 Views
Thema geschlossen
K
355 Beiträge seit 2004
vor 19 Jahren

Ka ich progge auch noch nich lange Managed DX 🙂

H
hauptmann Themenstarter:in
704 Beiträge seit 2003
vor 19 Jahren

** Der Indexbuffer - Indizieren von Vertices **

Diesmal sehen wir uns den sogenannten Indexbuffer an. Indexbuffer sind dazu da um Vertices zu reduzieren.
Bei einer Indizierung fallen nämlich doppelte Vertices weg und man kann so einen Vertexbuffer deutlich optimieren.
Nehmen wir an wir wollen zwei Dreiecke zeichnen. Grafisch würde das so aussehen:
1 2|4

0|3 5

Die Nummern geben dabei die einzelnen Vertices an. Für dieses Beispiel bräuchten wir also 6 Vertices in einem
Vertexbuffer. Jedoch fällt uns auf das zwei Vertices mit den selben Koordinaten zweimal im Vertexbuffer stehen.
Ist das nicht sinnloser Verbrauch von Speicherplatz? Deshalb erstellt man nun einen Indexbuffer in dem man
speichert, an welcher Position welcher Vertex ist. (sry, aber ihr solltet den Beitrag quoten oder die im zip beiliegende Tutorial.txt ansehen, dort wird die Tabelle richtig dargestellt -.- )
Index Wert Vertex
0 0 (x0,y0)
1 1 (x1,y1)
2 2 (x2,y2)
3 0 (x0,y0)
4 2 (x2,y2)
5 5 (x5,y5)

Wie wir in der Tabelle sehen müssen wir nur mehr 4 verschiedene Vertices speichern, nicht mehr 6 verschiedene.
In diesem Beispiel mag das nicht als viel erscheinen, aber wenn man große Objekte hat, kann man mit Indexbuffer
viel einsparen und sehr gut optimieren. Zu beachten ist aber, dass man jedoch 6 Indices braucht. In DirectX SDK
Hilfe wird übrigens empfohlen nur mit indizierten Vertices zu arbeiten. Und nun können wir bereits zu Praxis
kommen. Direct3D stellt uns die Klasse IndexBuffer zur Verfügung, um einen IndexBuffer zu erstellen. Wir werden
jedoch nicht direkt mit dem Indexbuffer arbeiten sondern verwenden ein Mesh Objekt. Ein Mesh Objekt ist einfach
eine Klasse die das Arbeiten mit Vertexdaten vereinfacht.


Mesh Object;

Sehen wir uns nun die OnCreateDevice Funktion an. Hier erstellen wir zuerst 4 Vertices, danach 6 Indices und
speichern diese im Mesh Objekt:


		public void OnCreateDevice(object sender, EventArgs e)
		{
			Device dev = (Device)sender;

			CustomVertex.PositionOnly[] verts = { 			
										new CustomVertex.PositionOnly(-1f,  0f, -1f),
										new CustomVertex.PositionOnly( 1f,  0f, -1f),
										new CustomVertex.PositionOnly( 1f,  0f,  1f),
										new CustomVertex.PositionOnly(-1f,  0f,  1f),
			};

			short[] indices = { 0,1,2,		// erstes Dreieck
								  0,2,3 };	// zweites Dreieck

Dieser Code bietet uns keine Probleme. Wir verwenden short Indices aus Speicherplatzgründen, da wird ja nur kleine
Werte brauchen(von 0 bis 3) und so müssen wir auf dem RAM der Grafikkarte pro Index nur 2 Bytes verwenden anstatt
4 Byte wie bei int. Die Zahlen im indices Array weisen auf die Vertices hin, die beim Zeichnen verwendet werden.
Für das erste Dreieck verwenden wir die Vertices 0, 1 und 2. Fürs zweite 0, 2 und 3.


Object = new Mesh(indices.Length / 3,verts.Length,MeshFlags.WriteOnly,CustomVertex.PositionOnly.Format,
							  device);

			Object.VertexBuffer.SetData(verts,0,LockFlags.None);
			Object.IndexBuffer.SetData(indices,0,LockFlags.None);

		}

Hier erstellen wir ein neues Mesh Objekt und setzen die VertexBuffer und IndexBuffer Werte dafür. Die Parameter
des Mesh Konstruktors sind einfach:
Der erste Parameter gibt die Anzahl der Flächen eines Objektes an. Wir brauchen logischerweise 2 Flächen. Einmal
fürs erste Dreieck und einmal fürs Zweite.
Der zweite Paramter gibt dann die Anzahl der Vertices an. Der Dritte gibt sogenannte MeshFlags an. Diese können
dazu verwendet werden der Klasse gewisse Informationen zu geben, wie sie die Daten behandeln soll. Wir wollen nur
Daten in das Mesh Objekt schreiben, jedoch keine herauslesen. Dazu geben wir MeshFalgs.WriteOnly an. Das nächste
ist das Format der Vertexdaten. Der letzte Parameter gibt dann schließlich das Device an.
Danach greifen wir direkt auf den VertexBuffer und den IndexBuffer zu und setzen die Daten mit SetData.
Nun können wir auch schon zur Renderfunktion kommen.
Diese ist diesmal auch ganz einfach:


			device.Clear(ClearFlags.Target , System.Drawing.Color.Blue, 1.0f, 0);
			
			device.BeginScene();

			device.Transform.View = Matrix.LookAtLH( new Vector3( 0.0f, 3.0f,-5.0f ), new Vector3( 0.0f, 0.0f, 0.0f ), new Vector3( 0.0f, 1.0f, 0.0f ) );
			device.Transform.Projection = Matrix.PerspectiveFovLH( (float)Math.PI / 4, 1.0f, 1.0f, 100.0f );

			device.Transform.World = Matrix.Identity;
			
			device.RenderState.CullMode = Cull.Clockwise;
			Object.DrawSubset(0);

			device.EndScene();
			device.Present();

Der Code bietet eigentlich nur vertraute Dinge -.-

Was ist jetzt jedoch wenn wir direkt aus einem VertexBuffer und einem IndexBuffer heraus rendern wollen? Dazu
können wir die Funktion DrawIndexedPrimitives verwenden (oder DrawIndexedUserPrimitives wenn wir ohne Vertexbuffer
arbeiten wollen). Doch um diese Funktion müssen wir uns erstmal nicht kümmern, da uns ja die Mesh Klasse die
meiste Arbeit abnimmt.

Wie immer gibt es das gesamte Visual Studio 2003 .net Projekt als zip zum Download.(achtung, ich verwende immer jeweils das neueste SDK dh für diese Version braucht ihr das April Update des SDKs, ich glaube aber das es mit älteren Ausgaben des SDK auch funktionieren sollte)

[last.fm](http://www.last.fm/user/hauptmanAlpha/)
S
125 Beiträge seit 2005
vor 19 Jahren

Wow... alle Achtung für dieses Tut. 👍
Sowas hab ich schon lange gesucht. Mich würd mal interessieren wie lange du schon (C#) proggst und vor allem wie weit du das hier noch durchziehen möchtest. Ist doch ne ganze Menge Arbeit.
Hab mich mal vor die DX-Doku gesetzt, ist schon ziemlich viel was da drin steht 😁 (alleine D3D betreffend). Respekt vor dem der sich da durch kämpft. 🤔

Wie gesagt, nur weiter so, bin gespannt...

*************************
Ich bin root, ich darf das... 😜
root>_
*************************

H
hauptmann Themenstarter:in
704 Beiträge seit 2003
vor 19 Jahren

Hi!

Mich würd mal interessieren wie lange du schon (C#) proggst und vor allem wie weit du das hier noch durchziehen möchtest. Ist doch ne ganze Menge Arbeit.

So ca. 2.5 Jahre und schreiben will ich das halt solange ich Zeit und Lust habe -.-

Das Tutorial ist jetzt unter Link verfügbar

[last.fm](http://www.last.fm/user/hauptmanAlpha/)
Thema geschlossen