diff --git a/src/game.cpp b/src/game.cpp index 9779104..b0b8bdc 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -71,6 +71,7 @@ void Game::Setup(int w, int h) { // Load OpenGL gladLoadGLLoader(SDL_GL_GetProcAddress); glEnable(GL_MULTISAMPLE); + // glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glEnable(GL_DEPTH_TEST); // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); @@ -91,7 +92,8 @@ void Game::Setup(int w, int h) { Texture texture; m_world->TextureID = texture.LoadTextures(BlockDictionary->Textures); - for (int x = 0; x < 3; x++) + + for (int x = 0; x < 2; x++) for (int y = 0; y < 3; y++) { m_world->Chunks.push_back(std::make_shared(x, y)); diff --git a/src/renderer/chunk.cpp b/src/renderer/chunk.cpp index 30eac84..469ba69 100644 --- a/src/renderer/chunk.cpp +++ b/src/renderer/chunk.cpp @@ -7,25 +7,31 @@ #include "../world/block.hpp" +#include + Chunk::Chunk(int x, int z) { m_model = glm::translate(glm::mat4(1.0f), { x * CHUNK_WIDTH, 0, z * CHUNK_DEPTH }); + std::default_random_engine generator; + // [x + WIDTH * (y + HEIGHT * z)] for (int x = 0; x < CHUNK_WIDTH; x++) for (int y = 0; y < CHUNK_HEIGHT; y++) for (int z = 0; z < CHUNK_DEPTH; z++) { + + if (y > 15) { + Voxels.push_back((uint8_t)EBlockType::Air); + continue; + } - // Grass on the top layer - if (y == CHUNK_HEIGHT - 1) { + std::uniform_real_distribution distribution(0, 1); + float r = distribution(generator); + if (r > 0.5f) Voxels.push_back((uint8_t)EBlockType::Grass); - - } else { - - Voxels.push_back((uint8_t)EBlockType::Dirt); - - } + else + Voxels.push_back((uint8_t)EBlockType::Air); } @@ -58,7 +64,7 @@ void Chunk::Render(std::shared_ptr camera, std::shared_ptr shade GLint uniProj = glGetUniformLocation(shader->Program, "proj"); glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(camera->GetProjectionMatrix())); - glDrawArrays(GL_TRIANGLES, 0, m_vertices.size()); + glDrawArrays(GL_TRIANGLES, 0, m_numVerts); } @@ -70,12 +76,21 @@ void Chunk::Update() { uint8_t Chunk::BlockAt(int x, int y, int z) { + if (x > CHUNK_WIDTH - 1) return 0; + if (y > CHUNK_HEIGHT - 1) return 0; + if (z > CHUNK_DEPTH - 1) return 0; + + if (x < 0) return 0; + if (y < 0) return 0; + if (z < 0) return 0; + return Voxels[x + CHUNK_WIDTH * (y + CHUNK_HEIGHT * z)]; } void Chunk::m_mesh() { + // TODO: Use greedy meshing for MAXIMUM performance for (int x = 0; x < CHUNK_WIDTH; x++) for (int y = 0; y < CHUNK_HEIGHT; y++) for (int z = 0; z < CHUNK_DEPTH; z++) { @@ -85,15 +100,28 @@ void Chunk::m_mesh() { uint8_t block = BlockAt(x, y, z); - Voxel tmp({x, y, z}, BlockAt(x, y, z)); + if (block == EBlockType::Air) continue; - tmp.AddFace(EFaceType::Top); - tmp.AddFace(EFaceType::Bottom); - tmp.AddFace(EFaceType::Left); - tmp.AddFace(EFaceType::Right); - tmp.AddFace(EFaceType::Front); - tmp.AddFace(EFaceType::Back); + Voxel tmp({x, y, z}, block); + if (BlockAt(x + 1, y, z) == EBlockType::Air) + tmp.AddFace(EFaceType::Right); + + if (BlockAt(x - 1, y, z) == EBlockType::Air) + tmp.AddFace(EFaceType::Left); + + if (BlockAt(x, y + 1, z) == EBlockType::Air) + tmp.AddFace(EFaceType::Top); + + if (BlockAt(x, y - 1, z) == EBlockType::Air) + tmp.AddFace(EFaceType::Bottom); + + if (BlockAt(x, y, z + 1) == EBlockType::Air) + tmp.AddFace(EFaceType::Front); + + if (BlockAt(x, y, z - 1) == EBlockType::Air) + tmp.AddFace(EFaceType::Back); + tmp.GetMesh(tempVerts, tempUVs); m_vertices.insert(m_vertices.end(), tempVerts.begin(), tempVerts.end()); @@ -111,6 +139,8 @@ void Chunk::m_mesh() { data.insert(data.end(), m_vertices.begin(), m_vertices.end()); data.insert(data.end(), m_uvs.begin(), m_uvs.end()); + m_numVerts = m_vertices.size(); + glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(glm::vec3), &data[0], GL_STATIC_DRAW); glEnableVertexAttribArray(0); @@ -119,6 +149,9 @@ void Chunk::m_mesh() { glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (const void*)(m_vertices.size() * sizeof(glm::vec3))); + m_vertices.clear(); + m_uvs.clear(); + glBindVertexArray(0); } diff --git a/src/renderer/chunk.hpp b/src/renderer/chunk.hpp index bf3a2ab..3126f50 100644 --- a/src/renderer/chunk.hpp +++ b/src/renderer/chunk.hpp @@ -3,7 +3,7 @@ #include "../common.hpp" -#define CHUNK_HEIGHT 32 +#define CHUNK_HEIGHT 128 #define CHUNK_WIDTH 16 #define CHUNK_DEPTH 16 @@ -40,6 +40,8 @@ private: glm::mat4 m_model; std::vector m_vertices; + int m_numVerts = 0; + std::vector m_uvs; diff --git a/src/renderer/voxel.cpp b/src/renderer/voxel.cpp index 11c691b..8f85391 100644 --- a/src/renderer/voxel.cpp +++ b/src/renderer/voxel.cpp @@ -21,8 +21,8 @@ Voxel::Voxel(glm::vec3 coordsInChunk, uint8_t block) { void Voxel::AddFace(EFaceType::Face face) { - std::vector verts; - std::vector uvs; + std::vector verts; + std::vector uvs; switch (face) { @@ -86,18 +86,18 @@ void Voxel::AddFace(EFaceType::Face face) { verts = m_translateIntoChunk(verts, m_coordsInChunk); m_vertices.insert(m_vertices.end(), verts.begin(), verts.end()); - std::shared_ptr block = CBlockDictionary::GetInstance()->BlockEntries[Block]; uint16_t tex = block->FaceTextures[(uint16_t)face]; - std::vector uvws; - - for (auto& uv : uvs) { - - uvws.push_back({ uv.x, uv.y, (float)tex }); - - } + std::vector uvws = { + { uvs[0].x, uvs[0].y, (float)tex }, + { uvs[1].x, uvs[1].y, (float)tex }, + { uvs[2].x, uvs[2].y, (float)tex }, + { uvs[3].x, uvs[3].y, (float)tex }, + { uvs[4].x, uvs[4].y, (float)tex }, + { uvs[5].x, uvs[5].y, (float)tex }, + }; m_uvs.insert(m_uvs.end(), uvws.begin(), uvws.end()); @@ -111,7 +111,7 @@ void Voxel::GetMesh(std::vector& verts, std::vector& uvs) } std::vector Voxel::m_translateIntoChunk(std::vector verts, glm::vec3 trans) { - + for (int i = 0; i < verts.size(); i++) { verts[i].x += trans.x;