diff --git a/SQCSim2021/chunk.cpp b/SQCSim2021/chunk.cpp index a732f85..3ca6797 100644 --- a/SQCSim2021/chunk.cpp +++ b/SQCSim2021/chunk.cpp @@ -5,18 +5,44 @@ Chunk::Chunk(int x, int y) : m_posX(x), m_posY(y) { m_blocks.Reset(BTYPE_AIR); } Chunk::~Chunk() { } -void Chunk::RemoveBlock(int x, int y, int z) { +void Chunk::RemoveBlock(int x, int y, int z, World* world) { m_blocks.Set(x, y, z, BTYPE_AIR); + + CheckNeighbors(x, y, world); + m_isDirty = true; } -void Chunk::SetBlock(int x, int y, int z, BlockType type) { +void Chunk::SetBlock(int x, int y, int z, BlockType type, World* world) { m_blocks.Set(x, y, z, type); + + CheckNeighbors(x, y, world); + m_isDirty = true; } BlockType Chunk::GetBlock(int x, int y, int z) { return m_blocks.Get(x, y, z); } +void Chunk::CheckNeighbors(int x, int z, World* world) { + if (x == 0 && m_posX > 0 && + world->ChunkAt((m_posX - 1) * CHUNK_SIZE_X, 1, m_posY * CHUNK_SIZE_Z) && + !world->ChunkAt((m_posX - 1) * CHUNK_SIZE_X, 1, m_posY * CHUNK_SIZE_Z)->IsDirty()) + world->ChunkAt((m_posX - 1) * CHUNK_SIZE_X, 1, m_posY * CHUNK_SIZE_Z)->MakeDirty(); + else if (x == CHUNK_SIZE_X - 1 && m_posX < VIEW_DISTANCE && + world->ChunkAt((m_posX + 1) * CHUNK_SIZE_X, 1, m_posY * CHUNK_SIZE_Z) && + !world->ChunkAt((m_posX + 1) * CHUNK_SIZE_X, 1, m_posY * CHUNK_SIZE_Z)->IsDirty()) + world->ChunkAt((m_posX + 1) * CHUNK_SIZE_X, 1, m_posY * CHUNK_SIZE_Z)->MakeDirty(); + + if (z == 0 && m_posY > 0 && + world->ChunkAt(m_posX * CHUNK_SIZE_X, 1, (m_posY - 1) * CHUNK_SIZE_Z) && + !world->ChunkAt(m_posX * CHUNK_SIZE_X, 1, (m_posY - 1) * CHUNK_SIZE_Z)->IsDirty()) + world->ChunkAt(m_posX * CHUNK_SIZE_X, 1, (m_posY - 1) * CHUNK_SIZE_Z)->MakeDirty(); + else if (z == CHUNK_SIZE_X - 1 && m_posY < VIEW_DISTANCE && + world->ChunkAt(m_posX * CHUNK_SIZE_X, 1, (m_posY + 1) * CHUNK_SIZE_Z) && + !world->ChunkAt(m_posX * CHUNK_SIZE_X, 1, (m_posY + 1) * CHUNK_SIZE_Z)->IsDirty()) + world->ChunkAt(m_posX * CHUNK_SIZE_X, 1, (m_posY + 1) * CHUNK_SIZE_Z)->MakeDirty(); +} + void Chunk::Update(BlockInfo* blockinfo[BTYPE_LAST], World* world) { float u, v, s; // Update mesh @@ -101,3 +127,5 @@ void Chunk::Render() const { m_vertexBuffer.Render(); } bool Chunk::IsDirty() const { return m_isDirty; } +void Chunk::MakeDirty() { m_isDirty = true; } + diff --git a/SQCSim2021/chunk.h b/SQCSim2021/chunk.h index f53c57f..533f979 100644 --- a/SQCSim2021/chunk.h +++ b/SQCSim2021/chunk.h @@ -24,14 +24,16 @@ class Chunk { Chunk(int x, int y); ~Chunk(); - void RemoveBlock(int x, int y, int z); - void SetBlock(int x, int y, int z, BlockType type); + void RemoveBlock(int x, int y, int z, World* world); + void SetBlock(int x, int y, int z, BlockType type, World* world); BlockType GetBlock(int x, int y, int z); + void CheckNeighbors(int x, int z, World* world); void Update(BlockInfo* blockinfo[BTYPE_LAST], World* world); void Render() const; bool IsDirty() const; + void MakeDirty(); }; #endif // CHUNK_H__ diff --git a/SQCSim2021/define.h b/SQCSim2021/define.h index 7696862..d6e79cf 100644 --- a/SQCSim2021/define.h +++ b/SQCSim2021/define.h @@ -16,6 +16,8 @@ #define CHUNK_SIZE_X 16 #define CHUNK_SIZE_Y 128 #define CHUNK_SIZE_Z 16 +#define MAX_RENDER_CHUNKS 2 +#define MAX_UPDATE_CHUNKS 2 typedef uint8_t BlockType; enum BLOCK_TYPE { BTYPE_AIR, BTYPE_DIRT, BTYPE_GRASS, BTYPE_METAL, BTYPE_ICE, BTYPE_LAST }; diff --git a/SQCSim2021/engine.cpp b/SQCSim2021/engine.cpp index da4b34d..651a607 100644 --- a/SQCSim2021/engine.cpp +++ b/SQCSim2021/engine.cpp @@ -48,47 +48,7 @@ void Engine::Init() m_audio.ToggleMusicState(); // Init Chunks - for (int chx = 0; chx < VIEW_DISTANCE; ++chx) // Un beau gros monde de VIEW_DISTANCE Chunks par VIEW_DISTANCE Chunks. - for (int chy = 0; chy < VIEW_DISTANCE; ++chy) - m_world.GetChunks().Set(chx, chy, new Chunk(chx, chy)); - - // Génération Chunks. - for (int chx = 0; chx < VIEW_DISTANCE; ++chx) - for (int chy = 0; chy < VIEW_DISTANCE; ++chy) { - - for (int x = 0; x < CHUNK_SIZE_X; ++x) - for (int z = 0; z < CHUNK_SIZE_Z; ++z) - for (int y = 0; y < 32; ++y) - m_world.GetChunks().Get(chx, chy)->SetBlock(x, y, z, ((chx + chy) % (BTYPE_LAST - 1)) + 1); - - m_world.GetChunks().Get(chx, chy)->SetBlock(5, 32, 15, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(5, 33, 15, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(5, 34, 15, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(6, 34, 15, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(7, 34, 15, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(7, 33, 15, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(7, 32, 15, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(8, 32, 3, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(8, 33, 4, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(8, 34, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(8, 35, 6, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(11, 32, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(11, 33, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(11, 34, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(11, 35, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(12, 32, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(12, 33, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(12, 34, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(12, 35, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(13, 32, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(13, 33, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(13, 34, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(13, 35, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(14, 32, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(14, 33, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(14, 34, 5, BTYPE_GRASS); - m_world.GetChunks().Get(chx, chy)->SetBlock(14, 35, 5, BTYPE_GRASS); - } + m_world.GetChunks().Reset(nullptr); // Gestion de souris. CenterMouse(); @@ -243,15 +203,71 @@ void Engine::Render(float elapsedTime) { glEnable(GL_LIGHT0); m_shader01.Use(); m_textureAtlas.Bind(); + + int cx = m_player.GetPosition().x; + int cy = m_player.GetPosition().z; + int accRender = 0; + + for (int chx = cx - CHUNK_SIZE_X * 6; chx < cx + CHUNK_SIZE_X * 6; chx+= CHUNK_SIZE_X) + for (int chy = cy - CHUNK_SIZE_Z * 6; chy < cy + CHUNK_SIZE_Z * 6; chy += CHUNK_SIZE_Z) { + if (!m_world.ChunkAt(chx, 1, chy)) { + + m_world.GetChunks().Set(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z, new Chunk(chx / CHUNK_SIZE_X, chy / CHUNK_SIZE_Z)); + + for (int x = 0; x < CHUNK_SIZE_X; ++x) + for (int z = 0; z < CHUNK_SIZE_Z; ++z) + for (int y = 0; y < 32; ++y) + m_world.ChunkAt(chx, 1, chy)->SetBlock(x, y, z, (chx + chy) % (BTYPE_LAST - 1) + 1, &m_world); + + m_world.ChunkAt(chx, 1, chy)->SetBlock(5, 32, 15, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(5, 33, 15, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(5, 34, 15, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(6, 34, 15, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(7, 34, 15, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(7, 33, 15, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(7, 32, 15, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(8, 32, 3, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(8, 33, 4, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(8, 34, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(8, 35, 6, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(11, 32, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(11, 33, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(11, 34, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(11, 35, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(12, 32, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(12, 33, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(12, 34, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(12, 35, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(13, 32, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(13, 33, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(13, 34, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(13, 35, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(14, 32, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(14, 33, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(14, 34, 5, BTYPE_GRASS, &m_world); + m_world.ChunkAt(chx, 1, chy)->SetBlock(14, 35, 5, BTYPE_GRASS, &m_world); + + if (++accRender > MAX_RENDER_CHUNKS) { + chx = cx + CHUNK_SIZE_X * 6; + chy = cy + CHUNK_SIZE_Z * 6; + } + } + } + + int accUpdate = 0; + for (int chx = 0; chx < VIEW_DISTANCE; chx++) for (int chy = 0; chy < VIEW_DISTANCE; chy++) { + if (m_world.GetChunks().Get(chx, chy)) { all.ApplyTranslation(chx * CHUNK_SIZE_X, 0, chy * CHUNK_SIZE_Z); all.Use(); - if (m_world.GetChunks().Get(chx, chy)->IsDirty()) - m_world.GetChunks().Get(chx, chy)->Update(m_blockinfo, &m_world); - //if (chx * CHUNK_SIZE_X >= m_player.GetPosition().x * m_player.GetDirection().x && chy * CHUNK_SIZE_Z >= m_player.GetPosition().z * m_player.GetDirection().z) + if (m_world.GetChunks().Get(chx, chy)->IsDirty()) + if (++accUpdate < MAX_UPDATE_CHUNKS) + m_world.GetChunks().Get(chx, chy)->Update(m_blockinfo, &m_world); + /* View fustrum culling va ici */ m_world.GetChunks().Get(chx, chy)->Render(); all.ApplyTranslation(-chx * CHUNK_SIZE_X, 0, -chy * CHUNK_SIZE_Z); + } } m_shader01.Disable();