Naive chunk meshing

This commit is contained in:
Ben
2019-10-18 21:17:28 +01:00
parent e2043c3b2c
commit ababa43c72
4 changed files with 66 additions and 29 deletions

View File

@@ -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<Chunk>(x, y));

View File

@@ -7,25 +7,31 @@
#include "../world/block.hpp"
#include <random>
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++) {
// Grass on the top layer
if (y == CHUNK_HEIGHT - 1) {
if (y > 15) {
Voxels.push_back((uint8_t)EBlockType::Air);
continue;
}
std::uniform_real_distribution<float> 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> camera, std::shared_ptr<Shader> 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,14 +100,27 @@ 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);
@@ -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);
}

View File

@@ -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<glm::vec3> m_vertices;
int m_numVerts = 0;
std::vector<glm::vec3> m_uvs;

View File

@@ -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<CBlockEntry> block = CBlockDictionary::GetInstance()->BlockEntries[Block];
uint16_t tex = block->FaceTextures[(uint16_t)face];
std::vector<glm::vec3> uvws;
for (auto& uv : uvs) {
uvws.push_back({ uv.x, uv.y, (float)tex });
}
std::vector<glm::vec3> 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());