/* * -------------------------------------------------------------------------- * * ___________ ____ ____.__ * \__ ___/______________________\ \ / /|__| _________________ * | |_/ __ \_ __ \_ __ \__ \\ Y / | |/ ___/ _ \_ __ \ * | |\ ___/| | \/| | \// __ \\ / | |\___ ( <_> ) | \/ * |____| \___ >__| |__| (____ /\___/ |__/____ >____/|__| * \/ \/ \/ * * TerraVisor * Dynamic Terrain Visualization * * -------------------------------------------------------------------------- * Author: Jack Christensen * Version: 0.0.1 * * Description: * TerraVisor is a dynamic terrain visualization tool that uses real-world elevation * data to render high-fidelity 3D landscapes. It leverages tessellation shaders * to provide detailed and adaptive terrain rendering. * * License: * This project is licensed under the GNU General Public License v3.0. * See the COPYING file for more details. */ #include #include #include #include #include #include #include #include #include "callbacks.h" #include "scene.h" namespace { const int kInitWindowWidth = 1280; const int kInitWindowHeight = 720; const int kTargetFps = 60; const auto kFrameDuration = std::chrono::milliseconds(1000 / kTargetFps); bool InitializeGlfw() { if (!glfwInit()) { std::cerr << "Failed to initialize GLFW" << std::endl; return false; } return true; } GLFWwindow* CreateGlfwWindow() { #ifdef _DEBUG glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); #endif GLFWwindow* window = glfwCreateWindow(kInitWindowWidth, kInitWindowHeight, "TerraVisor", nullptr, nullptr); if (!window) { std::cerr << "Failed to create GLFW window" << std::endl; glfwTerminate(); return nullptr; } glfwMakeContextCurrent(window); return window; } bool InitializeGlew() { glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { std::cerr << "Failed to initialize GLEW" << std::endl; return false; } return true; } void InitializeImGui(GLFWwindow* window) { IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init("#version 150"); } void CleanupImGui() { ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); } void MainLoop(GLFWwindow* window, Scene& scene) { auto last_frame_time = std::chrono::high_resolution_clock::now(); while (!glfwWindowShouldClose(window)) { auto frame_start = std::chrono::high_resolution_clock::now(); scene.Idle(); scene.Display(window); glfwPollEvents(); auto frame_end = std::chrono::high_resolution_clock::now(); auto frame_duration = frame_end - frame_start; if (frame_duration < kFrameDuration) { std::this_thread::sleep_for(kFrameDuration - frame_duration); } auto current_frame_time = std::chrono::high_resolution_clock::now(); auto actual_frame_duration = std::chrono::duration_cast(current_frame_time - last_frame_time).count(); last_frame_time = current_frame_time; } } } // namespace int main() { if (!InitializeGlfw()) return -1; GLFWwindow* window = CreateGlfwWindow(); if (!window) return -1; if (!InitializeGlew()) return -1; Scene scene(kInitWindowWidth, kInitWindowHeight); Callbacks::Register(window, &scene); scene.Init(); InitializeImGui(window); MainLoop(window, scene); CleanupImGui(); glfwDestroyWindow(window); glfwTerminate(); return 0; }