Added Renderer

This commit is contained in:
Isuru Samarathunga
2025-09-12 16:03:33 +05:30
parent 70d9cb3a85
commit a0b5dc2af2
38 changed files with 609 additions and 139 deletions

View File

@ -0,0 +1,15 @@
// IAEngine: 2D Game Engine by IA
// Copyright (C) 2025 IAS (ias@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 <https://www.gnu.org/licenses/>.

View File

@ -0,0 +1,158 @@
// IAEngine: 2D Game Engine by IA
// Copyright (C) 2025 IAS (ias@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 <https://www.gnu.org/licenses/>.
#include <IAEngine/IAEngine.hpp>
#include <IAEngine/Rendering/Renderer.hpp>
#include <SDL3/SDL_gpu.h>
#include <backends/imgui_impl_sdl3.h>
#include <backends/imgui_impl_sdlgpu3.h>
namespace ia::iae
{
INT32 Renderer::s_width{};
INT32 Renderer::s_height{};
Vector<Renderer::DebugUIWindow> Renderer::s_debugUIWindows;
SDL_Window *g_windowHandle{};
SDL_GPUDevice *g_gpuDevice{};
// Render State
SDL_GPUCommandBuffer *g_cmdBuffer{};
SDL_GPURenderPass *g_renderPass{};
SDL_GPUTexture *g_swpChainTexture{};
// ImGUI State
ImGuiIO g_imGUIIO{};
ImDrawData* g_imDrawData{};
BOOL Renderer::Initialize(IN Engine *engine)
{
g_windowHandle = (SDL_Window *) engine->GetWindowHandle();
if (!(g_gpuDevice =
SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV | SDL_GPU_SHADERFORMAT_DXIL | SDL_GPU_SHADERFORMAT_MSL,
engine->IsDebugMode, nullptr)))
{
IAE_LOG_ERROR("Couldn't create SDL3 GPU Device: ", SDL_GetError());
return false;
}
if (!SDL_ClaimWindowForGPUDevice(g_gpuDevice, g_windowHandle))
{
IAE_LOG_ERROR("Couldn't initialize SDL3 GPU for the window: ", SDL_GetError());
return false;
}
SDL_SetGPUSwapchainParameters(g_gpuDevice, g_windowHandle, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_VSYNC);
const auto mainScale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
IMGUI_CHECKVERSION();
ImGui::CreateContext();
g_imGUIIO = ImGui::GetIO();
g_imGUIIO.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
g_imGUIIO.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
ImGui::StyleColorsClassic();
ImGuiStyle &style = ImGui::GetStyle();
style.ScaleAllSizes(mainScale);
style.FontScaleDpi = mainScale;
ImGui_ImplSDLGPU3_InitInfo initInfo{
.Device = g_gpuDevice,
.ColorTargetFormat = SDL_GetGPUSwapchainTextureFormat(g_gpuDevice, g_windowHandle),
.PresentMode = SDL_GPU_PRESENTMODE_VSYNC
};
ImGui_ImplSDL3_InitForSDLGPU(g_windowHandle);
ImGui_ImplSDLGPU3_Init(&initInfo);
return true;
}
VOID Renderer::Terminate()
{
SDL_WaitForGPUIdle(g_gpuDevice);
ImGui_ImplSDL3_Shutdown();
ImGui_ImplSDLGPU3_Shutdown();
ImGui::DestroyContext();
SDL_ReleaseWindowFromGPUDevice(g_gpuDevice, g_windowHandle);
SDL_DestroyGPUDevice(g_gpuDevice);
}
VOID Renderer::AddDebugUIWindow(IN PCCHAR title, IN CONST iam::Vec2f &position, IN CONST iam::Vec2f &size,
IN std::function<VOID()> contentDrawCallback)
{
s_debugUIWindows.pushBack(DebugUIWindow{title, position, size, contentDrawCallback});
}
VOID Renderer::BeginFrame()
{
ImGui_ImplSDLGPU3_NewFrame();
ImGui_ImplSDL3_NewFrame();
ImGui::NewFrame();
for (const auto &w : s_debugUIWindows)
{
ImGui::Begin(w.Title);
ImGui::SetWindowPos({w.Position.X, w.Position.Y});
ImGui::SetWindowSize({w.Size.X, w.Size.Y});
w.ContentDrawCallback();
ImGui::End();
}
ImGui::Render();
if (!(g_cmdBuffer = SDL_AcquireGPUCommandBuffer(g_gpuDevice)))
{
IAE_LOG_ERROR("Couldn't acquire SDL3 GPU command buffer: ", SDL_GetError());
return;
}
if (!SDL_WaitAndAcquireGPUSwapchainTexture(g_cmdBuffer, g_windowHandle, &g_swpChainTexture, (PUINT32) &s_width,
(PUINT32) &s_height))
{
IAE_LOG_ERROR("Couldn't acquire SDL3 GPU Swapchain texture: ", SDL_GetError());
return;
}
if (!g_swpChainTexture)
return;
g_imDrawData = ImGui::GetDrawData();
ImGui_ImplSDLGPU3_PrepareDrawData(g_imDrawData, g_cmdBuffer);
SDL_GPUColorTargetInfo colorTargetInfo = {0};
colorTargetInfo.texture = g_swpChainTexture;
colorTargetInfo.clear_color = SDL_FColor{0.33f, 0.33f, 0.33f, 1.0f};
colorTargetInfo.load_op = SDL_GPU_LOADOP_CLEAR;
colorTargetInfo.store_op = SDL_GPU_STOREOP_STORE;
g_renderPass = SDL_BeginGPURenderPass(g_cmdBuffer, &colorTargetInfo, 1, NULL);
}
VOID Renderer::EndFrame()
{
if (!g_swpChainTexture)
return;
ImGui_ImplSDLGPU3_RenderDrawData(g_imDrawData, g_cmdBuffer, g_renderPass);
SDL_EndGPURenderPass(g_renderPass);
SDL_SubmitGPUCommandBuffer(g_cmdBuffer);
}
} // namespace ia::iae

View File

@ -0,0 +1,47 @@
// IAEngine: 2D Game Engine by IA
// Copyright (C) 2025 IAS (ias@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 <https://www.gnu.org/licenses/>.
#include <IAEngine/IAEngine.hpp>
#include <IAEngine/Rendering/Texture.hpp>
#include <SDL3/SDL.h>
#define TEXTURE_HANDLE (SDL_Texture *) m_handle
namespace ia::iae
{
Texture::Texture(IN Engine *engine) : m_engine(engine)
{
}
Texture::~Texture()
{
SDL_DestroyTexture(TEXTURE_HANDLE);
}
VOID Texture::Draw(IN CONST iam::Vec3f &position, IN CONST iam::Vec3f &scale, IN FLOAT32 rotation, IN BOOL flipH,
IN BOOL flipV, IN CONST iam::Vec4f &colorOverlay) CONST
{
SDL_FRect rect{.x = position.X, .y = position.Y, .w = m_width * scale.X, .h = m_height * scale.Y};
//SDL_SetTextureColorModFloat(TEXTURE_HANDLE, colorOverlay.X, colorOverlay.Y, colorOverlay.Z);
//SDL_SetTextureAlphaModFloat(TEXTURE_HANDLE, colorOverlay.W);
//SDL_RenderTextureRotated((SDL_Renderer *) m_engine->GetRendererHandle(), TEXTURE_HANDLE, nullptr, &rect,
// rotation, nullptr,
// (SDL_FlipMode) (SDL_FLIP_NONE | (flipV ? SDL_FLIP_VERTICAL : SDL_FLIP_NONE) |
// (flipH ? SDL_FLIP_HORIZONTAL : SDL_FLIP_NONE)));
}
} // namespace ia::iae