Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Elemente der 3D- Grafikprogrammierung. Render - Pipeline Aufgabe eines Grafikpakets wie DirectX: mit Grafikkarte eingehende Grafikdaten, Primitive, in.

Ähnliche Präsentationen


Präsentation zum Thema: "Elemente der 3D- Grafikprogrammierung. Render - Pipeline Aufgabe eines Grafikpakets wie DirectX: mit Grafikkarte eingehende Grafikdaten, Primitive, in."—  Präsentation transkript:

1 Elemente der 3D- Grafikprogrammierung

2 Render - Pipeline Aufgabe eines Grafikpakets wie DirectX: mit Grafikkarte eingehende Grafikdaten, Primitive, in Pixel auf dem Bildschirm transformieren Prozess aus mehreren Verarbeitungsschritten: Fixed Function Pipeline: 1.) Vorverarbeitung: -Tesselieren: komplexe Geometrieelemente in einfache Geometrieelemente (Grafikprimitive) zerlegen -Um weitere Operationen zu vereinheitlichen -Z.B. Meshes immer aus Dreiecken 2.) Tranformation und Beleuchtung -Geometrische Umrechnung der Eingangsdaten wird durchgeführt -Teilschritte: -World – Transformation -View-Transformation -Perspektivische Transformation

3 3.) Clipping: Abschneiden von Teilen, die außerhalb des Blickfeldes liegen -Backface Culling: Entfernen von Rückseiten -Beide Prozesse automatisch, aber Programmierer kann durch Setzen von Render-States eingreifen -> Culling abschalten: auch Rückseiten der Objekte erzeugt 4.) Texturierung -Texturen bzw Bilder werden auf Grafikprimitive aufgebracht -entsprechend Lichtverhältnissen eingefärbt 5.) Ergebnisse zusammenführen -Farbwerte der Pixel für Bildschirmausgabe berechnen -Anhand Tiefen-Information (Z-Buffer) wird entschieden, welche Pixel im Vordergrund liegen -Übereinander liegende Pixel werden verschnitten

4 Fixed Function Pipeline: geeignet für feste Strukturen Organische Strukturen wie Gesichter, Pflanzen, Wasser mit Verformungen oder Farbenspiel -> Berechnung aller geometrischen und farblichen Übergänge im Anwendungsprogramm nötig, dann Übergabe an Grafikkarte -> dazu programmierbare Render-Pipeline: Geometrische und farbliche Transformationen nah an der Hardware durchgeführt Vertexshader: zur geometrischen Transformation Pixelshader: zur Texturierung Shader: kleine Programme, die bei Bedarf in Grafikkarte geladen werden um Vertex- oder Pixelberechnungen durchzuführen Vorrangig dann, wenn spezielle geometrische pder farbliche Effekte erzielt werden sollen

5 7.2 Vertices und Vertexbuffer Interne Darstellung eines 3D-Modells: Datenstruktur, die performant gerendert werden kann maximale Geschwindigkeit in Render – Pipeline: am besten Arrays mit Aneinanderreihung von Geometriedaten, die als Ganzes in Grafikkarte geladen und mit einfachen Algorithmen verarbeitet werden können Verzicht auf Kopien -> es darf nur einen Originaldatensatz geben, auf dem dann sowohl Anwendungsprogramm als auch Grafiksystem arbeiten kann In DirectX: Vertexbuffer sind auf Verwendung an Schnittstelle zwischen Grafiksystem und Anwendungsprogramm hin optimiert

6 Vertexbuffer: –reservierter Speicherbereich –Informationen über Knoten (Vertices) eines 3D Modells sind hier abgelegt –Programm kann mehrere Vertexbuffer anlegen und unabhängig voneinander verwenden –in Vertexbuffer steht Aneinanderreihung von Vertices Vertices: –Eckpunkte oder Knoten eines dreidimensionalen Mesh –Hat Positionsdaten und ggf. weitere Daten über den Knoten wie Farbwerte, Texturkoordinaten Möglichst performant: schlichte, starre Struktur für Vertex -> einfachste Möglichkeit: immer gleiche Struktur, kann auch enorme Speichervergeudung bedeuten Daher flexibles Vertex - Format

7 7.2.1 Das Flexible Vertex-Format Flexibles Vertex-Format (FVF): zur Speicherung von Vertices in Vertexbuffer verwendetes Datenformat wird festgelegt Für jedes Attribut bestimmter Datentyp Position des Vertex durch Vektor D3DXVECTOR3 beschrieben, Farbe durch RGBA-Wert D3DCOLOR Zusätzlich ist verbindliche Reihenfolge der Attribute festgelegt -> Gesamtstruktur mit allen Feldern ist festgelegt, nicht verwendete Felder werden gelöscht

8 Vertexformat mit Positionsangabe, Normale, diffusem Farbwert: # define MEINVERTEXFORMAT (D3DFVF_XYZ I D3DFVF_NORMAL I D3DFVF_DIFFUSE) struct meinvertex { D3DXVECTOR3 pos; D3DXVECTOR3 normale; D3DCOLOR color; }; -Symbolische Konstante MEINVERTEXFORMAT verwendet man später zur Reservierung von Vertexbuffer -Datenstruktur meinvertex verwendet als Overlay, wenn man von Vertexbuffer schreiben oder lesen will -Deklaration des Vertexformats -> dieses wird später mit Funktion SetFVF dem Device bekannt gegeben -Bei Deklaration von MEINVERTEXFORMAT kommt es nicht auf die Reihenfolge einzelner Flags an -die Reihenfolge der Felder in der Datenstruktur meinvertex muss sich jedoch streng an Reihenfolge der Attribute in der Tabelle orientieren -> bei abweichender Reihenfolge erhält man später falsche Werte durch unpassendes Overlay

9 Umfassendere Methode zur Definition von Vertexformaten: Array mit Feldbeschreibungen anlegen D3DVERTEXELEMENT9 Diesen an Funktion CreateVertexDeclaration übergeben um Vertexdeklaration zu erzeugen SetVertexDeclaration setzt Deklaration im Device -> Feldbeschreibungen D3DVERTEXELEMENT9 entsprechen in etwa symbolischen Konstanten -> Aufruf von CreateVertexDeclaration entspricht Montage der symbolischen Konstanten durch Oder – Verbindung -> SetVertexDeclaration entspricht Funktion SetFVF -> Vertexdeklaration verwendet man im Zusammenhang mit Vertex- und Pixelshadern, wenn man selbst definierte Formate in der Renderpipeline verwenden will

10 7.2.2 Verwendung von Vertexbuffern Vertexbuffern anlegen für ausgewähltes Vertexformat: Position, Normale, Farbe wird für Vertices benötigt Vertexbuffer bereitstellen über Memberfunktion CreateVertexBuffer aus Interface des DirectX-Device (IDirect3DDevice9) HRESULT CreateVertexBuffer (UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9 **ppVertexBuffer, HANDLE pHandle) -> Länge des Buffers in Bytes, Verwendungsart, flexibles Vertexformat, Memorypool, aus dem Speicher bereitgestellt wird, Pointer für erzeugten Buffer, reservierter Parameter, muss NULL sein -Als Länge übergibt man Anzahl gewünschter Vertices x Größe der Datenstruktur für einen Vertex, etwa sizeof(meinvertex) -FVF-Parameter sollte zu Vertexstruktur passende Bitmaske, etwa MEINVERTEXFORMAT enthalten -im Parameter ppVertexBuffer erhalten wir Funktionsergebnis, d.h. Vertexbuffer

11 Konkretes Beispiel für Anforderung eines Buffers für 1000 Vertices LPDIRECT3DVERTEXBUFFER9 vertexbuffer; device->CreateVertexBuffer (1000*sizeof(meinvertex), 0, MEINVERTEXFORMAT, D3DPOOL_MANAGED, &vertexbuffer, NULL); -Device als Zeiger auf zuvor initialisiertes DirectX-Device -Zugriff auf Vertexbuffer über Interface (LPDIRECT3DVERTEXBUFFER9) -Buffer kann in anderem Adressraum als dem unseres Prozesses liegen und damit konkurrierend von anderen Prozessen verwendet werden -Daher mit Funktion Lock für exklusiven Zugriff ganz oder teilweise sperren ->

12 HRESULT Lock (UINT OffsetToLock, UINT SizeToLock, VOID **ppbData, DWORD Flags) -Offset, ab dem gesperrt wird; Anzahl Bytes, die gesperrt werden; unspezifizierter Zeiger, der nach Aufruf auf den Buffer zeigt; Flags, die Art des gewünschten Locks bestimmen -Bei erfolgreichem Aufruf erhalten wir in ppbData einen Zeiger auf reservierten Vertexbuffer -konkret: meinvertex *pv; vertexbuffer->Lock(0, 0, (void**)&pv, 0); -Wenn SizeToLock auf 0, wird der gesamte Vertexbuffer gesperrt -Nach Funktionsaufruf finden wir in pv einen Zeiger auf Vertexbuffer

13 -Struktur meinvertex dient dann als Overlay zum Lesen/Schreiben in Vertexbuffer for (int i=0; i<1000; i++) { pv[i].pos = D3DXVECTOR3 (1, 1, 1); pv[i].normale = D3DXVECTOR3 (0, 1, 0); pv[i].color = D3DCOLOR_ARGB (255, 255, 255, 0); } -Nach Zugriff Freigabe des Vertexbuffer für andere Prozesse über Funktion Unlock: HRESULT Unlock (VOID) -Freigabe über Aufruf von Release – Funktion: vertexbuffer -> Release();

14 7.3 Grafikprimitive Grafikprimitive in DirectX Grafikprimitive: einfache geometrische Struktur, aus der komplexere Strukturen aufgebaut werden können DirectX kennt Punkte, Linien, Dreiecke als Primitive -> alle räumlichen Modelle werden in Dreiecke aufgelöst >>Triangulierung<< Vertexbuffer kann Punktliste, Linienliste, Linienzug, Dreiecksliste, Dreiecksstreifen oder Dreiecksfächer enthalten

15 Punktliste: D3DPT_POINTLIST Vertexbuffer enthält einzelne Punkte Linienliste: D3DPT_LINELIST Zwei aufeinanderfolgende Vertices werden als Anfangs- bzw Endpunkt einer Linie aufgefasst Anzahl der Vertices muss größer als 1 und gerade sein Linienzüge: D3DPT_LINESTRIP Können ebenfalls im Vertexbuffer modelliert werden Punkte, Linien, Linienzüge eher selten, wichtiger sind Dreiecke -> flexibelste Form dazu Dreiecksliste D3DPT_TRIANGLELIST Je drei aufeinanderfolgende Vertices bilden Dreieck Dreiecke haben Vorder- und Rückseite -> nur Vorderseite wird gerendert Vorderseite: Windungsrichtung der im Vertexbuffer aufeinanderfolgenden Eckpunkte verläuft im Uhrzeigersinn Ausblenden der Rückseite: Backface - Culling

16 Culling stellt man mit Funktion SetRenderState um device->SetRenderState ( D3DRS_CULLMODE, D3DCULLL_CCW); -Im obigen Beispiel wird Culling so eingestellt, dass Rückseiten, deren Windungsrichtung gegen Uhrzeigersinn (CCW) verläuft, nicht dargestellt werden -Anzahl zur Beschreibung geometrischer Strukturen verwendete Vertices verringern: -Dreiecksstreifen (D3DPT_TRIANGLESTRIP) -Erste drei Vertices bilden Dreick, jeder weitere Vertex bildet mit seinen zwei Vorgängern das nächste Dreieck -Wenn Backface-Culling aktiviert: erstes Dreieck im eingestellten Cullingmode gerendert, bei jedem weiteren Dreieck wird Wichtungsrichtung umgekehrt -Dreiecksfächer (D3DPT_TRIANGLEFAN): drei erste Vertices ein Dreieck, jeder weitere Vertex mit Vorgänger und erstem Vertex -Culling für alle Dreiecke gleich

17 7.3.2 Rendern von Primitiven Vertex-Format festlegen -> Vertexbuffer allokieren -> Vertexbuffer mit Primitiven füllen -> rendern Vertexbuffer als Eingabequelle der Render-Pipeline unseres Devices festlegen: mit Funktion SetStreamSource HRESULT SetStreamSource (UINT StreamNumber, IDirect3DVertexBuffer9 *pStreamData, UINT OffsetInBytes, UINT Stride) -Nummer des Streams, Vertexbuffer als Quelle, Offset zum Startpunkt im Vertexbuffer, Größe des Datensatzes für einen Vertex in Bytes -StreamNumber ist logische Nummer -> mehrere Vertexbuffer als Streamsource festlegen, sofern man jedes Mal eine andere Nummer wählt -Beispiel: device->SetStreamSource (0, vertexbuffer, 0, sizeof(meinvertex));

18 -Device mitteilen, welches Vertexformat man im Vertexbuffer verwendet: HRESULT SetFVF (DWORD FVF) -> flexibles Vertex – Format -Als Parameter definiertes Vertexformat übergeben -Beispiel: device-> SetFVF(MEINVERTEXFORMAT); -Funktion DrawPrimitive rendert Vertexbuffer HRESULT DrawPrimitive (D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) -Art der Primitive, Startindex im Vertexbuffer, Anzahl der zu rendernden Primitiven -idR kompletten Vertexbuffer rendern und Startindex auf 0 setzen, aber auch andere Startpunkte sind möglich -Beispiel: Ab dem 10ten Vertex im Buffer 100 Dreiecke rendern: device->DrawPrimitive (D3DPT_TRIANGLELIST, 10, 100);

19 7.3.3 Beispiele mit Dreiecken und Linien 1.Schritt: Festlegen des Vertexformats -Für jeden Vertex Position und Farbwert im Vertexbuffer speichern # define MEINVERTEXFORMAT (D3DFVF_XYZ I D3DFVF_DIFFUSE) struct meinvertex { D3DXVECTOR3 pos; D3DCOLOR color; }; -Liste von Dreiecken mit Umrandung erstellen -Dazu Dreiecksliste und Linienliste rendern -Voraussetzung: Device (LPDIRECT3DDEVICE9) wurde erfolgreich initialisiert -Funktionalität zum Erstellen und rendern konzipieren wir als eine in sich geschlossene Klasse (trianglelist), in die von außen nur ein Zeiger auf Device eingeht

20 class trianglelist { private: LPDIRECT3DDEVICE9 device; LPDIRECT3DVERTEXBUFFER9 dreieckbuffer; LPDIRECT3DVERTEXBUFFER9 linienbuffer; public: trianglelist(); ~trianglelist(); void create(LPDIRECT3DDEVICE9 dev); void setup(); void render(); }; -Zwei Vertexbuffer: der erste (dreieckbuffer) soll Eckpunkte der Dreiecke, der zweite (linienbuffer) Eckpunkte der Umrandung aufnehmen -Fehlende Arbeitsschritte werden in öffentlichen Methoden create, setup, render abgehandelt

21 Konstruktor und Destruktor der Klasse: trianglelist::trianglelist() { dreieckbuffer = 0; linienbuffer = 0; } trianglelist::~trianglelist() { if (dreieckbuffer) dreieckbuffer -> Release(); if (linienbuffer) linienbuffer-> Release(); } -Konstruktor initialisiert Bufferzeiger -Destruktor gibt Buffer frei

22 2. Schritt: Allokieren des Vertexbuffers -Zwei Vertexbuffer: erste soll 2 Dreiecke = 6 Vertices aufnehmen, zweite soll 6 Randlinien = 12 Vertices aufnehmen -Daraus ergibt sich erforderlicher Speicherplatz void trianglelist::create (LPDIRECT3DDEVICE9 dev) { device = dev; device -> CreateVertexBuffer (6*sizeof(meinvertex),0, MEINVERTEXFORMAT, D3DPOOL_MANAGED, &dreieckbuffer, NULL); device->CreateVertexBuffer (12*sizeof(meinvertex),0, MEINVERTEXFORMAT, D3DPOOL_MANAGED, &linienbuffer, NULL); } - System legt beide Buffer an, kein direkter Zugriff -> bei Zugriff auf Inhalt zuvor Funktion Lock aufrufen

23 3. Schritt: Befüllen des Vertexbuffers -Zunächst beide Vertexbuffer für Zugriff durch unser Programm reservieren void trianglelist::setup() { meinvertex *dv, *lv; int i; dreieckbuffer -> Lock (0, 0, (void**)&dv, 0); linienbuffer ->Lock(0,0, (void**)&lv, 0); /* Zeiger auf jeweilige Bufferinhalte werden in Variablen dv und lv übertragen */ dv[o].pos = D3DXVECTOR3 (0, 0, 0); dv[1].pos = D3DXVECTOR3 (2, 1, 0); dv[2].pos = D3DXVECTOR3 (2, 0, 0); // … bis dv[5] /* Koordinatenwerte für sechs Eckpunkte der beiden Dreiecke eintragen dv[0] bis dv[5] in Dreiecks- bzw Linienpuffer */

24 dv[0].color = D3DCOLOR_ARGB (255, 80, 80, 80); dv[1].color = D3DCOLOR_ARGB (255, 160, 160, 160); //.. Bis dv[5] /* für Eckpunkte der Dreiecke unterschiedliche Farbwerte */ lv[0].pos = dv[0].pos; // 12 Eckpunkte der 6 Randlinien lv[1].pos = dv[1].pos; lv[2].pos = dv[1].pos; lv[3].pos = dv[2].pos; lv[4].pos = dv[2].pos; lv[5].pos = dv[0].pos; lv[6].pos = dv[3].pos; lv[7].pos = dv[4].pos; lv[8].pos = dv[4].pos; lv[9].pos = dv[5].pos; lv[10].pos = dv[5].pos; lv[11].pos = dv[3].pos;

25 for (i = 0; i<12; i++) lv[i].color=D3DCOLOR_ARGB(255, 0, 0, 0); // Eckpunkte der Randlinien schwarz dreieckbuffer->Unlock(); linienbuffer->Unlock(); } // Vertexbuffer freigeben - Beide Buffer sind jetzt bereit zum rendern

26 4. Schritt: Rendern der Primitiven im Vertexbuffer -Rendern besteht aus wenigen Funktionsaufrufen -Zunächst mit Funktion SetFVF richtiges Vertexformat setzen -Danach für jeden Buffer Funktionen SetStreamSource und DrawPrimitive aufrufen void trianglelist::render() { device->SetRenderState (D3DRS_AMBIENT, 0xffffff); // Beleuchtung: Ambient Licht einschalten device->SetRenderState (D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1); // Farbwerte aus diffusen Farbkomponente des Vertex verwenden device ->SetFVF (MEINVERTEXFORMAT); device->SetStreamSource (0, dreieckbuffer, 0 sizeof(meinvertex)); device->DrawPrimitive (D3DPT_TRIANGLELIST, 0, 2); devide->SetStreamSource(0, linienbuffer, 0 sizeof(meinvertex)); device->DrawPrimitive(D3DPT_LINELIST, 0, 6); } -Aufruf der Methoden create und setup sowie regelmäßiges Rendern ergibt gewünschtes Bild

27 Unterschiedliche Farbtöne an den Ecken der Dreiecke führen zu Farbverläufen Ecken dv[2] und dv[3] haben gleiche Position, unterscheiden sich aber in Farbe -> da Vertices zu unterschiedlichen Dreiecken gehören, hätten wir auf keines von beiden verzichten können -Wenn alle Dreiecke in der gleichen Farbe und ohne Farbverläufe dargestellt werden sollen, wäre Farbinfo für jeden Vertex Speicherplatzvergeudung -Stattdessen Material in gewünschter Farbe anlegen: D3DMATERIAL9 material; ZeroMemory (&material, sizeof (material)); Material.Ambient = D3DXCOLOR (255, 255, 0, 0); -Material in render-Funktion auswählen und durch SetRenderState festlegen, dass Material verwendet werden soll: device->SetMaterial (&material); device->SetRenderState (D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);

28 7.3.4 Beispiel mit Punktlisten (Partikelsysteme) -Dreiecke oder Linien als am häufigsten genutzte Primitive -Punktlisten zur Realisation von Partikelsystemen = 3- dimensionale Punktwolken um etwa Rauch oder Schnee zu implementieren -verwenden gleiches Vertexformat wie zuvor define MEINVERTEXFORMAT (D3DFVF_XYZ I D3DFVF_DIFFUSE) struct meinvertex { D3DXVECTOR3 pos; D3DCOLOR color; };

29 Jeder Punkt /Partikel hat eigene Position, kann eigenständig bewegt werden, hat eigene Farbe Beispiel: Kugeloberfläche als Wolke aus einzelnen Punkten zusammensetzen -> größer werden lassen - > zerstäuben class partikelsystem { private: LPDIRECT3DDEVICE9 device; LPDIRECT3DVERTEXBUFFER9 partikelbuffer; int anzahl; float radius; public: partikelsystem (); ~partikelsystem(); void create( LPDIRECT3DDEVICE9 dev, int anz); void setup(); void blowup(); void render (); void lookatme (…} };

30 Create – Methode: void partikelsystem::create(LPDIRECT3DDEVICE9 dev, int anz) { device = dev; anzahl = anz; device ->CreateVertexBuffer (anzahl*sizeof(meinvertex), 0, MEINVERTEXFORMAT, D3DPOOL_MANAGED, &partikelbuffer, NULL); } -Anwender kann wählen, wie viele Partikel er haben will ->entsprechend wird Vertexbuffer bereit gestellt

31 Setup – Funktion: Anfangspositionen einzelner Partikel in Buffer eingetragen void partikelsystem::setup() { int i; meinvertex *pv; srand (123); radius = 0.1f; partikelbuffer->Lock (0, 0, (void**)&pv, 0); for (i=0;i < anzahl; i++) { pv[i].pos.x = ((float)rand())/RAND_MAX – 0.5f; // für jedes Partikel durch Zufalls- pv[i].pos.y = ((float)rand())/RAND_MAX – 0.5f; // Zufallskoordinaten ein // Punkt in Würfel pv[i].pos.z = ((float)rand())/RAND_MAX – 0.5f; // um den Ursprung bestimmt D3DXVec3Normalize (&pv[i].pos, &pv[i].pos); // Normalisierung des Punktes pv[i].color = D3DCOLOR_ARGB (255, (int) (128*(pv[i].pos.x +1)), (int) (128*(pv[i].pos.y +1)), (int) (128*(pv[i].pos.z +1))); // Auswahl eines Farbwertes für Partikel pv[i].pos = radius * pv[i].pos; // Sphäre auf Anfangsgröße verkleinern } partikelbuffer -> Unlock(); }

32 Funktion blowup: Aufblasen der Sphäre, bei jedem Aufruf um 10% bis Maximalwert des Radius 10 Radius 10 erreicht -> Funktion setup setzt Sphäre in Ausgangszustand void partikelsystem::blowup() { int i; meinvertex *pv; radius *= 1.1f; if (radius <10) { partikelbuffer ->Lock (0, 0, (void**)&pv, 0); for (i = 0; i < anzahl; i++) pv[i].pos = 1.1f * pv[i].pos; partikelbuffer->Unlock(); } else setup (); }

33 Render – Funktion nimmt Beleuchtungseinstellungen vor und bringt Vertexbuffer zur Darstellung void partikelsystem::render () { device->SetRenderState (D3DRS_AMBIENT, 0xffffff); device->SetRenderState (D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1); device->SetFVF (MEINVERTEXFORMAT); device ->SetStreamSource (0, partikelbuffer, 0, sizeof (meinvertex)); device -> DrawPrimitive (D3DPT_POINTLIST, 0, anzahl); } -Effekt des Zerbröselns: die dem Auge näher liegenden Partikel größer und weiter entfernt liegende Partikel kleiner -> Pointscaling D3DRS_POINTSCALEENABLE aktivieren

34 Skalierung für Partikel einschalten und Konstanten A, B und C setzen: inline DWORD FtoDW (FLOAT f) { return *((DWORD*) &f);} void partikelsystem::render () { device ->SetRenderState (D3DRS_POINTSCALEENABLE, TRUE); device ->SetRenderState (D3DRS_POINTSIZE, FtoDW(0.1f)); device->SetRenderState (D3DRS_POINTSCALE_A, FtoDW (0.0f)); device->SetRenderState (D3DRS_POINTSCALE_B, FtoDW (0.0f)); device ->SetRenderState (D3DRS_POINTSCALE_C, FtoDW (1.00f)); device ->SetRenderState (D3DRS_AMBIENT, 0xffffff); device ->SetRenderState (D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1); device ->SetFVF (MEINVERTEXFORMAT); device ->SetStreamSource (0, partikelbuffer, 0, sizeof (meinvertex)); device -> DrawPrimitive (D3DPT_POINTLIST, 0, anzahl); } -Beim Setzen der Konstanten - Hilfsfunktion FtoDW: Funktion SetRenderState akzeptiert nur DWORD, aber eine Gleitkommazahl übergeben -> kopiert float in Speicherbereich, der für DWORD vorgesehen ist


Herunterladen ppt "Elemente der 3D- Grafikprogrammierung. Render - Pipeline Aufgabe eines Grafikpakets wie DirectX: mit Grafikkarte eingehende Grafikdaten, Primitive, in."

Ähnliche Präsentationen


Google-Anzeigen