Parcourir la source

fix probelms when updating tlas with more instances then before

Kolja Strohm il y a 3 semaines
Parent
commit
989f791cef
5 fichiers modifiés avec 64 ajouts et 28 suppressions
  1. 1 1
      DX12GraphicsApi.cpp
  2. 2 3
      DX12TLAS.cpp
  3. 5 0
      Drawing3D.cpp
  4. 13 9
      Drawing3D.h
  5. 43 15
      Framework Tests/Camera3D.cpp

+ 1 - 1
DX12GraphicsApi.cpp

@@ -887,7 +887,7 @@ void DirectX12::presentFrame()
 
     directCommandQueue->execute();
 
-    swapChain->Present(0, 0);
+    swapChain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
 
     backBufferIndex = swapChain->GetCurrentBackBufferIndex();
 

+ 2 - 3
DX12TLAS.cpp

@@ -97,9 +97,7 @@ void Framework::DX12TLAS::endUpdate()
         descriptorBuffer->zBuffer()->Unmap(0, nullptr);
     }
     mappedDescriptorBuffer = 0;
-    lastInstanceCount = currentInstanceIndex + 1;
-    if (!descriptorBuffer
-        || currentInstanceIndex >= descriptorBuffer->getElementCount())
+    if (!descriptorBuffer || currentInstanceIndex >= lastInstanceCount)
     {
         // recalculate the size of the descriptor buffer and reallocate it
         D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS
@@ -226,6 +224,7 @@ void Framework::DX12TLAS::endUpdate()
     uavBarrier.UAV.pResource = resultBuffer->zBuffer();
     uavBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
     zDirectQueue->zCommandList()->ResourceBarrier(1, &uavBarrier);
+    lastInstanceCount = currentInstanceIndex + 1;
 }
 
 Framework::DX12Buffer* Framework::DX12TLAS::zResultBuffer() const

+ 5 - 0
Drawing3D.cpp

@@ -122,6 +122,11 @@ void Drawable3D::setSize(float size)
     rend = 1;
 }
 
+float Framework::Drawable3D::getSize() const
+{
+    return size;
+}
+
 // Calculates the matrices of all bones of the drawing's skeleton
 //  viewProj: The multiplied camera matrices
 //  matBuffer: An array of matrices to be filled

+ 13 - 9
Drawing3D.h

@@ -16,9 +16,9 @@ namespace Framework
         Vec3<float> pos;   //! Position of the object
         Vec3<float> angle; //! Rotation angles for x, y and z
         Mat4<float> welt;  //! World translation matrix
-        float radius;      //! The radius of a sphere that encloses the entire object
-        bool alpha; //! Stores whether the object contains partially or fully
-                    //! transparent areas
+        float radius; //! The radius of a sphere that encloses the entire object
+        bool alpha;   //! Stores whether the object contains partially or fully
+                      //! transparent areas
         bool rend;
         float size;
 
@@ -65,6 +65,8 @@ namespace Framework
         DLLEXPORT void setAlpha(bool a);
         //! Sets the scaling
         DLLEXPORT void setSize(float size);
+        //! Returns the scaling
+        DLLEXPORT float getSize() const;
         //! Calculates the matrices of all bones in the drawing's skeleton
         //! \param viewProj The multiplied camera matrices
         //! \param matBuffer An array of matrices to fill
@@ -81,11 +83,13 @@ namespace Framework
         //! \param tickval The time in seconds since the last call of this
         //! function \return true if the object changed, false otherwise.
         DLLEXPORT virtual bool tick(double tickval);
-        //! Returns whether the object contains partially or fully transparent areas
+        //! Returns whether the object contains partially or fully transparent
+        //! areas
         DLLEXPORT bool hasAlpha() const;
         //! Returns the radius of a sphere that encloses the entire model
         DLLEXPORT inline float getRadius() const;
-        //! Returns a point representing the position of the drawing in the world
+        //! Returns a point representing the position of the drawing in the
+        //! world
         DLLEXPORT const Vec3<float>& getPos() const;
         //! Returns the X position of the drawing in the world
         DLLEXPORT float getX() const;
@@ -93,8 +97,8 @@ namespace Framework
         DLLEXPORT float getY() const;
         //! Returns the Z position of the drawing in the world
         DLLEXPORT float getZ() const;
-        //! Returns a vector representing the rotation of the drawing in the world.
-        //! x is the rotation around the X axis in radians, etc.
+        //! Returns a vector representing the rotation of the drawing in the
+        //! world. x is the rotation around the X axis in radians, etc.
         DLLEXPORT const Vec3<float>& getRotation() const;
         //! Returns the rotation around the X axis in radians
         DLLEXPORT float getXRotation() const;
@@ -104,8 +108,8 @@ namespace Framework
         DLLEXPORT float getZRotation() const;
         //! Returns the matrix that translates the drawing into world space
         DLLEXPORT const Mat4<float>& getMatrix() const;
-        //! Calculates a point in world coordinates from a point in local drawing
-        //! coordinates by applying rotation, scaling and translation
+        //! Calculates a point in world coordinates from a point in local
+        //! drawing coordinates by applying rotation, scaling and translation
         DLLEXPORT Vec3<float> applyWorldTransformation(
             const Vec3<float>& modelPos) const;
     };

+ 43 - 15
Framework Tests/Camera3D.cpp

@@ -62,9 +62,9 @@ namespace FrameworkTests
             });
             window.setMouseAction(Framework::_ret1ME);
             window.setKeyboardAction(Framework::_ret1TE);
+            Framework::DirectX12* api = new Framework::DirectX12();
             Framework::Screen3D screen(
-                dynamic_cast<Framework::NativeWindow*>(window.getThis()),
-                new Framework::DirectX12());
+                dynamic_cast<Framework::NativeWindow*>(window.getThis()), api);
             screen.setHandleUserInputsOnTick(0);
             window.setScreen(
                 dynamic_cast<Framework::Screen*>(screen.getThis()));
@@ -77,7 +77,6 @@ namespace FrameworkTests
             cam.setViewDirection(target);
             Framework::World3D world;
 
-            Framework::Model3D cube;
             Framework::Model3DData* data
                 = screen.zGraphicsApi()->createModel("cube");
             data->setAmbientFactor(0.f);
@@ -236,30 +235,59 @@ namespace FrameworkTests
             p->indexList[5] = 2 + 20;
             data->addPolygon(p);
             data->calculateNormals();
-            cube.setModelData(data);
-            cube.setPosition(0, 100, 0);
-            cube.setSize(50);
-            cube.setRotation(0.5, 0.5, 0.5);
-            cube.tick(0.1);
-            world.addDrawable(
-                dynamic_cast<Framework::Model3D*>(cube.getThis()));
+            Framework::Array<Framework::Model3D*> cubes;
+            std::function<void(int, int, int)> addCube
+                = [&cubes, &world, &data](int x, int y, int z) {
+                      Framework::Model3D* cube = new Framework::Model3D();
+                      cube->setModelData(dynamic_cast<Framework::Model3DData*>(
+                          data->getThis()));
+                      cube->setPosition(x, y, z);
+                      cube->setSize(5 + rand() % 5);
+                      cube->setRotation(
+                          rand() % 10 / 5, rand() % 10 / 5, rand() % 10 / 5);
+                      world.addDrawable(cube);
+                      cubes.add(cube);
+                  };
+            for (int i = 0; i < 10000; i++)
+            {
+                addCube(rand() % 1000 - 500,
+                    rand() % 1000 - 500,
+                    rand() % 1000 - 500);
+            }
 
             cam.setWorld(dynamic_cast<Framework::World3D*>(world.getThis()));
             cam.addStyle(Framework::Cam3D::Style::Movable
                          | Framework::Cam3D::Style::Rotatable
                          | Framework::Cam3D::Style::Zoomable
                          | Framework::Cam3D::Style::Tick);
+            cam.setMovementSpeed(0.1f);
             screen.addKamera(dynamic_cast<Framework::Cam3D*>(cam.getThis()));
 
             Framework::RenderTh rTh;
             rTh.setMaxFps(-1);
             rTh.setQuiet(0);
+            rTh.setMaxFps(-1);
             rTh.setScreen(dynamic_cast<Framework::Screen*>(screen.getThis()));
-            rTh.setTickFunktion([&cube](void* p, void* f, double tick) {
-                cube.setRotationX(cube.getXRotation() + tick);
-                cube.setRotationY(cube.getXRotation() + tick / 10);
-                cube.setRotationZ(cube.getXRotation() + tick / 50);
-            });
+            double sum = 0;
+            rTh.setTickFunktion(
+                [&cubes, &sum, &addCube](void* p, void* f, double tick) {
+                    for (Framework::Model3D* cube : cubes)
+                    {
+                        cube->setRotationX(cube->getXRotation() + tick * 2);
+                        cube->setRotationY(cube->getXRotation() + tick / 5);
+                        cube->setRotationZ(cube->getXRotation() + tick / 25);
+                        cube->setSize(
+                            cube->getSize() + tick * 5 * (sum > 2.5 ? 1 : -1));
+                    }
+                    sum += tick;
+                    if (sum > 5)
+                    {
+                        sum -= 5;
+                        /* addCube(rand() % 1000 - 500,
+                            rand() % 1000 - 500,
+                            rand() % 1000 - 500);*/
+                    }
+                });
 
             rTh.beginn();
             Framework::StartMessageLoop();