Compare commits

...

4 Commits

Author SHA1 Message Date
a2b80ef600 Fixes 2025-11-14 09:43:09 +05:30
9ff39d7245 Fixes 2025-11-12 23:07:53 +05:30
9d6f525b81 Fixes 2025-11-11 09:24:14 +05:30
67cb23d589 Fixes 2025-11-10 09:49:22 +05:30
101 changed files with 11567 additions and 775 deletions

View File

@ -1,6 +1,7 @@
--- ---
BasedOnStyle: Microsoft BasedOnStyle: Microsoft
IndentWidth: 4 IndentWidth: 4
SortIncludes: false
--- ---
Language: Cpp Language: Cpp
FixNamespaceComments: true FixNamespaceComments: true

BIN
Resources/logo-868x507.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
Resources/logo-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

BIN
Resources/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1,14 @@
<Assets>
<IAEngine>
<EngineVersion>1.0.0</EngineVersion>
<EditorVersion>1.0.0</EditorVersion>
</IAEngine>
<Properties>
</Properties>
<Entries>
</Entries>
</Assets>

View File

Before

Width:  |  Height:  |  Size: 622 B

After

Width:  |  Height:  |  Size: 622 B

View File

Before

Width:  |  Height:  |  Size: 983 B

After

Width:  |  Height:  |  Size: 983 B

View File

Before

Width:  |  Height:  |  Size: 735 B

After

Width:  |  Height:  |  Size: 735 B

View File

Before

Width:  |  Height:  |  Size: 748 B

After

Width:  |  Height:  |  Size: 748 B

View File

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 386 B

After

Width:  |  Height:  |  Size: 386 B

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

Before

Width:  |  Height:  |  Size: 648 B

After

Width:  |  Height:  |  Size: 648 B

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 371 B

After

Width:  |  Height:  |  Size: 371 B

View File

Before

Width:  |  Height:  |  Size: 99 B

After

Width:  |  Height:  |  Size: 99 B

View File

Before

Width:  |  Height:  |  Size: 99 B

After

Width:  |  Height:  |  Size: 99 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 99 B

After

Width:  |  Height:  |  Size: 99 B

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,29 @@
<Scene name="GameMap">
<IAEngine>
<EngineVersion>1.0.0</EngineVersion>
<EditorVersion>1.0.0</EditorVersion>
</IAEngine>
<Properties>
<Extent width="800" height="608"></Extent>
</Properties>
<Assets>
<Entry name="SpriteSheet_Player"></Entry>
<Entry name="TileSheet_MiddlePath"></Entry>
<Entry name="TileSheet_MiddleWater"></Entry>
<Entry name="TileSheet_MiddleGrass"></Entry>
<Entry name="TileSheet_Path"></Entry>
<Entry name="TileSheet_Water"></Entry>
<Entry name="TileSheet_Beach"></Entry>
<Entry name="TileSheet_Cliff"></Entry>
<Entry name="TileSheet_FarmLand"></Entry>
</Assets>
<Nodes>
</Nodes>
<Grid tileWidth="16" tileHeight="16">
</Grid>
</Scene>

11
Samples/RPG/Project.iae Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<Project name="RPG Sample">
<IAEngine>
<EngineVersion>1.0.0</EngineVersion>
<EditorVersion>1.0.0</EditorVersion>
</IAEngine>
<Properties>
<Window x="1920" y="23" />
<StartupScene>MainMenu</StartupScene>
</Properties>
</Project>

View File

@ -1,34 +0,0 @@
<Resources>
<IAEngine>
<EngineVersion>1.0.0</EngineVersion>
<EditorVersion>1.0.0</EditorVersion>
</IAEngine>
<Properties>
</Properties>
<Entries>
<SpriteSheet name="SpriteSheet_Player" path="Cute_Fantasy_Free/Player/Player.png" spriteWidth="32" spriteHeight="32">
<Animation name="IdleDown" frameCount="6"></Animation>
<Animation name="IdleRight" frameCount="6"></Animation>
<Animation name="IdleUp" frameCount="6"></Animation>
<Animation name="WalkDown" frameCount="6"></Animation>
<Animation name="WalkRight" frameCount="6"></Animation>
<Animation name="WalkUp" frameCount="6"></Animation>
<Animation name="AttackDown" frameCount="4"></Animation>
<Animation name="AttackRight" frameCount="4"></Animation>
<Animation name="AttackUp" frameCount="4"></Animation>
<Animation name="Die" frameCount="4"></Animation>
</SpriteSheet>
<TileSheet name="TileSheet_MiddlePath" path="Cute_Fantasy_Free/Tiles/Path_Middle.png" tileWidth="16" tileHeight="16"></TileSheet>
<TileSheet name="TileSheet_MiddleWater" path="Cute_Fantasy_Free/Tiles/Water_Middle.png" tileWidth="16" tileHeight="16"></TileSheet>
<TileSheet name="TileSheet_MiddleGrass" path="Cute_Fantasy_Free/Tiles/Grass_Middle.png" tileWidth="16" tileHeight="16"></TileSheet>
<TileSheet name="TileSheet_Path" path="Cute_Fantasy_Free/Tiles/Path_Tile.png" tileWidth="16" tileHeight="16"></TileSheet>
<TileSheet name="TileSheet_Water" path="Cute_Fantasy_Free/Tiles/Water_Tile.png" tileWidth="16" tileHeight="16"></TileSheet>
<TileSheet name="TileSheet_Beach" path="Cute_Fantasy_Free/Tiles/Beach_Tile.png" tileWidth="16" tileHeight="16"></TileSheet>
<TileSheet name="TileSheet_Cliff" path="Cute_Fantasy_Free/Tiles/Cliff_Tile.png" tileWidth="16" tileHeight="16"></TileSheet>
<TileSheet name="TileSheet_FarmLand" path="Cute_Fantasy_Free/Tiles/FarmLand_Tile.png" tileWidth="16" tileHeight="16"></TileSheet>
</Entries>
</Resources>

View File

@ -1,108 +0,0 @@
<Scene name="GameMap">
<IAEngine>
<EngineVersion>1.0.0</EngineVersion>
<EditorVersion>1.0.0</EditorVersion>
</IAEngine>
<Properties>
<Extent width="800" height="608"></Extent>
</Properties>
<Resources>
<Entry name="SpriteSheet_Player"></Entry>
<Entry name="TileSheet_MiddlePath"></Entry>
<Entry name="TileSheet_MiddleWater"></Entry>
<Entry name="TileSheet_MiddleGrass"></Entry>
<Entry name="TileSheet_Path"></Entry>
<Entry name="TileSheet_Water"></Entry>
<Entry name="TileSheet_Beach"></Entry>
<Entry name="TileSheet_Cliff"></Entry>
<Entry name="TileSheet_FarmLand"></Entry>
</Resources>
<Nodes>
</Nodes>
<Grid tileWidth="16" tileHeight="16">
<Repeat times="50">
<Cell tileSheet="TileSheet_MiddleGrass" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="10">
<Cell tileSheet="TileSheet_MiddleGrass" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="30">
<Cell tileSheet="TileSheet_MiddleWater" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="10">
<Cell tileSheet="TileSheet_MiddleGrass" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="10">
<Cell tileSheet="TileSheet_MiddleGrass" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="30">
<Cell tileSheet="TileSheet_MiddleWater" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="10">
<Cell tileSheet="TileSheet_MiddleGrass" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="10">
<Cell tileSheet="TileSheet_MiddleGrass" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="13">
<Cell tileSheet="TileSheet_MiddleWater" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Cell tileSheet="TileSheet_Beach" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
<Cell tileSheet="TileSheet_Beach" tileX="1" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
<Cell tileSheet="TileSheet_Beach" tileX="2" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
<Repeat times="14">
<Cell tileSheet="TileSheet_MiddleWater" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="10">
<Cell tileSheet="TileSheet_MiddleGrass" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="10">
<Cell tileSheet="TileSheet_MiddleGrass" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="13">
<Cell tileSheet="TileSheet_MiddleWater" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Cell tileSheet="TileSheet_Beach" tileX="0" tileY="1" collisionMask="0" colorOverlay="#ffffffff"></Cell>
<Cell tileSheet="TileSheet_Beach" tileX="1" tileY="1" collisionMask="0" colorOverlay="#ffffffff"></Cell>
<Cell tileSheet="TileSheet_Beach" tileX="2" tileY="1" collisionMask="0" colorOverlay="#ffffffff"></Cell>
<Repeat times="14">
<Cell tileSheet="TileSheet_MiddleWater" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="10">
<Cell tileSheet="TileSheet_MiddleGrass" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="10">
<Cell tileSheet="TileSheet_MiddleGrass" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="13">
<Cell tileSheet="TileSheet_MiddleWater" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Cell tileSheet="TileSheet_Beach" tileX="0" tileY="2" collisionMask="0" colorOverlay="#ffffffff"></Cell>
<Cell tileSheet="TileSheet_Beach" tileX="1" tileY="2" collisionMask="0" colorOverlay="#ffffffff"></Cell>
<Cell tileSheet="TileSheet_Beach" tileX="2" tileY="2" collisionMask="0" colorOverlay="#ffffffff"></Cell>
<Repeat times="14">
<Cell tileSheet="TileSheet_MiddleWater" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="10">
<Cell tileSheet="TileSheet_MiddleGrass" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="10">
<Cell tileSheet="TileSheet_MiddleGrass" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="30">
<Cell tileSheet="TileSheet_MiddleWater" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="10">
<Cell tileSheet="TileSheet_MiddleGrass" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
<Repeat times="50">
<Cell tileSheet="TileSheet_MiddleGrass" tileX="0" tileY="0" collisionMask="0" colorOverlay="#ffffffff"></Cell>
</Repeat>
</Grid>
</Scene>

View File

@ -1,6 +1,6 @@
add_subdirectory(Common/) add_subdirectory(Common/)
add_subdirectory(ConfigParser/) add_subdirectory(ConfigData/)
add_subdirectory(RenderCore/) add_subdirectory(RenderCore/)
add_subdirectory(IAEngine/) add_subdirectory(IAEngine/)
add_subdirectory(CLI/) add_subdirectory(CLI/)

View File

@ -18,6 +18,8 @@
#include <IACore/File.hpp> #include <IACore/File.hpp>
#include <filesystem>
namespace ia::iae namespace ia::iae
{ {
ConfigData::ConfigData(IN pugi::xml_document &&document, IN CONST String &type, IN CONST String &name, ConfigData::ConfigData(IN pugi::xml_document &&document, IN CONST String &type, IN CONST String &name,
@ -29,7 +31,9 @@ namespace ia::iae
RefPtr<ConfigData> ConfigData::LoadFromFile(IN CONST String &path) RefPtr<ConfigData> ConfigData::LoadFromFile(IN CONST String &path)
{ {
return LoadFromMemory(File::ReadToString(path)); const auto result = LoadFromMemory(File::ReadToString(path));
result->m_filePath = std::filesystem::canonical(path.c_str()).string().c_str();
return result;
} }
RefPtr<ConfigData> ConfigData::LoadFromMemory(IN CONST String &data) RefPtr<ConfigData> ConfigData::LoadFromMemory(IN CONST String &data)
@ -76,6 +80,14 @@ namespace ia::iae
propertiesNode, IA_MOVE(childNodes)); propertiesNode, IA_MOVE(childNodes));
} }
VOID ConfigData::WriteChangesToDisk()
{
if (m_filePath.empty())
return;
m_document.save_file(m_filePath.c_str());
}
pugi::xml_node ConfigData::Property(IN CONST String &name) pugi::xml_node ConfigData::Property(IN CONST String &name)
{ {
return m_propertiesNode.child(name.c_str()); return m_propertiesNode.child(name.c_str());

View File

@ -26,6 +26,8 @@ namespace ia::iae
STATIC RefPtr<ConfigData> LoadFromFile(IN CONST String &path); STATIC RefPtr<ConfigData> LoadFromFile(IN CONST String &path);
STATIC RefPtr<ConfigData> LoadFromMemory(IN CONST String &data); STATIC RefPtr<ConfigData> LoadFromMemory(IN CONST String &data);
VOID WriteChangesToDisk();
public: public:
pugi::xml_node Property(IN CONST String &name); pugi::xml_node Property(IN CONST String &name);
@ -46,6 +48,8 @@ namespace ia::iae
} }
private: private:
String m_filePath{};
CONST String m_type; CONST String m_type;
CONST String m_name; CONST String m_name;
CONST pugi::xml_document m_document; CONST pugi::xml_document m_document;

View File

@ -1,11 +1,24 @@
set(SRC_FILES set(SRC_FILES
"imp/cpp/UI.cpp"
"imp/cpp/Main.cpp" "imp/cpp/Main.cpp"
"imp/cpp/Editor.cpp" "imp/cpp/Editor.cpp"
"imp/cpp/Project.cpp" "imp/cpp/Project.cpp"
"imp/cpp/GamePreview.cpp"
"imp/cpp/View/AssetBrowser.cpp" "imp/cpp/UI/UI.cpp"
"imp/cpp/UI/Popup.cpp"
"imp/cpp/UI/Window.cpp"
"imp/cpp/UI/TabContainer.cpp"
"imp/cpp/UI/View/IView.cpp"
"imp/cpp/UI/View/FilePreview.cpp"
"imp/cpp/UI/View/AssetBrowser.cpp"
"imp/cpp/UI/View/Console.cpp"
"imp/cpp/UI/View/Nodes.cpp"
"imp/cpp/UI/View/Package.cpp"
"imp/cpp/UI/View/Scene.cpp"
"imp/cpp/UI/View/Game.cpp"
"imp/cpp/UI/View/Asset.cpp"
"imp/cpp/UI/View/Properties.cpp"
# imgui # imgui
"imp/cpp/Vendor/imgui/imgui.cpp" "imp/cpp/Vendor/imgui/imgui.cpp"
@ -14,6 +27,8 @@ set(SRC_FILES
"imp/cpp/Vendor/imgui/imgui_widgets.cpp" "imp/cpp/Vendor/imgui/imgui_widgets.cpp"
"imp/cpp/Vendor/imgui/backends/imgui_impl_sdl3.cpp" "imp/cpp/Vendor/imgui/backends/imgui_impl_sdl3.cpp"
"imp/cpp/Vendor/imgui/backends/imgui_impl_sdlgpu3.cpp" "imp/cpp/Vendor/imgui/backends/imgui_impl_sdlgpu3.cpp"
"imp/cpp/Vendor/FontAwesome7.cpp"
) )
add_executable(IAE_Editor ${SRC_FILES}) add_executable(IAE_Editor ${SRC_FILES})

File diff suppressed because one or more lines are too long

View File

@ -15,21 +15,39 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <Project.hpp> #include <Project.hpp>
#include <ConfigData/ConfigData.hpp>
#include <filesystem> #include <filesystem>
namespace ia::iae namespace ia::iae
{ {
RefPtr<Project> Project::Load(IN CONST String &directory) RefPtr<Project> Project::Load(IN CONST String &directory)
{ {
const auto config = ConfigData::LoadFromFile(BuildString(directory, "/", "Project.iae")); auto config = ConfigData::LoadFromFile(BuildString(directory, "/", "Project.iae"));
return MakeRefPtr<Project>(config->Name(), std::filesystem::canonical(directory.c_str()).string().c_str()); return MakeRefPtr<Project>(config->Name(), std::filesystem::canonical(directory.c_str()).string().c_str(), IA_MOVE(config));
} }
Project::Project(IN CONST String& name, IN CONST String& absolutePath): VOID Project::Update()
m_projectName(name), m_projectAbsolutePath(absolutePath), m_assetDirectory(BuildString(absolutePath, "/Assets/")) {
// Update Window Position
const auto windowNode = m_configData->Property("Window");
windowNode.attribute("x").set_value(m_windowPosition.x);
windowNode.attribute("y").set_value(m_windowPosition.y);
m_configData->WriteChangesToDisk();
}
Project::Project(IN CONST String &name, IN CONST String &absolutePath, IN RefPtr<ConfigData> &&configData)
: m_projectName(name), m_projectAbsolutePath(absolutePath),
m_assetDirectory(BuildString(absolutePath, "/Assets/")), m_configData(IA_MOVE(configData))
{ {
IA_ASSERT(std::filesystem::exists(m_assetDirectory.c_str())); IA_ASSERT(std::filesystem::exists(m_assetDirectory.c_str()));
const auto windowNode = m_configData->Property("Window");
if(windowNode && windowNode.attribute("x") && windowNode.attribute("y"))
{
m_windowPosition.x = windowNode.attribute("x").as_int();
m_windowPosition.y = windowNode.attribute("y").as_int();
}
} }
Project::~Project() Project::~Project()

View File

@ -1,87 +0,0 @@
// 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 <IAEngine/IAEngine.hpp>
#include <RenderCore/RenderCore.hpp>
#include <SDL3/SDL.h>
#include <Vendor/imgui/backends/imgui_impl_sdl3.h>
#include <Vendor/imgui/backends/imgui_impl_sdlgpu3.h>
#include <UI.hpp>
#include <View/AssetBrowser.hpp>
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()
{
}
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();
}
{ // 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});
g_assetBrowserView.Render();
ImGui::End();
}
}
} // namespace ia::iae::editor

View File

View File

@ -0,0 +1,126 @@
// 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 <UI/TabContainer.hpp>
namespace ia::iae
{
INT32 g_tabContainerCount{0};
TabContainer::TabContainer()
: m_containerID(BuildString("TabContainer##", g_tabContainerCount++)),
m_tabBarID(BuildString("TabBar##", g_tabContainerCount++))
{
}
VOID TabContainer::Initialize()
{
}
VOID TabContainer::Terminate()
{
for (const auto &t : m_tabViews)
RemoveTab(t->Key);
}
VOID TabContainer::Draw(IN ImVec2 position, IN ImVec2 size)
{
ImGui::Begin(m_containerID.c_str(), nullptr,
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_NoTitleBar);
ImGui::SetWindowPos(position);
ImGui::SetWindowSize(size);
ImGui::BeginTabBar(m_tabBarID.c_str());
for (const auto &v : m_tabViews)
{
ImGuiTabItemFlags flags{};
if (m_pendingActiveTabName && m_pendingActiveTabName == v->Key)
{
flags |= ImGuiTabItemFlags_SetSelected;
m_pendingActiveTabName = nullptr;
}
BOOL* isOpen = v->Value.IsCloseable ? &v->Value.IsOpen : nullptr;
if (ImGui::BeginTabItem(v->Value.View->IconAndName().c_str(), isOpen, flags))
{
v->Value.View->Render();
ImGui::EndTabItem();
m_activeTabName = v->Key.c_str();
}
}
ImGui::EndTabBar();
ImGui::End();
}
VOID TabContainer::Update()
{
for (const auto &t : m_tabViews)
t->Value.View->Update();
}
VOID TabContainer::ProcessEvent(IN SDL_Event *event)
{
for (const auto &t : m_tabViews)
t->Value.View->ProcessEvent(event);
}
VOID TabContainer::AddTab(IN CONST String &name, IN IView *view, IN BOOL isCloseable)
{
RemoveTab(name);
view->Initialize();
m_tabViews[name] = Tab{.View = view, .IsCloseable = isCloseable};
if (!m_activeTabName)
m_activeTabName = name.c_str();
}
VOID TabContainer::RemoveTab(IN CONST String &name)
{
if (!m_tabViews.contains(name))
return;
m_tabViews[name].IsOpen = false;
if (m_tabViews[name].View)
m_tabViews[name].View->Terminate();
delete m_tabViews[name].View;
m_tabViews[name] = {};
}
VOID TabContainer::OpenTab(IN CONST String &name)
{
if (!m_tabViews.contains(name))
return;
m_tabViews[name].IsOpen = true;
}
VOID TabContainer::CloseTab(IN CONST String &name)
{
if (!m_tabViews.contains(name))
return;
m_tabViews[name].IsOpen = false;
}
VOID TabContainer::ChangeActiveTab(IN PCCHAR name)
{
m_pendingActiveTabName = name;
}
IView *TabContainer::GetTab(IN CONST String &name)
{
return m_tabViews[name].View;
}
} // namespace ia::iae

View File

@ -0,0 +1,223 @@
// 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 <IAEngine/IAEngine.hpp>
#include <RenderCore/RenderCore.hpp>
#include <UI/UI.hpp>
#include <UI/View/Asset.hpp>
#include <UI/View/AssetBrowser.hpp>
#include <UI/View/Console.hpp>
#include <UI/View/FilePreview.hpp>
#include <UI/View/Nodes.hpp>
#include <UI/View/Package.hpp>
#include <UI/View/Properties.hpp>
#include <UI/View/Scene.hpp>
#include <UI/View/Game.hpp>
#include <UI/TabContainer.hpp>
namespace ia::iae
{
STATIC CONSTEXPR PCCHAR VIEW_NAME_ASSET_BROWSER = "AssetBrowser";
STATIC CONSTEXPR PCCHAR VIEW_NAME_FILE_PREVIEW = "FilePreview";
STATIC CONSTEXPR PCCHAR VIEW_NAME_ASSET = "Asset";
STATIC CONSTEXPR PCCHAR VIEW_NAME_CONSOLE = "Console";
STATIC CONSTEXPR PCCHAR VIEW_NAME_NODES = "Nodes";
STATIC CONSTEXPR PCCHAR VIEW_NAME_PACKAGE = "Package";
STATIC CONSTEXPR PCCHAR VIEW_NAME_PROPERTIES = "Properties";
STATIC CONSTEXPR PCCHAR VIEW_NAME_SCENE = "Scene";
STATIC CONSTEXPR PCCHAR VIEW_NAME_GAME = "Game";
EXTERN IVec2 g_windowExtent;
IView *UI::s_focusedView{};
TabContainer g_tabContainerB;
TabContainer g_tabContainerTL;
TabContainer g_tabContainerTM;
TabContainer g_tabContainerTR;
VOID UI::OpenFilePreviewView()
{
g_tabContainerTR.OpenTab(VIEW_NAME_FILE_PREVIEW);
g_tabContainerTR.ChangeActiveTab(VIEW_NAME_FILE_PREVIEW);
}
VOID UI::CloseFilePreviewView()
{
g_tabContainerTR.CloseTab(VIEW_NAME_FILE_PREVIEW);
}
VOID UI::OpenAssetView()
{
g_tabContainerTR.OpenTab(VIEW_NAME_ASSET);
g_tabContainerTR.ChangeActiveTab(VIEW_NAME_ASSET);
}
VOID UI::CloseAssetView()
{
g_tabContainerTR.CloseTab(VIEW_NAME_ASSET);
}
class View_Asset *UI::GetAssetView()
{
return (View_Asset *) g_tabContainerTR.GetTab(VIEW_NAME_ASSET);
}
class View_FilePreview *UI::GetFilePreviewView()
{
return (View_FilePreview *) g_tabContainerTR.GetTab(VIEW_NAME_FILE_PREVIEW);
}
VOID UI::Initialize()
{
g_tabContainerB.Initialize();
g_tabContainerTL.Initialize();
g_tabContainerTM.Initialize();
g_tabContainerTR.Initialize();
g_tabContainerB.AddTab<View_AssetBrowser>(VIEW_NAME_ASSET_BROWSER);
g_tabContainerB.AddTab<View_Console>(VIEW_NAME_CONSOLE);
g_tabContainerTL.AddTab<View_Nodes>(VIEW_NAME_NODES);
g_tabContainerTL.AddTab<View_Package>(VIEW_NAME_PACKAGE);
g_tabContainerTM.AddTab<View_Scene>(VIEW_NAME_SCENE);
g_tabContainerTM.AddTab<View_Game>(VIEW_NAME_GAME);
g_tabContainerTR.AddTab<View_Properties>(VIEW_NAME_PROPERTIES);
g_tabContainerTR.AddTab<View_Asset>(VIEW_NAME_ASSET, true);
g_tabContainerTR.AddTab<View_FilePreview>(VIEW_NAME_FILE_PREVIEW, true);
g_tabContainerTR.CloseTab(VIEW_NAME_ASSET);
g_tabContainerTR.CloseTab(VIEW_NAME_FILE_PREVIEW);
}
VOID UI::Terminate()
{
g_tabContainerB.Terminate();
g_tabContainerTL.Terminate();
g_tabContainerTM.Terminate();
g_tabContainerTR.Terminate();
}
VOID UI::Update()
{
g_tabContainerB.Update();
g_tabContainerTL.Update();
g_tabContainerTM.Update();
g_tabContainerTR.Update();
}
VOID UI::ProcessEvent(IN SDL_Event *event)
{
g_tabContainerB.ProcessEvent(event);
g_tabContainerTL.ProcessEvent(event);
g_tabContainerTM.ProcessEvent(event);
g_tabContainerTR.ProcessEvent(event);
}
VOID UI::Draw()
{
DrawMenuBar();
g_tabContainerB.Draw({0.0f, LAYOUT_TOP_MIDDLE_VIEW_EXTENT.y * g_windowExtent.y + MENUBAR_HEIGHT},
{g_windowExtent.x * LAYOUT_BOTTOM_VIEW_EXTENT.x,
g_windowExtent.y * LAYOUT_BOTTOM_VIEW_EXTENT.y - MENUBAR_HEIGHT});
g_tabContainerTL.Draw({0.0f, MENUBAR_HEIGHT}, {g_windowExtent.x * LAYOUT_TOP_LEFT_VIEW_EXTENT.x,
g_windowExtent.y * LAYOUT_TOP_LEFT_VIEW_EXTENT.y});
g_tabContainerTM.Draw(
{g_windowExtent.x * LAYOUT_TOP_LEFT_VIEW_EXTENT.x, MENUBAR_HEIGHT},
{g_windowExtent.x * LAYOUT_TOP_MIDDLE_VIEW_EXTENT.x, g_windowExtent.y * LAYOUT_TOP_MIDDLE_VIEW_EXTENT.y});
g_tabContainerTR.Draw(
{g_windowExtent.x * (1.0f - LAYOUT_TOP_RIGHT_VIEW_EXTENT.x), MENUBAR_HEIGHT},
{g_windowExtent.x * LAYOUT_TOP_RIGHT_VIEW_EXTENT.x, g_windowExtent.y * LAYOUT_TOP_RIGHT_VIEW_EXTENT.y});
}
VOID UI::DrawMenuBar()
{
if (ImGui::BeginMainMenuBar())
{
if (ImGui::BeginMenu("File"))
{
if (ImGui::MenuItem("New Scene", nullptr, nullptr))
{
}
UI::PadY();
if (ImGui::MenuItem("Open Scene", nullptr, nullptr))
{
}
UI::PadY();
ImGui::Separator();
UI::PadY();
if (ImGui::MenuItem("Exit", nullptr, nullptr))
SDL_Quit();
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
}
VOID UI::PadX(IN FLOAT32 v)
{
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + v);
}
VOID UI::PadY(IN FLOAT32 v)
{
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + v);
}
VOID UI::AlignCursorLeft(IN CONST ImRect &rect)
{
ImGui::SetCursorPosX(rect.GetTL().x);
}
VOID UI::AlignCursorRight(IN CONST ImRect &rect, IN FLOAT32 width)
{
ImGui::SetCursorPosX(rect.GetWidth() - width);
}
VOID UI::AlignCursorTop(IN CONST ImRect &rect)
{
ImGui::SetCursorPosY(rect.AsVec4().y);
}
VOID UI::AlignCursorBottom(IN CONST ImRect &rect, IN FLOAT32 height)
{
ImGui::SetCursorPosY(rect.GetHeight() - height);
}
VOID UI::AlignCursorHCenter(IN CONST ImRect &rect, IN FLOAT32 width)
{
ImGui::SetCursorPosX((rect.GetWidth() - width) / 2.0f);
}
VOID UI::AlignCursorVCenter(IN CONST ImRect &rect, IN FLOAT32 height)
{
ImGui::SetCursorPosY((rect.GetHeight() - height) / 2.0f);
}
VOID UI::DrawTextCentered(IN CONST ImVec2 &viewExtent, IN CONST String &text)
{
ImRect rect{{}, viewExtent};
const auto textSize = ImGui::CalcTextSize(text.c_str());
UI::AlignCursorHCenter(rect, textSize.x);
UI::AlignCursorVCenter(rect, textSize.y);
ImGui::Text("%s", text.c_str());
}
} // namespace ia::iae

View File

@ -0,0 +1,214 @@
// 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 <UI/View/Asset.hpp>
#include <IAEngine/Asset/AssetManager.hpp>
#include <RenderCore/RenderCore.hpp>
#include <Editor.hpp>
namespace ia::iae
{
VOID View_Asset::Initialize()
{
SetName("Asset");
SetIcon(ICON_FA_STAR);
}
VOID View_Asset::Terminate()
{
}
VOID View_Asset::Render()
{
PreRender();
if (!m_asset)
{
PostRender();
return;
}
STATIC CHAR NAME_BUFFER[256];
memcpy(NAME_BUFFER, m_assetName.c_str(), m_assetName.size() + 1);
ImGui::Text("Name: ");
ImGui::SameLine();
ImGui::InputText("##name", NAME_BUFFER, sizeof(NAME_BUFFER));
m_assetName = NAME_BUFFER;
DrawAssetTypePicker();
switch (m_asset->GetType())
{
case EAssetType::TEXTURE:
RenderTextureAsset();
break;
case EAssetType::SPRITE:
RenderSpriteAsset();
break;
case EAssetType::TILESHEET:
RenderTileSheetAsset();
break;
case EAssetType::SPRITESHEET:
RenderSpriteSheetAsset();
break;
case EAssetType::INVALID:
case EAssetType::SOUND:
case EAssetType::SCENE:
case EAssetType::PLUGIN:
case EAssetType::PACKAGE:
break;
}
PostRender();
}
VOID View_Asset::Update()
{
}
VOID View_Asset::OnEvent(IN SDL_Event *event)
{
}
VOID View_Asset::Open(IN String assetName)
{
m_assetName = assetName;
const auto asset = AssetManager::GetAssetByName<Asset_Texture>(m_assetName);
m_assetImageHandle = RDC::BakeTexture(asset->GetHandle()->ImagePtr);
m_assetImageExtent = {asset->GetHandle()->ImagePtr->Width, asset->GetHandle()->ImagePtr->Height};
m_asset = asset;
m_assetType = asset->GetType();
}
VOID View_Asset::Close()
{
m_assetName = "";
m_asset = nullptr;
m_assetImageHandle = 0;
m_assetImageExtent = {};
m_assetType = EAssetType::INVALID;
}
VOID View_Asset::RenderTextureAsset()
{
const auto asset = (Asset_Texture *) m_asset;
DrawAssetImage(0.75f, {0, 0});
}
VOID View_Asset::RenderSpriteAsset()
{
const auto asset = (Asset_Sprite *) m_asset;
DrawAssetImage(0.75f, {0, 0});
}
VOID View_Asset::RenderTileSheetAsset()
{
const auto asset = (Asset_TileSheet *) m_asset;
ImGui::Text("Tile Width: ");
ImGui::SameLine();
ImGui::InputInt("##TileWidth", &asset->TileWidth());
if (asset->TileWidth() < 1)
asset->TileWidth() = 1;
if (asset->TileWidth() > m_assetImageExtent.x)
asset->TileWidth() = m_assetImageExtent.x;
ImGui::Text("Tile Height: ");
ImGui::SameLine();
ImGui::InputInt("##TileHeight", &asset->TileHeight());
if (asset->TileHeight() < 1)
asset->TileHeight() = 1;
if (asset->TileHeight() > m_assetImageExtent.y)
asset->TileHeight() = m_assetImageExtent.y;
DrawAssetImage(0.75f, {asset->TileWidth(), asset->TileHeight()});
}
VOID View_Asset::RenderSpriteSheetAsset()
{
const auto asset = (Asset_SpriteSheet *) m_asset;
}
VOID View_Asset::DrawAssetImage(IN FLOAT32 relativeWidth, IN IVec2 gridSize)
{
ImVec2 base_pos = ImGui::GetCursorScreenPos();
const auto ImageWidth = m_extent.x * relativeWidth;
const auto aspectRatio =
static_cast<FLOAT32>(m_assetImageExtent.y) / static_cast<FLOAT32>(m_assetImageExtent.x);
const auto ImageHeight = aspectRatio * ImageWidth;
ImGui::Image((ImTextureRef) m_assetImageHandle, {ImageWidth, ImageHeight});
if((!gridSize.x) || (!gridSize.y))
return;
gridSize.x *= ImageWidth/m_assetImageExtent.x;
gridSize.y *= ImageHeight/m_assetImageExtent.y;
ImDrawList *draw_list = ImGui::GetWindowDrawList();
auto gridCountX = ImageWidth / gridSize.x;
auto gridCountY = ImageHeight / gridSize.y;
ImU32 grid_color = IM_COL32(200, 200, 200, 50);
float grid_thickness = 1.0f;
ImGui::Dummy(ImVec2(ImageWidth, ImageHeight));
for (int i = 0; i <= gridCountX; ++i)
{
ImVec2 p1 = ImVec2(base_pos.x + i * gridSize.x, base_pos.y);
ImVec2 p2 = ImVec2(base_pos.x + i * gridSize.x, base_pos.y + ImageHeight);
draw_list->AddLine(p1, p2, grid_color, grid_thickness);
}
for (int i = 0; i <= gridCountY; ++i)
{
ImVec2 p1 = ImVec2(base_pos.x, base_pos.y + i * gridSize.y);
ImVec2 p2 = ImVec2(base_pos.x + ImageWidth, base_pos.y + i * gridSize.y);
draw_list->AddLine(p1, p2, grid_color, grid_thickness);
}
}
VOID View_Asset::DrawAssetTypePicker()
{
ImGui::Text("Asset Type: ");
ImGui::SameLine();
ImGui::Combo("##", (INT32 *) &m_assetType, "None\0Texture\0Sprite\0TileSheet\0SpriteSheet\0");
if (m_assetType != m_asset->GetType())
{
ImGui::SameLine();
if (ImGui::Button("Apply"))
{
if (m_assetType == EAssetType::INVALID)
{
Editor::Instance().RemoveFromAssets(m_assetName);
Close();
UI::CloseAssetView();
}
m_asset = AssetManager::ChangeAssetType(m_assetName, m_assetType);
}
}
}
} // namespace ia::iae

View File

@ -14,12 +14,16 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <View/AssetBrowser.hpp> #include <Editor.hpp>
#include <UI/View/AssetBrowser.hpp>
namespace ia::iae namespace ia::iae
{ {
VOID View_AssetBrowser::Initialize() VOID View_AssetBrowser::Initialize()
{ {
SetName("Asset Browser");
SetIcon(ICON_FA_BOX_OPEN);
if (!std::filesystem::exists("Assets")) if (!std::filesystem::exists("Assets"))
THROW_INVALID_DATA("Not a valid IAEngine project directory"); THROW_INVALID_DATA("Not a valid IAEngine project directory");
m_assetDirectoryPath = std::filesystem::current_path() / "Assets/"; m_assetDirectoryPath = std::filesystem::current_path() / "Assets/";
@ -35,48 +39,90 @@ namespace ia::iae
{ {
PreRender(); PreRender();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{7.5f, 7.5f});
if (ImGui::BeginTable("root", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingStretchProp)) if (ImGui::BeginTable("root", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingStretchProp))
{ {
ImGui::TableSetupColumn("Navigation", ImGuiTableColumnFlags_WidthStretch, 0.25f); ImGui::TableSetupColumn("Navigation", ImGuiTableColumnFlags_WidthStretch, 0.15f);
ImGui::TableSetupColumn("Asset Browser", ImGuiTableColumnFlags_WidthStretch, 0.75f); ImGui::TableSetupColumn("Asset Browser", ImGuiTableColumnFlags_WidthStretch, 0.85f);
ImGui::TableNextColumn(); ImGui::TableNextColumn();
if (ImGui::BeginChild("Navigation", ImVec2(0, -FLT_MIN))) if (ImGui::BeginChild("Navigation", ImVec2(0, -FLT_MIN), ImGuiChildFlags_AlwaysUseWindowPadding))
{ {
for (const auto &t : m_assetDirectoryFiles) for (const auto &t : m_assetDirectoryFiles)
{ {
ImGui::Text("%s %s", t.Icon, t.Name.c_str()); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 1.75f);
if (ImGui::Selectable(t.IconAndName.c_str()))
{
if (t.IsDirectory)
{
ChangeCurrentOpenDirectory(t.Path);
break;
}
OpenAsset(t.Path);
}
} }
} }
ImGui::EndChild(); ImGui::EndChild();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
if (ImGui::BeginChild("Asset Browser", ImVec2(0, -FLT_MIN))) if (ImGui::BeginChild("Asset Browser", ImVec2(0, -FLT_MIN), ImGuiChildFlags_AlwaysUseWindowPadding))
{ {
for (const auto &t : m_currentOpenDirectoryFiles)
{
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 1.75f);
if (ImGui::Selectable(t.IconAndName.c_str()))
{
if (t.IsDirectory)
{
ChangeCurrentOpenDirectory(t.Path);
break;
}
OpenAsset(t.Path);
}
}
} }
ImGui::EndChild(); ImGui::EndChild();
ImGui::EndTable(); ImGui::EndTable();
} }
ImGui::PopStyleVar();
PostRender(); PostRender();
} }
VOID View_AssetBrowser::Update()
{
}
VOID View_AssetBrowser::OnEvent(IN SDL_Event *event)
{
}
VOID View_AssetBrowser::ChangeCurrentOpenDirectory(IN CONST std::filesystem::path &path) VOID View_AssetBrowser::ChangeCurrentOpenDirectory(IN CONST std::filesystem::path &path)
{ {
m_currentOpenDirectoryPath = path; m_currentOpenDirectoryPath = path;
std::filesystem::current_path(m_currentOpenDirectoryPath); std::filesystem::current_path(m_currentOpenDirectoryPath);
FillFileEntries(m_currentOpenDirectoryPath, m_currentOpenDirectoryFiles);
if (path == m_assetDirectoryPath)
m_currentOpenDirectoryFiles.clear();
else
FillFileEntries(m_currentOpenDirectoryPath, m_currentOpenDirectoryFiles);
} }
VOID View_AssetBrowser::FillFileEntries(IN CONST std::filesystem::path &path, IN Vector<FileEntry> &fileEntries) VOID View_AssetBrowser::FillFileEntries(IN CONST std::filesystem::path &path, IN Vector<FileEntry> &fileEntries)
{ {
fileEntries.clear();
for (const auto &t : std::filesystem::directory_iterator(path)) for (const auto &t : std::filesystem::directory_iterator(path))
{ {
if (!t.is_directory()) if (!t.is_directory())
continue; continue;
fileEntries.pushBack( fileEntries.pushBack({.Icon = ICON_FA_FOLDER,
{.Icon = ICON_FA_FOLDER, .Name = t.path().filename().string().c_str(), .IsDirectory = true}); .Name = t.path().filename().string().c_str(),
.IsDirectory = true,
.Path = t.path()});
fileEntries.back().IconAndName = BuildString(fileEntries.back().Icon, " ", fileEntries.back().Name);
} }
for (const auto &t : std::filesystem::directory_iterator(path)) for (const auto &t : std::filesystem::directory_iterator(path))
{ {
@ -84,14 +130,23 @@ namespace ia::iae
continue; continue;
fileEntries.pushBack({.Icon = GetFileEntryIcon(t.path().extension().string().c_str()), fileEntries.pushBack({.Icon = GetFileEntryIcon(t.path().extension().string().c_str()),
.Name = t.path().filename().string().c_str(), .Name = t.path().filename().string().c_str(),
.IsDirectory = false}); .IsDirectory = false,
.Path = t.path()});
fileEntries.back().IconAndName = BuildString(fileEntries.back().Icon, " ", fileEntries.back().Name);
} }
} }
PCCHAR View_AssetBrowser::GetFileEntryIcon(IN PCCHAR extension) PCCHAR View_AssetBrowser::GetFileEntryIcon(IN PCCHAR extension)
{ {
if(!strcmp(extension, ".xml")) if (!strcmp(extension, ".xml"))
return ICON_FA_CODE; return ICON_FA_CODE;
return ""; if (!strcmp(extension, ".png") || !strcmp(extension, ".jpg"))
return ICON_FA_IMAGE;
return ICON_FA_FILE;
} }
} // namespace ia::iae::editor
VOID View_AssetBrowser::OpenAsset(IN CONST std::filesystem::path &path)
{
Editor::Instance().OpenFile(path);
}
} // namespace ia::iae

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/>.
#include <UI/View/Console.hpp>
namespace ia::iae
{
VOID View_Console::Initialize()
{
SetName("Console");
SetIcon(ICON_FA_TERMINAL);
}
VOID View_Console::Terminate()
{
}
VOID View_Console::Render()
{
PreRender();
PostRender();
}
VOID View_Console::Update(){
}
VOID View_Console::OnEvent(IN SDL_Event *event)
{
}
} // namespace ia::iae

View File

@ -0,0 +1,170 @@
// 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 <UI/View/FilePreview.hpp>
#include <IAEngine/Asset/AssetManager.hpp>
#include <RenderCore/RenderCore.hpp>
#include <Editor.hpp>
#include <fstream>
namespace ia::iae
{
BOOL is_extension_one_of(IN PCCHAR ext, IN std::initializer_list<PCCHAR> values)
{
for (const auto &t : values)
{
if (!strcmp(ext, t))
return true;
}
return false;
}
Vector<String> get_lines_of_file(IN CONST Path &path)
{
Vector<String> result;
std::string line;
std::ifstream file(path);
while (std::getline(file, line))
result.pushBack(line.c_str());
return result;
}
VOID View_FilePreview::Initialize()
{
SetName("File Preview");
SetIcon(ICON_FA_MAGNIFYING_GLASS);
}
VOID View_FilePreview::Terminate()
{
}
VOID View_FilePreview::Render()
{
PreRender();
if (m_filePath.empty())
{
PostRender();
return;
}
switch (m_fileType)
{
case EFileType::UNKNOWN:
RenderUnknownFile();
break;
case EFileType::TEXT:
RenderTextFile();
break;
case EFileType::IMAGE:
RenderImageFile();
break;
}
PostRender();
}
VOID View_FilePreview::Update()
{
}
VOID View_FilePreview::OnEvent(IN SDL_Event *event)
{
}
VOID View_FilePreview::Open(IN Path path)
{
Close();
m_filePath = path;
m_fileType = EFileType::UNKNOWN;
const auto ext = path.extension().string();
if (is_extension_one_of(&ext[1], {"txt", "xml", "md", "cpp", "c", "hpp", "h"}))
{
m_fileType = EFileType::TEXT;
const auto lines = get_lines_of_file(path);
m_fileDataSize = lines.size();
const auto fileData = new String[m_fileDataSize];
for (SIZE_T i = 0; i < m_fileDataSize; i++)
fileData[i] = lines[i];
m_fileData = fileData;
}
else if (is_extension_one_of(&ext[1], {"png", "jpg", "webp"}))
{
m_fileType = EFileType::IMAGE;
m_fileDataSize = SIZE_MAX;
const auto image = AssetManager::LoadTexture(path.string().c_str())->GetHandle()->ImagePtr;
m_fileDataExtent = IVec2{image->Width, image->Height};
m_fileData = (PVOID)RDC::BakeTexture(image);
}
}
VOID View_FilePreview::Close()
{
switch (m_fileType)
{
case EFileType::UNKNOWN:
break;
case EFileType::TEXT:
delete[] ((String *) m_fileData);
m_fileDataSize = 0;
m_fileData = nullptr;
break;
case EFileType::IMAGE:
m_fileDataSize = 0;
m_fileData = nullptr;
m_fileDataExtent = {};
break;
}
m_filePath = Path();
m_fileType = EFileType::UNKNOWN;
}
VOID View_FilePreview::RenderTextFile()
{
const auto lines = (String*)m_fileData;
for(SIZE_T i = 0; i < m_fileDataSize; i++)
ImGui::Text("%s", lines[i].c_str());
}
VOID View_FilePreview::RenderImageFile()
{
UI::PadX();
UI::PadY();
if(ImGui::Button("Mark as Asset"))
Editor::Instance().MarkAsAsset(m_filePath);
UI::PadY();
const auto ImageWidth = m_extent.x * 0.75f;
UI::AlignCursorHCenter(ImRect{{}, m_extent}, ImageWidth);
const auto aspectRatio = static_cast<FLOAT32>(m_fileDataExtent.y)/static_cast<FLOAT32>(m_fileDataExtent.x);
ImGui::Image((ImTextureRef)m_fileData, {ImageWidth, aspectRatio * ImageWidth});
}
VOID View_FilePreview::RenderUnknownFile()
{
UI::DrawTextCentered(m_extent, "Unsupported File Format");
}
} // namespace ia::iae

View File

@ -0,0 +1,99 @@
// 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 <Editor.hpp>
#include <UI/View/Game.hpp>
#include <RenderCore/RenderCore.hpp>
#include <IAEngine/LibInterface.hpp>
namespace ia::iae
{
VOID View_Game::Initialize()
{
SetName("Game");
SetIcon(ICON_FA_GAMEPAD);
IAEngine::__Initialize(SCENE_EDITOR_RESOULTION, Editor::Instance().GetActiveProject()->AssetDirectory());
m_gameRenderTexture = new RDC_Texture(RDC_Texture::EType::SAMPLED, SCENE_EDITOR_RESOULTION.x, SCENE_EDITOR_RESOULTION.y);
}
VOID View_Game::Terminate()
{
delete m_gameRenderTexture;
}
VOID View_Game::Render()
{
PreRender();
ImGui::Image(m_gameRenderTexture->GetHandle(), m_extent);
PostRender();
}
VOID View_Game::Update()
{
STATIC INT32 frameCounter{0};
IAEngine::__Update();
frameCounter++;
if (frameCounter >= 60)
{
frameCounter = 0;
IAEngine::__FixedUpdate();
}
IAEngine::__RenderToTexture(m_gameRenderTexture->GetHandle());
}
VOID View_Game::OnEvent(IN SDL_Event *event)
{
IAEngine::__ProcessEvent(event);
}
} // namespace ia::iae
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))
{
}

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 <UI/View/IView.hpp>
namespace ia::iae
{
VOID IView::ProcessEvent(IN SDL_Event *event)
{
if (UI::GetFocusedView() == this)
OnEvent(event);
}
VOID IView::SetIcon(IN PCCHAR icon)
{
m_icon = icon;
m_iconAndName = BuildString(m_icon, " ", m_name);
}
VOID IView::SetName(IN CONST String &name)
{
m_name = name;
m_iconAndName = m_icon ? BuildString(m_icon, " ", m_name) : m_name;
}
} // namespace ia::iae

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/>.
#include <UI/View/Nodes.hpp>
namespace ia::iae
{
VOID View_Nodes::Initialize()
{
SetName("Nodes");
SetIcon(ICON_FA_CIRCLE_NODES);
}
VOID View_Nodes::Terminate()
{
}
VOID View_Nodes::Render()
{
PreRender();
PostRender();
}
VOID View_Nodes::Update(){
}
VOID View_Nodes::OnEvent(IN SDL_Event *event)
{
}
} // namespace ia::iae

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/>.
#include <UI/View/Package.hpp>
namespace ia::iae
{
VOID View_Package::Initialize()
{
SetName("Package");
SetIcon(ICON_FA_BOX_ARCHIVE);
}
VOID View_Package::Terminate()
{
}
VOID View_Package::Render()
{
PreRender();
PostRender();
}
VOID View_Package::Update(){
}
VOID View_Package::OnEvent(IN SDL_Event *event)
{
}
} // namespace ia::iae

View File

@ -14,33 +14,33 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once #include <UI/View/Properties.hpp>
#include <Base.hpp>
namespace ia::iae namespace ia::iae
{ {
class IView VOID View_Properties::Initialize()
{ {
public: SetName("Properties");
PURE_VIRTUAL(VOID Initialize()); SetIcon(ICON_FA_LIST);
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() VOID View_Properties::Terminate()
{ {
} }
} // namespace ia::iae::editor
VOID View_Properties::Render()
{
PreRender();
PostRender();
}
VOID View_Properties::Update(){
}
VOID View_Properties::OnEvent(IN SDL_Event *event)
{
}
} // namespace ia::iae

View File

@ -14,41 +14,39 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <GamePreview.hpp> #include <Editor.hpp>
#include <UI/View/Scene.hpp>
#include <RenderCore/RenderCore.hpp> #include <RenderCore/RenderCore.hpp>
namespace ia::iae namespace ia::iae
{ {
VOID View_Scene::Initialize()
} {
SetName("Scene");
SetIcon(ICON_FA_HASHTAG);
#include <IAEngine/LibInterface.hpp> }
C_DECL(GameRequestedConfig *Game_GetConfigRequest()) VOID View_Scene::Terminate()
{ {
return nullptr; }
}
C_DECL(VOID Game_OnInitialize()) VOID View_Scene::Render()
{ {
} PreRender();
C_DECL(VOID Game_OnTerminate())
{
}
C_DECL(VOID Game_OnDebugDraw()) PostRender();
{ }
}
C_DECL(VOID Game_OnFixedUpdate()) VOID View_Scene::Update()
{ {
} STATIC INT32 frameCounter{0};
C_DECL(VOID Game_OnUpdate(IN FLOAT32 deltaTime)) }
{
}
C_DECL(VOID Game_OnResize(IN INT32 newWidth, IN INT32 newHeight)) VOID View_Scene::OnEvent(IN SDL_Event *event)
{ {
} }
} // namespace ia::iae

View File

File diff suppressed because one or more lines are too long

View File

@ -21,7 +21,12 @@
#include <Vendor/imgui/imgui.h> #include <Vendor/imgui/imgui.h>
#include <Vendor/IconsFontAwesome7.h> #include <Vendor/IconsFontAwesome7.h>
#include <SDL3/SDL.h>
#include <filesystem>
namespace ia::iae namespace ia::iae
{ {
namespace fs = std::filesystem;
using Path = std::filesystem::path;
} }

View File

@ -32,6 +32,10 @@ namespace ia::iae
public: public:
VOID LoadProject(IN CONST String &directory); VOID LoadProject(IN CONST String &directory);
VOID OpenFile(IN Path path);
VOID MarkAsAsset(IN Path path);
VOID RemoveFromAssets(IN CONST String& assetName);
public: public:
CONST Project *GetActiveProject() CONST CONST Project *GetActiveProject() CONST

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@
#pragma once #pragma once
#include <Base.hpp> #include <Base.hpp>
#include <ConfigData/ConfigData.hpp>
namespace ia::iae namespace ia::iae
{ {
@ -25,7 +26,14 @@ namespace ia::iae
public: public:
STATIC RefPtr<Project> Load(IN CONST String &directory); STATIC RefPtr<Project> Load(IN CONST String &directory);
VOID Update();
public: public:
IVec2 &WindowPosition()
{
return m_windowPosition;
}
CONST String &Name() CONST CONST String &Name() CONST
{ {
return m_projectName; return m_projectName;
@ -35,14 +43,18 @@ namespace ia::iae
{ {
return m_assetDirectory; return m_assetDirectory;
} }
private: private:
IVec2 m_windowPosition{};
CONST String m_projectName; CONST String m_projectName;
CONST String m_assetDirectory; CONST String m_assetDirectory;
CONST String m_projectAbsolutePath; CONST String m_projectAbsolutePath;
RefPtr<ConfigData> m_configData;
public: public:
Project(IN CONST String &name, IN CONST String &absolutePath); Project(IN CONST String &name, IN CONST String &absolutePath, IN RefPtr<ConfigData>&& configData);
~Project(); ~Project();
}; };
} // namespace ia::iae } // namespace ia::iae

View File

@ -0,0 +1,32 @@
// 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>
#include <Vendor/imgui/imgui_internal.h>
namespace ia::iae
{
STATIC CONSTEXPR IVec2 SCENE_EDITOR_RESOULTION = {800, 604};
STATIC CONSTEXPR Vec2 LAYOUT_TOP_LEFT_VIEW_EXTENT = {0.275f, 0.55f};
STATIC CONSTEXPR Vec2 LAYOUT_TOP_MIDDLE_VIEW_EXTENT = {0.45f, 0.55f};
STATIC CONSTEXPR Vec2 LAYOUT_TOP_RIGHT_VIEW_EXTENT = {0.275f, 0.55f};
STATIC CONSTEXPR Vec2 LAYOUT_BOTTOM_VIEW_EXTENT = {1.0f, 0.45f};
STATIC CONSTEXPR FLOAT32 MENUBAR_HEIGHT = 18.0f;
} // namespace ia::iae

View File

View File

@ -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 <https://www.gnu.org/licenses/>.
#pragma once
#include <UI/View/IView.hpp>
namespace ia::iae
{
class TabContainer
{
struct Tab
{
IView* View{};
BOOL IsOpen{true};
BOOL IsCloseable{false};
};
public:
TabContainer();
VOID Initialize();
VOID Terminate();
VOID Draw(IN ImVec2 position, IN ImVec2 size);
VOID Update();
VOID ProcessEvent(IN SDL_Event *event);
template<typename ViewType> INLINE VOID AddTab(IN CONST String &name, IN BOOL isCloseable = false);
IView *GetTab(IN CONST String &name);
VOID RemoveTab(IN CONST String &name);
VOID OpenTab(IN CONST String& name);
VOID CloseTab(IN CONST String& name);
VOID ChangeActiveTab(IN PCCHAR name);
private:
CONST String m_tabBarID;
CONST String m_containerID;
PCCHAR m_activeTabName{};
PCCHAR m_pendingActiveTabName{};
Map<String, Tab> m_tabViews;
private:
VOID AddTab(IN CONST String &name, IN IView *view, IN BOOL isCloseable);
};
template<typename ViewType> VOID TabContainer::AddTab(IN CONST String &name, IN BOOL isCloseable)
{
AddTab(name, new ViewType(), isCloseable);
}
} // namespace ia::iae

View File

@ -0,0 +1,69 @@
// 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 <UI/Base.hpp>
namespace ia::iae
{
class UI
{
public:
STATIC VOID PadX(IN FLOAT32 v = 5.0f);
STATIC VOID PadY(IN FLOAT32 v = 5.0f);
STATIC VOID AlignCursorLeft(IN CONST ImRect &rect);
STATIC VOID AlignCursorRight(IN CONST ImRect &rect, IN FLOAT32 width);
STATIC VOID AlignCursorTop(IN CONST ImRect &rect);
STATIC VOID AlignCursorBottom(IN CONST ImRect &rect, IN FLOAT32 height);
STATIC VOID AlignCursorHCenter(IN CONST ImRect &rect, IN FLOAT32 width);
STATIC VOID AlignCursorVCenter(IN CONST ImRect &rect, IN FLOAT32 height);
STATIC VOID DrawTextCentered(IN CONST ImVec2& viewExtent, IN CONST String& text);
public:
STATIC VOID OpenFilePreviewView();
STATIC VOID CloseFilePreviewView();
STATIC VOID OpenAssetView();
STATIC VOID CloseAssetView();
STATIC class View_Asset* GetAssetView();
STATIC class View_FilePreview *GetFilePreviewView();
STATIC class IView *GetFocusedView()
{
return s_focusedView;
}
private:
STATIC class IView *s_focusedView;
private:
STATIC VOID Initialize();
STATIC VOID Terminate();
STATIC VOID Draw();
STATIC VOID Update();
STATIC VOID ProcessEvent(IN SDL_Event *event);
friend class Editor;
private:
STATIC VOID DrawMenuBar();
};
} // namespace ia::iae

View File

@ -0,0 +1,56 @@
// 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 <UI/View/IView.hpp>
#include <IAEngine/Asset/IAsset.hpp>
namespace ia::iae
{
class View_Asset : public IView
{
public:
VOID Open(IN String assetName);
VOID Close();
public:
VOID Initialize();
VOID Terminate();
VOID Render();
VOID Update();
protected:
VOID OnEvent(IN SDL_Event *event);
private:
VOID RenderTextureAsset();
VOID RenderSpriteAsset();
VOID RenderTileSheetAsset();
VOID RenderSpriteSheetAsset();
VOID DrawAssetTypePicker();
VOID DrawAssetImage(IN FLOAT32 relativeWidth, IN IVec2 gridSize);
private:
class IAsset *m_asset{};
String m_assetName{};
Handle m_assetImageHandle{};
IVec2 m_assetImageExtent{};
EAssetType m_assetType{};
};
} // namespace ia::iae

View File

@ -16,7 +16,7 @@
#pragma once #pragma once
#include <View/IView.hpp> #include <UI/View/IView.hpp>
#include <filesystem> #include <filesystem>
@ -29,12 +29,18 @@ namespace ia::iae
PCCHAR Icon{""}; PCCHAR Icon{""};
String Name{}; String Name{};
BOOL IsDirectory{}; BOOL IsDirectory{};
String IconAndName{};
std::filesystem::path Path{};
}; };
public: public:
VOID Initialize(); VOID Initialize();
VOID Terminate(); VOID Terminate();
VOID Render(); VOID Render();
VOID Update();
protected:
VOID OnEvent(IN SDL_Event *event);
private: private:
VOID ChangeCurrentOpenDirectory(IN CONST std::filesystem::path &path); VOID ChangeCurrentOpenDirectory(IN CONST std::filesystem::path &path);
@ -42,6 +48,8 @@ namespace ia::iae
PCCHAR GetFileEntryIcon(IN PCCHAR extension); PCCHAR GetFileEntryIcon(IN PCCHAR extension);
VOID OpenAsset(IN CONST std::filesystem::path &path);
private: private:
Vector<FileEntry> m_assetDirectoryFiles; Vector<FileEntry> m_assetDirectoryFiles;
std::filesystem::path m_assetDirectoryPath{}; std::filesystem::path m_assetDirectoryPath{};

View File

@ -16,12 +16,19 @@
#pragma once #pragma once
#include <Base.hpp> #include <UI/View/IView.hpp>
namespace ia::iae namespace ia::iae
{ {
class GamePreview class View_Console : public IView
{ {
public: public:
VOID Initialize();
VOID Terminate();
VOID Render();
VOID Update();
protected:
VOID OnEvent(IN SDL_Event *event);
}; };
} }

View File

@ -0,0 +1,58 @@
// 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 <UI/View/IView.hpp>
namespace ia::iae
{
class View_FilePreview : public IView
{
enum class EFileType
{
UNKNOWN,
TEXT,
IMAGE,
};
public:
VOID Open(IN Path path);
VOID Close();
public:
VOID Initialize();
VOID Terminate();
VOID Render();
VOID Update();
protected:
VOID OnEvent(IN SDL_Event *event);
private:
VOID RenderTextFile();
VOID RenderImageFile();
VOID RenderUnknownFile();
private:
Path m_filePath{};
EFileType m_fileType{EFileType::UNKNOWN};
PVOID m_fileData{};
SIZE_T m_fileDataSize{};
IVec2 m_fileDataExtent{};
};
} // namespace ia::iae

View File

@ -0,0 +1,43 @@
// 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 <UI/View/IView.hpp>
namespace ia::iae
{
class View_Game : public IView
{
public:
VOID Initialize();
VOID Terminate();
VOID Render();
VOID Update();
protected:
VOID OnEvent(IN SDL_Event *event);
public:
VOID ProcessEvent(IN SDL_Event *event)
{
OnEvent(event);
}
private:
class RDC_Texture* m_gameRenderTexture;
};
} // namespace ia::iae

View File

@ -0,0 +1,82 @@
// 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 <UI/UI.hpp>
namespace ia::iae
{
class IView
{
protected:
PURE_VIRTUAL(VOID OnEvent(IN SDL_Event *event));
public:
PURE_VIRTUAL(VOID Initialize());
PURE_VIRTUAL(VOID Terminate());
PURE_VIRTUAL(VOID Render());
PURE_VIRTUAL(VOID Update());
public:
VOID SetIcon(IN PCCHAR icon);
VOID SetName(IN CONST String &name);
VIRTUAL VOID ProcessEvent(IN SDL_Event *event);
public:
CONST String &Name() CONST
{
return m_name;
}
CONST PCCHAR Icon() CONST
{
return m_icon;
}
CONST String &IconAndName() CONST
{
return m_iconAndName;
}
protected:
INLINE VOID PreRender();
INLINE VOID PostRender();
protected:
ImVec2 m_extent{};
String m_name{};
PCCHAR m_icon{};
String m_iconAndName{};
public:
VIRTUAL ~IView()
{
}
};
VOID IView::PreRender()
{
m_extent = ImGui::GetContentRegionAvail();
ImGui::BeginChild("##");
}
VOID IView::PostRender()
{
ImGui::EndChild();
}
} // namespace ia::iae

View File

@ -16,18 +16,19 @@
#pragma once #pragma once
#include <Base.hpp> #include <UI/View/IView.hpp>
namespace ia::iae namespace ia::iae
{ {
CONST IVec2 gamePreviewResolution = {800, 608}; class View_Nodes : public IView
class UI
{ {
public: public:
STATIC VOID Initialize(); VOID Initialize();
STATIC VOID Terminate(); VOID Terminate();
STATIC VOID Update(); VOID Render();
STATIC VOID Draw(); VOID Update();
protected:
VOID OnEvent(IN SDL_Event *event);
}; };
} }

View File

@ -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 <https://www.gnu.org/licenses/>.
#pragma once
#include <UI/View/IView.hpp>
namespace ia::iae
{
class View_Package : public IView
{
public:
VOID Initialize();
VOID Terminate();
VOID Render();
VOID Update();
protected:
VOID OnEvent(IN SDL_Event *event);
};
}

View File

@ -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 <https://www.gnu.org/licenses/>.
#pragma once
#include <UI/View/IView.hpp>
namespace ia::iae
{
class View_Properties : public IView
{
public:
VOID Initialize();
VOID Terminate();
VOID Render();
VOID Update();
protected:
VOID OnEvent(IN SDL_Event *event);
};
}

View File

@ -0,0 +1,40 @@
// 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 <UI/View/IView.hpp>
namespace ia::iae
{
class View_Scene : public IView
{
public:
VOID Initialize();
VOID Terminate();
VOID Render();
VOID Update();
protected:
VOID OnEvent(IN SDL_Event *event);
public:
VOID ProcessEvent(IN SDL_Event *event)
{
OnEvent(event);
}
};
} // namespace ia::iae

View File

View File

@ -3,7 +3,8 @@ set(SRC_FILES
"imp/cpp/Scene.cpp" "imp/cpp/Scene.cpp"
"imp/cpp/GameData.cpp" "imp/cpp/GameData.cpp"
"imp/cpp/AssetManager.cpp"
"imp/cpp/Asset/AssetManager.cpp"
#"imp/cpp/EmbeddedResources.cpp" #"imp/cpp/EmbeddedResources.cpp"
) )

View File

@ -14,10 +14,9 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <IAEngine/AssetManager.hpp> #include <IAEngine/Asset/AssetManager.hpp>
#include <IAEngine/IAEngine.hpp> #include <IAEngine/IAEngine.hpp>
#include <SDL3/SDL_iostream.h> #include <SDL3/SDL_iostream.h>
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
@ -27,18 +26,27 @@
#include <IACore/DynamicLib.hpp> #include <IACore/DynamicLib.hpp>
#include <filesystem>
namespace ia::iae namespace ia::iae
{ {
Handle CreateTextureFromFile(IN PCCHAR path, IN INT32 tileWidth = -1, IN INT32 tileHeight = -1) Map<String, String> g_assetNameToPathMap;
Map<String, String> g_assetPathToNameMap;
String AssetManager::s_assetDirectory;
Vector<IAsset *> AssetManager::s_assets;
Map<String, IAsset *> AssetManager::s_assetNames;
ImageView *CreateTextureFromFile(IN PCCHAR path, IN INT32 tileWidth = -1, IN INT32 tileHeight = -1)
{ {
const auto data = IAEngine::GetAssetManager()->ReadBinaryAsset(path); const auto data = AssetManager::ReadBinaryAsset(path);
INT32 w, h, n; INT32 w, h, n;
auto pixels = stbi_load_from_memory(data.data(), data.size(), &w, &h, &n, STBI_rgb_alpha); auto pixels = stbi_load_from_memory(data.data(), data.size(), &w, &h, &n, STBI_rgb_alpha);
if (!pixels) if (!pixels)
THROW_INVALID_DATA(path); THROW_INVALID_DATA(path);
const auto t = const auto t = RDC::CreateImageView(RDC::CreateImage(pixels, w, h), tileWidth == -1 ? 1 : w / tileWidth,
RDC::CreateImage(pixels, w, h, tileWidth == -1 ? 1 : w / tileWidth, tileHeight == -1 ? 1 : h / tileHeight); tileHeight == -1 ? 1 : h / tileHeight);
stbi_image_free(pixels); stbi_image_free(pixels);
return t; return t;
} }
@ -49,18 +57,78 @@ namespace ia::iae
VOID AssetManager::Terminate() VOID AssetManager::Terminate()
{ {
for (SIZE_T i = 0; i < m_assets.size(); i++) for (SIZE_T i = 0; i < s_assets.size(); i++)
DestroyAsset(m_assets[i]); DestroyAsset(s_assets[i]);
}
String get_relative_asset_path(IN CONST String& _path)
{
std::string __path = _path.c_str();
const auto t = std::filesystem::path(_path.c_str());
return t.is_absolute() ? String(__path.substr(__path.find("Assets") + 7).c_str()) : _path;
}
String AssetManager::GetAssetName(IN CONST String &_path)
{
const auto path = get_relative_asset_path(_path);
if(g_assetPathToNameMap.contains(path))
return g_assetPathToNameMap[path];
return "";
}
IAsset* AssetManager::ChangeAssetType(IN CONST String& assetName, IN EAssetType newType)
{
if(!s_assetNames.contains(assetName))
return nullptr;
const auto currentAsset = (Asset_Texture*)s_assetNames[assetName];
if(newType == currentAsset->GetType())
return currentAsset;
IAsset* asset{};
switch(newType)
{
case EAssetType::TEXTURE:
asset = new Asset_Texture(currentAsset->GetHandle());
break;
case EAssetType::SPRITE:
asset = new Asset_Sprite(currentAsset->GetHandle());
break;
case EAssetType::TILESHEET:
asset = new Asset_TileSheet(currentAsset->GetHandle(), currentAsset->GetHandle()->ImagePtr->Width, currentAsset->GetHandle()->ImagePtr->Height);
break;
case EAssetType::SPRITESHEET:
asset = new Asset_SpriteSheet(currentAsset->GetHandle(), currentAsset->GetHandle()->ImagePtr->Width, currentAsset->GetHandle()->ImagePtr->Height, {});
break;
case EAssetType::INVALID:
case EAssetType::SOUND:
case EAssetType::SCENE:
case EAssetType::PLUGIN:
case EAssetType::PACKAGE:
break;
}
DestroyAsset(s_assetNames[assetName]);
s_assetNames[assetName] = asset;
return asset;
} }
VOID AssetManager::SetAssetDirectory(IN CONST String &path) VOID AssetManager::SetAssetDirectory(IN CONST String &path)
{ {
m_assetDirectory = path; s_assetDirectory = path;
} }
String AssetManager::ReadTextAsset(IN CONST String &path) String AssetManager::ReadTextAsset(IN CONST String &path)
{ {
const auto t = BuildString(m_assetDirectory, "/", path); const auto t =
std::filesystem::path(path.c_str()).is_absolute() ? path : BuildString(s_assetDirectory, "/", path);
SDL_IOStream *f = SDL_IOFromFile(t.c_str(), "r"); SDL_IOStream *f = SDL_IOFromFile(t.c_str(), "r");
if (!f) if (!f)
THROW_FILE_OPEN_READ(t); THROW_FILE_OPEN_READ(t);
@ -76,7 +144,8 @@ namespace ia::iae
Vector<UINT8> AssetManager::ReadBinaryAsset(IN CONST String &path) Vector<UINT8> AssetManager::ReadBinaryAsset(IN CONST String &path)
{ {
const auto t = BuildString(m_assetDirectory, "/", path); const auto t =
std::filesystem::path(path.c_str()).is_absolute() ? path : BuildString(s_assetDirectory, "/", path);
SDL_IOStream *f = SDL_IOFromFile(t.c_str(), "rb"); SDL_IOStream *f = SDL_IOFromFile(t.c_str(), "rb");
if (!f) if (!f)
THROW_FILE_OPEN_READ(t); THROW_FILE_OPEN_READ(t);
@ -89,64 +158,63 @@ namespace ia::iae
return result; return result;
} }
Asset_Plugin *AssetManager::LoadPlugin(IN CONST String &path) Asset_Texture *AssetManager::LoadTexture(IN CONST String &path)
{ {
auto lib = DynamicLib::Load(BuildString(m_assetDirectory, "/Plugins"), path); const auto t = new Asset_Texture(CreateTextureFromFile(path.c_str()));
auto t = new Asset_Plugin(); t->SetPath(get_relative_asset_path(path));
t->OnInitialize = lib.GetFunction<VOID (*)()>("Plugin_OnInitialize"); s_assets.pushBack(t);
t->OnTerminate = lib.GetFunction<VOID (*)()>("Plugin_OnTerminate");
t->OnDebugDraw = lib.GetFunction<VOID (*)()>("Plugin_OnDebugDraw");
t->OnFixedUpdate = lib.GetFunction<VOID (*)()>("Plugin_OnFixedUpdate");
t->OnUpdate = lib.GetFunction<VOID (*)(IN FLOAT32 deltaTime)>("Plugin_OnUpdate");
return t; return t;
} }
Asset_Sprite *AssetManager::CreateSprite(IN CONST String &path) Asset_Sprite *AssetManager::LoadSprite(IN CONST String &path)
{ {
const auto t = new Asset_Sprite();
t->m_texture = CreateTextureFromFile(path.c_str());
m_assets.pushBack(t);
return t;
}
Asset_Sprite *AssetManager::CreateSprite(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height)
{
const auto t = new Asset_Sprite();
t->m_texture = RDC::CreateImage(rgbaData, width, height);
m_assets.pushBack(t);
return t;
}
Asset_SpriteSheet *AssetManager::CreateSpriteSheet(IN CONST Vector<Vector<Handle>> &animations)
{
THROW_NOT_IMPLEMENTED();
return nullptr; return nullptr;
} }
Asset_SpriteSheet *AssetManager::CreateSpriteSheet(IN CONST String &path, IN INT32 spriteWidth, Asset_SpriteSheet *AssetManager::LoadSpriteSheet(IN CONST String &path)
IN INT32 spriteHeight, IN CONST Vector<INT32> &frameCounts)
{ {
const auto t = new Asset_SpriteSheet(); return nullptr;
t->m_frameCounts = frameCounts;
t->m_texture = CreateTextureFromFile(path.c_str(), spriteWidth, spriteHeight);
m_assets.pushBack(t);
return t;
} }
Asset_TileSheet *AssetManager::CreateTileSheet(IN CONST String &path, IN INT32 tileWidth, IN INT32 tileHeight) Asset_TileSheet *AssetManager::LoadTileSheet(IN CONST String &path)
{ {
const auto t = new Asset_TileSheet(); return nullptr;
t->m_texture = CreateTextureFromFile(path.c_str(), tileWidth, tileHeight);
m_assets.pushBack(t);
return t;
} }
Asset_TileSheet *AssetManager::CreateTileSheet(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height, IAsset_Package *AssetManager::LoadPackage(IN CONST String &path)
IN INT32 tileWidth, IN INT32 tileHeight)
{ {
const auto t = new Asset_TileSheet(); return nullptr;
t->m_texture = RDC::CreateImage(rgbaData, width, height, width / tileWidth, height / tileHeight); }
m_assets.pushBack(t);
Asset_Texture *AssetManager::CreateTexture(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height)
{
return new Asset_Texture(RDC::CreateImageView(RDC::CreateImage(rgbaData, width, height)));
}
Asset_Sprite *AssetManager::CreateSprite(IN CONST Asset_Texture *texture)
{
return new Asset_Sprite(texture->m_handle);
}
Asset_SpriteSheet *AssetManager::CreateSpriteSheet(IN CONST Vector<Asset_Texture *> &sprites,
IN CONST Map<String, INT32> &animations)
{
return nullptr;
}
Asset_SpriteSheet *AssetManager::CreateSpriteSheet(IN CONST Asset_Texture *texture, IN INT32 frameWidth,
IN INT32 frameHeight, IN CONST Map<String, INT32> &animations)
{
return nullptr;
}
Asset_TileSheet *AssetManager::CreateTileSheet(IN CONST Asset_Texture *texture, IN INT32 tileWidth,
IN INT32 tileHeight)
{
const auto image = texture->m_handle->ImagePtr;
const auto t = new Asset_TileSheet(
RDC::CreateImageView(image, image->Width / tileWidth, image->Height / tileHeight), tileWidth, tileHeight);
s_assets.pushBack(t);
return t; return t;
} }
@ -155,30 +223,31 @@ namespace ia::iae
asset->Destroy(); asset->Destroy();
delete asset; delete asset;
for (auto &t : m_assets) for (auto &t : s_assets)
if (t == asset) if (t == asset)
t = nullptr; t = nullptr;
for (auto &t : m_assetNames) for (auto &t : s_assetNames)
if (t->Value == asset) if (t->Value == asset)
t->Value = nullptr; t->Value = nullptr;
} }
IAsset *AssetManager::GetAssetByName(IN CONST String &name) IAsset *AssetManager::GetAssetByName(IN CONST String &name)
{ {
return m_assetNames[name]; return s_assetNames[name];
} }
VOID AssetManager::AssignAssetName(IN IAsset *asset, IN CONST String &name) VOID AssetManager::AssignAssetName(IN IAsset *asset, IN CONST String &name)
{ {
m_assetNames[name] = asset; s_assetNames[name] = asset;
g_assetNameToPathMap[name] = asset->GetPath();
g_assetPathToNameMap[asset->GetPath()] = name;
} }
Asset_Scene *AssetManager::CreateScene(IN IVec2 extent) Asset_Scene *AssetManager::CreateScene(IN IVec2 extent)
{ {
const auto t = new Asset_Scene(); const auto t = new Asset_Scene(new Scene(extent));
t->m_scene.SetExtent(extent); s_assets.pushBack(t);
m_assets.pushBack(t);
return t; return t;
} }
} // namespace ia::iae } // namespace ia::iae
@ -193,6 +262,22 @@ namespace ia::iae
{ {
} }
VOID Asset_Texture::Compile()
{
}
VOID Asset_Texture::Destroy()
{
}
VOID Asset_TileSheet::Compile()
{
}
VOID Asset_TileSheet::Destroy()
{
}
VOID Asset_Sprite::Compile() VOID Asset_Sprite::Compile()
{ {
} }
@ -224,6 +309,14 @@ namespace ia::iae
VOID Asset_Plugin::Destroy() VOID Asset_Plugin::Destroy()
{ {
} }
VOID IAsset_Package::Compile()
{
}
VOID IAsset_Package::Destroy()
{
}
} // namespace ia::iae } // namespace ia::iae
#include <zlib.h> #include <zlib.h>

View File

@ -45,7 +45,7 @@ namespace ia::iae
BOOL GameData::LoadSceneData() BOOL GameData::LoadSceneData()
{ {
for (const auto &entry : std::filesystem::directory_iterator("Assets/Scenes/")) for (const auto &entry : std::filesystem::directory_iterator(BuildString(AssetManager::GetAssetDirectory(), "/Scenes/").c_str()))
{ {
const auto scene = ParseScene(entry.path().string().c_str()); const auto scene = ParseScene(entry.path().string().c_str());
if (!scene) if (!scene)
@ -59,7 +59,7 @@ namespace ia::iae
BOOL GameData::LoadAssetData() BOOL GameData::LoadAssetData()
{ {
auto xml = ConfigData::LoadFromFile("Assets/Assets.xml"); auto xml = ConfigData::LoadFromFile(BuildString(AssetManager::GetAssetDirectory(), "/Assets.xml"));
if (!xml) if (!xml)
return false; return false;
@ -85,8 +85,8 @@ namespace ia::iae
} }
else if (!strcmp(entry.name(), "TileSheet")) else if (!strcmp(entry.name(), "TileSheet"))
{ {
IAEngine::GetAssetManager()->AssignAssetName( AssetManager::AssignAssetName(
IAEngine::GetAssetManager()->CreateTileSheet(entry.attribute("path").as_string(), AssetManager::CreateTileSheet(AssetManager::LoadTexture(entry.attribute("path").as_string()),
entry.attribute("tileWidth").as_int(), entry.attribute("tileWidth").as_int(),
entry.attribute("tileHeight").as_int()), entry.attribute("tileHeight").as_int()),
entry.attribute("name").as_string()); entry.attribute("name").as_string());
@ -109,27 +109,27 @@ namespace ia::iae
return nullptr; return nullptr;
const auto extent = IVec2{extentNode.attribute("width").as_int(), extentNode.attribute("height").as_int()}; const auto extent = IVec2{extentNode.attribute("width").as_int(), extentNode.attribute("height").as_int()};
auto scene = IAEngine::GetAssetManager()->CreateScene(extent); auto scene = AssetManager::CreateScene(extent);
for (const auto &child : xml->Children()) for (const auto &child : xml->Children())
{ {
if (!strcmp(child.name(), "Assets")) if (!strcmp(child.name(), "Assets"))
{ {
for (const auto &r : child.children()) for (const auto &r : child.children())
scene->GetScene().AddReferencedResources(IAEngine::GetAssetManager()->GetAssetByName<IAsset>(r.attribute("name").as_string())); scene->GetHandle()->AddReferencedResources(AssetManager::GetAssetByName<IAsset>(r.attribute("name").as_string()));
} }
else if (!strcmp(child.name(), "Nodes")) else if (!strcmp(child.name(), "Nodes"))
{ {
} }
else if (!strcmp(child.name(), "Grid")) else if (!strcmp(child.name(), "Grid"))
{ {
ParseSceneGrid(&scene->GetScene(), &child); ParseSceneGrid(scene->GetHandle(), &child);
} }
else else
THROW_INVALID_DATA(); THROW_INVALID_DATA();
} }
IAEngine::GetAssetManager()->AssignAssetName(scene, xml->Name()); AssetManager::AssignAssetName(scene, xml->Name());
if (!g_entryScene) if (!g_entryScene)
g_entryScene = scene; g_entryScene = scene;
@ -155,7 +155,7 @@ namespace ia::iae
return; return;
auto& cell = scene->GetGridCell(tileCursorX, tileCursorY); auto& cell = scene->GetGridCell(tileCursorX, tileCursorY);
cell.TileSheet = IAEngine::GetAssetManager()->GetAssetByName<Asset_TileSheet>(cellNode.attribute("tileSheet").as_string()); cell.TileSheet = AssetManager::GetAssetByName<Asset_TileSheet>(cellNode.attribute("tileSheet").as_string());
cell.TileIndex.x = cellNode.attribute("tileX").as_int(); cell.TileIndex.x = cellNode.attribute("tileX").as_int();
cell.TileIndex.y = cellNode.attribute("tileY").as_int(); cell.TileIndex.y = cellNode.attribute("tileY").as_int();
cell.CollisionMask = cellNode.attribute("collisionMask").as_ullong(); cell.CollisionMask = cellNode.attribute("collisionMask").as_ullong();

View File

@ -35,15 +35,6 @@ namespace ia::iae
Vector<Asset_Plugin *> g_plugins; Vector<Asset_Plugin *> g_plugins;
AssetManager* g_assetManager{};
AssetManager* g_defaultAssetManager{};
#if defined(__IA_DEBUG) && __IA_DEBUG
BOOL g_isDebugMode = true;
#else
BOOL g_isDebugMode = false;
#endif
BOOL g_isHeadlessMode = false; BOOL g_isHeadlessMode = false;
INT32 Run(IN CONST String &name, IN CONST String &packageName, IN CONST String &developerName, INT32 Run(IN CONST String &name, IN CONST String &packageName, IN CONST String &developerName,
@ -82,7 +73,7 @@ namespace ia::iae
// EmbeddedResources::Initialize(); // EmbeddedResources::Initialize();
IAEngine::__Initialize(); IAEngine::__Initialize(g_designViewport, "./Assets/");
SDL_Event event{}; SDL_Event event{};
while (true) while (true)
@ -117,105 +108,102 @@ namespace ia::iae
namespace ia::iae namespace ia::iae
{ {
VOID IAEngine::__Initialize() VOID IAEngine::__Initialize(IN IVec2 designResolution, IN CONST String& assetDirectory)
{ {
g_isHeadlessMode = false; g_isHeadlessMode = false;
g_designViewport = designResolution;
RDC::Initialize(IVec2{g_designViewport.x, g_designViewport.y}, g_windowHandle, g_isDebugMode); RDC::Initialize(IVec2{g_designViewport.x, g_designViewport.y}, g_windowHandle, g_isDebugMode);
g_defaultAssetManager = new AssetManager(); AssetManager::SetAssetDirectory(assetDirectory);
g_assetManager = g_defaultAssetManager;
GameData::Initialize(); GameData::Initialize();
ChangeActiveScene(GameData::GetEntryScene() ChangeActiveScene(GameData::GetEntryScene()
? GameData::GetEntryScene() ? GameData::GetEntryScene()
: g_assetManager->CreateScene({g_designViewport.x, g_designViewport.y})); : AssetManager::CreateScene({g_designViewport.x, g_designViewport.y}));
Game_OnInitialize(); Game_OnInitialize();
for (auto &p : g_plugins) //for (auto &p : g_plugins)
p->OnInitialize(); // p->OnInitialize();
} }
VOID IAEngine::__InitializeHeadless() VOID IAEngine::__InitializeHeadless(IN CONST String& assetDirectory)
{ {
g_isHeadlessMode = true; g_isHeadlessMode = true;
if (!g_designViewport.x || !g_designViewport.y) if (!g_designViewport.x || !g_designViewport.y)
g_designViewport = {800, 600}; g_designViewport = {800, 600};
g_defaultAssetManager = new AssetManager(); AssetManager::SetAssetDirectory(assetDirectory);
g_assetManager = g_defaultAssetManager;
GameData::Initialize(); GameData::Initialize();
ChangeActiveScene(GameData::GetEntryScene() ChangeActiveScene(GameData::GetEntryScene()
? GameData::GetEntryScene() ? GameData::GetEntryScene()
: g_assetManager->CreateScene({g_designViewport.x, g_designViewport.y})); : AssetManager::CreateScene({g_designViewport.x, g_designViewport.y}));
Game_OnInitialize(); Game_OnInitialize();
for (auto &p : g_plugins) //for (auto &p : g_plugins)
p->OnInitialize(); // p->OnInitialize();
} }
VOID IAEngine::__Terminate() VOID IAEngine::__Terminate()
{ {
for (auto &p : g_plugins) //for (auto &p : g_plugins)
p->OnTerminate(); // p->OnTerminate();
Game_OnTerminate(); Game_OnTerminate();
GameData::Terminate(); GameData::Terminate();
delete g_defaultAssetManager;
RDC::Terminate(); RDC::Terminate();
} }
VOID IAEngine::__RenderToWindow() VOID IAEngine::__RenderToWindow()
{ {
g_activeScene->GetScene().OnDraw(); g_activeScene->GetHandle()->OnDraw();
RDC::RenderToWindow(); RDC::RenderToWindow();
g_activeScene->GetScene().OnDebugDraw(); g_activeScene->GetHandle()->OnDebugDraw();
Game_OnDebugDraw(); Game_OnDebugDraw();
for (auto &p : g_plugins) //for (auto &p : g_plugins)
p->OnDebugDraw(); // p->OnDebugDraw();
} }
VOID IAEngine::__RenderToTexture(IN PVOID textureHandle) VOID IAEngine::__RenderToTexture(IN PVOID textureHandle)
{ {
g_activeScene->GetScene().OnDraw(); g_activeScene->GetHandle()->OnDraw();
RDC::RenderToTexture((SDL_GPUTexture *) textureHandle); RDC::RenderToTexture((SDL_GPUTexture *) textureHandle);
g_activeScene->GetScene().OnDebugDraw(); g_activeScene->GetHandle()->OnDebugDraw();
Game_OnDebugDraw(); Game_OnDebugDraw();
for (auto &p : g_plugins) //for (auto &p : g_plugins)
p->OnDebugDraw(); // p->OnDebugDraw();
} }
VOID IAEngine::__Update() VOID IAEngine::__Update()
{ {
FLOAT32 deltaTime = 0; FLOAT32 deltaTime = 0;
g_activeScene->GetScene().OnUpdate(deltaTime); g_activeScene->GetHandle()->OnUpdate(deltaTime);
Game_OnUpdate(deltaTime); Game_OnUpdate(deltaTime);
for (auto &p : g_plugins) //for (auto &p : g_plugins)
p->OnUpdate(deltaTime); // p->OnUpdate(deltaTime);
} }
VOID IAEngine::__FixedUpdate() VOID IAEngine::__FixedUpdate()
{ {
g_activeScene->GetScene().OnFixedUpdate(); g_activeScene->GetHandle()->OnFixedUpdate();
Game_OnFixedUpdate(); Game_OnFixedUpdate();
for (auto &p : g_plugins) //for (auto &p : g_plugins)
p->OnFixedUpdate(); // p->OnFixedUpdate();
} }
VOID IAEngine::__ProcessEvent(IN PVOID _event) VOID IAEngine::__ProcessEvent(IN PVOID _event)
@ -227,16 +215,6 @@ namespace ia::iae
{ {
g_plugins.pushBack(plugin); g_plugins.pushBack(plugin);
} }
AssetManager* IAEngine::GetAssetManager()
{
return g_assetManager;
}
VOID IAEngine::SetAssetManager(IN AssetManager *instance)
{
g_assetManager = instance;
}
} // namespace ia::iae } // namespace ia::iae
namespace ia::iae namespace ia::iae
@ -244,21 +222,21 @@ namespace ia::iae
VOID IAEngine::DrawTile(IN Asset_TileSheet *tileSheet, IN INT32 tileIndexX, IN INT32 tileIndexY, IN Vec2 position, VOID IAEngine::DrawTile(IN Asset_TileSheet *tileSheet, IN INT32 tileIndexX, IN INT32 tileIndexY, IN Vec2 position,
IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset) IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset)
{ {
RDC::DrawSpriteTopLeft(tileSheet->GetTexture(), tileIndexX, tileIndexY, position, scale, rotation, flipH, flipV, RDC::DrawSpriteTopLeft(tileSheet->GetHandle(), tileIndexX, tileIndexY, position, scale, rotation, flipH, flipV,
uvOffset); uvOffset);
} }
VOID IAEngine::DrawSprite(IN Asset_Sprite *sprite, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, VOID IAEngine::DrawSprite(IN Asset_Sprite *sprite, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation,
IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset) IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset)
{ {
RDC::DrawSpriteTopLeft(sprite->GetTexture(), 0, 0, position, scale, rotation, flipH, flipV, uvOffset); RDC::DrawSpriteTopLeft(sprite->GetHandle(), 0, 0, position, scale, rotation, flipH, flipV, uvOffset);
} }
VOID IAEngine::DrawSprite(IN Asset_SpriteSheet *spriteSheet, IN INT32 animationIndex, IN INT32 frameIndex, VOID IAEngine::DrawSprite(IN Asset_SpriteSheet *spriteSheet, IN INT32 animationIndex, IN INT32 frameIndex,
IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV,
IN Vec2 uvOffset) IN Vec2 uvOffset)
{ {
RDC::DrawSpriteTopLeft(spriteSheet->GetTexture(), frameIndex, animationIndex, position, scale, rotation, flipH, RDC::DrawSpriteTopLeft(spriteSheet->GetHandle(), frameIndex, animationIndex, position, scale, rotation, flipH,
flipV, uvOffset); flipV, uvOffset);
} }
} // namespace ia::iae } // namespace ia::iae

View File

@ -16,7 +16,7 @@
#pragma once #pragma once
#include <IAEngine/AssetManager.hpp> #include <IAEngine/Asset/AssetManager.hpp>
namespace ia::iae namespace ia::iae
{ {

View File

@ -0,0 +1,95 @@
// 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 <IAEngine/Asset/Package.hpp>
#include <IAEngine/Asset/Plugin.hpp>
#include <IAEngine/Asset/Scene.hpp>
#include <IAEngine/Asset/Sound.hpp>
#include <IAEngine/Asset/Sprite.hpp>
#include <IAEngine/Asset/SpriteSheet.hpp>
#include <IAEngine/Asset/Texture.hpp>
#include <IAEngine/Asset/TileSheet.hpp>
namespace ia::iae
{
class AssetManager final
{
public:
STATIC VOID SetAssetDirectory(IN CONST String &path);
STATIC String ReadTextAsset(IN CONST String &path);
STATIC Vector<UINT8> ReadBinaryAsset(IN CONST String &path);
public:
STATIC Asset_Texture *LoadTexture(IN CONST String &path);
STATIC Asset_Sprite *LoadSprite(IN CONST String &path);
STATIC Asset_SpriteSheet *LoadSpriteSheet(IN CONST String &path);
STATIC Asset_TileSheet *LoadTileSheet(IN CONST String &path);
STATIC IAsset_Package *LoadPackage(IN CONST String &path);
STATIC Asset_Scene *CreateScene(IN IVec2 extent);
STATIC Asset_Texture *CreateTexture(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height);
STATIC Asset_Sprite *CreateSprite(IN CONST Asset_Texture *texture);
STATIC Asset_SpriteSheet *CreateSpriteSheet(IN CONST Vector<Asset_Texture*>& sprites, IN CONST Map<String, INT32> &animations);
STATIC Asset_SpriteSheet *CreateSpriteSheet(IN CONST Asset_Texture *texture, IN INT32 frameWidth,
IN INT32 frameHeight, IN CONST Map<String, INT32> &animations);
STATIC Asset_TileSheet *CreateTileSheet(IN CONST Asset_Texture *texture, IN INT32 tileWidth,
IN INT32 tileHeight);
STATIC VOID DestroyAsset(IN IAsset *asset);
STATIC VOID AssignAssetName(IN IAsset *asset, IN CONST String &name);
STATIC String GetAssetName(IN CONST String& path);
STATIC IAsset* ChangeAssetType(IN CONST String& assetName, IN EAssetType newType);
template<typename AssetType>
requires std::is_base_of<IAsset, AssetType>::value
STATIC AssetType *GetAssetByName(IN CONST String &name);
public:
STATIC Vector<UINT8> Inflate(IN PCUINT8 data, IN SIZE_T dataSize);
STATIC Vector<UINT8> Deflate(IN PCUINT8 data, IN SIZE_T dataSize);
public:
STATIC CONST String &GetAssetDirectory()
{
return s_assetDirectory;
}
protected:
STATIC String s_assetDirectory;
STATIC Vector<IAsset *> s_assets;
STATIC Map<String, IAsset *> s_assetNames;
protected:
STATIC IAsset *GetAssetByName(IN CONST String &name);
private:
STATIC VOID Initialize();
STATIC VOID Terminate();
friend class IAEngine;
};
template<typename AssetType>
requires std::is_base_of<IAsset, AssetType>::value
AssetType *AssetManager::GetAssetByName(IN CONST String &name)
{
return (AssetType *) GetAssetByName(name);
}
} // namespace ia::iae

View File

@ -0,0 +1,66 @@
// 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 <IAEngine/Base.hpp>
namespace ia::iae
{
enum class EAssetType: INT32
{
INVALID,
TEXTURE,
SPRITE,
TILESHEET,
SPRITESHEET,
SOUND,
SCENE,
PLUGIN,
PACKAGE
};
class IAsset
{
public:
IAsset(IN EAssetType type);
VIRTUAL ~IAsset();
PURE_VIRTUAL(VOID Compile());
PURE_VIRTUAL(VOID Destroy());
public:
String GetPath() CONST
{
return m_path;
}
VOID SetPath(IN CONST String &path)
{
m_path = path;
}
EAssetType GetType() CONST
{
return m_type;
}
protected:
String m_path;
CONST EAssetType m_type;
};
} // namespace ia::iae

View File

@ -0,0 +1,49 @@
// 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 <IACore/StreamReader.hpp>
#include <IAEngine/Asset/IAsset.hpp>
namespace ia::iae
{
class IAsset_Package : public IAsset
{
public:
struct AssetRef
{
String Path;
Handle RefHandle{INVALID_HANDLE};
EAssetType Type{EAssetType::INVALID};
};
public:
IAsset_Package(IN Handle handle) : IAsset(EAssetType::PACKAGE)
{
}
VIRTUAL VOID Compile();
VIRTUAL VOID Destroy();
PURE_VIRTUAL(Vector<AssetRef>::const_iterator ListAssets());
PURE_VIRTUAL(RefPtr<IStreamReader> GetAssetData(IN Handle refHandle));
protected:
friend class AssetManager;
};
} // namespace ia::iae

View File

@ -0,0 +1,40 @@
// 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 <IAEngine/Asset/IAsset.hpp>
namespace ia::iae
{
class Asset_Plugin : public IAsset
{
public:
Asset_Plugin(IN Handle handle) : IAsset(EAssetType::PLUGIN), m_handle(handle)
{
}
VIRTUAL VOID Compile();
VIRTUAL VOID Destroy();
INLINE Handle GetHandle();
protected:
CONST Handle m_handle;
friend class AssetManager;
};
} // namespace ia::iae

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 <IAEngine/Asset/IAsset.hpp>
#include <IAEngine/Scene.hpp>
namespace ia::iae
{
class Asset_Scene : public IAsset
{
public:
Asset_Scene(IN Scene* handle) : IAsset(EAssetType::SCENE), m_handle(handle)
{
}
VIRTUAL VOID Compile();
VIRTUAL VOID Destroy();
INLINE Scene* GetHandle();
protected:
Scene* CONST m_handle;
friend class AssetManager;
};
INLINE Scene* Asset_Scene::GetHandle()
{
return m_handle;
}
} // namespace ia::iae

View File

@ -0,0 +1,45 @@
// 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 <IAEngine/Asset/IAsset.hpp>
namespace ia::iae
{
class Asset_Sound : public IAsset
{
public:
Asset_Sound(IN Handle handle) : IAsset(EAssetType::SOUND), m_handle(handle)
{
}
VIRTUAL VOID Compile();
VIRTUAL VOID Destroy();
INLINE Handle GetHandle();
protected:
CONST Handle m_handle;
friend class AssetManager;
};
INLINE Handle Asset_Sound::GetHandle()
{
return m_handle;
}
} // namespace ia::iae

View File

@ -0,0 +1,36 @@
// 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 <IAEngine/Asset/Texture.hpp>
namespace ia::iae
{
class Asset_Sprite : public Asset_Texture
{
public:
Asset_Sprite(IN ImageView* textureHandle) : Asset_Texture(textureHandle, EAssetType::SPRITE)
{
}
VIRTUAL VOID Compile();
VIRTUAL VOID Destroy();
protected:
friend class AssetManager;
};
}

View File

@ -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 <https://www.gnu.org/licenses/>.
#pragma once
#include <IAEngine/Asset/Texture.hpp>
namespace ia::iae
{
class Asset_SpriteSheet : public Asset_Texture
{
public:
struct AnimationDesc
{
INT32 StartRow{};
INT32 FrameCount{};
};
public:
Asset_SpriteSheet(IN ImageView *textureHandle, IN INT32 frameWidth, IN INT32 frameHeight,
IN Map<String, AnimationDesc> &&animations)
: Asset_Texture(textureHandle, EAssetType::SPRITESHEET), m_frameWidth(frameWidth),
m_frameHeight(frameHeight), m_animations(IA_MOVE(animations))
{
}
VIRTUAL VOID Compile();
VIRTUAL VOID Destroy();
INT32 &FrameWidth()
{
return m_frameWidth;
}
INT32 &FrameHeight()
{
return m_frameHeight;
}
Map<String, AnimationDesc> &Animations()
{
return m_animations;
}
protected:
INT32 m_frameWidth;
INT32 m_frameHeight;
Map<String, AnimationDesc> m_animations;
friend class AssetManager;
};
} // namespace ia::iae

View File

@ -0,0 +1,49 @@
// 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 <IAEngine/Asset/IAsset.hpp>
namespace ia::iae
{
class Asset_Texture : public IAsset
{
public:
Asset_Texture(IN ImageView* handle) : IAsset(EAssetType::TEXTURE), m_handle(handle)
{
}
Asset_Texture(IN ImageView* handle, IN EAssetType type) : IAsset(type), m_handle(handle)
{
}
VIRTUAL VOID Compile();
VIRTUAL VOID Destroy();
INLINE ImageView* GetHandle();
protected:
ImageView* CONST m_handle;
friend class AssetManager;
};
INLINE ImageView* Asset_Texture::GetHandle()
{
return m_handle;
}
} // namespace ia::iae

View File

@ -0,0 +1,49 @@
// 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 <IAEngine/Asset/Texture.hpp>
namespace ia::iae
{
class Asset_TileSheet : public Asset_Texture
{
public:
Asset_TileSheet(IN ImageView *textureHandle, IN INT32 tileWidth, IN INT32 tileHeight)
: Asset_Texture(textureHandle, EAssetType::TILESHEET), m_tileWidth(tileWidth), m_tileHeight(tileHeight)
{
}
VIRTUAL VOID Compile();
VIRTUAL VOID Destroy();
INT32 &TileWidth()
{
return m_tileWidth;
}
INT32 &TileHeight()
{
return m_tileHeight;
}
protected:
INT32 m_tileWidth;
INT32 m_tileHeight;
friend class AssetManager;
};
} // namespace ia::iae

View File

@ -1,222 +0,0 @@
// 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 <IAEngine/Scene.hpp>
#include <IACore/StreamReader.hpp>
namespace ia::iae
{
enum class EAssetType
{
INVALID,
SCENE,
SOUND,
SPRITE,
TILESHEET,
SPRITESHEET,
PLUGIN,
PACKAGE
};
class IAsset
{
public:
IAsset(IN EAssetType type);
VIRTUAL ~IAsset();
PURE_VIRTUAL(VOID Compile());
PURE_VIRTUAL(VOID Destroy());
protected:
CONST EAssetType m_type;
};
class Asset_Sprite : public IAsset
{
public:
Asset_Sprite() : IAsset(EAssetType::SPRITE)
{
}
Asset_Sprite(IN EAssetType type) : IAsset(type)
{
}
VOID Compile();
VOID Destroy();
INLINE Handle GetTexture();
protected:
Handle m_texture;
friend class AssetManager;
};
class Asset_TileSheet : public Asset_Sprite
{
public:
Asset_TileSheet() : Asset_Sprite(EAssetType::TILESHEET)
{
}
};
class Asset_SpriteSheet : public Asset_Sprite
{
public:
Asset_SpriteSheet() : Asset_Sprite(EAssetType::SPRITESHEET)
{
}
VOID Compile();
VOID Destroy();
INLINE CONST Vector<INT32> &GetFrameCounts() CONST;
protected:
Vector<INT32> m_frameCounts;
friend class AssetManager;
};
class Asset_Scene : public IAsset
{
public:
Asset_Scene() : IAsset(EAssetType::SCENE)
{
}
VOID Compile();
VOID Destroy();
public:
INLINE Scene &GetScene();
protected:
Scene m_scene;
friend class AssetManager;
};
class Asset_Plugin : public IAsset
{
public:
Asset_Plugin() : IAsset(EAssetType::PLUGIN)
{
}
VOID Compile();
VOID Destroy();
public:
VOID (*OnInitialize)();
VOID (*OnTerminate)();
VOID (*OnDebugDraw)();
VOID (*OnFixedUpdate)();
VOID (*OnUpdate)(IN FLOAT32 deltaTime);
};
class IAsset_Package : public IAsset
{
public:
struct AssetRef
{
String Path;
Handle RefHandle{INVALID_HANDLE};
EAssetType Type{EAssetType::INVALID};
};
public:
PURE_VIRTUAL(Vector<AssetRef>::const_iterator ListAssets());
PURE_VIRTUAL(RefPtr<IStreamReader> GetAssetData(IN Handle refHandle));
};
class AssetManager
{
public:
VIRTUAL VOID SetAssetDirectory(IN CONST String &path);
String ReadTextAsset(IN CONST String &path);
Vector<UINT8> ReadBinaryAsset(IN CONST String &path);
public:
VIRTUAL Asset_Plugin *LoadPlugin(IN CONST String &path);
VIRTUAL Asset_Sprite *CreateSprite(IN CONST String &path);
VIRTUAL Asset_Sprite *CreateSprite(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height);
VIRTUAL Asset_SpriteSheet *CreateSpriteSheet(IN CONST Vector<Vector<Handle>> &animations);
VIRTUAL Asset_SpriteSheet *CreateSpriteSheet(IN CONST String &path, IN INT32 spriteWidth, IN INT32 spriteHeight,
IN CONST Vector<INT32> &frameCounts);
VIRTUAL Asset_TileSheet *CreateTileSheet(IN CONST String &path, IN INT32 tileWidth, IN INT32 tileHeight);
VIRTUAL Asset_TileSheet *CreateTileSheet(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height,
IN INT32 tileWidth, IN INT32 tileHeight);
VIRTUAL Asset_Scene *CreateScene(IN IVec2 extent);
VIRTUAL VOID DestroyAsset(IN IAsset *asset);
VIRTUAL VOID AssignAssetName(IN IAsset *asset, IN CONST String &name);
template<typename AssetType>
requires std::is_base_of<IAsset, AssetType>::value
AssetType *GetAssetByName(IN CONST String &name);
public:
STATIC Vector<UINT8> Inflate(IN PCUINT8 data, IN SIZE_T dataSize);
STATIC Vector<UINT8> Deflate(IN PCUINT8 data, IN SIZE_T dataSize);
protected:
String m_assetDirectory;
Vector<IAsset *> m_assets;
Map<String, IAsset *> m_assetNames;
protected:
VIRTUAL IAsset *GetAssetByName(IN CONST String &name);
private:
VOID Initialize();
VOID Terminate();
friend class IAEngine;
};
template<typename AssetType>
requires std::is_base_of<IAsset, AssetType>::value
AssetType *AssetManager::GetAssetByName(IN CONST String &name)
{
return (AssetType *) GetAssetByName(name);
}
Handle Asset_Sprite::GetTexture()
{
return m_texture;
}
Scene &Asset_Scene::GetScene()
{
return m_scene;
}
CONST Vector<INT32> &Asset_SpriteSheet::GetFrameCounts() CONST
{
return m_frameCounts;
}
} // namespace ia::iae

View File

@ -27,4 +27,9 @@
namespace ia::iae namespace ia::iae
{ {
} #if (defined(__IA_DEBUG) && __IA_DEBUG) || (defined(__IAENGINE_DEBUG))
STATIC CONSTEXPR BOOL g_isDebugMode = true;
#else
STATIC CONSTEXPR BOOL g_isDebugMode = false;
#endif
} // namespace ia::iae

View File

@ -16,7 +16,7 @@
#pragma once #pragma once
#include <IAEngine/AssetManager.hpp> #include <IAEngine/Asset/AssetManager.hpp>
namespace ia::iae namespace ia::iae
{ {
@ -25,9 +25,6 @@ namespace ia::iae
public: public:
STATIC VOID AddPlugin(IN Asset_Plugin *plugin); STATIC VOID AddPlugin(IN Asset_Plugin *plugin);
STATIC AssetManager *GetAssetManager();
STATIC VOID SetAssetManager(IN AssetManager *instance);
public: public:
STATIC Asset_Scene *GetActiveScene(); STATIC Asset_Scene *GetActiveScene();
STATIC VOID ChangeActiveScene(IN Asset_Scene *scene); STATIC VOID ChangeActiveScene(IN Asset_Scene *scene);
@ -45,8 +42,8 @@ namespace ia::iae
IN BOOL flipH = false, IN BOOL flipV = false, IN Vec2 uvOffset = {}); IN BOOL flipH = false, IN BOOL flipV = false, IN Vec2 uvOffset = {});
public: public:
STATIC VOID __Initialize(); STATIC VOID __Initialize(IN IVec2 designResolution, IN CONST String& assetDirectory);
STATIC VOID __InitializeHeadless(); STATIC VOID __InitializeHeadless(IN CONST String& assetDirectory);
STATIC VOID __Terminate(); STATIC VOID __Terminate();
STATIC VOID __RenderToWindow(); STATIC VOID __RenderToWindow();
STATIC VOID __RenderToTexture(IN PVOID textureHandle); STATIC VOID __RenderToTexture(IN PVOID textureHandle);

View File

@ -50,8 +50,13 @@ namespace ia::iae
INT32 RDC::s_primitiveInstanceCount{}; INT32 RDC::s_primitiveInstanceCount{};
GeometryVertex RDC::s_primitiveInstances[RDC::MAX_PRIMITIVE_COUNT]; GeometryVertex RDC::s_primitiveInstances[RDC::MAX_PRIMITIVE_COUNT];
Vector<RDC_Texture*> g_managedBakedTextures;
VOID RDC::Initialize(IN IVec2 viewportExtent, IN SDL_Window *windowHandle, IN BOOL isDebugMode) VOID RDC::Initialize(IN IVec2 viewportExtent, IN SDL_Window *windowHandle, IN BOOL isDebugMode)
{ {
if (s_windowHandle)
return;
EmbeddedResources::Initialize(); EmbeddedResources::Initialize();
s_windowHandle = windowHandle; s_windowHandle = windowHandle;
@ -74,6 +79,9 @@ namespace ia::iae
RDC_Device::DestroyGeometry(s_quadGeometry); RDC_Device::DestroyGeometry(s_quadGeometry);
for (const auto &t : g_managedBakedTextures)
delete t;
SDL_ReleaseGPUSampler(RDC_Device::GetHandle(), s_linearClampSampler); SDL_ReleaseGPUSampler(RDC_Device::GetHandle(), s_linearClampSampler);
SDL_ReleaseGPUSampler(RDC_Device::GetHandle(), s_linearRepeatSampler); SDL_ReleaseGPUSampler(RDC_Device::GetHandle(), s_linearRepeatSampler);
@ -187,29 +195,26 @@ namespace ia::iae
RDC_Device::WaitForIdle(); RDC_Device::WaitForIdle();
} }
Vec2 RDC::DrawSpriteTopLeft(IN Handle _image, IN INT32 tileIndexX, IN INT32 tileIndexY, IN Vec2 position, Vec2 RDC::DrawSpriteTopLeft(IN ImageView *imageView, IN INT32 tileIndexX, IN INT32 tileIndexY, IN Vec2 position,
IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset) IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset)
{ {
const auto image = (ImageData *) _image; const auto _s = Vec2{scale.x * imageView->TileWidth, scale.y * imageView->TileHeight};
const auto _s = Vec2{scale.x * image->TileWidth, scale.y * image->TileHeight};
Mat4 transform = glm::translate(glm::mat4(1.0f), glm::vec3{position.x, position.y, 0}); Mat4 transform = glm::translate(glm::mat4(1.0f), glm::vec3{position.x, position.y, 0});
transform = glm::rotate(transform, rotation, glm::vec3(0.0f, 0.0f, 1.0f)); transform = glm::rotate(transform, rotation, glm::vec3(0.0f, 0.0f, 1.0f));
transform = glm::scale(transform, glm::vec3(_s, 1.0f)); transform = glm::scale(transform, glm::vec3(_s, 1.0f));
s_spriteInstances[s_spriteInstanceCount++] = { s_spriteInstances[s_spriteInstanceCount++] = {
.Transform = transform, .Transform = transform,
.TexCoords = s_dynamicSpriteAtlas ? s_dynamicSpriteAtlas->GetTextureCoordinates( .TexCoords = s_dynamicSpriteAtlas ? s_dynamicSpriteAtlas->GetTextureCoordinates(
_image, tileIndexX, tileIndexY, flipH, flipV, uvOffset) imageView, tileIndexX, tileIndexY, flipH, flipV, uvOffset)
: Vec4{0.0f, 0.0f, 1.0f, 1.0f}, : Vec4{0.0f, 0.0f, 1.0f, 1.0f},
.Color = {1.0f, 1.0f, 1.0f, 1.0f}}; .Color = {1.0f, 1.0f, 1.0f, 1.0f}};
return _s; return _s;
} }
Vec2 RDC::DrawSpriteCentered(IN Handle _image, IN INT32 tileIndexX, IN INT32 tileIndexY, IN Vec2 position, Vec2 RDC::DrawSpriteCentered(IN ImageView *imageView, IN INT32 tileIndexX, IN INT32 tileIndexY, IN Vec2 position,
IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset) IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH, IN BOOL flipV, IN Vec2 uvOffset)
{ {
const auto image = (ImageData *) _image; const auto _s = Vec2{scale.x * imageView->TileWidth, scale.y * imageView->TileHeight};
const auto _s = Vec2{scale.x * image->TileWidth, scale.y * image->TileHeight};
Mat4 transform = Mat4 transform =
glm::translate(glm::mat4(1.0f), glm::vec3{position.x - _s.x / 2.0f, position.y - _s.y / 2.0f, 0}); glm::translate(glm::mat4(1.0f), glm::vec3{position.x - _s.x / 2.0f, position.y - _s.y / 2.0f, 0});
transform = glm::rotate(transform, rotation, glm::vec3(0.0f, 0.0f, 1.0f)); transform = glm::rotate(transform, rotation, glm::vec3(0.0f, 0.0f, 1.0f));
@ -217,7 +222,7 @@ namespace ia::iae
s_spriteInstances[s_spriteInstanceCount++] = { s_spriteInstances[s_spriteInstanceCount++] = {
.Transform = transform, .Transform = transform,
.TexCoords = s_dynamicSpriteAtlas ? s_dynamicSpriteAtlas->GetTextureCoordinates( .TexCoords = s_dynamicSpriteAtlas ? s_dynamicSpriteAtlas->GetTextureCoordinates(
_image, tileIndexX, tileIndexY, flipH, flipV, uvOffset) imageView, tileIndexX, tileIndexY, flipH, flipV, uvOffset)
: Vec4{0.0f, 0.0f, 1.0f, 1.0f}, : Vec4{0.0f, 0.0f, 1.0f, 1.0f},
.Color = {1.0f, 1.0f, 1.0f, 1.0f}}; .Color = {1.0f, 1.0f, 1.0f, 1.0f}};
return _s; return _s;
@ -260,34 +265,50 @@ namespace ia::iae
s_viewMatrix = glm::lookAtLH(glm::vec3{s_cameraPosition, -1.0f}, {s_cameraPosition, 0.0f}, {0.0f, 1.0f, 0.0f}); s_viewMatrix = glm::lookAtLH(glm::vec3{s_cameraPosition, -1.0f}, {s_cameraPosition, 0.0f}, {0.0f, 1.0f, 0.0f});
} }
Handle RDC::CreateImage(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height, IN INT32 tileCountX, Image *RDC::CreateImage(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height)
IN INT32 tileCountY)
{ {
const auto pixelDataSize = width * height * 4; const auto pixelDataSize = width * height * 4;
const auto image = new ImageData{ const auto image = new Image{.Pixels = new UINT8[pixelDataSize], .Width = width, .Height = height};
.Pixels = new UINT8[pixelDataSize],
.Width = width, ia_memcpy(image->Pixels, rgbaData, pixelDataSize);
.Height = height,
.TileWidth = width / tileCountX, return image;
.TileHeight = height / tileCountY, }
ImageView *RDC::CreateImageView(IN Image *image, IN INT32 tileCountX, IN INT32 tileCountY)
{
const auto imageView = new ImageView{
.ImagePtr = image,
.TileWidth = image->Width / tileCountX,
.TileHeight = image->Height / tileCountY,
.TileCountX = tileCountX, .TileCountX = tileCountX,
.TileCountY = tileCountY, .TileCountY = tileCountY,
}; };
ia_memcpy(image->Pixels, rgbaData, pixelDataSize); return imageView;
return (Handle) image;
} }
VOID RDC::DestroyImage(IN Handle _image) VOID RDC::DestroyImage(IN Image *image)
{ {
const auto image = (ImageData *) _image;
delete[] image->Pixels; delete[] image->Pixels;
delete image; delete image;
} }
VOID RDC::CompileTextures(IN CONST Vector<Handle> &images) VOID RDC::DestroyImageView(IN ImageView *imageView)
{
delete imageView;
}
Handle RDC::BakeTexture(IN Image *image)
{
const auto texture = new RDC_Texture(RDC_Texture::EType::SAMPLED, image->Width, image->Height);
texture->SetImageData(image->Pixels);
g_managedBakedTextures.pushBack(texture);
return (Handle)texture->GetHandle();
}
VOID RDC::CompileTextures(IN CONST Vector<Image *> &images)
{ {
if (!images.size()) if (!images.size())
return; return;

View File

@ -18,19 +18,18 @@
namespace ia::iae namespace ia::iae
{ {
RDC_TextureAtlas::RDC_TextureAtlas(IN CONST Vector<Handle> &images) RDC_TextureAtlas::RDC_TextureAtlas(IN CONST Vector<Image*> &images)
{ {
if (images.empty()) if (images.empty())
return; return;
m_atlasSize.x = 0; m_atlasSize.x = 0;
m_atlasSize.y = 0; m_atlasSize.y = 0;
for (const auto &_image : images) for (const auto &image : images)
{ {
const auto d = (ImageData *) _image; m_atlasSize.x += image->Width;
m_atlasSize.x += d->Width; if (image->Height > m_atlasSize.y)
if (d->Height > m_atlasSize.y) m_atlasSize.y = image->Height;
m_atlasSize.y = d->Height;
} }
m_inverseAtlasSize = {1.0f / ((FLOAT32) m_atlasSize.x), 1.0f / ((FLOAT32) m_atlasSize.y)}; m_inverseAtlasSize = {1.0f / ((FLOAT32) m_atlasSize.x), 1.0f / ((FLOAT32) m_atlasSize.y)};
@ -38,13 +37,12 @@ namespace ia::iae
const auto pixels = new UINT8[m_atlasSize.x * m_atlasSize.y * 4]; const auto pixels = new UINT8[m_atlasSize.x * m_atlasSize.y * 4];
INT32 atlasCursor{0}; INT32 atlasCursor{0};
for (const auto &_image : images) for (const auto &image : images)
{ {
const auto d = (ImageData *) _image; for (INT32 y = 0; y < image->Height; y++)
for (INT32 y = 0; y < d->Height; y++) ia_memcpy(&pixels[(atlasCursor + (y * m_atlasSize.x)) * 4], &image->Pixels[y * image->Width * 4], image->Width * 4);
ia_memcpy(&pixels[(atlasCursor + (y * m_atlasSize.x)) * 4], &d->Pixels[y * d->Width * 4], d->Width * 4); m_texCoordMap[(Handle)(image)] = Vec2(((FLOAT32) atlasCursor) / ((FLOAT32) m_atlasSize.x), 0.0f);
m_texCoordMap[_image] = Vec2(((FLOAT32) atlasCursor) / ((FLOAT32) m_atlasSize.x), 0.0f); atlasCursor += image->Width;
atlasCursor += d->Width;
} }
m_texture = new RDC_Texture(RDC_Texture::EType::SAMPLED, m_atlasSize.x, m_atlasSize.y); m_texture = new RDC_Texture(RDC_Texture::EType::SAMPLED, m_atlasSize.x, m_atlasSize.y);
@ -58,15 +56,14 @@ namespace ia::iae
delete m_texture; delete m_texture;
} }
Vec4 RDC_TextureAtlas::GetTextureCoordinates(IN Handle _image, IN INT32 tileIndexX, IN INT32 tileIndexY, IN BOOL flipH, Vec4 RDC_TextureAtlas::GetTextureCoordinates(IN ImageView* imageView, IN INT32 tileIndexX, IN INT32 tileIndexY, IN BOOL flipH,
IN BOOL flipV, IN Vec2 uvOffset) IN BOOL flipV, IN Vec2 uvOffset)
{ {
const auto d = (ImageData *) _image; const auto &t = m_texCoordMap[(Handle)(imageView->ImagePtr)];
const auto &t = m_texCoordMap[_image]; const auto pX = ((tileIndexX + uvOffset.x) * ((FLOAT32) imageView->TileWidth)) * m_inverseAtlasSize.x;
const auto pX = ((tileIndexX + uvOffset.x) * ((FLOAT32) d->TileWidth)) * m_inverseAtlasSize.x; const auto pY = ((tileIndexY + uvOffset.y) * ((FLOAT32) imageView->TileHeight)) * m_inverseAtlasSize.y;
const auto pY = ((tileIndexY + uvOffset.y) * ((FLOAT32) d->TileHeight)) * m_inverseAtlasSize.y; auto texCoords = Vec4(t.x + pX, t.y + pY, imageView->TileWidth * m_inverseAtlasSize.x,
auto texCoords = Vec4(t.x + pX, t.y + pY, d->TileWidth * m_inverseAtlasSize.x, imageView->TileHeight * m_inverseAtlasSize.y);
d->TileHeight * m_inverseAtlasSize.y);
if (flipH) if (flipH)
{ {
texCoords.x += texCoords.z; texCoords.x += texCoords.z;

View File

@ -27,11 +27,16 @@
namespace ia::iae namespace ia::iae
{ {
struct ImageData struct Image
{ {
PUINT8 Pixels{}; PUINT8 Pixels{};
INT32 Width{}; INT32 Width{};
INT32 Height{}; INT32 Height{};
};
struct ImageView
{
Image* ImagePtr{};
INT32 TileWidth{}; INT32 TileWidth{};
INT32 TileHeight{}; INT32 TileHeight{};
INT32 TileCountX{}; INT32 TileCountX{};

View File

@ -17,10 +17,11 @@
#pragma once #pragma once
#include <RenderCore/Buffer.hpp> #include <RenderCore/Buffer.hpp>
#include <RenderCore/Texture.hpp>
#include <RenderCore/Pipeline.hpp> #include <RenderCore/Pipeline.hpp>
#include <RenderCore/Texture.hpp>
#include <RenderCore/TextureAtlas.hpp> #include <RenderCore/TextureAtlas.hpp>
namespace ia::iae namespace ia::iae
{ {
#pragma pack(push, 1) #pragma pack(push, 1)
@ -47,25 +48,30 @@ namespace ia::iae
STATIC VOID ResizeScreen(IN IVec2 newExtent); STATIC VOID ResizeScreen(IN IVec2 newExtent);
STATIC VOID RenderToWindow(); STATIC VOID RenderToWindow();
STATIC VOID RenderToTexture(IN SDL_GPUTexture* texture); STATIC VOID RenderToTexture(IN SDL_GPUTexture *texture);
public: public:
STATIC Vec2 GetCameraPosition(); STATIC Vec2 GetCameraPosition();
STATIC VOID SetCameraPosition(IN Vec2 position); STATIC VOID SetCameraPosition(IN Vec2 position);
STATIC Vec2 DrawSpriteTopLeft(IN Handle image, IN INT32 tileIndexX, IN INT32 tileIndexY, STATIC Vec2 DrawSpriteTopLeft(IN ImageView* imageView, IN INT32 tileIndexX, IN INT32 tileIndexY, IN Vec2 position,
IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH = false, IN BOOL flipV = false, IN Vec2 uvOffset = {}); IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH = false, IN BOOL flipV = false,
STATIC Vec2 DrawSpriteCentered(IN Handle image, IN INT32 tileIndexX, IN INT32 tileIndexY, IN Vec2 uvOffset = {});
IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH = false, IN BOOL flipV = false, IN Vec2 uvOffset = {}); STATIC Vec2 DrawSpriteCentered(IN ImageView* imageView, IN INT32 tileIndexX, IN INT32 tileIndexY, IN Vec2 position,
IN Vec2 scale, IN FLOAT32 rotation, IN BOOL flipH = false, IN BOOL flipV = false,
IN Vec2 uvOffset = {});
STATIC VOID DrawLine(IN Vec2 start, IN Vec2 end, IN Vec4 color); STATIC VOID DrawLine(IN Vec2 start, IN Vec2 end, IN Vec4 color);
STATIC VOID DrawRect(IN Vec2 start, IN Vec2 end, IN Vec4 color); STATIC VOID DrawRect(IN Vec2 start, IN Vec2 end, IN Vec4 color);
STATIC Handle CreateImage(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height, IN INT32 tileCountX = 1, STATIC Image* CreateImage(IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height);
IN INT32 tileCountY = 1); STATIC ImageView* CreateImageView(IN Image* image, IN INT32 tileCountX = 1, IN INT32 tileCountY = 1);
STATIC VOID DestroyImage(IN Handle image); STATIC VOID DestroyImage(IN Image* image);
STATIC VOID DestroyImageView(IN ImageView* imageView);
STATIC VOID CompileTextures(IN CONST Vector<Handle>& images); STATIC Handle BakeTexture(IN Image* image);
STATIC VOID CompileTextures(IN CONST Vector<Image*> &images);
private: private:
STATIC VOID InitializeSamplers(); STATIC VOID InitializeSamplers();
@ -74,7 +80,7 @@ namespace ia::iae
STATIC VOID InitializePipelines(); STATIC VOID InitializePipelines();
STATIC VOID InitializeGeometries(); STATIC VOID InitializeGeometries();
STATIC VOID Render(IN SDL_GPURenderPass* renderPass, IN SDL_GPUCommandBuffer* commandBuffer); STATIC VOID Render(IN SDL_GPURenderPass *renderPass, IN SDL_GPUCommandBuffer *commandBuffer);
private: private:
STATIC Mat4 s_viewMatrix; STATIC Mat4 s_viewMatrix;
@ -83,7 +89,7 @@ namespace ia::iae
STATIC IVec2 s_viewportExtent; STATIC IVec2 s_viewportExtent;
STATIC Mat4 s_projectionMatrix; STATIC Mat4 s_projectionMatrix;
STATIC SDL_Window *s_windowHandle; STATIC SDL_Window *s_windowHandle;
STATIC RDC_Texture* s_defaultTexture; STATIC RDC_Texture *s_defaultTexture;
STATIC RDC_Pipeline *s_primitiveDrawPipeline; STATIC RDC_Pipeline *s_primitiveDrawPipeline;
STATIC RDC_Pipeline *s_dynamicSpritePipeline; STATIC RDC_Pipeline *s_dynamicSpritePipeline;
@ -93,9 +99,9 @@ namespace ia::iae
STATIC RDC_TextureAtlas *s_staticSpriteAtlas; STATIC RDC_TextureAtlas *s_staticSpriteAtlas;
STATIC RDC_TextureAtlas *s_dynamicSpriteAtlas; STATIC RDC_TextureAtlas *s_dynamicSpriteAtlas;
STATIC RDC_HostVisibleBuffer* s_primitiveInstanceBuffer; STATIC RDC_HostVisibleBuffer *s_primitiveInstanceBuffer;
STATIC RDC_HostVisibleBuffer* s_staticSpriteInstanceBuffer; STATIC RDC_HostVisibleBuffer *s_staticSpriteInstanceBuffer;
STATIC RDC_HostVisibleBuffer* s_dynamicSpriteInstanceBuffer; STATIC RDC_HostVisibleBuffer *s_dynamicSpriteInstanceBuffer;
STATIC INT32 s_spriteInstanceCount; STATIC INT32 s_spriteInstanceCount;
STATIC RDC_SpriteInstanceData s_spriteInstances[MAX_SPRITE_COUNT]; STATIC RDC_SpriteInstanceData s_spriteInstances[MAX_SPRITE_COUNT];

Some files were not shown because too many files have changed in this diff Show More