247 lines
8.0 KiB
C++
247 lines
8.0 KiB
C++
#include <backends/imgui_impl_sdl2.h>
|
|
#include <backends/imgui_impl_sdlrenderer2.h>
|
|
#include <iostream>
|
|
#include "MainWindowSDL2.hpp"
|
|
#include "../gui/gui_exceptions.hpp"
|
|
#include "../common/ougge_format.hpp"
|
|
#include "../common/math.hpp"
|
|
|
|
using namespace ougge::gui;
|
|
|
|
namespace ougge::modules {
|
|
|
|
const std::string& MainWindowSDL2::getName() {
|
|
return ougge_type_name<MainWindowSDL2>();
|
|
}
|
|
|
|
f32 MainWindowSDL2::getDPI(){
|
|
i32 w=0, h=0;
|
|
SDL_GetRendererOutputSize(sdl_renderer, &w, &h);
|
|
i32 sim_w=0, sim_h=0;
|
|
SDL_GetWindowSize(sdl_window, &sim_w, &sim_h);
|
|
f32 wdpi=(f32)w / sim_w;
|
|
f32 hdpi=(f32)h / sim_h;
|
|
f32 dpi=SDL_sqrtf(wdpi*wdpi + hdpi*hdpi);
|
|
return dpi;
|
|
}
|
|
|
|
MainWindowSDL2::MainWindowSDL2(Engine& engine,
|
|
const std::string& window_title,
|
|
resources::ResourceManager& resourceManager)
|
|
: IEngineModule(engine)
|
|
{
|
|
SDL_TRY(SDL_Init(SDL_INIT_EVERYTHING));
|
|
SDL_version v;
|
|
SDL_GetVersion(&v);
|
|
std::cout<<ougge_format("SDL version: %u.%u.%u\n", v.major, v.minor, v.patch);
|
|
|
|
// From 2.0.18: Enable native IME.
|
|
#ifdef SDL_HINT_IME_SHOW_UI
|
|
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
|
|
#endif
|
|
|
|
SDL_WindowFlags window_flags = (SDL_WindowFlags)(
|
|
SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI
|
|
);
|
|
sdl_window = SDL_CreateWindow(window_title.c_str(),
|
|
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
|
1280, 720, window_flags);
|
|
if(sdl_window == nullptr)
|
|
throw SDLException();
|
|
|
|
SDL_RendererFlags renderer_flags = (SDL_RendererFlags)(
|
|
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
|
|
);
|
|
sdl_renderer = SDL_CreateRenderer(sdl_window, -1, renderer_flags);
|
|
if(sdl_renderer == nullptr)
|
|
throw SDLException();
|
|
|
|
SDL_RendererInfo info;
|
|
SDL_GetRendererInfo(sdl_renderer, &info);
|
|
std::cout<<"Current SDL_Renderer driver: "<<info.name<<std::endl;
|
|
|
|
// Setup Dear ImGui context
|
|
IMGUI_CHECKVERSION();
|
|
ImGui::CreateContext();
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
|
io.ConfigDockingTransparentPayload = true;
|
|
io.ConfigInputTextCursorBlink = false;
|
|
// io.ConfigViewportsNoTaskBarIcon = true;
|
|
io.ConfigWindowsMoveFromTitleBarOnly = true;
|
|
|
|
// Setup Platform/Renderer backends
|
|
if(!ImGui_ImplSDL2_InitForSDLRenderer(sdl_window, sdl_renderer))
|
|
throw SDLException();
|
|
if(!ImGui_ImplSDLRenderer2_Init(sdl_renderer))
|
|
throw SDLException();
|
|
|
|
// Setup Dear ImGui style
|
|
ImGui::StyleColorsDark();
|
|
|
|
resources::ResourceFactory* font_res = resourceManager.tryGetResource(default_font_path);
|
|
if(font_res == nullptr)
|
|
throw UsefulException("can't find default font resource");
|
|
f32 dpi = getDPI();
|
|
io.FontDefault = resources::ImFont_LoadFromResource(font_res, default_font_size, dpi);
|
|
}
|
|
|
|
MainWindowSDL2::~MainWindowSDL2(){
|
|
ImGui_ImplSDLRenderer2_Shutdown();
|
|
ImGui_ImplSDL2_Shutdown();
|
|
ImGui::DestroyContext();
|
|
SDL_DestroyRenderer(sdl_renderer);
|
|
SDL_DestroyWindow(sdl_window);
|
|
SDL_Quit();
|
|
}
|
|
|
|
void MainWindowSDL2::pollEvents(){
|
|
SDL_Event event;
|
|
while (SDL_PollEvent(&event)) {
|
|
ImGui_ImplSDL2_ProcessEvent(&event);
|
|
switch(event.type){
|
|
case SDL_QUIT: {
|
|
//TODO: log SDL_QUIT event
|
|
engine.stopLoop();
|
|
break;
|
|
}
|
|
case SDL_WINDOWEVENT: {
|
|
if(event.window.event == SDL_WINDOWEVENT_CLOSE
|
|
&& event.window.windowID == SDL_GetWindowID(sdl_window))
|
|
{
|
|
//TODO: log SDL_WINDOWEVENT event
|
|
engine.stopLoop();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainWindowSDL2::beginFrame(){
|
|
// process events happend since previous frame
|
|
pollEvents();
|
|
|
|
// Start the Dear ImGui frame
|
|
ImGui_ImplSDLRenderer2_NewFrame();
|
|
ImGui_ImplSDL2_NewFrame();
|
|
ImGui::NewFrame();
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
SDL_RenderSetScale(sdl_renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
|
|
SDL_SetRenderDrawColor(sdl_renderer,
|
|
(u8)(clear_color.x * 255),
|
|
(u8)(clear_color.y * 255),
|
|
(u8)(clear_color.z * 255),
|
|
(u8)(clear_color.w * 255));
|
|
SDL_RenderClear(sdl_renderer);
|
|
|
|
draw_bg_window();
|
|
draw_debug_window();
|
|
drawErrorWindow();
|
|
}
|
|
|
|
void MainWindowSDL2::endFrame(){
|
|
ImGui::Render();
|
|
ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), sdl_renderer);
|
|
// Swap buffers
|
|
SDL_RenderPresent(sdl_renderer);
|
|
}
|
|
|
|
void MainWindowSDL2::draw_bg_window(){
|
|
const ImGuiDockNodeFlags dockspace_flags =
|
|
ImGuiDockNodeFlags_PassthruCentralNode;
|
|
const ImGuiWindowFlags window_flags =
|
|
ImGuiWindowFlags_MenuBar |
|
|
ImGuiWindowFlags_NoDocking |
|
|
ImGuiWindowFlags_NoScrollbar |
|
|
ImGuiWindowFlags_NoScrollWithMouse |
|
|
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
|
ImGuiWindowFlags_NoFocusOnAppearing |
|
|
ImGuiWindowFlags_NoMove |
|
|
ImGuiWindowFlags_NoResize |
|
|
ImGuiWindowFlags_NoCollapse |
|
|
ImGuiWindowFlags_NoTitleBar |
|
|
ImGuiWindowFlags_NoBackground;
|
|
// not dockable window that always bound to viewport
|
|
ImGuiViewport* viewport = ImGui::GetWindowViewport();
|
|
ImGui::SetNextWindowPos(viewport->Pos, ImGuiCond_Always);
|
|
ImGui::SetNextWindowSize(viewport->Size, ImGuiCond_Always);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
|
ImGui::Begin("bg_window", nullptr, window_flags);
|
|
ImGui::PopStyleVar(3);
|
|
|
|
// DockSpace
|
|
ImGuiID dockspace_id = ImGui::GetID("bg_dockspace");
|
|
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
|
|
|
// MenuBar
|
|
if(ImGui::BeginMainMenuBar()){
|
|
if(ImGui::BeginMenu("test")){
|
|
if(ImGui::MenuItem("throw exception")){
|
|
ImGui::EndMenu();
|
|
ImGui::EndMainMenuBar();
|
|
ImGui::End();
|
|
throw UsefulException("example exception");
|
|
}
|
|
if(ImGui::MenuItem("throw const char*")){
|
|
ImGui::EndMenu();
|
|
ImGui::EndMainMenuBar();
|
|
ImGui::End();
|
|
throw "cptr";
|
|
}
|
|
if(ImGui::MenuItem("throw std::string")){
|
|
ImGui::EndMenu();
|
|
ImGui::EndMainMenuBar();
|
|
ImGui::End();
|
|
throw std::string("str");
|
|
}
|
|
if(ImGui::MenuItem("throw unknown")){
|
|
ImGui::EndMenu();
|
|
ImGui::EndMainMenuBar();
|
|
ImGui::End();
|
|
throw 111;
|
|
}
|
|
ImGui::EndMenu();
|
|
}
|
|
ImGui::EndMainMenuBar();
|
|
}
|
|
|
|
ImGui::End();
|
|
}
|
|
|
|
void MainWindowSDL2::draw_debug_window(){
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
if(ImGui::Begin("Debug Options", &show_debug_window)){
|
|
ImGui::ColorEdit3("clear_color", (float*)&clear_color);
|
|
ImGui::InputInt("fps_max", (int*)&engine.fps_max);
|
|
ImGui::Text("Application average %.3f ms/frame (%.2f FPS)", 1000.0f / io.Framerate, io.Framerate);
|
|
ImGui::Checkbox("Demo Window", &show_demo_window);
|
|
ImGui::Checkbox("Metrics/Debug Window", &show_metrics_window);
|
|
ImGui::End();
|
|
}
|
|
|
|
if (show_demo_window)
|
|
ImGui::ShowDemoWindow(&show_demo_window);
|
|
|
|
if (show_metrics_window)
|
|
ImGui::ShowMetricsWindow(&show_metrics_window);
|
|
}
|
|
|
|
void MainWindowSDL2::drawErrorWindow(){
|
|
if(engine.error_messages.size() < 1)
|
|
return;
|
|
ImGui::Begin("ERRORS");
|
|
if(ImGui::Button("Clear"))
|
|
engine.error_messages.clear();
|
|
for(auto& msg : engine.error_messages){
|
|
ImGui::TextWrapped("%s", msg.c_str());
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
} |