diff --git a/enginecustom/applicationclass.cpp b/enginecustom/applicationclass.cpp index 1784448..c3e34d6 100644 --- a/enginecustom/applicationclass.cpp +++ b/enginecustom/applicationclass.cpp @@ -17,7 +17,6 @@ ApplicationClass::ApplicationClass() : m_ShouldQuit(false) m_RenderCountString = 0; m_ModelList = 0; m_Position = 0; - m_Frustum = 0; m_DisplayPlane = 0; m_BathModel = 0; m_WaterModel = 0; @@ -382,9 +381,6 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) // Create the position class object. m_Position = new PositionClass; - // Create the frustum class object. - m_Frustum = new FrustumClass; - // Create and initialize the fps object. m_Fps = new FpsClass(); @@ -472,17 +468,6 @@ void ApplicationClass::Shutdown() m_Physics = 0; } - // Release the frustum class object. - if (m_Frustum) - { - Logger::Get().Log("Releasing the frustum class object", __FILE__, __LINE__, Logger::LogLevel::Shutdown); - - delete m_Frustum; - m_Frustum = 0; - - Logger::Get().Log("Frustum class object released", __FILE__, __LINE__, Logger::LogLevel::Shutdown); - } - // Release the display plane object. if (m_DisplayPlane) { @@ -1087,6 +1072,15 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t return false; } + // Update the render count text. + result = UpdateRenderCountString(GetRenderCount()); + if (!result) + { + Logger::Get().Log("Could not update the render count string", __FILE__, __LINE__, Logger::LogLevel::Error); + return false; + } + + // Translate to where the bath model will be rendered. worldMatrix = XMMatrixTranslation(0.0f, -10.0f, 0.0f); @@ -1164,57 +1158,6 @@ bool ApplicationClass::Render(float rotation, float x, float y, float z, float t return false; } - // Construct the frustum. - m_Frustum->ConstructFrustum(viewMatrix, projectionMatrix, SCREEN_DEPTH); - - // Get the number of models that will be rendered. - modelCount = m_ModelList->GetModelCount(); - - // Initialize the count of models that have been rendered. - renderCount = 0; - - // Go through all the models and render them only if they can be seen by the camera view. - for (i = 0; i < modelCount; i++) - { - // Get the position and color of the sphere model at this index. - m_ModelList->GetData(i, positionX, positionY, positionZ); - - // Set the radius of the sphere to 1.0 since this is already known. - radius = 1.0f; - - // Check if the sphere model is in the view frustum. - renderModel = m_Frustum->CheckSphere(positionX, positionY, positionZ, radius); - - // If it can be seen then render it, if not skip this model and check the next sphere. - if (renderModel) - { - // Move the model to the location it should be rendered at. - worldMatrix = XMMatrixTranslation(positionX, positionY, positionZ); - - // Render the model using the light shader. - m_Model->Render(m_Direct3D->GetDeviceContext()); - - result = m_ShaderManager->RenderlightShader(m_Direct3D->GetDeviceContext(), m_Model->GetIndexCount(), worldMatrix, viewMatrix, projectionMatrix, m_Model->GetTexture(0), - diffuseColor, lightPosition, ambientColor); - if (!result) - { - Logger::Get().Log("Could not render the model using the light shader", __FILE__, __LINE__, Logger::LogLevel::Error); - return false; - } - - // Since this model was rendered then increase the count for this frame. - renderCount++; - } - } - - // Update the render count text. - result = UpdateRenderCountString(renderCount); - if (!result) - { - Logger::Get().Log("Could not update the render count string", __FILE__, __LINE__, Logger::LogLevel::Error); - return false; - } - // Disable the Z buffer and enable alpha blending for 2D rendering. m_Direct3D->TurnZBufferOff(); m_Direct3D->EnableAlphaBlending(); @@ -1560,10 +1503,10 @@ void ApplicationClass::AddKobject(WCHAR* filepath) // Liste des fichiers de texture std::vector kobjTexture = { - L"assets/Texture/Bricks2K.png" + L"assets/Texture/Bricks2K.png", + L"assets/Texture/EmptyTexture.png" }; - textures.clear(); for (const auto& textureFilename : kobjTexture) { @@ -1917,6 +1860,11 @@ bool ApplicationClass::RenderPass(const std::vectorGetPosition(); + float x = XMVectorGetX(objposition); + float y = XMVectorGetY(objposition); + float z = XMVectorGetZ(objposition); + float radius = object->GetBoundingRadius(); + + // Vérifie si l'objet est dans le frustum + if (!m_FrustumCulling.CheckCube(x, y, z, radius, GetFrustumTolerance())) + { + + continue; + } + + renderCount++; + scaleMatrix = object->GetScaleMatrix(); rotateMatrix = object->GetRotateMatrix(); translateMatrix = object->GetTranslateMatrix(); @@ -1981,5 +1944,16 @@ bool ApplicationClass::RenderPass(const std::vectorGetProjectionMatrix(); + XMMATRIX viewMatrix; + m_Camera->GetViewMatrix(viewMatrix); + + m_FrustumCulling.ConstructFrustum(SCREEN_DEPTH, projectionMatrix, viewMatrix); +} \ No newline at end of file diff --git a/enginecustom/applicationclass.h b/enginecustom/applicationclass.h index 00c0a81..3e8231e 100644 --- a/enginecustom/applicationclass.h +++ b/enginecustom/applicationclass.h @@ -29,6 +29,7 @@ #include "translateshaderclass.h" #include "reflectionshaderclass.h" #include "physics.h" +#include "frustum.h" #include #include // Pour _com_error @@ -104,6 +105,19 @@ public: Physics* GetPhysics() const { return m_Physics; }; + // ----------------------------------- // + // ------------- Frustum ------------- // + // ----------------------------------- // + + Frustum GetFrustum() const { return m_FrustumCulling; }; + void SetFrustum(Frustum frustum) { m_FrustumCulling = frustum; }; + + void ConstructFrustum(); + int GetRenderCount() const { return m_renderCount; }; + void SetRenderCount(int renderCount) { m_renderCount = renderCount; }; + float GetFrustumTolerance() const { return m_FrustumCullingTolerance; }; + void SetFrustumTolerance(float frustumTolerance) { m_FrustumCullingTolerance = frustumTolerance; }; + private: bool Render(float, float, float, float, float); bool RenderPhysics(float x, float y, float z); @@ -115,6 +129,7 @@ private: bool RenderReflectionToTexture(); bool RenderPass(const std::vector>>& RenderQueues, XMFLOAT4* diffuse, XMFLOAT4* position, XMFLOAT4* ambient, XMMATRIX view, XMMATRIX projection); + private : // ------------------------------------- // @@ -140,7 +155,6 @@ private : int m_screenWidth, m_screenHeight; CameraClass* m_Camera; PositionClass* m_Position; - FrustumClass* m_Frustum; // ------------------------------------ // // ------------- OBJECTS -------------- // @@ -204,6 +218,14 @@ private : Physics* m_Physics; float m_gravity; XMVECTOR m_previousPosition; + + // ------------------------------------------------- // + // ------------------- Frustum --------------------- // + // ------------------------------------------------- // + + Frustum m_FrustumCulling; + int m_renderCount; + float m_FrustumCullingTolerance = 5.f; }; #endif \ No newline at end of file diff --git a/enginecustom/enginecustom.vcxproj b/enginecustom/enginecustom.vcxproj index e76a0b5..a649b5c 100644 --- a/enginecustom/enginecustom.vcxproj +++ b/enginecustom/enginecustom.vcxproj @@ -26,6 +26,7 @@ + @@ -79,6 +80,7 @@ + @@ -304,7 +306,10 @@ $(OutDir)\assets\Texture\ - + + $(OutDir)\assets\Texture\ + $(OutDir)\assets\Texture\ + diff --git a/enginecustom/enginecustom.vcxproj.filters b/enginecustom/enginecustom.vcxproj.filters index 84d1d6c..7e551de 100644 --- a/enginecustom/enginecustom.vcxproj.filters +++ b/enginecustom/enginecustom.vcxproj.filters @@ -219,6 +219,9 @@ Fichiers sources\System + + Fichiers sources\System + @@ -383,14 +386,14 @@ Fichiers d%27en-tête\System + + Fichiers d%27en-tête\System + Assets - - Assets\Texture - @@ -620,5 +623,8 @@ Assets\Model\OBJ + + Assets\Texture + \ No newline at end of file diff --git a/enginecustom/frustum.cpp b/enginecustom/frustum.cpp new file mode 100644 index 0000000..2057088 --- /dev/null +++ b/enginecustom/frustum.cpp @@ -0,0 +1,88 @@ +#include "frustum.h" + +void Frustum::ConstructFrustum(float screenDepth, XMMATRIX projectionMatrix, XMMATRIX viewMatrix) +{ + XMMATRIX matrix; + XMVECTOR planes[6]; + + // Calculate the minimum Z distance in the frustum. + float zMinimum = -projectionMatrix.r[3].m128_f32[2] / projectionMatrix.r[2].m128_f32[2]; + float r = screenDepth / (screenDepth - zMinimum); + projectionMatrix.r[2].m128_f32[2] = r; + projectionMatrix.r[3].m128_f32[2] = -r * zMinimum; + + // Create the frustum matrix from the view matrix and updated projection matrix. + matrix = XMMatrixMultiply(viewMatrix, projectionMatrix); + + // Calculate near plane of frustum. + planes[0] = XMPlaneNormalize(XMVectorSet(matrix.r[0].m128_f32[3] + matrix.r[0].m128_f32[2], + matrix.r[1].m128_f32[3] + matrix.r[1].m128_f32[2], + matrix.r[2].m128_f32[3] + matrix.r[2].m128_f32[2], + matrix.r[3].m128_f32[3] + matrix.r[3].m128_f32[2])); + + // Calculate far plane of frustum. + planes[1] = XMPlaneNormalize(XMVectorSet(matrix.r[0].m128_f32[3] - matrix.r[0].m128_f32[2], + matrix.r[1].m128_f32[3] - matrix.r[1].m128_f32[2], + matrix.r[2].m128_f32[3] - matrix.r[2].m128_f32[2], + matrix.r[3].m128_f32[3] - matrix.r[3].m128_f32[2])); + + // Calculate left plane of frustum. + planes[2] = XMPlaneNormalize(XMVectorSet(matrix.r[0].m128_f32[3] + matrix.r[0].m128_f32[0], + matrix.r[1].m128_f32[3] + matrix.r[1].m128_f32[0], + matrix.r[2].m128_f32[3] + matrix.r[2].m128_f32[0], + matrix.r[3].m128_f32[3] + matrix.r[3].m128_f32[0])); + + // Calculate right plane of frustum. + planes[3] = XMPlaneNormalize(XMVectorSet(matrix.r[0].m128_f32[3] - matrix.r[0].m128_f32[0], + matrix.r[1].m128_f32[3] - matrix.r[1].m128_f32[0], + matrix.r[2].m128_f32[3] - matrix.r[2].m128_f32[0], + matrix.r[3].m128_f32[3] - matrix.r[3].m128_f32[0])); + + // Calculate top plane of frustum. + planes[4] = XMPlaneNormalize(XMVectorSet(matrix.r[0].m128_f32[3] - matrix.r[0].m128_f32[1], + matrix.r[1].m128_f32[3] - matrix.r[1].m128_f32[1], + matrix.r[2].m128_f32[3] - matrix.r[2].m128_f32[1], + matrix.r[3].m128_f32[3] - matrix.r[3].m128_f32[1])); + + // Calculate bottom plane of frustum. + planes[5] = XMPlaneNormalize(XMVectorSet(matrix.r[0].m128_f32[3] + matrix.r[0].m128_f32[1], + matrix.r[1].m128_f32[3] + matrix.r[1].m128_f32[1], + matrix.r[2].m128_f32[3] + matrix.r[2].m128_f32[1], + matrix.r[3].m128_f32[3] + matrix.r[3].m128_f32[1])); + + for (int i = 0; i < 6; i++) + { + m_planes[i] = planes[i]; + } +} + +bool Frustum::CheckCube(float xCenter, float yCenter, float zCenter, float radius, float tolerance) +{ + // Vérifiez chaque plan du frustum pour voir si le cube est à l'intérieur + for (int i = 0; i < 6; i++) + { + XMVECTOR plane = m_planes[i]; + if (XMVectorGetX(plane) * (xCenter - radius) + XMVectorGetY(plane) * (yCenter - radius) + XMVectorGetZ(plane) * (zCenter - radius) + XMVectorGetW(plane) > -tolerance) + continue; + if (XMVectorGetX(plane) * (xCenter + radius) + XMVectorGetY(plane) * (yCenter - radius) + XMVectorGetZ(plane) * (zCenter - radius) + XMVectorGetW(plane) > -tolerance) + continue; + if (XMVectorGetX(plane) * (xCenter - radius) + XMVectorGetY(plane) * (yCenter + radius) + XMVectorGetZ(plane) * (zCenter - radius) + XMVectorGetW(plane) > -tolerance) + continue; + if (XMVectorGetX(plane) * (xCenter + radius) + XMVectorGetY(plane) * (yCenter + radius) + XMVectorGetZ(plane) * (zCenter - radius) + XMVectorGetW(plane) > -tolerance) + continue; + if (XMVectorGetX(plane) * (xCenter - radius) + XMVectorGetY(plane) * (yCenter - radius) + XMVectorGetZ(plane) * (zCenter + radius) + XMVectorGetW(plane) > -tolerance) + continue; + if (XMVectorGetX(plane) * (xCenter + radius) + XMVectorGetY(plane) * (yCenter - radius) + XMVectorGetZ(plane) * (zCenter + radius) + XMVectorGetW(plane) > -tolerance) + continue; + if (XMVectorGetX(plane) * (xCenter - radius) + XMVectorGetY(plane) * (yCenter + radius) + XMVectorGetZ(plane) * (zCenter + radius) + XMVectorGetW(plane) > -tolerance) + continue; + if (XMVectorGetX(plane) * (xCenter + radius) + XMVectorGetY(plane) * (yCenter + radius) + XMVectorGetZ(plane) * (zCenter + radius) + XMVectorGetW(plane) > -tolerance) + continue; + + // Si le cube est en dehors de l'un des plans, il n'est pas dans le frustum + return false; + } + + // Si le cube est à l'intérieur de tous les plans, il est dans le frustum + return true; +} diff --git a/enginecustom/frustum.h b/enginecustom/frustum.h new file mode 100644 index 0000000..eac209a --- /dev/null +++ b/enginecustom/frustum.h @@ -0,0 +1,12 @@ +#include +using namespace DirectX; + +class Frustum +{ +public: + void ConstructFrustum(float screenDepth, XMMATRIX projectionMatrix, XMMATRIX viewMatrix); + bool CheckCube(float xCenter, float yCenter, float zCenter, float radius, float tolerance); + +private: + XMVECTOR m_planes[6]; +}; \ No newline at end of file diff --git a/enginecustom/imgui.ini b/enginecustom/imgui.ini index d0ff702..9d74d7a 100644 --- a/enginecustom/imgui.ini +++ b/enginecustom/imgui.ini @@ -11,7 +11,7 @@ Pos=934,36 Size=457,294 [Window][Terrain] -Pos=60,60 +Pos=58,62 Size=342,82 [Window][Light] @@ -23,6 +23,6 @@ Pos=471,90 Size=180,79 [Window][Engine Settings] -Pos=106,213 -Size=168,77 +Pos=106,212 +Size=407,81 diff --git a/enginecustom/imguiManager.cpp b/enginecustom/imguiManager.cpp index 68621db..6771062 100644 --- a/enginecustom/imguiManager.cpp +++ b/enginecustom/imguiManager.cpp @@ -435,5 +435,12 @@ void imguiManager::WidgetEngineSettingsWindow(ApplicationClass* app) app->SetVsync(vsync); } + // float input for frustum tolerance + float frustumTolerance = app->GetFrustumTolerance(); + if (ImGui::DragFloat("Frustum Tolerance", &frustumTolerance, 0.1f, 0.0f, 100.0f)) + { + app->SetFrustumTolerance(frustumTolerance); + } + ImGui::End(); } \ No newline at end of file diff --git a/enginecustom/object.cpp b/enginecustom/object.cpp index 3d16471..9417cd9 100644 --- a/enginecustom/object.cpp +++ b/enginecustom/object.cpp @@ -13,6 +13,7 @@ Object::Object() : ModelClass() m_mass = NULL; m_isGrounded = false; m_id = NULL; + m_boundingRadius = 1.0f; } Object::~Object() @@ -233,4 +234,9 @@ bool Object::IsPhysicsEnabled() const void Object::SetPhysicsEnabled(bool state) { m_isPhysicsEnabled = state; -} \ No newline at end of file +} + +float Object::GetBoundingRadius() const +{ + return m_boundingRadius; +} diff --git a/enginecustom/object.h b/enginecustom/object.h index 111e34b..6abbc30 100644 --- a/enginecustom/object.h +++ b/enginecustom/object.h @@ -70,6 +70,8 @@ public: ShaderType GetActiveShader() const { return m_activeShader; }; void SetActiveShader(ShaderType activeShader) { m_activeShader = activeShader; }; + float GetBoundingRadius() const; + public : bool m_demoSpinning = false; XMVECTOR m_previousPosition; @@ -91,4 +93,6 @@ private: std::string m_name; ShaderType m_activeShader = LIGHTING; + + float m_boundingRadius; };