Browse Source

make frustum checks public and support rectangle frustrum checks

Kolja Strohm 1 year ago
parent
commit
9afa0819d1
8 changed files with 115 additions and 27 deletions
  1. 29 4
      DX11GraphicsApi.cpp
  2. 5 0
      DX12GraphicsApi.cpp
  3. 6 0
      DX9GraphicsApi.cpp
  4. 13 5
      DXBuffer.cpp
  5. 5 0
      Ebene3D.h
  6. 29 18
      GraphicsApi.h
  7. 22 0
      Welt3D.cpp
  8. 6 0
      Welt3D.h

+ 29 - 4
DX11GraphicsApi.cpp

@@ -597,12 +597,12 @@ void DirectX11::beginFrame(bool fill2D, bool fill3D, int fillColor)
         color[3] = ((fillColor >> 24) & 0xFF) / 255.f; // A
         d3d11Context->ClearRenderTargetView(rtview, color);
     }
-    // Clear the depth buffer.
-    d3d11Context->ClearDepthStencilView(
-        dsView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
     // Bind the render target view and depth stencil buffer to the output render
     // pipeline.
     d3d11Context->OMSetRenderTargets(1, &rtview, dsView);
+    // Clear the depth buffer.
+    d3d11Context->ClearDepthStencilView(
+        dsView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
     // Set the depth stencil state.
     d3d11Context->OMSetDepthStencilState(depthStencilState, 1);
 }
@@ -711,6 +711,18 @@ bool DirectX11::isInFrustrum(
     return 1;
 }
 
+bool DirectX11::isInFrustrum(
+    const Vec3<float>& pos, Vec3<float> radius, float* dist) const
+{
+    for (int i = 0; i < 6; i++)
+    {
+        float r = abs(frustrum[i].normal() * radius);
+        if (frustrum[i] * pos + r < 0) return 0;
+    }
+    if (dist) *dist = kamPos.abstand(pos);
+    return 1;
+}
+
 void DirectX11::renderKamera(Kam3D* zKamera)
 {
     d3d11Context->RSSetViewports(1, (D3D11_VIEWPORT*)zKamera->zViewPort());
@@ -766,7 +778,7 @@ void DirectX11::renderKamera(Kam3D* zKamera)
     int maxDist = 0;
     int minDist = 0x7FFFFFFF;
     Array<Model3D*> alphaModels;
-    w->render([this, &minDist, &maxDist, &alphaModels](Model3D* obj) {
+    w->render([this, &minDist, &maxDist, &alphaModels, &lc](Model3D* obj) {
         float dist;
         if (isInFrustrum(obj->getPos(), obj->getRadius(), &dist))
         {
@@ -775,7 +787,10 @@ void DirectX11::renderKamera(Kam3D* zKamera)
             if (obj->hatAlpha())
                 alphaModels.add(obj);
             else
+            {
+                pixelShader->füllConstBuffer((char*)lc, 2, sizeof(int) * 2);
                 renderObject(obj);
+            }
         }
     });
     maxDist++;
@@ -1126,4 +1141,14 @@ DX11PixelShader* DirectX11::initializePixelShader(
     TexturEffect e = {0, 0.f};
     pixelShader->füllConstBuffer((char*)&e, 3, sizeof(TexturEffect));
     return pixelShader;
+}
+
+DLLEXPORT ID3D11DeviceContext* DirectX11::zContext()
+{
+    return d3d11Context;
+}
+
+DXBuffer* DirectX11::createStructuredBuffer(int eSize)
+{
+    return new DX11StructuredBuffer(eSize, d3d11Device, d3d11Context);
 }

+ 5 - 0
DX12GraphicsApi.cpp

@@ -1296,4 +1296,9 @@ DXBuffer* DirectX12::createVertexBuffer()
 {
     return new DX12VertexBuffer(
         sizeof(Vertex3D), device, copyCommandQueue, directCommandQueue);
+}
+
+DXBuffer* DirectX12::createStructuredBuffer(int eSize)
+{
+    throw "Sorry, support for structured buffers will come eventualy"; // TODO: support structured buffers
 }

+ 6 - 0
DX9GraphicsApi.cpp

@@ -265,6 +265,12 @@ DXBuffer* DirectX9::createIndexBuffer()
 }
 
 DXBuffer* DirectX9::createVertexBuffer()
+{
+    throw "Unsupported Operation for DirectX9 Graphics API. Use DirectX11 or "
+          "12";
+}
+
+DXBuffer* DirectX9::createStructuredBuffer(int eSize)
 {
     throw "Unsupported Operation for DirectX9 Graphics API. Use DirectX11 or "
           "12";

+ 13 - 5
DXBuffer.cpp

@@ -109,15 +109,23 @@ void DX11Buffer::copieren(int byteCount)
     }
     if (changed)
     {
+        HRESULT res;
         D3D11_MAPPED_SUBRESOURCE map;
         if ((description->Usage | D3D11_USAGE_DYNAMIC) == description->Usage)
-            context->Map(
+            res = context->Map(
                 buffer, 0, D3D11_MAP::D3D11_MAP_WRITE_DISCARD, 0, &map);
         else
-            context->Map(buffer, 0, D3D11_MAP::D3D11_MAP_WRITE, 0, &map);
-        memcpy(map.pData, data, byteCount);
-        context->Unmap(buffer, 0);
-        changed = 0;
+            res = context->Map(buffer, 0, D3D11_MAP::D3D11_MAP_WRITE, 0, &map);
+        if (res == S_OK)
+        {
+            memcpy(map.pData, data, byteCount);
+            context->Unmap(buffer, 0);
+            changed = 0;
+        }
+        else
+        {
+            std::cout << "Could not update buffer: " << std::hex << res << std::endl;
+        }
     }
 }
 

+ 5 - 0
Ebene3D.h

@@ -185,5 +185,10 @@ namespace Framework
         {
             return !(*this == r);
         }
+
+        inline Vec3<T> normal() const
+        {
+            return {x, y, z};
+        }
     };
 } // namespace Framework

+ 29 - 18
GraphicsApi.h

@@ -130,6 +130,10 @@ namespace Framework
         DLLEXPORT virtual Model3DData* createModel(const char* name);
         // check if a model exists
         DLLEXPORT virtual bool hasModel(const char* name);
+        // creates a StructuredBuffer that is stored in the GPU memory and can
+        // be used as a shader resource
+        // \param eSize the size of one element of the buffer in bytes
+        DLLEXPORT virtual DXBuffer* createStructuredBuffer(int eSize) = 0;
     };
 
     class DirectX9 : public GraphicsApi
@@ -157,6 +161,8 @@ namespace Framework
         DLLEXPORT void presentFrame() override;
         DLLEXPORT Textur* createOrGetTextur(const char* name, Bild* b) override;
         DLLEXPORT Bild* zUIRenderBild() const override;
+
+        DLLEXPORT virtual DXBuffer* createStructuredBuffer(int eSize) override;
     };
 
     class DirectX11 : public GraphicsApi
@@ -178,8 +184,6 @@ namespace Framework
         D3D11_VIEWPORT* vp;
         TexturModel* texturModel;
         TexturList* texturRegister;
-        ID3D11RasterizerState* texturRS;
-        ID3D11RasterizerState* meshRS;
         Textur* defaultTextur;
         DX11StructuredBuffer* diffuseLights;
         DX11StructuredBuffer* pointLights;
@@ -190,22 +194,17 @@ namespace Framework
         int lastModelId = -1;
 
         void renderObject(Model3D* zObj);
-        //! Überprüft, ob eine Kugel in dem Sichtbaren Raum der Welt liegt und
-        //! gezeichnet werden muss \param pos Der Mittelpunkt der Kugel \param
-        //! radius Der Radius der Kugel \param dist Einen Zeiger auf einen
-        //! float, in dem das quadrat des Abstands zur Kammeraposition
-        //! gespeichert wird, falls diese Funktion true zurückgiebt und der
-        //! Zeiger nicht 0 ist
-        bool isInFrustrum(
-            const Vec3<float>& pos, float radius, float* dist = 0) const;
         DLLEXPORT virtual DXBuffer* createIndexBuffer() override;
         DLLEXPORT virtual DXBuffer* createVertexBuffer() override;
 
     protected:
+        ID3D11RasterizerState* texturRS;
+        ID3D11RasterizerState* meshRS;
         DLLEXPORT virtual DX11VertexShader* initializeVertexShader(
             unsigned char* byteCode, int size);
         DLLEXPORT virtual DX11PixelShader* initializePixelShader(
             unsigned char* byteCode, int size);
+        DLLEXPORT ID3D11DeviceContext* zContext();
 
     public:
         DLLEXPORT DirectX11();
@@ -221,6 +220,17 @@ namespace Framework
         DLLEXPORT void presentFrame() override;
         DLLEXPORT Textur* createOrGetTextur(const char* name, Bild* b) override;
         DLLEXPORT Bild* zUIRenderBild() const override;
+        DLLEXPORT virtual DXBuffer* createStructuredBuffer(int eSize) override;
+        //! Überprüft, ob eine Kugel in dem Sichtbaren Raum der Welt liegt und
+        //! gezeichnet werden muss \param pos Der Mittelpunkt der Kugel \param
+        //! radius Der Radius der Kugel \param dist Einen Zeiger auf einen
+        //! float, in dem das quadrat des Abstands zur Kammeraposition
+        //! gespeichert wird, falls diese Funktion true zurückgiebt und der
+        //! Zeiger nicht 0 ist
+        DLLEXPORT bool isInFrustrum(
+            const Vec3<float>& pos, float radius, float* dist = 0) const;
+        DLLEXPORT bool isInFrustrum(
+            const Vec3<float>& pos, Vec3<float> radius, float* dist = 0) const;
 
         DLLEXPORT static bool isAvailable();
     };
@@ -259,14 +269,6 @@ namespace Framework
         DX12PixelShader* pixelShader;
 
         void renderObject(Model3D* zObj);
-        //! Überprüft, ob eine Kugel in dem Sichtbaren Raum der Welt liegt und
-        //! gezeichnet werden muss \param pos Der Mittelpunkt der Kugel \param
-        //! radius Der Radius der Kugel \param dist Einen Zeiger auf einen
-        //! float, in dem das quadrat des Abstands zur Kammeraposition
-        //! gespeichert wird, falls diese Funktion true zurückgiebt und der
-        //! Zeiger nicht 0 ist
-        bool isInFrustrum(
-            const Vec3<float>& pos, float radius, float* dist = 0) const;
         DLLEXPORT virtual DXBuffer* createIndexBuffer() override;
         DLLEXPORT virtual DXBuffer* createVertexBuffer() override;
 
@@ -285,6 +287,15 @@ namespace Framework
         DLLEXPORT void presentFrame() override;
         DLLEXPORT Textur* createOrGetTextur(const char* name, Bild* b) override;
         DLLEXPORT Bild* zUIRenderBild() const override;
+        DLLEXPORT virtual DXBuffer* createStructuredBuffer(int eSize) override;
+        //! Überprüft, ob eine Kugel in dem Sichtbaren Raum der Welt liegt und
+        //! gezeichnet werden muss \param pos Der Mittelpunkt der Kugel \param
+        //! radius Der Radius der Kugel \param dist Einen Zeiger auf einen
+        //! float, in dem das quadrat des Abstands zur Kammeraposition
+        //! gespeichert wird, falls diese Funktion true zurückgiebt und der
+        //! Zeiger nicht 0 ist
+        DLLEXPORT bool isInFrustrum(
+            const Vec3<float>& pos, float radius, float* dist = 0) const;
 
         DLLEXPORT static bool isAvailable();
     };

+ 22 - 0
Welt3D.cpp

@@ -285,3 +285,25 @@ PointLight& Framework::Welt3D::getPointLight(int index) const
 {
     return pointLights[index];
 }
+
+//! removes a specific fiffuse light from the world
+//! \param index the index of the light
+DLLEXPORT void Framework::Welt3D::removeDiffuseLight(int index)
+{
+    for (int i = index; i < diffuseLightCount - 1; i++)
+    {
+        diffuseLights[i] = diffuseLights[i + 1];
+    }
+    diffuseLightCount--;
+}
+
+//! removes a specific point light from the world
+//! \param index the index of the light
+DLLEXPORT void Framework::Welt3D::removePointLight(int index)
+{
+    for (int i = index; i < pointLightCount - 1; i++)
+    {
+        pointLights[i] = pointLights[i + 1];
+    }
+    pointLightCount--;
+}

+ 6 - 0
Welt3D.h

@@ -93,5 +93,11 @@ namespace Framework
         //! Gibt die Referenz auf eine Punkt Lichtquelle zurück
         //! \param index Der Index der Lichtquelle
         DLLEXPORT PointLight& getPointLight(int index) const;
+        //! removes a specific fiffuse light from the world
+        //! \param index the index of the light
+        DLLEXPORT void removeDiffuseLight(int index);
+        //! removes a specific point light from the world
+        //! \param index the index of the light
+        DLLEXPORT void removePointLight(int index);
     };
 } // namespace Framework