Skip to content

Commit 1beec46

Browse files
committed
Added frustum culling
1 parent d268283 commit 1beec46

4 files changed

Lines changed: 77 additions & 18 deletions

File tree

Minecraft-Clone/src/Chunk.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ namespace RealEngine {
3737
MeshData& Reuse();
3838
void GenerateMesh();
3939

40+
// Used for frustum culling
41+
glm::vec3 GetMin() { return glm::vec3(m_ChunkOffset.x * CS, m_ChunkOffset.y * CS, m_ChunkOffset.z * CS); }
42+
glm::vec3 GetMax() { return glm::vec3(m_ChunkOffset.x * CS + CS, m_ChunkOffset.y * CS + CS, m_ChunkOffset.z * CS + CS); }
43+
4044
glm::ivec3& GetChunkOffset() { return m_ChunkOffset; }
4145
private:
4246
BlockType m_Blocks[CS_P * CS_P * CS_P];

Minecraft-Clone/src/ChunkManager.cpp

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,57 @@
11
#include "ChunkManager.h"
22

33
#include "RealEngine.h"
4+
#include <glm/gtc/matrix_access.hpp>
45

56
namespace RealEngine {
7+
namespace Utils {
8+
void ExtractFrustum(glm::vec4* frustumPlanes, const glm::mat4& viewProjectionMatrix) {
9+
RE_PROFILE_FUNCTION();
10+
11+
// Extract the right plane
12+
frustumPlanes[0] = glm::row(viewProjectionMatrix, 3) - glm::row(viewProjectionMatrix, 0);
13+
14+
// Extract the left plane
15+
frustumPlanes[1] = glm::row(viewProjectionMatrix, 3) + glm::row(viewProjectionMatrix, 0);
16+
17+
// Extract the top plane
18+
frustumPlanes[2] = glm::row(viewProjectionMatrix, 3) - glm::row(viewProjectionMatrix, 1);
19+
20+
// Extract the bottom plane
21+
frustumPlanes[3] = glm::row(viewProjectionMatrix, 3) + glm::row(viewProjectionMatrix, 1);
22+
23+
// Extract the near plane
24+
frustumPlanes[4] = glm::row(viewProjectionMatrix, 3) + glm::row(viewProjectionMatrix, 2);
25+
26+
// Extract the far plane
27+
frustumPlanes[5] = glm::row(viewProjectionMatrix, 3) - glm::row(viewProjectionMatrix, 2);
28+
29+
for (int i = 0; i < 6; i++) {
30+
frustumPlanes[i] = glm::normalize(frustumPlanes[i]);
31+
}
32+
}
33+
34+
//This is to check if the bounding boxes for the chunks are in the frustum
35+
bool IntersectFrustum(const glm::vec4* frustumPlanes, const glm::vec3& min, const glm::vec3& max) {
36+
RE_PROFILE_FUNCTION();
37+
38+
// Check if each corner of the bounding box is inside the frustum
39+
for (int i = 0; i < 6; i++) {
40+
if (glm::dot(frustumPlanes[i], glm::vec4(min, 1.0f)) < 0 &&
41+
glm::dot(frustumPlanes[i], glm::vec4(max, 1.0f)) < 0 &&
42+
glm::dot(frustumPlanes[i], glm::vec4(min.x, min.y, max.z, 1.0f)) < 0 &&
43+
glm::dot(frustumPlanes[i], glm::vec4(min.x, max.y, min.z, 1.0f)) < 0 &&
44+
glm::dot(frustumPlanes[i], glm::vec4(min.x, max.y, max.z, 1.0f)) < 0 &&
45+
glm::dot(frustumPlanes[i], glm::vec4(max.x, min.y, min.z, 1.0f)) < 0 &&
46+
glm::dot(frustumPlanes[i], glm::vec4(max.x, min.y, max.z, 1.0f)) < 0 &&
47+
glm::dot(frustumPlanes[i], glm::vec4(max.x, max.y, min.z, 1.0f)) < 0) {
48+
return false;
49+
}
50+
}
51+
return true;
52+
}
53+
}
54+
655
ChunkManager::ChunkManager(Ref<GameCamera> camera)
756
: m_Camera(camera) {
857
RE_PROFILE_FUNCTION();
@@ -14,13 +63,13 @@ namespace RealEngine {
1463
return sqrt(RenderDistance * RenderDistance - x * x);
1564
};
1665

17-
glm::ivec3 cameraposition = glm::ivec3(m_Camera->GetPosition()) / glm::ivec3(CS);
66+
glm::ivec3 cameraPosition = glm::ivec3(m_Camera->GetPosition()) / glm::ivec3(CS);
1867
for (float x = 0.5; x < RenderDistance; x += 1.0f) {
1968
uint8_t yChunkCnt = (uint8_t)std::roundf(circleFunction(x));
2069

2170
//Right side of circle
2271
for (int i = -yChunkCnt; i < yChunkCnt; i++) {
23-
glm::ivec3 chunkOffset = { (int)(x - 0.5f + cameraposition.x), 0, i + cameraposition.z };
72+
glm::ivec3 chunkOffset = { (int)(x - 0.5f + cameraPosition.x), 0, i + cameraPosition.z };
2473
Scope<Chunk> chunk = CreateScope<Chunk>(chunkOffset);
2574

2675
MeshData meshData = chunk->Reuse();
@@ -43,7 +92,7 @@ namespace RealEngine {
4392

4493
//Left side of circle
4594
for (int i = -yChunkCnt; i < yChunkCnt; i++) {
46-
glm::ivec3 chunkOffset = { cameraposition.z - (int)(x + 0.5f), 0, i + cameraposition.z };
95+
glm::ivec3 chunkOffset = { cameraPosition.z - (int)(x + 0.5f), 0, i + cameraPosition.z };
4796
Scope<Chunk> chunk = CreateScope<Chunk>(chunkOffset);
4897

4998
MeshData meshData = chunk->Reuse();
@@ -64,8 +113,6 @@ namespace RealEngine {
64113
m_Chunks.push_back({ std::move(chunk), renderData });
65114
}
66115
}
67-
68-
m_RenderStats.chunks = (uint32_t)m_Chunks.size();
69116
}
70117

71118
void ChunkManager::Update() {
@@ -74,16 +121,24 @@ namespace RealEngine {
74121

75122
void ChunkManager::Render() {
76123
RE_PROFILE_FUNCTION();
77-
m_RenderStats.drawCalls = 0;
78-
m_RenderStats.quads = 0;
124+
m_RenderStats.DrawCalls = 0;
125+
m_RenderStats.Quads = 0;
126+
m_RenderStats.Chunks = 0;
127+
128+
glm::vec4 frustumPlanes[6];
129+
Utils::ExtractFrustum(frustumPlanes, m_Camera->GetViewProjection());
79130

80131
for (const auto& chunk : m_Chunks) {
81-
for (int i = 0; i < chunk.RenderData.faceDrawCommands.size(); i++) {
82-
if (chunk.RenderData.faceDrawCommands[i]) {
83-
m_ChunkRenderer.addDrawCommand(*chunk.RenderData.faceDrawCommands[i]);
84-
m_RenderStats.drawCalls++;
85-
m_RenderStats.quads += chunk.RenderData.faceDrawCommands[i]->indexCount / 6;
132+
if (Utils::IntersectFrustum(frustumPlanes, chunk.Object->GetMin(), chunk.Object->GetMax())) {
133+
for (int i = 0; i < chunk.RenderData.faceDrawCommands.size(); i++) {
134+
if (chunk.RenderData.faceDrawCommands[i]) {
135+
m_ChunkRenderer.addDrawCommand(*chunk.RenderData.faceDrawCommands[i]);
136+
m_RenderStats.DrawCalls++;
137+
m_RenderStats.Quads += chunk.RenderData.faceDrawCommands[i]->indexCount / 6;
138+
}
86139
}
140+
141+
m_RenderStats.Chunks++;
87142
}
88143
}
89144

Minecraft-Clone/src/ChunkManager.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ namespace RealEngine {
1919
};
2020

2121
struct RenderStats {
22-
uint32_t drawCalls = 0;
23-
uint32_t quads = 0;
22+
uint32_t DrawCalls = 0;
23+
uint32_t Quads = 0;
2424

25-
uint32_t chunks = 0;
25+
uint32_t Chunks = 0;
2626
};
2727

2828
class ChunkManager {

Minecraft-Clone/src/MinecraftLayer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ namespace RealEngine {
6767
// Render Stats
6868
const RenderStats& renderStats = m_ChunkManager->GetRenderStats();
6969
ImGui::Text("Render Stats:");
70-
ImGui::Text("Draw Calls: %d", renderStats.drawCalls);
71-
ImGui::Text("Quads: %d", renderStats.quads);
72-
ImGui::Text("Chunks: %d", renderStats.chunks);
70+
ImGui::Text("Draw Calls: %d", renderStats.DrawCalls);
71+
ImGui::Text("Quads: %d", renderStats.Quads);
72+
ImGui::Text("Chunks: %d", renderStats.Chunks);
7373

7474
ImGui::End();
7575
}

0 commit comments

Comments
 (0)