Minor update - frustum rework
Complete overhaul of frustum culling
This commit is contained in:
parent
ab0355ed97
commit
01a9c940f0
@ -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<std::wstring> 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::vector<std::reference_wrapper<std::
|
||||
XMMATRIX worldMatrix, scaleMatrix, rotateMatrix, translateMatrix, srMatrix;
|
||||
bool result;
|
||||
|
||||
int renderCount = 0;
|
||||
|
||||
ConstructFrustum();
|
||||
|
||||
|
||||
for (const auto& RenderQueue : RenderQueues)
|
||||
{
|
||||
for (auto& object : RenderQueue.get())
|
||||
@ -1927,6 +1875,21 @@ bool ApplicationClass::RenderPass(const std::vector<std::reference_wrapper<std::
|
||||
return false;
|
||||
}
|
||||
|
||||
XMVECTOR objposition = object->GetPosition();
|
||||
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::vector<std::reference_wrapper<std::
|
||||
}
|
||||
}
|
||||
|
||||
SetRenderCount(renderCount);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ApplicationClass::ConstructFrustum()
|
||||
{
|
||||
XMMATRIX projectionMatrix = m_Direct3D->GetProjectionMatrix();
|
||||
XMMATRIX viewMatrix;
|
||||
m_Camera->GetViewMatrix(viewMatrix);
|
||||
|
||||
m_FrustumCulling.ConstructFrustum(SCREEN_DEPTH, projectionMatrix, viewMatrix);
|
||||
}
|
@ -29,6 +29,7 @@
|
||||
#include "translateshaderclass.h"
|
||||
#include "reflectionshaderclass.h"
|
||||
#include "physics.h"
|
||||
#include "frustum.h"
|
||||
|
||||
#include <WICTextureLoader.h>
|
||||
#include <comdef.h> // 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<std::reference_wrapper<std::vector<Object*>>>& 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
|
@ -26,6 +26,7 @@
|
||||
<ClCompile Include="CelShadingShader.cpp" />
|
||||
<ClCompile Include="Colorshaderclass.cpp" />
|
||||
<ClCompile Include="d3dclass.cpp" />
|
||||
<ClCompile Include="frustum.cpp" />
|
||||
<ClCompile Include="imguiManager.cpp" />
|
||||
<ClCompile Include="include\backends\imgui_impl_dx11.cpp" />
|
||||
<ClCompile Include="include\backends\imgui_impl_win32.cpp" />
|
||||
@ -79,6 +80,7 @@
|
||||
<ClInclude Include="CelShadingShader.h" />
|
||||
<ClInclude Include="Colorshaderclass.h" />
|
||||
<ClInclude Include="d3dclass.h" />
|
||||
<ClInclude Include="frustum.h" />
|
||||
<ClInclude Include="imguiManager.h" />
|
||||
<ClInclude Include="include\backends\imgui_impl_dx11.h" />
|
||||
<ClInclude Include="include\backends\imgui_impl_win32.h" />
|
||||
@ -304,7 +306,10 @@
|
||||
<CopyFileToFolders Include="assets\Texture\water01.png">
|
||||
<DestinationFolders Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)\assets\Texture\</DestinationFolders>
|
||||
</CopyFileToFolders>
|
||||
<Image Include="assets\Texture\EmptyTexture.png" />
|
||||
<CopyFileToFolders Include="assets\Texture\EmptyTexture.png">
|
||||
<DestinationFolders Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)\assets\Texture\</DestinationFolders>
|
||||
<DestinationFolders Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)\assets\Texture\</DestinationFolders>
|
||||
</CopyFileToFolders>
|
||||
<Image Include="KhaoticIcon.ico" />
|
||||
<CopyFileToFolders Include="sprite01.tga" />
|
||||
<CopyFileToFolders Include="sprite02.tga" />
|
||||
|
@ -219,6 +219,9 @@
|
||||
<ClCompile Include="textureclass.cpp">
|
||||
<Filter>Fichiers sources\System</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="frustum.cpp">
|
||||
<Filter>Fichiers sources\System</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="systemclass.h">
|
||||
@ -383,14 +386,14 @@
|
||||
<ClInclude Include="object.h">
|
||||
<Filter>Fichiers d%27en-tête\System</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="frustum.h">
|
||||
<Filter>Fichiers d%27en-tête\System</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="KhaoticIcon.ico">
|
||||
<Filter>Assets</Filter>
|
||||
</Image>
|
||||
<Image Include="assets\Texture\EmptyTexture.png">
|
||||
<Filter>Assets\Texture</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
@ -620,5 +623,8 @@
|
||||
<CopyFileToFolders Include="assets\Model\OBJ\plane.obj">
|
||||
<Filter>Assets\Model\OBJ</Filter>
|
||||
</CopyFileToFolders>
|
||||
<CopyFileToFolders Include="assets\Texture\EmptyTexture.png">
|
||||
<Filter>Assets\Texture</Filter>
|
||||
</CopyFileToFolders>
|
||||
</ItemGroup>
|
||||
</Project>
|
88
enginecustom/frustum.cpp
Normal file
88
enginecustom/frustum.cpp
Normal file
@ -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;
|
||||
}
|
12
enginecustom/frustum.h
Normal file
12
enginecustom/frustum.h
Normal file
@ -0,0 +1,12 @@
|
||||
#include <DirectXMath.h>
|
||||
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];
|
||||
};
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
float Object::GetBoundingRadius() const
|
||||
{
|
||||
return m_boundingRadius;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user