2026-10-04 22:45:06 +02:00

178 lines
3.7 KiB
C++

#include "deerith/graphics/window.h"
#include "primitive_internals.h"
#include <glad/gl.h>
#include <GLFW/glfw3.h>
#include <imgui.h>
#include <backends/imgui_impl_glfw.h>
#include <backends/imgui_impl_opengl3.h>
#include <chrono>
#include <thread>
#include <iostream>
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_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
init_primitives();
init_imgui();
return 0;
}
bool deerith::begin_window_display()
{
glfwPollEvents();
if (glfwWindowShouldClose(window))
{
return false;
}
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<double> elapsed = now - last_frame_time;
using clock = std::chrono::steady_clock;
while (std::chrono::duration<double>(
clock::now() - frame_start)
.count() < TARGET_FRAME_TIME)
{
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
frame_id++;
glfwSwapBuffers(window);
glClearColor(0.1f, 0.1f, 0.15f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
void deerith::shutdown_window()
{
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
shutdown_primitives();
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);
}