small-projects/cpp-voxel-engine/main.cpp
OusmBlueNinja 58962e52fc Broken
2025-04-05 23:20:54 -05:00

165 lines
4.8 KiB
C++

#include <iostream>
#include <cmath>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"
#include "VoxelGame.h"
// camera globals
static glm::vec3 cameraPos = {32.0f, 32.0f, 80.0f};
static glm::vec3 cameraFront = {0.0f, 0.0f, -1.0f};
static glm::vec3 cameraUp = {0.0f, 1.0f, 0.0f};
static float yaw = -90.0f, pitch = 0.0f;
static bool firstMouse = true;
static float lastX, lastY;
static void mouse_callback(GLFWwindow* window, double xpos, double ypos) {
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_NORMAL)
return; // do not rotate if cursor is free
if (firstMouse) {
lastX = float(xpos);
lastY = float(ypos);
firstMouse = false;
}
float dx = float(xpos) - lastX;
float dy = lastY - float(ypos);
lastX = float(xpos);
lastY = float(ypos);
const float sensitivity = 0.1f;
dx *= sensitivity;
dy *= sensitivity;
yaw += dx;
pitch += dy;
pitch = std::clamp(pitch, -89.0f, 89.0f);
float ry = glm::radians(yaw);
float rp = glm::radians(pitch);
cameraFront = glm::normalize(glm::vec3(
cos(ry)*cos(rp),
sin(rp),
sin(ry)*cos(rp)
));
}
static GLFWwindow* initWindow(int w, int h, const char* title) {
if (!glfwInit()) return nullptr;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
#endif
GLFWwindow* win = glfwCreateWindow(w, h, title, nullptr, nullptr);
if (!win) { glfwTerminate(); return nullptr; }
glfwMakeContextCurrent(win);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
glfwDestroyWindow(win);
glfwTerminate();
return nullptr;
}
glViewport(0, 0, w, h);
glfwSetCursorPosCallback(win, mouse_callback);
// start with cursor disabled
glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
lastX = w / 2.0f;
lastY = h / 2.0f;
return win;
}
int main() {
const int SCR_W = 1280, SCR_H = 720;
GLFWwindow* window = initWindow(SCR_W, SCR_H, "Voxel CSM");
if (!window) return -1;
// ImGui
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 330");
ImGui::StyleColorsDark();
// Our game
VoxelGame game;
if (!game.init(SCR_W, SCR_H)) {
std::cerr << "Failed to init VoxelGame\n";
return -1;
}
float lastFrame = 0.0f;
bool cursorEnabled = false;
bool f1Pressed = false;
while (!glfwWindowShouldClose(window)) {
float now = float(glfwGetTime());
float dt = now - lastFrame;
lastFrame = now;
glfwPollEvents();
// Toggle cursor with F1 (when ImGui not capturing)
ImGuiIO& io = ImGui::GetIO();
if (glfwGetKey(window, GLFW_KEY_F1) == GLFW_PRESS && !io.WantCaptureMouse) {
if (!f1Pressed) {
cursorEnabled = !cursorEnabled;
glfwSetInputMode(window, GLFW_CURSOR,
cursorEnabled ? GLFW_CURSOR_NORMAL : GLFW_CURSOR_DISABLED);
f1Pressed = true;
firstMouse = true; // reset for mouse callback
}
} else if (glfwGetKey(window, GLFW_KEY_F1) == GLFW_RELEASE) {
f1Pressed = false;
}
// WASD movement
float speed = 5.0f * dt;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
cameraPos += cameraFront * speed;
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
cameraPos -= cameraFront * speed;
glm::vec3 right = glm::normalize(glm::cross(cameraFront, cameraUp));
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
cameraPos -= right * speed;
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
cameraPos += right * speed;
// Build view/proj
glm::mat4 view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
glm::mat4 proj = glm::perspective(glm::radians(45.0f),
float(SCR_W)/SCR_H, 0.1f, 200.0f);
// Update & render
game.update(dt, cameraPos);
game.render(view, proj);
// Debug UI
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
game.debugUI();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
}
// Cleanup
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}