diff --git a/Engine/Src/Imp/CPP/Components/CameraComponent.cpp b/Engine/Src/Imp/CPP/Components/CameraComponent.cpp index 89fe9a7..0f31cb2 100644 --- a/Engine/Src/Imp/CPP/Components/CameraComponent.cpp +++ b/Engine/Src/Imp/CPP/Components/CameraComponent.cpp @@ -39,7 +39,7 @@ namespace ia::iae CONST Mat4 *CameraComponent::GetViewMatrix() { - const auto pos = (m_node->GetPosition() + m_positionOffset) * Engine::GetRendererScalingFactor(); + const auto pos = (m_node->GetPosition() + m_positionOffset) * Engine::GetSceneScalingFactor(); m_viewMatrix = glm::lookAtLH(glm::vec3{pos, -2.0f}, {pos, 0.0f}, {0.0f, 1.0f, 0.0f}); return &m_viewMatrix; } diff --git a/Engine/Src/Imp/CPP/Components/TextureComponent.cpp b/Engine/Src/Imp/CPP/Components/TextureComponent.cpp index c8161a7..2c84036 100644 --- a/Engine/Src/Imp/CPP/Components/TextureComponent.cpp +++ b/Engine/Src/Imp/CPP/Components/TextureComponent.cpp @@ -35,15 +35,15 @@ namespace ia::iae m_textureExtent = {t.x, t.y}; m_drawnSize = m_node->GetScale() * m_textureExtent * m_scaleOffset; - Engine::SetRenderState_Texture(m_texture); Engine::SetRenderState_FlippedH(m_isFlippedH); Engine::SetRenderState_FlippedV(m_isFlippedV); Engine::SetRenderState_ColorOverlay(m_colorOverlay); Engine::SetRenderState_TextureOffset(m_textureOffset); Engine::SetRenderState_CameraRelative(m_isCameraRelative); - Engine::SetRenderState_Transform(m_node->GetPosition() + m_positionOffset, m_node->GetScale() * Vec2{t2.x, t2.y} * m_scaleOffset, m_node->GetRotation() + m_rotationOffset); - Engine::DrawGeometry(Engine::GetGeometry_Quad(), m_node->Layer(), m_node->SortIndex()); + Engine::DrawGeometry(Engine::GetGeometry_Quad(), m_texture, m_node->GetPosition() + m_positionOffset, + m_node->GetScale() * Vec2{t2.x, t2.y} * m_scaleOffset, + m_node->GetRotation() + m_rotationOffset, m_node->Layer(), m_node->SortIndex()); } VOID TextureComponent::DebugDraw() diff --git a/Engine/Src/Imp/CPP/Components/UIButtonComponent.cpp b/Engine/Src/Imp/CPP/Components/UIButtonComponent.cpp index e69de29..dbab2d9 100644 --- a/Engine/Src/Imp/CPP/Components/UIButtonComponent.cpp +++ b/Engine/Src/Imp/CPP/Components/UIButtonComponent.cpp @@ -0,0 +1,65 @@ +// IAEngine: 2D Game Engine by IA +// Copyright (C) 2025 IASoft (PVT) LTD (oss@iasoft.dev) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include + +namespace ia::iae +{ + UIButtonComponent::UIButtonComponent(IN UINode *node) : UIImageComponent(node) + { + } + + VOID UIButtonComponent::Draw() + { + UIImageComponent::Draw(); + + if (m_label.length()) + { + Engine::SetRenderState_FlippedH(false); + Engine::SetRenderState_FlippedV(false); + Engine::SetRenderState_ColorOverlay(m_labelColor); + Engine::SetRenderState_TextureOffset({}); + Engine::SetRenderState_CameraRelative(false); + Engine::DrawText(m_label, m_node->GetPosition() + m_labelPosition, m_node->GetScale() * m_labelSize, + m_node->GetRotation(), 0xFF, 0); + } + } + + VOID UIButtonComponent::DebugDraw() + { + } + + VOID UIButtonComponent::Update() + { + if (Engine::Input_IsPointerDown(m_node->GetPosition(), m_node->GetPosition() + DrawnSize())) + { + if (m_onDownCallback) + m_onDownCallback(); + } + + if (Engine::Input_DidPointerClick(m_node->GetPosition(), m_node->GetPosition() + DrawnSize())) + { + if (m_onClickCallback) + m_onClickCallback(); + } + } + + VOID UIButtonComponent::FixedUpdate() + { + } +} // namespace ia::iae \ No newline at end of file diff --git a/Engine/Src/Imp/CPP/Components/UIImageComponent.cpp b/Engine/Src/Imp/CPP/Components/UIImageComponent.cpp index e69de29..0252dd4 100644 --- a/Engine/Src/Imp/CPP/Components/UIImageComponent.cpp +++ b/Engine/Src/Imp/CPP/Components/UIImageComponent.cpp @@ -0,0 +1,52 @@ +// IAEngine: 2D Game Engine by IA +// Copyright (C) 2025 IASoft (PVT) LTD (oss@iasoft.dev) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include + +namespace ia::iae +{ + UIImageComponent::UIImageComponent(IN UINode *node) : IUIComponent(node) + { + } + + VOID UIImageComponent::Draw() + { + const auto t = Engine::GetImageOriginalExtent(m_image); + m_drawnSize = {m_node->GetScale() * t.x, m_node->GetScale() * t.y}; + + Engine::SetRenderState_FlippedH(false); + Engine::SetRenderState_FlippedV(false); + Engine::SetRenderState_ColorOverlay({0xFF, 0xFF, 0xFF, 0xFF}); + Engine::SetRenderState_TextureOffset({}); + Engine::SetRenderState_CameraRelative(false); + + Engine::DrawGeometry(Engine::GetGeometry_Quad(), m_image, m_node->GetPosition(), m_drawnSize, m_node->GetRotation(), 0xFF, 0); + } + + VOID UIImageComponent::DebugDraw() + { + } + + VOID UIImageComponent::Update() + { + } + + VOID UIImageComponent::FixedUpdate() + { + } +} // namespace ia::iae \ No newline at end of file diff --git a/Engine/Src/Imp/CPP/Components/UILabelComponent.cpp b/Engine/Src/Imp/CPP/Components/UILabelComponent.cpp index f42ee8b..e229223 100644 --- a/Engine/Src/Imp/CPP/Components/UILabelComponent.cpp +++ b/Engine/Src/Imp/CPP/Components/UILabelComponent.cpp @@ -26,10 +26,9 @@ namespace ia::iae VOID UILabelComponent::Draw() { - Engine::SetRenderState_Texture(0); Engine::SetRenderState_FlippedH(false); Engine::SetRenderState_FlippedV(false); - Engine::SetRenderState_ColorOverlay({0xFF, 0xFF, 0xFF, 0xFF}); + Engine::SetRenderState_ColorOverlay(m_color); Engine::SetRenderState_TextureOffset({}); Engine::SetRenderState_CameraRelative(false); Engine::DrawText(m_label, m_node->GetPosition(), m_node->GetScale(), m_node->GetRotation(), 0xFF, 0); diff --git a/Engine/Src/Imp/CPP/Engine.cpp b/Engine/Src/Imp/CPP/Engine.cpp index 598c285..c54afda 100644 --- a/Engine/Src/Imp/CPP/Engine.cpp +++ b/Engine/Src/Imp/CPP/Engine.cpp @@ -24,10 +24,15 @@ #include +#include + namespace ia::iae { EXTERN SDL_Window *g_windowHandle; - SIZE_T g_resourceNameCounter = 1; + SIZE_T g_resourceNameCounter {1}; + + Vec2 g_sceneScalingFactor{1.0f}; + Vec2 g_sceneDesignViewport{1.0f}; BOOL Engine::IsDebugMode() { @@ -96,8 +101,12 @@ namespace ia::iae { const auto data = ReadBinaryAsset(path); const auto handle = CreateImage(name, data.data(), data.size()); + if (!resizeToWidth || !resizeToHeight) + return handle; const auto extent = GetImageExtent(handle); - return (resizeToWidth && resizeToHeight) ? RescaleImage(handle, {(FLOAT32)resizeToWidth/(FLOAT32)extent.x, (FLOAT32)resizeToHeight/(FLOAT32)extent.y}) : handle; + const auto newHandle = ResourceManager::RescaleImage( + handle, {(FLOAT32) resizeToWidth / (FLOAT32) extent.x, (FLOAT32) resizeToHeight / (FLOAT32) extent.y}, true); + return newHandle; } Handle Engine::CreateSoundFromFile(IN CONST String &name, IN CONST String &path) @@ -108,11 +117,16 @@ namespace ia::iae Handle Engine::RescaleImage(IN CONST String &name, IN Vec2 factor) { - return RescaleImage(GetImage(name), factor); + return ResourceManager::RescaleImage(GetImage(name), factor); } String Engine::GetUniqueResourceName() { return BuildString("__res_", g_resourceNameCounter++); } + + Vec2 Engine::GetSceneScalingFactor() + { + return g_sceneScalingFactor; + } } // namespace ia::iae diff --git a/Engine/Src/Imp/CPP/InputManager.cpp b/Engine/Src/Imp/CPP/InputManager.cpp index a959bd1..fb20d5e 100644 --- a/Engine/Src/Imp/CPP/InputManager.cpp +++ b/Engine/Src/Imp/CPP/InputManager.cpp @@ -24,6 +24,8 @@ namespace ia::iae BOOL InputManager::s_keys[256]; BOOL InputManager::s_prevKeys[256]; Vec2 InputManager::s_pointerPosition{}; + BOOL InputManager::s_pointerState{}; + BOOL InputManager::s_pointerPrevState{}; InputManager::KeyboardGamePadMapping InputManager::s_keyboardGamePadMapping{}; BOOL InputManager::s_buttonA{}; @@ -48,6 +50,7 @@ namespace ia::iae VOID InputManager::OnSDLEvent(IN SDL_Event *event) { + s_pointerPrevState = s_pointerState; memcpy(s_prevKeys, s_keys, sizeof(s_prevKeys)); switch (event->type) { @@ -59,10 +62,21 @@ namespace ia::iae s_keys[event->key.scancode] = false; break; + case SDL_EVENT_FINGER_MOTION: case SDL_EVENT_MOUSE_MOTION: s_pointerPosition = {event->motion.x, event->motion.y}; break; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + case SDL_EVENT_FINGER_DOWN: + s_pointerState = true; + break; + + case SDL_EVENT_MOUSE_BUTTON_UP: + case SDL_EVENT_FINGER_UP: + s_pointerState = false; + break; + default: break; } @@ -78,6 +92,11 @@ namespace ia::iae SDL_StopTextInput(g_windowHandle); } + BOOL InputManager::IsPointerDown() + { + return s_pointerState; + } + Vec2 InputManager::GetPointerPosition() { return s_pointerPosition; @@ -178,16 +197,16 @@ namespace ia::iae { if (s_onScreenGamePadEnabled) { - //Engine::SetRenderState_Texture(0); - //Engine::SetRenderState_FlippedH(false); - //Engine::SetRenderState_FlippedV(false); - //Engine::SetRenderState_ColorOverlay({0xFF, 0xFF, 0xFF, 0xFF}); - //Engine::SetRenderState_TextureOffset({0, 0}); - //Engine::SetRenderState_CameraRelative(false); - //Engine::SetRenderState_Transform({300.0f, 500.0f}, - // {100.0f, 100.0f}, - // 0); - //Engine::DrawGeometry(Engine::GetGeometry_Circle(), 0xFF, 0); + // Engine::SetRenderState_Texture(0); + // Engine::SetRenderState_FlippedH(false); + // Engine::SetRenderState_FlippedV(false); + // Engine::SetRenderState_ColorOverlay({0xFF, 0xFF, 0xFF, 0xFF}); + // Engine::SetRenderState_TextureOffset({0, 0}); + // Engine::SetRenderState_CameraRelative(false); + // Engine::SetRenderState_Transform({300.0f, 500.0f}, + // {100.0f, 100.0f}, + // 0); + // Engine::DrawGeometry(Engine::GetGeometry_Circle(), 0xFF, 0); } } @@ -216,6 +235,18 @@ namespace ia::iae IsKeyDown(s_keyboardGamePadMapping.AxisRight) + IsKeyDown(s_keyboardGamePadMapping.AxisLeft) * -1; } } + + BOOL InputManager::IsPointerDown(IN CONST Vec2 &start, IN CONST Vec2 &end) + { + if(!s_pointerState) return false; + return (s_pointerPosition.x >= start.x) && (s_pointerPosition.x <= end.x) && (s_pointerPosition.y >= start.y) && + (s_pointerPosition.y <= end.y); + } + + BOOL InputManager::DidPointerClick(IN CONST Vec2 &start, IN CONST Vec2 &end) + { + return IsPointerDown(start, end) && !s_pointerPrevState; + } } // namespace ia::iae namespace ia::iae @@ -235,6 +266,21 @@ namespace ia::iae return InputManager::GetPointerPosition(); } + BOOL Engine::Input_IsPointerDown() + { + return InputManager::IsPointerDown(); + } + + BOOL Engine::Input_IsPointerDown(IN CONST Vec2 &start, IN CONST Vec2 &end) + { + return InputManager::IsPointerDown(start, end); + } + + BOOL Engine::Input_DidPointerClick(IN CONST Vec2 &start, IN CONST Vec2 &end) + { + return InputManager::DidPointerClick(start, end); + } + BOOL Engine::Input_IsKeyDown(IN InputKey key) { return InputManager::IsKeyDown(key); diff --git a/Engine/Src/Imp/CPP/InternalEngine.cpp b/Engine/Src/Imp/CPP/InternalEngine.cpp index e0e026b..6b0bc47 100644 --- a/Engine/Src/Imp/CPP/InternalEngine.cpp +++ b/Engine/Src/Imp/CPP/InternalEngine.cpp @@ -42,10 +42,15 @@ namespace ia::iae SDL_Window *g_windowHandle; + EXTERN Vec2 g_sceneDesignViewport; + VOID __Internal_Engine::Initialize() { const auto config = Game_GetConfigRequest(); + g_sceneDesignViewport.x = config->DesignWidth; + g_sceneDesignViewport.y = config->DesignHeight; + IAE_LOG_INFO("Booting IAEngine for ", g_gameName); SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeRight"); diff --git a/Engine/Src/Imp/CPP/Renderer/Renderer.cpp b/Engine/Src/Imp/CPP/Renderer/Renderer.cpp index c5f2fd5..82cde09 100644 --- a/Engine/Src/Imp/CPP/Renderer/Renderer.cpp +++ b/Engine/Src/Imp/CPP/Renderer/Renderer.cpp @@ -39,11 +39,7 @@ namespace ia::iae Renderer::State Renderer::s_state{}; SDL_GPUDevice *Renderer::s_gpuDevice{}; - SDL_GPUTexture *Renderer::s_renderTargetSceneColor{}; - SDL_GPUTexture *Renderer::s_renderTargetDebugDrawColor{}; - Pipeline *Renderer::s_geometryPipeline{}; - Pipeline *Renderer::s_postprocessPipeline{}; Renderer::Geometry *Renderer::s_quadGeometry{}; Renderer::Geometry *Renderer::s_circleGeometry{}; @@ -54,10 +50,12 @@ namespace ia::iae SDL_GPUCommandBuffer *Renderer::s_activeCommandBuffer{}; SDL_GPUColorTargetInfo Renderer::s_colorTargetInfo{}; class CameraComponent *Renderer::s_activeCamera{}; + BOOL Renderer::s_ySortingEnabled{false}; + SDL_Rect Renderer::s_defaultScissor{}; + SDL_GPUViewport Renderer::s_defaultViewport{}; - SDL_Rect Renderer::s_scissor{0, 0, 0, 0}; - SDL_GPUViewport Renderer::s_activeViewport{}; - Vec2 Renderer::s_sceneScaleFactor{1.0f, 1.0f}; + EXTERN Vec2 g_sceneScalingFactor; + EXTERN Vec2 g_sceneDesignViewport; VOID Renderer::Initialize() { @@ -81,7 +79,7 @@ namespace ia::iae SDL_GetWindowSizeInPixels(g_windowHandle, &s_screenWidth, &s_screenHeight); OnScreenResize(s_screenWidth, s_screenHeight); - // Initialize Pipelines + // Initialize Pipeline s_geometryPipeline = new Pipeline( Pipeline::StageDesc{ .SourceData = SHADER_SOURCE_GEOMETRY_VERT, @@ -96,20 +94,6 @@ namespace ia::iae .UniformBufferCount = 1, }, true, true); - s_postprocessPipeline = new Pipeline( - Pipeline::StageDesc{ - .SourceData = SHADER_SOURCE_POSTPROCESS_VERT, - .SourceLength = sizeof(SHADER_SOURCE_POSTPROCESS_VERT), - .SamplerCount = 0, - .UniformBufferCount = 0, - }, - Pipeline::StageDesc{ - .SourceData = SHADER_SOURCE_POSTPROCESS_FRAG, - .SourceLength = sizeof(SHADER_SOURCE_POSTPROCESS_FRAG), - .SamplerCount = 2, - .UniformBufferCount = 0, - }, - false, false); DebugDraw::Initialize(); @@ -256,10 +240,6 @@ namespace ia::iae DebugDraw::Terminate(); delete s_geometryPipeline; - delete s_postprocessPipeline; - - GPUResourceManager::DestroyTexture(s_renderTargetSceneColor); - GPUResourceManager::DestroyTexture(s_renderTargetDebugDrawColor); GPUResourceManager::Terminate(); @@ -267,6 +247,8 @@ namespace ia::iae SDL_DestroyGPUDevice(s_gpuDevice); } + ImDrawData *g_imDrawData{}; + VOID Renderer::BeginFrame() { s_drawEntries.clear(); @@ -274,18 +256,50 @@ namespace ia::iae if (!(s_activeCommandBuffer = SDL_AcquireGPUCommandBuffer(s_gpuDevice))) THROW_UNKNOWN("Failed to acquire SDL GPU command buffer: ", SDL_GetError()); + SDL_GPUTexture *swapChainTexture{}; + if (!SDL_WaitAndAcquireGPUSwapchainTexture(s_activeCommandBuffer, g_windowHandle, &swapChainTexture, + (PUINT32) &s_screenWidth, (PUINT32) &s_screenHeight)) + THROW_UNKNOWN("Failed to acquire SDL GPU Swapchain texture: ", SDL_GetError()); + + if (!swapChainTexture) + return; + + DebugDraw::Render(); + g_imDrawData = ImGui::GetDrawData(); + ImGui_ImplSDLGPU3_PrepareDrawData(g_imDrawData, s_activeCommandBuffer); + const auto clearColor = WorldManager::GetActiveScene()->BackgroundColor().GetAsFloatVec(); s_colorTargetInfo.clear_color = SDL_FColor{clearColor.x, clearColor.y, clearColor.z, 1.0f}; - s_colorTargetInfo.texture = s_renderTargetSceneColor; + s_colorTargetInfo.texture = swapChainTexture; s_activeRenderPass = SDL_BeginGPURenderPass(s_activeCommandBuffer, &s_colorTargetInfo, 1, nullptr); SDL_BindGPUGraphicsPipeline(s_activeRenderPass, s_geometryPipeline->GetHandle()); SDL_PushGPUVertexUniformData(s_activeCommandBuffer, 0, s_activeCamera ? s_activeCamera->GetProjectionMatrix() : &IdentityMatrix, sizeof(Mat4)); + + s_state.Scissor = s_defaultScissor; } VOID Renderer::EndFrame() + { + std::sort(s_drawEntries.begin(), s_drawEntries.end(), [](IN CONST DrawEntry &a, IN CONST DrawEntry &b) { + if (a.Layer != b.Layer) + return a.Layer < b.Layer; + return a.SortIndex < b.SortIndex; + }); + + for (const auto &t : s_drawEntries) + Draw(t); + + ImGui_ImplSDLGPU3_RenderDrawData(g_imDrawData, s_activeCommandBuffer, s_activeRenderPass); + + SDL_EndGPURenderPass(s_activeRenderPass); + + SDL_SubmitGPUCommandBuffer(s_activeCommandBuffer); + } + + VOID Renderer::Draw(IN CONST DrawEntry &t) { #pragma pack(push, 1) @@ -299,78 +313,39 @@ namespace ia::iae #pragma pack(pop) - std::sort(s_drawEntries.begin(), s_drawEntries.end(), [](IN CONST DrawEntry &a, IN CONST DrawEntry &b) { - if (a.Layer != b.Layer) - return a.Layer < b.Layer; - return a.SortIndex < b.SortIndex; - }); + Vec2 position = t.DrawState.Position * g_sceneScalingFactor; + Vec2 scale = t.DrawState.Scale * g_sceneScalingFactor; - for (const auto &t : s_drawEntries) - { - SDL_PushGPUVertexUniformData( - s_activeCommandBuffer, 1, - (s_activeCamera && t.DrawState.CameraRelative) ? s_activeCamera->GetViewMatrix() : &IdentityMatrix, - sizeof(Mat4)); + Mat4 modelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3{position.x, position.y, 0}); + modelMatrix = glm::rotate(modelMatrix, t.DrawState.Rotation, glm::vec3(0.0f, 0.0f, 1.0f)); + modelMatrix = glm::scale(modelMatrix, glm::vec3{scale.x, scale.y, 1.0f}); - SDL_PushGPUVertexUniformData(Renderer::s_activeCommandBuffer, 2, &t.DrawState.ModelMatrix, sizeof(Mat4)); + SDL_PushGPUVertexUniformData(s_activeCommandBuffer, 1, + (s_activeCamera && t.DrawState.CameraRelative) ? s_activeCamera->GetViewMatrix() + : &IdentityMatrix, + sizeof(Mat4)); - s_fragmentUniform.ColorOverlay = t.DrawState.ColorOverlay.GetAsFloatVec(); - s_fragmentUniform.FlippedH = t.DrawState.FlippedH; - s_fragmentUniform.FlippedV = t.DrawState.FlippedV; - s_fragmentUniform.TextureOffset = t.DrawState.TextureOffset; - SDL_GPUTextureSamplerBinding textureBinding{.texture = t.DrawState.ActiveTexture, - .sampler = ((t.DrawState.TextureOffset.x <= FLOAT32_EPSILON) && - (t.DrawState.TextureOffset.y <= FLOAT32_EPSILON)) - ? GPUResourceManager::GetSampler_LinearClamp() - : GPUResourceManager::GetSampler_LinearRepeat()}; - SDL_BindGPUFragmentSamplers(s_activeRenderPass, 0, &textureBinding, 1); - SDL_PushGPUFragmentUniformData(s_activeCommandBuffer, 0, &s_fragmentUniform, sizeof(s_fragmentUniform)); + SDL_PushGPUVertexUniformData(Renderer::s_activeCommandBuffer, 2, &modelMatrix, sizeof(Mat4)); - // SDL_SetGPUScissor(s_activeRenderPass, &s_scissor); - // SDL_SetGPUViewport(s_activeRenderPass, &s_activeViewport); + s_fragmentUniform.ColorOverlay = t.DrawState.ColorOverlay.GetAsFloatVec(); + s_fragmentUniform.FlippedH = t.DrawState.FlippedH; + s_fragmentUniform.FlippedV = t.DrawState.FlippedV; + s_fragmentUniform.TextureOffset = t.DrawState.TextureOffset; + SDL_GPUTextureSamplerBinding textureBinding{.texture = t.DrawState.ActiveTexture, + .sampler = ((t.DrawState.TextureOffset.x <= FLOAT32_EPSILON) && + (t.DrawState.TextureOffset.y <= FLOAT32_EPSILON)) + ? GPUResourceManager::GetSampler_LinearClamp() + : GPUResourceManager::GetSampler_LinearRepeat()}; + SDL_BindGPUFragmentSamplers(s_activeRenderPass, 0, &textureBinding, 1); + SDL_PushGPUFragmentUniformData(s_activeCommandBuffer, 0, &s_fragmentUniform, sizeof(s_fragmentUniform)); - SDL_GPUBufferBinding bufferBindings[] = {{.buffer = t.GeometryHandle->VertexBuffer, .offset = 0}, - {.buffer = t.GeometryHandle->IndexBuffer, .offset = 0}}; - SDL_BindGPUVertexBuffers(s_activeRenderPass, 0, bufferBindings, 1); - SDL_BindGPUIndexBuffer(s_activeRenderPass, &bufferBindings[1], SDL_GPU_INDEXELEMENTSIZE_32BIT); - SDL_DrawGPUIndexedPrimitives(s_activeRenderPass, t.GeometryHandle->IndexCount, 1, 0, 0, 0); - } + SDL_SetGPUScissor(s_activeRenderPass, &t.DrawState.Scissor); - SDL_EndGPURenderPass(s_activeRenderPass); - - DebugDraw::Render(); - const auto imDrawData = ImGui::GetDrawData(); - ImGui_ImplSDLGPU3_PrepareDrawData(imDrawData, s_activeCommandBuffer); - s_colorTargetInfo.load_op = SDL_GPU_LOADOP_CLEAR; - s_colorTargetInfo.clear_color = SDL_FColor{0.0f, 0.0f, 0.0f, 0.0f}; - s_colorTargetInfo.texture = s_renderTargetDebugDrawColor; - s_activeRenderPass = SDL_BeginGPURenderPass(s_activeCommandBuffer, &s_colorTargetInfo, 1, nullptr); - ImGui_ImplSDLGPU3_RenderDrawData(imDrawData, s_activeCommandBuffer, s_activeRenderPass); - SDL_EndGPURenderPass(s_activeRenderPass); - - SDL_GPUTexture *swapChainTexture{}; - if (!SDL_WaitAndAcquireGPUSwapchainTexture(s_activeCommandBuffer, g_windowHandle, &swapChainTexture, - (PUINT32) &s_screenWidth, (PUINT32) &s_screenHeight)) - THROW_UNKNOWN("Failed to acquire SDL GPU Swapchain texture: ", SDL_GetError()); - - if (!swapChainTexture) - return; - - s_colorTargetInfo.clear_color = SDL_FColor{1.0f, 1.0f, 1.0f, 1.0f}; - s_colorTargetInfo.load_op = SDL_GPU_LOADOP_CLEAR; - s_colorTargetInfo.texture = swapChainTexture; - - s_activeRenderPass = SDL_BeginGPURenderPass(s_activeCommandBuffer, &s_colorTargetInfo, 1, nullptr); - SDL_BindGPUGraphicsPipeline(s_activeRenderPass, s_postprocessPipeline->GetHandle()); - SDL_GPUTextureSamplerBinding textureBindings[2] = { - {.texture = s_renderTargetSceneColor, .sampler = GPUResourceManager::GetSampler_LinearClamp()}, - {.texture = s_renderTargetDebugDrawColor, .sampler = GPUResourceManager::GetSampler_LinearClamp()}, - }; - SDL_BindGPUFragmentSamplers(s_activeRenderPass, 0, textureBindings, 2); - SDL_DrawGPUPrimitives(s_activeRenderPass, 6, 1, 0, 0); - SDL_EndGPURenderPass(s_activeRenderPass); - - SDL_SubmitGPUCommandBuffer(s_activeCommandBuffer); + SDL_GPUBufferBinding bufferBindings[] = {{.buffer = t.GeometryHandle->VertexBuffer, .offset = 0}, + {.buffer = t.GeometryHandle->IndexBuffer, .offset = 0}}; + SDL_BindGPUVertexBuffers(s_activeRenderPass, 0, bufferBindings, 1); + SDL_BindGPUIndexBuffer(s_activeRenderPass, &bufferBindings[1], SDL_GPU_INDEXELEMENTSIZE_32BIT); + SDL_DrawGPUIndexedPrimitives(s_activeRenderPass, t.GeometryHandle->IndexCount, 1, 0, 0, 0); } VOID Renderer::OnScreenResize(IN INT32 newWidth, IN INT32 newHeight) @@ -378,38 +353,21 @@ namespace ia::iae s_screenWidth = newWidth; s_screenHeight = newHeight; - if (s_renderTargetSceneColor) - GPUResourceManager::DestroyTexture(s_renderTargetSceneColor); - if (s_renderTargetDebugDrawColor) - GPUResourceManager::DestroyTexture(s_renderTargetDebugDrawColor); + s_defaultScissor = {0, 0, newWidth, newHeight}; - s_renderTargetSceneColor = GPUResourceManager::CreateTexture( - SDL_GPU_TEXTUREUSAGE_COLOR_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER, s_screenWidth, s_screenHeight, nullptr, - SDL_GetGPUSwapchainTextureFormat(s_gpuDevice, g_windowHandle)); - s_renderTargetDebugDrawColor = GPUResourceManager::CreateTexture( - SDL_GPU_TEXTUREUSAGE_COLOR_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER, s_screenWidth, s_screenHeight, nullptr, - SDL_GetGPUSwapchainTextureFormat(s_gpuDevice, g_windowHandle)); - - s_scissor = {0, 0, newWidth, newHeight}; - - s_activeViewport.x = 0; - s_activeViewport.y = 0; - s_activeViewport.w = newWidth; - s_activeViewport.h = newHeight; - s_activeViewport.min_depth = 0.0f; - s_activeViewport.max_depth = 1.0f; + s_defaultViewport.x = 0; + s_defaultViewport.y = 0; + s_defaultViewport.w = newWidth; + s_defaultViewport.h = newHeight; + s_defaultViewport.min_depth = 0.0f; + s_defaultViewport.max_depth = 1.0f; if (s_activeCamera) s_activeCamera->SetViewport(newWidth, newHeight); - const auto activeScene = WorldManager::GetActiveScene(); - if (activeScene) - { - const auto sceneViewport = activeScene->Viewport(); - s_sceneScaleFactor = {(FLOAT32) newWidth / (FLOAT32) sceneViewport.x, - (FLOAT32) newHeight / (FLOAT32) sceneViewport.y}; - IAE_LOG_INFO("Updated Scene Scale Factor: (", s_sceneScaleFactor.x, ", ", s_sceneScaleFactor.y, ")"); - } + g_sceneScalingFactor = {(FLOAT32) newWidth / g_sceneDesignViewport.x, + (FLOAT32) newHeight / g_sceneDesignViewport.y}; + IAE_LOG_INFO("Updated Scene Scale Factor: (", g_sceneScalingFactor.x, ", ", g_sceneScalingFactor.y, ")"); } SDL_GPUTextureFormat Renderer::GetRenderTargetFormat() @@ -436,36 +394,38 @@ namespace ia::iae delete handle; } - VOID Renderer::DrawGeometry(IN Geometry *handle, IN UINT8 layer, IN UINT16 sortIndex) + VOID Renderer::DrawGeometry(IN Geometry *handle, IN SDL_GPUTexture *texture, IN Vec2 position, IN Vec2 scale, + IN FLOAT32 rotation, IN UINT8 layer, IN UINT16 sortIndex) { - const auto t = (UINT16) (sortIndex + ((UINT16) s_state.PositionY * s_state.YSortingEnabled)); + s_state.ActiveTexture = texture; + s_state.Position = position; + s_state.Rotation = rotation; + s_state.Scale = scale; s_drawEntries.pushBack( - DrawEntry{.Layer = layer, .SortIndex = t, .DrawState = s_state, .GeometryHandle = handle}); + DrawEntry{.Layer = layer, + .SortIndex = (UINT16) (sortIndex + ((UINT16) s_state.Position.y * s_ySortingEnabled)), + .DrawState = s_state, + .GeometryHandle = handle}); } VOID Renderer::DrawText(IN CONST String &text, IN Vec2 position, IN FLOAT32 scale, IN FLOAT32 rotation, IN UINT8 layer, IN UINT16 sortIndex) { + const auto t = (UINT16) (sortIndex + ((UINT16) s_state.Position.y * s_ySortingEnabled)); const auto &font = FontManager::GetFont("Roboto"); - const auto t = (UINT16) (sortIndex + ((UINT16) s_state.PositionY * s_state.YSortingEnabled)); - Vec3 p{}; - Vec3 s{}; for (const auto &c : text) { if (!c) break; + const auto glyph = font.Chars[(UINT8) c]; - p = Vec3(position.x, position.y, 0.0f) + - Vec3(glyph.Bearing.x, glyph.Size.y - glyph.Bearing.y, 0.0f) * scale; - p.y += (16 - glyph.Size.y) * scale; - s = Vec3(scale * glyph.Size.x, scale * glyph.Size.y, 1.0f); - s_state.ActiveTexture = glyph.Texture; - s_state.PositionY = position.y; - s_state.ModelMatrix = glm::translate(glm::mat4(1.0f), p); - s_state.ModelMatrix = glm::rotate(s_state.ModelMatrix, rotation, glm::vec3(0.0f, 0.0f, 1.0f)); - s_state.ModelMatrix = glm::scale(s_state.ModelMatrix, s); + s_state.Position = position + Vec2(glyph.Bearing.x, glyph.Size.y - glyph.Bearing.y) * scale; + s_state.Position.y += (16 - glyph.Size.y) * scale; + s_state.Rotation = rotation; + s_state.Scale = Vec2(scale * glyph.Size.x, scale * glyph.Size.y); + s_drawEntries.pushBack( DrawEntry{.Layer = layer, .SortIndex = t, .DrawState = s_state, .GeometryHandle = s_quadGeometry}); @@ -502,11 +462,6 @@ namespace ia::iae return Renderer::s_activeCamera; } - Vec2 Engine::GetRendererScalingFactor() - { - return Renderer::s_sceneScaleFactor; - } - Handle Engine::CreateGeometry(IN CONST Vector &vertices, IN CONST Vector &indices) { return (Handle) Renderer::CreateGeometry(vertices, indices); @@ -517,9 +472,11 @@ namespace ia::iae Renderer::DestroyGeometry((Renderer::Geometry *) geometry); } - VOID Engine::DrawGeometry(IN Handle handle, IN UINT8 layer, IN UINT16 sortIndex) + VOID Engine::DrawGeometry(IN Handle handle, IN Handle texture, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, + IN UINT8 layer, IN UINT16 sortIndex) { - Renderer::DrawGeometry((Renderer::Geometry *) handle, layer, sortIndex); + Renderer::DrawGeometry((Renderer::Geometry *) handle, ResourceManager::GetTextureFromImage(texture), position, + scale, rotation, layer, sortIndex); } VOID Engine::DrawText(IN CONST String &text, IN Vec2 position, IN FLOAT32 scale, IN FLOAT32 rotation, @@ -528,10 +485,24 @@ namespace ia::iae Renderer::DrawText(text, position, scale, rotation, layer, sortIndex); } + VOID Engine::DrawQuad(IN Vec2 position, IN Handle texture, IN Vec2 scale, IN FLOAT32 rotation, IN UINT8 layer, + IN UINT16 sortIndex) + { + Renderer::DrawGeometry(Renderer::s_quadGeometry, ResourceManager::GetTextureFromImage(texture), position, scale, + rotation, layer, sortIndex); + } + + VOID Engine::DrawCircle(IN Vec2 position, IN Handle texture, IN FLOAT32 radius, IN FLOAT32 rotation, IN UINT8 layer, + IN UINT16 sortIndex) + { + Renderer::DrawGeometry(Renderer::s_circleGeometry, ResourceManager::GetTextureFromImage(texture), position, + {radius, radius}, rotation, layer, sortIndex); + } + VOID Engine::SetRenderState_Scissor(IN IVec4 rect) { - Renderer::s_scissor = rect.z ? SDL_Rect{0, 0, Renderer::s_screenWidth, Renderer::s_screenHeight} - : SDL_Rect{rect.x, rect.y, rect.z, rect.w}; + Renderer::s_state.Scissor = rect.z ? SDL_Rect{0, 0, Renderer::s_screenWidth, Renderer::s_screenHeight} + : SDL_Rect{rect.x, rect.y, rect.z, rect.w}; } VOID Engine::SetRenderState_FlippedH(IN BOOL value) @@ -559,35 +530,9 @@ namespace ia::iae Renderer::s_state.CameraRelative = value; } - VOID Engine::SetRenderState_Texture(IN Handle image) - { - Renderer::s_state.ActiveTexture = ResourceManager::GetTextureFromImage(image); - } - - VOID Engine::SetRenderState_Transform(IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation) - { - position *= Renderer::s_sceneScaleFactor; - scale *= Renderer::s_sceneScaleFactor; - - Renderer::s_state.PositionY = position.y; - - Renderer::s_state.ModelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3{position.x, position.y, 0}); - Renderer::s_state.ModelMatrix = - glm::rotate(Renderer::s_state.ModelMatrix, rotation, glm::vec3(0.0f, 0.0f, 1.0f)); - Renderer::s_state.ModelMatrix = glm::scale(Renderer::s_state.ModelMatrix, glm::vec3{scale.x, scale.y, 1.0f}); - } - - VOID Engine::SetRenderState_TransformUI(IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation) - { - Renderer::s_state.ModelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3{position.x, position.y, 0}); - Renderer::s_state.ModelMatrix = - glm::rotate(Renderer::s_state.ModelMatrix, rotation, glm::vec3(0.0f, 0.0f, 1.0f)); - Renderer::s_state.ModelMatrix = glm::scale(Renderer::s_state.ModelMatrix, glm::vec3{scale.x, scale.y, 1.0f}); - } - VOID Engine::SetRenderState_YSortingEnabled(IN BOOL value) { - Renderer::s_state.YSortingEnabled = value; + Renderer::s_ySortingEnabled = value; } Handle Engine::GetGeometry_Quad() diff --git a/Engine/Src/Imp/CPP/ResourceManager.cpp b/Engine/Src/Imp/CPP/ResourceManager.cpp index 46363d9..b81d085 100644 --- a/Engine/Src/Imp/CPP/ResourceManager.cpp +++ b/Engine/Src/Imp/CPP/ResourceManager.cpp @@ -61,8 +61,9 @@ namespace ia::iae Handle ResourceManager::CreateImage(IN CONST String &name, IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height) { - const auto texture = GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, width, height, rgbaData, - SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM, true); + const auto texture = + GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, width, + height, rgbaData, SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM, true); s_imageHandles.pushBack(ImageResource{.OriginalWidth = width, .OriginalHeight = height, .OriginalPixelData = new UINT8[width * height * 4], @@ -137,7 +138,7 @@ namespace ia::iae return {t.OriginalWidth, t.OriginalHeight}; } - Handle ResourceManager::RescaleImage(IN Handle image, IN Vec2 factor) + Handle ResourceManager::RescaleImage(IN Handle image, IN Vec2 factor, IN BOOL makeOriginal) { if (!s_imageHandles[image].OriginalPixelData) return image; @@ -145,21 +146,29 @@ namespace ia::iae const auto newWidth = (INT32) (s_imageHandles[image].OriginalWidth * factor.x); const auto newHeight = (INT32) (s_imageHandles[image].OriginalHeight * factor.y); - if (!newWidth || !newHeight || - ((newWidth <= s_imageHandles[image].OriginalWidth) && (newHeight <= s_imageHandles[image].OriginalHeight))) + if (!newWidth || !newHeight) return image; const auto newPixelData = stbir_resize_uint8_linear(s_imageHandles[image].OriginalPixelData, s_imageHandles[image].OriginalWidth, s_imageHandles[image].OriginalHeight, s_imageHandles[image].OriginalWidth * 4, nullptr, newWidth, newHeight, newWidth * 4, stbir_pixel_layout::STBIR_RGBA); - const auto texture = GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, newWidth, newHeight, - newPixelData, SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM, true); + const auto texture = GPUResourceManager::CreateTexture( + SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, newWidth, newHeight, newPixelData, + SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM, true); GPUResourceManager::DestroyTexture(s_imageHandles[image].Handle); s_imageHandles[image].Handle = texture; s_imageHandles[image].Width = newWidth; s_imageHandles[image].Height = newHeight; - free(newPixelData); + if (!makeOriginal) + { + free(newPixelData); + return image; + } + free(s_imageHandles[image].OriginalPixelData); + s_imageHandles[image].OriginalPixelData = newPixelData; + s_imageHandles[image].OriginalWidth = newWidth; + s_imageHandles[image].OriginalHeight = newHeight; return image; } diff --git a/Engine/Src/Imp/CPP/SceneManager.cpp b/Engine/Src/Imp/CPP/SceneManager.cpp index 2ab3b88..303ff1f 100644 --- a/Engine/Src/Imp/CPP/SceneManager.cpp +++ b/Engine/Src/Imp/CPP/SceneManager.cpp @@ -101,9 +101,6 @@ namespace ia::iae { auto t = propRoot.child("Extent"); scene->Extent() = Vec2{t.attribute("width").as_float(), t.attribute("height").as_float()}; - - t = propRoot.child("Viewport"); - scene->Viewport() = Vec2{t.attribute("width").as_float(), t.attribute("height").as_float()}; } // Process Nodes diff --git a/Engine/Src/Imp/CPP/UI.cpp b/Engine/Src/Imp/CPP/UI.cpp index 37cd05b..d2ed7aa 100644 --- a/Engine/Src/Imp/CPP/UI.cpp +++ b/Engine/Src/Imp/CPP/UI.cpp @@ -589,15 +589,13 @@ namespace ia::iae Rml::TextureHandle texture) { - Engine::SetRenderState_Texture((Handle) texture); Engine::SetRenderState_FlippedH(false); Engine::SetRenderState_FlippedV(false); Engine::SetRenderState_ColorOverlay({255, 255, 255, 255}); Engine::SetRenderState_TextureOffset({0, 0}); Engine::SetRenderState_CameraRelative(false); - Engine::SetRenderState_Transform({translation.x, translation.y}, {1.0f, 1.0f}, 0); - Engine::DrawGeometry((Handle) geometry, 0xFF, 0); + Engine::DrawGeometry((Handle) geometry, (Handle) texture, {translation.x, translation.y}, {1.0f, 1.0f}, 0, 0xFF, 0); } void RmlUIRenderInterface::ReleaseGeometry(Rml::CompiledGeometryHandle geometry) diff --git a/Engine/Src/Imp/HPP/InputManager.hpp b/Engine/Src/Imp/HPP/InputManager.hpp index b9868c3..feac4ab 100644 --- a/Engine/Src/Imp/HPP/InputManager.hpp +++ b/Engine/Src/Imp/HPP/InputManager.hpp @@ -41,7 +41,10 @@ namespace ia::iae STATIC VOID SwitchModeToText(); STATIC VOID SwitchModeToAction(); + STATIC BOOL IsPointerDown(); STATIC Vec2 GetPointerPosition(); + STATIC BOOL IsPointerDown(IN CONST Vec2& start, IN CONST Vec2& end); + STATIC BOOL DidPointerClick(IN CONST Vec2& start, IN CONST Vec2& end); STATIC BOOL IsKeyDown(IN InputKey key); STATIC BOOL WasKeyPressed(IN InputKey key); @@ -74,6 +77,8 @@ namespace ia::iae STATIC INT16 s_horizontalAxis; STATIC BOOL s_keys[256]; STATIC BOOL s_prevKeys[256]; + STATIC BOOL s_pointerState; + STATIC BOOL s_pointerPrevState; STATIC Vec2 s_pointerPosition; STATIC BOOL s_onScreenGamePadEnabled; STATIC BOOL s_keyboardGamePadEnabled; diff --git a/Engine/Src/Imp/HPP/Renderer/Renderer.hpp b/Engine/Src/Imp/HPP/Renderer/Renderer.hpp index 30460ac..22863ec 100644 --- a/Engine/Src/Imp/HPP/Renderer/Renderer.hpp +++ b/Engine/Src/Imp/HPP/Renderer/Renderer.hpp @@ -16,17 +16,14 @@ #pragma once -#include #include +#include namespace ia::iae { class Renderer { public: - STATIC CONSTEXPR FLOAT32 MIN_DEPTH = -2097152.0f; - STATIC CONSTEXPR FLOAT32 MAX_DEPTH = 2097152.0f; - struct Geometry { INT32 IndexCount{}; @@ -39,12 +36,16 @@ namespace ia::iae BOOL FlippedH{false}; BOOL FlippedV{false}; BOOL CameraRelative{true}; - BOOL YSortingEnabled{false}; Color ColorOverlay{}; Vec2 TextureOffset{0.0f, 0.0f}; - SDL_GPUTexture* ActiveTexture{nullptr}; - Mat4 ModelMatrix{1.0f}; - FLOAT32 PositionY{}; + + Vec2 Position{}; + Vec2 Scale{}; + FLOAT32 Rotation; + + SDL_Rect Scissor{}; + + SDL_GPUTexture *ActiveTexture{nullptr}; }; struct DrawEntry @@ -52,7 +53,7 @@ namespace ia::iae UINT8 Layer{}; UINT16 SortIndex{}; State DrawState{}; - Geometry* GeometryHandle{}; + Geometry *GeometryHandle{}; }; public: @@ -67,11 +68,13 @@ namespace ia::iae STATIC VOID OnScreenResize(IN INT32 newWidth, IN INT32 newHeight); public: - STATIC Geometry* CreateGeometry(IN CONST Vector &vertices, IN CONST Vector &indices); - STATIC VOID DestroyGeometry(IN Geometry* handle); + STATIC Geometry *CreateGeometry(IN CONST Vector &vertices, IN CONST Vector &indices); + STATIC VOID DestroyGeometry(IN Geometry *handle); - STATIC VOID DrawGeometry(IN Geometry* handle, IN UINT8 layer, IN UINT16 sortIndex); - STATIC VOID DrawText(IN CONST String& text, IN Vec2 position, IN FLOAT32 scale, IN FLOAT32 rotation, IN UINT8 layer, IN UINT16 sortIndex); + STATIC VOID DrawGeometry(IN Geometry *handle, IN SDL_GPUTexture* texture, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, + IN UINT8 layer, IN UINT16 sortIndex); + STATIC VOID DrawText(IN CONST String &text, IN Vec2 position, IN FLOAT32 scale, IN FLOAT32 rotation, + IN UINT8 layer, IN UINT16 sortIndex); STATIC SDL_GPUTextureFormat GetRenderTargetFormat(); @@ -80,25 +83,25 @@ namespace ia::iae return s_gpuDevice; } + private: + STATIC VOID Draw(IN CONST DrawEntry &entity); + private: STATIC State s_state; STATIC INT32 s_screenWidth; STATIC INT32 s_screenHeight; STATIC SDL_GPUDevice *s_gpuDevice; - STATIC SDL_GPUTexture *s_renderTargetSceneColor; - STATIC SDL_GPUTexture *s_renderTargetDebugDrawColor; - STATIC Pipeline* s_geometryPipeline; - STATIC Pipeline* s_postprocessPipeline; - STATIC Geometry* s_quadGeometry; - STATIC Geometry* s_circleGeometry; + STATIC Pipeline *s_geometryPipeline; + STATIC Geometry *s_quadGeometry; + STATIC Geometry *s_circleGeometry; STATIC Vector s_drawEntries; - STATIC SDL_GPURenderPass* s_activeRenderPass; - STATIC SDL_GPUCommandBuffer* s_activeCommandBuffer; + STATIC SDL_GPURenderPass *s_activeRenderPass; + STATIC SDL_GPUCommandBuffer *s_activeCommandBuffer; STATIC SDL_GPUColorTargetInfo s_colorTargetInfo; STATIC class CameraComponent *s_activeCamera; - STATIC SDL_Rect s_scissor; - STATIC SDL_GPUViewport s_activeViewport; - STATIC Vec2 s_sceneScaleFactor; + STATIC BOOL s_ySortingEnabled; + STATIC SDL_Rect s_defaultScissor; + STATIC SDL_GPUViewport s_defaultViewport; friend class Engine; }; diff --git a/Engine/Src/Imp/HPP/ResourceManager.hpp b/Engine/Src/Imp/HPP/ResourceManager.hpp index f88969e..529a7b1 100644 --- a/Engine/Src/Imp/HPP/ResourceManager.hpp +++ b/Engine/Src/Imp/HPP/ResourceManager.hpp @@ -53,7 +53,7 @@ namespace ia::iae STATIC IVec2 GetImageExtent(IN Handle image); STATIC IVec2 GetImageOriginalExtent(IN Handle image); STATIC VOID RescaleAllImages(IN Vec2 factor); - STATIC Handle RescaleImage(IN Handle image, IN Vec2 factor); + STATIC Handle RescaleImage(IN Handle image, IN Vec2 factor, IN BOOL makeOriginal = false); STATIC Handle CombineImages(IN CONST Vector &images, IN INT32 unitWidth, IN INT32 unitHeight, IN INT32 unitCountX, IN INT32 unitCountY); diff --git a/Engine/Src/Inc/IAEngine/Components/UIButtonComponent.hpp b/Engine/Src/Inc/IAEngine/Components/UIButtonComponent.hpp index e69de29..69056dc 100644 --- a/Engine/Src/Inc/IAEngine/Components/UIButtonComponent.hpp +++ b/Engine/Src/Inc/IAEngine/Components/UIButtonComponent.hpp @@ -0,0 +1,79 @@ +// IAEngine: 2D Game Engine by IA +// Copyright (C) 2025 IASoft (PVT) LTD (oss@iasoft.dev) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#include + +namespace ia::iae +{ + class UIButtonComponent : public UIImageComponent + { + public: + UIButtonComponent(IN UINode *node); + + String &Label() + { + return m_label; + } + + CONST String &Label() CONST + { + return m_label; + } + + Vec2 &LabelPosition() + { + return m_labelPosition; + } + + FLOAT32 &LabelSize() + { + return m_labelSize; + } + + Color &LabelColor() + { + return m_labelColor; + } + + public: + VOID SetOnDownCallback(IN std::function callback) + { + m_onDownCallback = callback; + } + + VOID SetOnClickCallback(IN std::function callback) + { + m_onClickCallback = callback; + } + + public: + VOID Draw(); + VOID DebugDraw(); + + VOID Update(); + VOID FixedUpdate(); + + private: + String m_label{}; + Vec2 m_labelPosition{}; + FLOAT32 m_labelSize{1.0f}; + Color m_labelColor{0xFF, 0xFF, 0xFF, 0xFF}; + std::function m_onDownCallback; + std::function m_onClickCallback; + }; +} // namespace ia::iae \ No newline at end of file diff --git a/Engine/Src/Inc/IAEngine/Components/UIImageComponent.hpp b/Engine/Src/Inc/IAEngine/Components/UIImageComponent.hpp index e69de29..0565719 100644 --- a/Engine/Src/Inc/IAEngine/Components/UIImageComponent.hpp +++ b/Engine/Src/Inc/IAEngine/Components/UIImageComponent.hpp @@ -0,0 +1,54 @@ +// IAEngine: 2D Game Engine by IA +// Copyright (C) 2025 IASoft (PVT) LTD (oss@iasoft.dev) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#include + +namespace ia::iae +{ + class UIImageComponent : public IUIComponent + { + public: + UIImageComponent(IN UINode *node); + + Handle &Image() + { + return m_image; + } + + CONST Handle &Image() CONST + { + return m_image; + } + + CONST Vec2 &DrawnSize() CONST + { + return m_drawnSize; + } + + public: + VOID Draw(); + VOID DebugDraw(); + + VOID Update(); + VOID FixedUpdate(); + + private: + Handle m_image{}; + Vec2 m_drawnSize{}; + }; +} // namespace ia::iae \ No newline at end of file diff --git a/Engine/Src/Inc/IAEngine/Components/UILabelComponent.hpp b/Engine/Src/Inc/IAEngine/Components/UILabelComponent.hpp index 1dd8a11..180d7c6 100644 --- a/Engine/Src/Inc/IAEngine/Components/UILabelComponent.hpp +++ b/Engine/Src/Inc/IAEngine/Components/UILabelComponent.hpp @@ -23,7 +23,7 @@ namespace ia::iae class UILabelComponent : public IUIComponent { public: - UILabelComponent(IN UINode* node); + UILabelComponent(IN UINode *node); String &Label() { @@ -35,6 +35,11 @@ namespace ia::iae return m_label; } + struct Color &Color() + { + return m_color; + } + public: VOID Draw(); VOID DebugDraw(); @@ -44,5 +49,6 @@ namespace ia::iae private: String m_label{}; + struct Color m_color{0xFF, 0xFF, 0xFF, 0xFF}; }; } // namespace ia::iae \ No newline at end of file diff --git a/Engine/Src/Inc/IAEngine/Engine.hpp b/Engine/Src/Inc/IAEngine/Engine.hpp index 3eb62b4..f919da9 100644 --- a/Engine/Src/Inc/IAEngine/Engine.hpp +++ b/Engine/Src/Inc/IAEngine/Engine.hpp @@ -47,10 +47,12 @@ namespace ia::iae STATIC Handle GetGeometry_Circle(); STATIC Handle CreateGeometry(IN CONST Vector &vertices, IN CONST Vector &indices); STATIC VOID DestroyGeometry(IN Handle geometry); - STATIC VOID DrawGeometry(IN Handle handle, IN UINT8 layer, IN UINT16 sortIndex); STATIC IVec2 GetDisplayExtent(); STATIC FLOAT32 GetDisplayAspectRatio(); STATIC VOID ResizeDisplay(IN INT32 newWidth, IN INT32 newHeight); + STATIC VOID DrawGeometry(IN Handle geometry, IN Handle texture, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN UINT8 layer, IN UINT16 sortIndex); + STATIC VOID DrawQuad(IN Vec2 position, IN Handle texture, IN Vec2 scale, IN FLOAT32 rotation, IN UINT8 layer, IN UINT16 sortIndex); + STATIC VOID DrawCircle(IN Vec2 position, IN Handle texture, IN FLOAT32 radius, IN FLOAT32 rotation, IN UINT8 layer, IN UINT16 sortIndex); STATIC VOID DrawText(IN CONST String& text, IN Vec2 position, IN FLOAT32 scale, IN FLOAT32 rotation, IN UINT8 layer, IN UINT16 sortIndex); // Renderer State Functions @@ -61,10 +63,7 @@ namespace ia::iae STATIC VOID SetRenderState_YSortingEnabled(IN BOOL value); STATIC VOID SetRenderState_ColorOverlay(IN Color color); STATIC VOID SetRenderState_CameraRelative(IN BOOL value); - STATIC VOID SetRenderState_Texture(IN Handle image); - STATIC VOID SetRenderState_Transform(IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation); - STATIC VOID SetRenderState_TransformUI(IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation); - STATIC Vec2 GetRendererScalingFactor(); + STATIC Vec2 GetSceneScalingFactor(); // Debug Draw Functions STATIC VOID DebugDraw_SetColor(IN Color color); @@ -107,7 +106,12 @@ namespace ia::iae // Input Functions STATIC VOID Input_SwitchModeToText(); STATIC VOID Input_SwitchModeToAction(); + + STATIC BOOL Input_IsPointerDown(); STATIC Vec2 Input_GetPointerPosition(); + STATIC BOOL Input_DidPointerClick(IN CONST Vec2& start, IN CONST Vec2& end); + STATIC BOOL Input_IsPointerDown(IN CONST Vec2& start, IN CONST Vec2& end); + STATIC BOOL Input_IsKeyDown(IN InputKey key); STATIC BOOL Input_WasKeyPressed(IN InputKey key); STATIC BOOL Input_WasKeyReleased(IN InputKey key); diff --git a/Engine/Src/Inc/IAEngine/Scene.hpp b/Engine/Src/Inc/IAEngine/Scene.hpp index 2ffbdcd..d2ba591 100644 --- a/Engine/Src/Inc/IAEngine/Scene.hpp +++ b/Engine/Src/Inc/IAEngine/Scene.hpp @@ -48,11 +48,6 @@ namespace ia::iae return m_extent; } - IVec2 &Viewport() - { - return m_viewport; - } - Color &BackgroundColor() { return m_backgroundColor; @@ -62,7 +57,6 @@ namespace ia::iae String m_uiMarkup{}; String m_uiMarkupStyles{}; IVec2 m_extent{100, 100}; - IVec2 m_viewport{100, 100}; CameraComponent *m_camera{}; Color m_backgroundColor{0, 0, 0, 255}; Map> m_nodes; diff --git a/Resources/HUD/Button.png b/Resources/HUD/Button.png new file mode 100644 index 0000000..58c42a3 Binary files /dev/null and b/Resources/HUD/Button.png differ