diff --git a/Src/Editor/CMakeLists.txt b/Src/Editor/CMakeLists.txt index 2c1fae4..8b0ea4b 100644 --- a/Src/Editor/CMakeLists.txt +++ b/Src/Editor/CMakeLists.txt @@ -1,5 +1,7 @@ set(SRC_FILES + "imp/cpp/UI.cpp" "imp/cpp/Main.cpp" + "imp/cpp/GamePreview.cpp" # imgui "imp/cpp/Vendor/imgui/imgui.cpp" diff --git a/Src/Editor/imp/cpp/GamePreview.cpp b/Src/Editor/imp/cpp/GamePreview.cpp new file mode 100644 index 0000000..4d2342c --- /dev/null +++ b/Src/Editor/imp/cpp/GamePreview.cpp @@ -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 . + +#include +#include + +namespace ia::iae::editor +{ + +} + +#include + +C_DECL(GameRequestedConfig *Game_GetConfigRequest()) +{ + return nullptr; +} + +C_DECL(VOID Game_OnInitialize()) +{ +} + +C_DECL(VOID Game_OnTerminate()) +{ +} + +C_DECL(VOID Game_OnDebugDraw()) +{ +} + +C_DECL(VOID Game_OnFixedUpdate()) +{ +} + +C_DECL(VOID Game_OnUpdate(IN FLOAT32 deltaTime)) +{ +} + +C_DECL(VOID Game_OnResize(IN INT32 newWidth, IN INT32 newHeight)) +{ +} \ No newline at end of file diff --git a/Src/Editor/imp/cpp/Main.cpp b/Src/Editor/imp/cpp/Main.cpp index 2a9e50e..0ee4c93 100644 --- a/Src/Editor/imp/cpp/Main.cpp +++ b/Src/Editor/imp/cpp/Main.cpp @@ -14,169 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include -#include -#include - - -#include -#include -#include - -namespace ia::iae -{ - ImDrawData *g_imDrawData{}; - - EXTERN Vec2 g_designViewport; - EXTERN SDL_Window *g_windowHandle; - - INT32 Run(IN INT32 argc, IN PCCHAR argv[]) - { - INT32 frameCounter{0}; - IVec2 windowExtent{800, 600}; - g_designViewport = windowExtent; - - if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMEPAD)) - THROW_UNKNOWN("Failed to intialize SDL: ", SDL_GetError()); - - if (!(g_windowHandle = SDL_CreateWindow("IAEngine", windowExtent.x, windowExtent.y, - SDL_WINDOW_RESIZABLE | SDL_WINDOW_MAXIMIZED))) - THROW_UNKNOWN("Failed to create the SDL window: ", SDL_GetError()); - SDL_MaximizeWindow(g_windowHandle); - SDL_GetWindowSizeInPixels(g_windowHandle, &windowExtent.x, &windowExtent.y); - - IAEngine::__Initialize(); - - auto gamePreviewTexture = new RDC_Texture(RDC_Texture::EType::SAMPLED, 800, 600); - - const auto mainScale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); - - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - auto &imGUIIO = ImGui::GetIO(); - imGUIIO.IniFilename = nullptr; - imGUIIO.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; - imGUIIO.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; - - ImGui::StyleColorsClassic(); - - ImGuiStyle &style = ImGui::GetStyle(); - style.ScaleAllSizes(mainScale); - style.FontScaleDpi = mainScale; - - ImGui_ImplSDLGPU3_InitInfo initInfo{.Device = RDC_Device::GetHandle(), - .ColorTargetFormat = RDC_Device::GetSwapchainTextureFormat(), - .PresentMode = SDL_GPU_PRESENTMODE_VSYNC}; - ImGui_ImplSDL3_InitForSDLGPU(g_windowHandle); - ImGui_ImplSDLGPU3_Init(&initInfo); - - SDL_Event event{}; - while (true) - { - SDL_PollEvent(&event); - if (event.type == SDL_EVENT_QUIT) - break; - IAEngine::__ProcessEvent(&event); - IAEngine::__Update(); - ImGui_ImplSDL3_ProcessEvent(&event); - - frameCounter++; - if (frameCounter >= 60) - { - frameCounter = 0; - IAEngine::__FixedUpdate(); - } - - IAEngine::__RenderToTexture(gamePreviewTexture->GetHandle()); - - ImGui_ImplSDLGPU3_NewFrame(); - ImGui_ImplSDL3_NewFrame(); - ImGui::NewFrame(); - - { - ImGui::Begin("Scene"); - ImGui::Image(gamePreviewTexture->GetHandle(), {800, 600}); - ImGui::End(); - } - - ImGui::Render(); - - STATIC SDL_GPURenderPass *ActiveRenderPass{}; - STATIC SDL_GPUCommandBuffer *ActiveCommandBuffer{}; - STATIC SDL_GPUColorTargetInfo ActiveColorTargetInfo{.clear_color = SDL_FColor{0.0f, 0.0f, 0.0f, 1.0f}, - .load_op = SDL_GPU_LOADOP_CLEAR, - .store_op = SDL_GPU_STOREOP_STORE}; - - if (!(ActiveCommandBuffer = SDL_AcquireGPUCommandBuffer(RDC_Device::GetHandle()))) - THROW_UNKNOWN("Failed to acquire SDL GPU command buffer: ", SDL_GetError()); - - g_imDrawData = ImGui::GetDrawData(); - ImGui_ImplSDLGPU3_PrepareDrawData(g_imDrawData, ActiveCommandBuffer); - - SDL_GPUTexture *swapChainTexture{}; - if (!SDL_WaitAndAcquireGPUSwapchainTexture(ActiveCommandBuffer, g_windowHandle, &swapChainTexture, nullptr, - nullptr)) - THROW_UNKNOWN("Failed to acquire SDL GPU Swapchain texture: ", SDL_GetError()); - - ActiveColorTargetInfo.texture = swapChainTexture; - ActiveColorTargetInfo.clear_color = SDL_FColor{0.3f, 0.3f, 0.3f, 1.0f}; - ActiveRenderPass = SDL_BeginGPURenderPass(ActiveCommandBuffer, &ActiveColorTargetInfo, 1, nullptr); - ImGui_ImplSDLGPU3_RenderDrawData(g_imDrawData, ActiveCommandBuffer, ActiveRenderPass); - - SDL_EndGPURenderPass(ActiveRenderPass); - - SDL_SubmitGPUCommandBuffer(ActiveCommandBuffer); - - RDC_Device::WaitForIdle(); - } - - ImGui_ImplSDL3_Shutdown(); - ImGui_ImplSDLGPU3_Shutdown(); - ImGui::DestroyContext(); - - delete gamePreviewTexture; - - IAEngine::__Terminate(); - - SDL_DestroyWindow(g_windowHandle); - - return 0; - } -} // namespace ia::iae +#include int main(int argc, char *argv[]) { - return ia::iae::Run(argc, (const char **) argv); + return ia::iae::editor::UI::Run(argc, (const char **) argv); } - -#include - -C_DECL(GameRequestedConfig *Game_GetConfigRequest()) -{ - return nullptr; -} - -C_DECL(VOID Game_OnInitialize()) -{ -} - -C_DECL(VOID Game_OnTerminate()) -{ -} - -C_DECL(VOID Game_OnDebugDraw()) -{ - RDC::DrawRect({10, 10}, {700, 500}, {1.0f, 0.0f, 0.0f, 1.0f}); -} - -C_DECL(VOID Game_OnFixedUpdate()) -{ -} - -C_DECL(VOID Game_OnUpdate(IN FLOAT32 deltaTime)) -{ -} - -C_DECL(VOID Game_OnResize(IN INT32 newWidth, IN INT32 newHeight)) -{ -} \ No newline at end of file diff --git a/Src/Editor/imp/cpp/UI.cpp b/Src/Editor/imp/cpp/UI.cpp new file mode 100644 index 0000000..213f0c4 --- /dev/null +++ b/Src/Editor/imp/cpp/UI.cpp @@ -0,0 +1,207 @@ +// 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 + +#include +#include +#include + +#include + +namespace ia::iae::editor +{ + CONST IVec2 gamePreviewResolution = {800, 608}; + + IVec2 g_windowExtent{800, 600}; + RDC_Texture *g_gamePreviewTexture{}; + + VOID UI::Initialize() + { + } + + VOID UI::Terminate() + { + } + + VOID UI::Update() + { + } + + VOID UI::Draw() + { + ImVec2 gamePreviewViewSize = {(FLOAT32) gamePreviewResolution.x, (FLOAT32) gamePreviewResolution.y}; + + { // Scene Nodes View + ImGui::Begin("Nodes", nullptr, + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse); + ImGui::SetWindowPos({0.0f, 0.0f}); + ImGui::SetWindowSize({g_windowExtent.x / 2.0f - gamePreviewViewSize.x / 2.0f, gamePreviewViewSize.y + 35}); + ImGui::End(); + } + + { // Scene View + ImGui::Begin("Scene", nullptr, + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse); + ImGui::SetWindowPos({g_windowExtent.x / 2.0f - gamePreviewViewSize.x / 2.0f, 0.0f}); + ImGui::Image(g_gamePreviewTexture->GetHandle(), gamePreviewViewSize); + ImGui::End(); + } + + { // Properties View + ImGui::Begin("Properties", nullptr, + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse); + ImGui::SetWindowSize({g_windowExtent.x / 2.0f - gamePreviewViewSize.x / 2.0f - 15.0f, gamePreviewViewSize.y + 35}); + ImGui::SetWindowPos({g_windowExtent.x - ImGui::GetWindowSize().x, 0.0f}); + ImGui::End(); + } + + { // Tileset View + ImGui::Begin("Tilesets", nullptr, + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse); + ImGui::SetWindowPos({0.0f, gamePreviewViewSize.y + 35}); + ImGui::SetWindowSize({(FLOAT32)g_windowExtent.x, (FLOAT32)g_windowExtent.y - gamePreviewViewSize.y - 35}); + ImGui::End(); + } + } +} // namespace ia::iae::editor + +namespace ia::iae +{ + EXTERN Vec2 g_designViewport; + EXTERN SDL_Window *g_windowHandle; +} // namespace ia::iae + +namespace ia::iae::editor +{ + ImDrawData *g_imDrawData{}; + + INT32 UI::Run(IN INT32 argc, IN PCCHAR argv[]) + { + INT32 frameCounter{0}; + + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMEPAD)) + THROW_UNKNOWN("Failed to intialize SDL: ", SDL_GetError()); + + if (!(g_windowHandle = SDL_CreateWindow("IAEngine", g_windowExtent.x, g_windowExtent.y, + SDL_WINDOW_RESIZABLE | SDL_WINDOW_MAXIMIZED))) + THROW_UNKNOWN("Failed to create the SDL window: ", SDL_GetError()); + SDL_MaximizeWindow(g_windowHandle); + SDL_GetWindowSizeInPixels(g_windowHandle, &g_windowExtent.x, &g_windowExtent.y); + + g_designViewport = gamePreviewResolution; + IAEngine::__Initialize(); + + g_gamePreviewTexture = new RDC_Texture(RDC_Texture::EType::SAMPLED, g_designViewport.x, g_designViewport.y); + + const auto mainScale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); + + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + auto &imGUIIO = ImGui::GetIO(); + imGUIIO.IniFilename = nullptr; + imGUIIO.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + imGUIIO.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; + + ImGui::StyleColorsClassic(); + + ImGuiStyle &style = ImGui::GetStyle(); + style.ScaleAllSizes(mainScale); + style.FontScaleDpi = mainScale; + + ImGui_ImplSDLGPU3_InitInfo initInfo{.Device = RDC_Device::GetHandle(), + .ColorTargetFormat = RDC_Device::GetSwapchainTextureFormat(), + .PresentMode = SDL_GPU_PRESENTMODE_VSYNC}; + ImGui_ImplSDL3_InitForSDLGPU(g_windowHandle); + ImGui_ImplSDLGPU3_Init(&initInfo); + + Initialize(); + + SDL_Event event{}; + while (true) + { + SDL_PollEvent(&event); + if (event.type == SDL_EVENT_QUIT) + break; + IAEngine::__ProcessEvent(&event); + IAEngine::__Update(); + ImGui_ImplSDL3_ProcessEvent(&event); + + Update(); + + frameCounter++; + if (frameCounter >= 60) + { + frameCounter = 0; + IAEngine::__FixedUpdate(); + } + + IAEngine::__RenderToTexture(g_gamePreviewTexture->GetHandle()); + + ImGui_ImplSDLGPU3_NewFrame(); + ImGui_ImplSDL3_NewFrame(); + ImGui::NewFrame(); + + Draw(); + + ImGui::Render(); + + STATIC SDL_GPURenderPass *ActiveRenderPass{}; + STATIC SDL_GPUCommandBuffer *ActiveCommandBuffer{}; + STATIC SDL_GPUColorTargetInfo ActiveColorTargetInfo{.clear_color = SDL_FColor{0.0f, 0.0f, 0.0f, 1.0f}, + .load_op = SDL_GPU_LOADOP_CLEAR, + .store_op = SDL_GPU_STOREOP_STORE}; + + if (!(ActiveCommandBuffer = SDL_AcquireGPUCommandBuffer(RDC_Device::GetHandle()))) + THROW_UNKNOWN("Failed to acquire SDL GPU command buffer: ", SDL_GetError()); + + g_imDrawData = ImGui::GetDrawData(); + ImGui_ImplSDLGPU3_PrepareDrawData(g_imDrawData, ActiveCommandBuffer); + + SDL_GPUTexture *swapChainTexture{}; + if (!SDL_WaitAndAcquireGPUSwapchainTexture(ActiveCommandBuffer, g_windowHandle, &swapChainTexture, nullptr, + nullptr)) + THROW_UNKNOWN("Failed to acquire SDL GPU Swapchain texture: ", SDL_GetError()); + + ActiveColorTargetInfo.texture = swapChainTexture; + ActiveColorTargetInfo.clear_color = SDL_FColor{0.3f, 0.3f, 0.3f, 1.0f}; + ActiveRenderPass = SDL_BeginGPURenderPass(ActiveCommandBuffer, &ActiveColorTargetInfo, 1, nullptr); + ImGui_ImplSDLGPU3_RenderDrawData(g_imDrawData, ActiveCommandBuffer, ActiveRenderPass); + + SDL_EndGPURenderPass(ActiveRenderPass); + + SDL_SubmitGPUCommandBuffer(ActiveCommandBuffer); + + RDC_Device::WaitForIdle(); + } + + Terminate(); + + ImGui_ImplSDL3_Shutdown(); + ImGui_ImplSDLGPU3_Shutdown(); + ImGui::DestroyContext(); + + delete g_gamePreviewTexture; + + IAEngine::__Terminate(); + + SDL_DestroyWindow(g_windowHandle); + + return 0; + } +} // namespace ia::iae::editor diff --git a/Src/Editor/imp/hpp/Base.hpp b/Src/Editor/imp/hpp/Base.hpp new file mode 100644 index 0000000..d210241 --- /dev/null +++ b/Src/Editor/imp/hpp/Base.hpp @@ -0,0 +1,24 @@ +// 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::editor +{ + +} \ No newline at end of file diff --git a/Src/Editor/imp/hpp/GamePreview.hpp b/Src/Editor/imp/hpp/GamePreview.hpp new file mode 100644 index 0000000..693a51d --- /dev/null +++ b/Src/Editor/imp/hpp/GamePreview.hpp @@ -0,0 +1,27 @@ +// 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::editor +{ + class GamePreview + { + public: + }; +} diff --git a/Src/Editor/imp/hpp/UI.hpp b/Src/Editor/imp/hpp/UI.hpp new file mode 100644 index 0000000..9053284 --- /dev/null +++ b/Src/Editor/imp/hpp/UI.hpp @@ -0,0 +1,34 @@ +// 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::editor +{ + class UI + { + public: + STATIC INT32 Run(IN INT32 argc, IN PCCHAR argv[]); + + private: + STATIC VOID Initialize(); + STATIC VOID Terminate(); + STATIC VOID Update(); + STATIC VOID Draw(); + }; +} diff --git a/Vendor/IACore b/Vendor/IACore index cdc4413..c1cad88 160000 --- a/Vendor/IACore +++ b/Vendor/IACore @@ -1 +1 @@ -Subproject commit cdc44137e8fe70209f3b2fa048586d36d1e703b7 +Subproject commit c1cad882244eb08f5601738d0b07ee29b95e8384