2025-04-06 02:03:23 +00:00
|
|
|
|
#include <iostream>
|
2025-04-06 03:14:06 +00:00
|
|
|
|
#include <cmath>
|
2025-04-06 02:09:28 +00:00
|
|
|
|
#include <GL/glew.h>
|
2025-04-06 02:03:23 +00:00
|
|
|
|
#include <GLFW/glfw3.h>
|
2025-04-06 03:14:06 +00:00
|
|
|
|
#include <GL/glu.h>
|
2025-04-06 02:03:23 +00:00
|
|
|
|
#include "imgui.h"
|
2025-04-06 03:14:06 +00:00
|
|
|
|
#include "imgui_internal.h" // For Im_PI
|
2025-04-06 02:03:23 +00:00
|
|
|
|
#include "imgui_impl_glfw.h"
|
|
|
|
|
#include "imgui_impl_opengl3.h"
|
2025-04-06 03:14:06 +00:00
|
|
|
|
#include "VoxelGame.h"
|
|
|
|
|
|
|
|
|
|
// Global camera variables.
|
|
|
|
|
float yaw = -90.0f;
|
|
|
|
|
float pitch = 0.0f;
|
|
|
|
|
float lastX = 400.0f, lastY = 300.0f;
|
|
|
|
|
bool firstMouse = true;
|
|
|
|
|
float cameraPos[3] = {32.0f, 32.0f, 80.0f};
|
|
|
|
|
float cameraFront[3] = {0.0f, 0.0f, -1.0f};
|
|
|
|
|
float cameraUp[3] = {0.0f, 1.0f, 0.0f};
|
|
|
|
|
|
|
|
|
|
void mouse_callback(GLFWwindow* window, double xpos, double ypos) {
|
|
|
|
|
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_NORMAL)
|
|
|
|
|
return;
|
|
|
|
|
if (firstMouse) {
|
|
|
|
|
lastX = static_cast<float>(xpos);
|
|
|
|
|
lastY = static_cast<float>(ypos);
|
|
|
|
|
firstMouse = false;
|
|
|
|
|
}
|
|
|
|
|
float xoffset = static_cast<float>(xpos) - lastX;
|
|
|
|
|
float yoffset = lastY - static_cast<float>(ypos);
|
|
|
|
|
lastX = static_cast<float>(xpos);
|
|
|
|
|
lastY = static_cast<float>(ypos);
|
|
|
|
|
|
|
|
|
|
float sensitivity = 0.1f;
|
|
|
|
|
xoffset *= sensitivity;
|
|
|
|
|
yoffset *= sensitivity;
|
|
|
|
|
|
|
|
|
|
yaw += xoffset;
|
|
|
|
|
pitch += yoffset;
|
|
|
|
|
if (pitch > 89.0f) pitch = 89.0f;
|
|
|
|
|
if (pitch < -89.0f) pitch = -89.0f;
|
|
|
|
|
|
|
|
|
|
float radYaw = yaw * static_cast<float>(IM_PI) / 180.0f;
|
|
|
|
|
float radPitch = pitch * static_cast<float>(IM_PI) / 180.0f;
|
|
|
|
|
|
|
|
|
|
cameraFront[0] = cos(radYaw) * cos(radPitch);
|
|
|
|
|
cameraFront[1] = sin(radPitch);
|
|
|
|
|
cameraFront[2] = sin(radYaw) * cos(radPitch);
|
|
|
|
|
float len = std::sqrt(cameraFront[0]*cameraFront[0] +
|
|
|
|
|
cameraFront[1]*cameraFront[1] +
|
|
|
|
|
cameraFront[2]*cameraFront[2]);
|
|
|
|
|
cameraFront[0] /= len;
|
|
|
|
|
cameraFront[1] /= len;
|
|
|
|
|
cameraFront[2] /= len;
|
|
|
|
|
}
|
2025-04-06 02:03:23 +00:00
|
|
|
|
|
|
|
|
|
GLFWwindow* initWindow(int width, int height, const char* title) {
|
|
|
|
|
if (!glfwInit()) {
|
|
|
|
|
std::cerr << "Failed to initialize GLFW\n";
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
|
|
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
2025-04-06 03:14:06 +00:00
|
|
|
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
|
2025-04-06 02:03:23 +00:00
|
|
|
|
GLFWwindow* window = glfwCreateWindow(width, height, title, nullptr, nullptr);
|
|
|
|
|
if (!window) {
|
|
|
|
|
std::cerr << "Failed to create GLFW window\n";
|
|
|
|
|
glfwTerminate();
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
glfwMakeContextCurrent(window);
|
2025-04-06 03:14:06 +00:00
|
|
|
|
glfwSetCursorPosCallback(window, mouse_callback);
|
|
|
|
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
2025-04-06 02:09:28 +00:00
|
|
|
|
|
2025-04-06 03:14:06 +00:00
|
|
|
|
glewExperimental = GL_TRUE;
|
|
|
|
|
if (glewInit() != GLEW_OK) {
|
|
|
|
|
std::cerr << "GLEW Error\n";
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
2025-04-06 02:03:23 +00:00
|
|
|
|
return window;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
GLFWwindow* window = initWindow(800, 600, "Voxel Game");
|
|
|
|
|
if (!window)
|
|
|
|
|
return -1;
|
2025-04-06 03:14:06 +00:00
|
|
|
|
|
2025-04-06 02:03:23 +00:00
|
|
|
|
IMGUI_CHECKVERSION();
|
|
|
|
|
ImGui::CreateContext();
|
2025-04-06 03:14:06 +00:00
|
|
|
|
ImGuiIO &io = ImGui::GetIO(); (void)io;
|
2025-04-06 02:03:23 +00:00
|
|
|
|
ImGui::StyleColorsDark();
|
|
|
|
|
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
|
|
|
|
ImGui_ImplOpenGL3_Init("#version 330");
|
2025-04-06 03:14:06 +00:00
|
|
|
|
|
2025-04-06 02:03:23 +00:00
|
|
|
|
VoxelGame game;
|
|
|
|
|
if (!game.init()) {
|
|
|
|
|
std::cerr << "Failed to initialize game\n";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2025-04-06 03:14:06 +00:00
|
|
|
|
|
|
|
|
|
float deltaTime = 0.0f, lastFrame = 0.0f;
|
|
|
|
|
static bool cursorEnabled = false;
|
|
|
|
|
static bool f1Pressed = false;
|
|
|
|
|
|
2025-04-06 02:03:23 +00:00
|
|
|
|
while (!glfwWindowShouldClose(window)) {
|
2025-04-06 03:14:06 +00:00
|
|
|
|
float currentFrame = static_cast<float>(glfwGetTime());
|
|
|
|
|
deltaTime = currentFrame - lastFrame;
|
|
|
|
|
lastFrame = currentFrame;
|
2025-04-06 02:03:23 +00:00
|
|
|
|
glfwPollEvents();
|
2025-04-06 03:14:06 +00:00
|
|
|
|
|
|
|
|
|
// Toggle cursor lock with F1 (if ImGui isn’t capturing the mouse).
|
|
|
|
|
if (glfwGetKey(window, GLFW_KEY_F1) == GLFW_PRESS && !ImGui::GetIO().WantCaptureMouse) {
|
|
|
|
|
if (!f1Pressed) {
|
|
|
|
|
cursorEnabled = !cursorEnabled;
|
|
|
|
|
glfwSetInputMode(window, GLFW_CURSOR, cursorEnabled ? GLFW_CURSOR_NORMAL : GLFW_CURSOR_DISABLED);
|
|
|
|
|
f1Pressed = true;
|
|
|
|
|
firstMouse = true;
|
|
|
|
|
}
|
|
|
|
|
} else if (glfwGetKey(window, GLFW_KEY_F1) == GLFW_RELEASE) {
|
|
|
|
|
f1Pressed = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float cameraSpeed = 5.0f * deltaTime;
|
|
|
|
|
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
|
|
|
|
|
cameraPos[0] += cameraFront[0] * cameraSpeed;
|
|
|
|
|
cameraPos[1] += cameraFront[1] * cameraSpeed;
|
|
|
|
|
cameraPos[2] += cameraFront[2] * cameraSpeed;
|
|
|
|
|
}
|
|
|
|
|
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
|
|
|
|
|
cameraPos[0] -= cameraFront[0] * cameraSpeed;
|
|
|
|
|
cameraPos[1] -= cameraFront[1] * cameraSpeed;
|
|
|
|
|
cameraPos[2] -= cameraFront[2] * cameraSpeed;
|
|
|
|
|
}
|
|
|
|
|
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
|
|
|
|
|
float right[3] = {
|
|
|
|
|
cameraFront[1]*cameraUp[2] - cameraFront[2]*cameraUp[1],
|
|
|
|
|
cameraFront[2]*cameraUp[0] - cameraFront[0]*cameraUp[2],
|
|
|
|
|
cameraFront[0]*cameraUp[1] - cameraFront[1]*cameraUp[0]
|
|
|
|
|
};
|
|
|
|
|
float rLen = std::sqrt(right[0]*right[0] + right[1]*right[1] + right[2]*right[2]);
|
|
|
|
|
right[0] /= rLen; right[1] /= rLen; right[2] /= rLen;
|
|
|
|
|
cameraPos[0] -= right[0] * cameraSpeed;
|
|
|
|
|
cameraPos[1] -= right[1] * cameraSpeed;
|
|
|
|
|
cameraPos[2] -= right[2] * cameraSpeed;
|
|
|
|
|
}
|
|
|
|
|
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
|
|
|
|
|
float right[3] = {
|
|
|
|
|
cameraFront[1]*cameraUp[2] - cameraFront[2]*cameraUp[1],
|
|
|
|
|
cameraFront[2]*cameraUp[0] - cameraFront[0]*cameraUp[2],
|
|
|
|
|
cameraFront[0]*cameraUp[1] - cameraFront[1]*cameraUp[0]
|
|
|
|
|
};
|
|
|
|
|
float rLen = std::sqrt(right[0]*right[0] + right[1]*right[1] + right[2]*right[2]);
|
|
|
|
|
right[0] /= rLen; right[1] /= rLen; right[2] /= rLen;
|
|
|
|
|
cameraPos[0] += right[0] * cameraSpeed;
|
|
|
|
|
cameraPos[1] += right[1] * cameraSpeed;
|
|
|
|
|
cameraPos[2] += right[2] * cameraSpeed;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-06 02:03:23 +00:00
|
|
|
|
ImGui_ImplOpenGL3_NewFrame();
|
|
|
|
|
ImGui_ImplGlfw_NewFrame();
|
|
|
|
|
ImGui::NewFrame();
|
2025-04-06 03:14:06 +00:00
|
|
|
|
|
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
|
|
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
|
glLoadIdentity();
|
|
|
|
|
gluPerspective(45.0, 800.0/600.0, 0.1, 200.0);
|
|
|
|
|
|
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
|
glLoadIdentity();
|
|
|
|
|
float centerX = cameraPos[0] + cameraFront[0];
|
|
|
|
|
float centerY = cameraPos[1] + cameraFront[1];
|
|
|
|
|
float centerZ = cameraPos[2] + cameraFront[2];
|
|
|
|
|
gluLookAt(cameraPos[0], cameraPos[1], cameraPos[2],
|
|
|
|
|
centerX, centerY, centerZ,
|
|
|
|
|
cameraUp[0], cameraUp[1], cameraUp[2]);
|
|
|
|
|
|
|
|
|
|
game.update(deltaTime, cameraPos);
|
|
|
|
|
game.render();
|
2025-04-06 02:03:23 +00:00
|
|
|
|
game.debugUI();
|
2025-04-06 03:14:06 +00:00
|
|
|
|
|
2025-04-06 02:03:23 +00:00
|
|
|
|
ImGui::Render();
|
|
|
|
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
|
|
|
|
glfwSwapBuffers(window);
|
|
|
|
|
}
|
2025-04-06 03:14:06 +00:00
|
|
|
|
|
2025-04-06 02:03:23 +00:00
|
|
|
|
ImGui_ImplOpenGL3_Shutdown();
|
|
|
|
|
ImGui_ImplGlfw_Shutdown();
|
|
|
|
|
ImGui::DestroyContext();
|
|
|
|
|
glfwDestroyWindow(window);
|
|
|
|
|
glfwTerminate();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|