#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace deerith { GLFWwindow *window; int frame_id = 0; constexpr double TARGET_FRAME_TIME = 1.0 / 60.0; std::chrono::steady_clock::time_point last_frame_time; std::chrono::steady_clock::time_point frame_start; void init_imgui(); } int deerith::init_window() { if (!glfwInit()) { std::cerr << "Failed to initialize GLFW\n"; return -1; } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); window = glfwCreateWindow( 1280, 720, "Deerith", nullptr, nullptr); if (!window) { std::cerr << "Failed to create GLFW window\n"; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); int version = gladLoadGL(glfwGetProcAddress); if (version == 0) { std::cerr << "Failed to initialize GLAD\n"; glfwDestroyWindow(window); glfwTerminate(); return -1; } glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glFrontFace(GL_CCW); glDisable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); init_imgui(); init_engine_render_specific(); return 0; } bool deerith::is_windows_focused() { return window && glfwGetWindowAttrib(window, GLFW_FOCUSED); } bool deerith::begin_window_display() { glfwPollEvents(); if (glfwWindowShouldClose(window)) { return false; } execute_graphics_functions(); int display_w, display_h; glfwGetFramebufferSize(window, &display_w, &display_h); glViewport(0, 0, display_w, display_h); glBindFramebuffer(GL_FRAMEBUFFER, 0); glClearColor(0.1f, 0.1f, 0.15f, 1.0f); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); return true; } void deerith::finish_window_display() { ImGui::Render(); int display_w, display_h; glfwGetFramebufferSize(window, &display_w, &display_h); glViewport(0, 0, display_w, display_h); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); using clock = std::chrono::steady_clock; const auto now = clock::now(); const std::chrono::duration elapsed = now - last_frame_time; using clock = std::chrono::steady_clock; while (std::chrono::duration( clock::now() - frame_start) .count() < TARGET_FRAME_TIME) { std::this_thread::sleep_for(std::chrono::milliseconds(5)); } frame_id++; glfwSwapBuffers(window); } void deerith::shutdown_window() { ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); shutdown_engine_render_specific(); glfwDestroyWindow(window); glfwTerminate(); } int deerith::get_current_frame_id() { return frame_id; } glm::ivec2 deerith::get_window_size() { glm::ivec2 size; glfwGetWindowSize(window, &size.x, &size.y); return size; } float deerith::get_window_aspect_ratio() { glm::ivec2 size; glfwGetWindowSize(window, &size.x, &size.y); return (float)size.x / (float)size.y; } void deerith::init_imgui() { float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO &io = ImGui::GetIO(); (void)io; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls ImGui::StyleColorsDark(); ImGuiStyle &style = ImGui::GetStyle(); style.ScaleAllSizes(main_scale); style.FontScaleDpi = main_scale; const char *glsl_version = nullptr; ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init(glsl_version); }