131 lines
4.6 KiB
C++
131 lines
4.6 KiB
C++
|
#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();
|
||
|
}
|