194 lines
6.8 KiB
C++
194 lines
6.8 KiB
C++
#include <iostream>
|
||
#include <cmath>
|
||
#include <GL/glew.h>
|
||
#include <GLFW/glfw3.h>
|
||
#include <GL/glu.h>
|
||
#include "imgui.h"
|
||
#include "imgui_internal.h" // For Im_PI
|
||
#include "imgui_impl_glfw.h"
|
||
#include "imgui_impl_opengl3.h"
|
||
#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;
|
||
}
|
||
|
||
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);
|
||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
|
||
GLFWwindow* window = glfwCreateWindow(width, height, title, nullptr, nullptr);
|
||
if (!window) {
|
||
std::cerr << "Failed to create GLFW window\n";
|
||
glfwTerminate();
|
||
return nullptr;
|
||
}
|
||
glfwMakeContextCurrent(window);
|
||
glfwSetCursorPosCallback(window, mouse_callback);
|
||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||
|
||
glewExperimental = GL_TRUE;
|
||
if (glewInit() != GLEW_OK) {
|
||
std::cerr << "GLEW Error\n";
|
||
return nullptr;
|
||
}
|
||
return window;
|
||
}
|
||
|
||
int main() {
|
||
GLFWwindow* window = initWindow(800, 600, "Voxel Game");
|
||
if (!window)
|
||
return -1;
|
||
|
||
IMGUI_CHECKVERSION();
|
||
ImGui::CreateContext();
|
||
ImGuiIO &io = ImGui::GetIO(); (void)io;
|
||
ImGui::StyleColorsDark();
|
||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||
ImGui_ImplOpenGL3_Init("#version 330");
|
||
|
||
VoxelGame game;
|
||
if (!game.init()) {
|
||
std::cerr << "Failed to initialize game\n";
|
||
return -1;
|
||
}
|
||
|
||
float deltaTime = 0.0f, lastFrame = 0.0f;
|
||
static bool cursorEnabled = false;
|
||
static bool f1Pressed = false;
|
||
|
||
while (!glfwWindowShouldClose(window)) {
|
||
float currentFrame = static_cast<float>(glfwGetTime());
|
||
deltaTime = currentFrame - lastFrame;
|
||
lastFrame = currentFrame;
|
||
glfwPollEvents();
|
||
|
||
// 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;
|
||
}
|
||
|
||
ImGui_ImplOpenGL3_NewFrame();
|
||
ImGui_ImplGlfw_NewFrame();
|
||
ImGui::NewFrame();
|
||
|
||
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();
|
||
game.debugUI();
|
||
|
||
ImGui::Render();
|
||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||
glfwSwapBuffers(window);
|
||
}
|
||
|
||
ImGui_ImplOpenGL3_Shutdown();
|
||
ImGui_ImplGlfw_Shutdown();
|
||
ImGui::DestroyContext();
|
||
glfwDestroyWindow(window);
|
||
glfwTerminate();
|
||
return 0;
|
||
}
|