OpenGL Tutorial (Version 3.3) – Gemometry Instancing, Handhabung der Objekt-Instanzen (Download)

Im heutigen OpenGL-Tutorial dreht sich wieder einmal alles um das Thema Geometry Instancing. 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.



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


Rendering:

pMeshInstanceManager->Reset_All_Instances();

for(j = 0, i = 0; i < pMemoryManager->NumObjectsMax; i++)
{
    j = pMemoryManager->ReadingOrder[i];

    if(j != pMemoryManager->NoMore_Object)
    {
    // Gehört das Objekt zur Gruppe der zu rendernden Instanzen?
    if(InstanceGroupID != pTextureAndMeshDesc->
                          InstancedModelPart[pMemoryManager->
                          ObjectInstance[j].InstanceDescID].
                          InstanceGroupID)
        continue;

    // Sichtbarkeitstest durchführen:
    pMemoryManager->ObjectInstance[j].Check_Visibility(pCameraPosition,
                                     pCameraViewDirection, g_ViewDistance);

    if(pMemoryManager->ObjectInstance[j].visible == false)
        continue;

    textureSetID = pTextureAndMeshDesc->InstancedModelPart[pMemoryManager->
                   ObjectInstance[j].InstanceDescID].IDOfUsedTextureSet;

    pMeshInstanceManager->Set_CameraWorldMatrix(pCameraPosition,
                     &pMemoryManager->ObjectInstance[j].Orientation,
                     &pMemoryManager->ObjectInstance[j].WorldSpacePosition,
                      pMemoryManager->ObjectInstance[j].ScaleFactor,
                      textureSetID);

    NumInstances++;

    if(NumInstances == NumInstancesMaxPerDrawCall)
    {
    pMeshInstanceManager->Update_InstanceTransformUniformBuffer();

    InstancedModelPart->pMeshVB_IB->Render_Mesh(pShader, LODStep,
                        pMeshInstanceManager->UsedInstances);

    NumInstances = 0;
    pMeshInstanceManager->Reset_All_Instances();
    }
    }
    else if(j ==  pMemoryManager->NoMore_Object)
        break;
}

if(NumInstances > 0)
{
    pMeshInstanceManager->Update_InstanceTransformUniformBuffer();

    InstancedModelPart->pMeshVB_IB->Render_Mesh(pShader, LODStep,
                                    pMeshInstanceManager->UsedInstances);
}



Hinweis:
Für die Ausführung dieses Programmbeispiels muss der Treiber Ihrer Grafikkarte die OpenGL Version 3.3 unterstützen.

Visual C++ 2010: DemoWithOpenGL2010_Tut46