From 07ebd0d1d1c95a6fa42fb00b0d3dab3f4ee358e6 Mon Sep 17 00:00:00 2001 From: Michael Theall Date: Mon, 6 Apr 2020 22:38:14 -0500 Subject: [PATCH] Refactor as much code out of 3DS backends as possible --- source/3ds/imgui_citro3d.cpp | 80 ++++++++-------------------- source/3ds/imgui_citro3d.h | 6 +-- source/3ds/imgui_ctru.cpp | 20 +------ source/3ds/imgui_ctru.h | 2 - source/3ds/platform.cpp | 97 ++++++++++++++++++++++++++++++---- source/ftpServer.cpp | 2 +- source/linux/platform.cpp | 3 +- source/main.cpp | 4 +- source/switch/imgui_deko3d.cpp | 6 +-- source/switch/imgui_nx.cpp | 4 +- 10 files changed, 125 insertions(+), 99 deletions(-) diff --git a/source/3ds/imgui_citro3d.cpp b/source/3ds/imgui_citro3d.cpp index aee7c6a..4f53957 100644 --- a/source/3ds/imgui_citro3d.cpp +++ b/source/3ds/imgui_citro3d.cpp @@ -36,20 +36,6 @@ namespace /// \brief 3DS font glyph ranges std::vector s_fontRanges; -/// \brief Clear color -constexpr auto CLEAR_COLOR = 0x204B7AFF; - -/// \brief Display transfer flags -constexpr auto DISPLAY_TRANSFER_FLAGS = - GX_TRANSFER_FLIP_VERT (0) | GX_TRANSFER_OUT_TILED (0) | GX_TRANSFER_RAW_COPY (0) | - GX_TRANSFER_IN_FORMAT (GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT (GX_TRANSFER_FMT_RGB8) | - GX_TRANSFER_SCALING (GX_TRANSFER_SCALE_XY); - -/// \brief Top screen render target -C3D_RenderTarget *s_top = nullptr; -/// \brief Bottom screen render target -C3D_RenderTarget *s_bottom = nullptr; - /// \brief Vertex shader DVLB_s *s_vsh = nullptr; /// \brief Vertex shader program @@ -166,22 +152,11 @@ void setupRenderState (gfxScreen_t const screen_) void imgui::citro3d::init () { // setup back-end capabilities flags - ImGuiIO &io = ImGui::GetIO (); + auto &io = ImGui::GetIO (); io.BackendRendererName = "citro3d"; io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; - // initialize citro3d - C3D_Init (C3D_DEFAULT_CMDBUF_SIZE); - - // create top screen render target - s_top = C3D_RenderTargetCreate (480, 800, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); - C3D_RenderTargetSetOutput (s_top, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); - - // create bottom screen render target - s_bottom = C3D_RenderTargetCreate (480, 640, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); - C3D_RenderTargetSetOutput (s_bottom, GFX_BOTTOM, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); - // load vertex shader s_vsh = DVLB_ParseFile ( const_cast (reinterpret_cast (vshader_shbin)), @@ -194,10 +169,6 @@ void imgui::citro3d::init () // get projection matrix uniform location s_projLocation = shaderInstanceGetUniformLocation (s_program.vertexShader, "proj"); - // initialize projection matrices - Mtx_OrthoTilt (&s_projTop, 0.0f, 400.0f, 240.0f, 0.0f, -1.0f, 1.0f, false); - Mtx_OrthoTilt (&s_projBottom, 40.0f, 360.0f, 480.0f, 240.0f, -1.0f, 1.0f, false); - // allocate vertex data buffer s_vtxSize = 65536; s_vtxData = reinterpret_cast (linearAlloc (sizeof (ImDrawVert) * s_vtxSize)); @@ -421,43 +392,38 @@ void imgui::citro3d::exit () // free shader program shaderProgramFree (&s_program); DVLB_Free (s_vsh); - - // free render targets - C3D_RenderTargetDelete (s_bottom); - C3D_RenderTargetDelete (s_top); - - // deinitialize citro3d - C3D_Fini (); } -void imgui::citro3d::newFrame () +void imgui::citro3d::render (C3D_RenderTarget *const top_, C3D_RenderTarget *const bottom_) { -} - -void imgui::citro3d::render () -{ - C3D_FrameBegin (C3D_FRAME_SYNCDRAW); - - // clear frame/depth buffers - C3D_RenderTargetClear (s_top, C3D_CLEAR_ALL, CLEAR_COLOR, 0); - C3D_RenderTargetClear (s_bottom, C3D_CLEAR_ALL, CLEAR_COLOR, 0); - // get draw data auto const drawData = ImGui::GetDrawData (); if (drawData->CmdListsCount <= 0) - { - C3D_FrameEnd (0); return; - } // get framebuffer dimensions unsigned width = drawData->DisplaySize.x * drawData->FramebufferScale.x; unsigned height = drawData->DisplaySize.y * drawData->FramebufferScale.y; if (width <= 0 || height <= 0) - { - C3D_FrameEnd (0); return; - } + + // initialize projection matrices + Mtx_OrthoTilt (&s_projTop, + 0.0f, + drawData->DisplaySize.x, + drawData->DisplaySize.y * 0.5f, + 0.0f, + -1.0f, + 1.0f, + false); + Mtx_OrthoTilt (&s_projBottom, + drawData->DisplaySize.x * 0.1f, + drawData->DisplaySize.x * 0.9f, + drawData->DisplaySize.y, + drawData->DisplaySize.y * 0.5f, + -1.0f, + 1.0f, + false); // check if we need to grow vertex data buffer if (s_vtxSize < static_cast (drawData->TotalVtxCount)) @@ -515,9 +481,9 @@ void imgui::citro3d::render () for (auto const &screen : {GFX_TOP, GFX_BOTTOM}) { if (screen == GFX_TOP) - C3D_FrameDrawOn (s_top); + C3D_FrameDrawOn (top_); else - C3D_FrameDrawOn (s_bottom); + C3D_FrameDrawOn (bottom_); setupRenderState (screen); @@ -725,6 +691,4 @@ void imgui::citro3d::render () offsetIdx += cmdList.IdxBuffer.Size; } } - - C3D_FrameEnd (0); } diff --git a/source/3ds/imgui_citro3d.h b/source/3ds/imgui_citro3d.h index da078e2..7e6d5c6 100644 --- a/source/3ds/imgui_citro3d.h +++ b/source/3ds/imgui_citro3d.h @@ -20,6 +20,8 @@ #pragma once +#include + namespace imgui { namespace citro3d @@ -29,9 +31,7 @@ void init (); /// \brief Deinitialize citro3d void exit (); -/// \brief Prepare citro3d for a new frame -void newFrame (); /// \brief Render ImGui draw list -void render (); +void render (C3D_RenderTarget *top_, C3D_RenderTarget *bottom_); } } diff --git a/source/3ds/imgui_ctru.cpp b/source/3ds/imgui_ctru.cpp index 1a9ab91..8788a7b 100644 --- a/source/3ds/imgui_ctru.cpp +++ b/source/3ds/imgui_ctru.cpp @@ -36,11 +36,6 @@ using namespace std::chrono_literals; namespace { -/// \brief Screen width -constexpr auto SCREEN_WIDTH = 400.0f; -/// \brief Screen height -constexpr auto SCREEN_HEIGHT = 480.0f; - /// \brief Clipboard std::string s_clipboard; @@ -134,10 +129,7 @@ void updateGamepads (ImGuiIO &io_) bool imgui::ctru::init () { - ImGuiIO &io = ImGui::GetIO (); - - // disable imgui.ini file - io.IniFilename = nullptr; + auto &io = ImGui::GetIO (); // setup config flags io.ConfigFlags |= ImGuiConfigFlags_IsTouchScreen; @@ -160,17 +152,13 @@ bool imgui::ctru::init () void imgui::ctru::newFrame () { - ImGuiIO &io = ImGui::GetIO (); + auto &io = ImGui::GetIO (); // check that font was built IM_ASSERT (io.Fonts->IsBuilt () && "Font atlas not built! It is generally built by the renderer back-end. Missing call " "to renderer _NewFrame() function?"); - // setup display metrics - io.DisplaySize = ImVec2 (SCREEN_WIDTH, SCREEN_HEIGHT); - io.DisplayFramebufferScale = ImVec2 (2.0f, 2.0f); - // time step static auto const start = platform::steady_clock::now (); static auto prev = start; @@ -182,7 +170,3 @@ void imgui::ctru::newFrame () updateTouch (io); updateGamepads (io); } - -void imgui::ctru::exit () -{ -} diff --git a/source/3ds/imgui_ctru.h b/source/3ds/imgui_ctru.h index 7e76289..983a06e 100644 --- a/source/3ds/imgui_ctru.h +++ b/source/3ds/imgui_ctru.h @@ -26,8 +26,6 @@ namespace ctru { /// \brief Initialize 3ds platform bool init (); -/// \brief Deinitialize 3ds platform -void exit (); /// \brief Prepare 3ds for a new frame void newFrame (); diff --git a/source/3ds/platform.cpp b/source/3ds/platform.cpp index 7e9ffd8..ec39990 100644 --- a/source/3ds/platform.cpp +++ b/source/3ds/platform.cpp @@ -55,6 +55,45 @@ bool s_socuActive = false; /// \brief soc:u buffer u32 *s_socuBuffer = nullptr; +/// \brief Clear color +constexpr auto CLEAR_COLOR = 0x204B7AFF; + +/// \brief Screen width +constexpr auto SCREEN_WIDTH = 400.0f; +/// \brief Screen height +constexpr auto SCREEN_HEIGHT = 480.0f; + +/// \brief Whether to use anti-aliasing +#define ANTI_ALIAS 1 + +#if ANTI_ALIAS +/// \brief Display transfer scaling +constexpr auto TRANSFER_SCALING = GX_TRANSFER_SCALE_XY; +/// \brief Framebuffer scale +constexpr auto FB_SCALE = 2.0f; +#else +/// \brief Display transfer scaling +constexpr auto TRANSFER_SCALING = GX_TRANSFER_SCALE_NO; +/// \brief Framebuffer scale +constexpr auto FB_SCALE = 1.0f; +#endif + +/// \brief Framebuffer width +constexpr auto FB_WIDTH = SCREEN_WIDTH * FB_SCALE; +/// \brief Framebuffer height +constexpr auto FB_HEIGHT = SCREEN_HEIGHT * FB_SCALE; + +/// \brief Display transfer flags +constexpr auto DISPLAY_TRANSFER_FLAGS = + GX_TRANSFER_FLIP_VERT (0) | GX_TRANSFER_OUT_TILED (0) | GX_TRANSFER_RAW_COPY (0) | + GX_TRANSFER_IN_FORMAT (GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT (GX_TRANSFER_FMT_RGB8) | + GX_TRANSFER_SCALING (TRANSFER_SCALING); + +/// \brief Top screen render target +C3D_RenderTarget *s_top = nullptr; +/// \brief Bottom screen render target +C3D_RenderTarget *s_bottom = nullptr; + /// \brief Texture atlas C3D_Tex s_gfxTexture; /// \brief Texture atlas metadata @@ -94,16 +133,16 @@ void drawLogo () auto subTex = Tex3DS_GetSubTexture (s_gfxT3x, gfx_c3dlogo_idx); // get framebuffer metrics - ImGuiIO &io = ImGui::GetIO (); + auto const &io = ImGui::GetIO (); auto const screenWidth = io.DisplaySize.x; auto const screenHeight = io.DisplaySize.y; auto const logoWidth = subTex->width; auto const logoHeight = subTex->height; // calculate top screen coords - auto const x1 = (screenWidth - logoWidth) / 2.0f; + auto const x1 = (screenWidth - logoWidth) * 0.5f; auto const x2 = x1 + logoWidth; - auto const y1 = (screenHeight / 2.0f - logoHeight) / 2.0f; + auto const y1 = (screenHeight * 0.5f - logoHeight) * 0.5f; auto const y2 = y1 + logoHeight; // calculate uv coords @@ -116,8 +155,8 @@ void drawLogo () // draw to bottom screen ImGui::GetBackgroundDrawList ()->AddImage (&s_gfxTexture, - ImVec2 (x1, y1 + screenHeight / 2.0f), - ImVec2 (x2, y2 + screenHeight / 2.0f), + ImVec2 (x1, y1 + screenHeight * 0.5f), + ImVec2 (x2, y2 + screenHeight * 0.5f), uv1, uv2); } @@ -219,6 +258,19 @@ bool platform::init () std::setvbuf (stderr, nullptr, _IOLBF, 0); #endif + // initialize citro3d + C3D_Init (C3D_DEFAULT_CMDBUF_SIZE); + + // create top screen render target + s_top = + C3D_RenderTargetCreate (FB_HEIGHT * 0.5f, FB_WIDTH, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); + C3D_RenderTargetSetOutput (s_top, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); + + // create bottom screen render target + s_bottom = C3D_RenderTargetCreate ( + FB_HEIGHT * 0.5f, FB_WIDTH * 0.8f, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); + C3D_RenderTargetSetOutput (s_bottom, GFX_BOTTOM, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); + if (!imgui::ctru::init ()) return false; @@ -237,8 +289,13 @@ bool platform::init () C3D_TexSetFilter (&s_gfxTexture, GPU_LINEAR, GPU_LINEAR); } + auto &io = ImGui::GetIO (); + auto &style = ImGui::GetStyle (); + + // disable imgui.ini file + io.IniFilename = nullptr; + // citro3d logo doesn't quite show with the default transparency - auto &style = ImGui::GetStyle (); style.Colors[ImGuiCol_WindowBg].w = 0.8f; style.ScaleAllSizes (0.5f); @@ -257,8 +314,13 @@ bool platform::loop () if (hidKeysDown () & KEY_START) return false; + auto &io = ImGui::GetIO (); + + // setup display metrics + io.DisplaySize = ImVec2 (SCREEN_WIDTH, SCREEN_HEIGHT); + io.DisplayFramebufferScale = ImVec2 (FB_SCALE, FB_SCALE); + imgui::ctru::newFrame (); - imgui::citro3d::newFrame (); ImGui::NewFrame (); return true; @@ -271,16 +333,31 @@ void platform::render () ImGui::Render (); - imgui::citro3d::render (); + C3D_FrameBegin (C3D_FRAME_SYNCDRAW); + + // clear frame/depth buffers + C3D_RenderTargetClear (s_top, C3D_CLEAR_ALL, CLEAR_COLOR, 0); + C3D_RenderTargetClear (s_bottom, C3D_CLEAR_ALL, CLEAR_COLOR, 0); + + imgui::citro3d::render (s_top, s_bottom); + + C3D_FrameEnd (0); } void platform::exit () { + imgui::citro3d::exit (); + + // free graphics Tex3DS_TextureFree (s_gfxT3x); C3D_TexDelete (&s_gfxTexture); - imgui::citro3d::exit (); - imgui::ctru::exit (); + // free render targets + C3D_RenderTargetDelete (s_bottom); + C3D_RenderTargetDelete (s_top); + + // deinitialize citro3d + C3D_Fini (); if (s_socuActive) socExit (); diff --git a/source/ftpServer.cpp b/source/ftpServer.cpp index dc5487f..133d2c0 100644 --- a/source/ftpServer.cpp +++ b/source/ftpServer.cpp @@ -67,7 +67,7 @@ FtpServer::FtpServer (std::uint16_t const port_) void FtpServer::draw () { - ImGuiIO &io = ImGui::GetIO (); + auto const &io = ImGui::GetIO (); auto const width = io.DisplaySize.x; auto const height = io.DisplaySize.y; diff --git a/source/linux/platform.cpp b/source/linux/platform.cpp index 8203053..20c9637 100644 --- a/source/linux/platform.cpp +++ b/source/linux/platform.cpp @@ -154,8 +154,9 @@ bool platform::init () ImGui_ImplGlfw_InitForOpenGL (s_mainWindow.get (), true); ImGui_ImplOpenGL3_Init ("#version 150"); + auto &io = ImGui::GetIO (); + // disable imgui.ini file - ImGuiIO &io = ImGui::GetIO (); io.IniFilename = nullptr; return true; diff --git a/source/main.cpp b/source/main.cpp index 11e37bd..4be8e84 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -38,7 +38,9 @@ int main (int argc_, char *argv_[]) return EXIT_FAILURE; } - auto &style = ImGui::GetStyle (); + auto &style = ImGui::GetStyle (); + + // turn off window rounding style.WindowRounding = 0.0f; auto server = FtpServer::create (5000); diff --git a/source/switch/imgui_deko3d.cpp b/source/switch/imgui_deko3d.cpp index 32bee3e..3f721ac 100644 --- a/source/switch/imgui_deko3d.cpp +++ b/source/switch/imgui_deko3d.cpp @@ -368,9 +368,9 @@ DkCmdList setupRenderState (int const slot_, void imgui::deko3d::init () { - // setup back-end capabilities flags - ImGuiIO &io = ImGui::GetIO (); + auto &io = ImGui::GetIO (); + // setup back-end capabilities flags io.BackendRendererName = "deko3d"; io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; @@ -457,7 +457,7 @@ void imgui::deko3d::newFrame () .create (); // get texture atlas - ImGuiIO &io = ImGui::GetIO (); + auto &io = ImGui::GetIO (); io.Fonts->SetTexID (nullptr); unsigned char *pixels; int width; diff --git a/source/switch/imgui_nx.cpp b/source/switch/imgui_nx.cpp index 3df452c..9aa4e3f 100644 --- a/source/switch/imgui_nx.cpp +++ b/source/switch/imgui_nx.cpp @@ -1589,7 +1589,7 @@ bool saveFontAtlas () bool imgui::nx::init () { - ImGuiIO &io = ImGui::GetIO (); + auto &io = ImGui::GetIO (); if (!loadFontAtlas ()) { @@ -1690,7 +1690,7 @@ bool imgui::nx::init () void imgui::nx::newFrame () { - ImGuiIO &io = ImGui::GetIO (); + auto &io = ImGui::GetIO (); // check that font was built IM_ASSERT (io.Fonts->IsBuilt () &&