Tutorial 11 – Geometry Instancing (Teil 2)

Das zweite Programmbeispiel zum Thema Geometry Instancing demonstriert einen deutlich flexibleren Einsatz dieser Technik als Tutorial 4.











Ziel ist die Darstellung einer beliebig großen Anzahl von 3D-Objekten, die sich zur Laufzeit dynamisch initialisieren bzw. zerstören lassen. Für die Handhabung dieser Objekte ist die CSimpleObjectInstanceMemoryManager-Klasse verantwortlich, für die Bereitstellung aller für die Darstellung benötigten Texturen und Mesh-Daten die CInstancedObjectTextureAndMeshDesc-Klasse.


Schritt 1: Initialisierungsarbeiten

// Texturen und Mesh-Daten laden, die im Rahmen des Geometry Instancings
// benötigt werden:
InstancedObjectTextureAndMeshDesc = new CInstancedObjectTextureAndMeshDesc;
InstancedObjectTextureAndMeshDesc->Init_Data("../Models/Rocks", 5);

// Memory Manager für die Verwaltung aller 3D-Objekt-Instanzen
// initialisieren:
SimpleObjectInstanceMemoryManager = new CSimpleObjectInstanceMemoryManager;
SimpleObjectInstanceMemoryManager->Init(1000); // 1000 Objekte maximal

[...]

// eine weitere 3D-Objekt-Instanz initialisieren:
SimpleObjectInstanceMemoryManager->New_Object(&WorldSpacePosition,
                                              &Orientation, ScaleFactor,
                                              InstanceDescID);


InstancedNormalMappingShader = new CGLSLShader;
InstancedNormalMappingShader->Init_UserDefined_Shader(
                              "Shader/InstancedNormalMapping.vert",
                              "Shader/InstancedNormalMapping.frag",
                              Format_CTexturedVertexWithNormal_NM);

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

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


Schritt 2: Rendering


long InstanceGroupID;
long NumInstancesMaxPerDrawCall = 256;


InstancedNormalMappingShader->Use_Shader();

InstanceGroupID = 0;
Render_InstancedObjects(&g_CameraPosition, &g_CameraViewDirection,
                        &g_ViewProjectionMatrix,
                        InstanceGroupID, SimpleObjectInstanceMemoryManager,
                        InstancedObjectTextureAndMeshDesc,
                        MeshInstanceManager, InstancedNormalMappingShader,
                        g_LODStep, NumInstancesMaxPerDrawCall, 0.24f);

InstanceGroupID = 1;
Render_InstancedObjects(&g_CameraPosition, &g_CameraViewDirection,
                        &g_ViewProjectionMatrix,
                        InstanceGroupID, SimpleObjectInstanceMemoryManager,
                        InstancedObjectTextureAndMeshDesc,
                        MeshInstanceManager, InstancedNormalMappingShader,
                        g_LODStep, NumInstancesMaxPerDrawCall, 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.