Added Actual Asset manager
This commit is contained in:
parent
421cb639b9
commit
c4786629da
76
imgui.ini
76
imgui.ini
@ -10,97 +10,93 @@ Collapsed=1
|
||||
|
||||
[Window][WindowOverViewport_11111111]
|
||||
Pos=0,19
|
||||
Size=1280,701
|
||||
Size=1920,1158
|
||||
Collapsed=0
|
||||
|
||||
[Window][Inspector]
|
||||
Pos=0,421
|
||||
Size=342,299
|
||||
Pos=1578,19
|
||||
Size=342,1158
|
||||
Collapsed=0
|
||||
DockId=0x0000000A,0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][Scene Tree]
|
||||
Pos=0,19
|
||||
Size=342,400
|
||||
Size=342,575
|
||||
Collapsed=0
|
||||
DockId=0x00000009,0
|
||||
DockId=0x00000003,0
|
||||
|
||||
[Window][Viewport]
|
||||
Pos=344,19
|
||||
Size=936,139
|
||||
Size=1232,847
|
||||
Collapsed=0
|
||||
DockId=0x0000000B,0
|
||||
DockId=0x00000007,0
|
||||
|
||||
[Window][##MainMenuBar]
|
||||
Size=1920,19
|
||||
Collapsed=0
|
||||
|
||||
[Window][Performance Info]
|
||||
Pos=1083,410
|
||||
Size=197,310
|
||||
Pos=0,19
|
||||
Size=342,575
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
DockId=0x00000003,1
|
||||
|
||||
[Window][Console]
|
||||
Pos=344,410
|
||||
Size=286,310
|
||||
Pos=344,868
|
||||
Size=1232,309
|
||||
Collapsed=0
|
||||
DockId=0x0000000D,0
|
||||
DockId=0x00000008,0
|
||||
|
||||
[Window][Tilemap Editor]
|
||||
Pos=265,19
|
||||
Size=1263,674
|
||||
Collapsed=0
|
||||
DockId=0x0000000B,1
|
||||
DockId=0x00000007,1
|
||||
|
||||
[Window][Profiler]
|
||||
Pos=344,160
|
||||
Size=936,248
|
||||
Pos=344,868
|
||||
Size=1232,309
|
||||
Collapsed=0
|
||||
DockId=0x0000000C,0
|
||||
DockId=0x00000008,1
|
||||
|
||||
[Window][Profiler Timeline]
|
||||
Pos=265,69
|
||||
Size=623,651
|
||||
Collapsed=0
|
||||
DockId=0x00000005,1
|
||||
DockId=0x00000008,1
|
||||
|
||||
[Window][Profiler (Unity Style)]
|
||||
Pos=265,430
|
||||
Size=623,290
|
||||
Collapsed=0
|
||||
DockId=0x00000005,1
|
||||
DockId=0x00000008,1
|
||||
|
||||
[Window][Profiler Timeline View]
|
||||
Pos=265,526
|
||||
Size=1263,651
|
||||
Collapsed=0
|
||||
DockId=0x00000005,1
|
||||
DockId=0x00000008,1
|
||||
|
||||
[Window][Color Correction]
|
||||
Pos=1083,410
|
||||
Size=197,310
|
||||
Pos=1588,867
|
||||
Size=332,310
|
||||
Collapsed=0
|
||||
DockId=0x00000006,1
|
||||
DockId=0x00000008,1
|
||||
|
||||
[Window][Asset Browser]
|
||||
Pos=632,410
|
||||
Size=449,310
|
||||
Pos=0,596
|
||||
Size=342,581
|
||||
Collapsed=0
|
||||
DockId=0x0000000E,0
|
||||
DockId=0x00000004,0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x11111111 SizeRef=342,701 Split=Y Selected=0x12EF0F59
|
||||
DockNode ID=0x00000009 Parent=0x00000001 SizeRef=385,662 Selected=0x12EF0F59
|
||||
DockNode ID=0x0000000A Parent=0x00000001 SizeRef=385,494 HiddenTabBar=1 Selected=0x36DC96AB
|
||||
DockNode ID=0x00000002 Parent=0x11111111 SizeRef=1576,701 Split=Y Selected=0xC450F867
|
||||
DockNode ID=0x00000007 Parent=0x00000002 SizeRef=606,846 Split=Y Selected=0xC450F867
|
||||
DockNode ID=0x0000000B Parent=0x00000007 SizeRef=1576,596 CentralNode=1 HiddenTabBar=1 Selected=0xC450F867
|
||||
DockNode ID=0x0000000C Parent=0x00000007 SizeRef=1576,248 HiddenTabBar=1 Selected=0x9B5D3198
|
||||
DockNode ID=0x00000008 Parent=0x00000002 SizeRef=606,310 Split=X Selected=0x9B5D3198
|
||||
DockNode ID=0x00000005 Parent=0x00000008 SizeRef=1242,481 Split=X Selected=0x9B5D3198
|
||||
DockNode ID=0x0000000D Parent=0x00000005 SizeRef=482,248 HiddenTabBar=1 Selected=0xEA83D666
|
||||
DockNode ID=0x0000000E Parent=0x00000005 SizeRef=758,248 HiddenTabBar=1 Selected=0x36AF052B
|
||||
DockNode ID=0x00000006 Parent=0x00000008 SizeRef=332,481 Selected=0xA873C17F
|
||||
DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1920,1158 Split=X
|
||||
DockNode ID=0x00000005 Parent=0x11111111 SizeRef=1576,1158 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=342,701 Split=Y Selected=0x12EF0F59
|
||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=342,575 Selected=0x12EF0F59
|
||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=342,581 HiddenTabBar=1 Selected=0x36AF052B
|
||||
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1576,701 Split=Y 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=0x00000006 Parent=0x11111111 SizeRef=342,1158 Selected=0x36DC96AB
|
||||
|
||||
|
@ -1,15 +1,5 @@
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\core\utils\Texture.cpp -o src\build\core\utils\Texture.o
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\editor\windows\AssetBrowser.cpp -o src\build\editor\windows\AssetBrowser.o
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\utils\Shader.cpp -o src\build\utils\Shader.o
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\Components\ScriptComponent.cpp -o src\build\Components\ScriptComponent.o
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\Components\TilemapComponent.cpp -o src\build\Components\TilemapComponent.o
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\core\utils\Profiler.cpp -o src\build\core\utils\Profiler.o
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\Renderer.cpp -o src\build\Renderer.o
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\Components\ParticleComponent.cpp -o src\build\Components\ParticleComponent.o
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\Components\AnimationComponent.cpp -o src\build\Components\AnimationComponent.o
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\editor\windows\Inspector.cpp -o src\build\editor\windows\Inspector.o
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\core\utils\EngineConfig.cpp -o src\build\core\utils\EngineConfig.o
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\core\utils\utils.cpp -o src\build\core\utils\utils.o
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\Components\SpriteComponent.cpp -o src\build\Components\SpriteComponent.o
|
||||
[COMPILE] g++ -std=c++20 -Wall -g -Isrc/include -Isrc/include/lua -Isrc/vendor -Isrc/vendor/imgui -Isrc/vendor/box2d -IC:/msys64/mingw64/include -IC:\msys64\mingw64\lib\libyaml-cpp.a -Isrc\vendor\imgui -MMD -MP -c src\src\Engine.cpp -o src\build\Engine.o
|
||||
[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\AssetLoader.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\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 -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto
|
||||
[RUN] Executed app.exe successfully.
|
||||
[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\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 -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto
|
||||
[ERROR] Runtime crash
|
||||
Command 'src\build\app.exe' returned non-zero exit status 3221225477.
|
||||
|
26
src/assets/scenes/animation.cene
Normal file
26
src/assets/scenes/animation.cene
Normal file
@ -0,0 +1,26 @@
|
||||
engine_version: 0.1.0
|
||||
scene_name: Animation Test
|
||||
scene_hash: 4118ae64656b78eaaae99b4b2b842496e6c90b20ec8399a165be0bdfa3e80bdc
|
||||
format_version: 1
|
||||
objects:
|
||||
- name: Hello, Create
|
||||
uid: 19b6b2eb03084eae822f776ba886f55b
|
||||
id: 0
|
||||
position: [0, 0]
|
||||
rotation: 0
|
||||
layer: 0
|
||||
visable: true
|
||||
components:
|
||||
- AnimationComponent
|
||||
- TexturePath: C:\Users\spenc\OneDrive\Pictures\Pixel Holy Spell Effect 32x32 Pack 3\01.png
|
||||
TexelWidth: 64
|
||||
TexelHeight: 64
|
||||
FrameDuration: 0.100000000
|
||||
children: []
|
||||
color_correction:
|
||||
brightness: 1
|
||||
saturation: 1
|
||||
gamma: 1
|
||||
bloom: false
|
||||
intensity: 1.20000005
|
||||
threshold: 0.200000003
|
35
src/assets/scenes/assettest.cene
Normal file
35
src/assets/scenes/assettest.cene
Normal file
@ -0,0 +1,35 @@
|
||||
engine_version: 0.1.0
|
||||
scene_name: New Text Document
|
||||
scene_hash: d3b8c771af41a9f6021a650b384379cd3582e59a8e167c0e06e99643d29ad97b
|
||||
format_version: 1
|
||||
objects:
|
||||
- name: Hello, Create
|
||||
uid: fced127a6c9c485cb3dd1b947e1429f9
|
||||
id: 0
|
||||
position: [0, 0]
|
||||
rotation: 0
|
||||
layer: 0
|
||||
visable: true
|
||||
components:
|
||||
- AnimationComponent
|
||||
- TexturePath: C:\Users\spenc\OneDrive\Pictures\6656e7221e49a1774d2fb280357e56f8d25d9d95.png
|
||||
TexelWidth: 32
|
||||
TexelHeight: 32
|
||||
FrameDuration: 0.100000001
|
||||
StartFrame: 0
|
||||
EndFrame: 1023
|
||||
children: []
|
||||
color_correction:
|
||||
brightness: 1
|
||||
saturation: 1
|
||||
gamma: 1
|
||||
bloom: true
|
||||
intensity: 1.20000005
|
||||
threshold: 1
|
||||
assets: Assets
|
||||
? - uaid: 1
|
||||
path: C:\Users\spenc\OneDrive\Pictures\6656e7221e49a1774d2fb280357e56f8d25d9d95.png
|
||||
filename: 6656e7221e49a1774d2fb280357e56f8d25d9d95.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
@ -1,6 +1,6 @@
|
||||
engine_version: 0.1.0
|
||||
scene_name: lighting_test
|
||||
scene_hash: 964a6472a140773c791bf1ed2b8e6ea5b20b183e7bb02489110ad41df5d364e2
|
||||
scene_hash: ee7d7a88a6c1a4eaa0ae27372e3d055df3511e13144a267574ebb7a7842d63d2
|
||||
format_version: 1
|
||||
objects:
|
||||
- name: Tiles
|
||||
@ -21,86 +21,47 @@ objects:
|
||||
visable: true
|
||||
components:
|
||||
- type: SpriteComponent
|
||||
texture: C:\Users\spenc\OneDrive\Pictures\textures\bark_willow_02_diff_1k.png
|
||||
normalMap: C:\Users\spenc\OneDrive\Pictures\textures\bark_willow_02_nor_gl_1k.png
|
||||
texture: 1
|
||||
normalMap: 2
|
||||
renderType: Lit
|
||||
children: []
|
||||
- name: Planks
|
||||
uid: 13d8988343354e3c8a1f51c03ed40cda
|
||||
id: 5
|
||||
position: [1024, 0]
|
||||
position: [2048, 0]
|
||||
rotation: 0
|
||||
layer: 0
|
||||
visable: true
|
||||
components:
|
||||
- type: SpriteComponent
|
||||
texture: C:\Users\spenc\OneDrive\Pictures\textures\wood_floor_worn_diff_1k.png
|
||||
normalMap: C:\Users\spenc\OneDrive\Pictures\textures\wood_floor_worn_nor_gl_1k.png
|
||||
texture: 3
|
||||
normalMap: 4
|
||||
renderType: Lit
|
||||
children: []
|
||||
- name: Rocks
|
||||
uid: cff28abe7e3b455ab9b756acc84cd2d7
|
||||
id: 6
|
||||
position: [0, 1024]
|
||||
position: [0, 2048]
|
||||
rotation: 0
|
||||
layer: 0
|
||||
visable: true
|
||||
components:
|
||||
- type: SpriteComponent
|
||||
texture: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_diff_1k.png
|
||||
normalMap: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_nor_gl_1k.png
|
||||
texture: 6
|
||||
normalMap: 5
|
||||
renderType: Lit
|
||||
children: []
|
||||
- name: Metal
|
||||
uid: 98967eb30e5b429b992766d8062b7c17
|
||||
id: 7
|
||||
position: [1024, 1024]
|
||||
position: [2048, 2048]
|
||||
rotation: 0
|
||||
layer: 0
|
||||
visable: true
|
||||
components:
|
||||
- type: SpriteComponent
|
||||
texture: C:\Users\spenc\OneDrive\Pictures\textures\metal_plate_diff_1k.png
|
||||
normalMap: C:\Users\spenc\OneDrive\Pictures\textures\metal_plate_nor_gl_1k.png
|
||||
renderType: Lit
|
||||
children: []
|
||||
- name: Logo
|
||||
uid: c4ce6f16dfb347b0ae0ac67f5881b243
|
||||
id: 8
|
||||
position: [3181, 56]
|
||||
rotation: 0
|
||||
layer: 0
|
||||
visable: true
|
||||
components:
|
||||
- type: SpriteComponent
|
||||
texture: C:\Users\spenc\OneDrive\Pictures\blue_logo.png
|
||||
normalMap: C:\Users\spenc\OneDrive\Pictures\textures\circuits_normal.jpg
|
||||
renderType: Lit
|
||||
children: []
|
||||
- name: Carbooon Fobar
|
||||
uid: 5ea269572751401da6d86519d3513b7d
|
||||
id: 9
|
||||
position: [4087.8999, 3070]
|
||||
rotation: 0
|
||||
layer: 1
|
||||
visable: true
|
||||
components:
|
||||
- type: SpriteComponent
|
||||
texture: C:\Users\spenc\OneDrive\Pictures\textures\carbon-fiber-smooth-bl\carbon-fiber-smooth-bl\carbon-fiber_smooth_albedo.png
|
||||
normalMap: C:\Users\spenc\OneDrive\Pictures\textures\carbon-fiber-smooth-bl\carbon-fiber-smooth-bl\carbon-fiber_smooth_normal-ogl.png
|
||||
renderType: Lit
|
||||
children: []
|
||||
- name: Carbooon Fobar 2
|
||||
uid: a36b71937ba349bd8e6414f75be9ee16
|
||||
id: 10
|
||||
position: [-7.69999981, 3070]
|
||||
rotation: 0
|
||||
layer: 0
|
||||
visable: true
|
||||
components:
|
||||
- type: SpriteComponent
|
||||
texture: C:\Users\spenc\OneDrive\Pictures\textures\carbon-fiber-smooth-bl\carbon-fiber-smooth-bl\carbon-fiber_smooth_albedo.png
|
||||
normalMap: C:\Users\spenc\OneDrive\Pictures\textures\carbon-fiber-smooth-bl\carbon-fiber-smooth-bl\carbon-fiber_smooth_normal-ogl.png
|
||||
texture: 7
|
||||
normalMap: 8
|
||||
renderType: Lit
|
||||
children: []
|
||||
- name: Lights
|
||||
@ -115,7 +76,7 @@ objects:
|
||||
- name: Red
|
||||
uid: 6afde2dd47aa4557b6afb1a607c99dc8
|
||||
id: 13
|
||||
position: [878.398376, 545.669373]
|
||||
position: [574.239258, 805.561768]
|
||||
rotation: 0
|
||||
layer: 2
|
||||
visable: true
|
||||
@ -133,7 +94,7 @@ objects:
|
||||
- name: Green
|
||||
uid: 0f950d76d24b4dc18f54cab2c3aaaf9a
|
||||
id: 14
|
||||
position: [1511.04724, 1137.07068]
|
||||
position: [1438.05347, 743.714905]
|
||||
rotation: 0
|
||||
layer: 2
|
||||
visable: true
|
||||
@ -151,7 +112,7 @@ objects:
|
||||
- name: Blue
|
||||
uid: 09f722f51c7c4b0f98de3a0a16d127c4
|
||||
id: 15
|
||||
position: [682.554321, 1389.26001]
|
||||
position: [1059.70728, 1522.72339]
|
||||
rotation: 0
|
||||
layer: 2
|
||||
visable: true
|
||||
@ -232,6 +193,7 @@ objects:
|
||||
endColor: [0.792156875, 0, 1, 1]
|
||||
loop: true
|
||||
burst: false
|
||||
roundness: 1
|
||||
children: []
|
||||
- name: Rain
|
||||
uid: 19253834f75d4e69a618c45ddb14e8b0
|
||||
@ -256,6 +218,7 @@ objects:
|
||||
endColor: [0, 0, 1, 0]
|
||||
loop: true
|
||||
burst: false
|
||||
roundness: 1
|
||||
children: []
|
||||
- name: Fire
|
||||
uid: 995af3d194694309a490504eaee3ae92
|
||||
@ -280,11 +243,61 @@ objects:
|
||||
endColor: [1, 0, 0, 0]
|
||||
loop: true
|
||||
burst: false
|
||||
roundness: 1
|
||||
children: []
|
||||
color_correction:
|
||||
brightness: 2
|
||||
saturation: 2
|
||||
gamma: 1.05999994
|
||||
bloom: true
|
||||
intensity: 1.40999997
|
||||
threshold: 0.300000012
|
||||
intensity: 1.35000002
|
||||
threshold: 0.810000002
|
||||
Assets:
|
||||
- uaid: 1
|
||||
path: C:\Users\spenc\OneDrive\Pictures\textures\bark_willow_02_diff_1k.png
|
||||
filename: bark_willow_02_diff_1k.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
||||
- uaid: 2
|
||||
path: C:\Users\spenc\OneDrive\Pictures\textures\bark_willow_02_nor_gl_1k.png
|
||||
filename: bark_willow_02_nor_gl_1k.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
||||
- uaid: 3
|
||||
path: C:\Users\spenc\OneDrive\Pictures\textures\wood_floor_worn_diff_1k.png
|
||||
filename: wood_floor_worn_diff_1k.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
||||
- uaid: 4
|
||||
path: C:\Users\spenc\OneDrive\Pictures\textures\wood_floor_worn_nor_gl_1k.png
|
||||
filename: wood_floor_worn_nor_gl_1k.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
||||
- uaid: 5
|
||||
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
|
||||
size: [1024, 1024]
|
||||
- uaid: 6
|
||||
path: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_diff_1k.png
|
||||
filename: ganges_river_pebbles_diff_1k.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
||||
- uaid: 7
|
||||
path: C:\Users\spenc\OneDrive\Pictures\textures\metal_plate_diff_1k.png
|
||||
filename: metal_plate_diff_1k.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
||||
- uaid: 8
|
||||
path: C:\Users\spenc\OneDrive\Pictures\textures\metal_plate_nor_gl_1k.png
|
||||
filename: metal_plate_nor_gl_1k.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
@ -1,12 +1,12 @@
|
||||
engine_version: 0.1.0
|
||||
scene_name: lighting_test_2
|
||||
scene_hash: 8d1aa1b7b386c5e68c5ad14aa2db10dad6c1fef078b7cbd009df408784b8f915
|
||||
scene_hash: fd4d1e65a004b05f9654d657efa90617ff63d3c6c4e624518825d4dae50ef3a3
|
||||
format_version: 1
|
||||
objects:
|
||||
- name: Tiles
|
||||
uid: f5e01f7892874a67b662633650b41dbd
|
||||
id: 3
|
||||
position: [0, 0]
|
||||
position: [426, 1088]
|
||||
rotation: 0
|
||||
layer: 0
|
||||
visable: true
|
||||
@ -21,86 +21,47 @@ objects:
|
||||
visable: true
|
||||
components:
|
||||
- type: SpriteComponent
|
||||
texture: C:\Users\spenc\OneDrive\Pictures\textures\bark_willow_02_diff_1k.png
|
||||
normalMap: C:\Users\spenc\OneDrive\Pictures\textures\bark_willow_02_nor_gl_1k.png
|
||||
texture: 1
|
||||
normalMap: 2
|
||||
renderType: Lit
|
||||
children: []
|
||||
- name: Planks
|
||||
uid: 13d8988343354e3c8a1f51c03ed40cda
|
||||
id: 5
|
||||
position: [1024, 0]
|
||||
position: [2048, 0]
|
||||
rotation: 0
|
||||
layer: 0
|
||||
visable: true
|
||||
components:
|
||||
- type: SpriteComponent
|
||||
texture: C:\Users\spenc\OneDrive\Pictures\textures\wood_floor_worn_diff_1k.png
|
||||
normalMap: C:\Users\spenc\OneDrive\Pictures\textures\wood_floor_worn_nor_gl_1k.png
|
||||
texture: 3
|
||||
normalMap: 4
|
||||
renderType: Lit
|
||||
children: []
|
||||
- name: Rocks
|
||||
uid: cff28abe7e3b455ab9b756acc84cd2d7
|
||||
id: 6
|
||||
position: [0, 1024]
|
||||
position: [0, 2048]
|
||||
rotation: 0
|
||||
layer: 0
|
||||
visable: true
|
||||
components:
|
||||
- type: SpriteComponent
|
||||
texture: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_diff_1k.png
|
||||
normalMap: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_nor_gl_1k.png
|
||||
texture: 6
|
||||
normalMap: 5
|
||||
renderType: Lit
|
||||
children: []
|
||||
- name: Metal
|
||||
uid: 98967eb30e5b429b992766d8062b7c17
|
||||
id: 7
|
||||
position: [1024, 1024]
|
||||
position: [2048, 2048]
|
||||
rotation: 0
|
||||
layer: 0
|
||||
visable: true
|
||||
components:
|
||||
- type: SpriteComponent
|
||||
texture: C:\Users\spenc\OneDrive\Pictures\textures\metal_plate_diff_1k.png
|
||||
normalMap: C:\Users\spenc\OneDrive\Pictures\textures\metal_plate_nor_gl_1k.png
|
||||
renderType: Lit
|
||||
children: []
|
||||
- name: Logo
|
||||
uid: c4ce6f16dfb347b0ae0ac67f5881b243
|
||||
id: 8
|
||||
position: [3181, 56]
|
||||
rotation: 0
|
||||
layer: 0
|
||||
visable: true
|
||||
components:
|
||||
- type: SpriteComponent
|
||||
texture: C:\Users\spenc\OneDrive\Pictures\blue_logo.png
|
||||
normalMap: C:\Users\spenc\OneDrive\Pictures\textures\circuits_normal.jpg
|
||||
renderType: Lit
|
||||
children: []
|
||||
- name: Carbooon Fobar
|
||||
uid: 5ea269572751401da6d86519d3513b7d
|
||||
id: 9
|
||||
position: [4087.8999, 3070]
|
||||
rotation: 0
|
||||
layer: 1
|
||||
visable: true
|
||||
components:
|
||||
- type: SpriteComponent
|
||||
texture: C:\Users\spenc\OneDrive\Pictures\textures\carbon-fiber-smooth-bl\carbon-fiber-smooth-bl\carbon-fiber_smooth_albedo.png
|
||||
normalMap: C:\Users\spenc\OneDrive\Pictures\textures\carbon-fiber-smooth-bl\carbon-fiber-smooth-bl\carbon-fiber_smooth_normal-ogl.png
|
||||
renderType: Lit
|
||||
children: []
|
||||
- name: Carbooon Fobar 2
|
||||
uid: a36b71937ba349bd8e6414f75be9ee16
|
||||
id: 10
|
||||
position: [-7.69999981, 3070]
|
||||
rotation: 0
|
||||
layer: 0
|
||||
visable: true
|
||||
components:
|
||||
- type: SpriteComponent
|
||||
texture: C:\Users\spenc\OneDrive\Pictures\textures\carbon-fiber-smooth-bl\carbon-fiber-smooth-bl\carbon-fiber_smooth_albedo.png
|
||||
normalMap: C:\Users\spenc\OneDrive\Pictures\textures\carbon-fiber-smooth-bl\carbon-fiber-smooth-bl\carbon-fiber_smooth_normal-ogl.png
|
||||
texture: 7
|
||||
normalMap: 8
|
||||
renderType: Lit
|
||||
children: []
|
||||
- name: Lights
|
||||
@ -115,7 +76,7 @@ objects:
|
||||
- name: Red
|
||||
uid: 6afde2dd47aa4557b6afb1a607c99dc8
|
||||
id: 13
|
||||
position: [574.239258, 805.561768]
|
||||
position: [1062.8678, 525.513]
|
||||
rotation: 0
|
||||
layer: 2
|
||||
visable: true
|
||||
@ -133,7 +94,7 @@ objects:
|
||||
- name: Green
|
||||
uid: 0f950d76d24b4dc18f54cab2c3aaaf9a
|
||||
id: 14
|
||||
position: [1438.05347, 743.714905]
|
||||
position: [1436.26843, 1306.90405]
|
||||
rotation: 0
|
||||
layer: 2
|
||||
visable: true
|
||||
@ -151,7 +112,7 @@ objects:
|
||||
- name: Blue
|
||||
uid: 09f722f51c7c4b0f98de3a0a16d127c4
|
||||
id: 15
|
||||
position: [1059.70728, 1522.72339]
|
||||
position: [572.863647, 1239.58301]
|
||||
rotation: 0
|
||||
layer: 2
|
||||
visable: true
|
||||
@ -232,6 +193,7 @@ objects:
|
||||
endColor: [0.792156875, 0, 1, 1]
|
||||
loop: true
|
||||
burst: false
|
||||
roundness: 1
|
||||
children: []
|
||||
- name: Rain
|
||||
uid: 19253834f75d4e69a618c45ddb14e8b0
|
||||
@ -256,6 +218,7 @@ objects:
|
||||
endColor: [0, 0, 1, 0]
|
||||
loop: true
|
||||
burst: false
|
||||
roundness: 1
|
||||
children: []
|
||||
- name: Fire
|
||||
uid: 995af3d194694309a490504eaee3ae92
|
||||
@ -280,11 +243,61 @@ objects:
|
||||
endColor: [1, 0, 0, 0]
|
||||
loop: true
|
||||
burst: false
|
||||
roundness: 1
|
||||
children: []
|
||||
color_correction:
|
||||
brightness: 2
|
||||
saturation: 2
|
||||
gamma: 1.05999994
|
||||
bloom: true
|
||||
intensity: 1.40999997
|
||||
threshold: 0.300000012
|
||||
intensity: 0.200000003
|
||||
threshold: 1.75999999
|
||||
Assets:
|
||||
- uaid: 1
|
||||
path: C:\Users\spenc\OneDrive\Pictures\textures\bark_willow_02_diff_1k.png
|
||||
filename: bark_willow_02_diff_1k.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
||||
- uaid: 2
|
||||
path: C:\Users\spenc\OneDrive\Pictures\textures\bark_willow_02_nor_gl_1k.png
|
||||
filename: bark_willow_02_nor_gl_1k.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
||||
- uaid: 3
|
||||
path: C:\Users\spenc\OneDrive\Pictures\textures\wood_floor_worn_diff_1k.png
|
||||
filename: wood_floor_worn_diff_1k.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
||||
- uaid: 4
|
||||
path: C:\Users\spenc\OneDrive\Pictures\textures\wood_floor_worn_nor_gl_1k.png
|
||||
filename: wood_floor_worn_nor_gl_1k.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
||||
- uaid: 5
|
||||
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
|
||||
size: [1024, 1024]
|
||||
- uaid: 6
|
||||
path: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_diff_1k.png
|
||||
filename: ganges_river_pebbles_diff_1k.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
||||
- uaid: 7
|
||||
path: C:\Users\spenc\OneDrive\Pictures\textures\metal_plate_diff_1k.png
|
||||
filename: metal_plate_diff_1k.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
||||
- uaid: 8
|
||||
path: C:\Users\spenc\OneDrive\Pictures\textures\metal_plate_nor_gl_1k.png
|
||||
filename: metal_plate_nor_gl_1k.png
|
||||
filetype: png
|
||||
type: 0
|
||||
size: [1024, 1024]
|
@ -1,6 +1,10 @@
|
||||
#version 430 core
|
||||
|
||||
in vec2 vUV;
|
||||
|
||||
uniform vec2 uUVMin;
|
||||
uniform vec2 uUVMax;
|
||||
|
||||
in vec2 vFragScreenPos;
|
||||
out vec4 FragColor;
|
||||
|
||||
@ -18,6 +22,8 @@ uniform int uClusterHeight;
|
||||
uniform int uClusterCols;
|
||||
uniform int uMaxLightsPerCluster;
|
||||
|
||||
|
||||
|
||||
#define MAX_LIGHTS 512
|
||||
uniform vec2 uLightPos[MAX_LIGHTS];
|
||||
uniform vec3 uLightColor[MAX_LIGHTS];
|
||||
@ -30,7 +36,9 @@ layout(std430, binding = 1) readonly buffer ClusterLightBuffer {
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 rotatedUV = vec2(vUV.y, 1.0 - vUV.x);
|
||||
|
||||
vec2 rotatedUV = mix(uUVMin, uUVMax, vec2(vUV.y, 1.0 - vUV.x));
|
||||
|
||||
vec4 texColor = texture(uTex, rotatedUV);
|
||||
if (texColor.a < 0.1)
|
||||
discard;
|
||||
|
@ -1,15 +1,21 @@
|
||||
#version 330 core
|
||||
|
||||
in vec2 vUV;
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D uTex;
|
||||
uniform vec2 uUVMin;
|
||||
uniform vec2 uUVMax;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
// Rotate UV 90 degrees to the right: (x, y) → (y, 1 - x)
|
||||
vec2 rotatedUV = vec2(vUV.y, 1.0 - vUV.x);
|
||||
|
||||
vec4 color = texture(uTex, rotatedUV);
|
||||
// Interpolate UVs within atlas range
|
||||
vec2 uv = mix(uUVMin, uUVMax, rotatedUV);
|
||||
|
||||
vec4 color = texture(uTex, uv);
|
||||
if (color.a < 0.01)
|
||||
discard;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 430 core
|
||||
layout (location = 0) in vec2 aPos;
|
||||
layout (location = 1) in vec2 aUV;
|
||||
|
||||
|
@ -1,11 +1,23 @@
|
||||
#version 330 core
|
||||
|
||||
in vec4 vColor;
|
||||
in vec2 vUV;
|
||||
in float vRoundness;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
// Optional: kill particles with near-zero alpha (optional)
|
||||
if (vColor.a < 0.01)
|
||||
void main()
|
||||
{
|
||||
vec2 pos = vUV * 2.0 - 1.0;
|
||||
vec2 absPos = abs(pos);
|
||||
|
||||
bool insideSquare = all(lessThanEqual(absPos, vec2(1.0)));
|
||||
|
||||
bool insideCircle = length(pos) <= 1.0;
|
||||
|
||||
bool inside = mix(float(insideSquare), float(insideCircle), vRoundness) >= 0.5;
|
||||
|
||||
if (!inside)
|
||||
discard;
|
||||
|
||||
FragColor = vColor;
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 330 core
|
||||
#version 430 core
|
||||
|
||||
layout (location = 0) in vec2 aPos;
|
||||
|
||||
@ -6,12 +6,17 @@ layout (location = 1) in vec2 iPos;
|
||||
layout (location = 2) in vec2 iSize;
|
||||
layout (location = 3) in float iRot;
|
||||
layout (location = 4) in vec4 iColor;
|
||||
layout (location = 5) in float iRoundness; // 0 to 1 rounded
|
||||
|
||||
uniform vec2 uScreen;
|
||||
|
||||
out vec4 vColor;
|
||||
out float vRoundness;
|
||||
out vec2 vUV;
|
||||
|
||||
void main() {
|
||||
|
||||
void main()
|
||||
{
|
||||
float cosR = cos(iRot);
|
||||
float sinR = sin(iRot);
|
||||
|
||||
@ -24,5 +29,9 @@ void main() {
|
||||
vec2 finalPos = iPos + rotated;
|
||||
|
||||
gl_Position = vec4((finalPos / uScreen * 2.0 - 1.0) * vec2(1, -1), 0.0, 1.0);
|
||||
|
||||
// Map [-0.5, 0.5] to [0.0, 1.0]
|
||||
vUV = aPos + vec2(0.5);
|
||||
vColor = iColor;
|
||||
vRoundness = iRoundness;
|
||||
}
|
||||
|
@ -1,71 +1,117 @@
|
||||
#include "AnimationComponent.h"
|
||||
|
||||
AnimationComponent::AnimationComponent(Object* owner)
|
||||
AnimationComponent::AnimationComponent(Object *owner)
|
||||
: Component(owner) {}
|
||||
|
||||
void AnimationComponent::SetTextureAtlas(const std::string& path, int cols, int rows, float duration) {
|
||||
texturePath = path;
|
||||
texture = std::make_shared<Texture>(path);
|
||||
atlas = TextureAtlas(texture, cols, rows);
|
||||
columns = cols;
|
||||
rows = rows;
|
||||
totalFrames = cols * rows;
|
||||
frameDuration = duration;
|
||||
void AnimationComponent::SetTextureAtlasPath(const std::string &path, int texelWidth, int texelHeight, float duration, int start, int end)
|
||||
{
|
||||
AssetManager::LoadAssetAsync(path, AssetType::Image);
|
||||
const auto *asset = AssetManager::GetAssetByPath(path);
|
||||
if (asset)
|
||||
SetTextureAtlas(asset->uaid, texelWidth, texelHeight, duration, start, end);
|
||||
}
|
||||
|
||||
void AnimationComponent::SetTextureAtlas(uint64_t uaid, int texelWidth, int texelHeight, float duration, int /*start*/, int /*end*/)
|
||||
{
|
||||
textureUAID = uaid;
|
||||
|
||||
const auto *asset = AssetManager::GetAssetByID(uaid);
|
||||
if (!asset || !asset->loaded)
|
||||
{
|
||||
Logger::LogError("SetTextureAtlas: Asset not found or not loaded (UAID: %llu)", uaid);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int texWidth = static_cast<int>(asset->size.x);
|
||||
int texHeight = static_cast<int>(asset->size.y);
|
||||
|
||||
if (texelWidth <= 0 || texelHeight <= 0 || texWidth < texelWidth || texHeight < texelHeight)
|
||||
{
|
||||
Logger::LogError("SetTextureAtlas: Invalid texel size %dx%d for image size %dx%d (UAID: %llu)",
|
||||
texelWidth, texelHeight, texWidth, texHeight, uaid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (texWidth % texelWidth != 0 || texHeight % texelHeight != 0)
|
||||
{
|
||||
Logger::LogWarning("SetTextureAtlas: Texture size is not cleanly divisible by texel size (UAID: %llu)", uaid);
|
||||
}
|
||||
|
||||
texture = std::make_shared<Texture>(asset->uaid);
|
||||
|
||||
atlas.texture = texture;
|
||||
atlas.SetTexelSize(texelWidth, texelHeight);
|
||||
|
||||
columns = texWidth / texelWidth;
|
||||
rows = texHeight / texelHeight;
|
||||
totalFrames = columns * rows;
|
||||
|
||||
startFrame = 0;
|
||||
endFrame = totalFrames > 0 ? totalFrames - 1 : 0;
|
||||
|
||||
frameDuration = duration;
|
||||
currentFrame = startFrame;
|
||||
|
||||
renderType = RenderType::Unlit;
|
||||
}
|
||||
|
||||
void AnimationComponent::Play() { playing = true; }
|
||||
void AnimationComponent::Stop() { playing = false; }
|
||||
void AnimationComponent::SetLooping(bool l) { loop = l; }
|
||||
void AnimationComponent::SetSpeed(float s) { speed = s; }
|
||||
void AnimationComponent::SetFrame(int f) { currentFrame = f % totalFrames; }
|
||||
void AnimationComponent::SetFrame(int f) { currentFrame = std::clamp(f, startFrame, endFrame); }
|
||||
|
||||
void AnimationComponent::Update(float dt) {
|
||||
if (!playing || totalFrames <= 1) return;
|
||||
void AnimationComponent::Update(float dt)
|
||||
{
|
||||
if (!playing || totalFrames <= 1)
|
||||
return;
|
||||
|
||||
time += dt * speed;
|
||||
if (time >= frameDuration) {
|
||||
if (time >= frameDuration)
|
||||
{
|
||||
time -= frameDuration;
|
||||
currentFrame++;
|
||||
|
||||
if (currentFrame >= totalFrames) {
|
||||
if (currentFrame > endFrame)
|
||||
{
|
||||
if (loop)
|
||||
currentFrame = 0;
|
||||
else {
|
||||
currentFrame = totalFrames - 1;
|
||||
currentFrame = startFrame;
|
||||
else
|
||||
{
|
||||
currentFrame = endFrame;
|
||||
playing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string AnimationComponent::GetName() const { return "AnimationComponent"; }
|
||||
|
||||
|
||||
std::string AnimationComponent::GetName() const {
|
||||
return "AnimationComponent";
|
||||
}
|
||||
|
||||
void AnimationComponent::Save(YAML::Emitter& out) const {
|
||||
void AnimationComponent::Save(YAML::Emitter &out) const
|
||||
{
|
||||
out << YAML::Key << "AnimationComponent";
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "TexturePath" << YAML::Value << texturePath;
|
||||
out << YAML::Key << "Columns" << YAML::Value << columns;
|
||||
out << YAML::Key << "Rows" << YAML::Value << rows;
|
||||
out << YAML::Key << "TextureUAID" << YAML::Value << textureUAID;
|
||||
out << YAML::Key << "TexelWidth" << YAML::Value << atlas.frameWidth;
|
||||
out << YAML::Key << "TexelHeight" << YAML::Value << atlas.frameHeight;
|
||||
out << YAML::Key << "FrameDuration" << YAML::Value << frameDuration;
|
||||
out << YAML::Key << "StartFrame" << YAML::Value << startFrame;
|
||||
out << YAML::Key << "EndFrame" << YAML::Value << endFrame;
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
|
||||
void AnimationComponent::Load(const YAML::Node& node) {
|
||||
void AnimationComponent::Load(const YAML::Node &node)
|
||||
{
|
||||
if (!node["AnimationComponent"])
|
||||
return;
|
||||
|
||||
const auto& data = node["AnimationComponent"];
|
||||
std::string path = data["TexturePath"].as<std::string>();
|
||||
int cols = data["Columns"].as<int>();
|
||||
int rows = data["Rows"].as<int>();
|
||||
float duration = data["FrameDuration"].as<float>();
|
||||
const auto &data = node["AnimationComponent"];
|
||||
uint64_t uaid = data["TextureUAID"].as<uint64_t>();
|
||||
int texelWidth = data["TexelWidth"].as<int>();
|
||||
int texelHeight = data["TexelHeight"].as<int>();
|
||||
float duration = data["FrameDuration"].as<float>();
|
||||
int start = data["StartFrame"] ? data["StartFrame"].as<int>() : 0;
|
||||
int end = data["EndFrame"] ? data["EndFrame"].as<int>() : INT_MAX;
|
||||
|
||||
SetTextureAtlas(path, cols, rows, duration);
|
||||
SetTextureAtlas(uaid, texelWidth, texelHeight, duration, start, end);
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,13 +6,17 @@
|
||||
#include <memory>
|
||||
#include "../core/utils/Texture.h"
|
||||
#include "../core/utils/TextureAtlas.h"
|
||||
#include "../core/utils/AssetManager.h"
|
||||
#include "../core/utils/Logging.h"
|
||||
|
||||
|
||||
class AnimationComponent : public Component
|
||||
{
|
||||
public:
|
||||
AnimationComponent(Object *owner);
|
||||
|
||||
void SetTextureAtlas(const std::string &path, int cols, int rows, float frameDuration);
|
||||
void SetTextureAtlasPath(const std::string &path, int texelWidth, int texelHeight, float frameDuration, int startFrame = 0, int endFrame = INT_MAX);
|
||||
void SetTextureAtlas(uint64_t uaid, int texelWidth, int texelHeight, float frameDuration, int startFrame = 0, int endFrame = INT_MAX);
|
||||
|
||||
void Play();
|
||||
void Stop();
|
||||
@ -25,9 +29,11 @@ public:
|
||||
float GetSpeed() const { return speed; }
|
||||
|
||||
TextureAtlas *GetAtlas() { return &atlas; }
|
||||
const TextureAtlas *GetAtlas() const { return &atlas; }
|
||||
|
||||
int GetCurrentFrame() const { return currentFrame; }
|
||||
|
||||
const std::string &GetTexturePath() const { return texturePath; }
|
||||
uint64_t GetTextureUAID() const { return textureUAID; }
|
||||
float GetFrameDuration() const { return frameDuration; }
|
||||
|
||||
void Update(float dt);
|
||||
@ -36,9 +42,11 @@ public:
|
||||
void Save(YAML::Emitter &out) const override;
|
||||
void Load(const YAML::Node &node) override;
|
||||
|
||||
private:
|
||||
std::string texturePath;
|
||||
|
||||
|
||||
RenderType renderType;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Texture> texture;
|
||||
TextureAtlas atlas;
|
||||
|
||||
@ -46,10 +54,15 @@ private:
|
||||
int rows = 1;
|
||||
int totalFrames = 1;
|
||||
|
||||
int startFrame = 0;
|
||||
int endFrame = 0;
|
||||
|
||||
float frameDuration = 0.1f;
|
||||
float time = 0.0f;
|
||||
int currentFrame = 0;
|
||||
bool playing = true;
|
||||
bool loop = true;
|
||||
float speed = 1.0f;
|
||||
|
||||
uint64_t textureUAID = 0;
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "ParticleComponent.h"
|
||||
#include "../Renderer.h" // Adjust if needed
|
||||
#include "../Renderer.h"
|
||||
#include <random>
|
||||
#include <algorithm>
|
||||
|
||||
@ -55,7 +55,6 @@ void ParticleComponent::Update(float dt)
|
||||
particles.end());
|
||||
}
|
||||
|
||||
|
||||
void ParticleComponent::SpawnParticle()
|
||||
{
|
||||
Particle p;
|
||||
@ -73,7 +72,8 @@ void ParticleComponent::SpawnParticle()
|
||||
|
||||
particles.push_back(p);
|
||||
}
|
||||
void ParticleComponent::Save(YAML::Emitter& out) const
|
||||
|
||||
void ParticleComponent::Save(YAML::Emitter &out) const
|
||||
{
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "type" << YAML::Value << "ParticleComponent";
|
||||
@ -90,7 +90,7 @@ void ParticleComponent::Save(YAML::Emitter& out) const
|
||||
out << YAML::Key << "direction" << YAML::Value << YAML::Flow << YAML::BeginSeq << settings.direction.x << settings.direction.y << YAML::EndSeq;
|
||||
out << YAML::Key << "spread" << YAML::Value << settings.spread;
|
||||
|
||||
auto writeColor = [](const Color& c, YAML::Emitter& out)
|
||||
auto writeColor = [](const Color &c, YAML::Emitter &out)
|
||||
{
|
||||
out << YAML::Flow << YAML::BeginSeq << c.r << c.g << c.b << c.a << YAML::EndSeq;
|
||||
};
|
||||
@ -102,21 +102,22 @@ void ParticleComponent::Save(YAML::Emitter& out) const
|
||||
out << YAML::Key << "loop" << YAML::Value << settings.loop;
|
||||
out << YAML::Key << "burst" << YAML::Value << settings.burst;
|
||||
|
||||
out << YAML::Key << "roundness" << YAML::Value << settings.roundness;
|
||||
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
|
||||
|
||||
void ParticleComponent::Load(const YAML::Node& node)
|
||||
void ParticleComponent::Load(const YAML::Node &node)
|
||||
{
|
||||
if (!node || !node.IsMap())
|
||||
return;
|
||||
|
||||
auto vec2 = [](const YAML::Node& n)
|
||||
auto vec2 = [](const YAML::Node &n)
|
||||
{
|
||||
return Vec2(n[0].as<float>(), n[1].as<float>());
|
||||
};
|
||||
|
||||
auto color = [](const YAML::Node& n)
|
||||
auto color = [](const YAML::Node &n)
|
||||
{
|
||||
return Color(n[0].as<float>(), n[1].as<float>(), n[2].as<float>(), n[3].as<float>());
|
||||
};
|
||||
@ -142,4 +143,6 @@ void ParticleComponent::Load(const YAML::Node& node)
|
||||
settings.loop = node["loop"].as<bool>();
|
||||
if (node["burst"])
|
||||
settings.burst = node["burst"].as<bool>();
|
||||
if (node["roundness"])
|
||||
settings.roundness = node["roundness"].as<float>();
|
||||
}
|
||||
|
@ -13,6 +13,22 @@
|
||||
|
||||
#include <string>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
enum class ParticleShape
|
||||
{
|
||||
Circle,
|
||||
Square,
|
||||
// Triangle,
|
||||
// Line,
|
||||
// Star,
|
||||
// Hexagon,
|
||||
// Diamond,
|
||||
// Cross,
|
||||
|
||||
// Outline
|
||||
MAX_SHAPE
|
||||
};
|
||||
|
||||
struct Particle
|
||||
{
|
||||
core::types::Vec2 position;
|
||||
@ -39,8 +55,11 @@ struct ParticleEmitterSettings
|
||||
core::types::Color endColor = {1, 1, 1, 0};
|
||||
bool loop = true;
|
||||
bool burst = false;
|
||||
|
||||
float roundness = 1.0f; // 0 = square, 1 = circle
|
||||
};
|
||||
|
||||
|
||||
class ParticleComponent : public Component
|
||||
{
|
||||
public:
|
||||
|
@ -1,81 +1,12 @@
|
||||
#include "SpriteComponent.h"
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
#include <unordered_map>
|
||||
#include <GL/glew.h>
|
||||
#include <iostream>
|
||||
#include "../core/utils/AssetManager.h"
|
||||
#include "../core/utils/Logging.h"
|
||||
#include "../core/utils/utils.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
SpriteComponent::SpriteComponent(Object *owner) : Component(owner) {}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
unsigned int SpriteComponent::LoadTexture(const std::string& path, bool updateSize)
|
||||
{
|
||||
auto [it, inserted] = textureCache.try_emplace(path, ImageCacheEntry{});
|
||||
|
||||
if (!inserted)
|
||||
{
|
||||
if (updateSize)
|
||||
size = it->second.size;
|
||||
Logger::LogDebug("Using Cached Image: '%s', Texture ID: %u", path.c_str(), it->second.textureID);
|
||||
return it->second.textureID;
|
||||
}
|
||||
|
||||
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': %s", path.c_str(), stbi_failure_reason());
|
||||
textureCache.erase(it);
|
||||
return 0;
|
||||
}
|
||||
|
||||
glm::vec2 imageSize(w, h);
|
||||
if (updateSize)
|
||||
size = imageSize;
|
||||
|
||||
unsigned int 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);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
stbi_image_free(data);
|
||||
|
||||
it->second = { id, imageSize };
|
||||
|
||||
Logger::LogDebug("Loaded Image: '%s' (%dx%d), Texture ID: %u", path.c_str(), w, h, id);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool SpriteComponent::HasTexture()
|
||||
{
|
||||
return texture_loaded;
|
||||
@ -83,22 +14,44 @@ bool SpriteComponent::HasTexture()
|
||||
|
||||
void SpriteComponent::SetTexture(const std::string &path)
|
||||
{
|
||||
if (path.empty())
|
||||
return;
|
||||
texturePath = path;
|
||||
textureID = LoadTexture(path, true);
|
||||
if (textureID != 0)
|
||||
{
|
||||
texture_loaded = true;
|
||||
}
|
||||
if (path.empty()) return;
|
||||
|
||||
AssetManager::LoadAssetAsync(path, AssetType::Image);
|
||||
const auto* asset = AssetManager::GetAssetByPath(path);
|
||||
if (asset)
|
||||
SetTexture(asset->uaid);
|
||||
}
|
||||
|
||||
void SpriteComponent::SetNormalMap(const std::string &path)
|
||||
{
|
||||
if (path.empty())
|
||||
return;
|
||||
normalMapPath = path;
|
||||
normalMapID = LoadTexture(path, false);
|
||||
if (path.empty()) return;
|
||||
|
||||
AssetManager::LoadAssetAsync(path, AssetType::Image);
|
||||
const auto* asset = AssetManager::GetAssetByPath(path);
|
||||
if (asset)
|
||||
SetNormalMap(asset->uaid);
|
||||
}
|
||||
|
||||
void SpriteComponent::SetTexture(uint64_t uaid)
|
||||
{
|
||||
textureUAID = uaid;
|
||||
const auto* asset = AssetManager::GetAssetByID(uaid);
|
||||
if (asset && asset->loaded)
|
||||
{
|
||||
textureID = asset->textureID;
|
||||
size = asset->size;
|
||||
texture_loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteComponent::SetNormalMap(uint64_t uaid)
|
||||
{
|
||||
normalMapUAID = uaid;
|
||||
const auto* asset = AssetManager::GetAssetByID(uaid);
|
||||
if (asset && asset->loaded)
|
||||
{
|
||||
normalMapID = asset->textureID;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int SpriteComponent::GetTextureID() const
|
||||
@ -111,62 +64,42 @@ unsigned int SpriteComponent::GetNormalMapID() const
|
||||
return normalMapID;
|
||||
}
|
||||
|
||||
std::string SpriteComponent::GetTexturePath() const
|
||||
uint64_t SpriteComponent::GetTextureUAID() const
|
||||
{
|
||||
return texturePath;
|
||||
return textureUAID;
|
||||
}
|
||||
|
||||
std::string SpriteComponent::GetNormalMapPath() const
|
||||
uint64_t SpriteComponent::GetNormalMapUAID() const
|
||||
{
|
||||
return normalMapPath;
|
||||
return normalMapUAID;
|
||||
}
|
||||
|
||||
void SpriteComponent::Save(YAML::Emitter &out) const
|
||||
{
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "type" << YAML::Value << "SpriteComponent";
|
||||
out << YAML::Key << "texture" << YAML::Value << texturePath;
|
||||
out << YAML::Key << "normalMap" << YAML::Value << normalMapPath;
|
||||
out << YAML::Key << "texture" << YAML::Value << textureUAID;
|
||||
out << YAML::Key << "normalMap" << YAML::Value << normalMapUAID;
|
||||
out << YAML::Key << "renderType" << YAML::Value << (renderType == RenderType::Lit ? "Lit" : "Unlit");
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
|
||||
|
||||
void SpriteComponent::Load(const YAML::Node& node)
|
||||
{
|
||||
try {
|
||||
if (!node["texture"])
|
||||
{
|
||||
RecoverableError("Missing 'texture' key in SpriteComponent YAML node", Create::Exceptions::MissingField).Handle();
|
||||
}
|
||||
else if (!node["texture"].IsScalar())
|
||||
{
|
||||
RecoverableError("'texture' field must be a string", Create::Exceptions::InvalidFormat).Handle();
|
||||
}
|
||||
else if (!node["texture"].as<std::string>().empty())
|
||||
{
|
||||
SetTexture(node["texture"].as<std::string>());
|
||||
}
|
||||
if (node["texture"])
|
||||
SetTexture(node["texture"].as<uint64_t>());
|
||||
|
||||
if (!node["normalMap"])
|
||||
{
|
||||
RecoverableError("Missing 'normalMap' key in SpriteComponent YAML node", Create::Exceptions::MissingField).Handle();
|
||||
}
|
||||
else if (!node["normalMap"].IsScalar())
|
||||
{
|
||||
RecoverableError("'normalMap' field must be a string", Create::Exceptions::InvalidFormat).Handle();
|
||||
}
|
||||
else if (!node["normalMap"].as<std::string>().empty())
|
||||
{
|
||||
SetNormalMap(node["normalMap"].as<std::string>());
|
||||
}
|
||||
if (node["normalMap"])
|
||||
SetNormalMap(node["normalMap"].as<uint64_t>());
|
||||
|
||||
if (node["renderType"] && node["renderType"].IsScalar()) {
|
||||
std::string typeStr = node["renderType"].as<std::string>();
|
||||
if (typeStr == "Lit") renderType = RenderType::Lit;
|
||||
else if (typeStr == "Unlit") renderType = RenderType::Unlit;
|
||||
else
|
||||
RecoverableError("Invalid 'renderType' value in SpriteComponent: " + typeStr, Create::Exceptions::InvalidFormat).Handle();
|
||||
RecoverableError("Invalid 'renderType' value in SpriteComponent: " + typeStr,
|
||||
Create::Exceptions::InvalidFormat).Handle();
|
||||
}
|
||||
|
||||
} catch (const YAML::Exception& e) {
|
||||
|
@ -3,54 +3,42 @@
|
||||
#include "Component.h"
|
||||
#include <string>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
|
||||
|
||||
|
||||
#include "../core/utils/AssetManager.h"
|
||||
#include "../core/utils/Texture.h"
|
||||
|
||||
|
||||
class SpriteComponent : public Component {
|
||||
public:
|
||||
SpriteComponent(Object* owner);
|
||||
|
||||
enum class RenderType {
|
||||
Unlit,
|
||||
Lit
|
||||
};
|
||||
|
||||
|
||||
void SetTexture(const std::string& path);
|
||||
void SetTexture(uint64_t uaid);
|
||||
void SetNormalMap(const std::string& path);
|
||||
void SetNormalMap(uint64_t uaid);
|
||||
|
||||
unsigned int GetTextureID() const;
|
||||
unsigned int GetNormalMapID() const;
|
||||
|
||||
std::string GetTexturePath() const;
|
||||
std::string GetNormalMapPath() const;
|
||||
uint64_t GetTextureUAID() const;
|
||||
uint64_t GetNormalMapUAID() const;
|
||||
|
||||
bool HasTexture();
|
||||
|
||||
RenderType GetRenderType() const { return renderType; }
|
||||
void SetRenderType(RenderType type) { renderType = type; }
|
||||
|
||||
virtual glm::vec2 GetSize() const { return size; }
|
||||
|
||||
virtual std::string GetName() const override { return "SpriteComponent"; }
|
||||
|
||||
virtual void Save(YAML::Emitter& out) const override;
|
||||
virtual void Load(const YAML::Node& node) override;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
glm::vec2 size = { 64, 64 };
|
||||
std::string texturePath;
|
||||
std::string normalMapPath;
|
||||
RenderType renderType = RenderType::Lit;
|
||||
|
||||
uint64_t textureUAID = 0;
|
||||
uint64_t normalMapUAID = 0;
|
||||
|
||||
unsigned int textureID = 0;
|
||||
unsigned int normalMapID = 0;
|
||||
bool texture_loaded = false;
|
||||
unsigned int LoadTexture(const std::string& path, bool updateSize);
|
||||
|
||||
|
||||
};
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "components/ParticleComponent.h"
|
||||
#include "components/AnimationComponent.h"
|
||||
|
||||
|
||||
#include "core/utils/FileDialog.h"
|
||||
#include "core/utils/Logging.h"
|
||||
|
||||
@ -489,7 +488,7 @@ void Engine::Init()
|
||||
// auto sprite = obj->AddComponent<SpriteComponent>();
|
||||
// sprite->SetTexture("C:/Users/spenc/OneDrive/Pictures/textures/ganges_river_pebbles_diff_1k.png");
|
||||
// sprite->SetNormalMap("C:/Users/spenc/OneDrive/Pictures/textures/ganges_river_pebbles_nor_gl_1k.png");
|
||||
// sprite->SetRenderType(SpriteComponent::RenderType::Lit);
|
||||
// sprite->SetRenderType(RenderType::Lit);
|
||||
//
|
||||
// objects.push_back(obj);
|
||||
// }
|
||||
@ -515,22 +514,26 @@ void Engine::Init()
|
||||
Logger::LogVerbose("Resverving Objects");
|
||||
|
||||
m_toDraw.reserve(1024);
|
||||
m_scriptUpdates.reserve(256);
|
||||
m_scriptUpdates.reserve(10);
|
||||
m_collectStack.reserve(1024);
|
||||
m_physicsUpdates.reserve(1024);
|
||||
m_particleUpdates.reserve(1024);
|
||||
m_particleUpdates.reserve(100);
|
||||
m_animationsUpdates.reserve(100);
|
||||
|
||||
Logger::LogInfo("Initialized Engine");
|
||||
}
|
||||
|
||||
void Engine::collectObjects(bool playing, const glm::vec2 &camPos, float camZoom)
|
||||
{
|
||||
|
||||
m_activeCamera = nullptr;
|
||||
|
||||
m_toDraw.clear();
|
||||
m_scriptUpdates.clear();
|
||||
m_animationsUpdates.clear();
|
||||
m_collectStack.clear();
|
||||
m_activeCamera = nullptr;
|
||||
m_physicsUpdates.clear();
|
||||
m_particleUpdates.clear(); // <-- Add this
|
||||
m_particleUpdates.clear();
|
||||
|
||||
const glm::vec2 screenSize = glm::vec2(Renderer::GetSize());
|
||||
|
||||
@ -566,6 +569,8 @@ void Engine::collectObjects(bool playing, const glm::vec2 &camPos, float camZoom
|
||||
|
||||
if (auto particles = obj->GetComponent<ParticleComponent>())
|
||||
m_particleUpdates.push_back(particles.get());
|
||||
if (auto animator = obj->GetComponent<AnimationComponent>())
|
||||
m_animationsUpdates.push_back(animator.get());
|
||||
|
||||
if (playing)
|
||||
{
|
||||
@ -696,7 +701,6 @@ void Engine::Run()
|
||||
ImGui::Checkbox("Profiler", &g_engineConfig.settings.show_profiler_window);
|
||||
ImGui::Checkbox("Assets", &g_engineConfig.settings.show_asset_window);
|
||||
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
@ -862,7 +866,6 @@ void Engine::Run()
|
||||
|
||||
m_OnUpdateCalls = 0;
|
||||
|
||||
|
||||
if (!g_engineConfig.settings.profile_editor)
|
||||
{
|
||||
profiler.BeginFrame();
|
||||
@ -888,6 +891,15 @@ void Engine::Run()
|
||||
}
|
||||
profiler.EndSection();
|
||||
|
||||
profiler.BeginSection("Animations");
|
||||
for (auto *animation : m_animationsUpdates)
|
||||
{
|
||||
profiler.BeginSection("Object: " + animation->GetOwner()->GetName());
|
||||
animation->Update(deltaTime);
|
||||
profiler.EndSection();
|
||||
}
|
||||
profiler.EndSection();
|
||||
|
||||
profiler.EndSection();
|
||||
|
||||
profiler.BeginSection("Render");
|
||||
@ -895,22 +907,21 @@ void Engine::Run()
|
||||
{
|
||||
const core::types::Vec2 worldPos = obj->GetWorldPosition();
|
||||
|
||||
if (auto spritePtr = obj->GetComponent<SpriteComponent>())
|
||||
if (auto sprite = obj->GetComponent<SpriteComponent>())
|
||||
{
|
||||
profiler.BeginSection("Draw Sprite: " + obj->GetName());
|
||||
Renderer::DrawSprite(spritePtr.get(), worldPos, cameraZoom, cameraPos);
|
||||
Renderer::DrawSprite(sprite.get(), worldPos, cameraZoom, cameraPos);
|
||||
profiler.EndSection();
|
||||
}
|
||||
|
||||
if (auto animator = obj->GetComponent<AnimationComponent>()) {
|
||||
profiler.BeginSection("Draw Animation: " + obj->GetName());
|
||||
|
||||
Renderer::DrawTextureAtlas(animator->GetAtlas(), animator->GetCurrentFrame(), obj->GetWorldPosition(), obj->GetWorldRotation(), 1.0f);
|
||||
|
||||
if (auto animator = obj->GetComponent<AnimationComponent>())
|
||||
{
|
||||
profiler.BeginSection("Draw Animator: " + obj->GetName());
|
||||
|
||||
Renderer::DrawAnimator(animator.get(), worldPos, cameraZoom, cameraPos);
|
||||
|
||||
profiler.EndSection();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (auto particle = obj->GetComponent<ParticleComponent>())
|
||||
{
|
||||
@ -926,7 +937,7 @@ void Engine::Run()
|
||||
|
||||
core::types::Vec2 pWorld = p.position + particle->GetOwner()->GetWorldPosition();
|
||||
core::types::Vec2 size = core::types::Vec2(p.size, p.size);
|
||||
Renderer::BatchQuad(pWorld, size, p.rotation, color, cameraPos, cameraZoom);
|
||||
Renderer::BatchQuad(pWorld, size, p.rotation, color, cameraPos, cameraZoom, settings.roundness);
|
||||
}
|
||||
|
||||
profiler.EndSection();
|
||||
@ -1117,7 +1128,6 @@ void Engine::SaveScene(const std::string &path)
|
||||
for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i)
|
||||
hashHex << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(hash[i]);
|
||||
|
||||
// Build final full YAML output
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "engine_version" << YAML::Value << g_engineConfig.version;
|
||||
out << YAML::Key << "scene_name" << YAML::Value << std::filesystem::path(path).stem().string();
|
||||
@ -1131,13 +1141,13 @@ void Engine::SaveScene(const std::string &path)
|
||||
out << YAML::Key << "brightness" << YAML::Value << Renderer::GetColorCorrection()->brightness;
|
||||
out << YAML::Key << "saturation" << YAML::Value << Renderer::GetColorCorrection()->saturation;
|
||||
out << YAML::Key << "gamma" << YAML::Value << Renderer::GetColorCorrection()->gamma;
|
||||
|
||||
out << YAML::Key << "bloom" << YAML::Value << Renderer::GetColorCorrection()->bloom;
|
||||
out << YAML::Key << "intensity" << YAML::Value << Renderer::GetColorCorrection()->intensity;
|
||||
out << YAML::Key << "threshold" << YAML::Value << Renderer::GetColorCorrection()->threshold;
|
||||
|
||||
out << YAML::EndMap;
|
||||
|
||||
AssetManager::Save(out);
|
||||
|
||||
out << YAML::EndMap;
|
||||
|
||||
std::ofstream file(path);
|
||||
@ -1147,7 +1157,6 @@ void Engine::SaveScene(const std::string &path)
|
||||
void Engine::LoadScene(const std::string &path)
|
||||
{
|
||||
Logger::LogDebug("[LoadScene] Reading Scene File.");
|
||||
|
||||
YAML::Node root = YAML::LoadFile(path);
|
||||
|
||||
Logger::LogDebug("[LoadScene] Verifying Scene");
|
||||
@ -1169,6 +1178,12 @@ void Engine::LoadScene(const std::string &path)
|
||||
Logger::LogWarning("[LoadScene] Scene hash does not match! File may be corrupted or tampered.");
|
||||
}
|
||||
|
||||
if (root["Assets"])
|
||||
{
|
||||
Logger::LogVerbose("[LoadScene] Loading Assets");
|
||||
AssetManager::Load(root["Assets"]);
|
||||
}
|
||||
|
||||
Logger::LogDebug("[LoadScene] Reseting Scene.");
|
||||
objects.clear();
|
||||
|
||||
@ -1196,7 +1211,6 @@ void Engine::LoadScene(const std::string &path)
|
||||
cc->saturation = data["saturation"].as<float>();
|
||||
if (data["gamma"])
|
||||
cc->gamma = data["gamma"].as<float>();
|
||||
|
||||
if (data["bloom"])
|
||||
cc->bloom = data["bloom"].as<bool>();
|
||||
if (data["intensity"])
|
||||
@ -1225,18 +1239,19 @@ void Engine::SaveState()
|
||||
out << YAML::Key << "brightness" << YAML::Value << Renderer::GetColorCorrection()->brightness;
|
||||
out << YAML::Key << "saturation" << YAML::Value << Renderer::GetColorCorrection()->saturation;
|
||||
out << YAML::Key << "gamma" << YAML::Value << Renderer::GetColorCorrection()->gamma;
|
||||
|
||||
out << YAML::Key << "bloom" << YAML::Value << Renderer::GetColorCorrection()->bloom;
|
||||
out << YAML::Key << "intensity" << YAML::Value << Renderer::GetColorCorrection()->intensity;
|
||||
out << YAML::Key << "threshold" << YAML::Value << Renderer::GetColorCorrection()->threshold;
|
||||
|
||||
out << YAML::EndMap;
|
||||
|
||||
AssetManager::Save(out);
|
||||
|
||||
out << YAML::EndMap;
|
||||
|
||||
savedStateYAML = out.c_str();
|
||||
Logger::LogVerbose("[SaveState] Scene serialized (%zu bytes)", savedStateYAML.size());
|
||||
}
|
||||
|
||||
void Engine::LoadState()
|
||||
{
|
||||
if (savedStateYAML.empty())
|
||||
@ -1256,6 +1271,12 @@ void Engine::LoadState()
|
||||
return;
|
||||
}
|
||||
|
||||
if (root["Assets"])
|
||||
{
|
||||
Logger::LogVerbose("[LoadState] Loading Assets");
|
||||
AssetManager::Load(root["Assets"]);
|
||||
}
|
||||
|
||||
objects.clear();
|
||||
|
||||
const auto &objectArray = root["objects"];
|
||||
@ -1263,7 +1284,6 @@ void Engine::LoadState()
|
||||
{
|
||||
auto obj = std::make_shared<Object>("[DefaultObject]");
|
||||
obj->Load(node);
|
||||
|
||||
objects.push_back(obj);
|
||||
}
|
||||
|
||||
@ -1281,7 +1301,6 @@ void Engine::LoadState()
|
||||
cc->saturation = data["saturation"].as<float>();
|
||||
if (data["gamma"])
|
||||
cc->gamma = data["gamma"].as<float>();
|
||||
|
||||
if (data["bloom"])
|
||||
cc->bloom = data["bloom"].as<bool>();
|
||||
if (data["intensity"])
|
||||
|
@ -10,6 +10,7 @@ class Object;
|
||||
class ScriptComponent;
|
||||
class PhysicsComponent;
|
||||
class ParticleComponent;
|
||||
class AnimationComponent;
|
||||
|
||||
class Engine
|
||||
{
|
||||
@ -36,6 +37,7 @@ private:
|
||||
|
||||
std::vector<Object *> m_toDraw;
|
||||
std::vector<ScriptComponent *> m_scriptUpdates;
|
||||
std::vector<AnimationComponent *> m_animationsUpdates;
|
||||
int m_OnUpdateCalls;
|
||||
|
||||
std::vector<std::shared_ptr<Object>> m_collectStack;
|
||||
|
@ -77,15 +77,16 @@ struct BatchedSprite
|
||||
glm::vec4 texCoords;
|
||||
GLuint textureID;
|
||||
GLuint normalMapID;
|
||||
SpriteComponent::RenderType renderType;
|
||||
RenderType renderType;
|
||||
SpriteComponent *sprite;
|
||||
};
|
||||
|
||||
struct SortedDrawEntry
|
||||
{
|
||||
BatchedSprite sprite;
|
||||
Shader *shader;
|
||||
bool useLighting;
|
||||
Shader *shader = nullptr;
|
||||
bool useLighting = true;
|
||||
bool usesUV = false;
|
||||
};
|
||||
|
||||
std::vector<CachedLightUniforms> s_LightUniforms;
|
||||
@ -162,25 +163,26 @@ void Renderer::InitQuadBatch()
|
||||
|
||||
std::size_t offset = 0;
|
||||
|
||||
glEnableVertexAttribArray(1); // pos
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(QuadInstance), (void *)(offset));
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(QuadInstance), (void *)offsetof(QuadInstance, screenPos));
|
||||
glVertexAttribDivisor(1, 1);
|
||||
offset += sizeof(glm::vec2);
|
||||
|
||||
glEnableVertexAttribArray(2); // size
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(QuadInstance), (void *)(offset));
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(QuadInstance), (void *)offsetof(QuadInstance, size));
|
||||
glVertexAttribDivisor(2, 1);
|
||||
offset += sizeof(glm::vec2);
|
||||
|
||||
glEnableVertexAttribArray(3); // rotation
|
||||
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(QuadInstance), (void *)(offset));
|
||||
glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(QuadInstance), (void *)offsetof(QuadInstance, rotation));
|
||||
glVertexAttribDivisor(3, 1);
|
||||
offset += sizeof(float);
|
||||
|
||||
glEnableVertexAttribArray(4); // color
|
||||
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(QuadInstance), (void *)(offset));
|
||||
glEnableVertexAttribArray(4);
|
||||
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(QuadInstance), (void *)offsetof(QuadInstance, color));
|
||||
glVertexAttribDivisor(4, 1);
|
||||
|
||||
glEnableVertexAttribArray(5);
|
||||
glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(QuadInstance), (void *)offsetof(QuadInstance, roundness));
|
||||
glVertexAttribDivisor(5, 1);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
@ -525,7 +527,14 @@ void Renderer::DrawQuad(const core::types::Vec2 &pos, const core::types::Vec2 &s
|
||||
|
||||
s_QuadBatch.push_back({pos, size, rotation, color});
|
||||
}
|
||||
void Renderer::BatchQuad(const core::types::Vec2 &worldPos, const core::types::Vec2 &size, float rotation, const core::types::Color &color, const core::types::Vec2 &cameraPos, float zoom)
|
||||
|
||||
void Renderer::BatchQuad(const core::types::Vec2 &worldPos,
|
||||
const core::types::Vec2 &size,
|
||||
float rotation,
|
||||
const core::types::Color &color,
|
||||
const core::types::Vec2 &cameraPos,
|
||||
float zoom,
|
||||
float isCircle)
|
||||
{
|
||||
if (s_QuadBatch.size() >= MAX_QUADS)
|
||||
FlushQuads();
|
||||
@ -533,7 +542,16 @@ void Renderer::BatchQuad(const core::types::Vec2 &worldPos, const core::types::V
|
||||
core::types::Vec2 screenPos = (worldPos - cameraPos) * zoom + core::types::Vec2(width * 0.5f, height * 0.5f);
|
||||
core::types::Vec2 finalSize = size * zoom;
|
||||
|
||||
s_QuadBatch.push_back({screenPos, finalSize, rotation, color});
|
||||
s_QuadBatch.push_back({screenPos, finalSize, rotation, color, isCircle});
|
||||
}
|
||||
|
||||
void Renderer::BatchCircle(const core::types::Vec2 &worldPos,
|
||||
const core::types::Vec2 &size,
|
||||
const core::types::Color &color,
|
||||
const core::types::Vec2 &cameraPos,
|
||||
float zoom)
|
||||
{
|
||||
BatchQuad(worldPos, size, 0.0f, color, cameraPos, zoom, 1.0f);
|
||||
}
|
||||
|
||||
void Renderer::DrawSprite(SpriteComponent *sprite, const glm::vec2 &pos, float zoom, glm::vec2 &CameraPos)
|
||||
@ -558,7 +576,7 @@ void Renderer::DrawSprite(SpriteComponent *sprite, const glm::vec2 &pos, float z
|
||||
|
||||
SortedDrawEntry drawEntry;
|
||||
drawEntry.sprite = entry;
|
||||
drawEntry.shader = (g_engineConfig.settings.lighting_enabled && entry.renderType == SpriteComponent::RenderType::Lit)
|
||||
drawEntry.shader = (g_engineConfig.settings.lighting_enabled && entry.renderType == RenderType::Lit)
|
||||
? &spriteShader
|
||||
: &unlitShader;
|
||||
drawEntry.useLighting = (drawEntry.shader == &spriteShader);
|
||||
@ -566,7 +584,6 @@ void Renderer::DrawSprite(SpriteComponent *sprite, const glm::vec2 &pos, float z
|
||||
sortedDrawList.push_back(drawEntry);
|
||||
}
|
||||
|
||||
|
||||
void Renderer::DrawTextureAtlas(const TextureAtlas *atlas, int index, const core::types::Vec2 &pos, float rotationDeg, float zoom)
|
||||
{
|
||||
PROFILE_DEEP_SCOPE("DrawTextureAtlas");
|
||||
@ -579,7 +596,10 @@ void Renderer::DrawTextureAtlas(const TextureAtlas *atlas, int index, const core
|
||||
const core::types::Vec2 uvMax = uvMin + atlas->GetFrameSizeUV();
|
||||
|
||||
glm::vec2 screenPos = pos * zoom + glm::vec2(width, height) * 0.5f;
|
||||
glm::vec2 finalSize = glm::vec2(1.0f) * zoom;
|
||||
|
||||
glm::vec2 frameSize = atlas->GetFrameSizeUV() * tex->GetSize();
|
||||
|
||||
glm::vec2 finalSize = frameSize * zoom;
|
||||
|
||||
BatchedSprite entry;
|
||||
entry.screenPos = screenPos;
|
||||
@ -587,7 +607,7 @@ void Renderer::DrawTextureAtlas(const TextureAtlas *atlas, int index, const core
|
||||
entry.rotationRad = glm::radians(rotationDeg);
|
||||
entry.textureID = tex->GetID();
|
||||
entry.normalMapID = defaultNormalMap;
|
||||
entry.renderType = SpriteComponent::RenderType::Unlit; // no lighting for raw atlas drawing
|
||||
entry.renderType = RenderType::Lit;
|
||||
entry.sprite = nullptr;
|
||||
entry.texCoords = glm::vec4(uvMin.x, uvMin.y, uvMax.x, uvMax.y);
|
||||
|
||||
@ -595,10 +615,51 @@ void Renderer::DrawTextureAtlas(const TextureAtlas *atlas, int index, const core
|
||||
drawEntry.sprite = entry;
|
||||
drawEntry.shader = &unlitShader;
|
||||
drawEntry.useLighting = false;
|
||||
drawEntry.usesUV = true; // <- Important!
|
||||
|
||||
sortedDrawList.push_back(drawEntry);
|
||||
}
|
||||
|
||||
void Renderer::DrawAnimator(const AnimationComponent *anim, const core::types::Vec2 &worldPos, float zoom, const core::types::Vec2 &cameraPos)
|
||||
{
|
||||
PROFILE_DEEP_SCOPE("Renderer::DrawAnimator");
|
||||
|
||||
if (!anim || !anim->GetAtlas() || !anim->GetAtlas()->texture)
|
||||
return;
|
||||
|
||||
const TextureAtlas *atlas = anim->GetAtlas();
|
||||
int frameIndex = anim->GetCurrentFrame();
|
||||
|
||||
if (frameIndex >= atlas->GetTotalFrames())
|
||||
return;
|
||||
|
||||
const auto &tex = atlas->texture;
|
||||
core::types::Vec2 uvMin = atlas->GetFrameUV(frameIndex);
|
||||
core::types::Vec2 uvMax = uvMin + atlas->GetFrameSizeUV();
|
||||
core::types::Vec2 texSize = tex->GetSize();
|
||||
|
||||
glm::vec2 screenPos = (worldPos - cameraPos) * zoom + glm::vec2(width, height) * 0.5f;
|
||||
glm::vec2 frameSize = atlas->GetFrameSizeUV() * texSize;
|
||||
glm::vec2 finalSize = frameSize * zoom;
|
||||
|
||||
BatchedSprite entry;
|
||||
entry.screenPos = screenPos;
|
||||
entry.size = finalSize;
|
||||
entry.rotationRad = 0.0f;
|
||||
entry.textureID = tex->GetID();
|
||||
entry.normalMapID = defaultNormalMap;
|
||||
entry.renderType = anim->renderType;
|
||||
entry.sprite = nullptr;
|
||||
entry.texCoords = glm::vec4(uvMin.x, uvMin.y, uvMax.x, uvMax.y);
|
||||
|
||||
SortedDrawEntry drawEntry;
|
||||
drawEntry.sprite = entry;
|
||||
drawEntry.shader = &unlitShader;
|
||||
drawEntry.useLighting = false;
|
||||
drawEntry.usesUV = true;
|
||||
|
||||
sortedDrawList.push_back(drawEntry);
|
||||
}
|
||||
void Renderer::FlushQuads()
|
||||
{
|
||||
PROFILE_ENGINE_SCOPE("Renderer::FlushQuads");
|
||||
@ -614,16 +675,8 @@ void Renderer::FlushQuads()
|
||||
|
||||
glBindVertexArray(s_QuadVAO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, s_QuadInstanceVBO);
|
||||
{
|
||||
PROFILE_DEEP_SCOPE("Upload");
|
||||
|
||||
s_UnlitQuadShader.Use();
|
||||
s_UnlitQuadShader.SetVec2("uScreen", glm::vec2(width, height));
|
||||
|
||||
glBindVertexArray(s_QuadVAO);
|
||||
// Write directly to mapped buffer
|
||||
std::memcpy(s_QuadMappedPtr, s_QuadBatch.data(), s_QuadBatch.size() * sizeof(QuadInstance));
|
||||
}
|
||||
std::memcpy(s_QuadMappedPtr, s_QuadBatch.data(), s_QuadBatch.size() * sizeof(QuadInstance));
|
||||
}
|
||||
|
||||
{
|
||||
@ -685,13 +738,26 @@ void Renderer::FlushSprites()
|
||||
}
|
||||
}
|
||||
|
||||
// Uniforms
|
||||
// Common uniforms
|
||||
currentShader->SetVec2("uPos", entry.sprite.screenPos);
|
||||
currentShader->SetVec2("uSize", entry.sprite.size);
|
||||
currentShader->SetFloat("uRotation", entry.sprite.rotationRad);
|
||||
currentShader->SetInt("uTex", 0);
|
||||
|
||||
// Textures
|
||||
// Set UVs if applicable
|
||||
if (entry.usesUV)
|
||||
{
|
||||
currentShader->SetVec2("uUVMin", glm::vec2(entry.sprite.texCoords.x, entry.sprite.texCoords.y));
|
||||
currentShader->SetVec2("uUVMax", glm::vec2(entry.sprite.texCoords.z, entry.sprite.texCoords.w));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Full UV range fallback
|
||||
currentShader->SetVec2("uUVMin", glm::vec2(0.0f));
|
||||
currentShader->SetVec2("uUVMax", glm::vec2(1.0f));
|
||||
}
|
||||
|
||||
// Bind textures
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, entry.sprite.textureID);
|
||||
|
||||
|
@ -6,6 +6,9 @@
|
||||
|
||||
#include "Components/TilemapComponent.h"
|
||||
#include "Components/SpriteComponent.h"
|
||||
#include "Components/SpriteComponent.h"
|
||||
#include "Components/AnimationComponent.h"
|
||||
|
||||
#include "core/utils/EngineConfig.h"
|
||||
#include "utils/Shader.h"
|
||||
#include "core/utils/Profiler.h"
|
||||
@ -20,7 +23,7 @@ struct ColorCorrection
|
||||
float gamma = 1.0f;
|
||||
|
||||
bool bloom = true;
|
||||
float threshold = 0.2f;
|
||||
float threshold = 1.0f;
|
||||
float intensity = 1.2f;
|
||||
|
||||
void Upload(Shader &shader) const
|
||||
@ -41,10 +44,11 @@ struct Light
|
||||
|
||||
struct QuadInstance
|
||||
{
|
||||
core::types::Vec2 pos;
|
||||
core::types::Vec2 screenPos;
|
||||
core::types::Vec2 size;
|
||||
float rotation;
|
||||
core::types::Color color;
|
||||
float roundness = 0.0f;
|
||||
};
|
||||
|
||||
class Renderer
|
||||
@ -80,10 +84,24 @@ public:
|
||||
|
||||
static void InitQuadBatch();
|
||||
static void DrawQuad(const core::types::Vec2 &pos, const core::types::Vec2 &size, float rotation, const core::types::Color &color);
|
||||
static void BatchQuad(const core::types::Vec2 &worldPos, const core::types::Vec2 &size, float rotation, const core::types::Color &color, const core::types::Vec2 &cameraPos, float zoom);
|
||||
static void BatchQuad(const core::types::Vec2 &worldPos,
|
||||
const core::types::Vec2 &size,
|
||||
float rotation,
|
||||
const core::types::Color &color,
|
||||
const core::types::Vec2 &cameraPos,
|
||||
float zoom,
|
||||
float isCircle = 0.0f);
|
||||
|
||||
static void BatchCircle(const core::types::Vec2 &worldPos,
|
||||
const core::types::Vec2 &size,
|
||||
const core::types::Color &color,
|
||||
const core::types::Vec2 &cameraPos,
|
||||
float zoom);
|
||||
|
||||
static void DrawTextureAtlas(const TextureAtlas *atlas, int index, const core::types::Vec2 &pos, float rotationDeg, float zoom);
|
||||
|
||||
static void DrawAnimator(const AnimationComponent *anim, const core::types::Vec2 &worldPos, float zoom, const core::types::Vec2 &cameraPos);
|
||||
|
||||
static void FlushQuads();
|
||||
|
||||
private:
|
||||
|
@ -9,62 +9,40 @@ namespace core
|
||||
namespace types
|
||||
{
|
||||
|
||||
struct Vec2i;
|
||||
|
||||
struct Vec2
|
||||
{
|
||||
float x{0}, y{0};
|
||||
|
||||
// Constructors
|
||||
Vec2() = default;
|
||||
Vec2(float x, float y) : x(x), y(y) {}
|
||||
Vec2(float v) : x(v), y(v) {}
|
||||
Vec2(const glm::vec2 &v) : x(v.x), y(v.y) {}
|
||||
Vec2(const Vec2i &v);
|
||||
|
||||
// Conversion to glm
|
||||
operator glm::vec2() const { return {x, y}; }
|
||||
|
||||
// Arithmetic operators
|
||||
Vec2 operator+(const Vec2 &rhs) const { return {x + rhs.x, y + rhs.y}; }
|
||||
Vec2 operator-(const Vec2 &rhs) const { return {x - rhs.x, y - rhs.y}; }
|
||||
Vec2 operator*(float scalar) const { return {x * scalar, y * scalar}; }
|
||||
Vec2 operator/(float scalar) const { return {x / scalar, y / scalar}; }
|
||||
|
||||
Vec2 &operator+=(const Vec2 &rhs)
|
||||
{
|
||||
x += rhs.x;
|
||||
y += rhs.y;
|
||||
return *this;
|
||||
}
|
||||
Vec2 &operator-=(const Vec2 &rhs)
|
||||
{
|
||||
x -= rhs.x;
|
||||
y -= rhs.y;
|
||||
return *this;
|
||||
}
|
||||
Vec2 &operator*=(float scalar)
|
||||
{
|
||||
x *= scalar;
|
||||
y *= scalar;
|
||||
return *this;
|
||||
}
|
||||
Vec2 &operator/=(float scalar)
|
||||
{
|
||||
x /= scalar;
|
||||
y /= scalar;
|
||||
return *this;
|
||||
}
|
||||
Vec2 operator*(const Vec2 &rhs) const { return {x * rhs.x, y * rhs.y}; }
|
||||
|
||||
Vec2 &operator+=(const Vec2 &rhs) { x += rhs.x; y += rhs.y; return *this; }
|
||||
Vec2 &operator-=(const Vec2 &rhs) { x -= rhs.x; y -= rhs.y; return *this; }
|
||||
Vec2 &operator*=(float scalar) { x *= scalar; y *= scalar; return *this; }
|
||||
Vec2 &operator/=(float scalar) { x /= scalar; y /= scalar; return *this; }
|
||||
|
||||
// Unary operators
|
||||
Vec2 operator-() const { return {-x, -y}; }
|
||||
|
||||
// Comparison
|
||||
bool operator==(const Vec2 &rhs) const { return x == rhs.x && y == rhs.y; }
|
||||
bool operator!=(const Vec2 &rhs) const { return !(*this == rhs); }
|
||||
|
||||
// Length
|
||||
float Length() const { return std::sqrt(x * x + y * y); }
|
||||
float LengthSquared() const { return x * x + y * y; }
|
||||
|
||||
// Normalization
|
||||
Vec2 Normalized() const
|
||||
{
|
||||
float len = Length();
|
||||
@ -81,40 +59,61 @@ namespace core
|
||||
}
|
||||
}
|
||||
|
||||
// Dot product
|
||||
float Dot(const Vec2 &rhs) const { return x * rhs.x + y * rhs.y; }
|
||||
|
||||
// Clamp
|
||||
void Clamp(const Vec2 &min, const Vec2 &max)
|
||||
{
|
||||
x = std::max(min.x, std::min(x, max.x));
|
||||
y = std::max(min.y, std::min(y, max.y));
|
||||
}
|
||||
|
||||
// Lerp
|
||||
static Vec2 Lerp(const Vec2 &a, const Vec2 &b, float t)
|
||||
{
|
||||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
// Distance
|
||||
static float Distance(const Vec2 &a, const Vec2 &b)
|
||||
{
|
||||
return (a - b).Length();
|
||||
}
|
||||
|
||||
// Serialization helpers (optional)
|
||||
friend std::ostream &operator<<(std::ostream &os, const Vec2 &v)
|
||||
{
|
||||
return os << "(" << v.x << ", " << v.y << ")";
|
||||
}
|
||||
};
|
||||
|
||||
// Scalar * Vec2 support
|
||||
inline Vec2 operator*(float scalar, const Vec2 &v)
|
||||
struct Vec2i
|
||||
{
|
||||
return v * scalar;
|
||||
}
|
||||
int x{0}, y{0};
|
||||
|
||||
Vec2i() = default;
|
||||
Vec2i(int x, int y) : x(x), y(y) {}
|
||||
Vec2i(int v) : x(v), y(v) {}
|
||||
Vec2i(const Vec2 &v) : x(static_cast<int>(v.x)), y(static_cast<int>(v.y)) {}
|
||||
|
||||
Vec2i operator+(const Vec2i &rhs) const { return {x + rhs.x, y + rhs.y}; }
|
||||
Vec2i operator-(const Vec2i &rhs) const { return {x - rhs.x, y - rhs.y}; }
|
||||
Vec2i operator*(int scalar) const { return {x * scalar, y * scalar}; }
|
||||
Vec2i operator/(int scalar) const { return {x / scalar, y / scalar}; }
|
||||
|
||||
Vec2 operator*(const Vec2 &rhs) const { return Vec2(x * rhs.x, y * rhs.y); }
|
||||
|
||||
Vec2i &operator+=(const Vec2i &rhs) { x += rhs.x; y += rhs.y; return *this; }
|
||||
Vec2i &operator-=(const Vec2i &rhs) { x -= rhs.x; y -= rhs.y; return *this; }
|
||||
Vec2i &operator*=(int scalar) { x *= scalar; y *= scalar; return *this; }
|
||||
Vec2i &operator/=(int scalar) { x /= scalar; y /= scalar; return *this; }
|
||||
|
||||
bool operator==(const Vec2i &rhs) const { return x == rhs.x && y == rhs.y; }
|
||||
bool operator!=(const Vec2i &rhs) const { return !(*this == rhs); }
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os, const Vec2i &v)
|
||||
{
|
||||
return os << "(" << v.x << ", " << v.y << ")";
|
||||
}
|
||||
};
|
||||
|
||||
inline Vec2 operator*(float scalar, const Vec2 &v) { return v * scalar; }
|
||||
|
||||
} // namespace types
|
||||
} // namespace core
|
||||
} // namespace core
|
@ -1,167 +1,167 @@
|
||||
#pragma once
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <new>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <type_traits>
|
||||
|
||||
#ifndef FV_ASSERT
|
||||
#define FV_ASSERT(cond) assert(cond)
|
||||
#endif
|
||||
|
||||
template<typename T, size_t SBO_CAP = 16>
|
||||
class FastVector {
|
||||
using StorageT = typename std::aligned_storage<sizeof(T), alignof(T)>::type;
|
||||
|
||||
StorageT sbo_[SBO_CAP];
|
||||
T* data_ = reinterpret_cast<T*>(sbo_);
|
||||
size_t size_ = 0;
|
||||
size_t capacity_ = SBO_CAP;
|
||||
bool heapAllocated_ = false;
|
||||
|
||||
inline void reallocate(size_t newCap) {
|
||||
T* newData = reinterpret_cast<T*>(std::malloc(newCap * sizeof(T)));
|
||||
if (!newData) std::abort();
|
||||
|
||||
if constexpr (std::is_trivially_copyable_v<T>) {
|
||||
std::memcpy(newData, data_, size_ * sizeof(T));
|
||||
} else {
|
||||
std::uninitialized_copy(data_, data_ + size_, newData);
|
||||
std::destroy(data_, data_ + size_);
|
||||
}
|
||||
|
||||
if (heapAllocated_) std::free(data_);
|
||||
data_ = newData;
|
||||
capacity_ = newCap;
|
||||
heapAllocated_ = true;
|
||||
}
|
||||
|
||||
public:
|
||||
inline FastVector() = default;
|
||||
|
||||
inline ~FastVector() {
|
||||
std::destroy(data_, data_ + size_);
|
||||
if (heapAllocated_) std::free(data_);
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
FastVector(const FastVector& other) {
|
||||
reserve(other.size_);
|
||||
if constexpr (std::is_trivially_copyable_v<T>) {
|
||||
std::memcpy(data_, other.data_, other.size_ * sizeof(T));
|
||||
} else {
|
||||
std::uninitialized_copy(other.data_, other.data_ + other.size_, data_);
|
||||
}
|
||||
size_ = other.size_;
|
||||
}
|
||||
|
||||
// Move constructor
|
||||
FastVector(FastVector&& other) noexcept {
|
||||
if (other.heapAllocated_) {
|
||||
data_ = other.data_;
|
||||
size_ = other.size_;
|
||||
capacity_ = other.capacity_;
|
||||
heapAllocated_ = true;
|
||||
} else {
|
||||
std::uninitialized_move(other.data_, other.data_ + other.size_, data_);
|
||||
}
|
||||
other.data_ = reinterpret_cast<T*>(other.sbo_);
|
||||
other.size_ = 0;
|
||||
other.capacity_ = SBO_CAP;
|
||||
other.heapAllocated_ = false;
|
||||
}
|
||||
|
||||
// Copy assignment
|
||||
FastVector& operator=(const FastVector& other) {
|
||||
if (this != &other) {
|
||||
clear();
|
||||
reserve(other.size_);
|
||||
if constexpr (std::is_trivially_copyable_v<T>) {
|
||||
std::memcpy(data_, other.data_, other.size_ * sizeof(T));
|
||||
} else {
|
||||
std::uninitialized_copy(other.data_, other.data_ + other.size_, data_);
|
||||
}
|
||||
size_ = other.size_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Move assignment
|
||||
FastVector& operator=(FastVector&& other) noexcept {
|
||||
if (this != &other) {
|
||||
clear();
|
||||
if (heapAllocated_) std::free(data_);
|
||||
|
||||
if (other.heapAllocated_) {
|
||||
data_ = other.data_;
|
||||
size_ = other.size_;
|
||||
capacity_ = other.capacity_;
|
||||
heapAllocated_ = true;
|
||||
} else {
|
||||
std::uninitialized_move(other.data_, other.data_ + other.size_, data_);
|
||||
}
|
||||
|
||||
other.data_ = reinterpret_cast<T*>(other.sbo_);
|
||||
other.size_ = 0;
|
||||
other.capacity_ = SBO_CAP;
|
||||
other.heapAllocated_ = false;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void push_back(const T& val) {
|
||||
if (size_ == capacity_) reallocate(capacity_ * 2);
|
||||
new (data_ + size_) T(val);
|
||||
++size_;
|
||||
}
|
||||
|
||||
inline void push_back(T&& val) {
|
||||
if (size_ == capacity_) reallocate(capacity_ * 2);
|
||||
new (data_ + size_) T(std::move(val));
|
||||
++size_;
|
||||
}
|
||||
|
||||
inline void pop_back() {
|
||||
FV_ASSERT(size_ > 0);
|
||||
--size_;
|
||||
std::destroy_at(data_ + size_);
|
||||
}
|
||||
|
||||
inline void clear() {
|
||||
std::destroy(data_, data_ + size_);
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
inline void reserve(size_t newCap) {
|
||||
if (newCap > capacity_) reallocate(newCap);
|
||||
}
|
||||
|
||||
inline void resize(size_t newSize) {
|
||||
if (newSize > capacity_) reallocate(newSize);
|
||||
if (newSize > size_) {
|
||||
std::uninitialized_value_construct(data_ + size_, data_ + newSize);
|
||||
} else {
|
||||
std::destroy(data_ + newSize, data_ + size_);
|
||||
}
|
||||
size_ = newSize;
|
||||
}
|
||||
|
||||
inline T& operator[](size_t i) {
|
||||
FV_ASSERT(i < size_);
|
||||
return data_[i];
|
||||
}
|
||||
|
||||
inline const T& operator[](size_t i) const {
|
||||
FV_ASSERT(i < size_);
|
||||
return data_[i];
|
||||
}
|
||||
|
||||
inline T* data() { return data_; }
|
||||
inline const T* data() const { return data_; }
|
||||
|
||||
inline size_t size() const { return size_; }
|
||||
inline size_t capacity() const { return capacity_; }
|
||||
inline bool empty() const { return size_ == 0; }
|
||||
};
|
||||
//#pragma once
|
||||
//#include <cstdlib>
|
||||
//#include <cstring>
|
||||
//#include <cassert>
|
||||
//#include <new>
|
||||
//#include <utility>
|
||||
//#include <algorithm>
|
||||
//#include <type_traits>
|
||||
//
|
||||
//#ifndef FV_ASSERT
|
||||
//#define FV_ASSERT(cond) assert(cond)
|
||||
//#endif
|
||||
//
|
||||
//template<typename T, size_t SBO_CAP = 16>
|
||||
//class FastVector {
|
||||
// using StorageT = typename std::aligned_storage<sizeof(T), alignof(T)>::type;
|
||||
//
|
||||
// StorageT sbo_[SBO_CAP];
|
||||
// T* data_ = reinterpret_cast<T*>(sbo_);
|
||||
// size_t size_ = 0;
|
||||
// size_t capacity_ = SBO_CAP;
|
||||
// bool heapAllocated_ = false;
|
||||
//
|
||||
// inline void reallocate(size_t newCap) {
|
||||
// T* newData = reinterpret_cast<T*>(std::malloc(newCap * sizeof(T)));
|
||||
// if (!newData) std::abort();
|
||||
//
|
||||
// if constexpr (std::is_trivially_copyable_v<T>) {
|
||||
// std::memcpy(newData, data_, size_ * sizeof(T));
|
||||
// } else {
|
||||
// std::uninitialized_copy(data_, data_ + size_, newData);
|
||||
// std::destroy(data_, data_ + size_);
|
||||
// }
|
||||
//
|
||||
// if (heapAllocated_) std::free(data_);
|
||||
// data_ = newData;
|
||||
// capacity_ = newCap;
|
||||
// heapAllocated_ = true;
|
||||
// }
|
||||
//
|
||||
//public:
|
||||
// inline FastVector() = default;
|
||||
//
|
||||
// inline ~FastVector() {
|
||||
// std::destroy(data_, data_ + size_);
|
||||
// if (heapAllocated_) std::free(data_);
|
||||
// }
|
||||
//
|
||||
// // Copy constructor
|
||||
// FastVector(const FastVector& other) {
|
||||
// reserve(other.size_);
|
||||
// if constexpr (std::is_trivially_copyable_v<T>) {
|
||||
// std::memcpy(data_, other.data_, other.size_ * sizeof(T));
|
||||
// } else {
|
||||
// std::uninitialized_copy(other.data_, other.data_ + other.size_, data_);
|
||||
// }
|
||||
// size_ = other.size_;
|
||||
// }
|
||||
//
|
||||
// // Move constructor
|
||||
// FastVector(FastVector&& other) noexcept {
|
||||
// if (other.heapAllocated_) {
|
||||
// data_ = other.data_;
|
||||
// size_ = other.size_;
|
||||
// capacity_ = other.capacity_;
|
||||
// heapAllocated_ = true;
|
||||
// } else {
|
||||
// std::uninitialized_move(other.data_, other.data_ + other.size_, data_);
|
||||
// }
|
||||
// other.data_ = reinterpret_cast<T*>(other.sbo_);
|
||||
// other.size_ = 0;
|
||||
// other.capacity_ = SBO_CAP;
|
||||
// other.heapAllocated_ = false;
|
||||
// }
|
||||
//
|
||||
// // Copy assignment
|
||||
// FastVector& operator=(const FastVector& other) {
|
||||
// if (this != &other) {
|
||||
// clear();
|
||||
// reserve(other.size_);
|
||||
// if constexpr (std::is_trivially_copyable_v<T>) {
|
||||
// std::memcpy(data_, other.data_, other.size_ * sizeof(T));
|
||||
// } else {
|
||||
// std::uninitialized_copy(other.data_, other.data_ + other.size_, data_);
|
||||
// }
|
||||
// size_ = other.size_;
|
||||
// }
|
||||
// return *this;
|
||||
// }
|
||||
//
|
||||
// // Move assignment
|
||||
// FastVector& operator=(FastVector&& other) noexcept {
|
||||
// if (this != &other) {
|
||||
// clear();
|
||||
// if (heapAllocated_) std::free(data_);
|
||||
//
|
||||
// if (other.heapAllocated_) {
|
||||
// data_ = other.data_;
|
||||
// size_ = other.size_;
|
||||
// capacity_ = other.capacity_;
|
||||
// heapAllocated_ = true;
|
||||
// } else {
|
||||
// std::uninitialized_move(other.data_, other.data_ + other.size_, data_);
|
||||
// }
|
||||
//
|
||||
// other.data_ = reinterpret_cast<T*>(other.sbo_);
|
||||
// other.size_ = 0;
|
||||
// other.capacity_ = SBO_CAP;
|
||||
// other.heapAllocated_ = false;
|
||||
// }
|
||||
// return *this;
|
||||
// }
|
||||
//
|
||||
// inline void push_back(const T& val) {
|
||||
// if (size_ == capacity_) reallocate(capacity_ * 2);
|
||||
// new (data_ + size_) T(val);
|
||||
// ++size_;
|
||||
// }
|
||||
//
|
||||
// inline void push_back(T&& val) {
|
||||
// if (size_ == capacity_) reallocate(capacity_ * 2);
|
||||
// new (data_ + size_) T(std::move(val));
|
||||
// ++size_;
|
||||
// }
|
||||
//
|
||||
// inline void pop_back() {
|
||||
// FV_ASSERT(size_ > 0);
|
||||
// --size_;
|
||||
// std::destroy_at(data_ + size_);
|
||||
// }
|
||||
//
|
||||
// inline void clear() {
|
||||
// std::destroy(data_, data_ + size_);
|
||||
// size_ = 0;
|
||||
// }
|
||||
//
|
||||
// inline void reserve(size_t newCap) {
|
||||
// if (newCap > capacity_) reallocate(newCap);
|
||||
// }
|
||||
//
|
||||
// inline void resize(size_t newSize) {
|
||||
// if (newSize > capacity_) reallocate(newSize);
|
||||
// if (newSize > size_) {
|
||||
// std::uninitialized_value_construct(data_ + size_, data_ + newSize);
|
||||
// } else {
|
||||
// std::destroy(data_ + newSize, data_ + size_);
|
||||
// }
|
||||
// size_ = newSize;
|
||||
// }
|
||||
//
|
||||
// inline T& operator[](size_t i) {
|
||||
// FV_ASSERT(i < size_);
|
||||
// return data_[i];
|
||||
// }
|
||||
//
|
||||
// inline const T& operator[](size_t i) const {
|
||||
// FV_ASSERT(i < size_);
|
||||
// return data_[i];
|
||||
// }
|
||||
//
|
||||
// inline T* data() { return data_; }
|
||||
// inline const T* data() const { return data_; }
|
||||
//
|
||||
// inline size_t size() const { return size_; }
|
||||
// inline size_t capacity() const { return capacity_; }
|
||||
// inline bool empty() const { return size_ == 0; }
|
||||
//};
|
||||
|
243
src/src/core/utils/AssetManager.cpp
Normal file
243
src/src/core/utils/AssetManager.cpp
Normal file
@ -0,0 +1,243 @@
|
||||
#include "AssetManager.h"
|
||||
#include "utils.h"
|
||||
#include "../../Renderer.h"
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
|
||||
#include <string>
|
||||
#include <random>
|
||||
#include <mutex>
|
||||
#include <functional> // for std::hash
|
||||
|
||||
std::unordered_map<uint64_t, AssetInfo> AssetManager::s_Assets;
|
||||
|
||||
std::mutex AssetManager::s_Mutex;
|
||||
uint64_t AssetManager::s_NextUAID = 1;
|
||||
|
||||
inline static std::unordered_map<std::string, uint64_t> s_PathToUAID;
|
||||
|
||||
inline std::string GetFileExtension(const std::string &path)
|
||||
{
|
||||
size_t dot = path.find_last_of('.');
|
||||
if (dot == std::string::npos)
|
||||
return "";
|
||||
return path.substr(dot + 1);
|
||||
}
|
||||
|
||||
inline GLuint CreateOpenGLTexture(unsigned char *data, int width, int height)
|
||||
{
|
||||
GLuint tex;
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
return tex;
|
||||
}
|
||||
|
||||
void AssetManager::Init() {}
|
||||
|
||||
uint64_t AssetManager::GenerateUAID()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_Mutex);
|
||||
|
||||
static std::random_device rd;
|
||||
static std::mt19937 gen(rd());
|
||||
static std::uniform_int_distribution<int> dist(0, 9);
|
||||
|
||||
std::string digits;
|
||||
digits.reserve(32);
|
||||
for (int i = 0; i < 32; ++i)
|
||||
digits += static_cast<char>('0' + dist(gen));
|
||||
|
||||
return std::hash<std::string>{}(digits);
|
||||
}
|
||||
|
||||
void AssetManager::LoadAssetAsync(const std::string &path, AssetType type)
|
||||
{
|
||||
uint64_t uaid = GenerateUAID();
|
||||
|
||||
AssetInfo info;
|
||||
info.uaid = uaid;
|
||||
info.path = path;
|
||||
info.filename = GetFilenameFromPath(path);
|
||||
info.filetype = GetFileExtension(path);
|
||||
info.type = type;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_Mutex);
|
||||
s_Assets[uaid] = info;
|
||||
}
|
||||
|
||||
if (type == AssetType::Image)
|
||||
{
|
||||
Logger::LogVerbose("[AssetManager] Loading image: %s (UAID: %llu)", path.c_str(), uaid);
|
||||
LoadImageInternal(path, uaid);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::LogWarning("Unknown Asset Type: '%d'", type);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetManager::LoadImageInternal(const std::string &path, uint64_t uaid)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_Mutex);
|
||||
auto it = s_PathToUAID.find(path);
|
||||
if (it != s_PathToUAID.end())
|
||||
{
|
||||
const auto &asset = s_Assets[it->second];
|
||||
if (asset.loaded)
|
||||
{
|
||||
Logger::LogVerbose("[AssetManager] Skipping already loaded asset: %s (UAID: %llu)", path.c_str(), asset.uaid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Logger::LogVerbose("[AssetManager] Begin loading image: %s (UAID: %llu)", path.c_str(), uaid);
|
||||
|
||||
stbi_set_flip_vertically_on_load(false);
|
||||
|
||||
int w, h, channels;
|
||||
stbi_uc *pixels = stbi_load(path.c_str(), &w, &h, &channels, STBI_rgb_alpha);
|
||||
if (!pixels)
|
||||
{
|
||||
Logger::LogError("[AssetManager] Failed to load image: %s", path.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
GLuint texID = CreateOpenGLTexture(pixels, w, h);
|
||||
stbi_image_free(pixels);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_Mutex);
|
||||
|
||||
auto &asset = s_Assets[uaid];
|
||||
asset.path = path;
|
||||
asset.filename = GetFilenameFromPath(path);
|
||||
asset.filetype = GetFileExtension(path);
|
||||
asset.size = {(float)w, (float)h};
|
||||
asset.textureID = texID;
|
||||
asset.type = AssetType::Image;
|
||||
asset.loaded = true;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_Mutex);
|
||||
s_PathToUAID[path] = uaid;
|
||||
}
|
||||
|
||||
Logger::LogVerbose("[AssetManager] Finished loading image: %s (%dx%d) (UAID: %llu, Texture ID: %u)",
|
||||
path.c_str(), w, h, uaid, texID);
|
||||
}
|
||||
|
||||
const AssetInfo *AssetManager::GetAssetByID(uint64_t uaid)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_Mutex);
|
||||
auto it = s_Assets.find(uaid);
|
||||
return (it != s_Assets.end()) ? &it->second : nullptr;
|
||||
}
|
||||
|
||||
const AssetInfo *AssetManager::GetAssetByPath(const std::string &path)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_Mutex);
|
||||
for (const auto &[id, asset] : s_Assets)
|
||||
if (asset.path == path)
|
||||
return &asset;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const std::unordered_map<uint64_t, AssetInfo> &AssetManager::GetAllAssets()
|
||||
{
|
||||
return s_Assets; // Assume read-only external usage
|
||||
}
|
||||
|
||||
void AssetManager::UnloadAsset(uint64_t uaid)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_Mutex);
|
||||
auto it = s_Assets.find(uaid);
|
||||
if (it != s_Assets.end())
|
||||
{
|
||||
if (it->second.textureID)
|
||||
glDeleteTextures(1, &it->second.textureID);
|
||||
s_Assets.erase(it);
|
||||
s_PathToUAID.erase(it->second.path);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void AssetManager::ClearAllAssets()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_Mutex);
|
||||
for (auto &[id, asset] : s_Assets)
|
||||
{
|
||||
if (asset.textureID)
|
||||
glDeleteTextures(1, &asset.textureID);
|
||||
}
|
||||
s_Assets.clear();
|
||||
s_PathToUAID.clear();
|
||||
|
||||
}
|
||||
|
||||
void AssetManager::Save(YAML::Emitter &out)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_Mutex);
|
||||
out << YAML::Key << "Assets";
|
||||
out << YAML::BeginSeq;
|
||||
|
||||
for (const auto &[uaid, asset] : s_Assets)
|
||||
{
|
||||
out << YAML::BeginMap;
|
||||
out << YAML::Key << "uaid" << YAML::Value << asset.uaid;
|
||||
out << YAML::Key << "path" << YAML::Value << asset.path;
|
||||
out << YAML::Key << "filename" << YAML::Value << asset.filename;
|
||||
out << YAML::Key << "filetype" << YAML::Value << asset.filetype;
|
||||
out << YAML::Key << "type" << YAML::Value << static_cast<int>(asset.type);
|
||||
out << YAML::Key << "size" << YAML::Value << YAML::Flow << YAML::BeginSeq << asset.size.x << asset.size.y << YAML::EndSeq;
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
|
||||
out << YAML::EndSeq;
|
||||
}
|
||||
|
||||
void AssetManager::Load(const YAML::Node &node)
|
||||
{
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
for (const auto &item : node)
|
||||
{
|
||||
AssetInfo asset;
|
||||
asset.uaid = item["uaid"].as<uint64_t>();
|
||||
asset.path = item["path"].as<std::string>();
|
||||
asset.filename = item["filename"].as<std::string>();
|
||||
asset.filetype = item["filetype"].as<std::string>();
|
||||
asset.type = static_cast<AssetType>(item["type"].as<int>());
|
||||
|
||||
const auto &size = item["size"];
|
||||
asset.size = {size[0].as<float>(), size[1].as<float>()};
|
||||
asset.loaded = false;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_Mutex);
|
||||
s_Assets[asset.uaid] = asset;
|
||||
if (asset.uaid >= s_NextUAID)
|
||||
s_NextUAID = asset.uaid + 1;
|
||||
}
|
||||
|
||||
if (asset.type == AssetType::Image)
|
||||
{
|
||||
Logger::LogVerbose("[AssetManager] Reloading from file: %s (UAID: %llu)", asset.path.c_str(), asset.uaid);
|
||||
LoadImageInternal(asset.path, asset.uaid);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::LogWarning("Unknown Asset Type: '%d'", asset.type);
|
||||
}
|
||||
}
|
||||
}
|
50
src/src/core/utils/AssetManager.h
Normal file
50
src/src/core/utils/AssetManager.h
Normal file
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <future>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
#include "../types/vec2.h"
|
||||
#include <GL/glew.h>
|
||||
|
||||
|
||||
enum class AssetType { Image, Audio };
|
||||
|
||||
struct AssetInfo
|
||||
{
|
||||
uint64_t uaid;
|
||||
std::string path;
|
||||
std::string filename;
|
||||
std::string filetype;
|
||||
AssetType type;
|
||||
core::types::Vec2 size;
|
||||
|
||||
bool loaded = false;
|
||||
GLuint textureID = 0;
|
||||
};
|
||||
|
||||
class AssetManager
|
||||
{
|
||||
public:
|
||||
static void Init();
|
||||
static void LoadAssetAsync(const std::string& path, AssetType type);
|
||||
static const AssetInfo* GetAssetByID(uint64_t uaid);
|
||||
static const AssetInfo* GetAssetByPath(const std::string& path);
|
||||
static const std::unordered_map<uint64_t, AssetInfo>& GetAllAssets();
|
||||
|
||||
static void UnloadAsset(uint64_t uaid);
|
||||
static void ClearAllAssets();
|
||||
|
||||
static void Save(YAML::Emitter& out);
|
||||
static void Load(const YAML::Node& node);
|
||||
|
||||
|
||||
private:
|
||||
static std::unordered_map<uint64_t, AssetInfo> s_Assets;
|
||||
static std::mutex s_Mutex;
|
||||
static uint64_t s_NextUAID;
|
||||
|
||||
static uint64_t GenerateUAID();
|
||||
static void LoadImageInternal(const std::string& path, uint64_t uaid);
|
||||
};
|
@ -7,7 +7,7 @@
|
||||
USER_SETTING(profile_enabled, bool, true) \
|
||||
USER_SETTING(show_color_correction_window, bool, false) \
|
||||
USER_SETTING(show_profiler_window, bool, false) \
|
||||
USER_SETTING(lighting_enabled, bool, true) \
|
||||
USER_SETTING(lighting_enabled, bool, false) \
|
||||
USER_SETTING(profile_deep, bool, false) \
|
||||
USER_SETTING(show_asset_window, bool, false) \
|
||||
USER_SETTING(profile_gpu, bool, false)
|
||||
|
@ -1,19 +1,41 @@
|
||||
#include "Texture.h"
|
||||
#include <GL/glew.h>
|
||||
#include <stb_image.h>
|
||||
#include <iostream>
|
||||
#include "utils.h"
|
||||
|
||||
#include "AssetManager.h"
|
||||
#include "Logging.h"
|
||||
|
||||
Texture::Texture(const std::string &path)
|
||||
{
|
||||
id = LoadTextureIfNeeded(path);
|
||||
if (!path.empty())
|
||||
{
|
||||
AssetManager::LoadAssetAsync(path, AssetType::Image);
|
||||
const auto *asset = AssetManager::GetAssetByPath(path);
|
||||
if (asset && asset->loaded)
|
||||
{
|
||||
id = asset->textureID;
|
||||
size = asset->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::LogError("[Texture] Failed to get asset for path: %s", path.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Texture::~Texture()
|
||||
Texture::Texture(uint64_t uaid)
|
||||
{
|
||||
const auto *asset = AssetManager::GetAssetByID(uaid);
|
||||
if (asset && asset->loaded)
|
||||
{
|
||||
id = asset->textureID;
|
||||
size = asset->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::LogError("[Texture] Failed to get asset for UAID: %llu", uaid);
|
||||
}
|
||||
}
|
||||
|
||||
Texture::~Texture() {}
|
||||
|
||||
unsigned int Texture::GetID() const
|
||||
{
|
||||
return id;
|
||||
|
@ -1,13 +1,26 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "../types/all.h"
|
||||
|
||||
|
||||
enum class RenderType {
|
||||
Unlit,
|
||||
Lit
|
||||
};
|
||||
|
||||
class Texture {
|
||||
public:
|
||||
Texture(const std::string& path);
|
||||
Texture(uint64_t uaid); // New constructor using UAID
|
||||
~Texture();
|
||||
|
||||
unsigned int GetID() const;
|
||||
|
||||
void SetSize(core::types::Vec2 newSize) {size = newSize;};
|
||||
core::types::Vec2 GetSize() {return size;};
|
||||
|
||||
|
||||
private:
|
||||
unsigned int id = 0;
|
||||
core::types::Vec2 size;
|
||||
};
|
||||
|
@ -6,36 +6,62 @@
|
||||
struct TextureAtlas
|
||||
{
|
||||
std::shared_ptr<Texture> texture;
|
||||
int columns = 1;
|
||||
int rows = 1;
|
||||
int frameWidth = 1;
|
||||
int frameHeight = 1;
|
||||
|
||||
TextureAtlas() = default;
|
||||
TextureAtlas(std::shared_ptr<Texture> tex, int cols, int rows)
|
||||
: texture(std::move(tex)), columns(cols), rows(rows) {}
|
||||
|
||||
inline core::types::Vec2 GetFrameUV(int index) const
|
||||
TextureAtlas(std::shared_ptr<Texture> tex, int texelW, int texelH)
|
||||
: texture(std::move(tex))
|
||||
{
|
||||
if (columns <= 0 || rows <= 0)
|
||||
{
|
||||
SetTexelSize(texelW, texelH);
|
||||
}
|
||||
|
||||
void SetTexelSize(int texelWidth, int texelHeight)
|
||||
{
|
||||
frameWidth = texelWidth;
|
||||
frameHeight = texelHeight;
|
||||
}
|
||||
|
||||
core::types::Vec2 GetFrameUV(int index) const
|
||||
{
|
||||
if (!texture || frameWidth <= 0 || frameHeight <= 0)
|
||||
return core::types::Vec2(0.0f);
|
||||
}
|
||||
|
||||
int x = index % columns;
|
||||
int y = index / columns;
|
||||
int texWidth = texture->GetSize().x;
|
||||
int texHeight = texture->GetSize().y;
|
||||
|
||||
float u = static_cast<float>(x) / static_cast<float>(columns);
|
||||
float v = static_cast<float>(y) / static_cast<float>(rows);
|
||||
int cols = texWidth / frameWidth;
|
||||
int x = index % cols;
|
||||
int y = index / cols;
|
||||
|
||||
float u = (float)(x * frameWidth) / (float)texWidth;
|
||||
float v = 1.0f - (float)((y + 1) * frameHeight) / (float)texHeight; // flip y
|
||||
|
||||
return core::types::Vec2(u, v);
|
||||
}
|
||||
|
||||
core::types::Vec2 GetFrameSizeUV() const
|
||||
{
|
||||
return core::types::Vec2(1.0f / float(columns), 1.0f / float(rows));
|
||||
if (!texture || frameWidth <= 0 || frameHeight <= 0)
|
||||
return core::types::Vec2(0.0f);
|
||||
|
||||
return core::types::Vec2(
|
||||
static_cast<float>(frameWidth) / texture->GetSize().x,
|
||||
static_cast<float>(frameHeight) / texture->GetSize().y
|
||||
);
|
||||
}
|
||||
|
||||
int GetTotalFrames() const
|
||||
{
|
||||
return columns * rows;
|
||||
if (!texture || frameWidth <= 0 || frameHeight <= 0)
|
||||
return 0;
|
||||
|
||||
int texWidth = texture->GetSize().x;
|
||||
int texHeight = texture->GetSize().y;
|
||||
int cols = texWidth / frameWidth;
|
||||
int rows = texHeight / frameHeight;
|
||||
|
||||
return cols * rows;
|
||||
}
|
||||
};
|
||||
|
@ -12,6 +12,44 @@ std::unordered_map<std::string, ImageCacheEntry> engineTextureCache;
|
||||
|
||||
|
||||
|
||||
|
||||
ImageCacheEntry LoadImageCache(const std::string& path)
|
||||
{
|
||||
auto [it, inserted] = textureCache.try_emplace(path, ImageCacheEntry{});
|
||||
|
||||
if (!inserted)
|
||||
{
|
||||
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)
|
||||
{
|
||||
auto [it, inserted] = textureCache.try_emplace(path, ImageCacheEntry{});
|
||||
@ -39,7 +77,8 @@ GLuint LoadTextureIfNeeded(const std::string &path)
|
||||
|
||||
it->second = { id, imageSize };
|
||||
|
||||
Logger::LogVerbose("Loaded Image: '%s'", path.c_str());
|
||||
Logger::LogVerbose("Loaded Image: (%d, %d) '%s'",w, h, path.c_str());
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "FileDialog.h"
|
||||
#include "EngineConfig.h"
|
||||
|
||||
#include "AssetManager.h"
|
||||
|
||||
struct ImageCacheEntry {
|
||||
unsigned int textureID;
|
||||
glm::vec2 size;
|
||||
@ -26,6 +28,8 @@ std::string GetFilenameFromPath(const std::string& path);
|
||||
|
||||
|
||||
GLuint LoadTextureIfNeeded(const std::string& path);
|
||||
ImageCacheEntry LoadImageCache(const std::string& path);
|
||||
|
||||
GLuint EngineLoadTextureIfNeeded(const std::string &path);
|
||||
|
||||
|
||||
|
@ -2,11 +2,10 @@
|
||||
#include <imgui.h>
|
||||
#include "../../core/utils/EngineConfig.h"
|
||||
#include "../../core/utils/utils.h"
|
||||
#include "../../core/utils/AssetManager.h"
|
||||
#include "../../Renderer.h"
|
||||
#include "../../core/utils/Logging.h"
|
||||
|
||||
extern std::unordered_map<std::string, ImageCacheEntry> textureCache;
|
||||
|
||||
static std::string assetSearchQuery;
|
||||
|
||||
void ShowAssetBrowser()
|
||||
@ -23,13 +22,10 @@ void ShowAssetBrowser()
|
||||
std::string path = OpenFileDialog(FileDialogType::Images);
|
||||
if (!path.empty())
|
||||
{
|
||||
LoadTextureIfNeeded(path);
|
||||
AssetManager::LoadAssetAsync(path, AssetType::Image);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ImGui::Separator();
|
||||
char buffer[256] = {};
|
||||
strncpy(buffer, assetSearchQuery.c_str(), sizeof(buffer) - 1);
|
||||
@ -40,7 +36,6 @@ void ShowAssetBrowser()
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::BeginChild("##AssetScroll", ImVec2(0, 0), true);
|
||||
|
||||
const float padding = 8.0f;
|
||||
@ -55,46 +50,51 @@ void ShowAssetBrowser()
|
||||
ImGui::Columns(columns, nullptr, false);
|
||||
|
||||
int idx = 0;
|
||||
for (auto it = textureCache.begin(); it != textureCache.end();)
|
||||
for (const auto& [uaid, asset] : AssetManager::GetAllAssets())
|
||||
{
|
||||
const std::string &path = it->first;
|
||||
auto &entry = it->second;
|
||||
if (asset.type != AssetType::Image || !asset.loaded)
|
||||
continue;
|
||||
|
||||
if (!assetSearchQuery.empty() &&
|
||||
path.find(assetSearchQuery) == std::string::npos)
|
||||
asset.filename.find(assetSearchQuery) == std::string::npos &&
|
||||
asset.path.find(assetSearchQuery) == std::string::npos)
|
||||
{
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
ImGui::PushID(idx++);
|
||||
std::string displayName = GetFilenameFromPath(path);
|
||||
std::string displayName = GetFilenameFromPath(asset.path);
|
||||
|
||||
if (ImGui::ImageButton("##Image",
|
||||
(ImTextureID)(intptr_t)entry.textureID,
|
||||
ImVec2(thumbnailSize, thumbnailSize),
|
||||
ImVec2(0, 0), ImVec2(1, 1)))
|
||||
ImGui::Image((ImTextureID)(intptr_t)asset.textureID,
|
||||
ImVec2(thumbnailSize, thumbnailSize));
|
||||
|
||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID))
|
||||
{
|
||||
// Optional: preview or inspect
|
||||
ImGui::SetDragDropPayload("ASSET_TEXTURE", &uaid, sizeof(uint64_t));
|
||||
|
||||
ImGui::Image((ImTextureID)(intptr_t)asset.textureID,
|
||||
ImVec2(thumbnailSize * 2, thumbnailSize * 2));
|
||||
ImGui::Text("%s", displayName.c_str());
|
||||
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
|
||||
// Tooltip
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("Path: %s", path.c_str());
|
||||
ImGui::Text("Texture ID: %u", entry.textureID);
|
||||
ImGui::Text("Size: %dx%d", entry.size.x, entry.size.y);
|
||||
ImGui::Text("Path: %s", asset.path.c_str());
|
||||
ImGui::Text("UAID: %llu", asset.uaid);
|
||||
ImGui::Text("Texture ID: %u", asset.textureID);
|
||||
ImGui::Text("Size: (%.0f, %.0f)", asset.size.x, asset.size.y);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
// Right-click menu
|
||||
if (ImGui::BeginPopupContextItem("AssetContext"))
|
||||
{
|
||||
if (ImGui::MenuItem("Unload"))
|
||||
{
|
||||
Logger::LogInfo("[AssetBrowser] Unloaded: %s", path.c_str());
|
||||
it = textureCache.erase(it);
|
||||
Logger::LogInfo("[AssetBrowser] Unloaded: %s", asset.path.c_str());
|
||||
AssetManager::UnloadAsset(uaid);
|
||||
ImGui::EndPopup();
|
||||
ImGui::PopID();
|
||||
continue;
|
||||
@ -102,28 +102,20 @@ void ShowAssetBrowser()
|
||||
|
||||
if (ImGui::MenuItem("Copy Path"))
|
||||
{
|
||||
ImGui::SetClipboardText(path.c_str());
|
||||
ImGui::SetClipboardText(asset.path.c_str());
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Copy UAID"))
|
||||
{
|
||||
ImGui::SetClipboardText(std::to_string(asset.uaid).c_str());
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (ImGui::BeginDragDropSource())
|
||||
{
|
||||
ImGui::SetDragDropPayload("ASSET_TEXTURE",
|
||||
path.c_str(),
|
||||
path.size() + 1);
|
||||
ImGui::Image((ImTextureID)(intptr_t)entry.textureID,
|
||||
ImVec2(thumbnailSize * 2, thumbnailSize * 2));
|
||||
ImGui::Text("%s", displayName.c_str());
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
|
||||
ImGui::TextWrapped("%s", displayName.c_str());
|
||||
ImGui::NextColumn();
|
||||
ImGui::PopID();
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
ImGui::Columns(1);
|
||||
|
@ -119,20 +119,23 @@ void DrawInspectorUI(std::shared_ptr<Object> selected)
|
||||
const char *renderTypes[] = {"Unlit", "Lit"};
|
||||
int currentTypeIndex = static_cast<int>(sprite->GetRenderType());
|
||||
if (ImGui::Combo("Render Type", ¤tTypeIndex, renderTypes, IM_ARRAYSIZE(renderTypes)))
|
||||
sprite->SetRenderType(static_cast<SpriteComponent::RenderType>(currentTypeIndex));
|
||||
sprite->SetRenderType(static_cast<RenderType>(currentTypeIndex));
|
||||
|
||||
ImGui::SeparatorText("Texture");
|
||||
|
||||
{
|
||||
std::string texFile = GetFilenameFromPath(sprite->GetTexturePath());
|
||||
const AssetInfo *asset = AssetManager::GetAssetByID(sprite->GetTextureUAID());
|
||||
std::string texFile = asset ? GetFilenameFromPath(asset->path) : "(None)";
|
||||
ImGui::Text("%s", texFile.c_str());
|
||||
|
||||
ImGui::Text(texFile.c_str());
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("ASSET_TEXTURE"))
|
||||
{
|
||||
const char *dropped = (const char *)payload->Data;
|
||||
sprite->SetTexture(dropped);
|
||||
if (payload->DataSize == sizeof(uint64_t))
|
||||
{
|
||||
uint64_t uaid = *reinterpret_cast<const uint64_t *>(payload->Data);
|
||||
sprite->SetTexture(uaid);
|
||||
}
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
@ -141,34 +144,39 @@ void DrawInspectorUI(std::shared_ptr<Object> selected)
|
||||
{
|
||||
auto path = OpenFileDialog(FileDialogType::Images);
|
||||
if (!path.empty())
|
||||
sprite->SetTexture(path);
|
||||
sprite->SetTexture(path); // Auto-registers and sets UAID
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SeparatorText("Normal Map");
|
||||
{
|
||||
std::string normFile = GetFilenameFromPath(sprite->GetNormalMapPath());
|
||||
const AssetInfo *asset = AssetManager::GetAssetByID(sprite->GetNormalMapUAID());
|
||||
std::string normFile = asset ? GetFilenameFromPath(asset->path) : "(None)";
|
||||
ImGui::Text("%s", normFile.c_str());
|
||||
|
||||
ImGui::Text(normFile.c_str());
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("ASSET_TEXTURE"))
|
||||
{
|
||||
const char *dropped = (const char *)payload->Data;
|
||||
sprite->SetNormalMap(dropped);
|
||||
if (payload->DataSize == sizeof(uint64_t))
|
||||
{
|
||||
uint64_t uaid = *reinterpret_cast<const uint64_t *>(payload->Data);
|
||||
sprite->SetNormalMap(uaid);
|
||||
}
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
if (ImGui::SmallButton("Load##SpriteNorm"))
|
||||
{
|
||||
auto path = OpenFileDialog(FileDialogType::Images);
|
||||
if (!path.empty())
|
||||
sprite->SetNormalMap(path);
|
||||
sprite->SetNormalMap(path); // Auto-registers and sets UAID
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SeparatorText("Info");
|
||||
|
||||
// — Size Display & Remove —
|
||||
glm::vec2 size = sprite->GetSize();
|
||||
ImGui::Text("Size: %.0f × %.0f", size.x, size.y);
|
||||
|
||||
@ -252,51 +260,61 @@ void DrawInspectorUI(std::shared_ptr<Object> selected)
|
||||
if (ImGui::Button("Remove ScriptComponent"))
|
||||
selected->RemoveComponent<ScriptComponent>();
|
||||
}
|
||||
|
||||
if (auto anim = selected->GetComponent<AnimationComponent>())
|
||||
{
|
||||
ImGui::SeparatorText("Animation Component");
|
||||
|
||||
static int columns = anim->GetAtlas()->columns;
|
||||
static int rows = anim->GetAtlas()->rows;
|
||||
static int frameWidth = anim->GetAtlas()->frameWidth;
|
||||
static int frameHeight = anim->GetAtlas()->frameHeight;
|
||||
static float frameDuration = anim->GetFrameDuration();
|
||||
static int frameIndex = anim->GetCurrentFrame();
|
||||
static int startFrame = 0;
|
||||
static int endFrame = 0;
|
||||
|
||||
// — Texture Preview & Selector —
|
||||
ImGui::SeparatorText("Texture Atlas");
|
||||
|
||||
{
|
||||
std::string texFile = GetFilenameFromPath(anim->GetTexturePath());
|
||||
ImGui::Text(texFile.c_str());
|
||||
|
||||
std::string texFile = "(None)";
|
||||
if (const auto* asset = AssetManager::GetAssetByID(anim->GetTextureUAID()))
|
||||
texFile = GetFilenameFromPath(asset->path);
|
||||
|
||||
ImGui::Text("%s", texFile.c_str());
|
||||
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("ASSET_TEXTURE"))
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("ASSET_TEXTURE"))
|
||||
{
|
||||
const char *dropped = (const char *)payload->Data;
|
||||
anim->SetTextureAtlas(dropped, columns, rows, frameDuration);
|
||||
uint64_t droppedUAID = *(const uint64_t*)payload->Data;
|
||||
anim->SetTextureAtlas(droppedUAID, frameWidth, frameHeight, frameDuration, startFrame, endFrame);
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
|
||||
if (ImGui::SmallButton("Load##AnimTex"))
|
||||
{
|
||||
auto path = OpenFileDialog(FileDialogType::Images);
|
||||
if (!path.empty())
|
||||
anim->SetTextureAtlas(path, columns, rows, frameDuration);
|
||||
std::string path = OpenFileDialog(FileDialogType::Images);
|
||||
if (const auto *asset = AssetManager::GetAssetByPath(path))
|
||||
anim->SetTextureAtlas(asset->uaid, frameWidth, frameHeight, frameDuration, startFrame, endFrame);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// — Grid settings —
|
||||
ImGui::InputInt("Columns", &columns);
|
||||
ImGui::InputInt("Rows", &rows);
|
||||
ImGui::InputInt("Texel Width", &frameWidth);
|
||||
ImGui::InputInt("Texel Height", &frameHeight);
|
||||
ImGui::InputFloat("Frame Duration", &frameDuration, 0.01f, 0.1f, "%.3f");
|
||||
|
||||
if (ImGui::Button("Apply Grid"))
|
||||
ImGui::InputInt("Start Frame", &startFrame);
|
||||
ImGui::InputInt("End Frame", &endFrame);
|
||||
|
||||
if (ImGui::Button("Apply"))
|
||||
{
|
||||
anim->SetTextureAtlas(anim->GetTexturePath(), columns, rows, frameDuration);
|
||||
if (const auto *asset = AssetManager::GetAssetByID(anim->GetTextureUAID()))
|
||||
anim->SetTextureAtlas(asset->uaid, frameWidth, frameHeight, frameDuration, startFrame, endFrame);
|
||||
|
||||
}
|
||||
|
||||
// — Playback Controls —
|
||||
ImGui::SeparatorText("Playback");
|
||||
|
||||
bool isPlaying = anim->IsPlaying();
|
||||
@ -318,7 +336,7 @@ void DrawInspectorUI(std::shared_ptr<Object> selected)
|
||||
}
|
||||
|
||||
// Frame scrubber
|
||||
int maxFrame = columns * rows - 1;
|
||||
int maxFrame = anim->GetAtlas()->GetTotalFrames() - 1;
|
||||
frameIndex = anim->GetCurrentFrame();
|
||||
if (ImGui::SliderInt("Current Frame", &frameIndex, 0, maxFrame))
|
||||
{
|
||||
@ -331,14 +349,13 @@ void DrawInspectorUI(std::shared_ptr<Object> selected)
|
||||
ImGui::SeparatorText("Atlas Viewer");
|
||||
|
||||
const float previewSize = 128.0f;
|
||||
ImVec2 uv0, uv1;
|
||||
|
||||
core::types::Vec2 uvMin = anim->GetAtlas()->GetFrameUV(frameIndex);
|
||||
core::types::Vec2 uvSize = anim->GetAtlas()->GetFrameSizeUV();
|
||||
uv0 = ImVec2(uvMin.x, uvMin.y);
|
||||
uv1 = ImVec2(uvMin.x + uvSize.x, uvMin.y + uvSize.y);
|
||||
|
||||
ImGui::Image((ImTextureID)(intptr_t)anim->GetAtlas()->texture->GetID(), ImVec2(previewSize, previewSize), uv0, uv1);
|
||||
ImVec2 uv0 = ImVec2(uvMin.x, uvMin.y + uvSize.y);
|
||||
ImVec2 uv1 = ImVec2(uvMin.x + uvSize.x, uvMin.y);
|
||||
|
||||
ImGui::Image((ImTextureID)(intptr_t)anim->GetAtlas()->texture->GetID(), ImVec2(previewSize, previewSize), uv1, uv0);
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
@ -367,6 +384,10 @@ void DrawInspectorUI(std::shared_ptr<Object> selected)
|
||||
ImGui::ColorEdit4("Start Color", &settings.startColor.r);
|
||||
ImGui::ColorEdit4("End Color", &settings.endColor.r);
|
||||
|
||||
bool isRound = settings.roundness > 0.5f;
|
||||
if (ImGui::Checkbox("Circle", &isRound))
|
||||
settings.roundness = isRound ? 1.0f : 0.0f;
|
||||
|
||||
ImGui::Checkbox("Loop", &settings.loop);
|
||||
ImGui::Checkbox("Burst", &settings.burst);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user