Tutorial 4 – Geometry Instancing (Teil 1)

Geometry Instancing ermöglicht eine effiziente Darstellung einer großen Anzahl von 3D-Objekten. Die einzelnen Objekte können hierbei zwar unterschiedlich skaliert und texturiert werden, ihre Mesh-Daten (Vertex und Index Buffer) dürfen sich jedoch nicht unterscheiden.
Im Rahmen dieses Tutorials kommt ein spezielles Modellformat zum Einsatz, welches speziell für den Einsatz beim Geometry Instancing konzipiert wurde.




Schritt 1 – 3D-Modell laden und Modell-Instanz anlegen

InstancedTestModel = new CInstancedModel;
InstancedTestModel->Init_Model("../Models/Rocks", 5, true);

// Jede Modell-Instanz repräsentiert ein 3D-Objekt in der Spielewelt.
// Bevor ein 3D-Objekt gerendert werden kann, muss man der Modell-Instanz
// ein 3D-Modell zuordnen.
InstancedTestModelInstance = new CModelInstance;
InstancedTestModelInstance->Init_ModelInstance(InstancedTestModel);


Schritt 2 – Instanz-Manager anlegen

// Der Instanz-Manager wird zum Update der Transformationsmatrizen aller
// darzustellenden Instanzen benötigt.
// Gespeichert werden die Matrizen in einem vom
Instanz-Manager verwalteten
// Uniform-Buffer-Objekt.
MeshInstanceManager = new CMeshInstanceManager;
MeshInstanceManager->Set_NumInstancesMax(InstancedNormalMappingShader, 256);



Schritt 3 – Shader an den Instanz-Manager binden

// Shader-Zugriff auf die im Uniform-Buffer-Objekt gespeicherten Daten
// gewährleisten
MeshInstanceManager->Bind_InstanceTransformUniformBuffer(0);
MeshInstanceManager->Bind_InstanceTransformUniformBlock(
                     InstancedNormalMappingShader);


Schritt 4 – Instanzen Positionieren und ausrichten; Uniform-Buffer-Objekt updaten

MeshInstanceManager->Reset_All_Instances();

InstancedTestModel_WorldSpacePosition[0] = D3DXVECTOR3(0.0f, -1.5f, 6.0f);

[...]

InstancedTestModel_WorldSpacePosition[7] = D3DXVECTOR3(0.0f, -1.5f, 6.0f);

// Instanz Nr. 6 um die eigene Achse rotieren lassen
D3DXMATRIXA16 FrameRotationMatrix;
D3DXMatrixRotationY(&FrameRotationMatrix, -0.25f*g_FrameTime);
RotationMatrix *= FrameRotationMatrix;

InstancedTestModelInstance->Set_New_ModelPart_AnimatedOrientation(
                            &RotationMatrix, 6);

// Orientierung aller Instanzen festlegen (relativ zum Ursprung des
// Modellkoordinatensystems)
// Hinweis: In der Modell-Datei InstancedModel.txt finden sich die
// Modellkoordinaten-Positionen
aller Instanzen.
D3DXMATRIXA16 OrientationMatrix;
D3DXMatrixRotationZ(&OrientationMatrix, 0.2f);

InstancedTestModelInstance->Set_New_ModelOrientationMatrix(
                            &OrientationMatrix);

InstancedTestModelInstance->Set_New_ModelOrientation();


// Uniform-Buffer-Objekt updaten:

long InstanceListID = 0;

InstancedTestModelInstance->Update_InstanceCameraWorldMatrices(
                            InstanceListID, MeshInstanceManager,
                            InstancedTestModel_WorldSpacePosition, true);

MeshInstanceManager->Update_InstanceTransformUniformBuffer();


Schritt 4: Rendern aller Instanzen

long InstanceListID = 0;

InstancedNormalMappingShader->Use_Shader();

Render_InstancedModel(InstanceListID, InstancedTestModel,
                      InstancedNormalMappingShader, g_LODStep,
                      MeshInstanceManager->UsedInstances, 0.24f);

InstancedNormalMappingShader->Stop_Using_Shader();



Hinweise zum Erstellen eines neuen Projekts:

  • Kopieren Sie den Ordner GraphicsAndPhysicsFrameworkImports ins Projektverzeichnis
  • Kopieren sie alle dll-Dateien sowie die Konfigurationsdatei ResolutionAndRendering.txt aus besagtem Ordner ins gleiche Verzeichnis, in dem sich auch die exe-Datei befindet (in unseren Programmbeispielen ist dies das Bin-Verzeichnis)
  • Binden Sie die folgenden Dateien in Ihr Projekt ein: GraphicsAndPhysics_Framework_Imports.h, GraphicsAndPhysics_Framework_Imports.lib, glew32.lib, glew32s.lib, glut32.lib. Die Glew- und Glut-Bibliotheken ermöglichen die Nutzung der aktuellen OpenGL-Spezifikationen unabhängig vom Framework.