diff --git a/Runtime/CMain.cpp b/Runtime/CMain.cpp index 99b095617..3a605cfd9 100644 --- a/Runtime/CMain.cpp +++ b/Runtime/CMain.cpp @@ -432,6 +432,8 @@ public: // TODO: implement this } + void onAppDisplayScaleChanged(float scale) noexcept override { ImGuiEngine_Initialize(scale); } + void onControllerButton(uint32_t idx, aurora::ControllerButton button, bool pressed) noexcept override { if (auto* input = g_InputGenerator) { input->controllerButton(idx, button, pressed); diff --git a/Runtime/GuiSys/CAuiImagePane.cpp b/Runtime/GuiSys/CAuiImagePane.cpp index 949acc28f..5c86d1bc7 100644 --- a/Runtime/GuiSys/CAuiImagePane.cpp +++ b/Runtime/GuiSys/CAuiImagePane.cpp @@ -84,17 +84,17 @@ void CAuiImagePane::DoDrawImagePane(const zeus::CColor& color, const CTexture& t bool zTest = xac_drawFlags == EGuiModelDrawFlags::Shadeless || xac_drawFlags == EGuiModelDrawFlags::Opaque; if (noBlur) { aurora::gfx::queue_textured_quad_verts(aurora::gfx::CameraFilterType(filter), tex.GetTexture(), - aurora::gfx::ZTest::LEqual, zTest, useColor, xe0_coords, realUseUvs, 0); + aurora::gfx::ZComp::LEqual, zTest, useColor, xe0_coords, realUseUvs, 0); // quad.drawVerts(useColor, verts); } else if ((x14c_deResFactor == 0.f && alpha == 1.f) || tex.GetNumMips() == 1) { aurora::gfx::queue_textured_quad_verts(aurora::gfx::CameraFilterType(filter), tex.GetTexture(), - aurora::gfx::ZTest::LEqual, zTest, useColor, xe0_coords, realUseUvs, 0); + aurora::gfx::ZComp::LEqual, zTest, useColor, xe0_coords, realUseUvs, 0); } else { const float tmp = (1.f - x14c_deResFactor) * alpha; const float tmp3 = 1.f - tmp * tmp * tmp; const float mip = tmp3 * static_cast(tex.GetNumMips() - 1); aurora::gfx::queue_textured_quad_verts(aurora::gfx::CameraFilterType(filter), tex.GetTexture(), - aurora::gfx::ZTest::LEqual, zTest, useColor, xe0_coords, realUseUvs, mip); + aurora::gfx::ZComp::LEqual, zTest, useColor, xe0_coords, realUseUvs, mip); } } diff --git a/Runtime/GuiSys/CGuiPane.cpp b/Runtime/GuiSys/CGuiPane.cpp index 228535324..09b683af7 100644 --- a/Runtime/GuiSys/CGuiPane.cpp +++ b/Runtime/GuiSys/CGuiPane.cpp @@ -16,7 +16,7 @@ void CGuiPane::Draw(const CGuiWidgetDrawParms& parms) { auto col = xa8_color2; col.a() = parms.x0_alphaMod * xa8_color2.a(); - aurora::gfx::queue_colored_quad_verts(aurora::gfx::CameraFilterType::Blend, aurora::gfx::ZTest::Always, false, col, + aurora::gfx::queue_colored_quad_verts(aurora::gfx::CameraFilterType::Blend, aurora::gfx::ZComp::Always, false, col, xc0_verts); } CGuiWidget::Draw(parms); diff --git a/Runtime/GuiSys/CSplashScreen.cpp b/Runtime/GuiSys/CSplashScreen.cpp index 43df7817e..c0018afea 100644 --- a/Runtime/GuiSys/CSplashScreen.cpp +++ b/Runtime/GuiSys/CSplashScreen.cpp @@ -76,7 +76,7 @@ void CSplashScreen::Draw() { aurora::gfx::queue_textured_quad( aurora::gfx::CameraFilterType::Blend, m_texture->GetTexture(), - aurora::gfx::ZTest::Always, + aurora::gfx::ZComp::Always, false, color, 1.f, diff --git a/Runtime/MP1/CFrontEndUI.cpp b/Runtime/MP1/CFrontEndUI.cpp index 6194a2c28..094d49125 100644 --- a/Runtime/MP1/CFrontEndUI.cpp +++ b/Runtime/MP1/CFrontEndUI.cpp @@ -2046,7 +2046,7 @@ void CFrontEndUI::Draw() { zeus::CColor color = zeus::skWhite; color.a() = x64_pressStartAlpha; aurora::gfx::queue_textured_quad(aurora::gfx::CameraFilterType::Add, x38_pressStart->GetTexture(), - aurora::gfx::ZTest::Always, false, color, 1.f, rect, 0.f); + aurora::gfx::ZComp::Always, false, color, 1.f, rect, 0.f); } if (xc0_attractCount > 0) { @@ -2058,7 +2058,7 @@ void CFrontEndUI::Draw() { zeus::CColor color = zeus::skBlack; color.a() = 1.f - x58_fadeBlackTimer; zeus::CRectangle rect(0, 0, 1, 1); - aurora::gfx::queue_colored_quad(aurora::gfx::CameraFilterType::Blend, aurora::gfx::ZTest::Always, false, color, + aurora::gfx::queue_colored_quad(aurora::gfx::CameraFilterType::Blend, aurora::gfx::ZComp::Always, false, color, rect, 0.f); } } @@ -2070,14 +2070,14 @@ void CFrontEndUI::Draw() { zeus::CColor color = zeus::skBlack; color.a() = zeus::clamp(0.f, 1.f - x58_fadeBlackTimer, 1.f); zeus::CRectangle rect(0, 0, 1, 1); - aurora::gfx::queue_colored_quad(aurora::gfx::CameraFilterType::Blend, aurora::gfx::ZTest::Always, false, color, + aurora::gfx::queue_colored_quad(aurora::gfx::CameraFilterType::Blend, aurora::gfx::ZComp::Always, false, color, rect, 0.f); } else if (x50_curScreen == EScreen::Title && x54_nextScreen == EScreen::Title) { /* From black with 30-sec skip to title */ zeus::CColor color = zeus::skBlack; color.a() = 1.f - zeus::clamp(0.f, 30.f - x58_fadeBlackTimer, 1.f); zeus::CRectangle rect(0, 0, 1, 1); - aurora::gfx::queue_colored_quad(aurora::gfx::CameraFilterType::Blend, aurora::gfx::ZTest::Always, false, color, + aurora::gfx::queue_colored_quad(aurora::gfx::CameraFilterType::Blend, aurora::gfx::ZComp::Always, false, color, rect, 0.f); } } diff --git a/aurora/CMakeLists.txt b/aurora/CMakeLists.txt index 09386ac34..61f354e53 100644 --- a/aurora/CMakeLists.txt +++ b/aurora/CMakeLists.txt @@ -22,6 +22,7 @@ add_library(aurora STATIC lib/gfx/texture.cpp lib/gfx/movie_player/shader.cpp lib/gfx/textured_quad/shader.cpp + lib/gfx/colored_quad/shader.cpp # TODO move to imgui? or move imgui impl to here? ../extern/imgui/backends/imgui_impl_sdl.cpp ../extern/imgui/backends/imgui_impl_wgpu.cpp diff --git a/aurora/include/aurora/aurora.hpp b/aurora/include/aurora/aurora.hpp index de6726f6c..5c94aa013 100644 --- a/aurora/include/aurora/aurora.hpp +++ b/aurora/include/aurora/aurora.hpp @@ -211,6 +211,7 @@ struct AppDelegate { virtual void onAppPostDraw() noexcept = 0; virtual void onAppWindowResized(const WindowSize& size) noexcept = 0; virtual void onAppWindowMoved(int32_t x, int32_t y) noexcept = 0; + virtual void onAppDisplayScaleChanged(float scale) noexcept = 0; virtual void onAppExiting() noexcept = 0; // ImGui diff --git a/aurora/include/aurora/gfx.hpp b/aurora/include/aurora/gfx.hpp index cb42a66fb..e0d8a3ff3 100644 --- a/aurora/include/aurora/gfx.hpp +++ b/aurora/include/aurora/gfx.hpp @@ -76,7 +76,7 @@ enum class CameraFilterType : uint8_t { NoColor, InvDstMultiply, }; -enum class ZTest : uint8_t { +enum class ZComp : uint8_t { Never, Less, Equal, @@ -104,14 +104,14 @@ void add_model(/* TODO */) noexcept; void queue_aabb(const zeus::CAABox& aabb, const zeus::CColor& color, bool z_only) noexcept; void queue_fog_volume_plane(const ArrayRef& verts, uint8_t pass); void queue_fog_volume_filter(const zeus::CColor& color, bool two_way) noexcept; -void queue_textured_quad_verts(CameraFilterType filter_type, const TextureHandle& texture, ZTest z_comparison, +void queue_textured_quad_verts(CameraFilterType filter_type, const TextureHandle& texture, ZComp z_comparison, bool z_test, const zeus::CColor& color, const ArrayRef& pos, const ArrayRef& uvs, float lod) noexcept; -void queue_textured_quad(CameraFilterType filter_type, const TextureHandle& texture, ZTest z_comparison, bool z_test, - const zeus::CColor& color, float uv_scale, const zeus::CRectangle& rect, float z) noexcept; -void queue_colored_quad_verts(CameraFilterType filter_type, ZTest z_comparison, bool z_test, const zeus::CColor& color, +void queue_textured_quad(CameraFilterType filter_type, const TextureHandle& texture, ZComp z_comparison, bool z_test, + const zeus::CColor& color, float uv_scale, const zeus::CRectangle& rect, float z, float lod = 0) noexcept; +void queue_colored_quad_verts(CameraFilterType filter_type, ZComp z_comparison, bool z_test, const zeus::CColor& color, const ArrayRef& pos) noexcept; -void queue_colored_quad(CameraFilterType filter_type, ZTest z_comparison, bool z_test, const zeus::CColor& color, +void queue_colored_quad(CameraFilterType filter_type, ZComp z_comparison, bool z_test, const zeus::CColor& color, const zeus::CRectangle& rect, float z) noexcept; void queue_movie_player(const TextureHandle& tex_y, const TextureHandle& tex_u, const TextureHandle& tex_v, const zeus::CColor& color, float h_pad, float v_pad) noexcept; diff --git a/aurora/lib/aurora.cpp b/aurora/lib/aurora.cpp index 6f9b06d6b..aa18eb2c8 100644 --- a/aurora/lib/aurora.cpp +++ b/aurora/lib/aurora.cpp @@ -15,6 +15,7 @@ static logvisor::Module Log("aurora"); // TODO: Move global state to a class/struct? static std::unique_ptr g_AppDelegate; static std::vector g_Args; +static float g_AppDpi = 1.f; // SDL static SDL_Window* g_Window; @@ -112,11 +113,17 @@ static bool poll_events() noexcept { break; } case SDL_WINDOWEVENT_DISPLAY_CHANGED: { - // TODO: handle display chaaged event + printf("DISPLAY_CHANGED!\n"); + float scale = 1.0f; + if (SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(g_Window), nullptr, &scale, nullptr) == 0) { + scale /= 96.0f; + if (g_AppDpi != scale) { + g_AppDelegate->onAppDisplayScaleChanged(scale); + } + } break; } } - /* TODO: More window events */ break; } case SDL_CONTROLLERDEVICEADDED: { @@ -258,6 +265,10 @@ void app_run(std::unique_ptr app, Icon icon, int argc, char** argv) gpu::initialize(g_Window); gfx::initialize(); + g_AppDpi = 1.0f; + if (SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(g_Window), nullptr, &g_AppDpi, nullptr) == 0) { + g_AppDpi /= 96.0f; + } imgui::create_context(); g_AppDelegate->onImGuiInit(1.f); // TODO scale @@ -381,16 +392,16 @@ void set_fullscreen(bool fullscreen) noexcept { } int32_t get_controller_player_index(uint32_t which) noexcept { - return input::player_index(which); // TODO + return input::player_index(which); } void set_controller_player_index(uint32_t which, int32_t index) noexcept { input::set_player_index(which, index); } bool is_controller_gamecube(uint32_t which) noexcept { - return input::is_gamecube(which); // TODO + return input::is_gamecube(which); } std::string get_controller_name(uint32_t instance) noexcept { - return input::controller_name(instance); // TODO + return input::controller_name(instance); } } // namespace aurora diff --git a/aurora/lib/gfx/colored_quad/shader.cpp b/aurora/lib/gfx/colored_quad/shader.cpp new file mode 100644 index 000000000..571a36140 --- /dev/null +++ b/aurora/lib/gfx/colored_quad/shader.cpp @@ -0,0 +1,309 @@ +#include "shader.hpp" + +#include "../../gpu.hpp" + +#include +#include + +namespace aurora::gfx::colored_quad { +static logvisor::Module Log("aurora::gfx::colored_quad"); + +using gpu::g_device; +using gpu::g_graphicsConfig; +using gpu::utils::make_vertex_attributes; +using gpu::utils::make_vertex_buffer_layout; +using gpu::utils::make_vertex_state; + +State construct_state() { + wgpu::ShaderModuleWGSLDescriptor wgslDescriptor{}; + wgslDescriptor.source = R"""( +struct Uniform { + xf: mat4x4; + color: vec4; +}; +@group(0) @binding(0) +var ubuf: Uniform; + +struct VertexOutput { + @builtin(position) pos: vec4; + //@builtin(normal) norm: vec4; +}; + +@stage(vertex) +fn vs_main(@location(0) in_pos: vec3) -> VertexOutput {//, @location(1) in_norm: vec3) -> VertexOutput { + var out: VertexOutput; + out.pos = ubuf.xf * vec4(in_pos, 1.0); + //out.norm = in_norm; + return out; +} + +@stage(fragment) +fn fs_main(in: VertexOutput) -> @location(0) vec4 { + return ubuf.color; +} +)"""; + const auto shaderDescriptor = wgpu::ShaderModuleDescriptor{ + .nextInChain = &wgslDescriptor, + .label = "Colored Quad Shader", + }; + auto shader = g_device.CreateShaderModule(&shaderDescriptor); + + wgpu::SupportedLimits limits; + g_device.GetLimits(&limits); + const auto uniform_alignment = limits.limits.minUniformBufferOffsetAlignment; + const auto uniform_size = ALIGN(sizeof(Uniform), uniform_alignment); + + const std::array uniformLayoutEntries{ + wgpu::BindGroupLayoutEntry{ + .binding = 0, + .visibility = wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment, + .buffer = + wgpu::BufferBindingLayout{ + .type = wgpu::BufferBindingType::Uniform, + .hasDynamicOffset = true, + .minBindingSize = uniform_size, + }, + }, + }; + + const auto uniformLayoutDescriptor = wgpu::BindGroupLayoutDescriptor{ + .label = "Colored Quad Uniform Bind Group Layout", + .entryCount = uniformLayoutEntries.size(), + .entries = uniformLayoutEntries.data(), + }; + auto uniformLayout = g_device.CreateBindGroupLayout(&uniformLayoutDescriptor); + + const std::array uniformBindGroupEntries{ + wgpu::BindGroupEntry{ + .binding = 0, + .buffer = g_uniformBuffer, + .size = uniform_size, + }, + }; + + const auto uniformBindGroupDescriptor = wgpu::BindGroupDescriptor{ + .label = "Colored Quad Uniform Bind Group", + .layout = uniformLayout, + .entryCount = uniformBindGroupEntries.size(), + .entries = uniformBindGroupEntries.data(), + }; + auto uniformBindGroup = g_device.CreateBindGroup(&uniformBindGroupDescriptor); + + const std::array bindGroupLayouts{ + uniformLayout, + }; + + const auto pipelineLayoutDescriptor = wgpu::PipelineLayoutDescriptor{ + .label = "Colored Quad Pipeline Layout", + .bindGroupLayoutCount = bindGroupLayouts.size(), + .bindGroupLayouts = bindGroupLayouts.data(), + }; + auto pipelineLayout = g_device.CreatePipelineLayout(&pipelineLayoutDescriptor); + + return { + .shader = shader, + .uniformLayout = uniformLayout, + .uniformBindGroup = uniformBindGroup, + .pipelineLayout = pipelineLayout, + }; +} + +wgpu::RenderPipeline create_pipeline(const State& state, [[maybe_unused]] PipelineConfig config) { + const auto attributes = make_vertex_attributes(std::array{wgpu::VertexFormat::Float32x3}); + const std::array vertexBuffers{make_vertex_buffer_layout(sizeof(Vert), attributes)}; + + wgpu::CompareFunction depthCompare{}; + switch (config.zComparison) { + case ZComp::Never: + depthCompare = wgpu::CompareFunction::Never; + break; + case ZComp::Less: + depthCompare = wgpu::CompareFunction::Less; + break; + case ZComp::Equal: + depthCompare = wgpu::CompareFunction::Equal; + break; + case ZComp::LEqual: + depthCompare = wgpu::CompareFunction::LessEqual; + break; + case ZComp::Greater: + depthCompare = wgpu::CompareFunction::Greater; + break; + case ZComp::NEqual: + depthCompare = wgpu::CompareFunction::NotEqual; + break; + case ZComp::GEqual: + depthCompare = wgpu::CompareFunction::GreaterEqual; + break; + case ZComp::Always: + depthCompare = wgpu::CompareFunction::Always; + break; + } + const auto depthStencil = wgpu::DepthStencilState{ + .format = g_graphicsConfig.depthFormat, + .depthWriteEnabled = config.zTest, + .depthCompare = depthCompare, + }; + + bool alphaWrite = false; + wgpu::BlendComponent blendComponent{}; + switch (config.filterType) { + case CameraFilterType::Multiply: + blendComponent = wgpu::BlendComponent{ + .srcFactor = wgpu::BlendFactor::Zero, + .dstFactor = wgpu::BlendFactor::Src, + }; + alphaWrite = true; + break; + case CameraFilterType::Add: + blendComponent = wgpu::BlendComponent{ + .srcFactor = wgpu::BlendFactor::SrcAlpha, + .dstFactor = wgpu::BlendFactor::One, + }; + alphaWrite = false; + break; + case CameraFilterType::Subtract: + blendComponent = wgpu::BlendComponent{ + .operation = wgpu::BlendOperation::Subtract, + .srcFactor = wgpu::BlendFactor::SrcAlpha, + .dstFactor = wgpu::BlendFactor::One, + }; + alphaWrite = false; + break; + case CameraFilterType::Blend: + blendComponent = wgpu::BlendComponent{ + .srcFactor = wgpu::BlendFactor::SrcAlpha, + .dstFactor = wgpu::BlendFactor::OneMinusSrcAlpha, + }; + alphaWrite = false; + break; + case CameraFilterType::InvDstMultiply: + blendComponent = wgpu::BlendComponent{ + .srcFactor = wgpu::BlendFactor::Zero, + .dstFactor = wgpu::BlendFactor::OneMinusSrc, + }; + alphaWrite = true; + break; + default: + Log.report(logvisor::Fatal, FMT_STRING("unimplemented filter type {}"), magic_enum::enum_name(config.filterType)); + unreachable(); + } + + const auto blendState = wgpu::BlendState{ + .color = blendComponent, + .alpha = blendComponent, + }; + auto writeMask = wgpu::ColorWriteMask::Red | wgpu::ColorWriteMask::Green | wgpu::ColorWriteMask::Blue; + if (alphaWrite) { + writeMask = writeMask | wgpu::ColorWriteMask::Alpha; + } + const std::array colorTargets{ + wgpu::ColorTargetState{ + .format = g_graphicsConfig.colorFormat, + .blend = &blendState, + .writeMask = writeMask, + }, + }; + const auto fragmentState = wgpu::FragmentState{ + .module = state.shader, + .entryPoint = "fs_main", + .targetCount = colorTargets.size(), + .targets = colorTargets.data(), + }; + + const auto pipelineDescriptor = wgpu::RenderPipelineDescriptor{ + .label = "Colored Quad Pipeline", + .layout = state.pipelineLayout, + .vertex = make_vertex_state(state.shader, vertexBuffers), + .primitive = + wgpu::PrimitiveState{ + .topology = wgpu::PrimitiveTopology::TriangleStrip, + }, + .depthStencil = &depthStencil, + .multisample = + wgpu::MultisampleState{ + .count = g_graphicsConfig.msaaSamples, + }, + .fragment = &fragmentState, + }; + + return g_device.CreateRenderPipeline(&pipelineDescriptor); +} + +DrawData make_draw_data(const State& state, CameraFilterType filter_type, ZComp z_comparison, bool z_test, + const zeus::CColor& color, const zeus::CRectangle& rect, float z) { + auto pipeline = pipeline_ref(PipelineConfig{ + .filterType = filter_type, + .zComparison = z_comparison, + .zTest = z_test, + }); + + const std::array verts{ + Vert{{0.f, 0.f, z}}, + Vert{{0.f, 1.f, z}}, + Vert{{1.f, 0.f, z}}, + Vert{{1.f, 1.f, z}}, + }; + const auto vertRange = push_verts(ArrayRef{verts}); + + const auto uniform = Uniform{ + .xf = + Mat4x4{ + Vec4{rect.size.x() * 2.f, 0.f, 0.f, 0.f}, + Vec4{0.f, rect.size.y() * 2.f, 0.f, 0.f}, + Vec4{0.f, 0.f, 1.f, 0.f}, + Vec4{rect.position.x() * 2.f - 1.f, rect.position.y() * 2.f - 1.f, 0.f, 1.f}, + }, + .color = color, + }; + const auto uniformRange = push_uniform(uniform); + + return { + .pipeline = pipeline, + .vertRange = vertRange, + .uniformRange = uniformRange, + }; +} + +DrawData make_draw_data_verts(const State& state, CameraFilterType filter_type, ZComp z_comparison, bool z_test, + const zeus::CColor& color, const ArrayRef& pos) { + auto pipeline = pipeline_ref(PipelineConfig{ + .filterType = filter_type, + .zComparison = z_comparison, + .zTest = z_test, + }); + + assert(pos.size() == 4 && "Invalid pos size!"); + + const std::array verts{ + Vert{pos[0]}, + Vert{pos[1]}, + Vert{pos[2]}, + Vert{pos[3]}, + }; + const auto vertRange = push_verts(ArrayRef{verts}); + + const auto uniform = Uniform{ + .xf = get_combined_matrix(), + .color = color, + }; + const auto uniformRange = push_uniform(uniform); + + return { + .pipeline = pipeline, + .vertRange = vertRange, + .uniformRange = uniformRange, + }; +} + +void render(const State& state, const DrawData& data, const wgpu::RenderPassEncoder& pass) { + if (!bind_pipeline(data.pipeline, pass)) { + return; + } + + const std::array offsets{data.uniformRange.first}; + pass.SetBindGroup(0, state.uniformBindGroup, offsets.size(), offsets.data()); + pass.SetVertexBuffer(0, g_vertexBuffer, data.vertRange.first, data.vertRange.second); + pass.Draw(4); +} +} // namespace aurora::gfx::colored_quad diff --git a/aurora/lib/gfx/colored_quad/shader.hpp b/aurora/lib/gfx/colored_quad/shader.hpp new file mode 100644 index 000000000..b777238cc --- /dev/null +++ b/aurora/lib/gfx/colored_quad/shader.hpp @@ -0,0 +1,47 @@ +#include "../common.hpp" + +namespace aurora::gfx::colored_quad { +struct DrawData { + PipelineRef pipeline; + Range vertRange; + Range uniformRange; +}; + +struct PipelineConfig { + CameraFilterType filterType; + ZComp zComparison; + bool zTest; +}; + +static const std::array INITIAL_PIPELINES { + PipelineConfig{}, // TODO +}; + +struct State { + wgpu::ShaderModule shader; + wgpu::BindGroupLayout uniformLayout; + wgpu::BindGroup uniformBindGroup; + wgpu::Sampler sampler; + wgpu::PipelineLayout pipelineLayout; +}; + +struct alignas(4) Vert { + Vec3 pos; +}; + +struct alignas(4) Uniform { + Mat4x4 xf; + Vec4 color; +}; +static_assert(sizeof(Uniform) == 80); + +State construct_state(); +wgpu::RenderPipeline create_pipeline(const State& state, [[maybe_unused]] PipelineConfig config); +DrawData make_draw_data(const State& state, CameraFilterType filter_type, ZComp z_comparison, bool z_test, + const zeus::CColor& color, const zeus::CRectangle& rect, float z); + +DrawData make_draw_data_verts(const State& state, CameraFilterType filter_type, ZComp z_comparison, bool z_test, + const zeus::CColor& color, const ArrayRef& pos); + +void render(const State& state, const DrawData& data, const wgpu::RenderPassEncoder& pass); +} // namespace aurora::gfx::colored_quad \ No newline at end of file diff --git a/aurora/lib/gfx/common.cpp b/aurora/lib/gfx/common.cpp index f4fe7a31e..0724f070d 100644 --- a/aurora/lib/gfx/common.cpp +++ b/aurora/lib/gfx/common.cpp @@ -1,7 +1,8 @@ #include "common.hpp" #include "../gpu.hpp" -#include "textured_quad//shader.hpp" +#include "colored_quad/shader.hpp" +#include "textured_quad/shader.hpp" #include "movie_player/shader.hpp" #include @@ -18,12 +19,14 @@ using gpu::g_queue; struct ShaderState { movie_player::State moviePlayer; + colored_quad::State coloredQuad; textured_quad::State texturedQuad; }; struct ShaderDrawCommand { ShaderType type; union { movie_player::DrawData moviePlayer; + colored_quad::DrawData coloredQuad; textured_quad::DrawData texturedQuad; }; }; @@ -31,6 +34,7 @@ struct PipelineCreateCommand { ShaderType type; union { movie_player::PipelineConfig moviePlayer; + colored_quad::PipelineConfig coloredQuad; textured_quad::PipelineConfig texturedQuad; }; }; @@ -148,15 +152,18 @@ void queue_fog_volume_filter(const zeus::CColor& color, bool two_way) noexcept { // TODO } -void queue_textured_quad_verts(CameraFilterType filter_type, const TextureHandle& texture, ZTest z_comparison, +void queue_textured_quad_verts(CameraFilterType filter_type, const TextureHandle& texture, ZComp z_comparison, bool z_test, const zeus::CColor& color, const ArrayRef& pos, const ArrayRef& uvs, float lod) noexcept { - // TODO + auto data = textured_quad::make_draw_data_verts(g_state.texturedQuad, filter_type, texture, z_comparison, z_test, + color, pos, uvs, lod); + push_draw_command({.type = ShaderType::TexturedQuad, .texturedQuad = data}); } -void queue_textured_quad(CameraFilterType filter_type, const TextureHandle& texture, ZTest z_comparison, bool z_test, - const zeus::CColor& color, float uv_scale, const zeus::CRectangle& rect, float z) noexcept { +void queue_textured_quad(CameraFilterType filter_type, const TextureHandle& texture, ZComp z_comparison, bool z_test, + const zeus::CColor& color, float uv_scale, const zeus::CRectangle& rect, float z, + float lod) noexcept { auto data = textured_quad::make_draw_data(g_state.texturedQuad, filter_type, texture, z_comparison, z_test, color, - uv_scale, rect, z); + uv_scale, rect, z, lod); push_draw_command({.type = ShaderType::TexturedQuad, .texturedQuad = data}); } template <> @@ -165,13 +172,21 @@ PipelineRef pipeline_ref(textured_quad::PipelineConfig config) { [=]() { return create_pipeline(g_state.texturedQuad, config); }); } -void queue_colored_quad_verts(CameraFilterType filter_type, ZTest z_comparison, bool z_test, const zeus::CColor& color, +void queue_colored_quad_verts(CameraFilterType filter_type, ZComp z_comparison, bool z_test, const zeus::CColor& color, const ArrayRef& pos) noexcept { - // TODO + auto data = colored_quad::make_draw_data_verts(g_state.coloredQuad, filter_type, z_comparison, z_test, color, pos); + push_draw_command({.type = ShaderType::ColoredQuad, .coloredQuad = data}); } -void queue_colored_quad(CameraFilterType filter_type, ZTest z_comparison, bool z_test, const zeus::CColor& color, +void queue_colored_quad(CameraFilterType filter_type, ZComp z_comparison, bool z_test, const zeus::CColor& color, const zeus::CRectangle& rect, float z) noexcept { - // TODO + auto data = colored_quad::make_draw_data(g_state.coloredQuad, filter_type, z_comparison, z_test, color, rect, z); + push_draw_command({.type = ShaderType::ColoredQuad, .coloredQuad = data}); +} + +template <> +PipelineRef pipeline_ref(colored_quad::PipelineConfig config) { + return find_pipeline({.type = ShaderType::ColoredQuad, .coloredQuad = config}, + [=]() { return create_pipeline(g_state.coloredQuad, config); }); } void queue_movie_player(const TextureHandle& tex_y, const TextureHandle& tex_u, const TextureHandle& tex_v, @@ -245,6 +260,7 @@ void initialize() { } g_state.moviePlayer = movie_player::construct_state(); + g_state.coloredQuad = colored_quad::construct_state(); g_state.texturedQuad = textured_quad::construct_state(); } @@ -289,6 +305,9 @@ void render(const wgpu::RenderPassEncoder& pass) { case ShaderType::Aabb: // TODO break; + case ShaderType::ColoredQuad: + colored_quad::render(g_state.coloredQuad, draw.coloredQuad, pass); + break; case ShaderType::TexturedQuad: textured_quad::render(g_state.texturedQuad, draw.texturedQuad, pass); break; diff --git a/aurora/lib/gfx/common.hpp b/aurora/lib/gfx/common.hpp index 0c1aa8e38..fdd3dcb08 100644 --- a/aurora/lib/gfx/common.hpp +++ b/aurora/lib/gfx/common.hpp @@ -150,6 +150,7 @@ using Range = std::pair; enum class ShaderType { Aabb, + ColoredQuad, TexturedQuad, MoviePlayer, }; diff --git a/aurora/lib/gfx/textured_quad/shader.cpp b/aurora/lib/gfx/textured_quad/shader.cpp index 5f0d55799..9fc29ea11 100644 --- a/aurora/lib/gfx/textured_quad/shader.cpp +++ b/aurora/lib/gfx/textured_quad/shader.cpp @@ -161,28 +161,28 @@ wgpu::RenderPipeline create_pipeline(const State& state, [[maybe_unused]] Pipeli wgpu::CompareFunction depthCompare; switch (config.zComparison) { - case ZTest::Never: + case ZComp::Never: depthCompare = wgpu::CompareFunction::Never; break; - case ZTest::Less: + case ZComp::Less: depthCompare = wgpu::CompareFunction::Less; break; - case ZTest::Equal: + case ZComp::Equal: depthCompare = wgpu::CompareFunction::Equal; break; - case ZTest::LEqual: + case ZComp::LEqual: depthCompare = wgpu::CompareFunction::LessEqual; break; - case ZTest::Greater: + case ZComp::Greater: depthCompare = wgpu::CompareFunction::Greater; break; - case ZTest::NEqual: + case ZComp::NEqual: depthCompare = wgpu::CompareFunction::NotEqual; break; - case ZTest::GEqual: + case ZComp::GEqual: depthCompare = wgpu::CompareFunction::GreaterEqual; break; - case ZTest::Always: + case ZComp::Always: depthCompare = wgpu::CompareFunction::Always; break; } @@ -277,8 +277,8 @@ wgpu::RenderPipeline create_pipeline(const State& state, [[maybe_unused]] Pipeli } DrawData make_draw_data(const State& state, CameraFilterType filter_type, const TextureHandle& texture, - ZTest z_comparison, bool z_test, const zeus::CColor& color, float uv_scale, - const zeus::CRectangle& rect, float z) { + ZComp z_comparison, bool z_test, const zeus::CColor& color, float uv_scale, + const zeus::CRectangle& rect, float z, float lod) { auto pipeline = pipeline_ref(PipelineConfig{ .filterType = filter_type, .zComparison = z_comparison, @@ -302,7 +302,54 @@ DrawData make_draw_data(const State& state, CameraFilterType filter_type, const Vec4{rect.position.x() * 2.f - 1.f, rect.position.y() * 2.f - 1.f, 0.f, 1.f}, }, .color = color, - .lod = 0.f, + .lod = lod, + }; + const auto uniformRange = push_uniform(uniform); + + const std::array entries{ + wgpu::BindGroupEntry{ + .binding = 0, + .textureView = texture.ref->view, + }, + }; + const auto textureBindGroup = bind_group_ref(wgpu::BindGroupDescriptor{ + .label = "Textured Quad Texture Bind Group", + .layout = state.textureLayout, + .entryCount = entries.size(), + .entries = entries.data(), + }); + + return { + .pipeline = pipeline, + .vertRange = vertRange, + .uniformRange = uniformRange, + .textureBindGroup = textureBindGroup, + }; +} + +DrawData make_draw_data_verts(const State& state, CameraFilterType filter_type, const TextureHandle& texture, + ZComp z_comparison, bool z_test, const zeus::CColor& color, + const ArrayRef& pos, const ArrayRef& uvs, float lod) { + auto pipeline = pipeline_ref(PipelineConfig{ + .filterType = filter_type, + .zComparison = z_comparison, + .zTest = z_test, + }); + + assert(pos.size() == 4 && uvs.size() == 4 && "Invalid pos/uv sizes!"); + + const std::array verts{ + Vert{pos[0], uvs[0]}, + Vert{pos[1], uvs[1]}, + Vert{pos[2], uvs[2]}, + Vert{pos[3], uvs[3]}, + }; + const auto vertRange = push_verts(ArrayRef{verts}); + + const auto uniform = Uniform{ + .xf = get_combined_matrix(), + .color = color, + .lod = lod, }; const auto uniformRange = push_uniform(uniform); diff --git a/aurora/lib/gfx/textured_quad/shader.hpp b/aurora/lib/gfx/textured_quad/shader.hpp index d6e21c772..ba3840d68 100644 --- a/aurora/lib/gfx/textured_quad/shader.hpp +++ b/aurora/lib/gfx/textured_quad/shader.hpp @@ -10,7 +10,7 @@ struct DrawData { struct PipelineConfig { CameraFilterType filterType; - ZTest zComparison; + ZComp zComparison; bool zTest; }; static const std::array INITIAL_PIPELINES{ @@ -40,7 +40,10 @@ static_assert(sizeof(Uniform) == 84); State construct_state(); wgpu::RenderPipeline create_pipeline(const State& state, [[maybe_unused]] PipelineConfig config); DrawData make_draw_data(const State& state, CameraFilterType filter_type, const TextureHandle& texture, - ZTest z_comparison, bool z_test, const zeus::CColor& color, float uv_scale, - const zeus::CRectangle& rect, float z); + ZComp z_comparison, bool z_test, const zeus::CColor& color, float uv_scale, + const zeus::CRectangle& rect, float z, float lod); +DrawData make_draw_data_verts(const State& state, CameraFilterType filter_type, const TextureHandle& texture, + ZComp z_comparison, bool z_test, const zeus::CColor& color, + const ArrayRef& pos, const ArrayRef& uvs, float lod); void render(const State& state, const DrawData& data, const wgpu::RenderPassEncoder& pass); } // namespace aurora::gfx::textured_quad diff --git a/imgui/ImGuiEngine.cpp b/imgui/ImGuiEngine.cpp index 4830aaf97..e674aa9a0 100644 --- a/imgui/ImGuiEngine.cpp +++ b/imgui/ImGuiEngine.cpp @@ -54,10 +54,24 @@ void ImGuiEngine_Initialize(float scale) { ImGuiEngine::fontLarge = io.Fonts->AddFont(&fontConfig); auto& style = ImGui::GetStyle(); + style.WindowPadding = ImVec2(15, 15); + style.WindowRounding = 5.0f; + style.FrameBorderSize = 1.f; + style.FramePadding = ImVec2(5, 5); style.FrameRounding = 4.0f; - style.GrabRounding = 4.0f; + style.ItemSpacing = ImVec2(12, 8); + style.ItemInnerSpacing = ImVec2(8, 6); + style.IndentSpacing = 25.0f; + style.ScrollbarSize = 15.0f; + style.ScrollbarRounding = 9.0f; + style.GrabMinSize = 5.0f; + style.GrabRounding = 3.0f; + style.PopupBorderSize = 1.f; + style.PopupRounding = 7.0; + style.TabBorderSize = 1.f; + style.TabRounding = 3.f; - auto colors = style.Colors; + auto* colors = style.Colors; colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f); colors[ImGuiCol_TextDisabled] = ImVec4(0.36f, 0.42f, 0.47f, 1.00f); colors[ImGuiCol_WindowBg] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f); @@ -125,7 +139,6 @@ Icon GetIcon() { void ImGuiEngine_AddTextures() { auto icon = GetIcon(); - ImGuiEngine::metaforceIcon = - aurora::imgui::add_texture(icon.width, icon.height, {icon.data.get(), icon.size}); + ImGuiEngine::metaforceIcon = aurora::imgui::add_texture(icon.width, icon.height, {icon.data.get(), icon.size}); } } // namespace metaforce