Still need to fix asset loading
This commit is contained in:
parent
d70c04e57e
commit
4bdae7213d
38
imgui.ini
38
imgui.ini
@ -10,24 +10,24 @@ Collapsed=1
|
|||||||
|
|
||||||
[Window][WindowOverViewport_11111111]
|
[Window][WindowOverViewport_11111111]
|
||||||
Pos=0,19
|
Pos=0,19
|
||||||
Size=1920,1158
|
Size=1280,701
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Inspector]
|
[Window][Inspector]
|
||||||
Pos=1402,19
|
Pos=774,19
|
||||||
Size=518,1158
|
Size=506,701
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000006,0
|
DockId=0x00000006,0
|
||||||
|
|
||||||
[Window][Scene Tree]
|
[Window][Scene Tree]
|
||||||
Pos=0,19
|
Pos=0,19
|
||||||
Size=342,575
|
Size=342,348
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000003,0
|
DockId=0x00000003,0
|
||||||
|
|
||||||
[Window][Viewport]
|
[Window][Viewport]
|
||||||
Pos=344,19
|
Pos=344,19
|
||||||
Size=1056,847
|
Size=428,390
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000007,0
|
DockId=0x00000007,0
|
||||||
|
|
||||||
@ -36,14 +36,14 @@ Size=1280,19
|
|||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Performance Info]
|
[Window][Performance Info]
|
||||||
Pos=344,868
|
Pos=344,411
|
||||||
Size=1056,309
|
Size=428,309
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000008,2
|
DockId=0x00000008,2
|
||||||
|
|
||||||
[Window][Console]
|
[Window][Console]
|
||||||
Pos=344,868
|
Pos=344,411
|
||||||
Size=1056,309
|
Size=428,309
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000008,0
|
DockId=0x00000008,0
|
||||||
|
|
||||||
@ -54,8 +54,8 @@ Collapsed=0
|
|||||||
DockId=0x00000007,1
|
DockId=0x00000007,1
|
||||||
|
|
||||||
[Window][Profiler]
|
[Window][Profiler]
|
||||||
Pos=344,868
|
Pos=344,411
|
||||||
Size=1056,309
|
Size=428,309
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000008,3
|
DockId=0x00000008,3
|
||||||
|
|
||||||
@ -78,14 +78,14 @@ Collapsed=0
|
|||||||
DockId=0x00000008,1
|
DockId=0x00000008,1
|
||||||
|
|
||||||
[Window][Color Correction]
|
[Window][Color Correction]
|
||||||
Pos=344,868
|
Pos=344,411
|
||||||
Size=1056,309
|
Size=428,309
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000008,1
|
DockId=0x00000008,1
|
||||||
|
|
||||||
[Window][Asset Browser]
|
[Window][Asset Browser]
|
||||||
Pos=0,596
|
Pos=0,369
|
||||||
Size=342,581
|
Size=342,351
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000004,0
|
DockId=0x00000004,0
|
||||||
|
|
||||||
@ -95,13 +95,13 @@ Size=325,75
|
|||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Docking][Data]
|
[Docking][Data]
|
||||||
DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1920,1158 Split=X
|
DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Split=X
|
||||||
DockNode ID=0x00000005 Parent=0x11111111 SizeRef=1400,1158 Split=X
|
DockNode ID=0x00000005 Parent=0x11111111 SizeRef=772,1158 Split=X
|
||||||
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=342,701 Split=Y Selected=0x12EF0F59
|
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=342,701 Split=Y Selected=0x12EF0F59
|
||||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=342,575 HiddenTabBar=1 Selected=0x12EF0F59
|
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=342,575 HiddenTabBar=1 Selected=0x12EF0F59
|
||||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=342,581 HiddenTabBar=1 Selected=0x36AF052B
|
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=342,581 HiddenTabBar=1 Selected=0x36AF052B
|
||||||
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1056,701 Split=Y Selected=0xC450F867
|
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=428,701 Split=Y Selected=0xC450F867
|
||||||
DockNode ID=0x00000007 Parent=0x00000002 SizeRef=606,847 CentralNode=1 HiddenTabBar=1 Selected=0xC450F867
|
DockNode ID=0x00000007 Parent=0x00000002 SizeRef=606,847 CentralNode=1 HiddenTabBar=1 Selected=0xC450F867
|
||||||
DockNode ID=0x00000008 Parent=0x00000002 SizeRef=606,309 Selected=0x9B5D3198
|
DockNode ID=0x00000008 Parent=0x00000002 SizeRef=606,309 Selected=0x9B5D3198
|
||||||
DockNode ID=0x00000006 Parent=0x11111111 SizeRef=518,1158 HiddenTabBar=1 Selected=0x36DC96AB
|
DockNode ID=0x00000006 Parent=0x11111111 SizeRef=506,1158 HiddenTabBar=1 Selected=0x36DC96AB
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ include_dirs:
|
|||||||
- src/vendor/imgui
|
- src/vendor/imgui
|
||||||
- src/vendor/box2d
|
- src/vendor/box2d
|
||||||
- src/vendor/xxhash
|
- src/vendor/xxhash
|
||||||
|
- src/vendor/miniaudio
|
||||||
|
|
||||||
- C:/msys64/mingw64/include
|
- C:/msys64/mingw64/include
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
[LINK] g++ src\build\Engine.o src\build\main.o src\build\Renderer.o src\build\Components\AnimationComponent.o src\build\Components\CameraComponent.o src\build\Components\LightComponent.o src\build\Components\ParticleComponent.o src\build\Components\PhysicsComponent.o src\build\Components\ScriptComponent.o src\build\Components\SpriteComponent.o src\build\Components\TextComonent.o src\build\Components\TilemapComponent.o src\build\core\utils\AssetManager.o src\build\core\utils\EngineConfig.o src\build\core\utils\ExceptionHandler.o src\build\core\utils\FileDialog.o src\build\core\utils\input.o src\build\core\utils\LoadingWindow.o src\build\core\utils\Logging.o src\build\core\utils\Profiler.o src\build\core\utils\Texture.o src\build\core\utils\utils.o src\build\editor\windows\AssetBrowser.o src\build\editor\windows\Inspector.o src\build\Entitys\Object.o src\build\utils\GameObjectsList.o src\build\utils\Shader.o src\build\utils\UID.o src\build\lapi.o src\build\lauxlib.o src\build\lbaselib.o src\build\lcode.o src\build\lcorolib.o src\build\lctype.o src\build\ldblib.o src\build\ldebug.o src\build\ldo.o src\build\ldump.o src\build\lfunc.o src\build\lgc.o src\build\linit.o src\build\liolib.o src\build\llex.o src\build\lmathlib.o src\build\lmem.o src\build\loadlib.o src\build\lobject.o src\build\lopcodes.o src\build\loslib.o src\build\lparser.o src\build\lstate.o src\build\lstring.o src\build\lstrlib.o src\build\ltable.o src\build\ltablib.o src\build\ltm.o src\build\lua.o src\build\luac.o src\build\lundump.o src\build\lutf8lib.o src\build\lvm.o src\build\lzio.o src\build\imgui.o src\build\imgui_demo.o src\build\imgui_draw.o src\build\imgui_impl_glfw.o src\build\imgui_impl_opengl3.o src\build\imgui_tables.o src\build\imgui_widgets.o src\build\aabb.o src\build\arena_allocator.o src\build\array.o src\build\bitset.o src\build\body.o src\build\broad_phase.o src\build\constraint_graph.o src\build\contact.o src\build\contact_solver.o src\build\core.o src\build\distance.o src\build\distance_joint.o src\build\dynamic_tree.o src\build\geometry.o src\build\hull.o src\build\id_pool.o src\build\island.o src\build\joint.o src\build\manifold.o src\build\math_functions.o src\build\motor_joint.o src\build\mouse_joint.o src\build\mover.o src\build\prismatic_joint.o src\build\revolute_joint.o src\build\sensor.o src\build\shape.o src\build\solver.o src\build\solver_set.o src\build\table.o src\build\timer.o src\build\types.o src\build\weld_joint.o src\build\wheel_joint.o src\build\world.o src\build\xxhash.o -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto
|
[LINK] g++ src\build\Engine.o src\build\main.o src\build\Renderer.o src\build\Components\AnimationComponent.o src\build\Components\CameraComponent.o src\build\Components\LightComponent.o src\build\Components\ParticleComponent.o src\build\Components\PhysicsComponent.o src\build\Components\ScriptComponent.o src\build\Components\SpriteComponent.o src\build\Components\TextComonent.o src\build\Components\TilemapComponent.o src\build\core\audio\AudioEngine.o src\build\core\utils\AssetManager.o src\build\core\utils\EngineConfig.o src\build\core\utils\ExceptionHandler.o src\build\core\utils\FileDialog.o src\build\core\utils\input.o src\build\core\utils\LoadingWindow.o src\build\core\utils\Logging.o src\build\core\utils\Profiler.o src\build\core\utils\Texture.o src\build\core\utils\utils.o src\build\editor\windows\AssetBrowser.o src\build\editor\windows\Inspector.o src\build\Entitys\Object.o src\build\utils\GameObjectsList.o src\build\utils\Shader.o src\build\utils\UID.o src\build\lapi.o src\build\lauxlib.o src\build\lbaselib.o src\build\lcode.o src\build\lcorolib.o src\build\lctype.o src\build\ldblib.o src\build\ldebug.o src\build\ldo.o src\build\ldump.o src\build\lfunc.o src\build\lgc.o src\build\linit.o src\build\liolib.o src\build\llex.o src\build\lmathlib.o src\build\lmem.o src\build\loadlib.o src\build\lobject.o src\build\lopcodes.o src\build\loslib.o src\build\lparser.o src\build\lstate.o src\build\lstring.o src\build\lstrlib.o src\build\ltable.o src\build\ltablib.o src\build\ltm.o src\build\lua.o src\build\luac.o src\build\lundump.o src\build\lutf8lib.o src\build\lvm.o src\build\lzio.o src\build\imgui.o src\build\imgui_demo.o src\build\imgui_draw.o src\build\imgui_impl_glfw.o src\build\imgui_impl_opengl3.o src\build\imgui_tables.o src\build\imgui_widgets.o src\build\aabb.o src\build\arena_allocator.o src\build\array.o src\build\bitset.o src\build\body.o src\build\broad_phase.o src\build\constraint_graph.o src\build\contact.o src\build\contact_solver.o src\build\core.o src\build\distance.o src\build\distance_joint.o src\build\dynamic_tree.o src\build\geometry.o src\build\hull.o src\build\id_pool.o src\build\island.o src\build\joint.o src\build\manifold.o src\build\math_functions.o src\build\motor_joint.o src\build\mouse_joint.o src\build\mover.o src\build\prismatic_joint.o src\build\revolute_joint.o src\build\sensor.o src\build\shape.o src\build\solver.o src\build\solver_set.o src\build\table.o src\build\timer.o src\build\types.o src\build\weld_joint.o src\build\wheel_joint.o src\build\world.o src\build\xxhash.o -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto
|
||||||
[RUN] Executed app.exe successfully.
|
[RUN] Executed app.exe successfully.
|
||||||
|
56
src/assets/scenes/updated_asset_manager.cene
Normal file
56
src/assets/scenes/updated_asset_manager.cene
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
engine_version: 0.1.0
|
||||||
|
scene_name: updated_asset_manager
|
||||||
|
scene_hash: 0293966521aa0692590ed25b05d9076fc6d206e07484422d814d7ee33ac235b4
|
||||||
|
format_version: 1
|
||||||
|
objects:
|
||||||
|
- name: Hello, Create
|
||||||
|
uid: 4afb134ba5a84d3d837374e314ca9adb
|
||||||
|
id: 0
|
||||||
|
position: [0, 0]
|
||||||
|
rotation: 0
|
||||||
|
layer: 0
|
||||||
|
visable: true
|
||||||
|
components: []
|
||||||
|
children: []
|
||||||
|
color_correction:
|
||||||
|
brightness: 1
|
||||||
|
saturation: 1
|
||||||
|
gamma: 1
|
||||||
|
bloom: true
|
||||||
|
intensity: 1.20000005
|
||||||
|
threshold: 1
|
||||||
|
Assets:
|
||||||
|
- uaid: 4
|
||||||
|
path: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_nor_gl_1k.png
|
||||||
|
filename: ganges_river_pebbles_nor_gl_1k.png
|
||||||
|
filetype: png
|
||||||
|
type: 0
|
||||||
|
hash: 6711b00700d4c94a
|
||||||
|
lastModified: 1744565594
|
||||||
|
size: [1024, 1024]
|
||||||
|
channels: 4
|
||||||
|
format: GL_RGBA
|
||||||
|
- uaid: 3
|
||||||
|
path: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_diff_1k.png
|
||||||
|
filename: ganges_river_pebbles_diff_1k.png
|
||||||
|
filetype: png
|
||||||
|
type: 0
|
||||||
|
hash: 0349580fcbf62155
|
||||||
|
lastModified: 1744565605
|
||||||
|
size: [1024, 1024]
|
||||||
|
channels: 4
|
||||||
|
format: GL_RGBA
|
||||||
|
- uaid: 2
|
||||||
|
path: C:\Users\spenc\Music\simple-notification-152054.mp3
|
||||||
|
filename: simple-notification-152054.mp3
|
||||||
|
filetype: mp3
|
||||||
|
type: 1
|
||||||
|
hash: 3e57c2530f08c1ab
|
||||||
|
lastModified: 1745951639
|
||||||
|
- uaid: 1
|
||||||
|
path: C:\Users\spenc\Music\simple-notification-152054.wav
|
||||||
|
filename: simple-notification-152054.wav
|
||||||
|
filetype: wav
|
||||||
|
type: 1
|
||||||
|
hash: 0f5adca8b95e7494
|
||||||
|
lastModified: 1745952999
|
@ -15,15 +15,22 @@ void AnimationComponent::SetTextureAtlas(uint64_t uaid, int texelWidth, int texe
|
|||||||
{
|
{
|
||||||
textureUAID = uaid;
|
textureUAID = uaid;
|
||||||
|
|
||||||
const auto *asset = AssetManager::GetAssetByID(uaid);
|
const auto* asset = AssetManager::GetAssetByID(uaid);
|
||||||
if (!asset || !asset->loaded)
|
if (!asset || !asset->loaded)
|
||||||
{
|
{
|
||||||
Logger::LogError("SetTextureAtlas: Asset not found or not loaded (UAID: %llu)", uaid);
|
Logger::LogError("SetTextureAtlas: Asset not found or not loaded (UAID: %llu)", uaid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int texWidth = static_cast<int>(asset->size.x);
|
const auto* imageAsset = dynamic_cast<const ImageAssetInfo*>(asset);
|
||||||
int texHeight = static_cast<int>(asset->size.y);
|
if (!imageAsset)
|
||||||
|
{
|
||||||
|
Logger::LogError("SetTextureAtlas: Asset with UAID %llu is not an image", uaid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int texWidth = static_cast<int>(imageAsset->size.x);
|
||||||
|
int texHeight = static_cast<int>(imageAsset->size.y);
|
||||||
|
|
||||||
if (texelWidth <= 0 || texelHeight <= 0 || texWidth < texelWidth || texHeight < texelHeight)
|
if (texelWidth <= 0 || texelHeight <= 0 || texWidth < texelWidth || texHeight < texelHeight)
|
||||||
{
|
{
|
||||||
@ -37,7 +44,7 @@ void AnimationComponent::SetTextureAtlas(uint64_t uaid, int texelWidth, int texe
|
|||||||
Logger::LogWarning("SetTextureAtlas: Texture size is not cleanly divisible by texel size (UAID: %llu)", uaid);
|
Logger::LogWarning("SetTextureAtlas: Texture size is not cleanly divisible by texel size (UAID: %llu)", uaid);
|
||||||
}
|
}
|
||||||
|
|
||||||
texture = std::make_shared<Texture>(asset->uaid);
|
texture = std::make_shared<Texture>(imageAsset->uaid);
|
||||||
|
|
||||||
atlas.texture = texture;
|
atlas.texture = texture;
|
||||||
atlas.SetTexelSize(texelWidth, texelHeight);
|
atlas.SetTexelSize(texelWidth, texelHeight);
|
||||||
@ -50,14 +57,10 @@ void AnimationComponent::SetTextureAtlas(uint64_t uaid, int texelWidth, int texe
|
|||||||
endFrame = totalFrames > 0 ? totalFrames - 1 : 0;
|
endFrame = totalFrames > 0 ? totalFrames - 1 : 0;
|
||||||
|
|
||||||
if (start != 0)
|
if (start != 0)
|
||||||
{
|
|
||||||
startFrame = start;
|
startFrame = start;
|
||||||
}
|
|
||||||
|
|
||||||
if (end != 0)
|
if (end != 0)
|
||||||
{
|
|
||||||
endFrame = end;
|
endFrame = end;
|
||||||
}
|
|
||||||
|
|
||||||
frameDuration = duration;
|
frameDuration = duration;
|
||||||
currentFrame = startFrame;
|
currentFrame = startFrame;
|
||||||
@ -65,6 +68,7 @@ void AnimationComponent::SetTextureAtlas(uint64_t uaid, int texelWidth, int texe
|
|||||||
renderType = RenderType::Unlit;
|
renderType = RenderType::Unlit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AnimationComponent::Play() { playing = true; }
|
void AnimationComponent::Play() { playing = true; }
|
||||||
void AnimationComponent::Stop() { playing = false; }
|
void AnimationComponent::Stop() { playing = false; }
|
||||||
void AnimationComponent::SetLooping(bool loop_) { loop = loop_; }
|
void AnimationComponent::SetLooping(bool loop_) { loop = loop_; }
|
||||||
|
@ -44,26 +44,42 @@ void SpriteComponent::SetTexture(uint64_t uaid)
|
|||||||
const auto* asset = AssetManager::GetAssetByID(uaid);
|
const auto* asset = AssetManager::GetAssetByID(uaid);
|
||||||
if (asset && asset->loaded)
|
if (asset && asset->loaded)
|
||||||
{
|
{
|
||||||
textureID = asset->textureID;
|
if (const auto* imageAsset = dynamic_cast<const ImageAssetInfo*>(asset))
|
||||||
size = asset->size;
|
{
|
||||||
texture_loaded = true;
|
textureID = imageAsset->textureID;
|
||||||
|
size = imageAsset->size;
|
||||||
|
texture_loaded = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::LogError("[SpriteComponent] Asset with UAID '%llu' is not an image!", uaid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SpriteComponent::SetNormalMap(uint64_t uaid)
|
void SpriteComponent::SetNormalMap(uint64_t uaid)
|
||||||
{
|
{
|
||||||
normalMapUAID = uaid;
|
normalMapUAID = uaid;
|
||||||
const auto* asset = AssetManager::GetAssetByID(uaid);
|
const auto* asset = AssetManager::GetAssetByID(uaid);
|
||||||
if (asset && asset->loaded)
|
if (asset && asset->loaded)
|
||||||
{
|
{
|
||||||
normalMapID = asset->textureID;
|
if (const auto* imageAsset = dynamic_cast<const ImageAssetInfo*>(asset))
|
||||||
|
{
|
||||||
|
normalMapID = imageAsset->textureID;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::LogError("[SpriteComponent] Asset with UAID '%llu' is not an image!", uaid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int SpriteComponent::GetTextureID() const
|
unsigned int SpriteComponent::GetTextureID() const
|
||||||
{
|
{
|
||||||
return textureID;
|
return textureID;
|
||||||
|
@ -40,18 +40,26 @@ void TilemapComponent::SetTextureAtlas(uint64_t uaid, int texelWidth, int texelH
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
texture = std::make_shared<Texture>(uaid);
|
const auto* imageAsset = dynamic_cast<const ImageAssetInfo*>(asset);
|
||||||
|
if (!imageAsset)
|
||||||
|
{
|
||||||
|
Logger::LogError("TilemapComponent: Asset with UAID %llu is not an image", uaid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture = std::make_shared<Texture>(imageAsset->uaid);
|
||||||
|
|
||||||
atlas.texture = texture;
|
atlas.texture = texture;
|
||||||
atlas.SetTexelSize(texelWidth, texelHeight);
|
atlas.SetTexelSize(texelWidth, texelHeight);
|
||||||
|
|
||||||
int texWidth = static_cast<int>(asset->size.x);
|
int texWidth = static_cast<int>(imageAsset->size.x);
|
||||||
int texHeight = static_cast<int>(asset->size.y);
|
int texHeight = static_cast<int>(imageAsset->size.y);
|
||||||
|
|
||||||
atlasColumns = texWidth / texelWidth;
|
atlasColumns = texWidth / texelWidth;
|
||||||
atlasRows = texHeight / texelHeight;
|
atlasRows = texHeight / texelHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TilemapComponent::SetTile(int x, int y, int index)
|
void TilemapComponent::SetTile(int x, int y, int index)
|
||||||
{
|
{
|
||||||
uint64_t key = PackCoord(x, y);
|
uint64_t key = PackCoord(x, y);
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
#include "core/utils/FileDialog.h"
|
#include "core/utils/FileDialog.h"
|
||||||
#include "core/utils/Logging.h"
|
#include "core/utils/Logging.h"
|
||||||
|
|
||||||
|
#include "core/audio/AudioEngine.h"
|
||||||
|
|
||||||
|
|
||||||
#include "core/utils/EngineConfig.h"
|
#include "core/utils/EngineConfig.h"
|
||||||
#include "utils/GameObjectsList.h"
|
#include "utils/GameObjectsList.h"
|
||||||
#include "core/utils/Profiler.h"
|
#include "core/utils/Profiler.h"
|
||||||
@ -510,6 +513,12 @@ void Engine::Init()
|
|||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
Logger::LogVerbose("Init Sound Core");
|
||||||
|
|
||||||
|
AudioEngine::Init();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Logger::LogVerbose("Resverving Objects");
|
Logger::LogVerbose("Resverving Objects");
|
||||||
|
|
||||||
// These values were AI Generated.
|
// These values were AI Generated.
|
||||||
@ -985,7 +994,6 @@ void Engine::Run()
|
|||||||
|
|
||||||
profiler.EndSection();
|
profiler.EndSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
profiler.EndSection();
|
profiler.EndSection();
|
||||||
|
|
||||||
@ -1023,103 +1031,106 @@ void Engine::Run()
|
|||||||
|
|
||||||
if (asset && asset->loaded)
|
if (asset && asset->loaded)
|
||||||
{
|
{
|
||||||
auto *drawList = ImGui::GetWindowDrawList();
|
if (const auto *imageAsset = dynamic_cast<const ImageAssetInfo *>(asset))
|
||||||
const auto texSize = asset->size;
|
|
||||||
int maxCols = static_cast<int>(texSize.x / tileSize.x);
|
|
||||||
int maxRows = static_cast<int>(texSize.y / tileSize.y);
|
|
||||||
|
|
||||||
core::types::Vec2 screenMouse(mousePos.x - winPos.x, mousePos.y - winPos.y);
|
|
||||||
core::types::Vec2 worldMouse = ScreenToWorld(screenMouse, {winSize.x, winSize.y}, cameraPos, cameraZoom);
|
|
||||||
|
|
||||||
int centerCol = static_cast<int>(worldMouse.x / tileSize.x);
|
|
||||||
int centerRow = static_cast<int>(worldMouse.y / tileSize.y);
|
|
||||||
|
|
||||||
int radius = 15;
|
|
||||||
int minCol = centerCol - radius;
|
|
||||||
int maxCol = centerCol + radius;
|
|
||||||
int minRow = centerRow - radius;
|
|
||||||
int maxRow = centerRow + radius;
|
|
||||||
|
|
||||||
core::types::Vec2 screenCenter = {winPos.x + winSize.x * 0.5f, winPos.y + winSize.y * 0.5f};
|
|
||||||
float maxDist = static_cast<float>(radius) * tileSize.x * cameraZoom;
|
|
||||||
|
|
||||||
for (int y = minRow; y <= maxRow; ++y)
|
|
||||||
{
|
{
|
||||||
for (int x = minCol; x <= maxCol; ++x)
|
auto *drawList = ImGui::GetWindowDrawList();
|
||||||
|
const auto texSize = imageAsset->size;
|
||||||
|
int maxCols = static_cast<int>(texSize.x / tileSize.x);
|
||||||
|
int maxRows = static_cast<int>(texSize.y / tileSize.y);
|
||||||
|
|
||||||
|
core::types::Vec2 screenMouse(mousePos.x - winPos.x, mousePos.y - winPos.y);
|
||||||
|
core::types::Vec2 worldMouse = ScreenToWorld(screenMouse, {winSize.x, winSize.y}, cameraPos, cameraZoom);
|
||||||
|
|
||||||
|
int centerCol = static_cast<int>(worldMouse.x / tileSize.x);
|
||||||
|
int centerRow = static_cast<int>(worldMouse.y / tileSize.y);
|
||||||
|
|
||||||
|
int radius = 15;
|
||||||
|
int minCol = centerCol - radius;
|
||||||
|
int maxCol = centerCol + radius;
|
||||||
|
int minRow = centerRow - radius;
|
||||||
|
int maxRow = centerRow + radius;
|
||||||
|
|
||||||
|
core::types::Vec2 screenCenter = {winPos.x + winSize.x * 0.5f, winPos.y + winSize.y * 0.5f};
|
||||||
|
float maxDist = static_cast<float>(radius) * tileSize.x * cameraZoom;
|
||||||
|
|
||||||
|
for (int y = minRow; y <= maxRow; ++y)
|
||||||
{
|
{
|
||||||
float gx = x * tileSize.x;
|
for (int x = minCol; x <= maxCol; ++x)
|
||||||
float gy = y * tileSize.y;
|
{
|
||||||
|
float gx = x * tileSize.x;
|
||||||
|
float gy = y * tileSize.y;
|
||||||
|
|
||||||
float sx = (gx - cameraPos.x) * cameraZoom + screenCenter.x;
|
float sx = (gx - cameraPos.x) * cameraZoom + screenCenter.x;
|
||||||
float sy = (gy - cameraPos.y) * cameraZoom + screenCenter.y;
|
float sy = (gy - cameraPos.y) * cameraZoom + screenCenter.y;
|
||||||
float sx2 = (gx + tileSize.x - cameraPos.x) * cameraZoom + screenCenter.x;
|
float sx2 = (gx + tileSize.x - cameraPos.x) * cameraZoom + screenCenter.x;
|
||||||
float sy2 = (gy + tileSize.y - cameraPos.y) * cameraZoom + screenCenter.y;
|
float sy2 = (gy + tileSize.y - cameraPos.y) * cameraZoom + screenCenter.y;
|
||||||
|
|
||||||
float centerGX = gx + tileSize.x * 0.5f;
|
float centerGX = gx + tileSize.x * 0.5f;
|
||||||
float centerGY = gy + tileSize.y * 0.5f;
|
float centerGY = gy + tileSize.y * 0.5f;
|
||||||
float dx = (centerGX - worldMouse.x);
|
float dx = (centerGX - worldMouse.x);
|
||||||
float dy = (centerGY - worldMouse.y);
|
float dy = (centerGY - worldMouse.y);
|
||||||
float dist = std::sqrt(dx * dx + dy * dy) * cameraZoom;
|
float dist = std::sqrt(dx * dx + dy * dy) * cameraZoom;
|
||||||
float fade = std::clamp(1.0f - dist / maxDist, 0.0f, 0.9f);
|
float fade = std::clamp(1.0f - dist / maxDist, 0.0f, 0.9f);
|
||||||
int alpha = static_cast<int>(fade * 255.0f);
|
int alpha = static_cast<int>(fade * 255.0f);
|
||||||
|
|
||||||
ImU32 color = IM_COL32(255, 255, 0, alpha);
|
ImU32 color = IM_COL32(255, 255, 0, alpha);
|
||||||
|
|
||||||
drawList->AddLine(ImVec2(sx, sy), ImVec2(sx2, sy), color);
|
drawList->AddLine(ImVec2(sx, sy), ImVec2(sx2, sy), color);
|
||||||
drawList->AddLine(ImVec2(sx2, sy), ImVec2(sx2, sy2), color);
|
drawList->AddLine(ImVec2(sx2, sy), ImVec2(sx2, sy2), color);
|
||||||
drawList->AddLine(ImVec2(sx2, sy2), ImVec2(sx, sy2), color);
|
drawList->AddLine(ImVec2(sx2, sy2), ImVec2(sx, sy2), color);
|
||||||
drawList->AddLine(ImVec2(sx, sy2), ImVec2(sx, sy), color);
|
drawList->AddLine(ImVec2(sx, sy2), ImVec2(sx, sy), color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Texture *texture = tilemap->GetTexture().get();
|
Texture *texture = tilemap->GetTexture().get();
|
||||||
int atlasCols = tilemap->GetAtlasColumns();
|
int atlasCols = tilemap->GetAtlasColumns();
|
||||||
int atlasRows = tilemap->GetAtlasRows();
|
int atlasRows = tilemap->GetAtlasRows();
|
||||||
|
|
||||||
if (texture && texture->GetID() != 0 && atlasCols > 0 && atlasRows > 0)
|
if (texture && texture->GetID() != 0 && atlasCols > 0 && atlasRows > 0)
|
||||||
{
|
|
||||||
int x0 = tilemap->selStartX;
|
|
||||||
int y0 = tilemap->selStartY;
|
|
||||||
int x1 = tilemap->selEndX;
|
|
||||||
int y1 = tilemap->selEndY;
|
|
||||||
|
|
||||||
// Normalize
|
|
||||||
if (x1 < x0)
|
|
||||||
std::swap(x0, x1);
|
|
||||||
if (y1 < y0)
|
|
||||||
std::swap(y0, y1);
|
|
||||||
|
|
||||||
int widthInTiles = x1 - x0 + 1;
|
|
||||||
int heightInTiles = y1 - y0 + 1;
|
|
||||||
|
|
||||||
float tileW = tileSize.x;
|
|
||||||
float tileH = tileSize.y;
|
|
||||||
|
|
||||||
float snappedGX = std::floor(worldMouse.x / tileW) * tileW;
|
|
||||||
float snappedGY = std::floor(worldMouse.y / tileH) * tileH;
|
|
||||||
|
|
||||||
float sx = (snappedGX - cameraPos.x) * cameraZoom + screenCenter.x;
|
|
||||||
float sy = (snappedGY - cameraPos.y) * cameraZoom + screenCenter.y;
|
|
||||||
float sx2 = (snappedGX + tileW * widthInTiles - cameraPos.x) * cameraZoom + screenCenter.x;
|
|
||||||
float sy2 = (snappedGY + tileH * heightInTiles - cameraPos.y) * cameraZoom + screenCenter.y;
|
|
||||||
|
|
||||||
float texWidth = static_cast<float>(texture->GetSize().x);
|
|
||||||
float texHeight = static_cast<float>(texture->GetSize().y);
|
|
||||||
|
|
||||||
float uvTileW = tileW / texWidth;
|
|
||||||
float uvTileH = tileH / texHeight;
|
|
||||||
|
|
||||||
ImVec2 uvMin(x0 * uvTileW, y0 * uvTileH);
|
|
||||||
ImVec2 uvMax((x1 + 1) * uvTileW, (y1 + 1) * uvTileH);
|
|
||||||
|
|
||||||
ImTextureID previewTexID = (ImTextureID)(uintptr_t)texture->GetID();
|
|
||||||
drawList->AddImage(previewTexID, ImVec2(sx, sy), ImVec2(sx2, sy2), uvMin, uvMax, IM_COL32(255, 255, 255, 180));
|
|
||||||
|
|
||||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left))
|
|
||||||
{
|
{
|
||||||
int gx = static_cast<int>(snappedGX / tileSize.x);
|
int x0 = tilemap->selStartX;
|
||||||
int gy = static_cast<int>(snappedGY / tileSize.y);
|
int y0 = tilemap->selStartY;
|
||||||
tilemap->PlaceSelection(gx, gy);
|
int x1 = tilemap->selEndX;
|
||||||
|
int y1 = tilemap->selEndY;
|
||||||
|
|
||||||
|
// Normalize
|
||||||
|
if (x1 < x0)
|
||||||
|
std::swap(x0, x1);
|
||||||
|
if (y1 < y0)
|
||||||
|
std::swap(y0, y1);
|
||||||
|
|
||||||
|
int widthInTiles = x1 - x0 + 1;
|
||||||
|
int heightInTiles = y1 - y0 + 1;
|
||||||
|
|
||||||
|
float tileW = tileSize.x;
|
||||||
|
float tileH = tileSize.y;
|
||||||
|
|
||||||
|
float snappedGX = std::floor(worldMouse.x / tileW) * tileW;
|
||||||
|
float snappedGY = std::floor(worldMouse.y / tileH) * tileH;
|
||||||
|
|
||||||
|
float sx = (snappedGX - cameraPos.x) * cameraZoom + screenCenter.x;
|
||||||
|
float sy = (snappedGY - cameraPos.y) * cameraZoom + screenCenter.y;
|
||||||
|
float sx2 = (snappedGX + tileW * widthInTiles - cameraPos.x) * cameraZoom + screenCenter.x;
|
||||||
|
float sy2 = (snappedGY + tileH * heightInTiles - cameraPos.y) * cameraZoom + screenCenter.y;
|
||||||
|
|
||||||
|
float texWidth = static_cast<float>(texture->GetSize().x);
|
||||||
|
float texHeight = static_cast<float>(texture->GetSize().y);
|
||||||
|
|
||||||
|
float uvTileW = tileW / texWidth;
|
||||||
|
float uvTileH = tileH / texHeight;
|
||||||
|
|
||||||
|
ImVec2 uvMin(x0 * uvTileW, y0 * uvTileH);
|
||||||
|
ImVec2 uvMax((x1 + 1) * uvTileW, (y1 + 1) * uvTileH);
|
||||||
|
|
||||||
|
ImTextureID previewTexID = (ImTextureID)(uintptr_t)texture->GetID();
|
||||||
|
drawList->AddImage(previewTexID, ImVec2(sx, sy), ImVec2(sx2, sy2), uvMin, uvMax, IM_COL32(255, 255, 255, 180));
|
||||||
|
|
||||||
|
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left))
|
||||||
|
{
|
||||||
|
int gx = static_cast<int>(snappedGX / tileSize.x);
|
||||||
|
int gy = static_cast<int>(snappedGY / tileSize.y);
|
||||||
|
tilemap->PlaceSelection(gx, gy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1550,5 +1561,8 @@ void Engine::Shutdown()
|
|||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(window);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
|
||||||
|
AudioEngine::Shutdown();
|
||||||
|
|
||||||
|
|
||||||
std::filesystem::remove(tempScenePath);
|
std::filesystem::remove(tempScenePath);
|
||||||
}
|
}
|
||||||
|
81
src/src/core/audio/AudioEngine.cpp
Normal file
81
src/src/core/audio/AudioEngine.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#define MA_ENABLE_MP3
|
||||||
|
#define MA_ENABLE_WAV
|
||||||
|
#define MA_ENABLE_FLAC
|
||||||
|
#define MA_ENABLE_VORBIS
|
||||||
|
#include "AudioEngine.h"
|
||||||
|
#include "../utils/AssetManager.h"
|
||||||
|
#include "../utils/Logging.h"
|
||||||
|
|
||||||
|
ma_engine AudioEngine::s_Engine{};
|
||||||
|
std::unordered_map<uint64_t, ma_sound> AudioEngine::s_SoundMap;
|
||||||
|
|
||||||
|
bool AudioEngine::Init()
|
||||||
|
{
|
||||||
|
ma_result result = ma_engine_init(nullptr, &s_Engine);
|
||||||
|
if (result != MA_SUCCESS)
|
||||||
|
{
|
||||||
|
Logger::LogError("Failed to start AudioCore: %s", MiniaudioResultToString(result));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::LogVerbose("AudioCore initialized successfully.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AudioEngine::Shutdown()
|
||||||
|
{
|
||||||
|
for (auto& [_, sound] : s_SoundMap)
|
||||||
|
ma_sound_uninit(&sound);
|
||||||
|
s_SoundMap.clear();
|
||||||
|
ma_engine_uninit(&s_Engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioEngine::Play(uint64_t uaid, bool loop)
|
||||||
|
{
|
||||||
|
if (s_SoundMap.find(uaid) == s_SoundMap.end())
|
||||||
|
{
|
||||||
|
const auto* asset = AssetManager::GetAssetByID(uaid);
|
||||||
|
if (!asset || !asset->loaded || asset->type != AssetType::Audio)
|
||||||
|
{
|
||||||
|
Logger::LogError("[AudioEngine] Invalid or unloaded audio asset: %llu", uaid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ma_sound sound;
|
||||||
|
if (ma_sound_init_from_file(&s_Engine, asset->path.c_str(), 0, NULL, NULL, &sound) != MA_SUCCESS)
|
||||||
|
{
|
||||||
|
Logger::LogError("[AudioEngine] Failed to initialize sound from: %s", asset->path.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_SoundMap[uaid] = sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& sound = s_SoundMap[uaid];
|
||||||
|
ma_sound_set_looping(&sound, loop);
|
||||||
|
ma_sound_start(&sound);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioEngine::Stop(uint64_t uaid)
|
||||||
|
{
|
||||||
|
auto it = s_SoundMap.find(uaid);
|
||||||
|
if (it != s_SoundMap.end())
|
||||||
|
ma_sound_stop(&it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioEngine::StopAll()
|
||||||
|
{
|
||||||
|
for (auto& [_, sound] : s_SoundMap)
|
||||||
|
ma_sound_stop(&sound);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioEngine::Unload(uint64_t uaid)
|
||||||
|
{
|
||||||
|
auto it = s_SoundMap.find(uaid);
|
||||||
|
if (it != s_SoundMap.end())
|
||||||
|
{
|
||||||
|
ma_sound_uninit(&it->second);
|
||||||
|
s_SoundMap.erase(it);
|
||||||
|
}
|
||||||
|
}
|
23
src/src/core/audio/AudioEngine.h
Normal file
23
src/src/core/audio/AudioEngine.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string>
|
||||||
|
#include "miniaudio.h"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class AudioEngine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool Init();
|
||||||
|
static void Shutdown();
|
||||||
|
|
||||||
|
static void Play(uint64_t uaid, bool loop = false);
|
||||||
|
static void Stop(uint64_t uaid);
|
||||||
|
static void StopAll();
|
||||||
|
static void Unload(uint64_t uaid);
|
||||||
|
|
||||||
|
static ma_engine* GetEngine() { return &s_Engine; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static ma_engine s_Engine;
|
||||||
|
static std::unordered_map<uint64_t, ma_sound> s_SoundMap;
|
||||||
|
};
|
@ -1,81 +1,178 @@
|
|||||||
// AssetManager.cpp
|
|
||||||
#include "AssetManager.h"
|
#include "AssetManager.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include <GL/glew.h>
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include "../audio/AudioEngine.h"
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
#include <future>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
// Static definitions
|
#define MINIAUDIO_IMPLEMENTATION
|
||||||
std::unordered_map<uint64_t, AssetInfo> AssetManager::s_Assets;
|
#define MA_ENABLE_MP3
|
||||||
|
#define MA_ENABLE_WAV
|
||||||
|
#define MA_ENABLE_FLAC
|
||||||
|
#define MA_ENABLE_VORBIS
|
||||||
|
#include "miniaudio.h"
|
||||||
|
|
||||||
|
std::unordered_map<uint64_t, std::shared_ptr<AssetInfo>> AssetManager::s_Assets;
|
||||||
std::unordered_map<std::string, uint64_t> AssetManager::s_PathToUAID;
|
std::unordered_map<std::string, uint64_t> AssetManager::s_PathToUAID;
|
||||||
uint64_t AssetManager::s_NextUAID = 1;
|
uint64_t AssetManager::s_NextUAID = 1;
|
||||||
|
|
||||||
void AssetManager::Init() {}
|
|
||||||
|
const char* MiniaudioResultToString(ma_result result)
|
||||||
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case MA_SUCCESS: return "Success";
|
||||||
|
case MA_ERROR: return "Generic error";
|
||||||
|
case MA_INVALID_ARGS: return "Invalid arguments";
|
||||||
|
case MA_INVALID_OPERATION: return "Invalid operation";
|
||||||
|
case MA_OUT_OF_MEMORY: return "Out of memory";
|
||||||
|
case MA_OUT_OF_RANGE: return "Out of range";
|
||||||
|
case MA_ACCESS_DENIED: return "Access denied";
|
||||||
|
case MA_DOES_NOT_EXIST: return "File does not exist";
|
||||||
|
case MA_ALREADY_EXISTS: return "File already exists";
|
||||||
|
case MA_TOO_MANY_OPEN_FILES: return "Too many open files";
|
||||||
|
case MA_INVALID_FILE: return "Invalid or corrupted file";
|
||||||
|
case MA_TOO_BIG: return "File too big";
|
||||||
|
case MA_PATH_TOO_LONG: return "Path too long";
|
||||||
|
case MA_NAME_TOO_LONG: return "Name too long";
|
||||||
|
case MA_NOT_DIRECTORY: return "Not a directory";
|
||||||
|
case MA_IS_DIRECTORY: return "Is a directory";
|
||||||
|
case MA_DIRECTORY_NOT_EMPTY: return "Directory not empty";
|
||||||
|
case MA_AT_END: return "End of file or stream";
|
||||||
|
case MA_NO_SPACE: return "No space left on device";
|
||||||
|
case MA_BUSY: return "Resource busy";
|
||||||
|
case MA_IO_ERROR: return "I/O error";
|
||||||
|
case MA_INTERRUPT: return "Operation interrupted";
|
||||||
|
case MA_UNAVAILABLE: return "Resource unavailable";
|
||||||
|
case MA_ALREADY_IN_USE: return "Already in use";
|
||||||
|
case MA_BAD_ADDRESS: return "Bad memory address";
|
||||||
|
case MA_BAD_SEEK: return "Bad seek operation";
|
||||||
|
case MA_BAD_PIPE: return "Bad pipe";
|
||||||
|
case MA_DEADLOCK: return "Deadlock detected";
|
||||||
|
case MA_TOO_MANY_LINKS: return "Too many symbolic links";
|
||||||
|
case MA_NOT_IMPLEMENTED: return "Not implemented";
|
||||||
|
case MA_NO_MESSAGE: return "No message available";
|
||||||
|
case MA_BAD_MESSAGE: return "Bad message format";
|
||||||
|
case MA_NO_DATA_AVAILABLE: return "No data available";
|
||||||
|
case MA_INVALID_DATA: return "Invalid data";
|
||||||
|
case MA_TIMEOUT: return "Operation timed out";
|
||||||
|
case MA_NO_NETWORK: return "Network unavailable";
|
||||||
|
case MA_NOT_UNIQUE: return "Not unique";
|
||||||
|
case MA_NOT_SOCKET: return "Not a socket";
|
||||||
|
case MA_NO_ADDRESS: return "No address available";
|
||||||
|
case MA_BAD_PROTOCOL: return "Bad protocol";
|
||||||
|
case MA_PROTOCOL_UNAVAILABLE: return "Protocol unavailable";
|
||||||
|
case MA_PROTOCOL_NOT_SUPPORTED: return "Protocol not supported";
|
||||||
|
case MA_PROTOCOL_FAMILY_NOT_SUPPORTED: return "Protocol family not supported";
|
||||||
|
case MA_ADDRESS_FAMILY_NOT_SUPPORTED: return "Address family not supported";
|
||||||
|
case MA_SOCKET_NOT_SUPPORTED: return "Socket not supported";
|
||||||
|
case MA_CONNECTION_RESET: return "Connection reset";
|
||||||
|
case MA_ALREADY_CONNECTED: return "Already connected";
|
||||||
|
case MA_NOT_CONNECTED: return "Not connected";
|
||||||
|
case MA_CONNECTION_REFUSED: return "Connection refused";
|
||||||
|
case MA_NO_HOST: return "Host not found";
|
||||||
|
case MA_IN_PROGRESS: return "Operation in progress";
|
||||||
|
case MA_CANCELLED: return "Operation cancelled";
|
||||||
|
case MA_MEMORY_ALREADY_MAPPED: return "Memory already mapped";
|
||||||
|
|
||||||
|
case MA_CRC_MISMATCH: return "CRC mismatch";
|
||||||
|
|
||||||
|
case MA_FORMAT_NOT_SUPPORTED: return "Audio format not supported";
|
||||||
|
case MA_DEVICE_TYPE_NOT_SUPPORTED: return "Device type not supported";
|
||||||
|
case MA_SHARE_MODE_NOT_SUPPORTED: return "Share mode not supported";
|
||||||
|
case MA_NO_BACKEND: return "No backend available";
|
||||||
|
case MA_NO_DEVICE: return "No device available";
|
||||||
|
case MA_API_NOT_FOUND: return "API not found";
|
||||||
|
case MA_INVALID_DEVICE_CONFIG: return "Invalid device configuration";
|
||||||
|
case MA_LOOP: return "Loop detected";
|
||||||
|
case MA_BACKEND_NOT_ENABLED: return "Backend not enabled";
|
||||||
|
|
||||||
|
case MA_DEVICE_NOT_INITIALIZED: return "Device not initialized";
|
||||||
|
case MA_DEVICE_ALREADY_INITIALIZED: return "Device already initialized";
|
||||||
|
case MA_DEVICE_NOT_STARTED: return "Device not started";
|
||||||
|
case MA_DEVICE_NOT_STOPPED: return "Device not stopped";
|
||||||
|
|
||||||
|
case MA_FAILED_TO_INIT_BACKEND: return "Failed to initialize backend";
|
||||||
|
case MA_FAILED_TO_OPEN_BACKEND_DEVICE: return "Failed to open backend device";
|
||||||
|
case MA_FAILED_TO_START_BACKEND_DEVICE: return "Failed to start backend device";
|
||||||
|
case MA_FAILED_TO_STOP_BACKEND_DEVICE: return "Failed to stop backend device";
|
||||||
|
|
||||||
|
default: return "Unknown error code";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AssetManager::Init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t AssetManager::GenerateUAID()
|
uint64_t AssetManager::GenerateUAID()
|
||||||
{
|
{
|
||||||
|
|
||||||
return s_NextUAID++;
|
return s_NextUAID++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetManager::LoadAssetAsync(const std::string &path, AssetType type)
|
void AssetManager::LoadAssetAsync(const std::string& path, AssetType type)
|
||||||
{
|
{
|
||||||
|
if (auto itPath = s_PathToUAID.find(path); itPath != s_PathToUAID.end() && s_Assets[itPath->second]->loaded)
|
||||||
{
|
{
|
||||||
|
Logger::LogVerbose("[AssetManager] Skipping already-loaded asset: %s (UAID: %llu)", path.c_str(), itPath->second);
|
||||||
auto itPath = s_PathToUAID.find(path);
|
return;
|
||||||
if (itPath != s_PathToUAID.end() && s_Assets[itPath->second].loaded)
|
|
||||||
{
|
|
||||||
Logger::LogVerbose("[AssetManager] Skipping already-loaded image: %s (UAID: %llu)", path.c_str(), itPath->second);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t uaid = GenerateUAID();
|
uint64_t uaid = GenerateUAID();
|
||||||
{
|
std::shared_ptr<AssetInfo> asset;
|
||||||
AssetInfo info;
|
|
||||||
info.uaid = uaid;
|
|
||||||
info.path = path;
|
|
||||||
info.filename = GetFilenameFromPath(path);
|
|
||||||
info.filetype = ::GetFileExtension(path);
|
|
||||||
info.type = type;
|
|
||||||
|
|
||||||
s_Assets[uaid] = info;
|
|
||||||
s_PathToUAID[path] = uaid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == AssetType::Image)
|
if (type == AssetType::Image)
|
||||||
{
|
asset = std::make_shared<ImageAssetInfo>();
|
||||||
Logger::LogVerbose("[AssetManager] Scheduling load: %s (UAID: %llu)", path.c_str(), uaid);
|
else if (type == AssetType::Audio)
|
||||||
AssetManager::LoadImageInternal(path, uaid);
|
asset = std::make_shared<AudioAssetInfo>();
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger::LogWarning("[AssetManager] Unknown Asset Type: '%d'", static_cast<int>(type));
|
Logger::LogWarning("[AssetManager] Unknown Asset Type: '%d'", static_cast<int>(type));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asset->uaid = uaid;
|
||||||
|
asset->path = path;
|
||||||
|
asset->filename = GetFilenameFromPath(path);
|
||||||
|
asset->filetype = ::GetFileExtension(path);
|
||||||
|
asset->type = type;
|
||||||
|
s_Assets[uaid] = asset;
|
||||||
|
s_PathToUAID[path] = uaid;
|
||||||
|
|
||||||
|
if (type == AssetType::Image)
|
||||||
|
LoadImageInternal(path, uaid);
|
||||||
|
else if (type == AssetType::Audio)
|
||||||
|
LoadAudioInternal(path, uaid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetManager::LoadImageInternal(const std::string &path, uint64_t uaid)
|
void AssetManager::LoadImageInternal(const std::string& path, uint64_t uaid)
|
||||||
{
|
{
|
||||||
{
|
auto it = s_Assets.find(uaid);
|
||||||
auto it = s_Assets.find(uaid);
|
if (it == s_Assets.end())
|
||||||
if (it != s_Assets.end() && it->second.loaded)
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
auto itPath = s_PathToUAID.find(path);
|
auto image = std::dynamic_pointer_cast<ImageAssetInfo>(it->second);
|
||||||
if (itPath != s_PathToUAID.end() && s_Assets[itPath->second].loaded)
|
if (!image)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
Logger::LogVerbose("[AssetManager] Begin loading image: %s (UAID: %llu)", path.c_str(), uaid);
|
|
||||||
stbi_set_flip_vertically_on_load(false);
|
stbi_set_flip_vertically_on_load(false);
|
||||||
|
|
||||||
|
std::ifstream file(path, std::ios::binary);
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
Logger::LogError("[AssetManager] Failed to open image file: %s", path.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> fileData((std::istreambuf_iterator<char>(file)), {});
|
||||||
int w, h, channels;
|
int w, h, channels;
|
||||||
stbi_uc *pixels = stbi_load(path.c_str(), &w, &h, &channels, STBI_rgb_alpha);
|
stbi_uc* pixels = stbi_load_from_memory(fileData.data(), static_cast<int>(fileData.size()), &w, &h, &channels, STBI_rgb_alpha);
|
||||||
|
|
||||||
if (!pixels)
|
if (!pixels)
|
||||||
{
|
{
|
||||||
Logger::LogError("[AssetManager] Failed to load image: %s", path.c_str());
|
Logger::LogError("[AssetManager] Failed to decode image: %s", path.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,125 +189,171 @@ void AssetManager::LoadImageInternal(const std::string &path, uint64_t uaid)
|
|||||||
|
|
||||||
if (texID == 0)
|
if (texID == 0)
|
||||||
{
|
{
|
||||||
Logger::LogError("[AssetManager] Failed to Load asset.");
|
Logger::LogError("[AssetManager] Failed to create GL texture.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &asset = s_Assets[uaid];
|
image->size = {static_cast<float>(w), static_cast<float>(h)};
|
||||||
asset.size = {static_cast<float>(w), static_cast<float>(h)};
|
image->textureID = texID;
|
||||||
asset.textureID = texID;
|
image->channels = channels;
|
||||||
asset.loaded = true;
|
image->format = "GL_RGBA";
|
||||||
asset.channels = channels;
|
image->loaded = true;
|
||||||
asset.format = "GL_RGBA";
|
image->lastModified = GetFileLastWrite(path);
|
||||||
asset.lastModified = GetFileLastWrite(path);
|
image->hash = GetFileHash(path);
|
||||||
asset.hash = GetFileHash(path);
|
|
||||||
|
|
||||||
Logger::LogVerbose("[AssetManager] Finished loading image: %s (%dx%d) (UAID: %llu, Texture ID: %u)", path.c_str(), w, h, uaid, texID);
|
Logger::LogVerbose("[AssetManager] Loaded image: %s (%dx%d)", path.c_str(), w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
const AssetInfo *AssetManager::GetAssetByID(uint64_t uaid)
|
void AssetManager::LoadAudioInternal(const std::string& path, uint64_t uaid)
|
||||||
{
|
{
|
||||||
|
|
||||||
auto it = s_Assets.find(uaid);
|
auto it = s_Assets.find(uaid);
|
||||||
return it != s_Assets.end() ? &it->second : nullptr;
|
if (it == s_Assets.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto audio = std::dynamic_pointer_cast<AudioAssetInfo>(it->second);
|
||||||
|
if (!audio)
|
||||||
|
return;
|
||||||
|
|
||||||
|
audio->sound = new ma_sound();
|
||||||
|
ma_result result = ma_sound_init_from_file(AudioEngine::GetEngine(), path.c_str(), 0, nullptr, nullptr, audio->sound);
|
||||||
|
|
||||||
|
if (result != MA_SUCCESS)
|
||||||
|
{
|
||||||
|
Logger::LogError("[AssetManager] Failed to load audio file: %s (Reason: %s)", path.c_str(), MiniaudioResultToString(result));
|
||||||
|
|
||||||
|
delete audio->sound;
|
||||||
|
audio->sound = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio->loaded = true;
|
||||||
|
audio->lastModified = GetFileLastWrite(path);
|
||||||
|
audio->hash = GetFileHash(path);
|
||||||
|
|
||||||
|
Logger::LogVerbose("[AssetManager] Loaded audio: %s", path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
const AssetInfo *AssetManager::GetAssetByPath(const std::string &path)
|
|
||||||
|
|
||||||
|
|
||||||
|
const AssetInfo* AssetManager::GetAssetByID(uint64_t uaid)
|
||||||
{
|
{
|
||||||
|
auto it = s_Assets.find(uaid);
|
||||||
auto it = s_PathToUAID.find(path);
|
return it != s_Assets.end() ? it->second.get() : nullptr;
|
||||||
return it != s_PathToUAID.end() ? &s_Assets[it->second] : nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::unordered_map<uint64_t, AssetInfo> &AssetManager::GetAllAssets()
|
const AssetInfo* AssetManager::GetAssetByPath(const std::string& path)
|
||||||
|
{
|
||||||
|
auto it = s_PathToUAID.find(path);
|
||||||
|
return it != s_PathToUAID.end() ? s_Assets[it->second].get() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::unordered_map<uint64_t, std::shared_ptr<AssetInfo>>& AssetManager::GetAllAssets()
|
||||||
{
|
{
|
||||||
return s_Assets;
|
return s_Assets;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetManager::UnloadAsset(uint64_t uaid)
|
void AssetManager::UnloadAsset(uint64_t uaid)
|
||||||
{
|
{
|
||||||
|
|
||||||
auto it = s_Assets.find(uaid);
|
auto it = s_Assets.find(uaid);
|
||||||
if (it != s_Assets.end())
|
if (it != s_Assets.end())
|
||||||
{
|
{
|
||||||
if (it->second.textureID)
|
if (auto img = std::dynamic_pointer_cast<ImageAssetInfo>(it->second); img && img->textureID)
|
||||||
glDeleteTextures(1, &it->second.textureID);
|
glDeleteTextures(1, &img->textureID);
|
||||||
s_PathToUAID.erase(it->second.path);
|
if (auto audio = std::dynamic_pointer_cast<AudioAssetInfo>(it->second); audio && audio->sound)
|
||||||
|
{
|
||||||
|
ma_sound_uninit(audio->sound);
|
||||||
|
delete audio->sound;
|
||||||
|
}
|
||||||
|
s_PathToUAID.erase(it->second->path);
|
||||||
s_Assets.erase(it);
|
s_Assets.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetManager::ClearAllAssets()
|
void AssetManager::ClearAllAssets()
|
||||||
{
|
{
|
||||||
|
for (auto& [id, asset] : s_Assets)
|
||||||
|
UnloadAsset(id);
|
||||||
|
|
||||||
for (auto &kv : s_Assets)
|
|
||||||
if (kv.second.textureID)
|
|
||||||
glDeleteTextures(1, &kv.second.textureID);
|
|
||||||
s_Assets.clear();
|
s_Assets.clear();
|
||||||
s_PathToUAID.clear();
|
s_PathToUAID.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetManager::Save(YAML::Emitter &out)
|
void AssetManager::Save(YAML::Emitter& out)
|
||||||
{
|
{
|
||||||
out << YAML::Key << "Assets" << YAML::BeginSeq;
|
out << YAML::Key << "Assets" << YAML::BeginSeq;
|
||||||
for (const auto &kv : s_Assets)
|
for (const auto& [uaid, asset] : s_Assets)
|
||||||
{
|
{
|
||||||
const auto &a = kv.second;
|
out << YAML::BeginMap;
|
||||||
out << YAML::BeginMap
|
out << YAML::Key << "uaid" << YAML::Value << asset->uaid;
|
||||||
<< YAML::Key << "uaid" << YAML::Value << a.uaid
|
out << YAML::Key << "path" << YAML::Value << asset->path;
|
||||||
<< YAML::Key << "path" << YAML::Value << a.path
|
out << YAML::Key << "filename" << YAML::Value << asset->filename;
|
||||||
<< YAML::Key << "filename" << YAML::Value << a.filename
|
out << YAML::Key << "filetype" << YAML::Value << asset->filetype;
|
||||||
<< YAML::Key << "filetype" << YAML::Value << a.filetype
|
out << YAML::Key << "type" << YAML::Value << static_cast<int>(asset->type);
|
||||||
<< YAML::Key << "type" << YAML::Value << static_cast<int>(a.type)
|
out << YAML::Key << "hash" << YAML::Value << asset->hash;
|
||||||
<< YAML::Key << "size" << YAML::Value << YAML::Flow << YAML::BeginSeq << a.size.x << a.size.y << YAML::EndSeq
|
out << YAML::Key << "lastModified" << YAML::Value << asset->lastModified;
|
||||||
<< YAML::Key << "hash" << YAML::Value << a.hash
|
asset->Save(out);
|
||||||
<< YAML::Key << "channels" << YAML::Value << a.channels
|
out << YAML::EndMap;
|
||||||
<< YAML::Key << "format" << YAML::Value << a.format
|
|
||||||
<< YAML::Key << "lastModified" << YAML::Value << a.lastModified
|
|
||||||
<< YAML::EndMap;
|
|
||||||
}
|
}
|
||||||
out << YAML::EndSeq;
|
out << YAML::EndSeq;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetManager::Load(const YAML::Node &node)
|
void AssetManager::Load(const YAML::Node& node)
|
||||||
{
|
{
|
||||||
if (!node)
|
if (!node)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (const auto &item : node)
|
for (const auto& item : node)
|
||||||
{
|
{
|
||||||
uint64_t uaid = item["uaid"].as<uint64_t>();
|
uint64_t uaid = item["uaid"].as<uint64_t>();
|
||||||
std::string path = item["path"].as<std::string>();
|
std::string path = item["path"].as<std::string>();
|
||||||
AssetType type = static_cast<AssetType>(item["type"].as<int>());
|
AssetType type = static_cast<AssetType>(item["type"].as<int>());
|
||||||
float sx = item["size"][0].as<float>();
|
|
||||||
float sy = item["size"][1].as<float>();
|
|
||||||
|
|
||||||
AssetInfo asset;
|
std::shared_ptr<AssetInfo> asset;
|
||||||
asset.uaid = uaid;
|
if (type == AssetType::Image)
|
||||||
asset.path = path;
|
asset = std::make_shared<ImageAssetInfo>();
|
||||||
asset.filename = item["filename"] ? item["filename"].as<std::string>() : GetFilenameFromPath(path);
|
else if (type == AssetType::Audio)
|
||||||
asset.filetype = item["filetype"] ? item["filetype"].as<std::string>() : ::GetFileExtension(path);
|
asset = std::make_shared<AudioAssetInfo>();
|
||||||
asset.type = type;
|
else
|
||||||
asset.size = {sx, sy};
|
continue;
|
||||||
asset.hash = item["hash"] ? item["hash"].as<std::string>() : "";
|
|
||||||
asset.channels = item["channels"] ? item["channels"].as<int>() : 4;
|
asset->uaid = uaid;
|
||||||
asset.format = item["format"] ? item["format"].as<std::string>() : "GL_RGBA";
|
asset->path = path;
|
||||||
asset.lastModified = item["lastModified"] ? item["lastModified"].as<std::time_t>() : 0;
|
asset->filename = item["filename"] ? item["filename"].as<std::string>() : GetFilenameFromPath(path);
|
||||||
asset.loaded = false;
|
asset->filetype = item["filetype"] ? item["filetype"].as<std::string>() : GetFileExtension(path);
|
||||||
asset.textureID = 0;
|
asset->hash = item["hash"] ? item["hash"].as<std::string>() : "";
|
||||||
|
asset->lastModified = item["lastModified"] ? item["lastModified"].as<std::time_t>() : 0;
|
||||||
|
asset->loaded = false;
|
||||||
|
|
||||||
|
asset->Load(item);
|
||||||
|
|
||||||
s_Assets[uaid] = asset;
|
s_Assets[uaid] = asset;
|
||||||
s_PathToUAID[path] = uaid;
|
s_PathToUAID[path] = uaid;
|
||||||
|
|
||||||
if (uaid >= s_NextUAID)
|
if (uaid >= s_NextUAID)
|
||||||
s_NextUAID = uaid + 1;
|
s_NextUAID = uaid + 1;
|
||||||
|
|
||||||
if (type == AssetType::Image)
|
|
||||||
{
|
|
||||||
Logger::LogVerbose("[AssetManager] Reloading from file: %s (UAID: %llu)", path.c_str(), uaid);
|
|
||||||
LoadImageInternal(path, uaid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ImageAssetInfo::Save(YAML::Emitter& out) const
|
||||||
|
{
|
||||||
|
out << YAML::Key << "size" << YAML::Value << YAML::Flow << YAML::BeginSeq << size.x << size.y << YAML::EndSeq;
|
||||||
|
out << YAML::Key << "channels" << YAML::Value << channels;
|
||||||
|
out << YAML::Key << "format" << YAML::Value << format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageAssetInfo::Load(const YAML::Node& node)
|
||||||
|
{
|
||||||
|
if (node["size"])
|
||||||
|
{
|
||||||
|
size.x = node["size"][0].as<float>();
|
||||||
|
size.y = node["size"][1].as<float>();
|
||||||
|
}
|
||||||
|
channels = node["channels"] ? node["channels"].as<int>() : 4;
|
||||||
|
format = node["format"] ? node["format"].as<std::string>() : "GL_RGBA";
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioAssetInfo::Save(YAML::Emitter& out) const {}
|
||||||
|
void AudioAssetInfo::Load(const YAML::Node& node) {}
|
||||||
|
|
||||||
|
@ -1,35 +1,59 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <mutex>
|
#include <memory>
|
||||||
#include <vector>
|
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <yaml-cpp/yaml.h>
|
#include <yaml-cpp/yaml.h>
|
||||||
#include "../types/vec2.h"
|
#include "../types/vec2.h"
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
#include "miniaudio.h"
|
||||||
|
|
||||||
enum class AssetType { Image, Audio };
|
enum class AssetType { Image, Audio };
|
||||||
|
|
||||||
struct AssetInfo
|
struct AssetInfo
|
||||||
{
|
{
|
||||||
uint64_t uaid;
|
uint64_t uaid = 0;
|
||||||
std::string path;
|
std::string path;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
std::string filetype;
|
std::string filetype;
|
||||||
AssetType type;
|
AssetType type = AssetType::Image;
|
||||||
core::types::Vec2 size;
|
|
||||||
|
|
||||||
std::string hash;
|
std::string hash;
|
||||||
int channels = 4;
|
|
||||||
std::string format;
|
|
||||||
std::time_t lastModified = 0;
|
std::time_t lastModified = 0;
|
||||||
|
|
||||||
|
|
||||||
bool loaded = false;
|
bool loaded = false;
|
||||||
GLuint textureID = 0;
|
|
||||||
|
virtual ~AssetInfo() = default;
|
||||||
|
|
||||||
|
virtual void Save(YAML::Emitter& out) const = 0;
|
||||||
|
virtual void Load(const YAML::Node& node) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ImageAssetInfo : public AssetInfo
|
||||||
|
{
|
||||||
|
core::types::Vec2 size = {0, 0};
|
||||||
|
int channels = 4;
|
||||||
|
std::string format = "GL_RGBA";
|
||||||
|
GLuint textureID = 0;
|
||||||
|
|
||||||
|
ImageAssetInfo() { type = AssetType::Image; }
|
||||||
|
|
||||||
|
void Save(YAML::Emitter& out) const override;
|
||||||
|
void Load(const YAML::Node& node) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AudioAssetInfo : public AssetInfo
|
||||||
|
{
|
||||||
|
ma_sound* sound = nullptr;
|
||||||
|
|
||||||
|
AudioAssetInfo() { type = AssetType::Audio; }
|
||||||
|
|
||||||
|
void Save(YAML::Emitter& out) const override;
|
||||||
|
void Load(const YAML::Node& node) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* MiniaudioResultToString(ma_result result);
|
||||||
|
|
||||||
|
|
||||||
class AssetManager
|
class AssetManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -37,20 +61,18 @@ public:
|
|||||||
static void LoadAssetAsync(const std::string& path, AssetType type);
|
static void LoadAssetAsync(const std::string& path, AssetType type);
|
||||||
static const AssetInfo* GetAssetByID(uint64_t uaid);
|
static const AssetInfo* GetAssetByID(uint64_t uaid);
|
||||||
static const AssetInfo* GetAssetByPath(const std::string& path);
|
static const AssetInfo* GetAssetByPath(const std::string& path);
|
||||||
static const std::unordered_map<uint64_t, AssetInfo>& GetAllAssets();
|
static const std::unordered_map<uint64_t, std::shared_ptr<AssetInfo>>& GetAllAssets();
|
||||||
|
|
||||||
static void UnloadAsset(uint64_t uaid);
|
static void UnloadAsset(uint64_t uaid);
|
||||||
static void ClearAllAssets();
|
static void ClearAllAssets();
|
||||||
|
|
||||||
static void Save(YAML::Emitter& out);
|
static void Save(YAML::Emitter& out);
|
||||||
static void Load(const YAML::Node& node);
|
static void Load(const YAML::Node& node);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::unordered_map<uint64_t, AssetInfo> s_Assets;
|
static std::unordered_map<uint64_t, std::shared_ptr<AssetInfo>> s_Assets;
|
||||||
static std::unordered_map<std::string, uint64_t> s_PathToUAID;
|
static std::unordered_map<std::string, uint64_t> s_PathToUAID;
|
||||||
static uint64_t s_NextUAID;
|
static uint64_t s_NextUAID;
|
||||||
|
|
||||||
static uint64_t GenerateUAID();
|
static uint64_t GenerateUAID();
|
||||||
static void LoadImageInternal(const std::string& path, uint64_t uaid);
|
static void LoadImageInternal(const std::string& path, uint64_t uaid);
|
||||||
|
static void LoadAudioInternal(const std::string& path, uint64_t uaid);
|
||||||
};
|
};
|
||||||
|
@ -2,16 +2,23 @@
|
|||||||
#include "AssetManager.h"
|
#include "AssetManager.h"
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
|
|
||||||
Texture::Texture(const std::string &path)
|
Texture::Texture(const std::string& path)
|
||||||
{
|
{
|
||||||
if (!path.empty())
|
if (!path.empty())
|
||||||
{
|
{
|
||||||
AssetManager::LoadAssetAsync(path, AssetType::Image);
|
AssetManager::LoadAssetAsync(path, AssetType::Image);
|
||||||
const auto *asset = AssetManager::GetAssetByPath(path);
|
const auto* asset = AssetManager::GetAssetByPath(path);
|
||||||
if (asset && asset->loaded)
|
if (asset && asset->loaded)
|
||||||
{
|
{
|
||||||
id = asset->textureID;
|
if (const auto* imageAsset = dynamic_cast<const ImageAssetInfo*>(asset))
|
||||||
size = asset->size;
|
{
|
||||||
|
id = imageAsset->textureID;
|
||||||
|
size = imageAsset->size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::LogError("[Texture] Asset at path '%s' is not an image!", path.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -20,15 +27,20 @@ Texture::Texture(const std::string &path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Texture::Texture(uint64_t uaid)
|
Texture::Texture(uint64_t uaid)
|
||||||
{
|
{
|
||||||
const auto *asset = AssetManager::GetAssetByID(uaid);
|
const auto* asset = AssetManager::GetAssetByID(uaid);
|
||||||
if (asset && asset->loaded)
|
if (asset && asset->loaded)
|
||||||
{
|
{
|
||||||
id = asset->textureID;
|
if (const auto* imageAsset = dynamic_cast<const ImageAssetInfo*>(asset))
|
||||||
size = asset->size;
|
{
|
||||||
|
id = imageAsset->textureID;
|
||||||
|
size = imageAsset->size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::LogError("[Texture] Asset with UAID '%llu' is not an image!", uaid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -25,41 +25,20 @@ std::unordered_map<std::string, ImageCacheEntry> engineTextureCache;
|
|||||||
|
|
||||||
ImageCacheEntry LoadImageCache(const std::string& path)
|
ImageCacheEntry LoadImageCache(const std::string& path)
|
||||||
{
|
{
|
||||||
auto [it, inserted] = textureCache.try_emplace(path, ImageCacheEntry{});
|
Logger::LogWarning(
|
||||||
|
"[LoadImageCache] This function is **deprecated**.\n"
|
||||||
|
"Please use one of the following AssetManager functions instead:\n"
|
||||||
|
" - AssetManager::LoadAssetAsync(path, AssetType::Image)\n"
|
||||||
|
" - AssetManager::GetAssetByID(uaid)\n"
|
||||||
|
" - AssetManager::GetAssetByPath(path)\n"
|
||||||
|
);
|
||||||
|
|
||||||
if (!inserted)
|
return ImageCacheEntry{};
|
||||||
{
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
int w, h, channels;
|
|
||||||
stbi_set_flip_vertically_on_load(false);
|
|
||||||
unsigned char* data = stbi_load(path.c_str(), &w, &h, &channels, 4);
|
|
||||||
if (!data)
|
|
||||||
{
|
|
||||||
Logger::LogError("Failed to load image: '%s'", path.c_str());
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint id;
|
|
||||||
glGenTextures(1, &id);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
stbi_image_free(data);
|
|
||||||
|
|
||||||
glm::vec2 imageSize(w, h);
|
|
||||||
ImageCacheEntry entry{ id, imageSize };
|
|
||||||
it->second = entry;
|
|
||||||
|
|
||||||
Logger::LogVerbose("Loaded Image: (%d, %d) '%s'",w,h, path.c_str());
|
|
||||||
Logger::LogWarning("Loaded Image Via Depricated Function: '%s'", path.c_str());
|
|
||||||
return entry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GLuint LoadTextureIfNeeded(const std::string &path)
|
GLuint LoadTextureIfNeeded(const std::string &path)
|
||||||
{
|
{
|
||||||
auto [it, inserted] = textureCache.try_emplace(path, ImageCacheEntry{});
|
auto [it, inserted] = textureCache.try_emplace(path, ImageCacheEntry{});
|
||||||
|
@ -17,13 +17,20 @@ void ShowAssetBrowser()
|
|||||||
|
|
||||||
ImGui::Begin("Asset Browser");
|
ImGui::Begin("Asset Browser");
|
||||||
|
|
||||||
if (ImGui::Button("Load Asset"))
|
if (ImGui::Button("Load Image"))
|
||||||
{
|
{
|
||||||
std::string path = OpenFileDialog(FileDialogType::Images);
|
std::string path = OpenFileDialog(FileDialogType::Images);
|
||||||
if (!path.empty())
|
if (!path.empty())
|
||||||
{
|
|
||||||
AssetManager::LoadAssetAsync(path, AssetType::Image);
|
AssetManager::LoadAssetAsync(path, AssetType::Image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
if (ImGui::Button("Load Audio"))
|
||||||
|
{
|
||||||
|
std::string path = OpenFileDialog(FileDialogType::Audio);
|
||||||
|
if (!path.empty())
|
||||||
|
AssetManager::LoadAssetAsync(path, AssetType::Audio);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
@ -50,42 +57,82 @@ void ShowAssetBrowser()
|
|||||||
ImGui::Columns(columns, nullptr, false);
|
ImGui::Columns(columns, nullptr, false);
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (const auto &[uaid, asset] : AssetManager::GetAllAssets())
|
for (const auto &[uaid, baseAsset] : AssetManager::GetAllAssets())
|
||||||
{
|
{
|
||||||
if (asset.type != AssetType::Image || !asset.loaded)
|
if (!baseAsset || !baseAsset->loaded)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!assetSearchQuery.empty() &&
|
if (!assetSearchQuery.empty() &&
|
||||||
asset.filename.find(assetSearchQuery) == std::string::npos &&
|
baseAsset->filename.find(assetSearchQuery) == std::string::npos &&
|
||||||
asset.path.find(assetSearchQuery) == std::string::npos)
|
baseAsset->path.find(assetSearchQuery) == std::string::npos)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::PushID(idx++);
|
ImGui::PushID(idx++);
|
||||||
std::string displayName = GetFilenameFromPath(asset.path);
|
std::string displayName = GetFilenameFromPath(baseAsset->path);
|
||||||
|
|
||||||
ImGui::Image((ImTextureID)(intptr_t)asset.textureID,
|
if (baseAsset->type == AssetType::Image)
|
||||||
ImVec2(thumbnailSize, thumbnailSize));
|
|
||||||
|
|
||||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID))
|
|
||||||
{
|
{
|
||||||
ImGui::SetDragDropPayload("ASSET_TEXTURE", &uaid, sizeof(uint64_t));
|
const auto *imageAsset = dynamic_cast<const ImageAssetInfo *>(baseAsset.get());
|
||||||
|
if (!imageAsset)
|
||||||
|
{
|
||||||
|
ImGui::PopID();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Image((ImTextureID)(intptr_t)asset.textureID,
|
ImGui::Image((ImTextureID)(intptr_t)imageAsset->textureID,
|
||||||
ImVec2(thumbnailSize * 2, thumbnailSize * 2));
|
ImVec2(thumbnailSize, thumbnailSize));
|
||||||
ImGui::Text("%s", displayName.c_str());
|
|
||||||
|
|
||||||
ImGui::EndDragDropSource();
|
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID))
|
||||||
|
{
|
||||||
|
ImGui::SetDragDropPayload("ASSET_TEXTURE", &uaid, sizeof(uint64_t));
|
||||||
|
ImGui::Image((ImTextureID)(intptr_t)imageAsset->textureID,
|
||||||
|
ImVec2(thumbnailSize * 2, thumbnailSize * 2));
|
||||||
|
ImGui::Text("%s", displayName.c_str());
|
||||||
|
ImGui::EndDragDropSource();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (baseAsset->type == AssetType::Audio)
|
||||||
|
{
|
||||||
|
std::string buttonLabel = baseAsset->filetype.empty() ? "Audio" : (baseAsset->filetype);
|
||||||
|
|
||||||
|
ImGui::Button(buttonLabel.c_str(), ImVec2(thumbnailSize, thumbnailSize));
|
||||||
|
|
||||||
|
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID))
|
||||||
|
{
|
||||||
|
ImGui::SetDragDropPayload("ASSET_AUDIO", &uaid, sizeof(uint64_t));
|
||||||
|
ImGui::Text("Audio: %s", displayName.c_str());
|
||||||
|
ImGui::EndDragDropSource();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui::PopID();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
{
|
{
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
ImGui::Text("Path: %s", asset.path.c_str());
|
ImGui::Text("Path: %s", baseAsset->path.c_str());
|
||||||
ImGui::Text("UAID: %llu", asset.uaid);
|
ImGui::Text("UAID: %llu", baseAsset->uaid);
|
||||||
ImGui::Text("Texture ID: %u", asset.textureID);
|
|
||||||
ImGui::Text("Size: (%.0f, %.0f)", asset.size.x, asset.size.y);
|
if (baseAsset->type == AssetType::Image)
|
||||||
|
{
|
||||||
|
const auto *imageAsset = dynamic_cast<const ImageAssetInfo *>(baseAsset.get());
|
||||||
|
if (imageAsset)
|
||||||
|
{
|
||||||
|
ImGui::Text("Texture ID: %u", imageAsset->textureID);
|
||||||
|
ImGui::Text("Size: (%.0f, %.0f)", imageAsset->size.x, imageAsset->size.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (baseAsset->type == AssetType::Audio)
|
||||||
|
{
|
||||||
|
ImGui::Text("Audio file");
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +140,7 @@ void ShowAssetBrowser()
|
|||||||
{
|
{
|
||||||
if (ImGui::MenuItem("Unload"))
|
if (ImGui::MenuItem("Unload"))
|
||||||
{
|
{
|
||||||
Logger::LogInfo("[AssetBrowser] Unloaded: %s", asset.path.c_str());
|
Logger::LogInfo("[AssetBrowser] Unloaded: %s", baseAsset->path.c_str());
|
||||||
AssetManager::UnloadAsset(uaid);
|
AssetManager::UnloadAsset(uaid);
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
@ -102,12 +149,12 @@ void ShowAssetBrowser()
|
|||||||
|
|
||||||
if (ImGui::MenuItem("Copy Path"))
|
if (ImGui::MenuItem("Copy Path"))
|
||||||
{
|
{
|
||||||
ImGui::SetClipboardText(asset.path.c_str());
|
ImGui::SetClipboardText(baseAsset->path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::MenuItem("Copy UAID"))
|
if (ImGui::MenuItem("Copy UAID"))
|
||||||
{
|
{
|
||||||
ImGui::SetClipboardText(std::to_string(asset.uaid).c_str());
|
ImGui::SetClipboardText(std::to_string(baseAsset->uaid).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
|
93468
src/vendor/miniaudio/miniaudio.h
vendored
Normal file
93468
src/vendor/miniaudio/miniaudio.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user