Skip to content

Commit 61ce2d5

Browse files
committed
Started work on rendering chunks around a player
1 parent ff1a0ad commit 61ce2d5

10 files changed

Lines changed: 312 additions & 80 deletions

File tree

Minecraft-Clone/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ project(Minecraft-Clone)
55
set(CMAKE_CXX_STANDARD 20)
66
set(CMAKE_CXX_STANDARD_REQUIRED True)
77

8-
add_executable(Minecraft-Clone "src/MinecraftAPP.cpp" "src/MinecraftLayer.h" "src/MinecraftLayer.cpp" "src/Chunk.h" "src/Chunk.cpp" "src/Block.cpp" "src/ChunkRenderer.h" "src/ChunkRenderer.cpp")
8+
add_executable(Minecraft-Clone "src/MinecraftAPP.cpp" "src/MinecraftLayer.h" "src/MinecraftLayer.cpp" "src/Chunk.h" "src/Chunk.cpp" "src/Block.cpp" "src/ChunkRenderer.h" "src/ChunkRenderer.cpp" "src/ChunkManager.h" "src/ChunkManager.cpp" "src/GameCamera.h")
99

1010
include_directories(Minecraft-Clone PRIVATE
1111
${CMAKE_SOURCE_DIR}/RealEngine/src

Minecraft-Clone/assets/shaders/basic.shader

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ layout(binding = 1, std430) readonly buffer ssbo1 {
1313
layout(binding = 0) uniform Camera {
1414
mat4 u_ViewProjection;
1515
vec3 eye_position;
16+
ivec3 eye_position_int;
1617
};
1718

1819
out VS_OUT {
@@ -67,7 +68,7 @@ void main() {
6768
vs_out.normal = normalLookup[face];
6869
vs_out.color = colorLookup[(quadData2&255u) - 1];
6970

70-
vec3 vertexPos = iVertexPos;
71+
vec3 vertexPos = iVertexPos - eye_position_int;
7172
vertexPos[wDir] += 0.0007 * flipLookup[face] * (wMod * 2 - 1);
7273
vertexPos[hDir] += 0.0007 * (hMod * 2 - 1);
7374

@@ -88,6 +89,7 @@ in VS_OUT {
8889
layout(binding = 0) uniform Camera {
8990
mat4 u_ViewProjection;
9091
vec3 eye_position;
92+
ivec3 eye_position_int;
9193
};
9294

9395
const vec3 diffuse_color = vec3(0.15, 0.15, 0.15);

Minecraft-Clone/src/Chunk.cpp

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,22 @@ namespace RealEngine {
1818
}
1919

2020
Chunk::Chunk(const glm::ivec3& chunkOffset)
21-
: m_ChunkOffset(chunkOffset) { }
21+
: m_ChunkOffset(chunkOffset) {
22+
m_MeshData.opaqueMask = new uint64_t[CS_P2]{ 0 };
23+
m_MeshData.faceMasks = new uint64_t[CS_2 * 6]{ 0 };
24+
m_MeshData.forwardMerged = new uint8_t[CS_2]{ 0 };
25+
m_MeshData.rightMerged = new uint8_t[CS]{ 0 };
26+
m_MeshData.vertices = new std::vector<uint64_t>(10000);
27+
m_MeshData.maxVertices = 10000;
28+
}
29+
30+
Chunk::~Chunk() {
31+
delete[] m_MeshData.opaqueMask;
32+
delete[] m_MeshData.faceMasks;
33+
delete[] m_MeshData.forwardMerged;
34+
delete[] m_MeshData.rightMerged;
35+
delete m_MeshData.vertices;
36+
}
2237

2338
constexpr uint64_t P_MASK = ~(1ull << 63 | 1);
2439

@@ -43,17 +58,9 @@ namespace RealEngine {
4358
return (type << 32) | (h << 24) | (w << 18) | (z << 12) | (y << 6) | x;
4459
}
4560

46-
MeshData Chunk::Generate() {
61+
MeshData& Chunk::Reuse() {
4762
RE_PROFILE_FUNCTION();
4863

49-
MeshData meshData;
50-
meshData.opaqueMask = new uint64_t[CS_P2]{ 0 };
51-
meshData.faceMasks = new uint64_t[CS_2 * 6]{ 0 };
52-
meshData.forwardMerged = new uint8_t[CS_2]{ 0 };
53-
meshData.rightMerged = new uint8_t[CS]{ 0 };
54-
meshData.vertices = new std::vector<uint64_t>(10000);
55-
meshData.maxVertices = 10000;
56-
5764
//for (uint16_t y = 0; y < CS; y++) {
5865
// for (uint8_t x = 0; x < CS; x++) {
5966
// for (uint8_t z = 0; z < CS; z++) {
@@ -78,34 +85,34 @@ namespace RealEngine {
7885
for (int z = 1; z < CS_P; z++) {
7986
if (x % 2 == 0 && y % 2 == 0 && z % 2 == 0) {
8087
m_Blocks[z + (x * CS_P) + (y * CS_P2)] = 1;
81-
meshData.opaqueMask[(y * CS_P) + x] |= 1ull << z;
88+
m_MeshData.opaqueMask[(y * CS_P) + x] |= 1ull << z;
8289

8390
m_Blocks[z + (x * CS_P) + (y * CS_P2)] = 2;
84-
meshData.opaqueMask[((y - 1) * CS_P) + (x - 1)] |= 1ull << z;
91+
m_MeshData.opaqueMask[((y - 1) * CS_P) + (x - 1)] |= 1ull << z;
8592

8693
m_Blocks[z + (x * CS_P) + (y * CS_P2)] = 3;
87-
meshData.opaqueMask[(y * CS_P) + (x - 1)] |= 1ull << (z - 1);
94+
m_MeshData.opaqueMask[(y * CS_P) + (x - 1)] |= 1ull << (z - 1);
8895

8996
m_Blocks[z + (x * CS_P) + (y * CS_P2)] = 4;
90-
meshData.opaqueMask[((y - 1) * CS_P) + x] |= 1ull << (z - 1);
97+
m_MeshData.opaqueMask[((y - 1) * CS_P) + x] |= 1ull << (z - 1);
9198
}
9299
}
93100
}
94101
}
95102

96-
GenerateMesh(meshData);
97-
return meshData;
103+
GenerateMesh();
104+
return m_MeshData;
98105
}
99106

100-
void Chunk::GenerateMesh(MeshData& meshData) {
107+
void Chunk::GenerateMesh() {
101108
RE_PROFILE_FUNCTION();
102109

103-
meshData.vertexCount = 0;
110+
m_MeshData.vertexCount = 0;
104111
int vertexI = 0;
105112

106-
uint64_t* opaqueMask = meshData.opaqueMask;
107-
uint64_t* faceMasks = meshData.faceMasks;
108-
uint8_t* forwardMerged = meshData.forwardMerged;
113+
uint64_t* opaqueMask = m_MeshData.opaqueMask;
114+
uint64_t* faceMasks = m_MeshData.faceMasks;
115+
uint8_t* forwardMerged = m_MeshData.forwardMerged;
109116

110117
// Hidden face culling
111118
for (int a = 1; a < CS_P - 1; a++) {
@@ -192,17 +199,17 @@ namespace RealEngine {
192199
break;
193200
}
194201

195-
insertQuad(*meshData.vertices, quad, vertexI, meshData.maxVertices);
202+
insertQuad(*m_MeshData.vertices, quad, vertexI, m_MeshData.maxVertices);
196203
}
197204
}
198205
}
199206

200207
const int faceVertexLength = vertexI - faceVertexBegin;
201-
meshData.faceVertexBegin[face] = faceVertexBegin;
202-
meshData.faceVertexLength[face] = faceVertexLength;
208+
m_MeshData.faceVertexBegin[face] = faceVertexBegin;
209+
m_MeshData.faceVertexLength[face] = faceVertexLength;
203210
}
204211

205-
uint8_t* rightMerged = meshData.rightMerged;
212+
uint8_t* rightMerged = m_MeshData.rightMerged;
206213

207214
// Greedy meshing faces 4-5
208215
for (uint8_t face = 4; face < 6; face++) {
@@ -259,16 +266,16 @@ namespace RealEngine {
259266

260267
const uint64_t quad = getQuad(meshLeft + (face == 4 ? meshWidth : 0), meshFront, meshUp, meshWidth, meshLength, type);
261268

262-
insertQuad(*meshData.vertices, quad, vertexI, meshData.maxVertices);
269+
insertQuad(*m_MeshData.vertices, quad, vertexI, m_MeshData.maxVertices);
263270
}
264271
}
265272
}
266273

267274
const int faceVertexLength = vertexI - faceVertexBegin;
268-
meshData.faceVertexBegin[face] = faceVertexBegin;
269-
meshData.faceVertexLength[face] = faceVertexLength;
275+
m_MeshData.faceVertexBegin[face] = faceVertexBegin;
276+
m_MeshData.faceVertexLength[face] = faceVertexLength;
270277
}
271278

272-
meshData.vertexCount = vertexI + 1;
279+
m_MeshData.vertexCount = vertexI + 1;
273280
}
274281
}

Minecraft-Clone/src/Chunk.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@
55

66
#include "Block.h"
77

8-
#define CHUNK_SIZE_WIDTH 62
8+
static constexpr int CS = 62;
99

10-
static constexpr int CS = CHUNK_SIZE_WIDTH;
11-
12-
static constexpr int CS_P = CHUNK_SIZE_WIDTH + 2;
10+
static constexpr int CS_P = CS + 2;
1311
static constexpr int CS_2 = CS * CS;
1412
static constexpr int CS_P2 = CS_P * CS_P;
1513
static constexpr int CS_P3 = CS_P * CS_P * CS_P;
@@ -29,16 +27,20 @@ namespace RealEngine {
2927

3028
class Chunk {
3129
public:
30+
Chunk() = delete;
3231
Chunk(const glm::ivec3& chunkOffset);
33-
~Chunk() = default;
32+
~Chunk();
3433

35-
MeshData Generate();
34+
Chunk(const Chunk&) = delete;
35+
Chunk& operator= (const Chunk&) = delete;
3636

37-
void GenerateMesh(MeshData& meshData);
37+
MeshData& Reuse();
38+
void GenerateMesh();
3839

3940
glm::ivec3& GetChunkOffset() { return m_ChunkOffset; }
4041
private:
4142
BlockType m_Blocks[CS_P * CS_P * CS_P];
43+
MeshData m_MeshData;
4244

4345
glm::ivec3 m_ChunkOffset;
4446
};
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include "ChunkManager.h"
2+
3+
#include "RealEngine.h"
4+
5+
namespace RealEngine {
6+
ChunkManager::ChunkManager() {
7+
RE_PROFILE_FUNCTION();
8+
m_Shader = Shader::Create("assets/shaders/basic.shader");
9+
10+
m_ChunkRenderer.init();
11+
12+
auto circleFunction = [](float x) {
13+
return sqrt(RenderDistance * RenderDistance - x * x);
14+
};
15+
16+
for (float x = 0.5; x < RenderDistance; x += 1.0f) {
17+
uint8_t yChunkCnt = (uint8_t)std::roundf(circleFunction(x));
18+
19+
//Right side of circle
20+
for (int i = -yChunkCnt; i < yChunkCnt; i++) {
21+
glm::ivec3 chunkOffset = { (int)(x - 0.5f), 0, -i };
22+
Scope<Chunk> chunk = CreateScope<Chunk>(chunkOffset);
23+
24+
MeshData meshData = chunk->Reuse();
25+
26+
ChunkRenderData renderData;
27+
for (uint32_t j = 0; j < renderData.faceDrawCommands.size(); j++) {
28+
if (meshData.faceVertexLength[j]) {
29+
uint32_t baseInstance = (j << 24) | (chunkOffset.z << 16) | (chunkOffset.y << 8) | chunkOffset.x;
30+
31+
auto drawCommand = m_ChunkRenderer.getDrawCommand(meshData.faceVertexLength[j], baseInstance);
32+
33+
renderData.faceDrawCommands[j] = drawCommand;
34+
35+
m_ChunkRenderer.buffer(*drawCommand, meshData.vertices->data() + meshData.faceVertexBegin[j]);
36+
}
37+
}
38+
39+
m_Chunks.push_back({ std::move(chunk), renderData });
40+
}
41+
42+
//Left side of circle
43+
for (int i = -yChunkCnt; i < yChunkCnt; i++) {
44+
glm::ivec3 chunkOffset = { -(int)(x + 0.5f), 0, i };
45+
Scope<Chunk> chunk = CreateScope<Chunk>(chunkOffset);
46+
47+
MeshData meshData = chunk->Reuse();
48+
49+
ChunkRenderData renderData;
50+
for (uint32_t j = 0; j < renderData.faceDrawCommands.size(); j++) {
51+
if (meshData.faceVertexLength[j]) {
52+
uint32_t baseInstance = (j << 24) | (chunkOffset.z << 16) | (chunkOffset.y << 8) | chunkOffset.x;
53+
54+
auto drawCommand = m_ChunkRenderer.getDrawCommand(meshData.faceVertexLength[j], baseInstance);
55+
56+
renderData.faceDrawCommands[j] = drawCommand;
57+
58+
m_ChunkRenderer.buffer(*drawCommand, meshData.vertices->data() + meshData.faceVertexBegin[j]);
59+
}
60+
}
61+
62+
m_Chunks.push_back({ std::move(chunk), renderData });
63+
}
64+
}
65+
}
66+
67+
void ChunkManager::Update() {
68+
// TODO: Implement
69+
}
70+
71+
void ChunkManager::Render() {
72+
for (const auto& chunk : m_Chunks) {
73+
for (int i = 0; i < chunk.ChunkRenderData.faceDrawCommands.size(); i++) {
74+
if (chunk.ChunkRenderData.faceDrawCommands[i]) {
75+
m_ChunkRenderer.addDrawCommand(*chunk.ChunkRenderData.faceDrawCommands[i]);
76+
}
77+
}
78+
}
79+
80+
m_ChunkRenderer.render(m_Shader);
81+
}
82+
}

Minecraft-Clone/src/ChunkManager.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#pragma once
2+
3+
#include "Chunk.h"
4+
#include "ChunkRenderer.h"
5+
6+
#include "RealEngine.h"
7+
8+
#define RenderDistance 1
9+
10+
namespace RealEngine {
11+
struct ChunkRenderData {
12+
std::array<DrawElementsIndirectCommand*, 6> faceDrawCommands = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
13+
};
14+
15+
struct ChunkData {
16+
Scope<Chunk> Chunk;
17+
ChunkRenderData ChunkRenderData;
18+
};
19+
20+
class ChunkManager {
21+
public:
22+
ChunkManager();
23+
~ChunkManager() = default;
24+
25+
void Update();
26+
void Render();
27+
private:
28+
Ref<Shader> m_Shader;
29+
30+
std::vector<ChunkData> m_Chunks;
31+
32+
ChunkRenderer m_ChunkRenderer;
33+
};
34+
}

0 commit comments

Comments
 (0)