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);
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);
// 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);
// 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
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();
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();
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.