Refactor as much code out of 3DS backends as possible

This commit is contained in:
Michael Theall 2020-04-06 22:38:14 -05:00
parent e8b62be621
commit 07ebd0d1d1
10 changed files with 125 additions and 99 deletions

View File

@ -36,20 +36,6 @@ namespace
/// \brief 3DS font glyph ranges /// \brief 3DS font glyph ranges
std::vector<ImWchar> s_fontRanges; std::vector<ImWchar> 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 /// \brief Vertex shader
DVLB_s *s_vsh = nullptr; DVLB_s *s_vsh = nullptr;
/// \brief Vertex shader program /// \brief Vertex shader program
@ -166,22 +152,11 @@ void setupRenderState (gfxScreen_t const screen_)
void imgui::citro3d::init () void imgui::citro3d::init ()
{ {
// setup back-end capabilities flags // setup back-end capabilities flags
ImGuiIO &io = ImGui::GetIO (); auto &io = ImGui::GetIO ();
io.BackendRendererName = "citro3d"; io.BackendRendererName = "citro3d";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; 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 // load vertex shader
s_vsh = DVLB_ParseFile ( s_vsh = DVLB_ParseFile (
const_cast<std::uint32_t *> (reinterpret_cast<std::uint32_t const *> (vshader_shbin)), const_cast<std::uint32_t *> (reinterpret_cast<std::uint32_t const *> (vshader_shbin)),
@ -194,10 +169,6 @@ void imgui::citro3d::init ()
// get projection matrix uniform location // get projection matrix uniform location
s_projLocation = shaderInstanceGetUniformLocation (s_program.vertexShader, "proj"); 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 // allocate vertex data buffer
s_vtxSize = 65536; s_vtxSize = 65536;
s_vtxData = reinterpret_cast<ImDrawVert *> (linearAlloc (sizeof (ImDrawVert) * s_vtxSize)); s_vtxData = reinterpret_cast<ImDrawVert *> (linearAlloc (sizeof (ImDrawVert) * s_vtxSize));
@ -421,43 +392,38 @@ void imgui::citro3d::exit ()
// free shader program // free shader program
shaderProgramFree (&s_program); shaderProgramFree (&s_program);
DVLB_Free (s_vsh); 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 // get draw data
auto const drawData = ImGui::GetDrawData (); auto const drawData = ImGui::GetDrawData ();
if (drawData->CmdListsCount <= 0) if (drawData->CmdListsCount <= 0)
{
C3D_FrameEnd (0);
return; return;
}
// get framebuffer dimensions // get framebuffer dimensions
unsigned width = drawData->DisplaySize.x * drawData->FramebufferScale.x; unsigned width = drawData->DisplaySize.x * drawData->FramebufferScale.x;
unsigned height = drawData->DisplaySize.y * drawData->FramebufferScale.y; unsigned height = drawData->DisplaySize.y * drawData->FramebufferScale.y;
if (width <= 0 || height <= 0) if (width <= 0 || height <= 0)
{
C3D_FrameEnd (0);
return; 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 // check if we need to grow vertex data buffer
if (s_vtxSize < static_cast<std::size_t> (drawData->TotalVtxCount)) if (s_vtxSize < static_cast<std::size_t> (drawData->TotalVtxCount))
@ -515,9 +481,9 @@ void imgui::citro3d::render ()
for (auto const &screen : {GFX_TOP, GFX_BOTTOM}) for (auto const &screen : {GFX_TOP, GFX_BOTTOM})
{ {
if (screen == GFX_TOP) if (screen == GFX_TOP)
C3D_FrameDrawOn (s_top); C3D_FrameDrawOn (top_);
else else
C3D_FrameDrawOn (s_bottom); C3D_FrameDrawOn (bottom_);
setupRenderState (screen); setupRenderState (screen);
@ -725,6 +691,4 @@ void imgui::citro3d::render ()
offsetIdx += cmdList.IdxBuffer.Size; offsetIdx += cmdList.IdxBuffer.Size;
} }
} }
C3D_FrameEnd (0);
} }

View File

@ -20,6 +20,8 @@
#pragma once #pragma once
#include <citro3d.h>
namespace imgui namespace imgui
{ {
namespace citro3d namespace citro3d
@ -29,9 +31,7 @@ void init ();
/// \brief Deinitialize citro3d /// \brief Deinitialize citro3d
void exit (); void exit ();
/// \brief Prepare citro3d for a new frame
void newFrame ();
/// \brief Render ImGui draw list /// \brief Render ImGui draw list
void render (); void render (C3D_RenderTarget *top_, C3D_RenderTarget *bottom_);
} }
} }

View File

@ -36,11 +36,6 @@ using namespace std::chrono_literals;
namespace namespace
{ {
/// \brief Screen width
constexpr auto SCREEN_WIDTH = 400.0f;
/// \brief Screen height
constexpr auto SCREEN_HEIGHT = 480.0f;
/// \brief Clipboard /// \brief Clipboard
std::string s_clipboard; std::string s_clipboard;
@ -134,10 +129,7 @@ void updateGamepads (ImGuiIO &io_)
bool imgui::ctru::init () bool imgui::ctru::init ()
{ {
ImGuiIO &io = ImGui::GetIO (); auto &io = ImGui::GetIO ();
// disable imgui.ini file
io.IniFilename = nullptr;
// setup config flags // setup config flags
io.ConfigFlags |= ImGuiConfigFlags_IsTouchScreen; io.ConfigFlags |= ImGuiConfigFlags_IsTouchScreen;
@ -160,17 +152,13 @@ bool imgui::ctru::init ()
void imgui::ctru::newFrame () void imgui::ctru::newFrame ()
{ {
ImGuiIO &io = ImGui::GetIO (); auto &io = ImGui::GetIO ();
// check that font was built // check that font was built
IM_ASSERT (io.Fonts->IsBuilt () && IM_ASSERT (io.Fonts->IsBuilt () &&
"Font atlas not built! It is generally built by the renderer back-end. Missing call " "Font atlas not built! It is generally built by the renderer back-end. Missing call "
"to renderer _NewFrame() function?"); "to renderer _NewFrame() function?");
// setup display metrics
io.DisplaySize = ImVec2 (SCREEN_WIDTH, SCREEN_HEIGHT);
io.DisplayFramebufferScale = ImVec2 (2.0f, 2.0f);
// time step // time step
static auto const start = platform::steady_clock::now (); static auto const start = platform::steady_clock::now ();
static auto prev = start; static auto prev = start;
@ -182,7 +170,3 @@ void imgui::ctru::newFrame ()
updateTouch (io); updateTouch (io);
updateGamepads (io); updateGamepads (io);
} }
void imgui::ctru::exit ()
{
}

View File

@ -26,8 +26,6 @@ namespace ctru
{ {
/// \brief Initialize 3ds platform /// \brief Initialize 3ds platform
bool init (); bool init ();
/// \brief Deinitialize 3ds platform
void exit ();
/// \brief Prepare 3ds for a new frame /// \brief Prepare 3ds for a new frame
void newFrame (); void newFrame ();

View File

@ -55,6 +55,45 @@ bool s_socuActive = false;
/// \brief soc:u buffer /// \brief soc:u buffer
u32 *s_socuBuffer = nullptr; 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 /// \brief Texture atlas
C3D_Tex s_gfxTexture; C3D_Tex s_gfxTexture;
/// \brief Texture atlas metadata /// \brief Texture atlas metadata
@ -94,16 +133,16 @@ void drawLogo ()
auto subTex = Tex3DS_GetSubTexture (s_gfxT3x, gfx_c3dlogo_idx); auto subTex = Tex3DS_GetSubTexture (s_gfxT3x, gfx_c3dlogo_idx);
// get framebuffer metrics // get framebuffer metrics
ImGuiIO &io = ImGui::GetIO (); auto const &io = ImGui::GetIO ();
auto const screenWidth = io.DisplaySize.x; auto const screenWidth = io.DisplaySize.x;
auto const screenHeight = io.DisplaySize.y; auto const screenHeight = io.DisplaySize.y;
auto const logoWidth = subTex->width; auto const logoWidth = subTex->width;
auto const logoHeight = subTex->height; auto const logoHeight = subTex->height;
// calculate top screen coords // 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 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; auto const y2 = y1 + logoHeight;
// calculate uv coords // calculate uv coords
@ -116,8 +155,8 @@ void drawLogo ()
// draw to bottom screen // draw to bottom screen
ImGui::GetBackgroundDrawList ()->AddImage (&s_gfxTexture, ImGui::GetBackgroundDrawList ()->AddImage (&s_gfxTexture,
ImVec2 (x1, y1 + screenHeight / 2.0f), ImVec2 (x1, y1 + screenHeight * 0.5f),
ImVec2 (x2, y2 + screenHeight / 2.0f), ImVec2 (x2, y2 + screenHeight * 0.5f),
uv1, uv1,
uv2); uv2);
} }
@ -219,6 +258,19 @@ bool platform::init ()
std::setvbuf (stderr, nullptr, _IOLBF, 0); std::setvbuf (stderr, nullptr, _IOLBF, 0);
#endif #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 ()) if (!imgui::ctru::init ())
return false; return false;
@ -237,8 +289,13 @@ bool platform::init ()
C3D_TexSetFilter (&s_gfxTexture, GPU_LINEAR, GPU_LINEAR); 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 // citro3d logo doesn't quite show with the default transparency
auto &style = ImGui::GetStyle ();
style.Colors[ImGuiCol_WindowBg].w = 0.8f; style.Colors[ImGuiCol_WindowBg].w = 0.8f;
style.ScaleAllSizes (0.5f); style.ScaleAllSizes (0.5f);
@ -257,8 +314,13 @@ bool platform::loop ()
if (hidKeysDown () & KEY_START) if (hidKeysDown () & KEY_START)
return false; 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::ctru::newFrame ();
imgui::citro3d::newFrame ();
ImGui::NewFrame (); ImGui::NewFrame ();
return true; return true;
@ -271,16 +333,31 @@ void platform::render ()
ImGui::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 () void platform::exit ()
{ {
imgui::citro3d::exit ();
// free graphics
Tex3DS_TextureFree (s_gfxT3x); Tex3DS_TextureFree (s_gfxT3x);
C3D_TexDelete (&s_gfxTexture); C3D_TexDelete (&s_gfxTexture);
imgui::citro3d::exit (); // free render targets
imgui::ctru::exit (); C3D_RenderTargetDelete (s_bottom);
C3D_RenderTargetDelete (s_top);
// deinitialize citro3d
C3D_Fini ();
if (s_socuActive) if (s_socuActive)
socExit (); socExit ();

View File

@ -67,7 +67,7 @@ FtpServer::FtpServer (std::uint16_t const port_)
void FtpServer::draw () void FtpServer::draw ()
{ {
ImGuiIO &io = ImGui::GetIO (); auto const &io = ImGui::GetIO ();
auto const width = io.DisplaySize.x; auto const width = io.DisplaySize.x;
auto const height = io.DisplaySize.y; auto const height = io.DisplaySize.y;

View File

@ -154,8 +154,9 @@ bool platform::init ()
ImGui_ImplGlfw_InitForOpenGL (s_mainWindow.get (), true); ImGui_ImplGlfw_InitForOpenGL (s_mainWindow.get (), true);
ImGui_ImplOpenGL3_Init ("#version 150"); ImGui_ImplOpenGL3_Init ("#version 150");
auto &io = ImGui::GetIO ();
// disable imgui.ini file // disable imgui.ini file
ImGuiIO &io = ImGui::GetIO ();
io.IniFilename = nullptr; io.IniFilename = nullptr;
return true; return true;

View File

@ -38,7 +38,9 @@ int main (int argc_, char *argv_[])
return EXIT_FAILURE; return EXIT_FAILURE;
} }
auto &style = ImGui::GetStyle (); auto &style = ImGui::GetStyle ();
// turn off window rounding
style.WindowRounding = 0.0f; style.WindowRounding = 0.0f;
auto server = FtpServer::create (5000); auto server = FtpServer::create (5000);

View File

@ -368,9 +368,9 @@ DkCmdList setupRenderState (int const slot_,
void imgui::deko3d::init () void imgui::deko3d::init ()
{ {
// setup back-end capabilities flags auto &io = ImGui::GetIO ();
ImGuiIO &io = ImGui::GetIO ();
// setup back-end capabilities flags
io.BackendRendererName = "deko3d"; io.BackendRendererName = "deko3d";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset;
@ -457,7 +457,7 @@ void imgui::deko3d::newFrame ()
.create (); .create ();
// get texture atlas // get texture atlas
ImGuiIO &io = ImGui::GetIO (); auto &io = ImGui::GetIO ();
io.Fonts->SetTexID (nullptr); io.Fonts->SetTexID (nullptr);
unsigned char *pixels; unsigned char *pixels;
int width; int width;

View File

@ -1589,7 +1589,7 @@ bool saveFontAtlas ()
bool imgui::nx::init () bool imgui::nx::init ()
{ {
ImGuiIO &io = ImGui::GetIO (); auto &io = ImGui::GetIO ();
if (!loadFontAtlas ()) if (!loadFontAtlas ())
{ {
@ -1690,7 +1690,7 @@ bool imgui::nx::init ()
void imgui::nx::newFrame () void imgui::nx::newFrame ()
{ {
ImGuiIO &io = ImGui::GetIO (); auto &io = ImGui::GetIO ();
// check that font was built // check that font was built
IM_ASSERT (io.Fonts->IsBuilt () && IM_ASSERT (io.Fonts->IsBuilt () &&