Sfoglia il codice sorgente

make DX12 Graphics API more abstract to be able to render custom objects easier in a subclass

Kolja Strohm 2 settimane fa
parent
commit
10bdb9acdf
6 ha cambiato i file con 66 aggiunte e 42 eliminazioni
  1. 4 0
      DX12BLASModel.cpp
  2. 46 41
      DX12GraphicsApi.cpp
  3. 7 1
      DX12GraphicsApi.h
  4. 2 0
      Model3D.cpp
  5. 5 0
      World3D.cpp
  6. 2 0
      World3D.h

+ 4 - 0
DX12BLASModel.cpp

@@ -79,6 +79,10 @@ void Framework::DX12BLASModel::calculateBuffers()
         for (int b = 0; b < 3; b++)
         { // for each bone of the model that is touched by the triangle
             int bone = vertexBuffer[indexBuffer[i + b]].knochenId;
+            if (maxBoneId < bone)
+            {
+                bone = maxBoneId;
+            }
             if (b1 != bone && b2 != bone)
             { // check if the bone is the same as the other two bones of the
               // triangle that were already processed

+ 46 - 41
DX12GraphicsApi.cpp

@@ -28,8 +28,6 @@
 #include "Window.h"
 #include "World3D.h"
 
-#define DEFAULT_MAX_TRANSPARENT_HITS 5
-
 using namespace Framework;
 
 class DX12RenderingData : public Framework::ReferenceCounter
@@ -215,8 +213,6 @@ void Framework::DirectX12::renderKamera(
     }
     directCommandQueue->zCommandList()->RSSetViewports(
         1, (D3D12_VIEWPORT*)zKamera->zViewPort());
-    Mat4<float> identity = Mat4<float>::identity();
-
     World3D* w = zKamera->zWorld();
     if (w->getId() < 0)
     {
@@ -251,15 +247,52 @@ void Framework::DirectX12::renderKamera(
     DX12ShaderBindingTable* sbt = worldShaderBindingTables[w->getId()];
     tlas->startUpdate();
     sbt->startUpdate();
-    int objectIndex = 0;
-    int instanceIndex = 0;
     // descriptor heaps must be set before filling the shader binding table with
     // hit groups
     sbt->setGlobalDescriptorHeap(globalDescriptorHeap);
     sbt->setTextureDescriptorHeap(textureDescriptorHeap);
     sbt->setSamplerDescriptorHeap(samplerDescriptorHeap);
-    w->render([this, &tlas, &objectIndex, &instanceIndex, &identity, &sbt](
-                  Model3D* obj) {
+    int objectIndex = 0;
+    renderWorld(w, tlas, sbt, objectIndex);
+    tlas->endUpdate();
+    settings.inverseProjection = zKamera->getInverseProjectionMatrix();
+    settings.inverseView = zKamera->getInverseViewMatrix();
+    settings.minDistance = zKamera->getMinDistance();
+    settings.maxDistance = zKamera->getMaxDistance();
+    settings.useRays = 1;
+    settings.renderGui = (int)guiVisible;
+    rayGenSettingsBuffer->setData(&settings, 1);
+    rayGenSettingsBuffer->copyToGPU(sizeof(settings));
+    if (defaultRayGenerationShaderFunction)
+    {
+        globalDescriptorHeap->updateTextureInput(
+            0, DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, zTarget);
+        globalDescriptorHeap->updateTLASInput(
+            3, DX12_SHADER_REGISTER_T_SHADER_RESOURCE, tlas);
+    }
+    sbt->endUpdate(device, directCommandQueue);
+    ID3D12DescriptorHeap* heaps[] = {globalDescriptorHeap->zDescriptorHeap(),
+        samplerDescriptorHeap->zDescriptorHeap()};
+    directCommandQueue->zCommandList()->SetDescriptorHeaps(2, heaps);
+
+    D3D12_DISPATCH_RAYS_DESC desc;
+    sbt->fillDispatchRaysDesc(&desc);
+    desc.Width = zTarget->zImage()->getWidth();
+    desc.Height = zTarget->zImage()->getHeight();
+    desc.Depth = 1;
+    directCommandQueue->zCommandList()->SetPipelineState1(
+        pipeline->zPipelineState());
+    directCommandQueue->zCommandList()->DispatchRays(&desc);
+}
+
+void Framework::DirectX12::renderWorld(World3D* zWorld,
+    DX12TLAS* zTLAS,
+    DX12ShaderBindingTable* zSBT,
+    int& objectIndex)
+{
+    Mat4<float> identity = Mat4<float>::identity();
+    zWorld->render([this, &zTLAS, &objectIndex, &identity, &zSBT](
+                       Model3D* obj) {
         DX12RenderingData* renderingData
             = dynamic_cast<DX12RenderingData*>(obj->zRenderingData());
         if (!renderingData)
@@ -295,12 +328,13 @@ void Framework::DirectX12::renderKamera(
             renderingData->lastBlasCount = blasModel->getBufferCount();
         }
         ArrayIterator<int> boneIds = blasModel->zBoneIds()->begin();
-        instanceIndex = 0;
+        int instanceIndex = 0;
         for (const DX12BLAS* blas : *blasModel->zBLAS())
         {
             if (changed)
             {
-                D3D12_RAYTRACING_INSTANCE_DESC* desc = tlas->nextInstanceDesc();
+                D3D12_RAYTRACING_INSTANCE_DESC* desc
+                    = zTLAS->nextInstanceDesc();
                 desc->InstanceID = objectIndex;
                 desc->InstanceContributionToHitGroupIndex = objectIndex;
                 desc->Flags = D3D12_RAYTRACING_INSTANCE_FLAG_NONE;
@@ -313,10 +347,10 @@ void Framework::DirectX12::renderKamera(
             }
             else
             {
-                tlas->nextInstanceDesc();
+                zTLAS->nextInstanceDesc();
             }
             boneIds++;
-            fillShaderBindingTable(sbt,
+            fillShaderBindingTable(zSBT,
                 obj,
                 objectIndex,
                 blas,
@@ -325,35 +359,6 @@ void Framework::DirectX12::renderKamera(
             objectIndex++;
         }
     });
-    tlas->endUpdate();
-    settings.inverseProjection = zKamera->getInverseProjectionMatrix();
-    settings.inverseView = zKamera->getInverseViewMatrix();
-    settings.minDistance = zKamera->getMinDistance();
-    settings.maxDistance = zKamera->getMaxDistance();
-    settings.useRays = 1;
-    settings.renderGui = (int)guiVisible;
-    rayGenSettingsBuffer->setData(&settings, 1);
-    rayGenSettingsBuffer->copyToGPU(sizeof(settings));
-    if (defaultRayGenerationShaderFunction)
-    {
-        globalDescriptorHeap->updateTextureInput(
-            0, DX12_SHADER_REGISTER_U_UNORDERED_ACCESS, zTarget);
-        globalDescriptorHeap->updateTLASInput(
-            3, DX12_SHADER_REGISTER_T_SHADER_RESOURCE, tlas);
-    }
-    sbt->endUpdate(device, directCommandQueue);
-    ID3D12DescriptorHeap* heaps[] = {globalDescriptorHeap->zDescriptorHeap(),
-        samplerDescriptorHeap->zDescriptorHeap()};
-    directCommandQueue->zCommandList()->SetDescriptorHeaps(2, heaps);
-
-    D3D12_DISPATCH_RAYS_DESC desc;
-    sbt->fillDispatchRaysDesc(&desc);
-    desc.Width = zTarget->zImage()->getWidth();
-    desc.Height = zTarget->zImage()->getHeight();
-    desc.Depth = 1;
-    directCommandQueue->zCommandList()->SetPipelineState1(
-        pipeline->zPipelineState());
-    directCommandQueue->zCommandList()->DispatchRays(&desc);
 }
 
 void Framework::DirectX12::initializePipeline()

+ 7 - 1
DX12GraphicsApi.h

@@ -4,6 +4,7 @@
 #include "GraphicsApi.h"
 
 //! DirectX 12 Types
+#define DEFAULT_MAX_TRANSPARENT_HITS 5
 
 struct ID3D12Debug;
 struct ID3D12Device5;
@@ -46,6 +47,7 @@ namespace Framework
     class Cam3D;
     class DX12BLAS;
     class DX12SamplerState;
+    class World3D;
 
     struct RayGenerationSettings
     {
@@ -62,7 +64,6 @@ namespace Framework
     private:
         ID3D12Debug* debug;
         ID3D12InfoQueue* infoQueue;
-        DX12DirectCommandQueue* directCommandQueue;
         IDXGISwapChain4* swapChain;
         ID3D12Resource* backBuffer[2];
         int backBufferIndex;
@@ -87,6 +88,7 @@ namespace Framework
         DX12Buffer* rayGenSettingsBuffer;
         RayGenerationSettings settings;
         ID3D12Device5* device;
+        DX12DirectCommandQueue* directCommandQueue;
         PFN_D3D12_SERIALIZE_ROOT_SIGNATURE pfnD3D12SerializeRootSignature;
         DX12Pipeline* pipeline;
         DX12GlobalDescriptorHeap* globalDescriptorHeap;
@@ -108,6 +110,10 @@ namespace Framework
         DLLEXPORT void updateBottomLevelAccelerationStructure();
         DLLEXPORT void renderKamera(
             Cam3D* zKamera, DX12Texture* zTarget, bool guiVisible);
+        DLLEXPORT virtual void renderWorld(World3D* zWorld,
+            DX12TLAS* zTLAS,
+            DX12ShaderBindingTable* zSBT,
+            int& objectIndex);
         DLLEXPORT virtual void initializePipeline();
         DLLEXPORT virtual void initializeGlobalDescriptorHeap();
         DLLEXPORT virtual void initializeTextureDescriptorHeap();

+ 2 - 0
Model3D.cpp

@@ -414,6 +414,8 @@ void Model3DData::setSkeletonZ(Skeleton* s)
 {
     if (skelett) skelett->release();
     skelett = s;
+    // the dx12 blas needs to be rebuilt if the skeleton changes
+    vertexBufferChanged = 1;
 }
 
 // Sets a pointer to a list with all vertices of the model

+ 5 - 0
World3D.cpp

@@ -340,3 +340,8 @@ int Framework::World3D::getId() const
 {
     return id;
 }
+
+const RCArray<Model3DCollection>& Framework::World3D::getCollections() const
+{
+    return modelCollections;
+}

+ 2 - 0
World3D.h

@@ -103,5 +103,7 @@ namespace Framework
         DLLEXPORT void setId(int id);
         //! Returns the id of the world
         DLLEXPORT int getId() const;
+        //! Returns a reference to the collections of models in the world
+        DLLEXPORT const RCArray<Model3DCollection>& getCollections() const;
     };
 } // namespace Framework