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