This commit is contained in:
Isuru Samarathunga
2025-11-08 23:46:47 +05:30
parent 042ff451b1
commit 73d26b2f35
41 changed files with 4348 additions and 532 deletions

View File

@ -1,8 +1,12 @@
set(SRC_FILES
"imp/cpp/UI.cpp"
"imp/cpp/Main.cpp"
"imp/cpp/Editor.cpp"
"imp/cpp/Project.cpp"
"imp/cpp/GamePreview.cpp"
"imp/cpp/View/AssetBrowser.cpp"
# imgui
"imp/cpp/Vendor/imgui/imgui.cpp"
"imp/cpp/Vendor/imgui/imgui_draw.cpp"

File diff suppressed because one or more lines are too long

View File

@ -17,7 +17,7 @@
#include <GamePreview.hpp>
#include <RenderCore/RenderCore.hpp>
namespace ia::iae::editor
namespace ia::iae
{
}

View File

@ -14,9 +14,9 @@
// 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 <UI.hpp>
#include <Editor.hpp>
int main(int argc, char *argv[])
{
return ia::iae::editor::UI::Run(argc, (const char **) argv);
return ia::iae::Editor::Instance().Run(argc, (const char **) argv);
}

View File

@ -0,0 +1,38 @@
// 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 <https://www.gnu.org/licenses/>.
#include <Project.hpp>
#include <ConfigData/ConfigData.hpp>
#include <filesystem>
namespace ia::iae
{
RefPtr<Project> Project::Load(IN CONST String &directory)
{
const auto config = ConfigData::LoadFromFile(BuildString(directory, "/", "Project.iae"));
return MakeRefPtr<Project>(config->Name(), std::filesystem::canonical(directory.c_str()).string().c_str());
}
Project::Project(IN CONST String& name, IN CONST String& absolutePath):
m_projectName(name), m_projectAbsolutePath(absolutePath), m_assetDirectory(BuildString(absolutePath, "/Assets/"))
{
IA_ASSERT(std::filesystem::exists(m_assetDirectory.c_str()));
}
Project::~Project()
{
}
} // namespace ia::iae

View File

@ -20,23 +20,26 @@
#include <Vendor/imgui/backends/imgui_impl_sdl3.h>
#include <Vendor/imgui/backends/imgui_impl_sdlgpu3.h>
#include <Vendor/imgui/imgui.h>
#include <UI.hpp>
namespace ia::iae::editor
{
CONST IVec2 gamePreviewResolution = {800, 608};
#include <View/AssetBrowser.hpp>
IVec2 g_windowExtent{800, 600};
RDC_Texture *g_gamePreviewTexture{};
namespace ia::iae
{
EXTERN IVec2 g_windowExtent;
EXTERN RDC_Texture *g_gamePreviewTexture;
View_AssetBrowser g_assetBrowserView;
VOID UI::Initialize()
{
g_assetBrowserView.Initialize();
}
VOID UI::Terminate()
{
g_assetBrowserView.Terminate();
}
VOID UI::Update()
@ -66,142 +69,19 @@ namespace ia::iae::editor
{ // 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::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,
{ // Asset Browser View
ImGui::Begin("Asset Browser", 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::SetWindowSize({(FLOAT32) g_windowExtent.x, (FLOAT32) g_windowExtent.y - gamePreviewViewSize.y - 35});
g_assetBrowserView.Render();
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

View File

@ -0,0 +1,97 @@
// 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 <https://www.gnu.org/licenses/>.
#include <View/AssetBrowser.hpp>
namespace ia::iae
{
VOID View_AssetBrowser::Initialize()
{
if (!std::filesystem::exists("Assets"))
THROW_INVALID_DATA("Not a valid IAEngine project directory");
m_assetDirectoryPath = std::filesystem::current_path() / "Assets/";
ChangeCurrentOpenDirectory(m_assetDirectoryPath);
FillFileEntries(m_assetDirectoryPath, m_assetDirectoryFiles);
}
VOID View_AssetBrowser::Terminate()
{
}
VOID View_AssetBrowser::Render()
{
PreRender();
if (ImGui::BeginTable("root", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingStretchProp))
{
ImGui::TableSetupColumn("Navigation", ImGuiTableColumnFlags_WidthStretch, 0.25f);
ImGui::TableSetupColumn("Asset Browser", ImGuiTableColumnFlags_WidthStretch, 0.75f);
ImGui::TableNextColumn();
if (ImGui::BeginChild("Navigation", ImVec2(0, -FLT_MIN)))
{
for (const auto &t : m_assetDirectoryFiles)
{
ImGui::Text("%s %s", t.Icon, t.Name.c_str());
}
}
ImGui::EndChild();
ImGui::TableNextColumn();
if (ImGui::BeginChild("Asset Browser", ImVec2(0, -FLT_MIN)))
{
}
ImGui::EndChild();
ImGui::EndTable();
}
PostRender();
}
VOID View_AssetBrowser::ChangeCurrentOpenDirectory(IN CONST std::filesystem::path &path)
{
m_currentOpenDirectoryPath = path;
std::filesystem::current_path(m_currentOpenDirectoryPath);
FillFileEntries(m_currentOpenDirectoryPath, m_currentOpenDirectoryFiles);
}
VOID View_AssetBrowser::FillFileEntries(IN CONST std::filesystem::path &path, IN Vector<FileEntry> &fileEntries)
{
for (const auto &t : std::filesystem::directory_iterator(path))
{
if (!t.is_directory())
continue;
fileEntries.pushBack(
{.Icon = ICON_FA_FOLDER, .Name = t.path().filename().string().c_str(), .IsDirectory = true});
}
for (const auto &t : std::filesystem::directory_iterator(path))
{
if (t.is_directory())
continue;
fileEntries.pushBack({.Icon = GetFileEntryIcon(t.path().extension().string().c_str()),
.Name = t.path().filename().string().c_str(),
.IsDirectory = false});
}
}
PCCHAR View_AssetBrowser::GetFileEntryIcon(IN PCCHAR extension)
{
if(!strcmp(extension, ".xml"))
return ICON_FA_CODE;
return "";
}
} // namespace ia::iae::editor

View File

@ -18,7 +18,10 @@
#include <IAEngine/Base.hpp>
namespace ia::iae::editor
#include <Vendor/imgui/imgui.h>
#include <Vendor/IconsFontAwesome7.h>
namespace ia::iae
{
}

View File

@ -0,0 +1,48 @@
// 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 <https://www.gnu.org/licenses/>.
#pragma once
#include <Project.hpp>
namespace ia::iae
{
class Editor
{
STATIC Editor s_instance;
public:
STATIC Editor &Instance()
{
return s_instance;
}
public:
VOID LoadProject(IN CONST String &directory);
public:
CONST Project *GetActiveProject() CONST
{
return m_activeProject.get();
}
public:
INT32 Run(IN INT32 argc, IN PCCHAR argv[]);
private:
RefPtr<Project> m_activeProject{};
};
} // namespace ia::iae

View File

@ -18,7 +18,7 @@
#include <Base.hpp>
namespace ia::iae::editor
namespace ia::iae
{
class GamePreview
{

View File

@ -0,0 +1,48 @@
// 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 <https://www.gnu.org/licenses/>.
#pragma once
#include <Base.hpp>
namespace ia::iae
{
class Project
{
public:
STATIC RefPtr<Project> Load(IN CONST String &directory);
public:
CONST String &Name() CONST
{
return m_projectName;
}
CONST String &AssetDirectory() CONST
{
return m_assetDirectory;
}
private:
CONST String m_projectName;
CONST String m_assetDirectory;
CONST String m_projectAbsolutePath;
public:
Project(IN CONST String &name, IN CONST String &absolutePath);
~Project();
};
} // namespace ia::iae

View File

@ -18,14 +18,13 @@
#include <Base.hpp>
namespace ia::iae::editor
namespace ia::iae
{
CONST IVec2 gamePreviewResolution = {800, 608};
class UI
{
public:
STATIC INT32 Run(IN INT32 argc, IN PCCHAR argv[]);
private:
STATIC VOID Initialize();
STATIC VOID Terminate();
STATIC VOID Update();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,51 @@
// 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 <https://www.gnu.org/licenses/>.
#pragma once
#include <View/IView.hpp>
#include <filesystem>
namespace ia::iae
{
class View_AssetBrowser : public IView
{
struct FileEntry
{
PCCHAR Icon{""};
String Name{};
BOOL IsDirectory{};
};
public:
VOID Initialize();
VOID Terminate();
VOID Render();
private:
VOID ChangeCurrentOpenDirectory(IN CONST std::filesystem::path &path);
VOID FillFileEntries(IN CONST std::filesystem::path &path, IN Vector<FileEntry> &fileEntries);
PCCHAR GetFileEntryIcon(IN PCCHAR extension);
private:
Vector<FileEntry> m_assetDirectoryFiles;
std::filesystem::path m_assetDirectoryPath{};
Vector<FileEntry> m_currentOpenDirectoryFiles;
std::filesystem::path m_currentOpenDirectoryPath{};
};
} // namespace ia::iae::editor

View File

@ -0,0 +1,46 @@
// 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 <https://www.gnu.org/licenses/>.
#pragma once
#include <Base.hpp>
namespace ia::iae
{
class IView
{
public:
PURE_VIRTUAL(VOID Initialize());
PURE_VIRTUAL(VOID Terminate());
PURE_VIRTUAL(VOID Render());
protected:
INLINE VOID PreRender();
INLINE VOID PostRender();
protected:
ImVec2 m_extent{};
};
VOID IView::PreRender()
{
m_extent = ImGui::GetWindowSize();
}
VOID IView::PostRender()
{
}
} // namespace ia::iae::editor