small-projects/cpp-voxel-engine/VoxelGame.cpp

131 lines
4.6 KiB
C++
Raw Normal View History

2025-04-06 02:03:23 +00:00
#include "VoxelGame.h"
#include <iostream>
#include <glad/glad.h>
// 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<std::vector<int>>(16, std::vector<int>(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();
}