#include "VoxelGame.h" #include #include // Include stb_image implementation (ensure stb_image.h is in your include path) #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" VoxelGame::VoxelGame() : textureGrass(0), textureDirt(0), textureWood(0) { // Initialize a 16x16x16 voxel grid with zeros voxelData.resize(16, std::vector>(16, std::vector(16, 0))); } VoxelGame::~VoxelGame() { glDeleteTextures(1, &textureGrass); glDeleteTextures(1, &textureDirt); glDeleteTextures(1, &textureWood); } bool VoxelGame::init() { if (!loadTextures()) return false; generateVoxelData(); generateMesh(); return true; } bool VoxelGame::loadTextures() { int width, height, nrChannels; unsigned char *data; // Load grass texture data = stbi_load("grass.png", &width, &height, &nrChannels, 0); if (data) { glGenTextures(1, &textureGrass); glBindTexture(GL_TEXTURE_2D, textureGrass); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, nrChannels == 4 ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); stbi_image_free(data); } else { std::cerr << "Failed to load grass texture\n"; return false; } // Load dirt texture data = stbi_load("dirt.png", &width, &height, &nrChannels, 0); if (data) { glGenTextures(1, &textureDirt); glBindTexture(GL_TEXTURE_2D, textureDirt); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, nrChannels == 4 ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); stbi_image_free(data); } else { std::cerr << "Failed to load dirt texture\n"; return false; } // Load wood texture data = stbi_load("wood.png", &width, &height, &nrChannels, 0); if (data) { glGenTextures(1, &textureWood); glBindTexture(GL_TEXTURE_2D, textureWood); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, nrChannels == 4 ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); stbi_image_free(data); } else { std::cerr << "Failed to load wood texture\n"; return false; } return true; } void VoxelGame::generateVoxelData() { // For demo purposes: // - Fill the bottom layer with grass (value 1) // - Fill the next layer with dirt (value 2) // - Add a couple of wood blocks (value 3) for (int x = 0; x < 16; ++x) { for (int z = 0; z < 16; ++z) { voxelData[x][0][z] = 1; // grass layer voxelData[x][1][z] = 2; // dirt layer } } // Add some wood blocks as an example voxelData[5][2][5] = 3; voxelData[6][2][5] = 3; } void VoxelGame::generateMesh() { // Use the GreedyMesher to create mesh quads from voxel data. meshQuads = GreedyMesher::mesh(voxelData); } void VoxelGame::update(float deltaTime) { // Update game logic (animations, input, physics, etc.) // (This is left minimal for demo purposes) } void VoxelGame::render() { // Here you would typically bind a shader, set uniforms, bind textures, // and render the mesh (e.g. drawing quads as two triangles each). // For this demo, we simply output the number of quads. std::cout << "Rendering " << meshQuads.size() << " quads." << std::endl; // You can extend this function to perform real OpenGL drawing. } void VoxelGame::debugUI() { // Display a debug window using ImGui ImGui::Begin("Debug"); ImGui::Text("Voxel Game Debug Window"); ImGui::Text("Mesh quads count: %d", (int)meshQuads.size()); ImGui::End(); }