Back
This commit is contained in:
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -8,7 +8,7 @@
|
||||
"name": "(Windows) Launch",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/bin/Debug/IAERuntime.exe",
|
||||
"program": "${workspaceFolder}/build/bin/Debug/Editor.exe",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}/Samples/SpaceInvaders",
|
||||
|
||||
71
.vscode/settings.json
vendored
71
.vscode/settings.json
vendored
@ -21,6 +21,75 @@
|
||||
"array": "cpp",
|
||||
"ranges": "cpp",
|
||||
"span": "cpp",
|
||||
"vector": "cpp"
|
||||
"vector": "cpp",
|
||||
"xiosbase": "cpp",
|
||||
"thread": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cctype": "cpp",
|
||||
"charconv": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"coroutine": "cpp",
|
||||
"csignal": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"deque": "cpp",
|
||||
"exception": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"fstream": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"ios": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"iterator": "cpp",
|
||||
"limits": "cpp",
|
||||
"list": "cpp",
|
||||
"locale": "cpp",
|
||||
"map": "cpp",
|
||||
"memory": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numeric": "cpp",
|
||||
"ostream": "cpp",
|
||||
"queue": "cpp",
|
||||
"ratio": "cpp",
|
||||
"set": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"source_location": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stack": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"string": "cpp",
|
||||
"tuple": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"utility": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xlocbuf": "cpp",
|
||||
"xlocmes": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xstddef": "cpp",
|
||||
"xtree": "cpp"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
set(SRC_FILES
|
||||
"Src/Imp/CPP/Main.cpp"
|
||||
)
|
||||
|
||||
add_executable(Editor ${SRC_FILES})
|
||||
|
||||
target_include_directories(Editor PRIVATE "Src/Imp/HPP")
|
||||
|
||||
target_link_libraries(Editor PUBLIC IAEngine)
|
||||
|
||||
0
Editor/Src/Imp/CPP/Editor.cpp
Normal file
0
Editor/Src/Imp/CPP/Editor.cpp
Normal file
93
Editor/Src/Imp/CPP/Main.cpp
Normal file
93
Editor/Src/Imp/CPP/Main.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
// 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/Engine.hpp>
|
||||
#include <IAEngine/EngineLibraryInterface.hpp>
|
||||
|
||||
C_DECL(GameRequestedConfig GetConfigRequest())
|
||||
{
|
||||
return {1280, 720};
|
||||
}
|
||||
|
||||
C_DECL(VOID OnInitialize())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
C_DECL(VOID OnTerminate())
|
||||
{
|
||||
}
|
||||
|
||||
C_DECL(VOID OnDebugDraw())
|
||||
{
|
||||
}
|
||||
|
||||
C_DECL(VOID OnFixedUpdate())
|
||||
{
|
||||
}
|
||||
|
||||
C_DECL(VOID OnUpdate(IN FLOAT32 deltaTime))
|
||||
{
|
||||
}
|
||||
|
||||
C_DECL(VOID OnResize(IN INT32 newWidth, IN INT32 newHeight))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
C_DECL(PCCHAR GetName())
|
||||
{
|
||||
return "IAEngine Editor";
|
||||
}
|
||||
|
||||
C_DECL(UINT64 GetVersion())
|
||||
{
|
||||
return IA_MAKE_VERSION(1, 0, 0);
|
||||
}
|
||||
|
||||
C_DECL(PCCHAR GetPackageName())
|
||||
{
|
||||
return "com.iasoft.iaengine.editor";
|
||||
}
|
||||
|
||||
C_DECL(PCCHAR GetDeveloperName())
|
||||
{
|
||||
return "IASoft (PVT) LTD";
|
||||
}
|
||||
|
||||
C_DECL(PCCHAR GetPublisherName())
|
||||
{
|
||||
return "IASoft (PVT) LTD";
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
GameFunctionTable functionTable{};
|
||||
functionTable.GetConfigRequest = GetConfigRequest;
|
||||
functionTable.GetDeveloperName = GetDeveloperName;
|
||||
functionTable.GetName = GetName;
|
||||
functionTable.GetPackageName = GetPackageName;
|
||||
functionTable.GetPublisherName = GetPublisherName;
|
||||
functionTable.GetVersion = GetVersion;
|
||||
functionTable.OnDebugDraw = OnDebugDraw;
|
||||
functionTable.OnFixedUpdate = OnFixedUpdate;
|
||||
functionTable.OnInitialize = OnInitialize;
|
||||
functionTable.OnResize = OnResize;
|
||||
functionTable.OnTerminate = OnTerminate;
|
||||
functionTable.OnUpdate = OnUpdate;
|
||||
IAEngine_Run(functionTable);
|
||||
return 0;
|
||||
}
|
||||
0
Editor/Src/Imp/HPP/Editor.hpp
Normal file
0
Editor/Src/Imp/HPP/Editor.hpp
Normal file
@ -1,4 +1,5 @@
|
||||
set(SRC_FILES
|
||||
"Src/Imp/CPP/UI.cpp"
|
||||
"Src/Imp/CPP/Time.cpp"
|
||||
"Src/Imp/CPP/Scene.cpp"
|
||||
"Src/Imp/CPP/Random.cpp"
|
||||
@ -14,7 +15,6 @@ set(SRC_FILES
|
||||
"Src/Imp/CPP/Renderer/DebugDraw.cpp"
|
||||
"Src/Imp/CPP/Renderer/Pipeline.cpp"
|
||||
"Src/Imp/CPP/Renderer/Renderer.cpp"
|
||||
"Src/Imp/CPP/Renderer/UIRenderer.cpp"
|
||||
"Src/Imp/CPP/Renderer/GPUResourceManager.cpp"
|
||||
|
||||
"Src/Imp/CPP/Nodes/Node2D.cpp"
|
||||
|
||||
@ -25,14 +25,13 @@ namespace ia::iae
|
||||
|
||||
VOID TextureComponent::SetTexture(IN Handle image)
|
||||
{
|
||||
const auto t = Engine::GetImageExtent(image);
|
||||
|
||||
m_texture = image;
|
||||
m_textureExtent = {t.x, t.y};
|
||||
}
|
||||
|
||||
VOID TextureComponent::Draw()
|
||||
{
|
||||
const auto t = Engine::GetImageExtent(m_texture);
|
||||
m_textureExtent = {t.x, t.y};
|
||||
m_drawnSize = m_node->GetScale() * m_textureExtent * m_scaleOffset;
|
||||
|
||||
Engine::SetRenderState_Texture(m_texture);
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <IAEngine/Engine.hpp>
|
||||
#include <IAEngine/UI.hpp>
|
||||
#include <Renderer/Renderer.hpp>
|
||||
|
||||
#include <IACore/File.hpp>
|
||||
@ -26,6 +27,7 @@ EXTERN GameFunctionTable g_gameFunctions;
|
||||
namespace ia::iae
|
||||
{
|
||||
EXTERN SDL_Window *g_windowHandle;
|
||||
SIZE_T g_resourceNameCounter = 1;
|
||||
|
||||
BOOL Engine::IsDebugMode()
|
||||
{
|
||||
@ -38,8 +40,10 @@ namespace ia::iae
|
||||
|
||||
VOID Engine::ResizeDisplay(IN INT32 newWidth, IN INT32 newHeight)
|
||||
{
|
||||
Renderer::WaitForGPUIdle();
|
||||
SDL_SetWindowSize(g_windowHandle, newWidth, newHeight);
|
||||
Renderer::OnScreenResize(newWidth, newHeight);
|
||||
UI::OnScreenResize(newWidth, newHeight);
|
||||
g_gameFunctions.OnResize(newWidth, newHeight);
|
||||
}
|
||||
|
||||
@ -62,4 +66,14 @@ namespace ia::iae
|
||||
const auto data = File::ReadToString(path.c_str());
|
||||
return Scene::Create(data);
|
||||
}
|
||||
|
||||
Handle Engine::ResizeImage(IN CONST String &name, IN INT32 newWidth, IN INT32 newHeight)
|
||||
{
|
||||
return ResizeImage(GetImage(name), newWidth, newHeight);
|
||||
}
|
||||
|
||||
String Engine::GetUniqueResourceName()
|
||||
{
|
||||
return BuildString("__res_", g_resourceNameCounter++);
|
||||
}
|
||||
} // namespace ia::iae
|
||||
|
||||
@ -38,15 +38,17 @@ namespace ia::iae
|
||||
|
||||
VOID __Internal_Engine::Initialize()
|
||||
{
|
||||
const auto config = g_gameFunctions.GetConfigRequest();
|
||||
|
||||
IAE_LOG_INFO("Booting IAEngine for ", g_gameFunctions.GetName());
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMEPAD))
|
||||
THROW_UNKNOWN("Failed to intialize SDL: ", SDL_GetError());
|
||||
|
||||
if (!(g_windowHandle = SDL_CreateWindow(g_gameFunctions.GetName(), 800, 600, SDL_WINDOW_RESIZABLE)))
|
||||
if (!(g_windowHandle = SDL_CreateWindow(g_gameFunctions.GetName(), config.ScreenWidth, config.ScreenHeight, SDL_WINDOW_RESIZABLE)))
|
||||
THROW_UNKNOWN("Failed to create the SDL window: ", SDL_GetError());
|
||||
|
||||
SDL_SetWindowResizable(g_windowHandle, false);
|
||||
//SDL_SetWindowResizable(g_windowHandle, false);
|
||||
|
||||
const auto gameVersion = g_gameFunctions.GetVersion();
|
||||
SDL_SetAppMetadata(g_gameFunctions.GetName(), BuildString(gameVersion).c_str(),
|
||||
@ -60,6 +62,7 @@ namespace ia::iae
|
||||
InputManager::Initialize();
|
||||
ResourceManager::Initialize();
|
||||
WorldManager::Initialize();
|
||||
UI::Initialize();
|
||||
|
||||
g_gameFunctions.OnInitialize();
|
||||
}
|
||||
@ -68,6 +71,7 @@ namespace ia::iae
|
||||
{
|
||||
g_gameFunctions.OnTerminate();
|
||||
|
||||
UI::Terminate();
|
||||
WorldManager::Terminate();
|
||||
ResourceManager::Terminate();
|
||||
InputManager::Terminate();
|
||||
@ -84,6 +88,7 @@ namespace ia::iae
|
||||
|
||||
VOID __Internal_Engine::Iterate()
|
||||
{
|
||||
UI::Update();
|
||||
WorldManager::Update();
|
||||
WorldManager::FixedUpdate();
|
||||
g_gameFunctions.OnUpdate(Time::GetFrameDeltaTime());
|
||||
@ -91,6 +96,7 @@ namespace ia::iae
|
||||
|
||||
Renderer::BeginFrame();
|
||||
WorldManager::Draw();
|
||||
UI::Draw();
|
||||
Renderer::EndFrame();
|
||||
}
|
||||
|
||||
@ -104,6 +110,7 @@ namespace ia::iae
|
||||
}
|
||||
InputManager::OnSDLEvent(event);
|
||||
EventManager::OnSDLEvent(event);
|
||||
UI::OnSDLEvent(event);
|
||||
ImGui_ImplSDL3_ProcessEvent(event);
|
||||
}
|
||||
|
||||
@ -115,6 +122,8 @@ namespace ia::iae
|
||||
|
||||
BOOL ValidateGameFunctionTable(IN GameFunctionTable gameFunctionTable)
|
||||
{
|
||||
if (!gameFunctionTable.GetConfigRequest)
|
||||
return false;
|
||||
if (!gameFunctionTable.OnInitialize)
|
||||
return false;
|
||||
if (!gameFunctionTable.OnTerminate)
|
||||
|
||||
@ -138,6 +138,7 @@ namespace ia::iae
|
||||
|
||||
VOID GPUResourceManager::DestroyTexture(IN SDL_GPUTexture *handle)
|
||||
{
|
||||
if(!handle) return;
|
||||
SDL_ReleaseGPUTexture(Renderer::GetDevice(), handle);
|
||||
}
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include <Renderer/EmbeddedShader.hpp>
|
||||
#include <Renderer/Renderer.hpp>
|
||||
|
||||
#include <ResourceManager.hpp>
|
||||
#include <WorldManager.hpp>
|
||||
|
||||
#include <backends/imgui_impl_sdl3.h>
|
||||
@ -231,6 +232,15 @@ namespace ia::iae
|
||||
|
||||
if (s_state.ActiveCamera)
|
||||
s_state.ActiveCamera->SetViewport(newWidth, newHeight);
|
||||
|
||||
const auto activeScene = WorldManager::GetActiveScene();
|
||||
if (activeScene)
|
||||
{
|
||||
const auto sceneExtent = activeScene->Extent();
|
||||
s_state.SceneScaleFactor = {(FLOAT32) newWidth / (FLOAT32) sceneExtent.x,
|
||||
(FLOAT32) newHeight / (FLOAT32) sceneExtent.y};
|
||||
IAE_LOG_INFO("Updated Scene Scale Factor: (", s_state.SceneScaleFactor.x, ", ", s_state.SceneScaleFactor.y, ")");
|
||||
}
|
||||
}
|
||||
|
||||
SDL_GPUTextureFormat Renderer::GetRenderTargetFormat()
|
||||
@ -266,7 +276,7 @@ namespace ia::iae
|
||||
INT32 FlippedH{false};
|
||||
INT32 FlippedV{false};
|
||||
Vec2 TextureOffset{0.0f, 0.0f};
|
||||
glm::vec4 ColorOverlay{1.0f, 1.0f, 1.0f, 1.0f};
|
||||
Vec4 ColorOverlay{1.0f, 1.0f, 1.0f, 1.0f};
|
||||
} s_fragmentUniform{};
|
||||
|
||||
#pragma pack(pop)
|
||||
@ -289,6 +299,11 @@ namespace ia::iae
|
||||
SDL_BindGPUIndexBuffer(s_state.ActiveRenderPass, &bufferBindings[1], SDL_GPU_INDEXELEMENTSIZE_32BIT);
|
||||
SDL_DrawGPUIndexedPrimitives(s_state.ActiveRenderPass, handle->IndexCount, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
VOID Renderer::WaitForGPUIdle()
|
||||
{
|
||||
SDL_WaitForGPUIdle(s_gpuDevice);
|
||||
}
|
||||
} // namespace ia::iae
|
||||
|
||||
namespace ia::iae
|
||||
@ -352,7 +367,7 @@ namespace ia::iae
|
||||
|
||||
VOID Engine::SetRenderState_Texture(IN Handle image)
|
||||
{
|
||||
Renderer::s_state.ActiveTexture = (SDL_GPUTexture *) image;
|
||||
Renderer::s_state.ActiveTexture = ResourceManager::GetTextureFromImage(image);
|
||||
}
|
||||
|
||||
VOID Engine::SetRenderState_Transform(IN Vec2 position, IN Vec2 scale, IN FLOAT32 rotation, IN UINT8 layer,
|
||||
@ -363,6 +378,9 @@ namespace ia::iae
|
||||
if (Renderer::s_state.YSortingEnabled)
|
||||
sortIndex += static_cast<INT16>(position.y);
|
||||
|
||||
position *= Renderer::s_state.SceneScaleFactor;
|
||||
scale *= Renderer::s_state.SceneScaleFactor;
|
||||
|
||||
Renderer::s_state.ModelMatrix =
|
||||
glm::translate(glm::mat4(1.0f), glm::vec3{position.x, position.y,
|
||||
static_cast<FLOAT32>((layer << 13) | (sortIndex & 0x1FFF))});
|
||||
|
||||
@ -1,24 +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/Engine.hpp>
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
namespace ia::iae
|
||||
{
|
||||
|
||||
}
|
||||
@ -18,6 +18,7 @@
|
||||
#include <ResourceManager.hpp>
|
||||
|
||||
#include <AudioManager.hpp>
|
||||
#include <Renderer/Renderer.hpp>
|
||||
#include <Renderer/GPUResourceManager.hpp>
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
@ -27,18 +28,26 @@
|
||||
|
||||
namespace ia::iae
|
||||
{
|
||||
Vector<SDL_GPUTexture*> ResourceManager::s_imageHandles;
|
||||
Map<String, Handle> ResourceManager::s_images;
|
||||
Map<String, Handle> ResourceManager::s_sounds;
|
||||
Map<Handle, UINT64> ResourceManager::s_imageExtents;
|
||||
Map<Handle, UINT64> ResourceManager::s_nonScaledImageExtents;
|
||||
|
||||
VOID ResourceManager::Initialize()
|
||||
{
|
||||
{ // Set Texture Handle 0 to a pure white image
|
||||
const auto data = new UINT8[100*100*4];
|
||||
ia_memset(data, 0xFF, 100* 100* 4);
|
||||
CreateImage(Engine::GetUniqueResourceName(), data, 100, 100);
|
||||
delete[] data;
|
||||
}
|
||||
}
|
||||
|
||||
VOID ResourceManager::Terminate()
|
||||
{
|
||||
for (const auto &t : s_images)
|
||||
GPUResourceManager::DestroyTexture((SDL_GPUTexture *) t->Value);
|
||||
GPUResourceManager::DestroyTexture(s_imageHandles[t->Value]);
|
||||
for (const auto &t : s_sounds)
|
||||
AudioManager::DestoryAudio(t->Value);
|
||||
}
|
||||
@ -54,10 +63,13 @@ namespace ia::iae
|
||||
|
||||
Handle ResourceManager::CreateImage(IN CONST String &name, IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height)
|
||||
{
|
||||
const auto handle = (Handle) GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER, width, height,
|
||||
const auto texture = GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER, width, height,
|
||||
rgbaData, SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM);
|
||||
s_imageExtents[handle] = (((UINT64) width) << 32) | height;
|
||||
s_imageHandles.pushBack(texture);
|
||||
Handle handle = s_imageHandles.size() - 1;
|
||||
s_images[name] = handle;
|
||||
s_imageExtents[handle] = (((UINT64) width) << 32) | height;
|
||||
s_nonScaledImageExtents[handle] = s_imageExtents[handle];
|
||||
return handle;
|
||||
}
|
||||
|
||||
@ -102,7 +114,8 @@ namespace ia::iae
|
||||
|
||||
VOID ResourceManager::DestroyImage(IN Handle image)
|
||||
{
|
||||
GPUResourceManager::DestroyTexture((SDL_GPUTexture *) image);
|
||||
GPUResourceManager::DestroyTexture(s_imageHandles[image]);
|
||||
s_imageHandles[image] = nullptr;
|
||||
}
|
||||
|
||||
VOID ResourceManager::DestroySound(IN Handle sound)
|
||||
@ -120,22 +133,37 @@ namespace ia::iae
|
||||
{
|
||||
const auto currentExtent = GetImageExtent(image);
|
||||
const auto pixelData =
|
||||
GPUResourceManager::GetTexturePixelData((SDL_GPUTexture *) image, currentExtent.x, currentExtent.y);
|
||||
GPUResourceManager::DestroyTexture((SDL_GPUTexture*)image);
|
||||
GPUResourceManager::GetTexturePixelData(s_imageHandles[image], currentExtent.x, currentExtent.y);
|
||||
const auto newPixelData =
|
||||
stbir_resize_uint8_linear(pixelData.data(), currentExtent.x, currentExtent.y, currentExtent.x * 4, nullptr,
|
||||
newWidth, newHeight, newWidth * 4, stbir_pixel_layout::STBIR_RGBA);
|
||||
const auto result = CreateImage(GetImageName(image), newPixelData, newWidth, newHeight);
|
||||
const auto texture = GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER, newWidth, newHeight,
|
||||
newPixelData, SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM);
|
||||
s_imageExtents[image] = (((UINT64) newWidth) << 32) | newHeight;
|
||||
GPUResourceManager::DestroyTexture(s_imageHandles[image]);
|
||||
s_imageHandles[image] = texture;
|
||||
free(newPixelData);
|
||||
return result;
|
||||
return image;
|
||||
}
|
||||
|
||||
Handle ResourceManager::CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight,
|
||||
IN INT32 unitCountX, IN INT32 unitCountY)
|
||||
{
|
||||
return (Handle) GPUResourceManager::CombineTextures((SDL_GPUTexture **) images.data(), unitWidth, unitHeight,
|
||||
Vector<SDL_GPUTexture*> textures;
|
||||
for(const auto& t: images)
|
||||
textures.pushBack(s_imageHandles[t]);
|
||||
return (Handle) GPUResourceManager::CombineTextures(textures.data(), unitWidth, unitHeight,
|
||||
unitCountX, unitCountY);
|
||||
}
|
||||
|
||||
VOID ResourceManager::RescaleAllImages(IN FLOAT32 factorX, IN FLOAT32 factorY)
|
||||
{
|
||||
for(auto& t: s_images)
|
||||
{
|
||||
const auto p = s_nonScaledImageExtents[t->Value];
|
||||
t->Value = ResizeImage(t->Value, ((INT32) (p >> 32)) * factorX, ((INT32) p) * factorY);
|
||||
}
|
||||
}
|
||||
} // namespace ia::iae
|
||||
|
||||
namespace ia::iae
|
||||
@ -185,6 +213,11 @@ namespace ia::iae
|
||||
return ResourceManager::ResizeImage(image, newWidth, newHeight);
|
||||
}
|
||||
|
||||
VOID Engine::RescaleAllImages(IN FLOAT32 factorX, IN FLOAT32 factorY)
|
||||
{
|
||||
ResourceManager::RescaleAllImages(factorX, factorY);
|
||||
}
|
||||
|
||||
Handle Engine::CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight,
|
||||
IN INT32 unitCountX, IN INT32 unitCountY)
|
||||
{
|
||||
|
||||
@ -21,13 +21,16 @@ namespace ia::iae
|
||||
{
|
||||
RefPtr<Scene> Scene::Create()
|
||||
{
|
||||
return MakeRefPtr<Scene>();
|
||||
const auto scene = MakeRefPtr<Scene>();
|
||||
scene->Extent() = Engine::GetDisplayExtent();
|
||||
return scene;
|
||||
}
|
||||
|
||||
RefPtr<Scene> Scene::Create(IN CONST String &sceneXML)
|
||||
{
|
||||
const auto scene = MakeRefPtr<Scene>();
|
||||
|
||||
scene->Extent() = Engine::GetDisplayExtent();
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
|
||||
465
Engine/Src/Imp/CPP/UI.cpp
Normal file
465
Engine/Src/Imp/CPP/UI.cpp
Normal file
@ -0,0 +1,465 @@
|
||||
// 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/Engine.hpp>
|
||||
#include <IAEngine/UI.hpp>
|
||||
|
||||
#include <Renderer/Renderer.hpp>
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <RmlUi/Core.h>
|
||||
#include <RmlUi/Debugger.h>
|
||||
|
||||
namespace ia::iae
|
||||
{
|
||||
Rml::Context *g_context{};
|
||||
BOOL g_debuggerEnabled{false};
|
||||
Rml::ElementDocument *g_document{};
|
||||
|
||||
class RmlUIRenderInterface : public Rml::RenderInterface
|
||||
{
|
||||
public:
|
||||
Rml::CompiledGeometryHandle CompileGeometry(Rml::Span<const Rml::Vertex> vertices,
|
||||
Rml::Span<const int> indices);
|
||||
void RenderGeometry(Rml::CompiledGeometryHandle geometry, Rml::Vector2f translation,
|
||||
Rml::TextureHandle texture);
|
||||
void ReleaseGeometry(Rml::CompiledGeometryHandle geometry);
|
||||
Rml::TextureHandle LoadTexture(Rml::Vector2i &texture_dimensions, const Rml::String &source);
|
||||
Rml::TextureHandle GenerateTexture(Rml::Span<const Rml::byte> source, Rml::Vector2i source_dimensions);
|
||||
void ReleaseTexture(Rml::TextureHandle texture);
|
||||
void EnableScissorRegion(bool enable);
|
||||
void SetScissorRegion(Rml::Rectanglei region);
|
||||
} g_rmlUIRenderInterface{};
|
||||
|
||||
class RmlEventListener : public Rml::EventListener
|
||||
{
|
||||
public:
|
||||
RmlEventListener()
|
||||
{
|
||||
}
|
||||
|
||||
VOID ProcessEvent(IN Rml::Event &event)
|
||||
{
|
||||
}
|
||||
|
||||
} g_eventListener{};
|
||||
|
||||
/* Taken from https://github.com/mikke89/RmlUi/blob/master/Backends/RmlUi_Platform_SDL.cpp */
|
||||
INT32 GetKeyModifierState()
|
||||
{
|
||||
SDL_Keymod sdl_mods = SDL_GetModState();
|
||||
INT32 keymods = 0;
|
||||
if (sdl_mods & SDL_KMOD_CTRL)
|
||||
keymods |= Rml::Input::KM_CTRL;
|
||||
if (sdl_mods & SDL_KMOD_SHIFT)
|
||||
keymods |= Rml::Input::KM_SHIFT;
|
||||
if (sdl_mods & SDL_KMOD_ALT)
|
||||
keymods |= Rml::Input::KM_ALT;
|
||||
if (sdl_mods & SDL_KMOD_NUM)
|
||||
keymods |= Rml::Input::KM_NUMLOCK;
|
||||
if (sdl_mods & SDL_KMOD_CAPS)
|
||||
keymods |= Rml::Input::KM_CAPSLOCK;
|
||||
return keymods;
|
||||
}
|
||||
|
||||
/* Taken from https://github.com/mikke89/RmlUi/blob/master/Backends/RmlUi_Platform_SDL.cpp */
|
||||
INT32 SDLMouseButtonToRml(IN INT32 button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
return 0;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
return 1;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
return 2;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* Taken from https://github.com/mikke89/RmlUi/blob/master/Backends/RmlUi_Platform_SDL.cpp */
|
||||
Rml::Input::KeyIdentifier SDLKeyToRml(int sdlkey)
|
||||
{
|
||||
switch (sdlkey)
|
||||
{
|
||||
case SDLK_UNKNOWN:
|
||||
return Rml::Input::KI_UNKNOWN;
|
||||
case SDLK_ESCAPE:
|
||||
return Rml::Input::KI_ESCAPE;
|
||||
case SDLK_SPACE:
|
||||
return Rml::Input::KI_SPACE;
|
||||
case SDLK_0:
|
||||
return Rml::Input::KI_0;
|
||||
case SDLK_1:
|
||||
return Rml::Input::KI_1;
|
||||
case SDLK_2:
|
||||
return Rml::Input::KI_2;
|
||||
case SDLK_3:
|
||||
return Rml::Input::KI_3;
|
||||
case SDLK_4:
|
||||
return Rml::Input::KI_4;
|
||||
case SDLK_5:
|
||||
return Rml::Input::KI_5;
|
||||
case SDLK_6:
|
||||
return Rml::Input::KI_6;
|
||||
case SDLK_7:
|
||||
return Rml::Input::KI_7;
|
||||
case SDLK_8:
|
||||
return Rml::Input::KI_8;
|
||||
case SDLK_9:
|
||||
return Rml::Input::KI_9;
|
||||
case SDLK_A:
|
||||
return Rml::Input::KI_A;
|
||||
case SDLK_B:
|
||||
return Rml::Input::KI_B;
|
||||
case SDLK_C:
|
||||
return Rml::Input::KI_C;
|
||||
case SDLK_D:
|
||||
return Rml::Input::KI_D;
|
||||
case SDLK_E:
|
||||
return Rml::Input::KI_E;
|
||||
case SDLK_F:
|
||||
return Rml::Input::KI_F;
|
||||
case SDLK_G:
|
||||
return Rml::Input::KI_G;
|
||||
case SDLK_H:
|
||||
return Rml::Input::KI_H;
|
||||
case SDLK_I:
|
||||
return Rml::Input::KI_I;
|
||||
case SDLK_J:
|
||||
return Rml::Input::KI_J;
|
||||
case SDLK_K:
|
||||
return Rml::Input::KI_K;
|
||||
case SDLK_L:
|
||||
return Rml::Input::KI_L;
|
||||
case SDLK_M:
|
||||
return Rml::Input::KI_M;
|
||||
case SDLK_N:
|
||||
return Rml::Input::KI_N;
|
||||
case SDLK_O:
|
||||
return Rml::Input::KI_O;
|
||||
case SDLK_P:
|
||||
return Rml::Input::KI_P;
|
||||
case SDLK_Q:
|
||||
return Rml::Input::KI_Q;
|
||||
case SDLK_R:
|
||||
return Rml::Input::KI_R;
|
||||
case SDLK_S:
|
||||
return Rml::Input::KI_S;
|
||||
case SDLK_T:
|
||||
return Rml::Input::KI_T;
|
||||
case SDLK_U:
|
||||
return Rml::Input::KI_U;
|
||||
case SDLK_V:
|
||||
return Rml::Input::KI_V;
|
||||
case SDLK_W:
|
||||
return Rml::Input::KI_W;
|
||||
case SDLK_X:
|
||||
return Rml::Input::KI_X;
|
||||
case SDLK_Y:
|
||||
return Rml::Input::KI_Y;
|
||||
case SDLK_Z:
|
||||
return Rml::Input::KI_Z;
|
||||
case SDLK_SEMICOLON:
|
||||
return Rml::Input::KI_OEM_1;
|
||||
case SDLK_PLUS:
|
||||
return Rml::Input::KI_OEM_PLUS;
|
||||
case SDLK_COMMA:
|
||||
return Rml::Input::KI_OEM_COMMA;
|
||||
case SDLK_MINUS:
|
||||
return Rml::Input::KI_OEM_MINUS;
|
||||
case SDLK_PERIOD:
|
||||
return Rml::Input::KI_OEM_PERIOD;
|
||||
case SDLK_SLASH:
|
||||
return Rml::Input::KI_OEM_2;
|
||||
case SDLK_GRAVE:
|
||||
return Rml::Input::KI_OEM_3;
|
||||
case SDLK_LEFTBRACKET:
|
||||
return Rml::Input::KI_OEM_4;
|
||||
case SDLK_BACKSLASH:
|
||||
return Rml::Input::KI_OEM_5;
|
||||
case SDLK_RIGHTBRACKET:
|
||||
return Rml::Input::KI_OEM_6;
|
||||
case SDLK_DBLAPOSTROPHE:
|
||||
return Rml::Input::KI_OEM_7;
|
||||
case SDLK_KP_0:
|
||||
return Rml::Input::KI_NUMPAD0;
|
||||
case SDLK_KP_1:
|
||||
return Rml::Input::KI_NUMPAD1;
|
||||
case SDLK_KP_2:
|
||||
return Rml::Input::KI_NUMPAD2;
|
||||
case SDLK_KP_3:
|
||||
return Rml::Input::KI_NUMPAD3;
|
||||
case SDLK_KP_4:
|
||||
return Rml::Input::KI_NUMPAD4;
|
||||
case SDLK_KP_5:
|
||||
return Rml::Input::KI_NUMPAD5;
|
||||
case SDLK_KP_6:
|
||||
return Rml::Input::KI_NUMPAD6;
|
||||
case SDLK_KP_7:
|
||||
return Rml::Input::KI_NUMPAD7;
|
||||
case SDLK_KP_8:
|
||||
return Rml::Input::KI_NUMPAD8;
|
||||
case SDLK_KP_9:
|
||||
return Rml::Input::KI_NUMPAD9;
|
||||
case SDLK_KP_ENTER:
|
||||
return Rml::Input::KI_NUMPADENTER;
|
||||
case SDLK_KP_MULTIPLY:
|
||||
return Rml::Input::KI_MULTIPLY;
|
||||
case SDLK_KP_PLUS:
|
||||
return Rml::Input::KI_ADD;
|
||||
case SDLK_KP_MINUS:
|
||||
return Rml::Input::KI_SUBTRACT;
|
||||
case SDLK_KP_PERIOD:
|
||||
return Rml::Input::KI_DECIMAL;
|
||||
case SDLK_KP_DIVIDE:
|
||||
return Rml::Input::KI_DIVIDE;
|
||||
case SDLK_KP_EQUALS:
|
||||
return Rml::Input::KI_OEM_NEC_EQUAL;
|
||||
case SDLK_BACKSPACE:
|
||||
return Rml::Input::KI_BACK;
|
||||
case SDLK_TAB:
|
||||
return Rml::Input::KI_TAB;
|
||||
case SDLK_CLEAR:
|
||||
return Rml::Input::KI_CLEAR;
|
||||
case SDLK_RETURN:
|
||||
return Rml::Input::KI_RETURN;
|
||||
case SDLK_PAUSE:
|
||||
return Rml::Input::KI_PAUSE;
|
||||
case SDLK_CAPSLOCK:
|
||||
return Rml::Input::KI_CAPITAL;
|
||||
case SDLK_PAGEUP:
|
||||
return Rml::Input::KI_PRIOR;
|
||||
case SDLK_PAGEDOWN:
|
||||
return Rml::Input::KI_NEXT;
|
||||
case SDLK_END:
|
||||
return Rml::Input::KI_END;
|
||||
case SDLK_HOME:
|
||||
return Rml::Input::KI_HOME;
|
||||
case SDLK_LEFT:
|
||||
return Rml::Input::KI_LEFT;
|
||||
case SDLK_UP:
|
||||
return Rml::Input::KI_UP;
|
||||
case SDLK_RIGHT:
|
||||
return Rml::Input::KI_RIGHT;
|
||||
case SDLK_DOWN:
|
||||
return Rml::Input::KI_DOWN;
|
||||
case SDLK_INSERT:
|
||||
return Rml::Input::KI_INSERT;
|
||||
case SDLK_DELETE:
|
||||
return Rml::Input::KI_DELETE;
|
||||
case SDLK_HELP:
|
||||
return Rml::Input::KI_HELP;
|
||||
case SDLK_F1:
|
||||
return Rml::Input::KI_F1;
|
||||
case SDLK_F2:
|
||||
return Rml::Input::KI_F2;
|
||||
case SDLK_F3:
|
||||
return Rml::Input::KI_F3;
|
||||
case SDLK_F4:
|
||||
return Rml::Input::KI_F4;
|
||||
case SDLK_F5:
|
||||
return Rml::Input::KI_F5;
|
||||
case SDLK_F6:
|
||||
return Rml::Input::KI_F6;
|
||||
case SDLK_F7:
|
||||
return Rml::Input::KI_F7;
|
||||
case SDLK_F8:
|
||||
return Rml::Input::KI_F8;
|
||||
case SDLK_F9:
|
||||
return Rml::Input::KI_F9;
|
||||
case SDLK_F10:
|
||||
return Rml::Input::KI_F10;
|
||||
case SDLK_F11:
|
||||
return Rml::Input::KI_F11;
|
||||
case SDLK_F12:
|
||||
return Rml::Input::KI_F12;
|
||||
case SDLK_F13:
|
||||
return Rml::Input::KI_F13;
|
||||
case SDLK_F14:
|
||||
return Rml::Input::KI_F14;
|
||||
case SDLK_F15:
|
||||
return Rml::Input::KI_F15;
|
||||
case SDLK_NUMLOCKCLEAR:
|
||||
return Rml::Input::KI_NUMLOCK;
|
||||
case SDLK_SCROLLLOCK:
|
||||
return Rml::Input::KI_SCROLL;
|
||||
case SDLK_LSHIFT:
|
||||
return Rml::Input::KI_LSHIFT;
|
||||
case SDLK_RSHIFT:
|
||||
return Rml::Input::KI_RSHIFT;
|
||||
case SDLK_LCTRL:
|
||||
return Rml::Input::KI_LCONTROL;
|
||||
case SDLK_RCTRL:
|
||||
return Rml::Input::KI_RCONTROL;
|
||||
case SDLK_LALT:
|
||||
return Rml::Input::KI_LMENU;
|
||||
case SDLK_RALT:
|
||||
return Rml::Input::KI_RMENU;
|
||||
case SDLK_LGUI:
|
||||
return Rml::Input::KI_LMETA;
|
||||
case SDLK_RGUI:
|
||||
return Rml::Input::KI_RMETA;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return Rml::Input::KI_UNKNOWN;
|
||||
}
|
||||
} // namespace ia::iae
|
||||
|
||||
namespace ia::iae
|
||||
{
|
||||
VOID UI::Initialize()
|
||||
{
|
||||
Rml::SetRenderInterface(&g_rmlUIRenderInterface);
|
||||
Rml::Initialise();
|
||||
|
||||
const auto displayExtent = Engine::GetDisplayExtent();
|
||||
g_context = Rml::CreateContext("main", Rml::Vector2i(displayExtent.x, displayExtent.y));
|
||||
Rml::Debugger::Initialise(g_context);
|
||||
Rml::Debugger::SetVisible(false);
|
||||
g_document = g_context->CreateDocument();
|
||||
}
|
||||
|
||||
VOID UI::Terminate()
|
||||
{
|
||||
Rml::Shutdown();
|
||||
}
|
||||
|
||||
VOID UI::Update()
|
||||
{
|
||||
if (Engine::WasInputKeyPressed(InputKey::F8))
|
||||
Rml::Debugger::SetVisible(g_debuggerEnabled = !g_debuggerEnabled);
|
||||
|
||||
g_context->Update();
|
||||
}
|
||||
|
||||
VOID UI::Draw()
|
||||
{
|
||||
g_context->Render();
|
||||
}
|
||||
|
||||
VOID UI::OnSDLEvent(IN PVOID _event)
|
||||
{
|
||||
const auto keymods = GetKeyModifierState();
|
||||
const auto event = (SDL_Event *) _event;
|
||||
switch (event->type)
|
||||
{
|
||||
case SDL_EventType::SDL_EVENT_MOUSE_MOTION:
|
||||
g_context->ProcessMouseMove(event->motion.x, event->motion.y, keymods);
|
||||
break;
|
||||
case SDL_EventType::SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
g_context->ProcessMouseButtonUp(SDLMouseButtonToRml(event->button.button), keymods);
|
||||
break;
|
||||
case SDL_EventType::SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
g_context->ProcessMouseButtonDown(SDLMouseButtonToRml(event->button.button), keymods);
|
||||
break;
|
||||
case SDL_EventType::SDL_EVENT_KEY_DOWN:
|
||||
g_context->ProcessKeyDown(SDLKeyToRml(event->key.key), keymods);
|
||||
break;
|
||||
case SDL_EventType::SDL_EVENT_KEY_UP:
|
||||
g_context->ProcessKeyUp(SDLKeyToRml(event->key.key), keymods);
|
||||
break;
|
||||
case SDL_EventType::SDL_EVENT_TEXT_INPUT:
|
||||
g_context->ProcessTextInput(Rml::String(&event->text.text[0]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VOID UI::OnScreenResize(IN INT32 newWidth, IN INT32 newHeight)
|
||||
{
|
||||
}
|
||||
|
||||
VOID UI::AddFontFromFile(IN CONST String &path)
|
||||
{
|
||||
Rml::LoadFontFace(path.c_str());
|
||||
}
|
||||
|
||||
VOID UI::SetHTML(IN CONST String &source)
|
||||
{
|
||||
g_document->SetInnerRML(
|
||||
BuildString("<body style=\"display: block; width: 100%; height: 100%;\">", source, "</body>").c_str());
|
||||
}
|
||||
} // namespace ia::iae
|
||||
|
||||
namespace ia::iae
|
||||
{
|
||||
Rml::CompiledGeometryHandle RmlUIRenderInterface::CompileGeometry(Rml::Span<const Rml::Vertex> vertices,
|
||||
Rml::Span<const int> indices)
|
||||
{
|
||||
Vector<GeometryVertex> _vertices;
|
||||
Vector<INT32> _indices;
|
||||
for (const auto &v : vertices)
|
||||
_vertices.pushBack({Vec2{v.position.x, v.position.y}, Vec2{v.tex_coord.x, v.tex_coord.y},
|
||||
Vec4{v.colour.red / 255.0f, v.colour.green / 255.0f, v.colour.blue / 255.0f,
|
||||
v.colour.alpha / 255.0f}});
|
||||
for (const auto &v : indices)
|
||||
_indices.pushBack(v);
|
||||
return (Rml::CompiledGeometryHandle) Engine::CreateGeometry(_vertices, _indices);
|
||||
}
|
||||
|
||||
void RmlUIRenderInterface::RenderGeometry(Rml::CompiledGeometryHandle geometry, Rml::Vector2f translation,
|
||||
Rml::TextureHandle texture)
|
||||
{
|
||||
|
||||
Engine::SetRenderState_Texture((Handle) texture);
|
||||
Engine::SetRenderState_FlippedH(false);
|
||||
Engine::SetRenderState_FlippedV(false);
|
||||
Engine::SetRenderState_ColorOverlay({255, 255, 255, 255});
|
||||
Engine::SetRenderState_TextureOffset({0, 0});
|
||||
Engine::SetRenderState_CameraRelative(false);
|
||||
Engine::SetRenderState_Transform({translation.x, translation.y}, {1.0f, 1.0f}, 0, 0xFF, 0);
|
||||
|
||||
Engine::DrawGeometry((Handle) geometry);
|
||||
}
|
||||
|
||||
void RmlUIRenderInterface::ReleaseGeometry(Rml::CompiledGeometryHandle geometry)
|
||||
{
|
||||
Engine::DestroyGeometry((Handle) geometry);
|
||||
}
|
||||
|
||||
Rml::TextureHandle RmlUIRenderInterface::LoadTexture(Rml::Vector2i &texture_dimensions, const Rml::String &source)
|
||||
{
|
||||
return Engine::CreateImageFromFile(Engine::GetUniqueResourceName(), source.c_str(), texture_dimensions.x,
|
||||
texture_dimensions.y);
|
||||
}
|
||||
|
||||
Rml::TextureHandle RmlUIRenderInterface::GenerateTexture(Rml::Span<const Rml::byte> source,
|
||||
Rml::Vector2i source_dimensions)
|
||||
{
|
||||
return Engine::CreateImage(Engine::GetUniqueResourceName(), (PCUINT8) source.data(), source_dimensions.x,
|
||||
source_dimensions.y);
|
||||
}
|
||||
|
||||
void RmlUIRenderInterface::ReleaseTexture(Rml::TextureHandle texture)
|
||||
{
|
||||
Engine::DestroyImage((Handle) texture);
|
||||
}
|
||||
|
||||
void RmlUIRenderInterface::EnableScissorRegion(bool enable)
|
||||
{
|
||||
if (!enable)
|
||||
Engine::SetRenderState_Scissor({});
|
||||
}
|
||||
|
||||
void RmlUIRenderInterface::SetScissorRegion(Rml::Rectanglei region)
|
||||
{
|
||||
Engine::SetRenderState_Scissor({region.Left(), region.Top(), region.Right(), region.Bottom()});
|
||||
}
|
||||
} // namespace ia::iae
|
||||
File diff suppressed because one or more lines are too long
@ -45,6 +45,7 @@ namespace ia::iae
|
||||
SDL_Rect Scissor{0, 0, 0, 0};
|
||||
SDL_GPUTexture* ActiveTexture{nullptr};
|
||||
SDL_GPUViewport ActiveViewport{};
|
||||
Vec2 SceneScaleFactor{1.0f, 1.0f};
|
||||
|
||||
Mat4 ModelMatrix{1.0f};
|
||||
|
||||
@ -63,6 +64,8 @@ namespace ia::iae
|
||||
STATIC VOID BeginFrame();
|
||||
STATIC VOID EndFrame();
|
||||
|
||||
STATIC VOID WaitForGPUIdle();
|
||||
|
||||
STATIC VOID OnScreenResize(IN INT32 newWidth, IN INT32 newHeight);
|
||||
|
||||
public:
|
||||
|
||||
@ -35,25 +35,34 @@ namespace ia::iae
|
||||
STATIC VOID Initialize();
|
||||
STATIC VOID Terminate();
|
||||
|
||||
STATIC Handle CreateImage(IN CONST String& name, IN PCUINT8 encodedData, IN SIZE_T encodedDataSize);
|
||||
STATIC Handle CreateImage(IN CONST String& name, IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height);
|
||||
STATIC Handle CreateSound(IN CONST String& name, IN PCUINT8 encodedData, IN SIZE_T encodedDataSize);
|
||||
|
||||
STATIC Handle GetImage(IN CONST String& name);
|
||||
STATIC Handle GetSound(IN CONST String& name);
|
||||
STATIC Handle CreateImage(IN CONST String &name, IN PCUINT8 encodedData, IN SIZE_T encodedDataSize);
|
||||
STATIC Handle CreateImage(IN CONST String &name, IN PCUINT8 rgbaData, IN INT32 width, IN INT32 height);
|
||||
STATIC Handle CreateSound(IN CONST String &name, IN PCUINT8 encodedData, IN SIZE_T encodedDataSize);
|
||||
|
||||
STATIC Handle GetImage(IN CONST String &name);
|
||||
STATIC Handle GetSound(IN CONST String &name);
|
||||
STATIC String GetImageName(IN Handle handle);
|
||||
STATIC String GetSoundName(IN Handle handle);
|
||||
|
||||
STATIC VOID DestroyImage(IN Handle image);
|
||||
STATIC VOID DestroySound(IN Handle sound);
|
||||
STATIC IVec2 GetImageExtent(IN Handle image);
|
||||
STATIC VOID RescaleAllImages(IN FLOAT32 factorX, IN FLOAT32 factorY);
|
||||
STATIC Handle ResizeImage(IN Handle image, IN INT32 newWidth, IN INT32 newHeight);
|
||||
STATIC Handle CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth, IN INT32 unitHeight,
|
||||
IN INT32 unitCountX, IN INT32 unitCountY);
|
||||
|
||||
public:
|
||||
STATIC SDL_GPUTexture *GetTextureFromImage(IN Handle image)
|
||||
{
|
||||
return s_imageHandles[image];
|
||||
}
|
||||
|
||||
private:
|
||||
STATIC Vector<SDL_GPUTexture *> s_imageHandles;
|
||||
STATIC Map<String, Handle> s_images;
|
||||
STATIC Map<String, Handle> s_sounds;
|
||||
STATIC Map<Handle, UINT64> s_imageExtents;
|
||||
STATIC Map<Handle, UINT64> s_nonScaledImageExtents;
|
||||
};
|
||||
} // namespace ia::iae
|
||||
@ -24,6 +24,7 @@
|
||||
#include <IAEngine/Components/CameraComponent.hpp>
|
||||
#include <IAEngine/Components/SoundEmitterComponent.hpp>
|
||||
|
||||
#include <IAEngine/UI.hpp>
|
||||
#include <IAEngine/Scene.hpp>
|
||||
|
||||
namespace ia::iae
|
||||
@ -82,6 +83,8 @@ namespace ia::iae
|
||||
STATIC IAE_DLL_API VOID DestroySound(IN Handle sound);
|
||||
STATIC IAE_DLL_API IVec2 GetImageExtent(IN Handle image);
|
||||
STATIC IAE_DLL_API Handle ResizeImage(IN Handle image, IN INT32 newWidth, IN INT32 newHeight);
|
||||
STATIC IAE_DLL_API Handle ResizeImage(IN CONST String& name, IN INT32 newWidth, IN INT32 newHeight);
|
||||
STATIC IAE_DLL_API VOID RescaleAllImages(IN FLOAT32 factorX, IN FLOAT32 factorY);
|
||||
STATIC IAE_DLL_API Handle CombineImages(IN CONST Vector<Handle> &images, IN INT32 unitWidth,
|
||||
IN INT32 unitHeight, IN INT32 unitCountX, IN INT32 unitCountY);
|
||||
|
||||
@ -127,5 +130,6 @@ namespace ia::iae
|
||||
|
||||
// Engine Functions
|
||||
STATIC IAE_DLL_API BOOL IsDebugMode();
|
||||
STATIC IAE_DLL_API String GetUniqueResourceName();
|
||||
};
|
||||
} // namespace ia::iae
|
||||
@ -21,6 +21,12 @@
|
||||
using namespace ia;
|
||||
using namespace ia::iae;
|
||||
|
||||
struct GameRequestedConfig
|
||||
{
|
||||
INT32 ScreenWidth{};
|
||||
INT32 ScreenHeight{};
|
||||
};
|
||||
|
||||
#if defined(__BUILDING_IAENGINE_GAME) && (__BUILDING_IAENGINE_GAME)
|
||||
|
||||
#define GAME_LOG_TAG "[GAME]: "
|
||||
@ -28,6 +34,7 @@ using namespace ia::iae;
|
||||
#define GAME_LOG_WARN(...) ia::Logger::Warn(IAE_LOG_TAG, __VA_ARGS__)
|
||||
#define GAME_LOG_ERROR(...) ia::Logger::Error(IAE_LOG_TAG, __VA_ARGS__)
|
||||
|
||||
C_DECL(IA_DLL_EXPORT GameRequestedConfig Game_GetConfigRequest());
|
||||
C_DECL(IA_DLL_EXPORT VOID Game_OnInitialize());
|
||||
C_DECL(IA_DLL_EXPORT VOID Game_OnTerminate());
|
||||
C_DECL(IA_DLL_EXPORT VOID Game_OnDebugDraw());
|
||||
@ -44,6 +51,8 @@ using namespace ia::iae;
|
||||
|
||||
struct GameFunctionTable
|
||||
{
|
||||
GameRequestedConfig(*GetConfigRequest)(){nullptr};
|
||||
|
||||
VOID (*OnInitialize)() {nullptr};
|
||||
VOID (*OnTerminate)() {nullptr};
|
||||
VOID (*OnDebugDraw)() {nullptr};
|
||||
|
||||
@ -32,12 +32,18 @@ namespace ia::iae
|
||||
IAE_DLL_API VOID RemoveNode(IN CONST String &name);
|
||||
|
||||
public:
|
||||
IVec2& Extent()
|
||||
{
|
||||
return m_extent;
|
||||
}
|
||||
|
||||
Color &BackgroundColor()
|
||||
{
|
||||
return m_backgroundColor;
|
||||
}
|
||||
|
||||
private:
|
||||
IVec2 m_extent{100, 100};
|
||||
Color m_backgroundColor{0, 0, 0, 255};
|
||||
Map<String, RefPtr<INode>> m_nodes;
|
||||
|
||||
|
||||
@ -20,5 +20,21 @@
|
||||
|
||||
namespace ia::iae
|
||||
{
|
||||
|
||||
class UI
|
||||
{
|
||||
public:
|
||||
STATIC IAE_DLL_API VOID AddFontFromFile(IN CONST String& path);
|
||||
|
||||
STATIC IAE_DLL_API VOID SetHTML(IN CONST String& source);
|
||||
|
||||
public:
|
||||
STATIC VOID Initialize();
|
||||
STATIC VOID Terminate();
|
||||
|
||||
STATIC VOID Update();
|
||||
STATIC VOID Draw();
|
||||
|
||||
STATIC VOID OnSDLEvent(IN PVOID event);
|
||||
STATIC VOID OnScreenResize(IN INT32 newWidth, IN INT32 newHeight);
|
||||
};
|
||||
}
|
||||
@ -24,6 +24,7 @@ int main(int argc, char* argv[])
|
||||
gameFunctionTable.OnResize =
|
||||
(VOID (*)(IN INT32 newWidth, IN INT32 newHeight)) GetProcAddress(gameLib, "Game_OnResize");
|
||||
|
||||
gameFunctionTable.GetConfigRequest = (GameRequestedConfig (*)()) GetProcAddress(gameLib, "Game_GetConfigRequest");
|
||||
gameFunctionTable.GetName = (PCCHAR (*)()) GetProcAddress(gameLib, "Game_GetName");
|
||||
gameFunctionTable.GetVersion = (UINT64 (*)()) GetProcAddress(gameLib, "Game_GetVersion");
|
||||
gameFunctionTable.GetPackageName = (PCCHAR (*)()) GetProcAddress(gameLib, "Game_GetPackageName");
|
||||
|
||||
@ -19,24 +19,30 @@
|
||||
RefPtr<Node2D> backgroundNode;
|
||||
RefPtr<CameraNode> mainCamera;
|
||||
|
||||
TextureComponent *title;
|
||||
|
||||
C_DECL(IA_DLL_EXPORT GameRequestedConfig Game_GetConfigRequest())
|
||||
{
|
||||
return {600, 600};
|
||||
}
|
||||
|
||||
C_DECL(IA_DLL_EXPORT VOID Game_OnInitialize())
|
||||
{
|
||||
Engine::ResizeDisplay(600, 600);
|
||||
|
||||
const auto displayExtent = Engine::GetDisplayExtent();
|
||||
|
||||
Engine::CreateImageFromFile("Background", "Resources/Sprites/bg.png", displayExtent.x, displayExtent.y);
|
||||
Engine::CreateImageFromFile("Stars-A", "Resources/Sprites/Stars-A.png", displayExtent.x, displayExtent.y);
|
||||
Engine::CreateImageFromFile("Stars-B", "Resources/Sprites/Stars-B.png", displayExtent.x, displayExtent.y);
|
||||
|
||||
mainCamera = MakeRefPtr<CameraNode>("MainCamera");
|
||||
Engine::SetActiveCamera(mainCamera->GetCameraComponent());
|
||||
|
||||
backgroundNode = MakeRefPtr<Node2D>("BG");
|
||||
backgroundNode->AddComponent<TextureComponent>()->SetTexture(Engine::GetImage("Stars-A"));
|
||||
//backgroundNode->AddComponent<TextureComponent>()->SetTexture(g_spriteBGStarsA);
|
||||
//backgroundNode->GetTextureComponent()->SetTexture(g_spriteBG);
|
||||
Engine::AddNodeToActiveScene(backgroundNode);
|
||||
Engine::CreateImageFromFile("Background", "Resources/Sprites/bg.png");
|
||||
Engine::CreateImageFromFile("Stars-A", "Resources/Sprites/Stars-A.png");
|
||||
Engine::CreateImageFromFile("Stars-B", "Resources/Sprites/Stars-B.png");
|
||||
Engine::CreateImageFromFile("Title", "Resources/UI/Title.png");
|
||||
|
||||
//UI::SetHTML("<img src=\"Resources/UI/Title.png\" style=\"width: 100%; height: 100%;\"></img>");
|
||||
//backgroundNode = MakeRefPtr<Node2D>("BG");
|
||||
//backgroundNode->AddComponent<TextureComponent>()->SetTexture(Engine::GetImage("Background"));
|
||||
//title = backgroundNode->AddComponent<TextureComponent>();
|
||||
//title->PositionOffset() = {150, 100};
|
||||
//title->SetTexture(Engine::GetImage("Title"));
|
||||
//Engine::AddNodeToActiveScene(backgroundNode);
|
||||
}
|
||||
|
||||
C_DECL(IA_DLL_EXPORT VOID Game_OnTerminate())
|
||||
@ -57,11 +63,12 @@ C_DECL(IA_DLL_EXPORT VOID Game_OnUpdate(IN FLOAT32 deltaTime))
|
||||
|
||||
C_DECL(IA_DLL_EXPORT VOID Game_OnResize(IN INT32 newWidth, IN INT32 newHeight))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
C_DECL(IA_DLL_EXPORT PCCHAR Game_GetName())
|
||||
{
|
||||
return "Space Invaders";
|
||||
return "Space Case";
|
||||
}
|
||||
|
||||
C_DECL(IA_DLL_EXPORT UINT64 Game_GetVersion())
|
||||
@ -71,7 +78,7 @@ C_DECL(IA_DLL_EXPORT UINT64 Game_GetVersion())
|
||||
|
||||
C_DECL(IA_DLL_EXPORT PCCHAR Game_GetPackageName())
|
||||
{
|
||||
return "com.iasoft.iaenginesamples.spaceinvaders";
|
||||
return "com.iasoft.spacecase";
|
||||
}
|
||||
|
||||
C_DECL(IA_DLL_EXPORT PCCHAR Game_GetDeveloperName())
|
||||
|
||||
Reference in New Issue
Block a user