1 / 32

3D-Grafik mit der TriBase-Engine

3D-Grafik mit der TriBase-Engine. Universität zu Köln Softwaretechnologie II WS 11/12 Dozent: Prof. Dr. M. Thaller Referentin: Nadya Steinert. Automatische Initialisierung von Direct3D Statusänderungen minimieren Texturverwaltung Vertex- und Indexbuffer einfacher erstellen

damia
Download Presentation

3D-Grafik mit der TriBase-Engine

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 3D-Grafik mit der TriBase-Engine Universität zu Köln Softwaretechnologie II WS 11/12 Dozent: Prof. Dr. M. Thaller Referentin: Nadya Steinert

  2. Automatische Initialisierung von Direct3D • Statusänderungen minimieren • Texturverwaltung • Vertex- und Indexbuffer einfacher erstellen • D3DX-Effekte leichter verwalten

  3. Die Klasse tbDirect3D • Dies ist eine Singleton-Klasse, von der nur eine Instanz erzeugt werden kann • Sie verkörpert die vorher benannten Funktionen • Die Funktion tbConfigDialog sammelt Informationen über die Direct3D-Einstellungen: Adapter, Videomodi, Oberflächenformate usw. Die Methode tbDirect3D:: Init initialisiert Direct3D und erstellt das Fenster; ihr werden die tbConfig-Struktur und Fenstertitel und -icon übergeben Die Exit- Methode setzt alle Texturen zurück und löscht alle Direct3D-Schnittstellen

  4. Klassendeklaration- Variablen • m_bInitialized (BOOL) – am Anfang und nach Herunterfahren FALSE; • Variable verhindert mehrfaches Aufrufen der Init-Funktion • Zwei Zeigerfür dieSchnittstellen IDirect3D9 und IDirect3DDevice9 • Die D3DCAPS9-Struktur des verwendeten Gerätes speichern • Eine HWND-Variable für das Fenster • m_bOwnWindow (BOOL) falls der Benutzer eigenes Fenster verwendet • Für Kapselung der Methoden SetRenderState, GetRenderState, SetTextureStageState usw. braucht man Tabellen; DWOR- und float-Version • Ein Array vom Typ PDIRECT3DBASETEXTURE9 mit 8 Elementen speichert die eingesetzten Texturen • m_vScreenSize (tbVector2) speichert die Größe des Bildpuffers in Pixeln

  5. Klassendeklaration- Methoden • Init-Methode erwartet zuerst einen Zeiger auf tbConfig , erstellt ein Fenster und initialisiert die IDirect3DDevice9-Schnittstelle; dann ein Fenstername, ein HWND-Parameter für Benutzerfenster, ein HICON-Parameter • Kapselungsmethoden für die verschiedenen States die mit den DWORD – und float- Tabellen arbeiten • Verschiedene Hilfsmethoden: IsInitialized, GetWindow, GetDirect3D usw. • Capture-Methode fragt den aktuellen Status der Geräteschnittstelle ab

  6. Die Funktion tbDuConfigDialog • sie ruft den Konfigurationsdialog auf • Füllt die tbConfig-Struktur aus, die die gesamte Konfiguration von TriBase-Engine beinhaltet

  7. Die Init-Methode • Erzeugt das Anwendungsfenster • Eine IDirect3D9-Schnittstelle • Ruft CreateDevice auf, um eine IDirect3DDevice9-Schnittstelle zu erhalten • Fragt die Gerätefähigkeiten( D3DCAPS9) ab • Speichert den aktuellen Status der Tabellen durch die Capture-Methode • Setzt Standard-Render und Sampler-States • Setzt m_bInitialized auf true

  8. Speichern des aktuellen Status mit Capture() • Diese Methode geht alle Render-States, Sampler-States usw. durch, deren Werte in Tabellen gespeichert sind, fragt sie ab und speichert sie • Doppelte Statusänderungen werden verhindert indem die Set-Methoden prüfen, ob der Status schon gesetzt ist und wenn dass der Fall ist, wird sofort unterbrochen • // Wenn das Render-State schon gesetzt ist, direkt abbrechen • if(m_RS.adwRS[RS] == dwValue) return TB_OK;

  9. Die Exit-Methode setzt alle Texturen, Index- und Vertex-Buffer zurück, gibt die zwei Schnittstellen frei(D3D und D3DDevice) • Methoden wie SetTextue() erhöhen den Zähler der ihr übergebenen Schnittstelle und müssen unbedingt zurückgesetzt werden, damit keine Speicherlecks entstehn • Um auf die IDirect3DDevice9 zugreifen zu können, wird der ‚->‘-Operator überladen • PDIRECT3DDEVICE9 operetor ->{return m_pD3DDevice;} • D3D->DrawPrimitive() //direkt Methoden von IDirect3DDevice9 aufrufen

  10. tbTextureManager • Sorgt dafür , dass keine Textur zwei Mal geladen wird • Alle geladenen Texturen werden in einer Liste mit deren Dateinamen festgehalten • Wenn eine bereits geladene Textur wieder gefragt ist, wird der Referenzzähler der Texturschnittstelle erhöht • Wenn der Referenzzähler null erreicht , wird die Textur aus der Liste gelöscht • Texturen können aus verschiedenen Quellen geladen werden: aus Speicher, einer Ressource oder aus ZIP_Archiv

  11. Klassendefinition von tbTextureManager • Es gibt eine Liste, wo alle Texturen eingetragen werden • jeder Textureintrag wird in die Struktur tbTextureListEntry gespeichert • struct TRIBASE_API tbTextureListEntry • { • BOOLbExists;// Existiert diese Textur? • PDIRECT3DBASETEXTURE9pTexture;// Die Texturschnittstelle • characSourceFilename[256];// Quelldateiname • intiWidth;// Breite der Textur • intiDepth;// Tiefe der Textur • intiHeight;// Höhe der Textur • intiNumMIPLevels;// Anzahl der MIP-Mapping-Ebenen • D3DFORMATFormat;// Oberflächenformat der Textur • DWORDdwUsage;// Verwendungszweck • D3DPOOLPool;// Speicherklasse • DWORDdwFilter;// Bildfilter (beim Laden) • DWORDdwMIPFilter;// MIP-Map-Filter (beim Laden) • D3DCOLORColorKey;// Color-Key (beim Laden) • };

  12. Klassendefinition -Variablen • Für die Texturen wird eine nicht verkette Liste benutzt; der Zeiger m_pTextureList zeigt auf eine tbTextureListEntry-Struktur; Speicher wird dynamischreserviert • m_iListSize speichert die aktuelle Größe der Texturliste • m_iNumTexture- Anzahl der geladene Texturen

  13. Klassendefinition- Methoden • Init-Methode erwartet als Parameter die Ausgangsgröße der Texturliste und reserviert genug Speisher • SetListSize verändert die Listengröße, wenn z.B. kein Platz für eine neue Textur da ist • GetTextureIndex erwartet als Perameter eine Texturschnitstelle, sucht sie in der Liste und liefert den Texturindex zurück • GetNewIndex liefert den nächsten freien Index in der Liste zurück, wenn kein Platz -1; es wird nach dem ersten Listeneintrag gesucht bei dem m_bExist FALSE ist • ReleaseTexture erwartet auch eine Texturschnittstelle, sucht die Textur und ruft Release auf; wenn Referenzzähler null, Textur wird gelöscht • DeleteAllTexture geht die gesamte Liste durch und ruft für jede Textur so lange Release auf bis Referenzzähler null

  14. Klassendefinition -Methoden • AddTextureToList fügt eine Textur zur Liste hinzu, und erweitert diese, wenn kein Platz mehr da ist • Load-Methoden für Standard-, Würfel- und Volumentexturen; Für jeden Typ vier verschiedene Versionen, die erwarten Dateiname, Speicheradresse,Ressourcenangabe, oder virtuelle Datei; Die ersten drei Methoden erzeugen eine virtuelle Datei aus der Quelle und rufen die Vierte Version auf; sie haben den gleichen Namen und verschiedene Parameter(immer zuerst die Quellangabe) • Get-Methoden bekommen die Parameter einer Textur und durchsuchen die Liste nach einer Übereinstimmung, passende Textur wird zurückgeliefert(Referenzzähler wird erhöht); wenn Textur nicht vorhanden, wird die entsprächende Load-Methode aufgerufen

  15. tbVertexBuffer und tbIndexBuffer • Informationen zum Art des Puffers • Verwendungszweck: 0 ist Standard; D3DUSAGE_DYNAMIC(dynamischer Puffer);D3DUSAGE_WRITEONLY(kein Lesezugriff; • Speicherklasse: die vier Flags D3DPOOL_DEFAULT,D3DPOOL_MANAGED,D3DPOOL_SYSTEMMEM und D3DPOOL_SCRATCHstehen zur Auswahl • Sperrmethode: 0, D3DLOCK_NOSYSLOCK, D3DLOCK_DISCARD, D3DLOCK_NOOVERWRITE und D3DLOCK_READONLY

  16. Funktionsweise von den Buffern • Beim Initialisieren der Klasse gibt der Benutzer den Verwendungszweck und die Speicherklasse an • Die Größe des Index- und Vertex-Buffer kann eventuell angepasst werden • Beide Klassen fertigen sich intern eine Kopie des gesamten Puffers an; mit SetVertex und SetIndex kann der Benutzer sie verändern, wenn die Veränderung durchgeführt werden soll, wird Update() aufgerufen • Der veränderte Speicherbereich wird gesperrt und die Daten aus der internen Kopie werden in den Puffer kopiert • Bei D3DUSAGE_WRITEONLY wird nur aus der Kopie im Systemspeicher gelesen und im Puffer nur geschrieben; GetVertex() fragt Vertizes von der internen Kopie ab

  17. Klassendefinition- Variablen(VertexBuffer) • m_pVertexBuffer vom Typ PDIRECT3SVERTEXBUFFER9 • m_pBuffer der auf die interne Kopie zeigt, vom Typ void • DWORD m_dwSize speichert die Größe des Puffers in Bytes • DWORD m_dwVertexSize- die Größe eines einzelnen Vertex • DWORD m_dwMaxVertices – Anzahl der Vertizes im Puffer • DWORD dwFVF : der Vertexformat, beim Indexbuffer m_IndexFormat (D3DFMT_INDEX16 oder D3DFMT_INDEX32) • DWORD m_dwUsage : Verwendungszweck des Puffers, D3DUSAGE_WRIETEONLY ist immer gesetzt • D3DPOOL m_Pool: die Speicherklasse, in der sich der Vertex-Buffer befindet

  18. Klassendefinition- Variablen(VertexBuffer) • DWORD dwFirstVertex, dwLastVertex speichern die Nummern des ersten und des letzten veränderten Vertex; SetVertex() setzt die Variablen, um später den zu sperrenden Bereich zu ermitteln; nach dem Sperren hat dwFirstVertex den höchst möglichen Wert und dwLastVertex 0 • DWORD m_dwCursor speichert die Nummer des nächsten Vertex, der mit AddVertex() gesetzt wird

  19. Klassendeklaration- Methoden • Init() generiert die IDirect3DVertexBuffer9-Schnittstelle und die interne Kopie; die erste Version der Methode erwartet die Größe des Vertex-Buffers, die Vertexgröße, den FVF-Bezeichner, Vervwendungszweck und Speicherklasse • Die zweite Version erwartet einen bereits existierenden Vertex-Buffer(PDirect3DVertexBuffer9) und die Größe eines Vertex; aus diesem wird die tbVertexBuffer- Instanz initialisiert; GetDesc() fragt die Beschreibung des Vertex-Buffers ab; erste Funktion baut auf die zweite auf • Exit() gibt die Schnittstelle und die interne Speicherkopie frei; wird einmal vom Destruktor und einmal am Anfang von Init() aufgerufen • SetVertex() erwartet die Nummer des zu setzenden Vertex(0 ist der erste) und den Vertex selbst; der angegebene Vertex wird in die Speicherkopie geschrieben und m_dwFirstVertex und m_dwLastVertex werden aktualisiert

  20. Klassendeklaration- Methoden • SetVertices() setzt mehrere Vertizes; erster Parameter: Index des ersten zu setzenden Vertex; dann Anzahl der Vertizes und schließlich Zeiger auf die Vertizes • AddVertex() fügte dem Vertex-Buffer einen neuen Vertex hinzu und liefert seinen Index zurück; die Nummer des nächsten Vertex ist im m_dwCursor • AddVertices() fügt gleich mehrere Vertizes hinzu, die im zweiten Parameter angegeben sind; Erster Parameter- die Anzahl • SetCursor() setzt den Vertexcursor auf den durch den Parameter angegebenen Wert; wenn Vertex-Buffer voll Cursor wird per Hand zurückgesetzt • GetVertex() liefert den durch den Index angegebenen Vertex • GetVertices() : erste Parameter gibt den Index des ersten abzufragenden Vertex an; 2. Parameter: Anzahl der abzufragenden Vertizes; dritter: Zeiger auf den Speicher Bereich, wo es hinkopiert werden soll

  21. Klassendeklaration- Methoden • Update() schreibt die veränderte Vertizes in den Vertex-Buffer; biem dynamischen Puffer Sperflag D3DLOCK_DISCARD; m_dwFirstVertex und m_dwLastVertex werden zurückgesetzt • Verschiedene Inline- Methoden

  22. tbEffect • Optionen zum zeichnen eines Objekts oder eins Materials werden in eine Effekt-Datei gespeichert werden • Der Benutzer kann selbst festlegen Welche Techniken benutzt werden oder überlässt das der Klasse • Ein globales Effekt-Pool ermöglicht es , das verschiedene Effekte ihre Parameter teilen; wird in Init() erstellt

  23. Klassendeklaration- Variablen • LPD3DXEFFECT m_pEffect : die Effekt-Schnittstelle • D3DXEFFECT_DESC m_Desc :die Effektbeschreibung • BOOL m_bStateSaved: TRUE , wenn beim Aufruf von Begin() angegeben wurde, dass dewr aktuelle Status gespeichert werden soll • BOOL m_bCaptureOnFinish: TRUE; WENN BEIM Beenden des Effekts automatisch Capture() aufgerufen werden soll

  24. Klassendeklaration - Methoden • 5 Init-Methoden: Initialisierung aus einem String , der den gesamten Code enthält; aus einer virtuellen Datei; einer echten Datei, einem Speicherbereich oder einer Ressource • Exit() löscht die Schnoittstellen und verringert die Referenzzähler der Texturen • SetTechnique: setzt eine Technik , die durch ihre Nummer angegeben wird; gibt man -1 an, sucht die Methode die erste gültige Technik aus • Begin() : erster BOOL-Parameter bestimmt, ob die Änderungen später rückgängig gemacht werden sollen; der zweite BOOL-Parametergibt an, ob die internen Tabellen der Render-States, Texturschicht-State usw. in der tbDirect3D-Klasse aktualisiert werden sollen • Die beide Parameter werden in m_bStateSaved bzw. in m_bCaptureOnFinish gespeichert;Rückgabewert von Begin() ist die Anzahl der benötigten Durchgänge für den Effekt • End() beendet den Effekt • Pass() aktiviert den durch seine Nummer angegebenen durchgang

  25. Ein Beispiel • Die Wasseroberfläche wird in eine Gitter eingeteilt • Die Höhe jedes Vertex wird einmal pro Frame aktualisiert und hängt von der abgelaufene Zeit und von x- un z-position ab • Wellen lassen sich durch Sinus-Funktionen simulieren • Globale Variablen und Strukturen: zwei Strukturen, eine für die Wasser-Vertizes und eine für die SkyBox-Vertizes • // Globale Variablen • tbConfigg_Config;// Konfigurationsstruktur • PDIRECT3DTEXTURE9g_pWaterTexture = NULL;// Wassertextur • PDIRECT3DCUBETEXTURE9g_pEnvMap = NULL;// Umgebungstextur • tbEffect*g_pWaterEffect = NULL;// Wassereffekt • tbEffect*g_pSkyBoxEffect = NULL;// Sky-Box-Effekt • tbVertexBuffer*g_pWaterVB = NULL;// Wasser-Vertex-Buffer • tbIndexBuffer*g_pWaterIB = NULL;// Wasser-Index-Buffer • tbVertexBuffer*g_pSkyBoxVB = NULL;// Sky-Box-Vertex-Buffer • tbIndexBuffer*g_pSkyBoxIB = NULL;// Sky-Box-Index-Buffer • const intg_iResolution = 64;// Die Auflösung der Wasseroberfläche • floatg_fTime = 0.0f;// Globaler Zeitzähler

  26. Programminitialisierung • Konfigurationsdialog wird aufgerufen und das Ergebnis wird in g_Config gespeichert • Danach wird die tbDitrect3-Klasse initialisiert • Ein Texturemanagerobjekt wird erstellt um die beiden Texturen zu laden • InitWater() und InitSkyBox() werden als nächstes aufgerufen • Gitterprinzip: es wird ein Statischer IndexBuffer erstellt, der mir den zu dritt gruppierten Indizes gefüllt wird; Die Methode GetVertexIndex(DWORD x, DWORD y) findet den Index jedes Vertex indem sie die Reihe mit der Anzahl Vertizes pro Reihe multipliziert und die Spalte dazu addiert • InitWater(): Vertex- und Index-Buffer werden erstellt; IndexBuffer wird gefüllt; Texturen und Effekte werden aufgerufen

  27. Die Animation • Einmal pro Frame geht das Programm alle Vertizes durch und generiert sie neu, abhängig von position und Zeit; drei Funktionen erwarten eine Positionsangabe und mit hilfe des Zeitzählers liefern die Vertexposition(besonders Höhe), Normalenvektor und Texturkoordinaten: PositionProc(tbVector3 v), NormalProc() und TextureProc() • UpdateWater() ruft diese Funktionen auf und füllt den VertexBuffer • Die Render-Funktion: der Z-Buffer wird ausgeschaltet

  28. Modelldateien • Sie sollen flexibel und offen für die Zukunft sein • Flexibilität durch Chunks: jeder Chunk hat ein Header(Beschreibung), gefolgt von den Daten , die Nach Chunktyp interpretiert werden; die Größe der Daten ist im Header angegeben, was erlaubt das unrelevante Chunks einfach übersprungen werden • Struktur für ChunkHeader: • struct TRIBASE_API tbModelChunkHeader • { • tbModelChunkTypeChunkType;// Typ des Chunks • DWORDdwDataSize;// Größe der Daten des Chunks • ChunkType ist vom Typ enum; alle ChunkTypen beginnen mit TB_CT_

  29. Vertexdaten-Chunk: TB_CT_MODEL_VERTICES • struct TRIBASE_API tbModelVerticesChunkHeader • { • DWORDdwFVF;// Vertexformat • DWORDdwVertexSize;// Größe eines einzelnen Vertex • DWORDdwNumVertices;// Anzahl der Vertizes • floatfBoundingSphereRadius;// Radius der umgebenden Kugel • tbVector3vBoundingBoxMin;// Minimumpunkt des umgebenden Quaders • tbVector3vBoundingBoxMax;// Maximumpunkt des umgebenden Quaders • Indexdaten-Chunk TB_CT_MODEL_INDICES • struct TRIBASE_API tbModelIndicesChunkHeader • { • D3DFORMATIndexFormat;// D3DFMT_INDEX16 oder D3DFMT_INDEX32 • DWORDdwIndexSize;// Größe eines Index • DWORDdwNumIndices;// Anzahl der Indizes

  30. Effekt-Chunk TB_CT_MODEL_EFFECTS • struct TRIBASE_API tbModelEffectHeader • { • characName[256];// Name des Effekts • BOOLbAlphaBlended;// Mit Alpha-Blending rendern? • D3DPRIMITIVETYPEPrimitiveType;// Typ der Primitiven • DWORDdwStartIndex;// Wo mit dem Rendern anfangen? • DWORDdwNumPrimitives;// Wie viele Primitiven rendern? • DWORDdwMinIndex;// Kleinster verwendeter Index • DWORDdwNumVertices;// Größter Index - Kleinster Index + 1 • DWORDdwEffectCodeSize;// Größe des Effektquellcodes • };

  31. To be continued…

More Related