Im currently making a voxel game like Minecraft for fun with DirectX11. Game works with chunk system like any other voxel game, but my current algorithm for generating chunk mesh is not expandable. Block class has a few attributes like is block full and mesh type.
class Block
{
public:
bool isFull = true;
MeshType type = MeshType::FullBlock;
Vector2i texture = { 9, 1 };
Vector2i topTexture = { 9, 1 };
const char* sound;
Block(){}
Block(bool isFull, MeshType type, Vector2i texture, Vector2i topTexture, const char* sound): isFull(isFull), type(type), texture(texture), topTexture(topTexture), sound(sound){}
Block(bool isFull, MeshType type, Vector2i texture, const char* sound) : isFull(isFull), type(type), texture(texture), topTexture(texture), sound(sound) {}
Block(bool isFull, MeshType type, Vector2i texture) : isFull(isFull), type(type), texture(texture), topTexture(texture) {}
};
Every block is then initialised in a vector
blocks.reserve(64);
Block air(false, MeshType::Empty, {0 ,0});
blocks.emplace_back(air);
Block grass(true, MeshType::FullBlock, { 3, 0 }, { 0, 0 }, "Audio/grass1.ogg");
blocks.emplace_back(grass);
Block stone(true, MeshType::FullBlock, { 1, 0 }, "Audio/stone1.ogg");
blocks.emplace_back(stone);
Block rose(false, MeshType::Cross, { 12 ,0 }, "Audio/grass1.ogg");
blocks.emplace_back(rose);
Block wheat(false, MeshType::Hash, { 8 ,3 });
blocks.emplace_back(wheat);
//and so on...
I have a function that accepts a vector of vertices and chunk data. That function loops through all the blocks with a few optimisations and emplaces data back into the vector that gets sent to the buffer.
for (int x = 0; x < ChunkWidth; x++)
{
for (int y = 0; y < ChunkHeight; y++)
{
for (int z = 0; z < ChunkWidth; z++)
{
if (IsDrawable[x][y][z] == 1)
{
switch (blocks[chunk->BlockID[x + 16 * y + 16 * 256 * z]].type)
{
case MeshType::FullBlock:
BuildBlock(chunk, vertices, x, y, z);
break;
case MeshType::Cross:
FillCross(vertices, blocks[chunk->BlockID[x + 16 * y + 16 * 256 * z]], x + chunk->x * ChunkWidth, y, z + chunk->z * ChunkWidth);
break;
case MeshType::Hash:
FillHash(vertices, blocks[chunk->BlockID[x + 16 * y + 16 * 256 * z]], x + chunk->x * ChunkWidth, y, z + chunk->z * ChunkWidth);
break;
}
}
}
}
}
With every new mesh type the switch statement gets bigger and I think that is not the way to go. Im asking if there are better ways of doing this. I thank you in advance.
See Question&Answers more detail:os