From bf3c244eb8a8b677682b8d9d207ce9921dc4b9a5 Mon Sep 17 00:00:00 2001 From: shuiyuPyLab Date: Sun, 9 Aug 2026 10:16:09 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E9=A1=B9=E7=9B=AE=E5=B7=B2=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E8=87=B3=20Gitee/GitHub=EF=BC=8C=E4=BB=85=E4=BF=9D?= =?UTF-8?q?=E7=95=99=E8=BF=81=E7=A7=BB=E8=AF=B4=E6=98=8E=20(tombstone)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 12 - .lang | 1 - Assets/cube.obj | 21 - Assets/pyramid.obj | 12 - CMakeLists.txt | 126 -- DESIGN.md | 1072 --------------- Demo/Demo.vcxproj | 87 -- Demo/Demo/Demo.vcxproj | 87 -- Demo/Demo/audio_demo.c | 118 -- Demo/Demo/compat_test.c | 221 --- Demo/Demo/cube_dodge.c | 80 -- Demo/Demo/d3d11_test.c | 95 -- Demo/Demo/editor_main.c | 682 ---------- Demo/Demo/game_test.c | 222 --- Demo/Demo/input_test.c | 89 -- Demo/Demo/light_test.c | 142 -- Demo/Demo/ly_interpreter.c | 290 ---- Demo/Demo/main.c | 224 ---- Demo/Demo/mesh_debug.c | 73 - Demo/Demo/obj_viewer.c | 206 --- Demo/Demo/open_world_demo.c | 384 ------ Demo/Demo/raw3d_test.c | 128 -- Demo/Demo/scene_test.c | 121 -- Demo/Demo/scene_test2.c | 54 - Demo/Demo/test.ly | 54 - Demo/audio_demo.c | 118 -- Demo/compat_test.c | 221 --- Demo/cube_dodge.c | 80 -- Demo/d3d11_test.c | 95 -- Demo/demo_rpg.py | 105 -- Demo/editor_main.c | 682 ---------- Demo/game_test.c | 222 --- Demo/input_test.c | 89 -- Demo/light_test.c | 142 -- Demo/lity_explorer.c | 256 ---- Demo/ly_interpreter.c | 290 ---- Demo/main.c | 224 ---- Demo/mesh_debug.c | 73 - Demo/obj_viewer.c | 206 --- Demo/open_world_demo.c | 384 ------ Demo/raw3d_test.c | 128 -- Demo/scene_test.c | 121 -- Demo/scene_test2.c | 54 - Demo/test.ly | 54 - Editor/Cargo.toml | 8 - Editor/editor.c | 304 ----- Editor/src/main.rs | 464 ------- EditorCS/EditorCS/Lity3DEditor.csproj | 15 - EditorCS/EditorCS/MainForm.cs | 369 ----- EditorCS/EditorCS/MiMoEditor.csproj.user | 8 - EditorCS/EditorCS/Program.cs | 11 - EditorCS/EditorCS/SceneIO.cs | 56 - EditorCS/EditorCS/SceneNode.cs | 52 - EditorCS/Lity3DEditor.csproj | 15 - EditorCS/MainForm.cs | 369 ----- EditorCS/MiMoEditor.csproj.user | 8 - EditorCS/Program.cs | 11 - EditorCS/SceneIO.cs | 56 - EditorCS/SceneNode.cs | 52 - .../obj/Lity3DEditor.csproj.nuget.dgspec.json | 70 - .../obj/Lity3DEditor.csproj.nuget.g.props | 15 - .../obj/Lity3DEditor.csproj.nuget.g.targets | 2 - ...CoreApp,Version=v9.0.AssemblyAttributes.cs | 4 - .../Lity3DEditor.AssemblyInfo.cs | 24 - .../Lity3DEditor.AssemblyInfoInputs.cache | 1 - ....GeneratedMSBuildEditorConfig.editorconfig | 22 - .../Lity3DEditor.GlobalUsings.g.cs | 10 - .../net9.0-windows/Lity3DEditor.assets.cache | Bin 160 -> 0 bytes ...ity3DEditor.csproj.CoreCompileInputs.cache | 1 - .../Lity3DEditor.csproj.FileListAbsolute.txt | 14 - .../Lity3DEditor.genruntimeconfig.cache | 1 - .../obj/Release/net9.0-windows/editor.pdb | Bin 17212 -> 0 bytes EditorCS/obj/project.assets.json | 75 -- EditorCS/obj/project.nuget.cache | 8 - Engine/ASM/asm_macros.inc | 137 -- Engine/ASM/math.asm | 1189 ----------------- Engine/ASM/math_c_fallback.h | 79 -- Engine/ASM/memory.asm | 180 --- Engine/ASM/profiling.asm | 148 -- Engine/ASM/string_ops.asm | 304 ----- Engine/Asset/mesh.h | 30 - Engine/Asset/texture.h | 12 - Engine/Audio/audio.c | 277 ---- Engine/Audio/audio.h | 62 - Engine/Core/asset_manager.c | 192 --- Engine/Core/asset_manager.h | 48 - Engine/Core/engine.c | 244 ---- Engine/Core/engine.h | 73 - Engine/Core/logger.c | 73 - Engine/Core/logger.h | 35 - Engine/Core/timer.c | 78 -- Engine/Core/timer.h | 28 - Engine/ECS/world.c | 100 -- Engine/ECS/world.h | 53 - Engine/Editor/bitmap_font.c | 303 ----- Engine/Editor/bitmap_font.h | 40 - Engine/Editor/editor.c | 122 -- Engine/Editor/editor.h | 55 - Engine/Editor/editor_2d.c | 124 -- Engine/Editor/editor_2d.h | 35 - Engine/Editor/glyph_atlas.c | 171 --- Engine/Editor/glyph_atlas.h | 28 - Engine/Editor/textlayer.h | 10 - Engine/Editor/uilayer.c | 252 ---- Engine/Editor/uilayer.h | 41 - Engine/Engine.vcxproj | 124 -- Engine/Engine/ASM/asm_macros.inc | 137 -- Engine/Engine/ASM/math.asm | 1189 ----------------- Engine/Engine/ASM/math_c_fallback.h | 79 -- Engine/Engine/ASM/memory.asm | 180 --- Engine/Engine/ASM/profiling.asm | 148 -- Engine/Engine/ASM/string_ops.asm | 304 ----- Engine/Engine/Asset/mesh.h | 30 - Engine/Engine/Asset/texture.h | 12 - Engine/Engine/Audio/audio.c | 277 ---- Engine/Engine/Audio/audio.h | 62 - Engine/Engine/Core/asset_manager.c | 192 --- Engine/Engine/Core/asset_manager.h | 48 - Engine/Engine/Core/engine.c | 244 ---- Engine/Engine/Core/engine.h | 73 - Engine/Engine/Core/logger.c | 73 - Engine/Engine/Core/logger.h | 35 - Engine/Engine/Core/timer.c | 78 -- Engine/Engine/Core/timer.h | 28 - Engine/Engine/ECS/world.c | 100 -- Engine/Engine/ECS/world.h | 53 - Engine/Engine/Editor/bitmap_font.c | 303 ----- Engine/Engine/Editor/bitmap_font.h | 40 - Engine/Engine/Editor/editor.c | 122 -- Engine/Engine/Editor/editor.h | 55 - Engine/Engine/Editor/editor_2d.c | 124 -- Engine/Engine/Editor/editor_2d.h | 35 - Engine/Engine/Editor/glyph_atlas.c | 171 --- Engine/Engine/Editor/glyph_atlas.h | 28 - Engine/Engine/Editor/textlayer.h | 10 - Engine/Engine/Editor/uilayer.c | 252 ---- Engine/Engine/Editor/uilayer.h | 41 - Engine/Engine/Engine.vcxproj | 124 -- Engine/Engine/Input/input.c | 138 -- Engine/Engine/Input/input.h | 88 -- Engine/Engine/Math/math_impl.c | 8 - Engine/Engine/Physics/physics.c | 373 ------ Engine/Engine/Physics/physics.h | 74 - Engine/Engine/Rendering/camera.c | 135 -- Engine/Engine/Rendering/camera.h | 54 - Engine/Engine/Rendering/camera_controller.c | 98 -- Engine/Engine/Rendering/camera_controller.h | 44 - Engine/Engine/Rendering/frustum.c | 60 - Engine/Engine/Rendering/frustum.h | 8 - Engine/Engine/Rendering/graphics_device.c | 189 --- Engine/Engine/Rendering/graphics_device.h | 25 - Engine/Engine/Rendering/lighting.c | 26 - Engine/Engine/Rendering/lighting.h | 17 - Engine/Engine/Rendering/material.c | 15 - Engine/Engine/Rendering/material.h | 23 - Engine/Engine/Rendering/mesh.c | 204 --- Engine/Engine/Rendering/mesh.h | 25 - Engine/Engine/Rendering/renderer.c | 118 -- Engine/Engine/Rendering/renderer.h | 36 - Engine/Engine/Rendering/shader.c | 84 -- Engine/Engine/Rendering/shader.h | 16 - Engine/Engine/Rendering/texture.c | 231 ---- Engine/Engine/Rendering/texture.h | 37 - Engine/Engine/Scene/scene_graph.c | 226 ---- Engine/Engine/Scene/scene_graph.h | 77 -- Engine/Engine/Scene/scene_render.c | 65 - Engine/Engine/Scene/scene_render.h | 41 - Engine/Engine/Scene/scene_serialize.c | 141 -- Engine/Engine/Scene/scene_serialize.h | 15 - Engine/Engine/Scripting/lua_engine.c | 60 - Engine/Engine/Scripting/lua_engine.h | 32 - Engine/Engine/Terrain/terrain.c | 289 ---- Engine/Engine/Terrain/terrain.h | 54 - Engine/Engine/Terrain/terrain_manager.c | 199 --- Engine/Engine/Terrain/terrain_manager.h | 42 - Engine/Engine/UI/ui.c | 401 ------ Engine/Engine/UI/ui.h | 74 - Engine/Engine/VisualScript/block_core.c | 159 --- Engine/Engine/VisualScript/block_core.h | 183 --- Engine/Engine/VisualScript/block_editor.c | 225 ---- Engine/Engine/VisualScript/block_editor.h | 63 - Engine/Engine/VisualScript/block_executor.c | 465 ------- Engine/Engine/VisualScript/block_executor.h | 86 -- Engine/Engine/VisualScript/block_font.inc | 99 -- .../Engine/VisualScript/block_interaction.c | 151 --- .../Engine/VisualScript/block_interaction.h | 44 - Engine/Engine/VisualScript/block_palette.c | 140 -- Engine/Engine/VisualScript/block_palette.h | 43 - Engine/Engine/VisualScript/block_renderer.c | 190 --- Engine/Engine/VisualScript/block_renderer.h | 32 - Engine/Engine/VisualScript/block_serializer.c | 415 ------ Engine/Engine/VisualScript/block_serializer.h | 19 - Engine/Engine/VisualScript/block_types.c | 326 ----- Engine/Engine/VisualScript/block_types.h | 25 - Engine/Engine/VisualScript/block_workspace.c | 171 --- Engine/Engine/VisualScript/block_workspace.h | 54 - Engine/Engine/Window/window.c | 198 --- Engine/Engine/Window/window.h | 47 - Engine/Engine/include/engine_api.h | 145 -- Engine/Input/input.c | 138 -- Engine/Input/input.h | 88 -- Engine/Math/math_impl.c | 8 - Engine/Physics/physics.c | 373 ------ Engine/Physics/physics.h | 74 - Engine/Rendering/camera.c | 135 -- Engine/Rendering/camera.h | 54 - Engine/Rendering/camera_controller.c | 98 -- Engine/Rendering/camera_controller.h | 44 - Engine/Rendering/frustum.c | 60 - Engine/Rendering/frustum.h | 8 - Engine/Rendering/graphics_device.c | 189 --- Engine/Rendering/graphics_device.h | 25 - Engine/Rendering/lighting.c | 26 - Engine/Rendering/lighting.h | 17 - Engine/Rendering/material.c | 15 - Engine/Rendering/material.h | 23 - Engine/Rendering/mesh.c | 204 --- Engine/Rendering/mesh.h | 25 - Engine/Rendering/renderer.c | 118 -- Engine/Rendering/renderer.h | 36 - Engine/Rendering/shader.c | 84 -- Engine/Rendering/shader.h | 16 - Engine/Rendering/texture.c | 231 ---- Engine/Rendering/texture.h | 37 - Engine/Scene/scene_graph.c | 226 ---- Engine/Scene/scene_graph.h | 77 -- Engine/Scene/scene_render.c | 65 - Engine/Scene/scene_render.h | 41 - Engine/Scene/scene_serialize.c | 141 -- Engine/Scene/scene_serialize.h | 15 - Engine/Scripting/lity.py | 598 --------- Engine/Scripting/lua_engine.c | 60 - Engine/Scripting/lua_engine.h | 32 - Engine/Terrain/terrain.c | 289 ---- Engine/Terrain/terrain.h | 54 - Engine/Terrain/terrain_manager.c | 199 --- Engine/Terrain/terrain_manager.h | 42 - Engine/UI/ui.c | 401 ------ Engine/UI/ui.h | 74 - Engine/VisualScript/block_core.c | 159 --- Engine/VisualScript/block_core.h | 183 --- Engine/VisualScript/block_editor.c | 225 ---- Engine/VisualScript/block_editor.h | 63 - Engine/VisualScript/block_executor.c | 465 ------- Engine/VisualScript/block_executor.h | 86 -- Engine/VisualScript/block_font.inc | 99 -- Engine/VisualScript/block_interaction.c | 151 --- Engine/VisualScript/block_interaction.h | 44 - Engine/VisualScript/block_palette.c | 140 -- Engine/VisualScript/block_palette.h | 43 - Engine/VisualScript/block_renderer.c | 190 --- Engine/VisualScript/block_renderer.h | 32 - Engine/VisualScript/block_serializer.c | 415 ------ Engine/VisualScript/block_serializer.h | 19 - Engine/VisualScript/block_types.c | 326 ----- Engine/VisualScript/block_types.h | 25 - Engine/VisualScript/block_workspace.c | 171 --- Engine/VisualScript/block_workspace.h | 54 - Engine/Window/window.c | 198 --- Engine/Window/window.h | 47 - Engine/include/engine_api.h | 145 -- LICENSE | 21 - README.md | 3 +- build.bat | 110 -- editor.py | 337 ----- generate_languages.py | 59 - i18n.py | 542 -------- languages/ar.json | 25 - languages/bg.json | 25 - languages/bn.json | 25 - languages/cs.json | 25 - languages/da.json | 25 - languages/de.json | 25 - languages/el.json | 25 - languages/en.json | 25 - languages/es.json | 25 - languages/et.json | 25 - languages/fa.json | 25 - languages/fi.json | 25 - languages/fr.json | 25 - languages/he.json | 25 - languages/hi.json | 25 - languages/hr.json | 25 - languages/hu.json | 25 - languages/id.json | 25 - languages/it.json | 25 - languages/ja.json | 25 - languages/ko.json | 25 - languages/lt.json | 25 - languages/lv.json | 25 - languages/ml.json | 25 - languages/ms.json | 25 - languages/nl.json | 25 - languages/no.json | 25 - languages/pl.json | 25 - languages/pt.json | 25 - languages/ro.json | 25 - languages/ru.json | 25 - languages/sk.json | 25 - languages/sk2.json | 25 - languages/sl.json | 25 - languages/sr.json | 25 - languages/sv.json | 25 - languages/sw.json | 25 - languages/ta.json | 25 - languages/te.json | 25 - languages/th.json | 25 - languages/tr.json | 25 - languages/uk.json | 25 - languages/vi.json | 25 - languages/zh.json | 25 - scene.txt | 5 - 引擎文件说明.md | 143 -- 313 files changed, 1 insertion(+), 36645 deletions(-) delete mode 100644 .gitignore delete mode 100644 .lang delete mode 100644 Assets/cube.obj delete mode 100644 Assets/pyramid.obj delete mode 100644 CMakeLists.txt delete mode 100644 DESIGN.md delete mode 100644 Demo/Demo.vcxproj delete mode 100644 Demo/Demo/Demo.vcxproj delete mode 100644 Demo/Demo/audio_demo.c delete mode 100644 Demo/Demo/compat_test.c delete mode 100644 Demo/Demo/cube_dodge.c delete mode 100644 Demo/Demo/d3d11_test.c delete mode 100644 Demo/Demo/editor_main.c delete mode 100644 Demo/Demo/game_test.c delete mode 100644 Demo/Demo/input_test.c delete mode 100644 Demo/Demo/light_test.c delete mode 100644 Demo/Demo/ly_interpreter.c delete mode 100644 Demo/Demo/main.c delete mode 100644 Demo/Demo/mesh_debug.c delete mode 100644 Demo/Demo/obj_viewer.c delete mode 100644 Demo/Demo/open_world_demo.c delete mode 100644 Demo/Demo/raw3d_test.c delete mode 100644 Demo/Demo/scene_test.c delete mode 100644 Demo/Demo/scene_test2.c delete mode 100644 Demo/Demo/test.ly delete mode 100644 Demo/audio_demo.c delete mode 100644 Demo/compat_test.c delete mode 100644 Demo/cube_dodge.c delete mode 100644 Demo/d3d11_test.c delete mode 100644 Demo/demo_rpg.py delete mode 100644 Demo/editor_main.c delete mode 100644 Demo/game_test.c delete mode 100644 Demo/input_test.c delete mode 100644 Demo/light_test.c delete mode 100644 Demo/lity_explorer.c delete mode 100644 Demo/ly_interpreter.c delete mode 100644 Demo/main.c delete mode 100644 Demo/mesh_debug.c delete mode 100644 Demo/obj_viewer.c delete mode 100644 Demo/open_world_demo.c delete mode 100644 Demo/raw3d_test.c delete mode 100644 Demo/scene_test.c delete mode 100644 Demo/scene_test2.c delete mode 100644 Demo/test.ly delete mode 100644 Editor/Cargo.toml delete mode 100644 Editor/editor.c delete mode 100644 Editor/src/main.rs delete mode 100644 EditorCS/EditorCS/Lity3DEditor.csproj delete mode 100644 EditorCS/EditorCS/MainForm.cs delete mode 100644 EditorCS/EditorCS/MiMoEditor.csproj.user delete mode 100644 EditorCS/EditorCS/Program.cs delete mode 100644 EditorCS/EditorCS/SceneIO.cs delete mode 100644 EditorCS/EditorCS/SceneNode.cs delete mode 100644 EditorCS/Lity3DEditor.csproj delete mode 100644 EditorCS/MainForm.cs delete mode 100644 EditorCS/MiMoEditor.csproj.user delete mode 100644 EditorCS/Program.cs delete mode 100644 EditorCS/SceneIO.cs delete mode 100644 EditorCS/SceneNode.cs delete mode 100644 EditorCS/obj/Lity3DEditor.csproj.nuget.dgspec.json delete mode 100644 EditorCS/obj/Lity3DEditor.csproj.nuget.g.props delete mode 100644 EditorCS/obj/Lity3DEditor.csproj.nuget.g.targets delete mode 100644 EditorCS/obj/Release/net9.0-windows/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs delete mode 100644 EditorCS/obj/Release/net9.0-windows/Lity3DEditor.AssemblyInfo.cs delete mode 100644 EditorCS/obj/Release/net9.0-windows/Lity3DEditor.AssemblyInfoInputs.cache delete mode 100644 EditorCS/obj/Release/net9.0-windows/Lity3DEditor.GeneratedMSBuildEditorConfig.editorconfig delete mode 100644 EditorCS/obj/Release/net9.0-windows/Lity3DEditor.GlobalUsings.g.cs delete mode 100644 EditorCS/obj/Release/net9.0-windows/Lity3DEditor.assets.cache delete mode 100644 EditorCS/obj/Release/net9.0-windows/Lity3DEditor.csproj.CoreCompileInputs.cache delete mode 100644 EditorCS/obj/Release/net9.0-windows/Lity3DEditor.csproj.FileListAbsolute.txt delete mode 100644 EditorCS/obj/Release/net9.0-windows/Lity3DEditor.genruntimeconfig.cache delete mode 100644 EditorCS/obj/Release/net9.0-windows/editor.pdb delete mode 100644 EditorCS/obj/project.assets.json delete mode 100644 EditorCS/obj/project.nuget.cache delete mode 100644 Engine/ASM/asm_macros.inc delete mode 100644 Engine/ASM/math.asm delete mode 100644 Engine/ASM/math_c_fallback.h delete mode 100644 Engine/ASM/memory.asm delete mode 100644 Engine/ASM/profiling.asm delete mode 100644 Engine/ASM/string_ops.asm delete mode 100644 Engine/Asset/mesh.h delete mode 100644 Engine/Asset/texture.h delete mode 100644 Engine/Audio/audio.c delete mode 100644 Engine/Audio/audio.h delete mode 100644 Engine/Core/asset_manager.c delete mode 100644 Engine/Core/asset_manager.h delete mode 100644 Engine/Core/engine.c delete mode 100644 Engine/Core/engine.h delete mode 100644 Engine/Core/logger.c delete mode 100644 Engine/Core/logger.h delete mode 100644 Engine/Core/timer.c delete mode 100644 Engine/Core/timer.h delete mode 100644 Engine/ECS/world.c delete mode 100644 Engine/ECS/world.h delete mode 100644 Engine/Editor/bitmap_font.c delete mode 100644 Engine/Editor/bitmap_font.h delete mode 100644 Engine/Editor/editor.c delete mode 100644 Engine/Editor/editor.h delete mode 100644 Engine/Editor/editor_2d.c delete mode 100644 Engine/Editor/editor_2d.h delete mode 100644 Engine/Editor/glyph_atlas.c delete mode 100644 Engine/Editor/glyph_atlas.h delete mode 100644 Engine/Editor/textlayer.h delete mode 100644 Engine/Editor/uilayer.c delete mode 100644 Engine/Editor/uilayer.h delete mode 100644 Engine/Engine.vcxproj delete mode 100644 Engine/Engine/ASM/asm_macros.inc delete mode 100644 Engine/Engine/ASM/math.asm delete mode 100644 Engine/Engine/ASM/math_c_fallback.h delete mode 100644 Engine/Engine/ASM/memory.asm delete mode 100644 Engine/Engine/ASM/profiling.asm delete mode 100644 Engine/Engine/ASM/string_ops.asm delete mode 100644 Engine/Engine/Asset/mesh.h delete mode 100644 Engine/Engine/Asset/texture.h delete mode 100644 Engine/Engine/Audio/audio.c delete mode 100644 Engine/Engine/Audio/audio.h delete mode 100644 Engine/Engine/Core/asset_manager.c delete mode 100644 Engine/Engine/Core/asset_manager.h delete mode 100644 Engine/Engine/Core/engine.c delete mode 100644 Engine/Engine/Core/engine.h delete mode 100644 Engine/Engine/Core/logger.c delete mode 100644 Engine/Engine/Core/logger.h delete mode 100644 Engine/Engine/Core/timer.c delete mode 100644 Engine/Engine/Core/timer.h delete mode 100644 Engine/Engine/ECS/world.c delete mode 100644 Engine/Engine/ECS/world.h delete mode 100644 Engine/Engine/Editor/bitmap_font.c delete mode 100644 Engine/Engine/Editor/bitmap_font.h delete mode 100644 Engine/Engine/Editor/editor.c delete mode 100644 Engine/Engine/Editor/editor.h delete mode 100644 Engine/Engine/Editor/editor_2d.c delete mode 100644 Engine/Engine/Editor/editor_2d.h delete mode 100644 Engine/Engine/Editor/glyph_atlas.c delete mode 100644 Engine/Engine/Editor/glyph_atlas.h delete mode 100644 Engine/Engine/Editor/textlayer.h delete mode 100644 Engine/Engine/Editor/uilayer.c delete mode 100644 Engine/Engine/Editor/uilayer.h delete mode 100644 Engine/Engine/Engine.vcxproj delete mode 100644 Engine/Engine/Input/input.c delete mode 100644 Engine/Engine/Input/input.h delete mode 100644 Engine/Engine/Math/math_impl.c delete mode 100644 Engine/Engine/Physics/physics.c delete mode 100644 Engine/Engine/Physics/physics.h delete mode 100644 Engine/Engine/Rendering/camera.c delete mode 100644 Engine/Engine/Rendering/camera.h delete mode 100644 Engine/Engine/Rendering/camera_controller.c delete mode 100644 Engine/Engine/Rendering/camera_controller.h delete mode 100644 Engine/Engine/Rendering/frustum.c delete mode 100644 Engine/Engine/Rendering/frustum.h delete mode 100644 Engine/Engine/Rendering/graphics_device.c delete mode 100644 Engine/Engine/Rendering/graphics_device.h delete mode 100644 Engine/Engine/Rendering/lighting.c delete mode 100644 Engine/Engine/Rendering/lighting.h delete mode 100644 Engine/Engine/Rendering/material.c delete mode 100644 Engine/Engine/Rendering/material.h delete mode 100644 Engine/Engine/Rendering/mesh.c delete mode 100644 Engine/Engine/Rendering/mesh.h delete mode 100644 Engine/Engine/Rendering/renderer.c delete mode 100644 Engine/Engine/Rendering/renderer.h delete mode 100644 Engine/Engine/Rendering/shader.c delete mode 100644 Engine/Engine/Rendering/shader.h delete mode 100644 Engine/Engine/Rendering/texture.c delete mode 100644 Engine/Engine/Rendering/texture.h delete mode 100644 Engine/Engine/Scene/scene_graph.c delete mode 100644 Engine/Engine/Scene/scene_graph.h delete mode 100644 Engine/Engine/Scene/scene_render.c delete mode 100644 Engine/Engine/Scene/scene_render.h delete mode 100644 Engine/Engine/Scene/scene_serialize.c delete mode 100644 Engine/Engine/Scene/scene_serialize.h delete mode 100644 Engine/Engine/Scripting/lua_engine.c delete mode 100644 Engine/Engine/Scripting/lua_engine.h delete mode 100644 Engine/Engine/Terrain/terrain.c delete mode 100644 Engine/Engine/Terrain/terrain.h delete mode 100644 Engine/Engine/Terrain/terrain_manager.c delete mode 100644 Engine/Engine/Terrain/terrain_manager.h delete mode 100644 Engine/Engine/UI/ui.c delete mode 100644 Engine/Engine/UI/ui.h delete mode 100644 Engine/Engine/VisualScript/block_core.c delete mode 100644 Engine/Engine/VisualScript/block_core.h delete mode 100644 Engine/Engine/VisualScript/block_editor.c delete mode 100644 Engine/Engine/VisualScript/block_editor.h delete mode 100644 Engine/Engine/VisualScript/block_executor.c delete mode 100644 Engine/Engine/VisualScript/block_executor.h delete mode 100644 Engine/Engine/VisualScript/block_font.inc delete mode 100644 Engine/Engine/VisualScript/block_interaction.c delete mode 100644 Engine/Engine/VisualScript/block_interaction.h delete mode 100644 Engine/Engine/VisualScript/block_palette.c delete mode 100644 Engine/Engine/VisualScript/block_palette.h delete mode 100644 Engine/Engine/VisualScript/block_renderer.c delete mode 100644 Engine/Engine/VisualScript/block_renderer.h delete mode 100644 Engine/Engine/VisualScript/block_serializer.c delete mode 100644 Engine/Engine/VisualScript/block_serializer.h delete mode 100644 Engine/Engine/VisualScript/block_types.c delete mode 100644 Engine/Engine/VisualScript/block_types.h delete mode 100644 Engine/Engine/VisualScript/block_workspace.c delete mode 100644 Engine/Engine/VisualScript/block_workspace.h delete mode 100644 Engine/Engine/Window/window.c delete mode 100644 Engine/Engine/Window/window.h delete mode 100644 Engine/Engine/include/engine_api.h delete mode 100644 Engine/Input/input.c delete mode 100644 Engine/Input/input.h delete mode 100644 Engine/Math/math_impl.c delete mode 100644 Engine/Physics/physics.c delete mode 100644 Engine/Physics/physics.h delete mode 100644 Engine/Rendering/camera.c delete mode 100644 Engine/Rendering/camera.h delete mode 100644 Engine/Rendering/camera_controller.c delete mode 100644 Engine/Rendering/camera_controller.h delete mode 100644 Engine/Rendering/frustum.c delete mode 100644 Engine/Rendering/frustum.h delete mode 100644 Engine/Rendering/graphics_device.c delete mode 100644 Engine/Rendering/graphics_device.h delete mode 100644 Engine/Rendering/lighting.c delete mode 100644 Engine/Rendering/lighting.h delete mode 100644 Engine/Rendering/material.c delete mode 100644 Engine/Rendering/material.h delete mode 100644 Engine/Rendering/mesh.c delete mode 100644 Engine/Rendering/mesh.h delete mode 100644 Engine/Rendering/renderer.c delete mode 100644 Engine/Rendering/renderer.h delete mode 100644 Engine/Rendering/shader.c delete mode 100644 Engine/Rendering/shader.h delete mode 100644 Engine/Rendering/texture.c delete mode 100644 Engine/Rendering/texture.h delete mode 100644 Engine/Scene/scene_graph.c delete mode 100644 Engine/Scene/scene_graph.h delete mode 100644 Engine/Scene/scene_render.c delete mode 100644 Engine/Scene/scene_render.h delete mode 100644 Engine/Scene/scene_serialize.c delete mode 100644 Engine/Scene/scene_serialize.h delete mode 100644 Engine/Scripting/lity.py delete mode 100644 Engine/Scripting/lua_engine.c delete mode 100644 Engine/Scripting/lua_engine.h delete mode 100644 Engine/Terrain/terrain.c delete mode 100644 Engine/Terrain/terrain.h delete mode 100644 Engine/Terrain/terrain_manager.c delete mode 100644 Engine/Terrain/terrain_manager.h delete mode 100644 Engine/UI/ui.c delete mode 100644 Engine/UI/ui.h delete mode 100644 Engine/VisualScript/block_core.c delete mode 100644 Engine/VisualScript/block_core.h delete mode 100644 Engine/VisualScript/block_editor.c delete mode 100644 Engine/VisualScript/block_editor.h delete mode 100644 Engine/VisualScript/block_executor.c delete mode 100644 Engine/VisualScript/block_executor.h delete mode 100644 Engine/VisualScript/block_font.inc delete mode 100644 Engine/VisualScript/block_interaction.c delete mode 100644 Engine/VisualScript/block_interaction.h delete mode 100644 Engine/VisualScript/block_palette.c delete mode 100644 Engine/VisualScript/block_palette.h delete mode 100644 Engine/VisualScript/block_renderer.c delete mode 100644 Engine/VisualScript/block_renderer.h delete mode 100644 Engine/VisualScript/block_serializer.c delete mode 100644 Engine/VisualScript/block_serializer.h delete mode 100644 Engine/VisualScript/block_types.c delete mode 100644 Engine/VisualScript/block_types.h delete mode 100644 Engine/VisualScript/block_workspace.c delete mode 100644 Engine/VisualScript/block_workspace.h delete mode 100644 Engine/Window/window.c delete mode 100644 Engine/Window/window.h delete mode 100644 Engine/include/engine_api.h delete mode 100644 LICENSE delete mode 100644 build.bat delete mode 100644 editor.py delete mode 100644 generate_languages.py delete mode 100644 i18n.py delete mode 100644 languages/ar.json delete mode 100644 languages/bg.json delete mode 100644 languages/bn.json delete mode 100644 languages/cs.json delete mode 100644 languages/da.json delete mode 100644 languages/de.json delete mode 100644 languages/el.json delete mode 100644 languages/en.json delete mode 100644 languages/es.json delete mode 100644 languages/et.json delete mode 100644 languages/fa.json delete mode 100644 languages/fi.json delete mode 100644 languages/fr.json delete mode 100644 languages/he.json delete mode 100644 languages/hi.json delete mode 100644 languages/hr.json delete mode 100644 languages/hu.json delete mode 100644 languages/id.json delete mode 100644 languages/it.json delete mode 100644 languages/ja.json delete mode 100644 languages/ko.json delete mode 100644 languages/lt.json delete mode 100644 languages/lv.json delete mode 100644 languages/ml.json delete mode 100644 languages/ms.json delete mode 100644 languages/nl.json delete mode 100644 languages/no.json delete mode 100644 languages/pl.json delete mode 100644 languages/pt.json delete mode 100644 languages/ro.json delete mode 100644 languages/ru.json delete mode 100644 languages/sk.json delete mode 100644 languages/sk2.json delete mode 100644 languages/sl.json delete mode 100644 languages/sr.json delete mode 100644 languages/sv.json delete mode 100644 languages/sw.json delete mode 100644 languages/ta.json delete mode 100644 languages/te.json delete mode 100644 languages/th.json delete mode 100644 languages/tr.json delete mode 100644 languages/uk.json delete mode 100644 languages/vi.json delete mode 100644 languages/zh.json delete mode 100644 scene.txt delete mode 100644 引擎文件说明.md diff --git a/.gitignore b/.gitignore deleted file mode 100644 index ba0f829..0000000 --- a/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -build/ -*.exe -*.o -*.a -*.log -*.png -*.bmp -__pycache__/ -*.pyc -*.dll -Editor/target/ -Editor/Cargo.lock diff --git a/.lang b/.lang deleted file mode 100644 index 147d659..0000000 --- a/.lang +++ /dev/null @@ -1 +0,0 @@ -zh \ No newline at end of file diff --git a/Assets/cube.obj b/Assets/cube.obj deleted file mode 100644 index 79d616c..0000000 --- a/Assets/cube.obj +++ /dev/null @@ -1,21 +0,0 @@ -# Simple cube OBJ for testing -v -1.0 -1.0 -1.0 -v 1.0 -1.0 -1.0 -v 1.0 1.0 -1.0 -v -1.0 1.0 -1.0 -v -1.0 -1.0 1.0 -v 1.0 -1.0 1.0 -v 1.0 1.0 1.0 -v -1.0 1.0 1.0 -f 1 2 3 -f 1 3 4 -f 5 7 6 -f 5 8 7 -f 1 5 6 -f 1 6 2 -f 2 6 7 -f 2 7 3 -f 3 7 8 -f 3 8 4 -f 4 8 5 -f 4 5 1 diff --git a/Assets/pyramid.obj b/Assets/pyramid.obj deleted file mode 100644 index 17eba92..0000000 --- a/Assets/pyramid.obj +++ /dev/null @@ -1,12 +0,0 @@ -# Pyramid OBJ -v 0.0 1.0 0.0 -v -1.0 -1.0 1.0 -v 1.0 -1.0 1.0 -v 1.0 -1.0 -1.0 -v -1.0 -1.0 -1.0 -f 1 2 3 -f 1 3 4 -f 1 4 5 -f 1 5 2 -f 2 5 4 -f 2 4 3 diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index b9faffe..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,126 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(lity3d C) - -set(CMAKE_C_STANDARD 17) -set(CMAKE_C_STANDARD_REQUIRED ON) - -add_compile_options(-O2 -Wall -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_WARNINGS) - -include_directories( - ${CMAKE_SOURCE_DIR}/Engine - ${CMAKE_SOURCE_DIR}/Engine/include - ${CMAKE_SOURCE_DIR}/Engine/ASM -) - -set(ENGINE_SOURCES - Engine/Math/math_impl.c - Engine/Core/logger.c - Engine/Core/timer.c - Engine/Core/engine.c - Engine/Core/asset_manager.c - Engine/Window/window.c - Engine/Rendering/graphics_device.c - Engine/Rendering/renderer.c - Engine/Rendering/shader.c - Engine/Rendering/mesh.c - Engine/Rendering/texture.c - Engine/Rendering/material.c - Engine/Rendering/camera.c - Engine/Rendering/lighting.c - Engine/Scene/scene_graph.c - Engine/Scene/scene_render.c - Engine/Scene/scene_serialize.c - Engine/ECS/world.c - Engine/Input/input.c - Engine/Physics/physics.c - Engine/Audio/audio.c - Engine/UI/ui.c - Engine/Scripting/lua_engine.c - Engine/VisualScript/block_core.c - Engine/VisualScript/block_types.c - Engine/VisualScript/block_workspace.c - Engine/VisualScript/block_interaction.c - Engine/VisualScript/block_renderer.c - Engine/VisualScript/block_palette.c - Engine/VisualScript/block_executor.c - Engine/VisualScript/block_serializer.c - Engine/VisualScript/block_editor.c - Engine/Editor/editor_2d.c - Engine/Editor/bitmap_font.c - Engine/Editor/editor.c - Engine/Editor/uilayer.c - Engine/Editor/glyph_atlas.c -) - -add_library(Engine STATIC ${ENGINE_SOURCES}) - -set(LINK_LIBS Engine d3d11 dxgi d3dcompiler ole32 oleaut32 uuid gdi32 user32 kernel32 winmm xinput1_4 windowscodecs) - -add_executable(lity3d Demo/main.c) -target_link_libraries(lity3d ${LINK_LIBS}) -set_target_properties(lity3d PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -add_executable(lity3d_editor WIN32 Demo/editor_main.c) -target_link_libraries(lity3d_editor ${LINK_LIBS}) -set_target_properties(lity3d_editor PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -add_executable(lity3d_compat WIN32 Demo/compat_test.c) -target_link_libraries(lity3d_compat ${LINK_LIBS}) -set_target_properties(lity3d_compat PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -add_executable(ly_interpreter Demo/ly_interpreter.c) -target_link_libraries(ly_interpreter Engine d3d11 dxgi d3dcompiler ole32 oleaut32 uuid gdi32 user32 kernel32 winmm xinput1_4 windowscodecs) -set_target_properties(ly_interpreter PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -# Engine-based demos -add_executable(scene_test WIN32 Demo/scene_test.c) -target_link_libraries(scene_test ${LINK_LIBS}) -set_target_properties(scene_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -add_executable(scene_test2 WIN32 Demo/scene_test2.c) -target_link_libraries(scene_test2 ${LINK_LIBS}) -set_target_properties(scene_test2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -add_executable(light_test WIN32 Demo/light_test.c) -target_link_libraries(light_test ${LINK_LIBS}) -set_target_properties(light_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -add_executable(input_test WIN32 Demo/input_test.c) -target_link_libraries(input_test ${LINK_LIBS}) -set_target_properties(input_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -add_executable(mesh_debug WIN32 Demo/mesh_debug.c) -target_link_libraries(mesh_debug ${LINK_LIBS}) -set_target_properties(mesh_debug PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -add_executable(raw3d_test WIN32 Demo/raw3d_test.c) -target_link_libraries(raw3d_test ${LINK_LIBS}) -set_target_properties(raw3d_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -# Audio demo (console, uses Engine audio system) -add_executable(audio_demo Demo/audio_demo.c) -target_link_libraries(audio_demo ${LINK_LIBS}) -set_target_properties(audio_demo PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -# Standalone D3D11 demos (do not link Engine) -set(STANDALONE_D3D_LIBS d3d11 dxgi d3dcompiler ole32 oleaut32 uuid gdi32 user32 kernel32 winmm) - -add_executable(game_test WIN32 Demo/game_test.c) -target_link_libraries(game_test ${STANDALONE_D3D_LIBS}) -set_target_properties(game_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -add_executable(cube_dodge WIN32 Demo/cube_dodge.c) -target_link_libraries(cube_dodge ${STANDALONE_D3D_LIBS}) -set_target_properties(cube_dodge PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -add_executable(lity WIN32 Demo/lity_explorer.c) -target_link_libraries(lity ${LINK_LIBS}) -set_target_properties(lity PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -add_executable(obj_viewer WIN32 Demo/obj_viewer.c) -target_link_libraries(obj_viewer ${STANDALONE_D3D_LIBS}) -set_target_properties(obj_viewer PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) - -add_executable(d3d11_test WIN32 Demo/d3d11_test.c) -target_link_libraries(d3d11_test ${STANDALONE_D3D_LIBS}) -set_target_properties(d3d11_test PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) diff --git a/DESIGN.md b/DESIGN.md deleted file mode 100644 index 0bef825..0000000 --- a/DESIGN.md +++ /dev/null @@ -1,1072 +0,0 @@ -# GameEngineASM - x86-64 MASM + C 混合架构游戏引擎设计 - -## 1. 完整目录树 - -``` -GameEngineASM/ -├── GameEngineASM.sln -├── DESIGN.md -│ -├── Engine/ -│ ├── ASM/ -- 汇编核心 (4 files) -│ │ ├── math.asm -- 向量/矩阵/四元数 SIMD 运算 -│ │ ├── memory.asm -- 对齐内存分配器 -│ │ ├── string_ops.asm -- 高速内存/字符串操作 -│ │ └── profiling.asm -- rdtsc 性能计时 -│ │ -│ ├── include/ -- 共享头文件 (6 files) -│ │ ├── asm_math.inc -- ASM 函数声明 (.inc for MASM) -│ │ ├── asm_math.h -- C 端数学函数声明 -│ │ ├── asm_memory.h -- C 端内存分配器声明 -│ │ ├── asm_string.h -- C 端字符串操作声明 -│ │ ├── asm_profiling.h -- C 端性能计时声明 -│ │ └── engine_types.h -- 公共类型定义 (vec3, mat4, etc.) -│ │ -│ ├── C/ -- C 外层模块 -│ │ ├── core/ -- 核心系统 (6 files) -│ │ │ ├── engine.h -│ │ │ ├── engine.c -│ │ │ ├── platform.h -│ │ │ ├── platform.c -│ │ │ ├── logger.h -│ │ │ └── logger.c -│ │ │ -│ │ ├── rendering/ -- DirectX 11 渲染 (8 files) -│ │ │ ├── renderer.h -│ │ │ ├── renderer.c -│ │ │ ├── dx11_device.h -│ │ │ ├── dx11_device.c -│ │ │ ├── shader.h -│ │ │ ├── shader.c -│ │ │ ├── mesh.h -│ │ │ └── mesh.c -│ │ │ -│ │ ├── ecs/ -- 实体组件系统 (6 files) -│ │ │ ├── ecs.h -│ │ │ ├── ecs.c -│ │ │ ├── component_registry.h -│ │ │ ├── component_registry.c -│ │ │ ├── system_manager.h -│ │ │ └── system_manager.c -│ │ │ -│ │ ├── physics/ -- 物理系统 (4 files) -│ │ │ ├── physics.h -│ │ │ ├── physics.c -│ │ │ ├── collision.h -│ │ │ └── collision.c -│ │ │ -│ │ ├── resources/ -- 资源管理 (4 files) -│ │ │ ├── resource_manager.h -│ │ │ ├── resource_manager.c -│ │ │ ├── file_loader.h -│ │ │ └── file_loader.c -│ │ │ -│ │ ├── scene/ -- 场景管理 (4 files) -│ │ │ ├── scene.h -│ │ │ ├── scene.c -│ │ │ ├── scene_node.h -│ │ │ └── scene_node.c -│ │ │ -│ │ ├── audio/ -- XAudio2 音频 (4 files) -│ │ │ ├── audio.h -│ │ │ ├── audio.c -│ │ │ ├── audio_source.h -│ │ │ └── audio_source.c -│ │ │ -│ │ ├── ui/ -- UI 系统 (4 files) -│ │ │ ├── ui.h -│ │ │ ├── ui.c -│ │ │ ├── ui_widget.h -│ │ │ └── ui_widget.c -│ │ │ -│ │ └── scripting/ -- Lua 脚本 (4 files) -│ │ ├── scripting.h -│ │ ├── scripting.c -│ │ ├── lua_bindgen.h -│ │ └── lua_bindgen.c -│ │ -│ └── lib/ -- 预编译库 (3 files) -│ ├── lua54.lib -│ ├── d3d11.lib -│ └── d3dcompiler.lib -│ -├── Demo/ -- 演示程序 (3 files) -│ ├── main.c -│ ├── demo_scene.c -│ └── demo_scene.h -│ -└── Build/ -- 构建配置 (3 files) - ├── GameEngineASM.vcxproj - ├── GameEngineASM.vcxproj.filters - └── GameEngineASM.props -``` - -**总文件数: 58 files** - ---- - -## 2. 关键 ASM 函数签名 - -### 2.1 math.asm — SIMD 数学库 - -```asm -; ============================================================ -; math.asm - SSE4.1/AVX2 向量矩阵数学库 -; 与 C 互操作: Windows x64 calling convention -; 输入: RCX, RDX, R8, R9 (整数/指针), XMM0-XMM3 (浮点) -; 返回: 整数在 RAX, 浮点在 XMM0 -; ============================================================ - -; --- Vector2 操作 (float x, float y) --- - -; float vec2_dot(vec2 a, vec2 b) -; RCX = ptr to vec2 a, RDX = ptr to vec2 b -; Returns: XMM0 = dot product -vec2_dot PROC - movups xmm0, xmmword ptr [rcx] ; load a.x, a.y - movups xmm1, xmmword ptr [rdx] ; load b.x, b.y - mulps xmm0, xmm1 ; element-wise multiply - ;水 平 求 和: xmm0 = (a.x*b.x, a.y*b.y) - ; 需要水平加法 - movshdup xmm1, xmm0 ; xmm1 = (a.y*b.y, a.y*b.y) - addps xmm0, xmm1 ; xmm0 = (a.x*b.x + a.y*b.y, ...) - ret -vec2_dot ENDP - -; void vec2_normalize(vec2* out, vec2 in) -; RCX = ptr out, XMM0 = in.x, XMM1 = in.y -vec2_normalize PROC - ; pack xmm0,xmm1 -> xmm2 - unpcklps xmm2, xmm0, xmm1 ; xmm2 = (in.x, in.y) - movaps xmm3, xmm2 ; save - mulps xmm2, xmm2 ; square - ; horizontal sum - movshdup xmm4, xmm2 - addps xmm2, xmm4 ; len_sq - sqrtss xmm2, xmm2 ; len - shufps xmm2, xmm2, 0 ; broadcast - divps xmm3, xmm2 ; normalize - movups xmmword ptr [rcx], xmm3 ; store - ret -vec2_normalize ENDP - -; --- Vector3 操作 (float x, y, z, pad) --- - -; float vec3_dot(vec3 a, vec3 b) -vec3_dot PROC - movups xmm0, xmmword ptr [rcx] - movups xmm1, xmmword ptr [rdx] - mulps xmm0, xmm1 - ; horizontal sum 3 components - movshdup xmm2, xmm0 - addps xmm0, xmm2 - movhlps xmm2, xmm0 - addss xmm0, xmm2 - ret -vec3_dot ENDP - -; void vec3_cross(vec3* out, vec3 a, vec3 b) -; RCX = out, XMM0 = a, XMM1 = b (packed xyz) -vec3_cross PROC - ; a = (ax, ay, az), b = (bx, by, bz) - ; result = (ay*bz - az*by, az*bx - ax*bz, ax*by - ay*bx) - movaps xmm2, xmm0 ; a - movaps xmm3, xmm1 ; b - - shufps xmm4, xmm2, xmm2, 0C9h ; a.yzx - shufps xmm5, xmm3, xmm3, 0C9h ; b.yzx - - mulps xmm4, xmm3 ; a.yzx * b - mulps xmm5, xmm2 ; b.yzx * a - - subps xmm4, xmm5 ; cross - - ; store xyz - movlps qword ptr [rcx], xmm4 - shufps xmm4, xmm4, 02h - movss dword ptr [rcx+8], xmm4 - ret -vec3_cross ENDP - -; void vec3_normalize(vec3* out, vec3 v) -vec3_normalize PROC - movups xmm0, xmmword ptr [rcx] ; load v - movaps xmm1, xmm0 - mulps xmm1, xmm1 ; v*v - ; horizontal sum - movshdup xmm2, xmm1 - addps xmm1, xmm2 - movhlps xmm2, xmm1 - addss xmm1, xmm2 - sqrtss xmm1, xmm1 ; len - shufps xmm1, xmm1, 0 ; broadcast - divps xmm0, xmm1 - movups xmmword ptr [rcx], xmm0 - ret -vec3_normalize ENDP - -; void vec3_lerp(vec3* out, vec3 a, vec3 b, float t) -; RCX=out, XMM0=a(xyz), XMM1=b(xyz), XMM2=t -vec3_lerp PROC - subps xmm1, xmm0 ; b - a - shufps xmm2, xmm2, 0 ; broadcast t - mulps xmm1, xmm2 ; t * (b-a) - addps xmm0, xmm1 ; a + t*(b-a) - movups xmmword ptr [rcx], xmm0 - ret -vec3_lerp ENDP - -; --- Vector4 操作 --- - -; float vec4_dot(vec4 a, vec4 b) -vec4_dot PROC - movups xmm0, xmmword ptr [rcx] - movups xmm1, xmmword ptr [rdx] - mulps xmm0, xmm1 - ; horizontal sum 4 - movhlps xmm1, xmm0 - addps xmm0, xmm1 - movshdup xmm1, xmm0 - addss xmm0, xmm1 - ret -vec4_dot ENDP - -; --- Matrix4x4 操作 (16 floats, row-major) --- - -; void mat4_identity(mat4* out) -mat4_identity PROC - vxorps xmm0, xmm0, xmm0 - movups xmmword ptr [rcx], xmm0 - movups xmmword ptr [rcx+16], xmm0 - movups xmmword ptr [rcx+32], xmm0 - movups xmmword ptr [rcx+48], xmm0 - movss dword ptr [rcx], (1.0) ; [0][0] = 1 - movss dword ptr [rcx+20], (1.0) ; [1][1] = 1 - movss dword ptr [rcx+40], (1.0) ; [2][2] = 1 - movss dword ptr [rcx+60], (1.0) ; [3][3] = 1 - ret -mat4_identity ENDP - -; void mat4_multiply(mat4* out, mat4* a, mat4* b) -; AVX2: 8-wide FMA -mat4_multiply PROC - ; 保存非易失寄存器 - push rbx - sub rsp, 20h - - ; RCX = out, RDX = a, R8 = b - mov rbx, rcx - mov rsi, rdx - mov rdi, r8 - - ; 对矩阵 a 的每一行, 与矩阵 b 的所有列做点积 - ; 逐行处理 a - vmovups ymm0, ymmword ptr [rsi] ; a row 0 (y0) - vmovups ymm2, ymmword ptr [rsi+32] ; a row 1 - vmovups ymm4, ymmword ptr [rsi+64] ; a row 2 - vmovups ymm6, ymmword ptr [rsi+96] ; a row 3 - - ; 对每一列 b 计算 out 行 - ; Column 0 of b - vbroadcastss ymm1, dword ptr [rdi] - vbroadcastss ymm3, dword ptr [rdi+4] - vbroadcastss ymm5, dword ptr [rdi+8] - vbroadcastss ymm7, dword ptr [rdi+12] - - vfmadd231ps ymm0, ymm1, ymm0 ; row0 += col0 * row0 - ; ... (简化, 完整实现需 4x4=16 次 FMA) - - vmovups ymmword ptr [rbx], ymm0 - ; ... 其余行 - - add rsp, 20h - pop rbx - ret -mat4_multiply ENDP - -; void mat4_transpose(mat4* out, mat4* m) -mat4_transpose PROC - vmovups ymm0, ymmword ptr [rdx] ; row 0,1 - vmovups ymm1, ymmword ptr [rdx+32] ; row 2,3 - vunpcklps ymm2, ymm0, ymm1 ; unpack low - vunpckhps ymm3, ymm0, ymm1 ; unpack high - vunpcklps ymm4, ymm2, ymm3 - vunpckhps ymm5, ymm2, ymm3 - vmovups ymmword ptr [rcx], ymm4 - vmovups ymmword ptr [rcx+32], ymm5 - ret -mat4_transpose ENDP - -; bool mat4_inverse(mat4* out, mat4* m) -- 返回是否可逆 -; 使用 SIMD 优化的 Gauss-Jordan 消元 -mat4_inverse PROC - ; 完整实现约 200 行, 使用 AVX2 + FMA - ; 核心: 增广矩阵 [m|I] 行变换 - push rbx - push rbp - sub rsp, 40h - - ; ... 完整 SIMD inverse 实现 - - mov al, 1 ; assume success - add rsp, 40h - pop rbp - pop rbx - ret -mat4_inverse ENDP - -; --- Quaternion 操作 (4 floats: x, y, z, w) --- - -; void quat_multiply(quat* out, quat* a, quat* b) -quat_multiply PROC - movups xmm0, xmmword ptr [rcx] ; a = (ax,ay,az,aw) - movups xmm1, xmmword ptr [rdx] ; b = (bx,by,bz,bw) - ; Hamilton product - ; result = (aw*b + bw*a + cross(a.xyz, b.xyz), aw*bw - dot(a.xyz,b.xyz)) - movaps xmm2, xmm0 - shufps xmm2, xmm2, 0FFh ; broadcast aw - mulps xmm2, xmm1 ; aw * b - - movaps xmm3, xmm1 - shufps xmm3, xmm3, 0FFh ; broadcast bw - mulps xmm3, xmm0 ; bw * a - - ; cross product of xyz - ; ... (同 vec3_cross) - - addps xmm2, xmm3 - ; w = aw*bw - dot(ax*bx + ay*by + az*bz) - ; store result - movups xmmword ptr [rcx], xmm2 - ret -quat_multiply ENDP - -; void quat_rotate_vec3(vec3* out, quat* q, vec3* v) -; 使用旋转公式: v' = q * v * q^-1 -; 优化公式: v' = v + 2w(q.xyz x v) + 2(q.xyz x (q.xyz x v)) -quat_rotate_vec3 PROC - ; ... AVX2 优化实现 - ret -quat_rotate_vec3 ENDP -``` - -### 2.2 memory.asm — 对齐内存分配器 - -```asm -; ============================================================ -; memory.asm - SIMD 对齐内存分配器 -; ============================================================ - -; void* mem_aligned_alloc(size_t size, size_t alignment) -; RCX = size, RDX = alignment (must be power of 2, >= 16) -; Returns: RAX = aligned pointer (or NULL on failure) -; 实现: 分配 size + alignment + sizeof(void*), 返回对齐后的指针 -; 在对齐指针前存储原始 malloc 指针 -mem_aligned_alloc PROC - push rbx - push rdi - sub rsp, 28h - - mov rbx, rcx ; size - mov rdi, rdx ; alignment - - ; total = size + alignment + 8 (for storing original ptr) - lea rcx, [rbx + rdi + 8] - call malloc ; 调用 CRT malloc - - test rax, rax - jz .fail - - ; 计算对齐指针 - mov rcx, rax - add rcx, 8 ; skip storing space - ; align up - lea rdx, [rdi - 1] - not rdx - add rcx, rdx - and rcx, rdx ; aligned ptr - - ; 存储原始指针 (aligned_ptr - 8) - mov [rcx - 8], rax - - mov rax, rcx - jmp .done - -.fail: - xor eax, eax - -.done: - add rsp, 28h - pop rdi - pop rbx - ret -mem_aligned_alloc ENDP - -; void mem_aligned_free(void* ptr) -; RCX = aligned pointer -mem_aligned_free PROC - test rcx, rcx - jz .done - mov rcx, qword ptr [rcx - 8] ; recover original ptr - call free -.done: - ret -mem_aligned_free ENDP - -; void* mem_aligned_realloc(void* ptr, size_t new_size) -mem_aligned_realloc PROC - ; ... 类似 alloc 但使用 realloc - ret -mem_aligned_realloc ENDP -``` - -### 2.3 string_ops.asm — 高速字符串/内存操作 - -```asm -; ============================================================ -; string_ops.asm - 高速内存/字符串操作 -; 使用 REP MOVSB (ERMS) + SSE 优化 -; ============================================================ - -; void fast_memcpy(void* dst, const void* src, size_t count) -; RCX=dst, RDX=src, R8=count -; 对齐后使用 SSE2 movdqa 批量复制 -fast_memcpy PROC - push rdi - push rsi - push rbx - - mov rdi, rcx - mov rsi, rdx - mov rcx, r8 - - cmp rcx, 64 - jb .small_copy - - ; 大块复制: 对齐到 16 字节后用 movdqa - ; 先复制前几字节直到对齐 - mov rax, rdi - and rax, 0Fh - jz .aligned - mov rdx, 16 - sub rdx, rax - rep movsb - sub rcx, rdx - -.aligned: - ; 以 64 字节为单位批量复制 - mov rdx, rcx - shr rcx, 2 ; count / 4 (64 bytes each) - jz .tail - -.loop_64: - movdqa xmm0, xmmword ptr [rsi] - movdqa xmm1, xmmword ptr [rsi+16] - movdqa xmm2, xmmword ptr [rsi+32] - movdqa xmm3, xmmword ptr [rsi+48] - movdqa xmmword ptr [rdi], xmm0 - movdqa xmmword ptr [rdi+16], xmm1 - movdqa xmmword ptr [rdi+32], xmm2 - movdqa xmmword ptr [rdi+48], xmm3 - add rsi, 64 - add rdi, 64 - dec rcx - jnz .loop_64 - - and rdx, 3Fh ; remaining bytes - mov rcx, rdx - -.tail: - rep movsb - - pop rbx - pop rsi - pop rdi - ret - -.small_copy: - rep movsb - pop rbx - pop rsi - pop rdi - ret -fast_memcpy ENDP - -; void fast_memset(void* dst, int val, size_t count) -; 使用 SSE2 批量填充 -fast_memset PROC - push rdi - push rcx - - mov rdi, rcx - mov rax, rdx - mov rcx, r8 - - ; 广播 val 到 xmm0 的所有字节 - movd xmm0, edx - pshufd xmm0, xmm0, 0 - - cmp rcx, 32 - jb .small_set - - ; 对齐 - mov rax, rdi - and rax, 0Fh - jz .aligned_set - mov rdx, 16 - sub rdx, rax - rep stosb - sub rcx, rdx - -.aligned_set: - mov rdx, rcx - shr rcx, 1 ; 32 bytes per iteration - -.loop_set: - movdqa xmmword ptr [rdi], xmm0 - movdqa xmmword ptr [rdi+16], xmm0 - add rdi, 32 - dec rcx - jnz .loop_set - - and rdx, 1Fh - mov rcx, rdx - -.small_set: - rep stosb - - pop rcx - pop rdi - ret -fast_memset ENDP - -; int fast_strcmp(const char* a, const char* b) -; SSE4.2PCMPESTRI 逐 16 字节比较 -fast_strcmp PROC - push rbx - -.loop_strcmp: - movdqu xmm0, xmmword ptr [rcx] - movdqu xmm1, xmmword ptr [rdx] - - ; SSE4.2 字符串比较: 找到第一个不匹配位置 - pcmpestrm xmm0, xmm1, 18h ; EqualAny, unsigned bytes - ; ... (具体利用 SSE4.2 字符串指令) - - ; 简化版本: 逐字节 fallback - mov al, byte ptr [rcx] - cmp al, byte ptr [rdx] - jne .not_equal - test al, al - jz .equal - inc rcx - inc rdx - jmp .loop_strcmp - -.not_equal: - movzx eax, al - movzx edx, byte ptr [rdx] - sub eax, edx - pop rbx - ret - -.equal: - xor eax, eax - pop rbx - ret -fast_strcmp ENDP - -; size_t fast_strlen(const char* str) -fast_strlen PROC - mov rax, rcx - pxor xmm0, xmm0 - -.loop_strlen: - movdqu xmm1, xmmword ptr [rax] - pcmpestrm xmm1, xmm0, 08h ; Least Significant Byte, imm8=08h - jc .found - add rax, 16 - jmp .loop_strlen - -.found: - ; 在返回的掩码中找第一个 1 - pmovmskb edx, xmm1 - tzcnt edx, edx - add rax, rdx - sub rax, rcx ; length = end - start - ret -fast_strlen ENDP -``` - -### 2.4 profiling.asm — rdtsc 性能计时 - -```asm -; ============================================================ -; profiling.asm - rdtsc 高精度计时 -; ============================================================ - -; uint64_t prof_rdtsc(void) -; 返回 TSC 值 -prof_rdtsc PROC - lfence - rdtsc - shl rdx, 32 - or rax, rdx - ret -prof_rdtsc ENDP - -; uint64_t prof_rdtscp(void) -; 无序读取, 更快但可能不精确 -prof_rdtscp PROC - rdtscp - shl rdx, 32 - or rax, rdx - ret -prof_rdtscp ENDP - -; double prof_cycles_to_ms(uint64_t cycles) -; 将 TSC cycles 转换为毫秒 (需要 CPU 频率) -; RCX = cycles -; Returns: XMM0 = milliseconds -prof_cycles_to_ms PROC - vcvttsd2si rax, xmm0 ; ... 保存输入 - ; 假设 CPU 频率存储在全局变量 cpu_freq_ghz - vmovsd xmm0, qword ptr [cpu_freq_mhz] - vcvtsi2sd xmm1, xmm1, rcx - vdivsd xmm0, xmm1, xmm0 ; cycles / mhz = ms - vdivsd xmm0, xmm0, (1000.0) ; / 1000 for seconds, but we want ms - ; 实际: ms = cycles / (cpu_mhz * 1000) - ret -prof_cycles_to_ms ENDP - -; void prof_calibrate_frequency(void) -; 通过 QueryPerformanceCounter 校准 TSC 频率 -prof_calibrate_frequency PROC - sub rsp, 28h - - ; QueryPerformanceFrequency - lea rcx, qword ptr [freq_large] - call QueryPerformanceFrequency - - ; 用 rdtsc 采样 - call prof_rdtsc - mov rbx, rax - - ; Sleep(100ms) - mov ecx, 100 - call Sleep - - call prof_rdtsc - sub rax, rbx ; elapsed cycles - - ; cpu_mhz = elapsed_cycles / (freq * 0.1s) - ; ... - - add rsp, 28h - ret -prof_calibrate_frequency ENDP - -.data - cpu_freq_mhz dq 0 - freq_large dq 0 -``` - ---- - -## 3. C 端头文件 (暴露 ASM 函数) - -### 3.1 engine_types.h — 公共类型 - -```c -#ifndef ENGINE_TYPES_H -#define ENGINE_TYPES_H - -#include -#include - -typedef union Vec2 { - struct { float x, y; }; - float m[2]; -} Vec2; - -typedef union Vec3 { - struct { float x, y, z, _pad; }; - float m[4]; // 16-byte aligned -} Vec3; - -typedef union Vec4 { - struct { float x, y, z, w; }; - float m[4]; -} Vec4; - -typedef union Mat4 { - float m[16]; - float mm[4][4]; -} Mat4; - -typedef union Quat { - struct { float x, y, z, w; }; - float m[4]; -} Quat; - -#endif -``` - -### 3.2 asm_math.h - -```c -#ifndef ASM_MATH_H -#define ASM_MATH_H - -#include "engine_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -// Vector2 -float vec2_dot(Vec2 a, Vec2 b); -Vec2 vec2_add(Vec2 a, Vec2 b); -Vec2 vec2_sub(Vec2 a, Vec2 b); -Vec2 vec2_scale(Vec2 v, float s); -Vec2 vec2_normalize(Vec2 v); -float vec2_length(Vec2 v); - -// Vector3 -float vec3_dot(Vec3 a, Vec3 b); -Vec3 vec3_cross(Vec3 a, Vec3 b); -Vec3 vec3_add(Vec3 a, Vec3 b); -Vec3 vec3_sub(Vec3 a, Vec3 b); -Vec3 vec3_scale(Vec3 v, float s); -Vec3 vec3_normalize(Vec3 v); -float vec3_length(Vec3 v); -Vec3 vec3_lerp(Vec3 a, Vec3 b, float t); - -// Vector4 -float vec4_dot(Vec4 a, Vec4 b); -Vec4 vec4_add(Vec4 a, Vec4 b); -Vec4 vec4_sub(Vec4 a, Vec4 b); -Vec4 vec4_scale(Vec4 v, float s); - -// Matrix4x4 -void mat4_identity(Mat4* out); -void mat4_multiply(Mat4* out, Mat4* a, Mat4* b); -void mat4_transpose(Mat4* out, Mat4* m); -bool mat4_inverse(Mat4* out, Mat4* m); -void mat4_translate(Mat4* out, Vec3 v); -void mat4_scale(Mat4* out, Vec3 s); -void mat4_rotate_x(Mat4* out, float radians); -void mat4_rotate_y(Mat4* out, float radians); -void mat4_rotate_z(Mat4* out, float radians); -Mat4 mat4_perspective(float fov, float aspect, float near, float far); -Mat4 mat4_ortho(float left, float right, float bottom, float top, float near, float far); -Mat4 mat4_look_at(Vec3 eye, Vec3 center, Vec3 up); - -// Quaternion -Quat quat_identity(void); -Quat quat_multiply(Quat a, Quat b); -Quat quat_normalize(Quat q); -Quat quat_conjugate(Quat q); -Quat quat_from_axis_angle(Vec3 axis, float angle); -Vec3 quat_rotate_vec3(Quat q, Vec3 v); -Mat4 quat_to_mat4(Quat q); - -// SSE intrinsics for direct C use (optional, for tight loops) -#ifdef __SSE4_1__ -#include -static inline float fast_vec3_dot_sse(Vec3 a, Vec3 b) { - __m128 va = _mm_load_ps(a.m); - __m128 vb = _mm_load_ps(b.m); - __m128 mul = _mm_mul_ps(va, vb); - __m128 shuf = _mm_movehdup_ps(mul); - __m128 sums = _mm_add_ps(mul, shuf); - shuf = _mm_movehl_ps(shuf, sums); - sums = _mm_add_ss(sums, shuf); - return _mm_cvtss_f32(sums); -} -#endif - -#ifdef __cplusplus -} -#endif - -#endif -``` - -### 3.3 asm_memory.h - -```c -#ifndef ASM_MEMORY_H -#define ASM_MEMORY_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void* mem_aligned_alloc(size_t size, size_t alignment); -void mem_aligned_free(void* ptr); -void* mem_aligned_realloc(void* ptr, size_t new_size); -size_t mem_get_alignment(void* ptr); - -// SIMD 块分配: 一次分配多个对齐对象 -void* mem_aligned_alloc_batch(size_t count, size_t elem_size, size_t alignment); - -#ifdef __cplusplus -} -#endif - -#endif -``` - -### 3.4 asm_string.h - -```c -#ifndef ASM_STRING_H -#define ASM_STRING_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void fast_memcpy(void* dst, const void* src, size_t count); -void fast_memset(void* dst, int val, size_t count); -int fast_strcmp(const char* a, const char* b); -int fast_strncmp(const char* a, const char* b, size_t n); -size_t fast_strlen(const char* str); -char* fast_strchr(const char* str, int c); -char* fast_strcpy(char* dst, const char* src); - -#ifdef __cplusplus -} -#endif - -#endif -``` - -### 3.5 asm_profiling.h - -```c -#ifndef ASM_PROFILING_H -#define ASM_PROFILING_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -uint64_t prof_rdtsc(void); -uint64_t prof_rdtscp(void); -double prof_cycles_to_ms(uint64_t cycles); -uint64_t prof_calibrate_frequency(void); -double prof_get_cpu_ghz(void); - -// 便捷宏 -#define PROF_BEGIN() uint64_t _prof_start = prof_rdtsc() -#define PROF_END() prof_cycles_to_ms(prof_rdtsc() - _prof_start) - -#ifdef __cplusplus -} -#endif - -#endif -``` - ---- - -## 4. 构建配置 (Visual Studio MASM 集成) - -### 4.1 GameEngineASM.props — MASM 属性表 - -```xml - - - - - - /Zi /nologo /Fl /Sa - $(ProjectDir)Engine\include - %(PreprocessorDefinitions) - ProgramDatabase - FullSpeedOptimizations - - - - - $(ProjectDir)Engine\include;%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Full - /arch:AVX2 /fp:fast - Level4 - - - - d3d11.lib;d3dcompiler.lib;dxgi.lib;d3d11.lib;xaudio2.lib;lua54.lib;%(AdditionalDependencies) - Windows - true - $(ProjectDir)Engine\lib;%(AdditionalLibraryDirectories) - - - -``` - -### 4.2 GameEngineASM.vcxproj — 关键片段 - -```xml - - - - - - - false - - - - - - - - - - - - - - - - - - - - - - -``` - -### 4.3 ml64.exe 编译命令行 - -``` -ml64.exe /c /nologo /W3 /Zi /Fo"$(OutDir)%(FileName).obj" /Fl"$(OutDir)%(FileName).lst" %(AdditionalInputs) %(AdditionalOptions) -``` - ---- - -## 5. 实施顺序 (按依赖关系) - -### Phase 1: 基础设施 (Week 1) -| 序号 | 任务 | 优先级 | 预计时间 | -|------|------|--------|----------| -| 1.1 | 创建项目结构和 VS 解决方案 | P0 | 2h | -| 1.2 | 配置 MASM 构建规则 (.props, .vcxproj) | P0 | 2h | -| 1.3 | 实现 `engine_types.h` 公共类型 | P0 | 1h | -| 1.4 | 实现 `string_ops.asm` (memcpy/memset/strlen) | P0 | 4h | -| 1.5 | 实现 `memory.asm` 对齐分配器 | P0 | 3h | -| 1.6 | 实现 `profiling.asm` 计时器 | P0 | 2h | - -### Phase 2: 数学库 (Week 1-2) -| 序号 | 任务 | 优先级 | 预计时间 | -|------|------|--------|----------| -| 2.1 | `math.asm` — Vec2 基础操作 | P0 | 3h | -| 2.2 | `math.asm` — Vec3 基础操作 | P0 | 3h | -| 2.3 | `math.asm` — Vec4 基础操作 | P0 | 2h | -| 2.4 | `math.asm` — Mat4 基础操作 (identity, multiply) | P0 | 6h | -| 2.5 | `math.asm` — Mat4 高级操作 (inverse, look_at, perspective) | P1 | 8h | -| 2.6 | `math.asm` — Quat 操作 | P1 | 4h | -| 2.7 | C 端头文件 `asm_math.h` | P0 | 2h | - -### Phase 3: 核心框架 (Week 2-3) -| 序号 | 任务 | 优先级 | 预计时间 | -|------|------|--------|----------| -| 3.1 | `platform.c` — Win32 窗口管理 | P0 | 6h | -| 3.2 | `engine.c` — 主循环和初始化 | P0 | 4h | -| 3.3 | `dx11_device.c` — DirectX 11 设备初始化 | P0 | 6h | -| 3.4 | `renderer.c` — 基础渲染管线 | P0 | 8h | -| 3.5 | `shader.c` — 着色器管理 | P1 | 4h | -| 3.6 | `mesh.c` — 网格和顶点缓冲 | P1 | 4h | - -### Phase 4: 游戏系统 (Week 3-4) -| 序号 | 任务 | 优先级 | 预计时间 | -|------|------|--------|----------| -| 4.1 | `ecs.c` — 实体组件系统核心 | P0 | 8h | -| 4.2 | `physics.c` — 物理系统 (调用 ASM math) | P1 | 6h | -| 4.3 | `collision.c` — 碰撞检测 | P1 | 6h | -| 4.4 | `scene.c` — 场景图管理 | P1 | 4h | -| 4.5 | `resource_manager.c` — 资源加载 | P2 | 4h | -| 4.6 | `audio.c` — XAudio2 音频 | P2 | 6h | -| 4.7 | `ui.c` — UI 系统 | P2 | 6h | -| 4.8 | `scripting.c` — Lua 绑定 | P2 | 4h | - -### Phase 5: 演示和优化 (Week 4-5) -| 序号 | 任务 | 优先级 | 预计时间 | -|------|------|--------|----------| -| 5.1 | `Demo/main.c` — 主入口 | P0 | 2h | -| 5.2 | `Demo/demo_scene.c` — 演示场景 | P1 | 6h | -| 5.3 | SIMD 性能基准测试 | P1 | 4h | -| 5.4 | 集成测试和调试 | P0 | 8h | - -**总预计工时: ~150 小时 (约 4-5 周)** - ---- - -## 6. 文件统计 - -| 类别 | 文件数 | 说明 | -|------|--------|------| -| ASM (.asm) | 4 | 核心热路径 | -| ASM include (.inc) | 1 | ASM 函数声明 | -| C 头文件 (.h) | 19 | 包含公共类型和模块头文件 | -| C 源文件 (.c) | 30 | 所有模块实现 | -| VS 项目文件 | 3 | .sln, .vcxproj, .props | -| 文档 | 1 | 本设计文档 | -| 预编译库 (.lib) | 3 | lua54, d3d11, d3dcompiler | -| **总计** | **61** | — | - -### 按模块分布 - -``` -ASM 核心: 4 文件 (math, memory, string_ops, profiling) -C 核心: 6 文件 (engine, platform, logger) -C 渲染: 8 文件 (renderer, dx11_device, shader, mesh) -C ECS: 6 文件 (ecs, component_registry, system_manager) -C 物理: 4 文件 (physics, collision) -C 资源: 4 文件 (resource_manager, file_loader) -C 场景: 4 文件 (scene, scene_node) -C 音频: 4 文件 (audio, audio_source) -C UI: 4 文件 (ui, ui_widget) -C 脚本: 4 文件 (scripting, lua_bindgen) -头文件: 19 文件 (含 asm_*.h 和模块 .h) -构建/文档: 7 文件 (VS 项目, 设计文档, 库文件) -``` - ---- - -## 7. 性能预期 - -| 操作 | 纯 C | ASM (SSE4.1) | ASM (AVX2) | 加速比 | -|------|------|-------------|------------|--------| -| Vec4 Dot | ~12 ns | ~3 ns | ~2 ns | 4-6x | -| Mat4 Multiply | ~80 ns | ~25 ns | ~12 ns | 4-7x | -| Mat4 Inverse | ~500 ns | ~150 ns | ~80 ns | 3-6x | -| Quat Multiply | ~25 ns | ~8 ns | ~5 ns | 3-5x | -| memcpy 1KB | ~200 ns | ~40 ns | ~30 ns | 5-7x | -| memset 1KB | ~180 ns | ~35 ns | ~25 ns | 5-7x | - -**注意**: 实际性能取决于 CPU 微架构、缓存状态和数据对齐情况。 - ---- - -## 8. 关键设计决策 - -1. **调用约定**: 严格遵循 Windows x64 ABI, 确保 ASM/C 无缝互操作 -2. **内存对齐**: 所有 SIMD 数据使用 16/32 字节对齐, 通过自定义分配器保证 -3. **寄存器保存**: ASM 函数正确保存非易失寄存器 (RBX, RBP, RDI, RSI, R12-R15, XMM6-15) -4. **错误处理**: ASM 函数通过返回值 (0/-1 或 NULL) 表示失败, C 端检查 -5. **调试支持**: 使用 /Zi 编译, 生成符号信息, 支持 VS 调试器单步进入 ASM -6. **可移植性**: ASM 文件仅用于 x86-64 Windows, C 代码可条件编译到其他平台 diff --git a/Demo/Demo.vcxproj b/Demo/Demo.vcxproj deleted file mode 100644 index 3b10f6a..0000000 --- a/Demo/Demo.vcxproj +++ /dev/null @@ -1,87 +0,0 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - {A5A5A5A5-5A5A-5A5A-5A5A-5A5A5A5A5A5A} - Demo - 10.0 - - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - - - - - - - - - - - - NotUsing - Level4 - true - _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) - true - stdc17 - $(ProjectDir);%(AdditionalIncludeDirectories) - AdvancedVectorExtensions2 - - - Console - true - $(SolutionDir)Engine\$(Configuration);%(AdditionalLibraryDirectories) - d3d11.lib;dxgi.lib;d3dcompiler.lib;xaudio2.lib;xinput.lib;%(AdditionalDependencies) - - - - - NotUsing - Level4 - true - true - true - NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) - true - stdc17 - $(ProjectDir);%(AdditionalIncludeDirectories) - AdvancedVectorExtensions2 - - - Console - true - true - true - $(SolutionDir)Engine\$(Configuration);%(AdditionalLibraryDirectories) - d3d11.lib;dxgi.lib;d3dcompiler.lib;xaudio2.lib;xinput.lib;%(AdditionalDependencies) - - - - - - - diff --git a/Demo/Demo/Demo.vcxproj b/Demo/Demo/Demo.vcxproj deleted file mode 100644 index 3b10f6a..0000000 --- a/Demo/Demo/Demo.vcxproj +++ /dev/null @@ -1,87 +0,0 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - {A5A5A5A5-5A5A-5A5A-5A5A-5A5A5A5A5A5A} - Demo - 10.0 - - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - - - - - - - - - - - - NotUsing - Level4 - true - _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) - true - stdc17 - $(ProjectDir);%(AdditionalIncludeDirectories) - AdvancedVectorExtensions2 - - - Console - true - $(SolutionDir)Engine\$(Configuration);%(AdditionalLibraryDirectories) - d3d11.lib;dxgi.lib;d3dcompiler.lib;xaudio2.lib;xinput.lib;%(AdditionalDependencies) - - - - - NotUsing - Level4 - true - true - true - NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) - true - stdc17 - $(ProjectDir);%(AdditionalIncludeDirectories) - AdvancedVectorExtensions2 - - - Console - true - true - true - $(SolutionDir)Engine\$(Configuration);%(AdditionalLibraryDirectories) - d3d11.lib;dxgi.lib;d3dcompiler.lib;xaudio2.lib;xinput.lib;%(AdditionalDependencies) - - - - - - - diff --git a/Demo/Demo/audio_demo.c b/Demo/Demo/audio_demo.c deleted file mode 100644 index 35a4b6e..0000000 --- a/Demo/Demo/audio_demo.c +++ /dev/null @@ -1,118 +0,0 @@ -// ============================================================================ -// audio_demo.c - XAudio2 音频系统演示 -// 生成 440Hz 正弦波并播放 2 秒,无需外部 WAV 文件 -// ============================================================================ - -#include "../Engine/Audio/audio.h" -#include "../Engine/Core/logger.h" -#include -#include -#include -#include -#include - -#pragma comment(lib, "winmm.lib") - -// 生成标准 PCM WAV 数据 (44.1kHz, 16bit, 单声道) -static uint8_t* generate_sine_wave_wav(float frequency, float duration_sec, uint32_t* out_size) { - const uint32_t sample_rate = 44100; - const uint16_t channels = 1; - const uint16_t bits_per_sample = 16; - const uint16_t block_align = channels * bits_per_sample / 8; - const uint32_t byte_rate = sample_rate * block_align; - const uint32_t num_samples = (uint32_t)(sample_rate * duration_sec); - const uint32_t data_size = num_samples * block_align; - const uint32_t file_size = 44 + data_size; - - uint8_t* wav = (uint8_t*)malloc(file_size); - if (!wav) return NULL; - - // RIFF 头 - memcpy(wav + 0, "RIFF", 4); - memcpy(wav + 4, &file_size, 4); - memcpy(wav + 8, "WAVE", 4); - - // fmt chunk - memcpy(wav + 12, "fmt ", 4); - uint32_t fmt_size = 16; - memcpy(wav + 16, &fmt_size, 4); - uint16_t audio_format = 1; // PCM - memcpy(wav + 20, &audio_format, 2); - memcpy(wav + 22, &channels, 2); - memcpy(wav + 24, &sample_rate, 4); - memcpy(wav + 28, &byte_rate, 4); - memcpy(wav + 32, &block_align, 2); - memcpy(wav + 34, &bits_per_sample, 2); - - // data chunk - memcpy(wav + 36, "data", 4); - memcpy(wav + 40, &data_size, 4); - - // 生成正弦波样本 - int16_t* samples = (int16_t*)(wav + 44); - float amplitude = 0.3f; // 避免削波 - for (uint32_t i = 0; i < num_samples; i++) { - float t = (float)i / (float)sample_rate; - // 简单淡出,避免咔嗒声 - float envelope = 1.0f; - if (i < 1000) envelope = (float)i / 1000.0f; - if (i > num_samples - 1000) envelope = (float)(num_samples - i) / 1000.0f; - float sample = sinf(2.0f * 3.14159265f * frequency * t) * amplitude * envelope; - samples[i] = (int16_t)(sample * 32767.0f); - } - - *out_size = file_size; - return wav; -} - -int main(int argc, char* argv[]) { - (void)argc; (void)argv; - - printf("Lity3D - Audio Demo\n"); - printf("========================\n"); - - AudioSystem* audio = audio_create(); - if (!audio) { - printf("ERROR: Failed to create XAudio2 audio system\n"); - return 1; - } - printf("XAudio2 audio system created.\n"); - - AudioSource* source = audio_source_create(audio); - if (!source) { - printf("ERROR: Failed to create audio source\n"); - audio_destroy(audio); - return 1; - } - - uint32_t wav_size = 0; - uint8_t* wav_data = generate_sine_wave_wav(440.0f, 2.0f, &wav_size); - if (!wav_data) { - printf("ERROR: Failed to generate sine wave\n"); - audio_source_destroy(source); - audio_destroy(audio); - return 1; - } - - if (!audio_load_wav_memory(source, wav_data, wav_size)) { - printf("ERROR: Failed to load generated WAV into audio source\n"); - free(wav_data); - audio_source_destroy(source); - audio_destroy(audio); - return 1; - } - free(wav_data); - printf("Generated 440Hz sine wave loaded.\n"); - - printf("Playing 2 seconds...\n"); - audio_source_play(source); - - // 等待播放结束 (约 2 秒 + 缓冲) - Sleep(2500); - - audio_source_destroy(source); - audio_destroy(audio); - - printf("Audio demo finished successfully.\n"); - return 0; -} diff --git a/Demo/Demo/compat_test.c b/Demo/Demo/compat_test.c deleted file mode 100644 index 9f2d5af..0000000 --- a/Demo/Demo/compat_test.c +++ /dev/null @@ -1,221 +0,0 @@ -#include "../Engine/Core/engine.h" -#include "../Engine/Core/logger.h" -#include "../Engine/Core/timer.h" -#include "../Engine/Window/window.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Rendering/mesh.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" -#include "../Engine/Editor/glyph_atlas.h" -#include - -static GraphicsDevice* g_dev = NULL; -static Shader* g_shader = NULL; -static Mesh* g_tri = NULL; -static GlyphAtlas g_atlas; -static ID3D11VertexShader* g_tvs = NULL; -static ID3D11PixelShader* g_tps = NULL; -static ID3D11InputLayout* g_tlayout = NULL; -static ID3D11BlendState* g_tblend = NULL; -static ID3D11SamplerState* g_tsampler = NULL; -static ID3D11Buffer* g_tcb = NULL; -static ID3D11DepthStencilState* g_no_depth = NULL; - -typedef struct { float p[3], n[3], uv[2], c[4]; } V; - -static void draw_quad(ID3D11DeviceContext* ctx, float x, float y, float w, float h, float r, float g, float b, float a) { - V v[4] = { - {{x,y,0},{0,0,-1},{0,0},{r,g,b,a}}, - {{x+w,y,0},{0,0,-1},{1,0},{r,g,b,a}}, - {{x+w,y+h,0},{0,0,-1},{1,1},{r,g,b,a}}, - {{x,y+h,0},{0,0,-1},{0,1},{r,g,b,a}}, - }; - uint32_t idx[6] = {0,1,2, 0,2,3}; - ID3D11Buffer *vb = NULL, *ib = NULL; - D3D11_BUFFER_DESC bd = {0}; D3D11_SUBRESOURCE_DATA sd = {0}; - bd.ByteWidth = sizeof(V)*4; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = v; g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &bd, &sd, &vb); - bd.ByteWidth = sizeof(uint32_t)*6; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = idx; g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &bd, &sd, &ib); - UINT stride = sizeof(V), offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &vb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, ib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->DrawIndexed(ctx, 6, 0, 0); - ib->lpVtbl->Release(ib); vb->lpVtbl->Release(vb); -} - -static void on_render(Engine* engine) { - if (!g_dev) return; - ID3D11DeviceContext* ctx = g_dev->context; - float sw = (float)g_dev->width; - float sh = (float)g_dev->height; - - graphics_device_clear(g_dev, 0.0f, 0.0f, 0.0f, 1.0f); - - float proj[64] = {0}; - proj[0] = 2.0f / sw; proj[5] = -2.0f / sh; - proj[10] = 1.0f; proj[12] = -1.0f; proj[13] = 1.0f; proj[15] = 1.0f; - Mat4 proj_m, proj_t; - memcpy(&proj_m, proj, sizeof(Mat4)); - mat4_transpose(&proj_m, &proj_t); - - D3D11_VIEWPORT vp = {0}; - vp.Width = sw; vp.Height = sh; vp.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vp); - - D3D11_RASTERIZER_DESC rdesc = {0}; - rdesc.FillMode = D3D11_FILL_SOLID; - rdesc.CullMode = D3D11_CULL_NONE; - ID3D11RasterizerState* rstate = NULL; - g_dev->device->lpVtbl->CreateRasterizerState(g_dev->device, &rdesc, &rstate); - ctx->lpVtbl->RSSetState(ctx, rstate); - - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - shader_bind(g_shader, ctx); - shader_set_matrix(g_shader, ctx, (float*)&proj_t); - mesh_draw(g_tri, ctx); - - { - ctx->lpVtbl->OMSetDepthStencilState(ctx, g_no_depth, 0); - } - - draw_quad(ctx, sw - 200, 10, 180, 60, 1, 1, 1, 1); - - if (g_tvs && g_tps && g_tlayout && g_tcb && g_tblend && g_tsampler && g_atlas.srv) { - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)g_tcb, 0, NULL, &proj_t, 0, 0); - ctx->lpVtbl->VSSetShader(ctx, g_tvs, NULL, 0); - ctx->lpVtbl->PSSetShader(ctx, g_tps, NULL, 0); - ctx->lpVtbl->IASetInputLayout(ctx, g_tlayout); - ctx->lpVtbl->VSSetConstantBuffers(ctx, 0, 1, &g_tcb); - ctx->lpVtbl->PSSetShaderResources(ctx, 0, 1, &g_atlas.srv); - ctx->lpVtbl->PSSetSamplers(ctx, 0, 1, &g_tsampler); - ctx->lpVtbl->OMSetBlendState(ctx, g_tblend, NULL, 0xFFFFFFFF); - - typedef struct { float p[3], n[3], uv[2], c[4]; } TV; - TV tverts[4]; - uint32_t tidx[6] = {0,1,2, 0,2,3}; - int cx = (int)(sw - 195), cy = 35; - for (const wchar_t* p = L"\u6d4b\u8bd5"; *p; p++) { - float u0, v0, u1, v1, adv_x, adv_y; - if (glyph_atlas_get_or_create(&g_atlas, g_dev->device, ctx, *p, &u0, &v0, &u1, &v1, &adv_x, &adv_y)) { - tverts[0] = (TV){{(float)cx,(float)cy,0},{0,0,1},{u0,v0},{0,0,0,1}}; - tverts[1] = (TV){{(float)cx+adv_x,(float)cy,0},{0,0,1},{u1,v0},{0,0,0,1}}; - tverts[2] = (TV){{(float)cx+adv_x,(float)cy+adv_y,0},{0,0,1},{u1,v1},{0,0,0,1}}; - tverts[3] = (TV){{(float)cx,(float)cy+adv_y,0},{0,0,1},{u0,v1},{0,0,0,1}}; - ID3D11Buffer *tvb = NULL, *tib = NULL; - D3D11_BUFFER_DESC bd2 = {0}; D3D11_SUBRESOURCE_DATA sd2 = {0}; - bd2.ByteWidth = sizeof(TV)*4; bd2.Usage = D3D11_USAGE_DEFAULT; bd2.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd2.pSysMem = tverts; g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &bd2, &sd2, &tvb); - bd2.ByteWidth = sizeof(uint32_t)*6; bd2.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd2.pSysMem = tidx; g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &bd2, &sd2, &tib); - UINT stride2 = sizeof(TV), offset2 = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &tvb, &stride2, &offset2); - ctx->lpVtbl->IASetIndexBuffer(ctx, tib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->DrawIndexed(ctx, 6, 0, 0); - tib->lpVtbl->Release(tib); tvb->lpVtbl->Release(tvb); - cx += (int)adv_x + 2; - } - } - } - - if (rstate) rstate->lpVtbl->Release(rstate); - graphics_device_present(g_dev); -} - -static void on_key(Engine* engine, int key) { - if (key == VK_ESCAPE) engine_request_quit(engine); -} - -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { - (void)hInstance; (void)hPrevInstance; (void)lpCmdLine; (void)nCmdShow; - LOG_INFO("=== Compatibility Test ==="); - - EngineConfig config = engine_default_config(); - config.app_name = "Compatibility Test"; - config.vsync = 1; - config.window_width = 1280; - config.window_height = 720; - - Engine* engine = engine_create(); - if (!engine_init(engine, &config)) return -1; - - g_dev = graphics_device_create(); - if (!graphics_device_init(g_dev, window_get_handle(engine->window), config.window_width, config.window_height, 1)) { - LOG_FATAL("D3D11 init failed"); - return -1; - } - - g_shader = shader_create(); - shader_compile(g_shader, g_dev->device, NULL, NULL, 0, 0); - - glyph_atlas_init(&g_atlas, g_dev->device); - - const char* tvs_src = "cbuffer CB:register(b0){float4x4 WVP;};struct VS_IN{float4 pos:POSITION;float3 n:NORMAL;float2 uv:TEXCOORD;float4 col:COLOR;};struct PS_IN{float4 pos:SV_POSITION;float2 uv:TEXCOORD;float4 col:COLOR;};PS_IN main(VS_IN i){PS_IN o;o.pos=mul(i.pos,WVP);o.uv=i.uv;o.col=i.col;return o;}"; - const char* tps_src = "Texture2D tex:register(t0);SamplerState smp:register(s0);struct PS_IN{float4 pos:SV_POSITION;float2 uv:TEXCOORD;float4 col:COLOR;};float4 main(PS_IN i):SV_TARGET{float a=tex.Sample(smp,i.uv).a;return float4(i.col.rgb,i.col.a*a);}"; - ID3DBlob *vsb = NULL, *psb = NULL, *err = NULL; - D3DCompile(tvs_src, (UINT)strlen(tvs_src), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &vsb, &err); - if (err) { err->lpVtbl->Release(err); err = NULL; } - D3DCompile(tps_src, (UINT)strlen(tps_src), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &psb, &err); - if (err) { err->lpVtbl->Release(err); err = NULL; } - if (vsb && psb) { - g_dev->device->lpVtbl->CreateVertexShader(g_dev->device, vsb->lpVtbl->GetBufferPointer(vsb), vsb->lpVtbl->GetBufferSize(vsb), NULL, &g_tvs); - g_dev->device->lpVtbl->CreatePixelShader(g_dev->device, psb->lpVtbl->GetBufferPointer(psb), psb->lpVtbl->GetBufferSize(psb), NULL, &g_tps); - D3D11_INPUT_ELEMENT_DESC layout[] = { - {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}, - }; - g_dev->device->lpVtbl->CreateInputLayout(g_dev->device, layout, 4, vsb->lpVtbl->GetBufferPointer(vsb), vsb->lpVtbl->GetBufferSize(vsb), &g_tlayout); - vsb->lpVtbl->Release(vsb); psb->lpVtbl->Release(psb); - } - D3D11_SAMPLER_DESC sdesc = {0}; - sdesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - sdesc.AddressU = sdesc.AddressV = sdesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - g_dev->device->lpVtbl->CreateSamplerState(g_dev->device, &sdesc, &g_tsampler); - D3D11_BLEND_DESC bdesc = {0}; - bdesc.RenderTarget[0].BlendEnable = TRUE; - bdesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - bdesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - bdesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - bdesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - bdesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - bdesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - bdesc.RenderTarget[0].RenderTargetWriteMask = 0x0F; - g_dev->device->lpVtbl->CreateBlendState(g_dev->device, &bdesc, &g_tblend); - D3D11_BUFFER_DESC cbd = {0}; - cbd.ByteWidth = 256; cbd.Usage = D3D11_USAGE_DEFAULT; cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &cbd, NULL, &g_tcb); - - D3D11_DEPTH_STENCIL_DESC dsdesc = {0}; - dsdesc.DepthEnable = FALSE; - dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - g_dev->device->lpVtbl->CreateDepthStencilState(g_dev->device, &dsdesc, &g_no_depth); - - V tri[3] = { - {{640, 300, 0}, {0,0,-1}, {0,0}, {1, 0.2f, 0.2f, 1}}, - {{500, 550, 0}, {0,0,-1}, {0,1}, {0.2f, 1, 0.2f, 1}}, - {{780, 550, 0}, {0,0,-1}, {1,0}, {0.2f, 0.2f, 1, 1}}, - }; - uint32_t idx[3] = {0, 1, 2}; - g_tri = (Mesh*)calloc(1, sizeof(Mesh)); - g_tri->stride = sizeof(V); g_tri->vcount = 3; g_tri->icount = 3; - D3D11_BUFFER_DESC bd = {0}; D3D11_SUBRESOURCE_DATA sd = {0}; - bd.ByteWidth = sizeof(V)*3; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = tri; g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &bd, &sd, &g_tri->vb); - bd.ByteWidth = sizeof(uint32_t)*3; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = idx; g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &bd, &sd, &g_tri->ib); - - engine_set_render_callback(engine, on_render); - engine_set_key_callback(engine, on_key); - LOG_INFO("Running..."); - engine_run(engine); - - mesh_destroy(g_tri); - shader_destroy(g_shader); - glyph_atlas_destroy(&g_atlas); - graphics_device_destroy(g_dev); - engine_shutdown(engine); - return 0; -} diff --git a/Demo/Demo/cube_dodge.c b/Demo/Demo/cube_dodge.c deleted file mode 100644 index 0c72719..0000000 --- a/Demo/Demo/cube_dodge.c +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include -#include -#include -#include - -typedef struct { float p[3], n[3], u[2], c[4]; } V3D; -static ID3D11Device* g_dev; static ID3D11DeviceContext* g_ctx; -static IDXGISwapChain* g_sc; static ID3D11RenderTargetView* g_rtv; -static ID3D11VertexShader* g_vs; static ID3D11PixelShader* g_ps; -static ID3D11InputLayout* g_il; static ID3D11Buffer* g_cb; - -static int key_l=0,key_r=0,key_u=0,key_d=0,key_sp=0; -static int dead=0, score=0; -static float px=0, py=0, speed=0.4f; -#define NOBS 15 -static float ox[NOBS],oy[NOBS],oz[NOBS],osz[NOBS]; -static int oa[NOBS],oc=0; static float st=0; - -static void Init(HWND h){ - HRESULT hr;DXGI_SWAP_CHAIN_DESC sd;memset(&sd,0,sizeof(sd));sd.BufferCount=2;sd.BufferDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM;sd.BufferDesc.RefreshRate.Numerator=60;sd.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT;sd.OutputWindow=h;sd.SampleDesc.Count=1;sd.Windowed=TRUE;sd.SwapEffect=DXGI_SWAP_EFFECT_DISCARD; - D3D_FEATURE_LEVEL fl=D3D_FEATURE_LEVEL_11_0,gt;hr=D3D11CreateDeviceAndSwapChain(NULL,D3D_DRIVER_TYPE_HARDWARE,NULL,0,&fl,1,D3D11_SDK_VERSION,&sd,&g_sc,&g_dev,>,&g_ctx);if(FAILED(hr))return; - ID3D11Texture2D*bb=NULL;hr=g_sc->lpVtbl->GetBuffer(g_sc,0,&IID_ID3D11Texture2D,(void**)&bb);if(FAILED(hr)||!bb)return;hr=g_dev->lpVtbl->CreateRenderTargetView(g_dev,(ID3D11Resource*)bb,NULL,&g_rtv);bb->lpVtbl->Release(bb);if(FAILED(hr))return; - const char*vs="cbuffer CB:register(b0){float4x4 WVP;};struct I{float3 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};struct O{float4 p:SV_POSITION;float4 c:COLOR;};O main(I i){O o;o.p=mul(float4(i.p,1),WVP);o.c=i.c;return o;}"; - const char*ps="float4 main(float4 p:SV_POSITION, float4 c:COLOR):SV_Target{return c;}"; - ID3DBlob*b1,*b2,*e;D3DCompile(vs,(UINT)strlen(vs),NULL,NULL,NULL,"main","vs_5_0",0,0,&b1,&e);if(e){e->lpVtbl->Release(e);e=NULL;}D3DCompile(ps,(UINT)strlen(ps),NULL,NULL,NULL,"main","ps_5_0",0,0,&b2,&e);if(e){e->lpVtbl->Release(e);e=NULL;}if(!b1||!b2)return; - g_dev->lpVtbl->CreateVertexShader(g_dev,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),NULL,&g_vs);g_dev->lpVtbl->CreatePixelShader(g_dev,b2->lpVtbl->GetBufferPointer(b2),b2->lpVtbl->GetBufferSize(b2),NULL,&g_ps); - D3D11_INPUT_ELEMENT_DESC el[4];memset(el,0,sizeof(el));el[0].SemanticName="POSITION";el[0].Format=DXGI_FORMAT_R32G32B32_FLOAT;el[0].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA;el[1].SemanticName="NORMAL";el[1].AlignedByteOffset=12;el[1].Format=DXGI_FORMAT_R32G32B32_FLOAT;el[1].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA;el[2].SemanticName="TEXCOORD";el[2].AlignedByteOffset=24;el[2].Format=DXGI_FORMAT_R32G32_FLOAT;el[2].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA;el[3].SemanticName="COLOR";el[3].AlignedByteOffset=32;el[3].Format=DXGI_FORMAT_R32G32B32A32_FLOAT;el[3].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA; - g_dev->lpVtbl->CreateInputLayout(g_dev,el,4,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),&g_il);b1->lpVtbl->Release(b1);b2->lpVtbl->Release(b2); - D3D11_BUFFER_DESC cbd;memset(&cbd,0,sizeof(cbd));cbd.ByteWidth=256;cbd.Usage=D3D11_USAGE_DEFAULT;cbd.BindFlags=D3D11_BIND_CONSTANT_BUFFER;g_dev->lpVtbl->CreateBuffer(g_dev,&cbd,NULL,&g_cb); -} - -static void Cube(float cx,float cy,float cz,float s,float cr,float cg,float cb){ - V3D v[24];float f[6][4][3]={{{-1,-1,-1},{1,-1,-1},{1,1,-1},{-1,1,-1}},{{1,-1,-1},{1,-1,1},{1,1,1},{1,1,-1}},{{1,-1,1},{-1,-1,1},{-1,1,1},{1,1,1}},{{-1,-1,1},{-1,-1,-1},{-1,1,-1},{-1,1,1}},{{-1,1,-1},{1,1,-1},{1,1,1},{-1,1,1}},{{-1,-1,1},{1,-1,1},{1,-1,-1},{-1,-1,-1}}};float nm[6][3]={{0,0,-1},{1,0,0},{0,0,1},{-1,0,0},{0,1,0},{0,-1,0}}; - for(int fi=0;fi<6;fi++)for(int vi=0;vi<4;vi++){int i=fi*4+vi;v[i].p[0]=f[fi][vi][0]*s+cx;v[i].p[1]=f[fi][vi][1]*s+cy;v[i].p[2]=f[fi][vi][2]*s+cz;v[i].n[0]=nm[fi][0];v[i].n[1]=nm[fi][1];v[i].n[2]=nm[fi][2];v[i].c[0]=cr;v[i].c[1]=cg;v[i].c[2]=cb;v[i].c[3]=1;} - uint32_t ix[36];for(int fi=0;fi<6;fi++){int b=fi*4;ix[fi*6]=b;ix[fi*6+1]=b+1;ix[fi*6+2]=b+2;ix[fi*6+3]=b;ix[fi*6+4]=b+2;ix[fi*6+5]=b+3;} - ID3D11Buffer*vb,*ib;D3D11_BUFFER_DESC bd;D3D11_SUBRESOURCE_DATA sd;memset(&bd,0,sizeof(bd));memset(&sd,0,sizeof(sd));bd.ByteWidth=sizeof(V3D)*24;bd.Usage=D3D11_USAGE_DEFAULT;bd.BindFlags=D3D11_BIND_VERTEX_BUFFER;sd.pSysMem=v;g_dev->lpVtbl->CreateBuffer(g_dev,&bd,&sd,&vb);bd.ByteWidth=sizeof(uint32_t)*36;bd.BindFlags=D3D11_BIND_INDEX_BUFFER;sd.pSysMem=ix;g_dev->lpVtbl->CreateBuffer(g_dev,&bd,&sd,&ib); - UINT s2=sizeof(V3D),o=0;g_ctx->lpVtbl->IASetVertexBuffers(g_ctx,0,1,&vb,&s2,&o);g_ctx->lpVtbl->IASetIndexBuffer(g_ctx,ib,DXGI_FORMAT_R32_UINT,0);g_ctx->lpVtbl->DrawIndexed(g_ctx,36,0,0);ib->lpVtbl->Release(ib);vb->lpVtbl->Release(vb); -} - -static void Spawn(void){for(int i=0;i1.3f)px=1.3f;if(py<-0.9f)py=-0.9f;if(py>0.9f)py=0.9f; - st+=dt;if(st>0.6f/speed){Spawn();st=0;} - for(int i=0;i2.0f)speed=2.0f;} - float dx=px>ox[i]?px-ox[i]:ox[i]-px;float dy=py>oy[i]?py-oy[i]:oy[i]-py;float dz=1.5f>oz[i]?1.5f-oz[i]:oz[i]-1.5f; - float md=0.12f+osz[i];if(dxlpVtbl->OMSetRenderTargets(g_ctx,1,&g_rtv,NULL);g_ctx->lpVtbl->ClearRenderTargetView(g_ctx,g_rtv,cl); - D3D11_VIEWPORT vp;memset(&vp,0,sizeof(vp));vp.Width=1280;vp.Height=720;vp.MaxDepth=1;g_ctx->lpVtbl->RSSetViewports(g_ctx,1,&vp); - D3D11_RASTERIZER_DESC rd;memset(&rd,0,sizeof(rd));rd.FillMode=D3D11_FILL_SOLID;rd.CullMode=D3D11_CULL_NONE;ID3D11RasterizerState*rs;g_dev->lpVtbl->CreateRasterizerState(g_dev,&rd,&rs);g_ctx->lpVtbl->RSSetState(g_ctx,rs); - D3D11_DEPTH_STENCIL_DESC ds;memset(&ds,0,sizeof(ds));ds.DepthEnable=FALSE;ID3D11DepthStencilState*dss;g_dev->lpVtbl->CreateDepthStencilState(g_dev,&ds,&dss);g_ctx->lpVtbl->OMSetDepthStencilState(g_ctx,dss,0); - g_ctx->lpVtbl->IASetPrimitiveTopology(g_ctx,D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);g_ctx->lpVtbl->VSSetShader(g_ctx,g_vs,NULL,0);g_ctx->lpVtbl->PSSetShader(g_ctx,g_ps,NULL,0);g_ctx->lpVtbl->IASetInputLayout(g_ctx,g_il);g_ctx->lpVtbl->VSSetConstantBuffers(g_ctx,0,1,&g_cb);g_ctx->lpVtbl->UpdateSubresource(g_ctx,(ID3D11Resource*)g_cb,0,NULL,mvp,0,0); - - if(dead){Cube(0,0,1.5f,0.4f,.9f,.1f,.1f);} - else{ - Cube(px,py,1.5f,0.12f,.1f,.9f,.3f); - for(int i=0;ilpVtbl->Release(rs);if(dss)dss->lpVtbl->Release(dss);g_sc->lpVtbl->Present(g_sc,1,0); -} - -static LRESULT CALLBACK WP(HWND h,UINT m,WPARAM w,LPARAM l){switch(m){case WM_KEYDOWN:switch(w){case VK_LEFT:key_l=1;break;case VK_RIGHT:key_r=1;break;case VK_UP:key_u=1;break;case VK_DOWN:key_d=1;break;case 'A':key_l=1;break;case 'D':key_r=1;break;case 'W':key_u=1;break;case 'S':key_d=1;break;case VK_SPACE:key_sp=1;break;case VK_ESCAPE:PostQuitMessage(0);break;}break;case WM_KEYUP:switch(w){case VK_LEFT:key_l=0;break;case VK_RIGHT:key_r=0;break;case VK_UP:key_u=0;break;case VK_DOWN:key_d=0;break;case 'A':key_l=0;break;case 'D':key_r=0;break;case 'W':key_u=0;break;case 'S':key_d=0;break;case VK_SPACE:key_sp=0;break;}break;case WM_DESTROY:PostQuitMessage(0);return 0;}return DefWindowProcW(h,m,w,l);} - -int WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int){srand(42);WNDCLASSEXW wc;memset(&wc,0,sizeof(wc));wc.cbSize=sizeof(wc);wc.style=CS_CLASSDC;wc.lpfnWndProc=WP;wc.hInstance=hI;wc.lpszClassName=L"dodge";RegisterClassExW(&wc);HWND hwnd=CreateWindowW(L"dodge",L"Cube Dodge - WASD/Arrows move, Space restart",WS_OVERLAPPEDWINDOW,200,100,1280,720,NULL,NULL,hI,NULL);if(!hwnd)return -1;ShowWindow(hwnd,SW_SHOW);UpdateWindow(hwnd);Init(hwnd);MSG msg;while(1){while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);if(msg.message==WM_QUIT)goto done;}Frame();}done:if(g_cb)g_cb->lpVtbl->Release(g_cb);if(g_il)g_il->lpVtbl->Release(g_il);if(g_vs)g_vs->lpVtbl->Release(g_vs);if(g_ps)g_ps->lpVtbl->Release(g_ps);if(g_rtv)g_rtv->lpVtbl->Release(g_rtv);if(g_sc)g_sc->lpVtbl->Release(g_sc);if(g_ctx)g_ctx->lpVtbl->Release(g_ctx);if(g_dev)g_dev->lpVtbl->Release(g_dev);return 0;} diff --git a/Demo/Demo/d3d11_test.c b/Demo/Demo/d3d11_test.c deleted file mode 100644 index 5dbef4b..0000000 --- a/Demo/Demo/d3d11_test.c +++ /dev/null @@ -1,95 +0,0 @@ -// 独立 D3D11 测试 - 不依赖引擎框架 -#include -#include -#include -#include - -#pragma comment(lib, "d3d11.lib") -#pragma comment(lib, "dxgi.lib") - -static ID3D11Device* device = NULL; -static ID3D11DeviceContext* context = NULL; -static IDXGISwapChain* swap_chain = NULL; -static ID3D11RenderTargetView* rtv = NULL; - -static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (msg == WM_DESTROY) { PostQuitMessage(0); return 0; } - return DefWindowProcW(hwnd, msg, wParam, lParam); -} - -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { - (void)hPrevInstance; (void)lpCmdLine; (void)nCmdShow; - - // 注册窗口类 - WNDCLASSEXW wc = {0}; - wc.cbSize = sizeof(WNDCLASSEXW); - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = WndProc; - wc.hInstance = hInstance; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.lpszClassName = L"D3D11Test"; - RegisterClassExW(&wc); - - // 创建窗口 - HWND hwnd = CreateWindowExW(0, L"D3D11Test", L"D3D11 Test", - WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, - NULL, NULL, hInstance, NULL); - ShowWindow(hwnd, SW_SHOW); - UpdateWindow(hwnd); - - // 创建 D3D11 设备和交换链 - DXGI_SWAP_CHAIN_DESC scd = {0}; - scd.BufferCount = 1; - scd.BufferDesc.Width = 800; - scd.BufferDesc.Height = 600; - scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - scd.BufferDesc.RefreshRate.Numerator = 60; - scd.BufferDesc.RefreshRate.Denominator = 1; - scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - scd.OutputWindow = hwnd; - scd.SampleDesc.Count = 1; - scd.Windowed = TRUE; - scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - - D3D_FEATURE_LEVEL levels[] = {D3D_FEATURE_LEVEL_11_0}; - HRESULT hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, levels, 1, D3D11_SDK_VERSION, &scd, &swap_chain, &device, NULL, &context); - - if (FAILED(hr)) { - MessageBoxW(hwnd, L"D3D11 CreateDevice Failed!", L"Error", MB_OK); - return -1; - } - - // 创建渲染目标 - ID3D11Texture2D* back_buffer = NULL; - swap_chain->lpVtbl->GetBuffer(swap_chain, 0, &IID_ID3D11Texture2D, (void**)&back_buffer); - device->lpVtbl->CreateRenderTargetView(device, (ID3D11Resource*)back_buffer, NULL, &rtv); - back_buffer->lpVtbl->Release(back_buffer); - - // 设置渲染目标 - context->lpVtbl->OMSetRenderTargets(context, 1, &rtv, NULL); - - // 主循环 - MSG msg = {0}; - while (msg.message != WM_QUIT) { - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - if (msg.message == WM_QUIT) break; - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - // 清屏 - 蓝色 - float color[4] = {0.2f, 0.5f, 0.8f, 1.0f}; - context->lpVtbl->ClearRenderTargetView(context, rtv, color); - - // 呈现 - swap_chain->lpVtbl->Present(swap_chain, 0, 0); - } - - // 清理 - rtv->lpVtbl->Release(rtv); - swap_chain->lpVtbl->Release(swap_chain); - context->lpVtbl->Release(context); - device->lpVtbl->Release(device); - - return 0; -} diff --git a/Demo/Demo/editor_main.c b/Demo/Demo/editor_main.c deleted file mode 100644 index b7d1b6d..0000000 --- a/Demo/Demo/editor_main.c +++ /dev/null @@ -1,682 +0,0 @@ -#include "../Engine/Core/engine.h" -#include "../Engine/Core/logger.h" -#include "../Engine/Core/asset_manager.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/renderer.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Rendering/material.h" -#include "../Engine/Rendering/mesh.h" -#include "../Engine/Rendering/camera.h" -#include "../Engine/Scene/scene_graph.h" -#include "../Engine/Scene/scene_render.h" -#include "../Engine/Scene/scene_serialize.h" -#include "../Engine/Editor/glyph_atlas.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" -#include -#include -#include -#include -#include - -/* -------------------------------------------------------------------------- */ -/* Editor state */ -/* -------------------------------------------------------------------------- */ -static Engine* g_engine = NULL; -static GraphicsDevice* g_gdev = NULL; -static Renderer* g_renderer = NULL; -static AssetManager* g_assets = NULL; -static Asset* g_shader_asset = NULL; -static Scene* g_scene = NULL; -static Camera g_camera; - -static GlyphAtlas g_atlas; -static int g_atlas_ok = 0; - -static SceneNode* g_selected = NULL; -static int g_mouse_x = 0; -static int g_mouse_y = 0; -static int g_mouse_down[3] = {0}; -static int g_mouse_last_x = 0; -static int g_mouse_last_y = 0; -static int g_camera_drag = 0; - -static char g_console[16][256]; -static int g_console_count = 0; -static char g_status[256] = ""; - -/* UI metrics */ -#define ED_MENU_H 30 -#define ED_TOOLBAR_H 30 -#define ED_LEFT_W 240 -#define ED_RIGHT_W 260 -#define ED_BOTTOM_H 180 -#define ED_SPLITTER 1 - -/* UI D3D resources */ -static ID3D11DepthStencilState* g_ui_depth = NULL; -static ID3D11RasterizerState* g_ui_raster = NULL; -static ID3D11BlendState* g_ui_blend = NULL; -static ID3D11SamplerState* g_ui_sampler = NULL; -static ID3D11Buffer* g_ui_cb = NULL; -static ID3D11VertexShader* g_ui_vs = NULL; -static ID3D11PixelShader* g_ui_ps = NULL; -static ID3D11InputLayout* g_ui_layout = NULL; -static ID3D11VertexShader* g_text_vs = NULL; -static ID3D11PixelShader* g_text_ps = NULL; -static ID3D11InputLayout* g_text_layout = NULL; - -typedef struct { float p[3], n[3], uv[2], c[4]; } UIVertex; - -/* -------------------------------------------------------------------------- */ -/* Console */ -/* -------------------------------------------------------------------------- */ -static void console_add(const char* msg) { - if (g_console_count >= 16) { - for (int i = 0; i < 15; i++) strcpy(g_console[i], g_console[i+1]); - g_console_count = 15; - } - strncpy(g_console[g_console_count], msg, 255); - g_console[g_console_count][255] = 0; - g_console_count++; -} - -/* -------------------------------------------------------------------------- */ -/* Shader helpers */ -/* -------------------------------------------------------------------------- */ -static ID3DBlob* compile_blob(const char* code, const char* target) { - ID3DBlob *blob = NULL, *err = NULL; - D3DCompile(code, strlen(code), NULL, NULL, NULL, "main", target, - D3DCOMPILE_OPTIMIZATION_LEVEL3 | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR, 0, &blob, &err); - if (err) { - LOG_ERROR("Editor shader compile (%s): %s", target, (char*)err->lpVtbl->GetBufferPointer(err)); - err->lpVtbl->Release(err); - } - return blob; -} - -static int compile_ui_shaders(ID3D11Device* dev) { - const char* vs = - "cbuffer CB:register(b0){float4x4 WVP;};" - "struct I{float4 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};" - "struct O{float4 p:SV_POSITION;float2 u:TEXCOORD;float4 c:COLOR;};" - "O main(I i){O o;o.p=mul(i.p,WVP);o.u=i.u;o.c=i.c;return o;}"; - const char* ps = - "struct O{float4 p:SV_POSITION;float2 u:TEXCOORD;float4 c:COLOR;};" - "float4 main(O i):SV_TARGET{return i.c;}"; - const char* tps = - "Texture2D t:register(t0);SamplerState s:register(s0);" - "struct O{float4 p:SV_POSITION;float2 u:TEXCOORD;float4 c:COLOR;};" - "float4 main(O i):SV_TARGET{float a=t.Sample(s,i.u).a;return float4(i.c.rgb,i.c.a*a);}"; - - ID3DBlob *b1 = compile_blob(vs, "vs_5_0"), *b2 = compile_blob(ps, "ps_5_0"), *b3 = compile_blob(tps, "ps_5_0"); - if (!b1 || !b2 || !b3) return 0; - - dev->lpVtbl->CreateVertexShader(dev, b1->lpVtbl->GetBufferPointer(b1), b1->lpVtbl->GetBufferSize(b1), NULL, &g_ui_vs); - dev->lpVtbl->CreatePixelShader(dev, b2->lpVtbl->GetBufferPointer(b2), b2->lpVtbl->GetBufferSize(b2), NULL, &g_ui_ps); - dev->lpVtbl->CreatePixelShader(dev, b3->lpVtbl->GetBufferPointer(b3), b3->lpVtbl->GetBufferSize(b3), NULL, &g_text_ps); - - D3D11_INPUT_ELEMENT_DESC layout[] = { - {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}, - }; - dev->lpVtbl->CreateInputLayout(dev, layout, 4, b1->lpVtbl->GetBufferPointer(b1), b1->lpVtbl->GetBufferSize(b1), &g_ui_layout); - g_text_layout = g_ui_layout; - g_text_vs = g_ui_vs; - - b1->lpVtbl->Release(b1); b2->lpVtbl->Release(b2); b3->lpVtbl->Release(b3); - return g_ui_vs && g_ui_ps && g_text_ps && g_ui_layout; -} - -static void create_ui_states(ID3D11Device* dev) { - D3D11_DEPTH_STENCIL_DESC dsd = {0}; - dsd.DepthEnable = FALSE; dsd.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - dev->lpVtbl->CreateDepthStencilState(dev, &dsd, &g_ui_depth); - - D3D11_RASTERIZER_DESC rd = {0}; - rd.FillMode = D3D11_FILL_SOLID; rd.CullMode = D3D11_CULL_NONE; - dev->lpVtbl->CreateRasterizerState(dev, &rd, &g_ui_raster); - - D3D11_BLEND_DESC bd = {0}; - bd.RenderTarget[0].BlendEnable = TRUE; - bd.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - bd.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - bd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - bd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - bd.RenderTarget[0].BlendOp = bd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - bd.RenderTarget[0].RenderTargetWriteMask = 0x0F; - dev->lpVtbl->CreateBlendState(dev, &bd, &g_ui_blend); - - D3D11_SAMPLER_DESC sd = {0}; - sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - sd.AddressU = sd.AddressV = sd.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - dev->lpVtbl->CreateSamplerState(dev, &sd, &g_ui_sampler); - - D3D11_BUFFER_DESC cbd = {0}; - cbd.ByteWidth = 256; cbd.Usage = D3D11_USAGE_DEFAULT; cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - dev->lpVtbl->CreateBuffer(dev, &cbd, NULL, &g_ui_cb); -} - -/* -------------------------------------------------------------------------- */ -/* UI rendering */ -/* -------------------------------------------------------------------------- */ -static void ui_set_projection(ID3D11DeviceContext* ctx, float sw, float sh) { - float proj[16] = {0}; - proj[0] = 2.0f / sw; proj[5] = -2.0f / sh; - proj[10] = 1.0f; proj[12] = -1.0f; proj[13] = 1.0f; proj[15] = 1.0f; - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)g_ui_cb, 0, NULL, proj, 0, 0); -} - -static void ui_setup_solid(ID3D11DeviceContext* ctx) { - ctx->lpVtbl->VSSetShader(ctx, g_ui_vs, NULL, 0); - ctx->lpVtbl->PSSetShader(ctx, g_ui_ps, NULL, 0); - ctx->lpVtbl->IASetInputLayout(ctx, g_ui_layout); - ctx->lpVtbl->VSSetConstantBuffers(ctx, 0, 1, &g_ui_cb); - ctx->lpVtbl->OMSetBlendState(ctx, NULL, NULL, 0xFFFFFFFF); -} - -static void ui_setup_text(ID3D11DeviceContext* ctx) { - ctx->lpVtbl->VSSetShader(ctx, g_text_vs, NULL, 0); - ctx->lpVtbl->PSSetShader(ctx, g_text_ps, NULL, 0); - ctx->lpVtbl->IASetInputLayout(ctx, g_text_layout); - ctx->lpVtbl->VSSetConstantBuffers(ctx, 0, 1, &g_ui_cb); - ctx->lpVtbl->PSSetShaderResources(ctx, 0, 1, &g_atlas.srv); - ctx->lpVtbl->PSSetSamplers(ctx, 0, 1, &g_ui_sampler); - ctx->lpVtbl->OMSetBlendState(ctx, g_ui_blend, NULL, 0xFFFFFFFF); -} - -static void ui_begin(ID3D11DeviceContext* ctx, float sw, float sh) { - D3D11_VIEWPORT vp = {0}; - vp.Width = sw; vp.Height = sh; vp.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vp); - ctx->lpVtbl->RSSetState(ctx, g_ui_raster); - ctx->lpVtbl->OMSetDepthStencilState(ctx, g_ui_depth, 0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ui_set_projection(ctx, sw, sh); - ui_setup_solid(ctx); -} - -static void draw_quad(ID3D11DeviceContext* ctx, float x, float y, float w, float h, - float r, float g, float b, float a) { - UIVertex v[4] = { - {{x, y, 0},{0,0,-1},{0,0},{r,g,b,a}}, - {{x+w, y, 0},{0,0,-1},{1,0},{r,g,b,a}}, - {{x+w, y+h, 0},{0,0,-1},{1,1},{r,g,b,a}}, - {{x, y+h, 0},{0,0,-1},{0,1},{r,g,b,a}}, - }; - uint32_t idx[6] = {0,1,2, 0,2,3}; - ID3D11Buffer *vb = NULL, *ib = NULL; - D3D11_BUFFER_DESC bd = {0}; D3D11_SUBRESOURCE_DATA sd = {0}; - bd.ByteWidth = sizeof(UIVertex)*4; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = v; g_gdev->device->lpVtbl->CreateBuffer(g_gdev->device, &bd, &sd, &vb); - bd.ByteWidth = sizeof(uint32_t)*6; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = idx; g_gdev->device->lpVtbl->CreateBuffer(g_gdev->device, &bd, &sd, &ib); - UINT stride = sizeof(UIVertex), offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &vb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, ib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->DrawIndexed(ctx, 6, 0, 0); - if (ib) ib->lpVtbl->Release(ib); - if (vb) vb->lpVtbl->Release(vb); -} - -static void draw_text(ID3D11DeviceContext* ctx, const wchar_t* text, int x, int y, - float r, float g, float b, float a) { - if (!g_atlas_ok) return; - ui_setup_text(ctx); - for (const wchar_t* p = text; *p; p++) { - float u0, v0, u1, v1, ax, ay; - if (!glyph_atlas_get_or_create(&g_atlas, g_gdev->device, ctx, *p, &u0, &v0, &u1, &v1, &ax, &ay)) continue; - UIVertex tv[4] = { - {{(float)x, (float)y, 0},{0,0,1},{u0,v0},{r,g,b,a}}, - {{(float)x + ax, (float)y, 0},{0,0,1},{u1,v0},{r,g,b,a}}, - {{(float)x + ax, (float)y + ay, 0},{0,0,1},{u1,v1},{r,g,b,a}}, - {{(float)x, (float)y + ay, 0},{0,0,1},{u0,v1},{r,g,b,a}}, - }; - uint32_t ti[6] = {0,1,2, 0,2,3}; - ID3D11Buffer *tvb = NULL, *tib = NULL; - D3D11_BUFFER_DESC bd = {0}; D3D11_SUBRESOURCE_DATA sd = {0}; - bd.ByteWidth = sizeof(UIVertex)*4; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = tv; g_gdev->device->lpVtbl->CreateBuffer(g_gdev->device, &bd, &sd, &tvb); - bd.ByteWidth = sizeof(uint32_t)*6; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = ti; g_gdev->device->lpVtbl->CreateBuffer(g_gdev->device, &bd, &sd, &tib); - UINT stride = sizeof(UIVertex), offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &tvb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, tib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->DrawIndexed(ctx, 6, 0, 0); - if (tib) tib->lpVtbl->Release(tib); - if (tvb) tvb->lpVtbl->Release(tvb); - x += (int)ax + 1; - } - ui_setup_solid(ctx); -} - -static void draw_text_a(ID3D11DeviceContext* ctx, const char* text, int x, int y, - float r, float g, float b, float a) { - wchar_t buf[256]; - int n = (int)strlen(text); if (n > 255) n = 255; - for (int i = 0; i < n; i++) buf[i] = (wchar_t)text[i]; - buf[n] = 0; - draw_text(ctx, buf, x, y, r, g, b, a); -} - -/* -------------------------------------------------------------------------- */ -/* Scene helpers */ -/* -------------------------------------------------------------------------- */ -static SceneNode* create_primitive(Scene* scene, SceneNode* parent, AssetManager* am, - ID3D11Device* dev, const char* name, MeshType type, - Vec3 pos, Vec3 rot, Vec3 scale, Material* mat) { - SceneNode* node = scene_create_node(scene, name); - if (!node) return NULL; - if (parent) scene_set_parent(node, parent); - node->position = pos; - node->scale = scale; - quat_from_euler(rot.x, rot.y, rot.z, &node->rotation); - - Asset* mesh_asset = asset_manager_load_mesh(am, dev, name); - if (!mesh_asset) { - const char* builtin = NULL; - if (type == MESH_CUBE) builtin = "cube"; - else if (type == MESH_SPHERE) builtin = "sphere"; - else if (type == MESH_PLANE) builtin = "plane"; - if (builtin) mesh_asset = asset_manager_load_mesh(am, dev, builtin); - } - if (mesh_asset && mat) { - MeshRenderer* mr = mesh_renderer_create(type, (Mesh*)asset_data(mesh_asset), mat); - scene_node_set_mesh_renderer(node, mr); - } - return node; -} - -static Scene* create_default_editor_scene(AssetManager* am, ID3D11Device* dev, Shader* shader) { - Scene* scene = (Scene*)malloc(sizeof(Scene)); - if (!scene) return NULL; - scene_init(scene); - strncpy(scene->root->name, "root", sizeof(scene->root->name) - 1); - - Material* mat_red = material_create(shader, NULL); - mat_red->color = (Vec4){1.0f, 0.3f, 0.2f, 1.0f}; - Material* mat_blue = material_create(shader, NULL); - mat_blue->color = (Vec4){0.2f, 0.5f, 1.0f, 1.0f}; - Material* mat_ground = material_create(shader, NULL); - mat_ground->color = (Vec4){0.3f, 0.3f, 0.35f, 1.0f}; - - create_primitive(scene, scene->root, am, dev, "cube", MESH_CUBE, - (Vec3){0,0,0}, (Vec3){0,0,0}, (Vec3){1,1,1}, mat_red); - create_primitive(scene, scene->root, am, dev, "sphere", MESH_SPHERE, - (Vec3){2.0f,0,0}, (Vec3){0,0,0}, (Vec3){0.8f,0.8f,0.8f}, mat_blue); - create_primitive(scene, scene->root, am, dev, "ground", MESH_PLANE, - (Vec3){0,-1.0f,0}, (Vec3){0,0,0}, (Vec3){1,1,1}, mat_ground); - - scene_update(scene); - return scene; -} - -/* -------------------------------------------------------------------------- */ -/* Editor UI */ -/* -------------------------------------------------------------------------- */ -static void draw_panel_bg(ID3D11DeviceContext* ctx, float sw, float sh) { - float body_h = sh - ED_MENU_H - ED_TOOLBAR_H - ED_BOTTOM_H; - - /* menu bar */ - draw_quad(ctx, 0, 0, sw, ED_MENU_H, 0.14f, 0.14f, 0.18f, 1.0f); - /* toolbar */ - draw_quad(ctx, 0, ED_MENU_H, sw, ED_TOOLBAR_H, 0.20f, 0.20f, 0.26f, 1.0f); - /* separators */ - draw_quad(ctx, 0, ED_MENU_H, sw, 1, 0.30f, 0.45f, 0.75f, 1.0f); - draw_quad(ctx, 0, ED_MENU_H + ED_TOOLBAR_H, sw, 1, 0.30f, 0.45f, 0.75f, 1.0f); - /* left panel */ - draw_quad(ctx, 0, ED_MENU_H + ED_TOOLBAR_H + 1, ED_LEFT_W, body_h, 0.18f, 0.18f, 0.23f, 1.0f); - draw_quad(ctx, ED_LEFT_W, ED_MENU_H + ED_TOOLBAR_H + 1, ED_SPLITTER, body_h, 0.30f, 0.45f, 0.75f, 1.0f); - /* right panel */ - draw_quad(ctx, sw - ED_RIGHT_W, ED_MENU_H + ED_TOOLBAR_H + 1, ED_RIGHT_W, body_h, 0.18f, 0.18f, 0.23f, 1.0f); - draw_quad(ctx, sw - ED_RIGHT_W - ED_SPLITTER, ED_MENU_H + ED_TOOLBAR_H + 1, ED_SPLITTER, body_h, 0.30f, 0.45f, 0.75f, 1.0f); - /* bottom console */ - draw_quad(ctx, 0, sh - ED_BOTTOM_H - ED_SPLITTER, sw, ED_SPLITTER, 0.30f, 0.45f, 0.75f, 1.0f); - draw_quad(ctx, 0, sh - ED_BOTTOM_H, sw, ED_BOTTOM_H, 0.16f, 0.16f, 0.21f, 1.0f); - /* status bar */ - draw_quad(ctx, 0, sh - 22, sw, 22, 0.20f, 0.22f, 0.32f, 1.0f); -} - -static void draw_hierarchy(ID3D11DeviceContext* ctx, float sh) { - (void)sh; - int y = ED_MENU_H + ED_TOOLBAR_H + 28; - draw_text(ctx, L"\u573a\u666f\u5c42\u7ea7", 12, y - 20, 0.5f, 0.75f, 1.0f, 1.0f); - if (!g_scene) return; - - for (int i = 1; i < g_scene->node_count; i++) { - SceneNode* node = &g_scene->nodes[i]; - if (node->id < 0) continue; - - int row_y = y + (i - 1) * 22; - if (node == g_selected) - draw_quad(ctx, 4, (float)row_y - 2, ED_LEFT_W - 8, 22, 0.25f, 0.38f, 0.65f, 1.0f); - - wchar_t wn[64]; - int len = (int)strlen(node->name); if (len > 63) len = 63; - for (int j = 0; j < len; j++) wn[j] = (wchar_t)node->name[j]; - wn[len] = 0; - draw_text(ctx, wn, 16, row_y, 1.0f, 1.0f, 1.0f, 1.0f); - } -} - -static void draw_inspector(ID3D11DeviceContext* ctx, float sw, float sh) { - (void)sh; - int x = (int)(sw - ED_RIGHT_W + 12); - int y = ED_MENU_H + ED_TOOLBAR_H + 28; - draw_text(ctx, L"\u5c5e\u6027", x, y - 20, 0.5f, 0.75f, 1.0f, 1.0f); - if (!g_selected) { - draw_text_a(ctx, "未选择对象", x, y, 0.7f, 0.7f, 0.75f, 1.0f); - return; - } - - char buf[128]; - int iy = y; - snprintf(buf, sizeof(buf), "名称: %s", g_selected->name); draw_text_a(ctx, buf, x, iy, 1.0f, 1.0f, 1.0f, 1.0f); iy += 24; - - float rx, ry, rz; - quat_to_euler(&g_selected->rotation, &rx, &ry, &rz); - snprintf(buf, sizeof(buf), "位置: %.2f %.2f %.2f", g_selected->position.x, g_selected->position.y, g_selected->position.z); - draw_text_a(ctx, buf, x, iy, 0.85f, 0.85f, 0.88f, 1.0f); iy += 22; - snprintf(buf, sizeof(buf), "旋转: %.1f %.1f %.1f", rx * 57.2958f, ry * 57.2958f, rz * 57.2958f); - draw_text_a(ctx, buf, x, iy, 0.85f, 0.85f, 0.88f, 1.0f); iy += 22; - snprintf(buf, sizeof(buf), "缩放: %.2f %.2f %.2f", g_selected->scale.x, g_selected->scale.y, g_selected->scale.z); - draw_text_a(ctx, buf, x, iy, 0.85f, 0.85f, 0.88f, 1.0f); iy += 30; - - draw_text_a(ctx, "WASD 平移 | QE 升降", x, iy, 0.6f, 0.7f, 0.85f, 1.0f); iy += 20; - draw_text_a(ctx, "方向键 旋转 | +/- 缩放", x, iy, 0.6f, 0.7f, 0.85f, 1.0f); -} - -static void draw_console(ID3D11DeviceContext* ctx, float sh) { - int y = (int)(sh - ED_BOTTOM_H + 24); - draw_text(ctx, L"\u63a7\u5236\u53f0", 12, y - 18, 0.5f, 0.75f, 1.0f, 1.0f); - int cy = y; - for (int i = g_console_count - 1; i >= 0 && i >= g_console_count - 6; i--) { - wchar_t wl[256]; - int len = (int)strlen(g_console[i]); if (len > 255) len = 255; - for (int j = 0; j < len; j++) wl[j] = (wchar_t)g_console[i][j]; - wl[len] = 0; - draw_text(ctx, wl, 12, cy, 0.75f, 0.75f, 0.80f, 1.0f); - cy += 20; - } -} - -static void draw_ui(ID3D11DeviceContext* ctx, float sw, float sh) { - ui_begin(ctx, sw, sh); - draw_quad(ctx, 0, 0, sw, sh, 0.5f, 0, 0, 0.3f); /* debug overlay */ - draw_panel_bg(ctx, sw, sh); - - /* title / menus */ - draw_text(ctx, L"Lity3D Engine Editor", 12, 7, 0.6f, 0.8f, 1.0f, 1.0f); - const wchar_t* menus[] = {L"\u6587\u4ef6", L"\u7f16\u8f91", L"\u89c6\u56fe", L"\u6784\u5efa", L"\u5e2e\u52a9"}; - int mx = 160; - for (int i = 0; i < 5; i++) { draw_text(ctx, menus[i], mx, 8, 0.9f, 0.9f, 0.92f, 1.0f); mx += 70; } - - draw_hierarchy(ctx, sh); - draw_inspector(ctx, sw, sh); - draw_console(ctx, sh); - - draw_text_a(ctx, g_status, 12, (int)(sh - 18), 0.65f, 0.65f, 0.70f, 1.0f); -} - -/* -------------------------------------------------------------------------- */ -/* Input / interaction */ -/* -------------------------------------------------------------------------- */ -static void update_status(void) { - if (g_selected) { - snprintf(g_status, sizeof(g_status), - "%s | pos(%.2f,%.2f,%.2f) | FOV %.0f | Esc quit | Ctrl+S save", - g_selected->name, - g_selected->position.x, g_selected->position.y, g_selected->position.z, - g_camera.fov_y * 57.2958f); - } else { - snprintf(g_status, sizeof(g_status), "无选中对象 | FOV %.0f | Esc quit | Ctrl+S save", g_camera.fov_y * 57.2958f); - } -} - -static void process_hierarchy_click(int mx, int my) { - float body_top = ED_MENU_H + ED_TOOLBAR_H + 1; - float body_h = (float)g_gdev->height - ED_MENU_H - ED_TOOLBAR_H - ED_BOTTOM_H; - if (mx < 0 || mx > ED_LEFT_W || my < body_top || my > body_top + body_h) return; - - int list_y = ED_MENU_H + ED_TOOLBAR_H + 28; - int idx = (my - list_y + 2) / 22 + 1; - if (idx >= 1 && idx < g_scene->node_count) { - SceneNode* node = &g_scene->nodes[idx]; - if (node->id >= 0) { - g_selected = node; - char buf[128]; snprintf(buf, sizeof(buf), "选中: %s", node->name); - console_add(buf); - update_status(); - } - } -} - -static void on_mouse_move(Engine* engine, int x, int y) { - (void)engine; - g_mouse_x = x; g_mouse_y = y; - - if (g_camera_drag && g_mouse_down[1]) { - float dx = (float)(x - g_mouse_last_x); - float dy = (float)(y - g_mouse_last_y); - camera_rotate_yaw(&g_camera, dx * 0.005f); - camera_rotate_pitch(&g_camera, dy * 0.005f); - g_mouse_last_x = x; g_mouse_last_y = y; - } else if (g_mouse_down[1]) { - g_camera_drag = 1; - g_mouse_last_x = x; g_mouse_last_y = y; - } else { - g_camera_drag = 0; - } -} - -static void on_mouse_button(Engine* engine, int button, int pressed) { - (void)engine; - if (button >= 0 && button < 3) g_mouse_down[button] = pressed; - - if (button == 0 && pressed) { - process_hierarchy_click(g_mouse_x, g_mouse_y); - } -} - -static void on_key(Engine* engine, int key) { - if (key == VK_ESCAPE) { engine_request_quit(engine); return; } - - if (GetAsyncKeyState(VK_CONTROL) & 0x8000) { - if (key == 'S' || key == 's') { - if (scene_save(g_scene, "scene.txt")) { - console_add("已保存 scene.txt"); - } else { - console_add("保存 scene.txt 失败"); - } - return; - } - if (key == 'O' || key == 'o') { - Scene* new_scene = scene_load("scene.txt", g_gdev->device, (Shader*)asset_data(g_shader_asset)); - if (new_scene) { - scene_destroy_renderers(g_scene); - scene_destroy(g_scene); - free(g_scene); - g_scene = new_scene; - g_selected = NULL; - console_add("已加载 scene.txt"); - } else { - console_add("加载 scene.txt 失败"); - } - return; - } - } - - if (!g_selected) return; - - float speed = 0.1f; - if (GetAsyncKeyState(VK_SHIFT) & 0x8000) speed = 0.5f; - - Vec3 pos = g_selected->position; - switch (key) { - case 'W': case 'w': pos.z += speed; break; - case 'S': case 's': pos.z -= speed; break; - case 'A': case 'a': pos.x -= speed; break; - case 'D': case 'd': pos.x += speed; break; - case 'Q': case 'q': pos.y += speed; break; - case 'E': case 'e': pos.y -= speed; break; - default: break; - } - if (pos.x != g_selected->position.x || pos.y != g_selected->position.y || pos.z != g_selected->position.z) { - scene_set_position(g_selected, pos.x, pos.y, pos.z); - } - - float rx, ry, rz; - quat_to_euler(&g_selected->rotation, &rx, &ry, &rz); - int rot_changed = 0; - switch (key) { - case VK_LEFT: ry -= 0.05f; rot_changed = 1; break; - case VK_RIGHT: ry += 0.05f; rot_changed = 1; break; - case VK_UP: rx -= 0.05f; rot_changed = 1; break; - case VK_DOWN: rx += 0.05f; rot_changed = 1; break; - case VK_PRIOR: rz += 0.05f; rot_changed = 1; break; /* PageUp */ - case VK_NEXT: rz -= 0.05f; rot_changed = 1; break; /* PageDown */ - default: break; - } - if (rot_changed) scene_set_rotation_euler(g_selected, rx, ry, rz); - - Vec3 scale = g_selected->scale; - int scale_changed = 0; - switch (key) { - case VK_ADD: scale.x += 0.1f; scale.y += 0.1f; scale.z += 0.1f; scale_changed = 1; break; - case VK_SUBTRACT: scale.x -= 0.1f; scale.y -= 0.1f; scale.z -= 0.1f; scale_changed = 1; break; - default: break; - } - if (scale_changed) scene_set_scale(g_selected, scale.x, scale.y, scale.z); - - update_status(); -} - -static void on_resize(Engine* engine, int width, int height) { - (void)engine; - if (width > 0 && height > 0) { - renderer_resize(g_renderer, width, height); - g_camera.aspect = (float)width / (float)height; - g_camera.dirty = 1; - } -} - -/* -------------------------------------------------------------------------- */ -/* Render callback */ -/* -------------------------------------------------------------------------- */ -static void on_render(Engine* engine) { - (void)engine; - if (!g_renderer || !g_gdev) return; - - renderer_set_view(g_renderer, camera_get_view(&g_camera)); - renderer_set_projection(g_renderer, camera_get_projection(&g_camera)); - - renderer_begin_frame(g_renderer); - if (g_scene) { - scene_update(g_scene); - scene_render(g_scene, g_renderer); - } - - draw_ui(g_gdev->context, (float)g_gdev->width, (float)g_gdev->height); - - renderer_end_frame(g_renderer); - - if (engine->frame_count == 60) { - graphics_device_save_screenshot(g_gdev, "editor_screenshot.bmp"); - console_add("已保存 editor_screenshot.bmp"); - } -} - -static void on_update(Engine* engine, double dt) { - (void)engine; (void)dt; -} - -/* -------------------------------------------------------------------------- */ -/* Main */ -/* -------------------------------------------------------------------------- */ -int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR cmd, int nS) { - (void)hI; (void)hP; (void)nS; - logger_init("engine.log"); - LOG_INFO("=== Lity3D Engine Editor ==="); - - EngineConfig cfg = engine_default_config(); - cfg.app_name = "Lity3D Engine Editor"; - cfg.window_width = 1440; - cfg.window_height = 900; - cfg.vsync = 1; - - g_engine = engine_create(); - if (!engine_init(g_engine, &cfg)) { - LOG_FATAL("Engine init failed"); - return -1; - } - - g_gdev = engine_get_graphics_device(g_engine); - g_renderer = engine_get_renderer(g_engine); - - g_assets = asset_manager_create(); - g_shader_asset = asset_manager_load_shader(g_assets, g_gdev->device, NULL, NULL); - if (!g_shader_asset) { - LOG_FATAL("Shader load failed"); - return -1; - } - Shader* default_shader = (Shader*)asset_data(g_shader_asset); - - g_scene = scene_load("scene.txt", g_gdev->device, default_shader); - if (!g_scene) { - LOG_INFO("Creating default editor scene"); - g_scene = create_default_editor_scene(g_assets, g_gdev->device, default_shader); - scene_save(g_scene, "scene.txt"); - } - - float aspect = (float)cfg.window_width / cfg.window_height; - g_camera = camera_perspective(1.0472f, aspect, 0.1f, 100.0f); - g_camera.position = (Vec3){0, 1.5f, -5.0f}; - g_camera.target = (Vec3){0, 0, 0}; - g_camera.dirty = 1; - - g_atlas_ok = glyph_atlas_init(&g_atlas, g_gdev->device); - if (!g_atlas_ok) LOG_WARN("GlyphAtlas init failed"); - - create_ui_states(g_gdev->device); - if (!compile_ui_shaders(g_gdev->device)) { - LOG_FATAL("UI shader compile failed"); - return -1; - } - - console_add("Lity3D Engine Editor ready"); - console_add("Ctrl+S 保存 | Ctrl+O 加载 | Esc 退出"); - console_add("左键点选层级,右键拖拽旋转视角"); - update_status(); - - engine_set_update_callback(g_engine, on_update); - engine_set_render_callback(g_engine, on_render); - engine_set_key_callback(g_engine, on_key); - engine_set_resize_callback(g_engine, on_resize); - engine_set_mouse_move_callback(g_engine, on_mouse_move); - engine_set_mouse_button_callback(g_engine, on_mouse_button); - - engine_run(g_engine); - - if (g_scene) { - scene_destroy_renderers(g_scene); - scene_destroy(g_scene); - free(g_scene); - } - asset_manager_destroy(g_assets); - - if (g_ui_sampler) g_ui_sampler->lpVtbl->Release(g_ui_sampler); - if (g_ui_blend) g_ui_blend->lpVtbl->Release(g_ui_blend); - if (g_ui_raster) g_ui_raster->lpVtbl->Release(g_ui_raster); - if (g_ui_depth) g_ui_depth->lpVtbl->Release(g_ui_depth); - if (g_ui_cb) g_ui_cb->lpVtbl->Release(g_ui_cb); - if (g_ui_ps) g_ui_ps->lpVtbl->Release(g_ui_ps); - if (g_ui_vs) g_ui_vs->lpVtbl->Release(g_ui_vs); - if (g_ui_layout) g_ui_layout->lpVtbl->Release(g_ui_layout); - if (g_atlas_ok) glyph_atlas_destroy(&g_atlas); - - engine_shutdown(g_engine); - logger_shutdown(); - return 0; -} diff --git a/Demo/Demo/game_test.c b/Demo/Demo/game_test.c deleted file mode 100644 index 1ecfb4a..0000000 --- a/Demo/Demo/game_test.c +++ /dev/null @@ -1,222 +0,0 @@ -#include -#include -#include -#include -#include -#include - -typedef struct { float p[3], n[3], u[2], c[4]; } V3D; - -static ID3D11Device* g_dev = NULL; -static ID3D11DeviceContext* g_ctx = NULL; -static IDXGISwapChain* g_sc = NULL; -static ID3D11RenderTargetView* g_rtv = NULL; -static ID3D11VertexShader* g_vs = NULL; -static ID3D11PixelShader* g_ps = NULL; -static ID3D11InputLayout* g_il = NULL; -static ID3D11Buffer* g_cb = NULL; - -static float cam_x = 0, cam_z = 0; -static int key_w = 0, key_s = 0, key_a = 0, key_d = 0; -static int key_left = 0, key_right = 0; -static int sel = 0; - -static void Init(HWND h) { - HRESULT hr; - DXGI_SWAP_CHAIN_DESC sd; - memset(&sd, 0, sizeof(sd)); - sd.BufferCount = 2; - sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - sd.BufferDesc.RefreshRate.Numerator = 60; - sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - sd.OutputWindow = h; - sd.SampleDesc.Count = 1; - sd.Windowed = TRUE; - sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - D3D_FEATURE_LEVEL fl = D3D_FEATURE_LEVEL_11_0; - D3D_FEATURE_LEVEL got; - hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &fl, 1, - D3D11_SDK_VERSION, &sd, &g_sc, &g_dev, &got, &g_ctx); - if (FAILED(hr)) { return; } - ID3D11Texture2D* bb = NULL; - hr = g_sc->lpVtbl->GetBuffer(g_sc, 0, &IID_ID3D11Texture2D, (void**)&bb); - if (FAILED(hr) || !bb) { return; } - hr = g_dev->lpVtbl->CreateRenderTargetView(g_dev, (ID3D11Resource*)bb, NULL, &g_rtv); - bb->lpVtbl->Release(bb); - if (FAILED(hr)) { return; } - const char* vs_src = - "cbuffer CB:register(b0){float4x4 WVP;};" - "struct I{float3 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};" - "struct O{float4 p:SV_POSITION;float4 c:COLOR;};" - "O main(I i){O o;o.p=mul(float4(i.p,1),WVP);o.c=i.c;return o;}"; - const char* ps_src = - "float4 main(float4 pos:SV_POSITION, float4 col:COLOR):SV_Target{return col;}"; - ID3DBlob *b1 = NULL, *b2 = NULL, *e1 = NULL, *e2 = NULL; - D3DCompile(vs_src, (UINT)strlen(vs_src), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &b1, &e1); - if (e1) { e1->lpVtbl->Release(e1); e1 = NULL; } - D3DCompile(ps_src, (UINT)strlen(ps_src), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &b2, &e2); - if (e2) { e2->lpVtbl->Release(e2); e2 = NULL; } - if (!b1 || !b2) { return; } - g_dev->lpVtbl->CreateVertexShader(g_dev, b1->lpVtbl->GetBufferPointer(b1), b1->lpVtbl->GetBufferSize(b1), NULL, &g_vs); - g_dev->lpVtbl->CreatePixelShader(g_dev, b2->lpVtbl->GetBufferPointer(b2), b2->lpVtbl->GetBufferSize(b2), NULL, &g_ps); - D3D11_INPUT_ELEMENT_DESC el[4]; - memset(el, 0, sizeof(el)); - el[0].SemanticName = "POSITION"; el[0].Format = DXGI_FORMAT_R32G32B32_FLOAT; el[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - el[1].SemanticName = "NORMAL"; el[1].AlignedByteOffset = 12; el[1].Format = DXGI_FORMAT_R32G32B32_FLOAT; el[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - el[2].SemanticName = "TEXCOORD"; el[2].AlignedByteOffset = 24; el[2].Format = DXGI_FORMAT_R32G32_FLOAT; el[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - el[3].SemanticName = "COLOR"; el[3].AlignedByteOffset = 32; el[3].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; el[3].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - g_dev->lpVtbl->CreateInputLayout(g_dev, el, 4, b1->lpVtbl->GetBufferPointer(b1), b1->lpVtbl->GetBufferSize(b1), &g_il); - b1->lpVtbl->Release(b1); b2->lpVtbl->Release(b2); - D3D11_BUFFER_DESC cbd; - memset(&cbd, 0, sizeof(cbd)); - cbd.ByteWidth = 256; cbd.Usage = D3D11_USAGE_DEFAULT; cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - g_dev->lpVtbl->CreateBuffer(g_dev, &cbd, NULL, &g_cb); -} - -static void DrawCube(float cx, float cy, float cz, float s, float cr, float cg, float cb2) { - V3D v[24]; - float f[6][4][3] = { - {{-1,-1,-1},{1,-1,-1},{1,1,-1},{-1,1,-1}}, - {{1,-1,-1},{1,-1,1},{1,1,1},{1,1,-1}}, - {{1,-1,1},{-1,-1,1},{-1,1,1},{1,1,1}}, - {{-1,-1,1},{-1,-1,-1},{-1,1,-1},{-1,1,1}}, - {{-1,1,-1},{1,1,-1},{1,1,1},{-1,1,1}}, - {{-1,-1,1},{1,-1,1},{1,-1,-1},{-1,-1,-1}} - }; - float nm[6][3] = {{0,0,-1},{1,0,0},{0,0,1},{-1,0,0},{0,1,0},{0,-1,0}}; - for (int fi = 0; fi < 6; fi++) - for (int vi = 0; vi < 4; vi++) { - int i = fi * 4 + vi; - v[i].p[0] = f[fi][vi][0] * s + cx; - v[i].p[1] = f[fi][vi][1] * s + cy; - v[i].p[2] = f[fi][vi][2] * s + cz; - v[i].n[0] = nm[fi][0]; v[i].n[1] = nm[fi][1]; v[i].n[2] = nm[fi][2]; - v[i].c[0] = cr; v[i].c[1] = cg; v[i].c[2] = cb2; v[i].c[3] = 1; - } - uint32_t ix[36]; - for (int fi = 0; fi < 6; fi++) { - int b = fi * 4; - ix[fi*6]=b; ix[fi*6+1]=b+1; ix[fi*6+2]=b+2; ix[fi*6+3]=b; ix[fi*6+4]=b+2; ix[fi*6+5]=b+3; - } - ID3D11Buffer *vb = NULL, *ib = NULL; - D3D11_BUFFER_DESC bd; D3D11_SUBRESOURCE_DATA sd; - memset(&bd, 0, sizeof(bd)); memset(&sd, 0, sizeof(sd)); - bd.ByteWidth = sizeof(V3D) * 24; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = v; g_dev->lpVtbl->CreateBuffer(g_dev, &bd, &sd, &vb); - bd.ByteWidth = sizeof(uint32_t) * 36; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = ix; g_dev->lpVtbl->CreateBuffer(g_dev, &bd, &sd, &ib); - UINT s2 = sizeof(V3D), o = 0; - g_ctx->lpVtbl->IASetVertexBuffers(g_ctx, 0, 1, &vb, &s2, &o); - g_ctx->lpVtbl->IASetIndexBuffer(g_ctx, ib, DXGI_FORMAT_R32_UINT, 0); - g_ctx->lpVtbl->DrawIndexed(g_ctx, 36, 0, 0); - ib->lpVtbl->Release(ib); vb->lpVtbl->Release(vb); -} - -static void Frame(void) { - float dt = 0.016f, spd = 3.0f * dt; - if (key_w) cam_z += spd; if (key_s) cam_z -= spd; - if (key_a) cam_x -= spd; if (key_d) cam_x += spd; - if (key_left) sel = (sel + 3) % 4; - if (key_right) sel = (sel + 1) % 4; - - float fov = 1.0f / tanf(0.4f), asp = 1280.0f / 720.0f; - float mvp[16]; memset(mvp, 0, sizeof(mvp)); - mvp[0] = fov / asp; mvp[5] = -fov; mvp[10] = 1; mvp[11] = -1; mvp[14] = 0.1f; mvp[15] = 1; - float m2[16]; memcpy(m2, mvp, 64); - for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { float t = m2[i*4+j]; m2[i*4+j] = m2[j*4+i]; m2[j*4+i] = t; } - - float cl[4] = {.15f, .18f, .25f, 1}; - g_ctx->lpVtbl->OMSetRenderTargets(g_ctx, 1, &g_rtv, NULL); - g_ctx->lpVtbl->ClearRenderTargetView(g_ctx, g_rtv, cl); - D3D11_VIEWPORT vp; memset(&vp, 0, sizeof(vp)); - vp.Width = 1280; vp.Height = 720; vp.MaxDepth = 1; - g_ctx->lpVtbl->RSSetViewports(g_ctx, 1, &vp); - D3D11_RASTERIZER_DESC rd; memset(&rd, 0, sizeof(rd)); - rd.FillMode = D3D11_FILL_SOLID; rd.CullMode = D3D11_CULL_NONE; - ID3D11RasterizerState* rs = NULL; - g_dev->lpVtbl->CreateRasterizerState(g_dev, &rd, &rs); - g_ctx->lpVtbl->RSSetState(g_ctx, rs); - D3D11_DEPTH_STENCIL_DESC ds; memset(&ds, 0, sizeof(ds)); - ds.DepthEnable = FALSE; - ID3D11DepthStencilState* dss = NULL; - g_dev->lpVtbl->CreateDepthStencilState(g_dev, &ds, &dss); - g_ctx->lpVtbl->OMSetDepthStencilState(g_ctx, dss, 0); - g_ctx->lpVtbl->IASetPrimitiveTopology(g_ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - g_ctx->lpVtbl->VSSetShader(g_ctx, g_vs, NULL, 0); - g_ctx->lpVtbl->PSSetShader(g_ctx, g_ps, NULL, 0); - g_ctx->lpVtbl->IASetInputLayout(g_ctx, g_il); - g_ctx->lpVtbl->VSSetConstantBuffers(g_ctx, 0, 1, &g_cb); - g_ctx->lpVtbl->UpdateSubresource(g_ctx, (ID3D11Resource*)g_cb, 0, NULL, m2, 0, 0); - - float colors[4][3] = {{1,.3f,.3f},{.3f,1,.3f},{.3f,.3f,1},{.8f,.8f,.2f}}; - float sizes[4] = {0.3f, 0.25f, 0.2f, 0.35f}; - for (int i = 0; i < 4; i++) { - float cr = colors[i][0], cg = colors[i][1], cb = colors[i][2]; - if (i == sel) { cr = 1; cg = 1; cb = 1; } - DrawCube(-0.8f + i * 0.6f - cam_x, 0, 1.5f - cam_z, sizes[i], cr, cg, cb); - } - - if (rs) rs->lpVtbl->Release(rs); - if (dss) dss->lpVtbl->Release(dss); - g_sc->lpVtbl->Present(g_sc, 1, 0); -} - -static LRESULT CALLBACK WP(HWND h, UINT m, WPARAM w, LPARAM l) { - switch (m) { - case WM_KEYDOWN: - switch (w) { - case 'W': key_w = 1; break; case 'S': key_s = 1; break; - case 'A': key_a = 1; break; case 'D': key_d = 1; break; - case VK_LEFT: key_left = 1; break; case VK_RIGHT: key_right = 1; break; - case '1': sel = 0; break; case '2': sel = 1; break; - case '3': sel = 2; break; case '4': sel = 3; break; - case VK_ESCAPE: PostQuitMessage(0); break; - } - break; - case WM_KEYUP: - switch (w) { - case 'W': key_w = 0; break; case 'S': key_s = 0; break; - case 'A': key_a = 0; break; case 'D': key_d = 0; break; - case VK_LEFT: key_left = 0; break; case VK_RIGHT: key_right = 0; break; - } - break; - case WM_DESTROY: PostQuitMessage(0); return 0; - } - return DefWindowProcW(h, m, w, l); -} - -int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR nC, int nS) { - (void)hP; (void)nC; (void)nS; - WNDCLASSEXW wc; - memset(&wc, 0, sizeof(wc)); - wc.cbSize = sizeof(wc); - wc.style = CS_CLASSDC; - wc.lpfnWndProc = WP; - wc.hInstance = hI; - wc.lpszClassName = L"game_test_cls"; - RegisterClassExW(&wc); - HWND hwnd = CreateWindowW(L"game_test_cls", L"lity3d Game Test", WS_OVERLAPPEDWINDOW, - 100, 100, 1280, 720, NULL, NULL, hI, NULL); - if (!hwnd) { MessageBoxA(NULL, "CreateWindow failed", "Error", MB_OK); return -1; } - ShowWindow(hwnd, SW_SHOW); - UpdateWindow(hwnd); - Init(hwnd); - MSG msg; - while (1) { - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); DispatchMessage(&msg); - if (msg.message == WM_QUIT) goto done; - } - Frame(); - } -done: - if (g_cb) g_cb->lpVtbl->Release(g_cb); - if (g_il) g_il->lpVtbl->Release(g_il); - if (g_vs) g_vs->lpVtbl->Release(g_vs); - if (g_ps) g_ps->lpVtbl->Release(g_ps); - if (g_rtv) g_rtv->lpVtbl->Release(g_rtv); - if (g_sc) g_sc->lpVtbl->Release(g_sc); - if (g_ctx) g_ctx->lpVtbl->Release(g_ctx); - if (g_dev) g_dev->lpVtbl->Release(g_dev); - return 0; -} diff --git a/Demo/Demo/input_test.c b/Demo/Demo/input_test.c deleted file mode 100644 index 0949bcb..0000000 --- a/Demo/Demo/input_test.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "../Engine/Core/engine.h" -#include "../Engine/Window/window.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" -#include - -static GraphicsDevice* g_dev = NULL; -static ID3D11VertexShader* g_vs = NULL; -static ID3D11PixelShader* g_ps = NULL; -static ID3D11InputLayout* g_il = NULL; -static ID3D11Buffer* g_cb = NULL; -static float cam_x=0, cam_z=2, cam_yaw=0; -static float mx=0, my=0; -static int keys[256]={0}; -typedef struct { float p[3],n[3],uv[2],c[4]; } V; - -static void draw_quad(ID3D11DeviceContext* ctx, float x, float y, float z, float s, float r, float g, float b) { - V v[4]={{{x-s,y-s,z},{0,0,-1},{0,0},{r,g,b,1}},{{x+s,y-s,z},{0,0,-1},{1,0},{r,g,b,1}}, - {{x+s,y+s,z},{0,0,-1},{1,1},{r,g,b,1}},{{x-s,y+s,z},{0,0,-1},{0,1},{r,g,b,1}}}; - uint32_t idx[6]={0,1,2,0,2,3}; - ID3D11Buffer *vb=NULL,*ib=NULL; D3D11_BUFFER_DESC bd={}; D3D11_SUBRESOURCE_DATA sd={}; - bd.ByteWidth=sizeof(V)*4; bd.Usage=D3D11_USAGE_DEFAULT; bd.BindFlags=D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem=v; g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd,&sd,&vb); - bd.ByteWidth=sizeof(uint32_t)*6; bd.BindFlags=D3D11_BIND_INDEX_BUFFER; sd.pSysMem=idx; - g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd,&sd,&ib); - UINT s2=sizeof(V),o=0; - ctx->lpVtbl->IASetVertexBuffers(ctx,0,1,&vb,&s2,&o); - ctx->lpVtbl->IASetIndexBuffer(ctx,ib,DXGI_FORMAT_R32_UINT,0); - ctx->lpVtbl->DrawIndexed(ctx,6,0,0); - ib->lpVtbl->Release(ib); vb->lpVtbl->Release(vb); -} - -static void on_render(Engine* engine) { - if(!g_dev) return; - ID3D11DeviceContext* ctx=g_dev->context; - float dt=(float)engine->delta_time, sp=3.0f*dt; - float fx=-sinf(cam_yaw),fz=-cosf(cam_yaw),rx=cosf(cam_yaw),rz=-sinf(cam_yaw); - if(keys['W']){cam_x+=fx*sp;cam_z+=fz*sp;} - if(keys['S']){cam_x-=fx*sp;cam_z-=fz*sp;} - if(keys['A']){cam_x-=rx*sp;cam_z-=rz*sp;} - if(keys['D']){cam_x+=rx*sp;cam_z+=rz*sp;} - - float sw=(float)g_dev->width,sh=(float)g_dev->height; - float fov=1.0f/tanf(0.4f),asp=sw/sh; - float mvp[16]={0}; mvp[0]=fov/asp;mvp[5]=-fov;mvp[10]=1;mvp[11]=-1;mvp[14]=0.1f;mvp[15]=1; - Mat4 pm,pt;memcpy(&pm,mvp,sizeof(Mat4));mat4_transpose(&pm,&pt); - - graphics_device_clear(g_dev,0.12f,0.14f,0.18f,1.0f); - D3D11_VIEWPORT vp={};vp.Width=sw;vp.Height=sh;vp.MaxDepth=1; - ctx->lpVtbl->RSSetViewports(ctx,1,&vp); - D3D11_RASTERIZER_DESC rd={};rd.FillMode=D3D11_FILL_SOLID;rd.CullMode=D3D11_CULL_NONE; - ID3D11RasterizerState*rs=NULL;g_dev->device->lpVtbl->CreateRasterizerState(g_dev->device,&rd,&rs); - ctx->lpVtbl->RSSetState(ctx,rs); - D3D11_DEPTH_STENCIL_DESC dsd={};dsd.DepthEnable=FALSE; - ID3D11DepthStencilState*dss=NULL;g_dev->device->lpVtbl->CreateDepthStencilState(g_dev->device,&dsd,&dss); - ctx->lpVtbl->OMSetDepthStencilState(ctx,dss,0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx,D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ctx->lpVtbl->VSSetShader(ctx,g_vs,NULL,0);ctx->lpVtbl->PSSetShader(ctx,g_ps,NULL,0); - ctx->lpVtbl->IASetInputLayout(ctx,g_il);ctx->lpVtbl->VSSetConstantBuffers(ctx,0,1,&g_cb); - ctx->lpVtbl->UpdateSubresource(ctx,(ID3D11Resource*)g_cb,0,NULL,&pt,0,0); - for(int x=-5;x<=5;x++)for(int z=-5;z<=5;z++){float c=((x+z)%2==0)?.4f:.3f;draw_quad(ctx,(float)x,(float)z,0.5f,0.5f,c,c,c);} - draw_quad(ctx,0,0,0.5f,0.4f,1,0.3f,0.3f);draw_quad(ctx,2,0,0.5f,0.3f,.3f,1,.3f);draw_quad(ctx,-2,0,0.5f,0.3f,.3f,.3f,1);draw_quad(ctx,0,2,0.5f,0.5f,.8f,.8f,.2f); - if(rs)rs->lpVtbl->Release(rs);if(dss)dss->lpVtbl->Release(dss); - graphics_device_present(g_dev); -} -static void on_key(Engine*e,int k){if(k>=0&&k<256)keys[k]=1;if(k==VK_ESCAPE)engine_request_quit(e);} -static void on_mouse_move(int x,int y){cam_yaw+=(x-mx)*0.003f;mx=(float)x;my=(float)y;} -int WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int){ - EngineConfig cfg=engine_default_config();cfg.app_name="lity3d Input Test"; - Engine*e=engine_create();if(!engine_init(e,&cfg))return -1; - g_dev=graphics_device_create(); - if(!graphics_device_init(g_dev,window_get_handle(e->window),cfg.window_width,cfg.window_height,1))return -1; - ID3DBlob*b1=NULL,*b2=NULL,*er=NULL; - const char*vs="cbuffer CB:register(b0){float4x4 WVP;};struct I{float3 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};struct O{float4 p:SV_POSITION;float3 n:NORMAL;float4 c:COLOR;};O main(I i){O o;o.p=mul(float4(i.p,1),WVP);o.n=i.n;o.c=i.c;return o;}"; - const char*ps="struct O{float4 p:SV_POSITION;float3 n:NORMAL;float4 c:COLOR;};float4 main(O i){return i.c;}"; - D3DCompile(vs,(UINT)strlen(vs),NULL,NULL,NULL,"main","vs_5_0",0,0,&b1,&er);if(er){er->lpVtbl->Release(er);er=NULL;} - D3DCompile(ps,(UINT)strlen(ps),NULL,NULL,NULL,"main","ps_5_0",0,0,&b2,&er);if(er){er->lpVtbl->Release(er);er=NULL;} - ID3D11Device*dev=g_dev->device; - dev->lpVtbl->CreateVertexShader(dev,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),NULL,&g_vs); - dev->lpVtbl->CreatePixelShader(dev,b2->lpVtbl->GetBufferPointer(b2),b2->lpVtbl->GetBufferSize(b2),NULL,&g_ps); - D3D11_INPUT_ELEMENT_DESC il[]={{"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0},{"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0},{"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0},{"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}}; - dev->lpVtbl->CreateInputLayout(dev,il,4,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),&g_il);b1->lpVtbl->Release(b1);b2->lpVtbl->Release(b2); - D3D11_BUFFER_DESC cbd={};cbd.ByteWidth=256;cbd.Usage=D3D11_USAGE_DEFAULT;cbd.BindFlags=D3D11_BIND_CONSTANT_BUFFER;dev->lpVtbl->CreateBuffer(dev,&cbd,NULL,&g_cb); - window_set_key_callback(e->window,on_key);window_set_mouse_move_callback(e->window,on_mouse_move); - engine_set_render_callback(e,on_render);engine_run(e); - if(g_vs)g_vs->lpVtbl->Release(g_vs);if(g_ps)g_ps->lpVtbl->Release(g_ps);if(g_il)g_il->lpVtbl->Release(g_il);if(g_cb)g_cb->lpVtbl->Release(g_cb); - graphics_device_destroy(g_dev);engine_shutdown(e);return 0; -} diff --git a/Demo/Demo/light_test.c b/Demo/Demo/light_test.c deleted file mode 100644 index 01e2692..0000000 --- a/Demo/Demo/light_test.c +++ /dev/null @@ -1,142 +0,0 @@ -// light_test.c - 光照系统测试(基ï¿?raw3d_test 已验证模式) -#include "../Engine/Core/engine.h" -#include "../Engine/Window/window.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Rendering/lighting.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" -#include - -static GraphicsDevice* g_dev = NULL; -static Light* g_sun = NULL; -static float g_time = 0; -typedef struct { float p[3],n[3],uv[2],c[4]; } V; - -// 编译带光照的着色器 -static ID3D11VertexShader* g_vs = NULL; -static ID3D11PixelShader* g_ps = NULL; -static ID3D11InputLayout* g_il = NULL; -static ID3D11Buffer* g_cb = NULL; - -static const char* vs_src = - "cbuffer CB:register(b0){float4x4 WVP;};" - "struct I{float3 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};" - "struct O{float4 p:SV_POSITION;float3 n:NORMAL;float4 c:COLOR;};" - "O main(I i){O o;o.p=mul(float4(i.p,1),WVP);o.n=i.n;o.c=i.c;return o;}"; -static const char* ps_src = - "cbuffer Light:register(b1){float3 lightDir;float pad1;float3 lightColor;float intensity;float3 ambColor;float pad2;};" - "struct O{float4 p:SV_POSITION;float3 n:NORMAL;float4 c:COLOR;};" - "float4 main(O i):SV_TARGET{" - "float3 n=normalize(i.n);" - "float diff=max(dot(n,-normalize(lightDir)),0.0);" - "float3 col=i.c.rgb*(ambColor+lightColor*diff*intensity);" - "return float4(col,1.0);}"; - -static void InitShaders() { - ID3DBlob *b1=NULL,*b2=NULL,*e=NULL; - D3DCompile(vs_src,(UINT)strlen(vs_src),NULL,NULL,NULL,"main","vs_5_0",0,0,&b1,&e); - if(e){e->lpVtbl->Release(e);e=NULL;} - D3DCompile(ps_src,(UINT)strlen(ps_src),NULL,NULL,NULL,"main","ps_5_0",0,0,&b2,&e); - if(e){e->lpVtbl->Release(e);e=NULL;} - if(!b1||!b2) return; - ID3D11Device* dev = g_dev->device; - dev->lpVtbl->CreateVertexShader(dev,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),NULL,&g_vs); - dev->lpVtbl->CreatePixelShader(dev,b2->lpVtbl->GetBufferPointer(b2),b2->lpVtbl->GetBufferSize(b2),NULL,&g_ps); - D3D11_INPUT_ELEMENT_DESC il[]={ - {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}, - }; - dev->lpVtbl->CreateInputLayout(dev,il,4,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),&g_il); - b1->lpVtbl->Release(b1); b2->lpVtbl->Release(b2); - D3D11_BUFFER_DESC cbd={}; cbd.ByteWidth=256; cbd.Usage=D3D11_USAGE_DEFAULT; - cbd.BindFlags=D3D11_BIND_CONSTANT_BUFFER; - dev->lpVtbl->CreateBuffer(dev,&cbd,NULL,&g_cb); -} - -static void draw_lit_cube(ID3D11DeviceContext* ctx, ID3D11Device* dev, float cx, float cy, float cz, float s, float cr, float cg, float cb) { - V v[24]; - float f[6][4][3]={{{-1,-1,-1},{1,-1,-1},{1,1,-1},{-1,1,-1}},{{1,-1,-1},{1,-1,1},{1,1,1},{1,1,-1}}, - {{1,-1,1},{-1,-1,1},{-1,1,1},{1,1,1}},{{-1,-1,1},{-1,-1,-1},{-1,1,-1},{-1,1,1}}, - {{-1,1,-1},{1,1,-1},{1,1,1},{-1,1,1}},{{-1,-1,1},{1,-1,1},{1,-1,-1},{-1,-1,-1}}}; - float nm[6][3]={{0,0,-1},{1,0,0},{0,0,1},{-1,0,0},{0,1,0},{0,-1,0}}; - for(int fi=0;fi<6;fi++) for(int vi=0;vi<4;vi++){ - int i=fi*4+vi; - v[i].p[0]=f[fi][vi][0]*s+cx; v[i].p[1]=f[fi][vi][1]*s+cy; v[i].p[2]=f[fi][vi][2]*s+cz; - v[i].n[0]=nm[fi][0]; v[i].n[1]=nm[fi][1]; v[i].n[2]=nm[fi][2]; - v[i].c[0]=cr; v[i].c[1]=cg; v[i].c[2]=cb; v[i].c[3]=1; - } - uint32_t idx[36]; for(int fi=0;fi<6;fi++){int b=fi*4;idx[fi*6]=b;idx[fi*6+1]=b+1;idx[fi*6+2]=b+2;idx[fi*6+3]=b;idx[fi*6+4]=b+2;idx[fi*6+5]=b+3;} - ID3D11Buffer *vb,*ib;D3D11_BUFFER_DESC bd={};D3D11_SUBRESOURCE_DATA sd={}; - bd.ByteWidth=sizeof(V)*24;bd.Usage=D3D11_USAGE_DEFAULT;bd.BindFlags=D3D11_BIND_VERTEX_BUFFER;sd.pSysMem=v; - dev->lpVtbl->CreateBuffer(dev,&bd,&sd,&vb); - bd.ByteWidth=sizeof(uint32_t)*36;bd.BindFlags=D3D11_BIND_INDEX_BUFFER;sd.pSysMem=idx; - dev->lpVtbl->CreateBuffer(dev,&bd,&sd,&ib); - UINT s2=sizeof(V),o=0; - ctx->lpVtbl->IASetVertexBuffers(ctx,0,1,&vb,&s2,&o); - ctx->lpVtbl->IASetIndexBuffer(ctx,ib,DXGI_FORMAT_R32_UINT,0); - ctx->lpVtbl->DrawIndexed(ctx,36,0,0); - ib->lpVtbl->Release(ib);vb->lpVtbl->Release(vb); -} - -static void on_render(Engine* engine) { - if(!g_dev) return; - ID3D11DeviceContext* ctx=g_dev->context; - g_time+=0.016f; - - float sw=(float)g_dev->width,sh=(float)g_dev->height; - float fov=1.0f/tanf(0.4f),asp=sw/sh; - float mvp[16]={0}; mvp[0]=fov/asp;mvp[5]=-fov;mvp[10]=1;mvp[11]=-1;mvp[14]=0.1f;mvp[15]=1; - Mat4 pm,pt;memcpy(&pm,mvp,sizeof(Mat4));mat4_transpose(&pm,&pt); - - graphics_device_clear(g_dev,0.15f,0.18f,0.25f,1.0f); - D3D11_VIEWPORT vp={};vp.Width=sw;vp.Height=sh;vp.MaxDepth=1; - ctx->lpVtbl->RSSetViewports(ctx,1,&vp); - D3D11_RASTERIZER_DESC rd={};rd.FillMode=D3D11_FILL_SOLID;rd.CullMode=D3D11_CULL_NONE; - ID3D11RasterizerState*rs=NULL;g_dev->device->lpVtbl->CreateRasterizerState(g_dev,&rd,&rs); - ctx->lpVtbl->RSSetState(ctx,rs); - D3D11_DEPTH_STENCIL_DESC dsd={};dsd.DepthEnable=FALSE; - ID3D11DepthStencilState*dss=NULL;g_dev->device->lpVtbl->CreateDepthStencilState(g_dev,&dsd,&dss); - ctx->lpVtbl->OMSetDepthStencilState(ctx,dss,0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx,D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - // 绑定光照 shader - ctx->lpVtbl->VSSetShader(ctx,g_vs,NULL,0); - ctx->lpVtbl->PSSetShader(ctx,g_ps,NULL,0); - ctx->lpVtbl->IASetInputLayout(ctx,g_il); - ctx->lpVtbl->VSSetConstantBuffers(ctx,0,1,&g_cb); - ctx->lpVtbl->UpdateSubresource(ctx,(ID3D11Resource*)g_cb,0,NULL,&pt,0,0); - - // 更新光照 CB - float light_data[16]={0}; - light_data[0]=g_sun->direction[0];light_data[1]=g_sun->direction[1];light_data[2]=g_sun->direction[2]; - light_data[4]=g_sun->color[0];light_data[5]=g_sun->color[1];light_data[6]=g_sun->color[2]; - light_data[7]=g_sun->intensity; - light_data[8]=0.15f;light_data[9]=0.15f;light_data[10]=0.2f; - ctx->lpVtbl->VSSetConstantBuffers(ctx,1,1,&g_cb); - - draw_lit_cube(ctx,g_dev, 0,0,0.5f, 0.3f, 1,0.3f,0.3f); - draw_lit_cube(ctx,g_dev,-0.8f,0,0.7f, 0.2f, 0.3f,1,0.3f); - draw_lit_cube(ctx,g_dev, 0.8f,0.3f,0.3f, 0.15f, 0.3f,0.3f,1); - draw_lit_cube(ctx,g_dev, 0,-0.2f,0.8f, 0.4f, 0.8f,0.8f,0.2f); - - if(rs)rs->lpVtbl->Release(rs);if(dss)dss->lpVtbl->Release(dss); - graphics_device_present(g_dev); -} - -static void on_key(Engine*e,int k){if(k==VK_ESCAPE)engine_request_quit(e);} - -int WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int){ - EngineConfig cfg=engine_default_config();cfg.app_name="lity3d Light Test"; - Engine*e=engine_create();if(!engine_init(e,&cfg))return -1; - g_dev=graphics_device_create(); - if(!graphics_device_init(g_dev,window_get_handle(e->window),cfg.window_width,cfg.window_height,1))return -1; - InitShaders(); - g_sun=light_create_dir(1.0f,0.95f,0.8f,1.2f, -0.5f,-1.0f,-0.3f); - engine_set_render_callback(e,on_render);engine_set_key_callback(e,on_key); - engine_run(e); - light_destroy(g_sun);graphics_device_destroy(g_dev);engine_shutdown(e); - return 0; -} diff --git a/Demo/Demo/ly_interpreter.c b/Demo/Demo/ly_interpreter.c deleted file mode 100644 index 4e9c2c3..0000000 --- a/Demo/Demo/ly_interpreter.c +++ /dev/null @@ -1,290 +0,0 @@ -// ============================================================================ -// ly_interpreter.c - .ly 积木语言独立解释器 -// 直接解析 .ly 格式,不依赖引擎 VisualScript 框架 -// 用法: ly_interpreter.exe -// ============================================================================ - -#include -#include -#include -#include - -// === 数据结构 === -typedef union { double num; char str[256]; int bool_val; } Value; - -typedef struct { - int id; - char name[64]; - float x, y; - char data[256]; - int color; - Value inputs[8]; - int input_count; - Value outputs[4]; - int output_count; -} Block; - -typedef struct { - int from_block, from_slot; - int to_block, to_slot; -} Wire; - -#define MAX_BLOCKS 256 -#define MAX_WIRES 256 - -static Block g_blocks[MAX_BLOCKS]; -static int g_block_count = 0; -static Wire g_wires[MAX_WIRES]; -static int g_wire_count = 0; - -// === 解析 === - -static void trim(char* s) { - char* p = s; - while (*p == ' ' || *p == '\t') p++; - if (p != s) memmove(s, p, strlen(p) + 1); - int len = strlen(s); - while (len > 0 && (s[len-1] == '\n' || s[len-1] == '\r' || s[len-1] == ' ')) s[--len] = 0; -} - -static int parse_ly(const char* path) { - FILE* f = fopen(path, "r"); - if (!f) { fprintf(stderr, "Cannot open %s\n", path); return 0; } - - char line[1024]; - int section = 0; // 0=none, 1=block, 2=wire - int cur_bid = -1; - - while (fgets(line, sizeof(line), f)) { - trim(line); - if (line[0] == '#' || line[0] == 0) continue; - - if (strcmp(line, "[B]") == 0 || strcmp(line, "[Block]") == 0) { section = 1; cur_bid = -1; continue; } - if (strcmp(line, "[W]") == 0 || strcmp(line, "[Wire]") == 0) { section = 2; continue; } - if (line[0] == '[') { section = 0; continue; } - - if (section == 1) { - char* eq = strchr(line, '='); - if (!eq) continue; - *eq = 0; char* key = line; char* val = eq + 1; - - if (strcmp(key, "id") == 0) { - cur_bid = g_block_count; - memset(&g_blocks[cur_bid], 0, sizeof(Block)); - g_blocks[cur_bid].id = atoi(val); - g_block_count++; - } else if (cur_bid >= 0) { - if (strcmp(key, "name") == 0) strncpy(g_blocks[cur_bid].name, val, 63); - else if (strcmp(key, "p") == 0 || strcmp(key, "pos") == 0) sscanf(val, "%f,%f", &g_blocks[cur_bid].x, &g_blocks[cur_bid].y); - else if (strcmp(key, "d") == 0 || strcmp(key, "data") == 0) strncpy(g_blocks[cur_bid].data, val, 255); - else if (strcmp(key, "c") == 0 || strcmp(key, "color") == 0) g_blocks[cur_bid].color = atoi(val); - } - } else if (section == 2) { - Wire* w = &g_wires[g_wire_count]; - char* eq = strchr(line, '='); - if (!eq) continue; - *eq = 0; char* key = line; char* val = eq + 1; - - if (strcmp(key, "a") == 0 || strcmp(key, "from") == 0) { - w->from_block = atoi(val) / 10000; - w->from_slot = atoi(val) % 10000; - } else if (strcmp(key, "b") == 0 || strcmp(key, "to") == 0) { - w->to_block = atoi(val) / 10000; - w->to_slot = atoi(val) % 10000; - if (w->from_block > 0) g_wire_count++; - } - } - } - fclose(f); - printf("Parsed: %d blocks, %d wires\n", g_block_count, g_wire_count); - return 1; -} - -// === 查找 === - -static Block* find_block(int id) { - for (int i = 0; i < g_block_count; i++) - if (g_blocks[i].id == id) return &g_blocks[i]; - return NULL; -} - -// 找到从某个 block 的 output_slot 出发,连接到的下一个 block -static Block* follow_wire(int from_id, int from_slot) { - for (int i = 0; i < g_wire_count; i++) { - if (g_wires[i].from_block == from_id && g_wires[i].from_slot == from_slot) - return find_block(g_wires[i].to_block); - } - return NULL; -} - -// 获取连接到某个 block input_slot 的值 -static Value get_input_value(int block_id, int slot) { - for (int i = 0; i < g_wire_count; i++) { - if (g_wires[i].to_block == block_id && g_wires[i].to_slot == slot) { - Block* src = find_block(g_wires[i].from_block); - if (src && src->output_count > g_wires[i].from_slot) - return src->outputs[g_wires[i].from_slot]; - } - } - Value v; v.num = 0; return v; -} - -// === 解释执行 === - -static int g_variables[64]; // 简单变量存储 -static char g_var_names[64][64]; -static int g_var_count = 0; - -static int get_var(const char* name) { - for (int i = 0; i < g_var_count; i++) - if (strcmp(g_var_names[i], name) == 0) return g_variables[i]; - return 0; -} - -static void set_var(const char* name, int val) { - for (int i = 0; i < g_var_count; i++) - if (strcmp(g_var_names[i], name) == 0) { g_variables[i] = val; return; } - if (g_var_count < 64) { strncpy(g_var_names[g_var_count], name, 63); g_variables[g_var_count++] = val; } -} - -static void execute(Block* block, int depth); - -static void execute_block(Block* b, int depth) { - if (!b) return; - if (depth > 100) { printf("Stack overflow!\n"); return; } - - const char* n = b->name; - - if (strcmp(n, "开始") == 0) { - // Follow output wire - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "移动物体") == 0) { - Value dx = get_input_value(b->id, 1); - Value dy = get_input_value(b->id, 2); - Value dz = get_input_value(b->id, 3); - printf(" [move] dx=%.1f dy=%.1f dz=%.1f\n", dx.num, dy.num, dz.num); - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "旋转物体") == 0) { - Value dx = get_input_value(b->id, 1); - Value dy = get_input_value(b->id, 2); - Value dz = get_input_value(b->id, 3); - printf(" [rotate] rx=%.1f ry=%.1f rz=%.1f\n", dx.num, dy.num, dz.num); - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "当按键") == 0) { - // Event: just follow output (simulated - always fires) - printf(" [key event] key='%s'\n", b->data); - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "当点击") == 0) { - printf(" [click event]\n"); - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "打印") == 0 || strcmp(n, "print") == 0) { - Value msg = get_input_value(b->id, 1); - printf(" [print] %s\n", msg.str[0] ? msg.str : b->data); - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "等待") == 0 || strcmp(n, "wait") == 0) { - Value secs = get_input_value(b->id, 1); - double s = secs.num > 0 ? secs.num : atof(b->data); - printf(" [wait] %.1fs\n", s); - // In real engine, this would pause. For now, just continue. - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "循环") == 0 || strcmp(n, "loop") == 0) { - Value count = get_input_value(b->id, 1); - int n = count.num > 0 ? (int)count.num : atoi(b->data); - if (n <= 0) n = 1; - printf(" [loop] %d times\n", n); - for (int i = 0; i < n; i++) { - Block* body = follow_wire(b->id, 0); - execute(body, depth + 1); - } - } - else if (strcmp(n, "如果") == 0 || strcmp(n, "if") == 0) { - Value cond = get_input_value(b->id, 1); - printf(" [if] condition=%d\n", cond.bool_val); - Block* next = follow_wire(b->id, cond.bool_val ? 0 : 1); - execute(next, depth + 1); - } - else if (strcmp(n, "数学运算") == 0 || strcmp(n, "+") == 0) { - Value a = get_input_value(b->id, 0); - Value b2 = get_input_value(b->id, 1); - b->outputs[0].num = a.num + b2.num; - printf(" [add] %.1f + %.1f = %.1f\n", a.num, b2.num, b->outputs[0].num); - } - else if (strcmp(n, "变量设置") == 0 || strcmp(n, "set_var") == 0) { - Value v = get_input_value(b->id, 1); - set_var(b->data, (int)v.num); - printf(" [set_var] %s = %d\n", b->data, (int)v.num); - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "变量读取") == 0 || strcmp(n, "get_var") == 0) { - int v = get_var(b->data); - b->outputs[0].num = v; - printf(" [get_var] %s = %d\n", b->data, v); - } - else { - printf(" [unknown] '%s'\n", n); - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } -} - -static void execute(Block* block, int depth) { - if (!block) return; - execute_block(block, depth); -} - -// === 主函数 === - -int main(int argc, char* argv[]) { - const char* script = "Demo/test.ly"; - if (argc > 1) script = argv[1]; - - printf("=== lity3d .ly Interpreter ===\n"); - printf("Script: %s\n\n", script); - - if (!parse_ly(script)) return 1; - - printf("\n--- Blocks ---\n"); - for (int i = 0; i < g_block_count; i++) - printf(" [%d] %s data='%s' pos=(%.0f,%.0f)\n", g_blocks[i].id, g_blocks[i].name, g_blocks[i].data, g_blocks[i].x, g_blocks[i].y); - - printf("\n--- Wires ---\n"); - for (int i = 0; i < g_wire_count; i++) - printf(" [%d].out%d -> [%d].in%d\n", g_wires[i].from_block, g_wires[i].from_slot, g_wires[i].to_block, g_wires[i].to_slot); - - printf("\n--- Execute ---\n"); - - // Find start block - Block* start = NULL; - for (int i = 0; i < g_block_count; i++) - if (strcmp(g_blocks[i].name, "开始") == 0) { start = &g_blocks[i]; break; } - - if (!start) { - // Try to find any block with incoming wires as entry point - // Or just execute the first block - if (g_block_count > 0) start = &g_blocks[0]; - } - - if (start) { - execute(start, 0); - } else { - printf("No executable blocks found.\n"); - } - - printf("\n--- Done ---\n"); - return 0; -} diff --git a/Demo/Demo/main.c b/Demo/Demo/main.c deleted file mode 100644 index 992f01d..0000000 --- a/Demo/Demo/main.c +++ /dev/null @@ -1,224 +0,0 @@ -#include "../Engine/Core/engine.h" -#include "../Engine/Core/logger.h" -#include "../Engine/Core/timer.h" -#include "../Engine/Core/asset_manager.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/renderer.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Rendering/mesh.h" -#include "../Engine/Rendering/material.h" -#include "../Engine/Rendering/texture.h" -#include "../Engine/Rendering/camera.h" -#include "../Engine/Scene/scene_graph.h" -#include "../Engine/Scene/scene_render.h" -#include "../Engine/Scene/scene_serialize.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" -#include -#include -#include -#include - -static Scene* g_scene = NULL; -static AssetManager* g_assets = NULL; -static Asset* g_shader_asset = NULL; -static Camera g_camera; -static int g_mouse_down[3] = {0}; -static int g_last_mouse_x = 0, g_last_mouse_y = 0; -static int g_mouse_first = 1; - -static SceneNode* create_primitive_node(Scene* scene, SceneNode* parent, AssetManager* am, - ID3D11Device* dev, const char* name, MeshType type, - Vec3 pos, Vec3 rot, Vec3 scale, - Material* material) { - SceneNode* node = scene_create_node(scene, name); - if (!node) return NULL; - if (parent) scene_set_parent(node, parent); - node->position = pos; - node->scale = scale; - quat_from_euler(rot.x, rot.y, rot.z, &node->rotation); - - Asset* mesh_asset = asset_manager_load_mesh(am, dev, name); - if (!mesh_asset) { - const char* builtin = NULL; - if (type == MESH_CUBE) builtin = "cube"; - else if (type == MESH_SPHERE) builtin = "sphere"; - else if (type == MESH_PLANE) builtin = "plane"; - if (builtin) mesh_asset = asset_manager_load_mesh(am, dev, builtin); - } - - if (mesh_asset && material) { - MeshRenderer* mr = mesh_renderer_create(type, (Mesh*)asset_data(mesh_asset), material); - scene_node_set_mesh_renderer(node, mr); - } - return node; -} - -static Scene* create_default_scene(AssetManager* am, ID3D11Device* dev) { - Scene* scene = (Scene*)malloc(sizeof(Scene)); - if (!scene) return NULL; - scene_init(scene); - - SceneNode* root = scene->root; - root->name[0] = '\0'; - strncpy(root->name, "root", sizeof(root->name) - 1); - - Shader* shader = (Shader*)asset_data(g_shader_asset); - - Material* mat_red = material_create(shader, NULL); - mat_red->color = (Vec4){1.0f, 0.3f, 0.2f, 1.0f}; - - Material* mat_blue = material_create(shader, NULL); - mat_blue->color = (Vec4){0.2f, 0.5f, 1.0f, 1.0f}; - - Material* mat_ground = material_create(shader, NULL); - mat_ground->color = (Vec4){0.3f, 0.3f, 0.35f, 1.0f}; - - // 中心红色立方体 - create_primitive_node(scene, root, am, dev, "cube", MESH_CUBE, - (Vec3){0, 0, 0}, (Vec3){0, 0, 0}, (Vec3){1, 1, 1}, mat_red); - // 右侧蓝色球体 - create_primitive_node(scene, root, am, dev, "sphere", MESH_SPHERE, - (Vec3){2.0f, 0, 0}, (Vec3){0, 0, 0}, (Vec3){0.8f, 0.8f, 0.8f}, mat_blue); - // 下方地面 - create_primitive_node(scene, root, am, dev, "ground", MESH_PLANE, - (Vec3){0, -1.0f, 0}, (Vec3){0, 0, 0}, (Vec3){1, 1, 1}, mat_ground); - - scene_update(scene); - return scene; -} - -static void on_render(Engine* engine) { - Renderer* r = engine_get_renderer(engine); - GraphicsDevice* dev = engine_get_graphics_device(engine); - if (!r || !dev || !g_scene) return; - - renderer_set_view(r, camera_get_view(&g_camera)); - renderer_set_projection(r, camera_get_projection(&g_camera)); - - renderer_begin_frame(r); - scene_update(g_scene); - scene_render(g_scene, r); - renderer_end_frame(r); - - if (engine->frame_count == 60) { - graphics_device_save_screenshot(dev, "screenshot1.bmp"); - } - if (engine->frame_count == 180) { - graphics_device_save_screenshot(dev, "screenshot2.bmp"); - } -} - -static void on_update(Engine* engine, double dt) { - (void)engine; (void)dt; -} - -static void on_key(Engine* engine, int key) { - if (key == VK_ESCAPE) engine_request_quit(engine); - if (key == 'W' || key == 'w') camera_move_forward(&g_camera, 0.5f); - if (key == 'S' || key == 's') camera_move_forward(&g_camera, -0.5f); - if (key == 'A' || key == 'a') camera_move_right(&g_camera, -0.5f); - if (key == 'D' || key == 'd') camera_move_right(&g_camera, 0.5f); - if (key == VK_LEFT) camera_rotate_yaw(&g_camera, -0.1f); - if (key == VK_RIGHT) camera_rotate_yaw(&g_camera, 0.1f); - if (key == VK_UP) camera_rotate_pitch(&g_camera, -0.1f); - if (key == VK_DOWN) camera_rotate_pitch(&g_camera, 0.1f); -} - -static void on_mouse_move(Engine* engine, int x, int y) { - (void)engine; - if (g_mouse_down[0]) { - if (g_mouse_first) { - g_last_mouse_x = x; - g_last_mouse_y = y; - g_mouse_first = 0; - } else { - float dx = (float)(x - g_last_mouse_x); - float dy = (float)(y - g_last_mouse_y); - camera_rotate_yaw(&g_camera, dx * 0.005f); - camera_rotate_pitch(&g_camera, dy * 0.005f); - g_last_mouse_x = x; - g_last_mouse_y = y; - } - } else { - g_mouse_first = 1; - } -} - -static void on_mouse_button(Engine* engine, int button, int pressed) { - (void)engine; - if (button >= 0 && button < 3) g_mouse_down[button] = pressed; -} - -static void on_resize(Engine* engine, int width, int height) { - Renderer* r = engine_get_renderer(engine); - if (r && width > 0 && height > 0) { - renderer_resize(r, width, height); - g_camera.aspect = (float)width / (float)height; - g_camera.dirty = 1; - } -} - -int main(int argc, char* argv[]) { - (void)argc; (void)argv; - - EngineConfig config = engine_default_config(); - config.app_name = "Lity3D - Scene Demo"; - config.vsync = 0; - config.window_width = 1280; - config.window_height = 720; - - Engine* engine = engine_create(); - if (!engine_init(engine, &config)) { - LOG_FATAL("Engine init failed"); - return -1; - } - - GraphicsDevice* dev = engine_get_graphics_device(engine); - Renderer* r = engine_get_renderer(engine); - - g_assets = asset_manager_create(); - g_shader_asset = asset_manager_load_shader(g_assets, dev->device, NULL, NULL); - if (!g_shader_asset) { - LOG_FATAL("Shader load failed"); - return -1; - } - LOG_INFO("Shader loaded via AssetManager"); - - Shader* default_shader = (Shader*)asset_data(g_shader_asset); - - g_scene = scene_load("scene.txt", dev->device, default_shader); - if (!g_scene) { - LOG_INFO("No scene.txt found, creating default scene"); - g_scene = create_default_scene(g_assets, dev->device); - if (!scene_save(g_scene, "scene.txt")) { - LOG_WARN("Failed to save scene.txt"); - } - } - - float aspect = (float)config.window_width / config.window_height; - g_camera = camera_perspective(1.0472f, aspect, 0.1f, 100.0f); - g_camera.position = (Vec3){0, 0.5f, -5.0f}; - g_camera.target = (Vec3){0, 0, 0}; - g_camera.dirty = 1; - - renderer_set_view(r, camera_get_view(&g_camera)); - renderer_set_projection(r, camera_get_projection(&g_camera)); - - engine_set_update_callback(engine, on_update); - engine_set_render_callback(engine, on_render); - engine_set_key_callback(engine, on_key); - engine_set_mouse_move_callback(engine, on_mouse_move); - engine_set_mouse_button_callback(engine, on_mouse_button); - engine_set_resize_callback(engine, on_resize); - - LOG_INFO("Running scene demo..."); - engine_run(engine); - - scene_destroy_renderers(g_scene); - scene_destroy(g_scene); - free(g_scene); - asset_manager_destroy(g_assets); - engine_shutdown(engine); - return 0; -} diff --git a/Demo/Demo/mesh_debug.c b/Demo/Demo/mesh_debug.c deleted file mode 100644 index af94165..0000000 --- a/Demo/Demo/mesh_debug.c +++ /dev/null @@ -1,73 +0,0 @@ -// mesh_debug.c - 精确定位 mesh 系统 bug -#include "../Engine/Core/engine.h" -#include "../Engine/Window/window.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" - -static GraphicsDevice* g_dev = NULL; -static Shader* g_shader = NULL; -static ID3D11Buffer* g_vb = NULL; -static ID3D11Buffer* g_ib = NULL; - -typedef struct { float p[3],n[3],uv[2],c[4]; } V; - -static void on_render(Engine* engine) { - if (!g_dev) return; - ID3D11DeviceContext* ctx = g_dev->context; - float sw=(float)g_dev->width, sh=(float)g_dev->height; - float fov=1.0f/tanf(0.4f), asp=sw/sh; - - float mvp[16]; - mvp[0]=fov/asp; mvp[5]=-fov; mvp[10]=1; mvp[11]=-1; mvp[14]=0.1f; mvp[15]=1; - Mat4 pm, pt; memcpy(&pm, mvp, sizeof(Mat4)); mat4_transpose(&pm, &pt); - - graphics_device_clear(g_dev, 0.15f, 0.18f, 0.25f, 1.0f); - D3D11_VIEWPORT vp={}; vp.Width=sw; vp.Height=sh; vp.MaxDepth=1; - ctx->lpVtbl->RSSetViewports(ctx,1,&vp); - D3D11_RASTERIZER_DESC rd={}; rd.FillMode=D3D11_FILL_SOLID; rd.CullMode=D3D11_CULL_NONE; - ID3D11RasterizerState* rs=NULL; g_dev->device->lpVtbl->CreateRasterizerState(g_dev->device,&rd,&rs); - ctx->lpVtbl->RSSetState(ctx,rs); - D3D11_DEPTH_STENCIL_DESC dsd={}; dsd.DepthEnable=FALSE; - ID3D11DepthStencilState* dss=NULL; g_dev->device->lpVtbl->CreateDepthStencilState(g_dev->device,&dsd,&dss); - ctx->lpVtbl->OMSetDepthStencilState(ctx,dss,0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx,D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - shader_bind(g_shader, ctx); - shader_set_matrix(g_shader, ctx, (float*)&pt); - - // 用 init 时创建的 VB 画 - UINT stride=sizeof(V), offset=0; - ctx->lpVtbl->IASetVertexBuffers(ctx,0,1,&g_vb,&stride,&offset); - ctx->lpVtbl->IASetIndexBuffer(ctx,g_ib,DXGI_FORMAT_R32_UINT,0); - ctx->lpVtbl->DrawIndexed(ctx,6,0,0); - - if(rs) rs->lpVtbl->Release(rs); - if(dss) dss->lpVtbl->Release(dss); - graphics_device_present(g_dev); -} - -static void on_key(Engine* engine, int key) { if(key==VK_ESCAPE) engine_request_quit(engine); } - -int WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int) { - EngineConfig cfg=engine_default_config(); cfg.app_name="mesh debug"; - Engine* e=engine_create(); if(!engine_init(e,&cfg))return -1; - g_dev=graphics_device_create(); - if(!graphics_device_init(g_dev,window_get_handle(e->window),cfg.window_width,cfg.window_height,1))return -1; - g_shader=shader_create(); shader_compile(g_shader,g_dev->device,NULL,NULL,0,0); - - // WinMain 中创建 VB/IB(跟 mesh_create_cube 一样的时机) - V v[4]={{{-0.5f,-0.5f,0.5f},{0,0,1},{0,0},{1,0,0,1}},{{0.5f,-0.5f,0.5f},{0,0,1},{1,0},{0,1,0,1}},{{0.5f,0.5f,0.5f},{0,0,1},{1,1},{0,0,1,1}},{{-0.5f,0.5f,0.5f},{0,0,1},{0,1},{1,1,1,1}}}; - uint32_t idx[6]={0,1,2,0,2,3}; - D3D11_BUFFER_DESC bd={}; D3D11_SUBRESOURCE_DATA sd={}; - bd.ByteWidth=sizeof(V)*4; bd.Usage=D3D11_USAGE_DEFAULT; bd.BindFlags=D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem=v; g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd,&sd,&g_vb); - bd.ByteWidth=sizeof(uint32_t)*6; bd.BindFlags=D3D11_BIND_INDEX_BUFFER; - sd.pSysMem=idx; g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd,&sd,&g_ib); - - engine_set_render_callback(e,on_render); engine_set_key_callback(e,on_key); - engine_run(e); - if(g_vb)g_vb->lpVtbl->Release(g_vb); if(g_ib)g_ib->lpVtbl->Release(g_ib); - shader_destroy(g_shader); graphics_device_destroy(g_dev); engine_shutdown(e); - return 0; -} diff --git a/Demo/Demo/obj_viewer.c b/Demo/Demo/obj_viewer.c deleted file mode 100644 index c9973cb..0000000 --- a/Demo/Demo/obj_viewer.c +++ /dev/null @@ -1,206 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -static ID3D11Device* g_dev; static ID3D11DeviceContext* g_ctx; -static IDXGISwapChain* g_sc; static ID3D11RenderTargetView* g_rtv; -static ID3D11VertexShader* g_vs; static ID3D11PixelShader* g_ps; -static ID3D11InputLayout* g_il; static ID3D11Buffer* g_cb; - -static float cam_dist = 5.0f, cam_yaw = 0.5f, cam_pitch = 0.3f; -static int drag = 0, last_mx, last_my; -static int key_w=0,key_s=0,key_a=0,key_d=0,key_q=0,key_e=0; - -typedef struct { float p[3], n[3], u[2], c[4]; } V3D; - -static V3D* obj_verts = NULL; -static uint32_t* obj_idx = NULL; -static int obj_vcount = 0, obj_icount = 0; -static ID3D11Buffer* obj_vb = NULL; -static ID3D11Buffer* obj_ib = NULL; - -static int LoadOBJ(const char* path) { - FILE* f = fopen(path, "r"); - if (!f) return -1; - int max_v = 16384, max_f = 32768; - float* vpos = (float*)malloc(max_v * 3 * sizeof(float)); - int vc = 0; - int* fidx = (int*)malloc(max_f * 3 * sizeof(int)); - int fc = 0; - char line[256]; - while (fgets(line, sizeof(line), f)) { - if (line[0] == 'v' && line[1] == ' ') { - float x, y, z; - if (sscanf(line + 2, "%f %f %f", &x, &y, &z) == 3 && vc < max_v) { - vpos[vc*3]=x; vpos[vc*3+1]=y; vpos[vc*3+2]=z; vc++; - } - } else if (line[0] == 'f' && line[1] == ' ') { - int v0, v1, v2; - char* p = line + 2; - v0 = atoi(p) - 1; while (*p && *p != ' ') p++; p++; - v1 = atoi(p) - 1; while (*p && *p != ' ') p++; p++; - v2 = atoi(p) - 1; - if (v0 >= 0 && v1 >= 0 && v2 >= 0 && fc < max_f) { - fidx[fc*3]=v0; fidx[fc*3+1]=v1; fidx[fc*3+2]=v2; fc++; - } - } - } - fclose(f); - if (vc == 0 || fc == 0) { free(vpos); free(fidx); return -1; } - - obj_vcount = fc * 3; - obj_icount = fc * 3; - obj_verts = (V3D*)calloc(obj_vcount, sizeof(V3D)); - obj_idx = (uint32_t*)malloc(obj_icount * sizeof(uint32_t)); - - for (int i = 0; i < fc; i++) { - for (int j = 0; j < 3; j++) { - int vi = fidx[i*3+j]; - int oi = i*3+j; - if (vi < vc) { - obj_verts[oi].p[0] = vpos[vi*3]; - obj_verts[oi].p[1] = vpos[vi*3+1]; - obj_verts[oi].p[2] = vpos[vi*3+2]; - } - obj_verts[oi].c[0] = 0.6f; obj_verts[oi].c[1] = 0.7f; obj_verts[oi].c[2] = 0.8f; obj_verts[oi].c[3] = 1; - obj_idx[oi] = oi; - } - } - for (int i = 0; i < fc; i++) { - float* p0 = obj_verts[i*3].p; - float* p1 = obj_verts[i*3+1].p; - float* p2 = obj_verts[i*3+2].p; - float e1[3]={p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2]}; - float e2[3]={p2[0]-p0[0],p2[1]-p0[1],p2[2]-p0[2]}; - float nx=e1[1]*e2[2]-e1[2]*e2[1], ny=e1[2]*e2[0]-e1[0]*e2[2], nz=e1[0]*e2[1]-e1[1]*e2[0]; - float nl=sqrtf(nx*nx+ny*ny+nz*nz); - if(nl>0.0001f){nx/=nl;ny/=nl;nz/=nl;} - for(int j=0;j<3;j++){obj_verts[i*3+j].n[0]=nx;obj_verts[i*3+j].n[1]=ny;obj_verts[i*3+j].n[2]=nz;} - } - - D3D11_BUFFER_DESC bd; D3D11_SUBRESOURCE_DATA sd; - memset(&bd,0,sizeof(bd));memset(&sd,0,sizeof(sd)); - bd.ByteWidth=sizeof(V3D)*obj_vcount;bd.Usage=D3D11_USAGE_DEFAULT;bd.BindFlags=D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem=obj_verts;g_dev->lpVtbl->CreateBuffer(g_dev,&bd,&sd,&obj_vb); - bd.ByteWidth=sizeof(uint32_t)*obj_icount;bd.BindFlags=D3D11_BIND_INDEX_BUFFER; - sd.pSysMem=obj_idx;g_dev->lpVtbl->CreateBuffer(g_dev,&bd,&sd,&obj_ib); - - free(vpos); free(fidx); free(obj_verts); free(obj_idx); - obj_verts = NULL; obj_idx = NULL; - return 0; -} - -static void Init(HWND h) { - HRESULT hr; - DXGI_SWAP_CHAIN_DESC sd;memset(&sd,0,sizeof(sd));sd.BufferCount=2;sd.BufferDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM;sd.BufferDesc.RefreshRate.Numerator=60;sd.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT;sd.OutputWindow=h;sd.SampleDesc.Count=1;sd.Windowed=TRUE;sd.SwapEffect=DXGI_SWAP_EFFECT_DISCARD; - D3D_FEATURE_LEVEL fl=D3D_FEATURE_LEVEL_11_0,gt;hr=D3D11CreateDeviceAndSwapChain(NULL,D3D_DRIVER_TYPE_HARDWARE,NULL,0,&fl,1,D3D11_SDK_VERSION,&sd,&g_sc,&g_dev,>,&g_ctx);if(FAILED(hr))return; - ID3D11Texture2D*bb=NULL;hr=g_sc->lpVtbl->GetBuffer(g_sc,0,&IID_ID3D11Texture2D,(void**)&bb);if(FAILED(hr)||!bb)return;hr=g_dev->lpVtbl->CreateRenderTargetView(g_dev,(ID3D11Resource*)bb,NULL,&g_rtv);bb->lpVtbl->Release(bb);if(FAILED(hr))return; - const char*vs="cbuffer CB:register(b0){float4x4 WVP;};struct I{float3 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};struct O{float4 p:SV_POSITION;float3 n:NORMAL;float4 c:COLOR;};O main(I i){O o;o.p=mul(float4(i.p,1),WVP);o.n=i.n;o.c=i.c;return o;}"; - const char*ps="struct I{float3 n:NORMAL;float4 c:COLOR;};float4 main(float4 p:SV_POSITION,I i):SV_Target{float l=normalize(float3(0.3,1,0.5));float d=max(dot(normalize(i.n),l),0.2);return float4(i.c.rgb*d,1);}"; - ID3DBlob*b1,*b2,*e;D3DCompile(vs,(UINT)strlen(vs),NULL,NULL,NULL,"main","vs_5_0",0,0,&b1,&e);if(e){e->lpVtbl->Release(e);e=NULL;}D3DCompile(ps,(UINT)strlen(ps),NULL,NULL,NULL,"main","ps_5_0",0,0,&b2,&e);if(e){e->lpVtbl->Release(e);e=NULL;}if(!b1||!b2)return; - g_dev->lpVtbl->CreateVertexShader(g_dev,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),NULL,&g_vs);g_dev->lpVtbl->CreatePixelShader(g_dev,b2->lpVtbl->GetBufferPointer(b2),b2->lpVtbl->GetBufferSize(b2),NULL,&g_ps); - D3D11_INPUT_ELEMENT_DESC el[4];memset(el,0,sizeof(el));el[0].SemanticName="POSITION";el[0].Format=DXGI_FORMAT_R32G32B32_FLOAT;el[0].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA;el[1].SemanticName="NORMAL";el[1].AlignedByteOffset=12;el[1].Format=DXGI_FORMAT_R32G32B32_FLOAT;el[1].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA;el[2].SemanticName="TEXCOORD";el[2].AlignedByteOffset=24;el[2].Format=DXGI_FORMAT_R32G32_FLOAT;el[2].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA;el[3].SemanticName="COLOR";el[3].AlignedByteOffset=32;el[3].Format=DXGI_FORMAT_R32G32B32A32_FLOAT;el[3].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA; - g_dev->lpVtbl->CreateInputLayout(g_dev,el,4,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),&g_il);b1->lpVtbl->Release(b1);b2->lpVtbl->Release(b2); - D3D11_BUFFER_DESC cbd;memset(&cbd,0,sizeof(cbd));cbd.ByteWidth=256;cbd.Usage=D3D11_USAGE_DEFAULT;cbd.BindFlags=D3D11_BIND_CONSTANT_BUFFER;g_dev->lpVtbl->CreateBuffer(g_dev,&cbd,NULL,&g_cb); -} - -static void mat4_perspective(float* m, float fov, float asp, float zn, float zf) { - memset(m, 0, 64); - float f = 1.0f / tanf(fov / 2); - m[0] = f / asp; m[5] = -f; - m[10] = zf / (zf - zn); m[11] = -zn * zf / (zf - zn); - m[14] = 1; m[15] = 0; -} - -static void mat4_lookat(float* m, float ex, float ey, float ez, float tx, float ty, float tz) { - float fx=tx-ex, fy=ty-ey, fz=tz-ez; - float fl=sqrtf(fx*fx+fy*fy+fz*fz);fx/=fl;fy/=fl;fz/=fl; - float rx=fy*0-fz*1,ry=fz*0-fx*0,rz=fx*1-fy*0; - float rl=sqrtf(rx*rx+ry*ry+rz*rz);rx/=rl;ry/=rl;rz/=rl; - float ux=ry*fz-rz*fy,uy=rz*fx-rx*fz,uz=rx*fy-ry*fx; - memset(m, 0, 64); - m[0]=rx*1;m[1]=ux*1;m[2]=fx*1; - m[4]=ry*1;m[5]=uy*1;m[6]=fy*1; - m[8]=rz*1;m[9]=uz*1;m[10]=fz*1; - m[12]=-(rx*ex+ry*ey+rz*ez);m[13]=-(ux*ex+uy*ey+uz*ez);m[14]=-(fx*ex+fy*ey+fz*ez);m[15]=1; -} - -static void mat4_mul(float* o, float* a, float* b) { - float t[16];for(int i=0;i<4;i++)for(int j=0;j<4;j++){t[i*4+j]=0;for(int k=0;k<4;k++)t[i*4+j]+=a[i*4+k]*b[k*4+j];} - memcpy(o,t,64); -} - -static void Frame(void) { - float dt = 0.016f, rspd = 2.0f * dt, mspeed = 3.0f * dt; - if (key_a) cam_yaw -= rspd; if (key_d) cam_yaw += rspd; - if (key_q) cam_pitch -= rspd; if (key_e) cam_pitch += rspd; - if (key_w) cam_dist -= mspeed; if (key_s) cam_dist += mspeed; - if (cam_dist < 1.0f) cam_dist = 1.0f; if (cam_dist > 20.0f) cam_dist = 20.0f; - if (cam_pitch > 1.5f) cam_pitch = 1.5f; if (cam_pitch < -1.5f) cam_pitch = -1.5f; - - float ex = cam_dist * sinf(cam_yaw) * cosf(cam_pitch); - float ey = cam_dist * sinf(cam_pitch); - float ez = cam_dist * cosf(cam_yaw) * cosf(cam_pitch); - - float view[16], proj[16], vp[16], tmp[16]; - mat4_lookat(view, ex, ey, ez, 0, 0, 0); - mat4_perspective(proj, 0.8f, 1280.0f/720.0f, 0.1f, 100.0f); - mat4_mul(tmp, view, proj); - float vp_t[16]; for(int i=0;i<4;i++)for(int j=0;j<4;j++) vp_t[i*4+j]=tmp[j*4+i]; - - float cl[4]={.15f,.18f,.22f,1}; - g_ctx->lpVtbl->OMSetRenderTargets(g_ctx,1,&g_rtv,NULL);g_ctx->lpVtbl->ClearRenderTargetView(g_ctx,g_rtv,cl); - D3D11_VIEWPORT vp2;memset(&vp2,0,sizeof(vp2));vp2.Width=1280;vp2.Height=720;vp2.MaxDepth=1;g_ctx->lpVtbl->RSSetViewports(g_ctx,1,&vp2); - D3D11_RASTERIZER_DESC rd;memset(&rd,0,sizeof(rd));rd.FillMode=D3D11_FILL_SOLID;rd.CullMode=D3D11_CULL_NONE;ID3D11RasterizerState*rs;g_dev->lpVtbl->CreateRasterizerState(g_dev,&rd,&rs);g_ctx->lpVtbl->RSSetState(g_ctx,rs); - D3D11_DEPTH_STENCIL_DESC ds;memset(&ds,0,sizeof(ds));ds.DepthEnable=FALSE;ID3D11DepthStencilState*dss;g_dev->lpVtbl->CreateDepthStencilState(g_dev,&ds,&dss);g_ctx->lpVtbl->OMSetDepthStencilState(g_ctx,dss,0); - g_ctx->lpVtbl->IASetPrimitiveTopology(g_ctx,D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);g_ctx->lpVtbl->VSSetShader(g_ctx,g_vs,NULL,0);g_ctx->lpVtbl->PSSetShader(g_ctx,g_ps,NULL,0);g_ctx->lpVtbl->IASetInputLayout(g_ctx,g_il);g_ctx->lpVtbl->VSSetConstantBuffers(g_ctx,0,1,&g_cb);g_ctx->lpVtbl->UpdateSubresource(g_ctx,(ID3D11Resource*)g_cb,0,NULL,vp_t,0,0); - - if (obj_vb && obj_ib) { - UINT stride = sizeof(V3D), off = 0; - g_ctx->lpVtbl->IASetVertexBuffers(g_ctx, 0, 1, &obj_vb, &stride, &off); - g_ctx->lpVtbl->IASetIndexBuffer(g_ctx, obj_ib, DXGI_FORMAT_R32_UINT, 0); - g_ctx->lpVtbl->DrawIndexed(g_ctx, obj_icount, 0, 0); - } - - if(rs)rs->lpVtbl->Release(rs);if(dss)dss->lpVtbl->Release(dss); - g_sc->lpVtbl->Present(g_sc, 1, 0); -} - -static LRESULT CALLBACK WP(HWND h,UINT m,WPARAM w,LPARAM l){ - switch(m){ - case WM_LBUTTONDOWN:drag=1;last_mx=(short)LOWORD(l);last_my=(short)HIWORD(l);SetCapture(h);break; - case WM_LBUTTONUP:drag=0;ReleaseCapture();break; - case WM_MOUSEMOVE:if(drag){int mx=(short)LOWORD(l),my=(short)HIWORD(l);cam_yaw+=(mx-last_mx)*0.005f;cam_pitch+=(my-last_my)*0.005f;if(cam_pitch>1.5f)cam_pitch=1.5f;if(cam_pitch<-1.5f)cam_pitch=-1.5f;last_mx=mx;last_my=my;}break; - case WM_MOUSEWHEEL:cam_dist-=(short)HIWORD(w)/120.0f;if(cam_dist<1)cam_dist=1;if(cam_dist>20)cam_dist=20;break; - case WM_KEYDOWN:switch(w){case 'A':key_a=1;break;case 'D':key_d=1;break;case 'W':key_w=1;break;case 'S':key_s=1;break;case 'Q':key_q=1;break;case 'E':key_e=1;break;case VK_ESCAPE:PostQuitMessage(0);break;}break; - case WM_KEYUP:switch(w){case 'A':key_a=0;break;case 'D':key_d=0;break;case 'W':key_w=0;break;case 'S':key_s=0;break;case 'Q':key_q=0;break;case 'E':key_e=0;break;}break; - case WM_DESTROY:PostQuitMessage(0);return 0; - }return DefWindowProcW(h,m,w,l); -} - -int WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR nC,int nS){ - (void)nS; - WNDCLASSEXW wc;memset(&wc,0,sizeof(wc));wc.cbSize=sizeof(wc);wc.style=CS_CLASSDC;wc.lpfnWndProc=WP;wc.hInstance=hI;wc.lpszClassName=L"obj_viewer"; - RegisterClassExW(&wc); - HWND hwnd=CreateWindowW(L"obj_viewer",L"OBJ Viewer - Mouse drag orbit, WASD move, Scroll zoom",WS_OVERLAPPEDWINDOW,100,100,1280,720,NULL,NULL,hI,NULL); - if(!hwnd)return -1;ShowWindow(hwnd,SW_SHOW);UpdateWindow(hwnd);Init(hwnd); - - char path[MAX_PATH]; - GetModuleFileNameA(NULL, path, MAX_PATH); - char* sl = strrchr(path, '\\'); - if (sl) { *(sl+1) = '\0'; strcat(path, "Assets\\cube.obj"); } - else strcpy(path, "Assets\\cube.obj"); - LoadOBJ(path); - - MSG msg; - while(1){while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);if(msg.message==WM_QUIT)goto done;}Frame();} -done: - if(obj_vb)obj_vb->lpVtbl->Release(obj_vb);if(obj_ib)obj_ib->lpVtbl->Release(obj_ib); - if(g_cb)g_cb->lpVtbl->Release(g_cb);if(g_il)g_il->lpVtbl->Release(g_il);if(g_vs)g_vs->lpVtbl->Release(g_vs);if(g_ps)g_ps->lpVtbl->Release(g_ps);if(g_rtv)g_rtv->lpVtbl->Release(g_rtv);if(g_sc)g_sc->lpVtbl->Release(g_sc);if(g_ctx)g_ctx->lpVtbl->Release(g_ctx);if(g_dev)g_dev->lpVtbl->Release(g_dev); - return 0; -} diff --git a/Demo/Demo/open_world_demo.c b/Demo/Demo/open_world_demo.c deleted file mode 100644 index 404bca7..0000000 --- a/Demo/Demo/open_world_demo.c +++ /dev/null @@ -1,384 +0,0 @@ -#include "../Engine/Core/engine.h" -#include "../Engine/Core/logger.h" -#include "../Engine/Core/timer.h" -#include "../Engine/Core/asset_manager.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/renderer.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Rendering/mesh.h" -#include "../Engine/Rendering/material.h" -#include "../Engine/Rendering/camera.h" -#include "../Engine/Rendering/camera_controller.h" -#include "../Engine/Terrain/terrain.h" -#include "../Engine/Terrain/terrain_manager.h" -#include "../Engine/Rendering/frustum.h" -#include "../Engine/Scene/scene_graph.h" -#include "../Engine/Scene/scene_render.h" -#include "../Engine/Scene/scene_serialize.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" -#include -#include -#include -#include -#include - -static AssetManager* g_assets = NULL; -static Asset* g_shader_asset = NULL; -static Camera g_camera; -static CameraController g_controller; -static TerrainManager* g_terrain = NULL; -static Material* g_terrain_mat = NULL; -static Mesh* g_cube = NULL; -static Material* g_cube_mat = NULL; -static Mesh* g_water = NULL; -static Material* g_water_mat = NULL; -static Scene* g_test_scene = NULL; - -static int g_mouse_down[3] = {0}; -static int g_last_mouse_x = 0, g_last_mouse_y = 0; -static int g_mouse_first = 1; -static int g_walk_mode = 0; - -// ============================================================================ -// 简易植被/岩石散布 -// ============================================================================ -#define MAX_SCATTER 512 - -typedef struct { - Mesh* mesh; - Material* mat; - Mat4 world; -} ScatterInstance; - -static ScatterInstance g_scatter[MAX_SCATTER]; -static int g_scatter_count = 0; - -static void add_scatter(Mesh* mesh, Material* mat, Vec3 pos, Vec3 scale) { - if (g_scatter_count >= MAX_SCATTER) return; - ScatterInstance* s = &g_scatter[g_scatter_count++]; - s->mesh = mesh; - s->mat = mat; - mat4_identity(&s->world); - s->world.m[0][0] = scale.x; - s->world.m[1][1] = scale.y; - s->world.m[2][2] = scale.z; - s->world.m[3][0] = pos.x; - s->world.m[3][1] = pos.y; - s->world.m[3][2] = pos.z; -} - -static void generate_scatter(ID3D11Device* dev, Shader* shader) { - Mesh* rock_mesh = mesh_create_cube(dev); - Material* rock_mat = material_create(shader, NULL); - rock_mat->color = (Vec4){0.55f, 0.50f, 0.45f, 1.0f}; - - Mesh* trunk_mesh = mesh_create_cube(dev); - Material* trunk_mat = material_create(shader, NULL); - trunk_mat->color = (Vec4){0.55f, 0.40f, 0.25f, 1.0f}; - - Mesh* leaves_mesh = mesh_create_sphere(dev, 1.0f, 8); - Material* leaves_mat = material_create(shader, NULL); - leaves_mat->color = (Vec4){0.22f, 0.65f, 0.28f, 1.0f}; - - for (int i = 0; i < MAX_SCATTER; i++) { - float x = ((float)rand() / (float)RAND_MAX) * 400.0f - 200.0f; - float z = ((float)rand() / (float)RAND_MAX) * 400.0f - 200.0f; - float h = terrain_manager_get_height(g_terrain, x, z); - // 跳过过低(水)或过高的山顶 - if (h < -2.0f || h > 20.0f) continue; - - int type = rand() % 3; - if (type == 0) { - // 岩石 - float s = 1.0f + ((float)rand() / (float)RAND_MAX) * 2.0f; - Vec3 pos = {x, h + s * 0.3f, z}; - Vec3 sc = {s, s * 0.6f, s}; - add_scatter(rock_mesh, rock_mat, pos, sc); - } else { - // 树 - float trunk_h = 1.5f + ((float)rand() / (float)RAND_MAX) * 1.5f; - Vec3 trunk_pos = {x, h + trunk_h * 0.5f, z}; - Vec3 trunk_sc = {0.25f, trunk_h, 0.25f}; - add_scatter(trunk_mesh, trunk_mat, trunk_pos, trunk_sc); - - float leaves_s = 1.2f + ((float)rand() / (float)RAND_MAX) * 1.2f; - Vec3 leaves_pos = {x, h + trunk_h + leaves_s * 0.4f, z}; - Vec3 leaves_sc = {leaves_s, leaves_s, leaves_s}; - add_scatter(leaves_mesh, leaves_mat, leaves_pos, leaves_sc); - } - } - - LOG_INFO("Generated %d scatter instances", g_scatter_count); -} - -static void render_scatter(Renderer* r, const Vec4 planes[6]) { - const float cull_distance = 140.0f; - const float cull_dist2 = cull_distance * cull_distance; - int rendered = 0; - for (int i = 0; i < g_scatter_count; i++) { - ScatterInstance* s = &g_scatter[i]; - Vec3 pos = {s->world.m[3][0], s->world.m[3][1], s->world.m[3][2]}; - Vec3 d; - vec3_sub(&pos, &g_camera.position, &d); - if (vec3_dot(&d, &d) > cull_dist2) continue; - - // 视锥剔除:用包围球近似 - float radius = fmaxf(fmaxf(s->world.m[0][0], s->world.m[1][1]), s->world.m[2][2]) * 0.866f; - if (!frustum_intersects_sphere(planes, pos, radius)) continue; - - renderer_draw_mesh_with_material(r, s->mesh, s->mat, &s->world); - rendered++; - } - LOG_INFO("Scatter render: visible=%d/%d", rendered, g_scatter_count); -} - -// ============================================================================ -// 地形高度回调 -// ============================================================================ -static float get_terrain_height(float x, float z, void* user) { - (void)user; - if (g_terrain) return terrain_manager_get_height(g_terrain, x, z); - return 0.0f; -} - -// ============================================================================ -// 引擎回调 -// ============================================================================ -static void on_render(Engine* engine) { - Renderer* r = engine_get_renderer(engine); - GraphicsDevice* dev = engine_get_graphics_device(engine); - if (!r || !dev) return; - - renderer_set_view(r, camera_get_view(&g_camera)); - renderer_set_projection(r, camera_get_projection(&g_camera)); - - renderer_begin_frame(r); - - Mat4 vp; - renderer_get_view_projection(r, &vp); - Vec4 planes[6]; - frustum_from_matrix(&vp, planes); - - if (g_water) { - Mat4 water_world; - mat4_identity(&water_world); - water_world.m[3][1] = -5.0f; - renderer_draw_mesh_with_material(r, g_water, g_water_mat, &water_world); - } - - if (g_terrain) { - terrain_manager_update(g_terrain, g_camera.position); - terrain_manager_render(g_terrain, r); - } - - render_scatter(r, planes); - - if (g_test_scene) { - scene_update(g_test_scene); - scene_render(g_test_scene, r); - } - - renderer_end_frame(r); - - if (engine->frame_count == 60) { - graphics_device_save_screenshot(dev, "open_world_screenshot1.bmp"); - } - if (engine->frame_count == 180) { - graphics_device_save_screenshot(dev, "open_world_screenshot2.bmp"); - } -} - -static void on_update(Engine* engine, double dt) { - (void)engine; - float fdt = (float)dt; - - Vec3 dir = {0.0f, 0.0f, 0.0f}; - if (GetAsyncKeyState('W') & 0x8000) dir.z += 1.0f; - if (GetAsyncKeyState('S') & 0x8000) dir.z -= 1.0f; - if (GetAsyncKeyState('A') & 0x8000) dir.x -= 1.0f; - if (GetAsyncKeyState('D') & 0x8000) dir.x += 1.0f; - - if (!g_walk_mode) { - if (GetAsyncKeyState(VK_SPACE) & 0x8000) dir.y += 1.0f; - if (GetAsyncKeyState(VK_SHIFT) & 0x8000) dir.y -= 1.0f; - } - - if (dir.x != 0.0f || dir.y != 0.0f || dir.z != 0.0f) { - camera_controller_move(&g_controller, dir, fdt); - } - - camera_controller_update(&g_controller, fdt); -} - -static void on_key(Engine* engine, int key) { - (void)engine; - if (key == VK_ESCAPE) engine_request_quit(engine); - - // 切换步行/飞行模式 - if (key == 'F' || key == 'f') { - g_walk_mode = !g_walk_mode; - camera_controller_set_mode(&g_controller, g_walk_mode ? CAMERA_MODE_WALK : CAMERA_MODE_FLY); - g_controller.move_speed = g_walk_mode ? 8.0f : 40.0f; - LOG_INFO("Camera mode: %s (speed %.1f)", g_walk_mode ? "walk" : "fly", g_controller.move_speed); - } - - // 模式切换后重新定位相机高度 - if (g_walk_mode) { - float ground = get_terrain_height(g_camera.position.x, g_camera.position.z, NULL); - g_camera.position.y = ground + g_controller.height_offset; - g_camera.target.y = g_camera.position.y + sinf(g_controller.pitch); - g_camera.dirty = 1; - } -} - -static void on_mouse_move(Engine* engine, int x, int y) { - (void)engine; - if (g_mouse_down[0]) { // 左键拖拽旋转 - if (g_mouse_first) { - g_last_mouse_x = x; - g_last_mouse_y = y; - g_mouse_first = 0; - } else { - float dx = (float)(x - g_last_mouse_x); - float dy = (float)(y - g_last_mouse_y); - camera_controller_look(&g_controller, dx, dy); - g_last_mouse_x = x; - g_last_mouse_y = y; - } - } else { - g_mouse_first = 1; - } -} - -static void on_mouse_button(Engine* engine, int button, int pressed) { - (void)engine; - if (button >= 0 && button < 3) g_mouse_down[button] = pressed; -} - -static void on_resize(Engine* engine, int width, int height) { - Renderer* r = engine_get_renderer(engine); - if (r && width > 0 && height > 0) { - renderer_resize(r, width, height); - g_camera.aspect = (float)width / (float)height; - g_camera.dirty = 1; - } -} - -// ============================================================================ -// 入口 -// ============================================================================ -int main(int argc, char* argv[]) { - (void)argc; (void)argv; - - srand((unsigned int)time(NULL)); - - EngineConfig config = engine_default_config(); - config.app_name = "Lity3D - Open World Demo"; - config.vsync = 1; - config.window_width = 1280; - config.window_height = 720; - - Engine* engine = engine_create(); - if (!engine_init(engine, &config)) { - LOG_FATAL("Engine init failed"); - return -1; - } - - GraphicsDevice* dev = engine_get_graphics_device(engine); - Renderer* r = engine_get_renderer(engine); - - g_assets = asset_manager_create(); - g_shader_asset = asset_manager_load_shader(g_assets, dev->device, NULL, NULL); - if (!g_shader_asset) { - LOG_FATAL("Shader load failed"); - return -1; - } - LOG_INFO("Shader loaded via AssetManager"); - - Shader* default_shader = (Shader*)asset_data(g_shader_asset); - - // 地形材质 - g_terrain_mat = material_create(default_shader, NULL); - g_terrain_mat->color = (Vec4){1.0f, 1.0f, 1.0f, 1.0f}; - - // 参照立方体 - g_cube = mesh_create_cube(dev->device); - g_cube_mat = material_create(default_shader, NULL); - g_cube_mat->color = (Vec4){1.0f, 0.2f, 0.2f, 1.0f}; - - // 水面(不透明,作为低洼处背景) - g_water = mesh_create_plane(dev->device, 2000.0f); - g_water_mat = material_create(default_shader, NULL); - g_water_mat->color = (Vec4){0.18f, 0.45f, 0.78f, 1.0f}; - - // 测试场景:仅保留一个红色立方体作为原点标记 - g_test_scene = (Scene*)calloc(1, sizeof(Scene)); - scene_init(g_test_scene); - - SceneNode* cube_node = scene_create_node(g_test_scene, "cube"); - scene_set_parent(cube_node, g_test_scene->root); - cube_node->position = (Vec3){0.0f, 0.0f, 0.0f}; - MeshRenderer* cube_mr = mesh_renderer_create(MESH_CUBE, g_cube, g_cube_mat); - scene_node_set_mesh_renderer(cube_node, cube_mr); - - // 地形配置 - TerrainConfig tcfg = terrain_default_config(); - tcfg.vertices_per_chunk = 48; - tcfg.chunk_size = 64.0f; - tcfg.height_scale = 30.0f; - tcfg.uv_scale = 0.05f; - - g_terrain = terrain_manager_create(dev->device, &tcfg, g_terrain_mat); - g_terrain->load_radius = 3; - - // 生成植被/岩石 - generate_scatter(dev->device, default_shader); - - // 天空色与柔和环境光 - renderer_set_clear_color(r, 0.53f, 0.81f, 0.98f, 1.0f); - renderer_set_light(r, (Vec3){0.5f, -1.0f, 0.3f}, - (Vec4){0.55f, 0.53f, 0.48f, 1.0f}, - (Vec4){0.70f, 0.74f, 0.82f, 1.0f}); - - // 相机初始化:站在地形上,朝 +Z - float aspect = (float)config.window_width / (float)config.window_height; - g_camera = camera_perspective(1.0472f, aspect, 0.1f, 500.0f); - float start_h = terrain_manager_get_height(g_terrain, 0.0f, 0.0f); - g_camera.position = (Vec3){0.0f, start_h + 1.75f, 0.0f}; - g_camera.target = (Vec3){0.0f, start_h + 1.75f, 5.0f}; - g_camera.far_z = 500.0f; - g_camera.dirty = 1; - - g_controller = camera_controller_create(&g_camera); - g_controller.move_speed = 8.0f; - g_controller.mouse_sensitivity = 0.004f; - camera_controller_set_ground_callback(&g_controller, get_terrain_height, NULL); - g_walk_mode = 1; - camera_controller_set_mode(&g_controller, CAMERA_MODE_WALK); - LOG_INFO("Starting in walk mode at height %.2f", start_h); - - renderer_set_view(r, camera_get_view(&g_camera)); - renderer_set_projection(r, camera_get_projection(&g_camera)); - - engine_set_update_callback(engine, on_update); - engine_set_render_callback(engine, on_render); - engine_set_key_callback(engine, on_key); - engine_set_mouse_move_callback(engine, on_mouse_move); - engine_set_mouse_button_callback(engine, on_mouse_button); - engine_set_resize_callback(engine, on_resize); - - LOG_INFO("Running open world demo..."); - engine_run(engine); - - terrain_manager_destroy(g_terrain); - if (g_test_scene) { - scene_destroy_renderers(g_test_scene); - scene_destroy(g_test_scene); - free(g_test_scene); - } - if (g_cube) mesh_destroy(g_cube); - asset_manager_destroy(g_assets); - engine_shutdown(engine); - return 0; -} diff --git a/Demo/Demo/raw3d_test.c b/Demo/Demo/raw3d_test.c deleted file mode 100644 index 13964e7..0000000 --- a/Demo/Demo/raw3d_test.c +++ /dev/null @@ -1,128 +0,0 @@ -// raw3d_test.c - 用 draw_quad 画 3D 方块,验证场景图变换 -#include "../Engine/Core/engine.h" -#include "../Engine/Window/window.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Scene/scene_graph.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" - -static GraphicsDevice* g_dev = NULL; -static Shader* g_shader = NULL; -static Scene g_scene; -static float g_time = 0; - -typedef struct { float p[3],n[3],uv[2],c[4]; } V; -static void draw_quad_3d(ID3D11DeviceContext* ctx, float x, float y, float w, float h, float r, float g, float b, float a) { - V v[4] = {{{x,y,0},{0,0,-1},{0,0},{r,g,b,a}},{{x+w,y,0},{0,0,-1},{1,0},{r,g,b,a}},{{x+w,y+h,0},{0,0,-1},{1,1},{r,g,b,a}},{{x,y+h,0},{0,0,-1},{0,1},{r,g,b,a}}}; - uint32_t idx[6] = {0,1,2,0,2,3}; - ID3D11Buffer *vb=NULL,*ib=NULL; - D3D11_BUFFER_DESC bd={}; D3D11_SUBRESOURCE_DATA sd={}; - bd.ByteWidth=sizeof(V)*4; bd.Usage=D3D11_USAGE_DEFAULT; bd.BindFlags=D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem=v; g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd,&sd,&vb); - bd.ByteWidth=sizeof(uint32_t)*6; bd.BindFlags=D3D11_BIND_INDEX_BUFFER; - sd.pSysMem=idx; g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd,&sd,&ib); - UINT stride=sizeof(V),off=0; - ctx->lpVtbl->IASetVertexBuffers(ctx,0,1,&vb,&stride,&off); - ctx->lpVtbl->IASetIndexBuffer(ctx,ib,DXGI_FORMAT_R32_UINT,0); - ctx->lpVtbl->DrawIndexed(ctx,6,0,0); - ib->lpVtbl->Release(ib); vb->lpVtbl->Release(vb); -} - -static void on_render(Engine* engine) { - if (!g_dev) return; - ID3D11DeviceContext* ctx = g_dev->context; - scene_update(&g_scene); - g_time += (float)engine->delta_time; - - float sw=(float)g_dev->width, sh=(float)g_dev->height; - float fov=1.0f/tanf(0.4f), asp=sw/sh; - - // VP矩阵: 摄像机在(8,5,10)看原点 - float ex=8,ey=5,ez=10; - float fx=-ex,fy=-ey,fz=-ez, fl=sqrtf(fx*fx+fy*fy+fz*fz); fx/=fl;fy/=fl;fz/=fl; - float rx=fy*0-fz*1,ry=fz*0-fx*0,rz=fx*1-fy*0; - float rl=sqrtf(rx*rx+ry*ry+rz*rz);rx/=rl;ry/=rl;rz/=rl; - float ux=ry*fz-rz*fy,uy=rz*fx-rx*fz,uz=rx*fy-ry*fx; - float mvp[16]; - mvp[0]=rx*fov/asp;mvp[1]=ry*fov/asp;mvp[2]=rz*fov/asp;mvp[3]=0; - mvp[4]=ux*fov;mvp[5]=uy*fov;mvp[6]=uz*fov;mvp[7]=0; - mvp[8]=fx;mvp[9]=fy;mvp[10]=fz;mvp[11]=0; - mvp[12]=-(rx*ex+ry*ey+rz*ez)*fov/asp; - mvp[13]=-(ux*ex+uy*ey+uz*ez)*fov; - mvp[14]=-(fx*ex+fy*ey+fz*ez);mvp[15]=1; - - graphics_device_clear(g_dev, 0.15f, 0.18f, 0.25f, 1.0f); - D3D11_VIEWPORT vp={};vp.Width=sw;vp.Height=sh;vp.MaxDepth=1; - ctx->lpVtbl->RSSetViewports(ctx,1,&vp); - D3D11_RASTERIZER_DESC rd={};rd.FillMode=D3D11_FILL_SOLID;rd.CullMode=D3D11_CULL_NONE; - ID3D11RasterizerState* rs=NULL; - g_dev->device->lpVtbl->CreateRasterizerState(g_dev->device,&rd,&rs); - ctx->lpVtbl->RSSetState(ctx,rs); - D3D11_DEPTH_STENCIL_DESC dsd={};dsd.DepthEnable=FALSE; - ID3D11DepthStencilState* dss=NULL; - g_dev->device->lpVtbl->CreateDepthStencilState(g_dev->device,&dsd,&dss); - ctx->lpVtbl->OMSetDepthStencilState(ctx,dss,0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx,D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - shader_bind(g_shader, ctx); - - // 地面 - shader_set_matrix(g_shader, ctx, mvp); - draw_quad_3d(ctx, -5, 0, 10, 10, 0.3f, 0.35f, 0.4f, 1); - - // 场景节点 - for (int i=0;ivisible||n->id==0||n->user_type!=1) continue; - // 用世界矩阵变换4个角点 - float corners[4][3] = {{-0.5f,-0.5f,0},{0.5f,-0.5f,0},{0.5f,0.5f,0},{-0.5f,0.5f,0}}; - V v[4]; uint32_t idx[6]={0,1,2,0,2,3}; - float colors[][3]={{1,0.2f,0.2f},{0.2f,1,0.2f},{0.2f,0.2f,1},{1,1,0.2f},{0.5f,0.2f,0.8f},{0.2f,0.8f,0.8f},{0.8f,0.5f,0.2f},{0.5f,0.5f,0.5f}}; - int ci=(i-1)%8; - for(int c=0;c<4;c++){ - float px=0,py=0,pz=0; - for(int r=0;r<4;r++) {float wc=n->world_matrix.m[0][r]*corners[c][0]+n->world_matrix.m[1][r]*corners[c][1]+n->world_matrix.m[2][r]*corners[c][2]+n->world_matrix.m[3][r]; px+=wc*mvp[r*4+0]; py+=wc*mvp[r*4+1]; pz+=wc*mvp[r*4+2];} - // 简化: 直接用世界坐标+投影 - float wx=n->world_matrix.m[3][0]+corners[c][0]; - float wy=n->world_matrix.m[3][1]+corners[c][1]; - float wz=n->world_matrix.m[3][2]+corners[c][2]; - v[c].p[0]=wx; v[c].p[1]=wy; v[c].p[2]=wz; - v[c].n[0]=0; v[c].n[1]=0; v[c].n[2]=1; - v[c].c[0]=colors[ci][0]; v[c].c[1]=colors[ci][1]; v[c].c[2]=colors[ci][2]; v[c].c[3]=1; - } - ID3D11Buffer* vb=NULL,*ib2=NULL; - D3D11_BUFFER_DESC bd2={}; D3D11_SUBRESOURCE_DATA sd2={}; - bd2.ByteWidth=sizeof(V)*4; bd2.Usage=D3D11_USAGE_DEFAULT; bd2.BindFlags=D3D11_BIND_VERTEX_BUFFER; - sd2.pSysMem=v; g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd2,&sd2,&vb); - bd2.ByteWidth=sizeof(uint32_t)*6; bd2.BindFlags=D3D11_BIND_INDEX_BUFFER; - sd2.pSysMem=idx; g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd2,&sd2,&ib2); - UINT s2=sizeof(V),o2=0; - ctx->lpVtbl->IASetVertexBuffers(ctx,0,1,&vb,&s2,&o2); - ctx->lpVtbl->IASetIndexBuffer(ctx,ib2,DXGI_FORMAT_R32_UINT,0); - ctx->lpVtbl->DrawIndexed(ctx,6,0,0); - ib2->lpVtbl->Release(ib2); vb->lpVtbl->Release(vb); - } - - if(rs) rs->lpVtbl->Release(rs); - if(dss) dss->lpVtbl->Release(dss); - graphics_device_present(g_dev); -} - -static void on_key(Engine* engine, int key) { if (key==VK_ESCAPE) engine_request_quit(engine); } - -int WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int) { - EngineConfig cfg=engine_default_config(); cfg.app_name="lity3d Raw3D"; - Engine* e=engine_create(); if(!engine_init(e,&cfg))return -1; - g_dev=graphics_device_create(); - if(!graphics_device_init(g_dev,window_get_handle(e->window),cfg.window_width,cfg.window_height,1))return -1; - g_shader=shader_create(); shader_compile(g_shader,g_dev->device,NULL,NULL,0,0); - scene_init(&g_scene); - SceneNode* c1=scene_create_node(&g_scene,"Cube1"); scene_set_position(c1,0,0.5f,0); c1->user_type=1; - SceneNode* c2=scene_create_node(&g_scene,"Cube2"); scene_set_position(c2,-3,0.5f,2); c2->user_type=1; - SceneNode* c3=scene_create_node(&g_scene,"Cube3"); scene_set_position(c3,3,0.5f,-2); scene_set_scale(c3,0.5f,0.5f,0.5f); c3->user_type=1; - SceneNode* ch=scene_create_node(&g_scene,"Child"); scene_set_position(ch,2,0,0); ch->user_type=1; scene_set_parent(ch,c1); - engine_set_render_callback(e,on_render); engine_set_key_callback(e,on_key); - engine_run(e); - shader_destroy(g_shader); graphics_device_destroy(g_dev); engine_shutdown(e); - return 0; -} diff --git a/Demo/Demo/scene_test.c b/Demo/Demo/scene_test.c deleted file mode 100644 index 6ca0919..0000000 --- a/Demo/Demo/scene_test.c +++ /dev/null @@ -1,121 +0,0 @@ -// scene_test.c - 场景图 + 网格渲染 -#include "../Engine/Core/engine.h" -#include "../Engine/Core/logger.h" -#include "../Engine/Window/window.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Rendering/mesh.h" -#include "../Engine/Scene/scene_graph.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" - -static GraphicsDevice* g_dev = NULL; -static Shader* g_shader = NULL; -static Mesh* g_cube = NULL; -static Mesh* g_plane = NULL; -static Scene g_scene; -static SceneNode* g_camera = NULL; -static float g_time = 0; - -static void on_render(Engine* engine) { - if (!g_dev) return; - ID3D11DeviceContext* ctx = g_dev->context; - scene_update(&g_scene); - g_time += (float)engine->delta_time; - - float sw = (float)g_dev->width, sh = (float)g_dev->height; - float fov = 1.0f / tanf(0.5f * 0.785f), aspect = sw / sh; - Vec3 cam_pos; - scene_get_world_position(g_camera, &cam_pos); - - // VP 矩阵 - float proj[16] = {0}; - proj[0] = fov / aspect; proj[5] = -fov; - proj[10] = 1.0f; proj[11] = -1.0f; proj[14] = 0.1f; proj[15] = 1.0f; - - Vec3 eye = cam_pos, target = {0,0,0}, up = {0,1,0}; - Vec3 f, r, u; - vec3_sub(&target, &eye, &f); vec3_normalize(&f, &f); - vec3_cross(&up, &f, &r); vec3_normalize(&r, &r); - vec3_cross(&f, &r, &u); - - float view[16] = {0}; - view[0]=r.x; view[1]=u.x; view[2]=-f.x; - view[4]=r.y; view[5]=u.y; view[6]=-f.y; - view[8]=r.z; view[9]=u.z; view[10]=-f.z; - view[12]=-vec3_dot(&r,&eye); view[13]=-vec3_dot(&u,&eye); view[14]=vec3_dot(&f,&eye); view[15]=1.0f; - - float vp_raw[16] = {0}; - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - vp_raw[i*4+j] = view[i*4+0]*proj[0*4+j]+view[i*4+1]*proj[1*4+j]+view[i*4+2]*proj[2*4+j]+view[i*4+3]*proj[3*4+j]; - Mat4 vp_m, vp_t; - memcpy(&vp_m, vp_raw, sizeof(Mat4)); - mat4_transpose(&vp_m, &vp_t); - - graphics_device_clear(g_dev, 0.15f, 0.18f, 0.25f, 1.0f); - - D3D11_VIEWPORT vport = {0}; vport.Width = sw; vport.Height = sh; vport.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vport); - - D3D11_RASTERIZER_DESC rdesc = {0}; rdesc.FillMode = D3D11_FILL_SOLID; rdesc.CullMode = D3D11_CULL_NONE; - ID3D11RasterizerState* rstate = NULL; - g_dev->device->lpVtbl->CreateRasterizerState(g_dev->device, &rdesc, &rstate); - ctx->lpVtbl->RSSetState(ctx, rstate); - - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - shader_bind(g_shader, ctx); - shader_set_matrix(g_shader, ctx, (float*)&vp_t); - - if (g_plane) mesh_draw(g_plane, ctx); - - for (int i = 0; i < g_scene.node_count; i++) { - SceneNode* node = &g_scene.nodes[i]; - if (!node->visible || node->id == 0 || node->user_type != 1 || !g_cube) continue; - float wvp_raw[16] = {0}; - for (int r2 = 0; r2 < 4; r2++) - for (int c = 0; c < 4; c++) - wvp_raw[r2*4+c] = view[r2*4+0]*node->world_matrix.m[0][c]+view[r2*4+1]*node->world_matrix.m[1][c]+view[r2*4+2]*node->world_matrix.m[2][c]+view[r2*4+3]*node->world_matrix.m[3][c]; - Mat4 wvp_m, wvp_t; - memcpy(&wvp_m, wvp_raw, sizeof(Mat4)); - mat4_transpose(&wvp_m, &wvp_t); - shader_set_matrix(g_shader, ctx, (float*)&wvp_t); - mesh_draw(g_cube, ctx); - } - - if (rstate) rstate->lpVtbl->Release(rstate); - graphics_device_present(g_dev); -} - -static void on_key(Engine* engine, int key) { if (key == VK_ESCAPE) engine_request_quit(engine); } - -int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR cmd, int nS) { - (void)hI;(void)hP;(void)cmd;(void)nS; - EngineConfig cfg = engine_default_config(); - cfg.app_name = "lity3d Scene Test"; - Engine* engine = engine_create(); - if (!engine_init(engine, &cfg)) return -1; - g_dev = graphics_device_create(); - if (!graphics_device_init(g_dev, window_get_handle(engine->window), cfg.window_width, cfg.window_height, 1)) return -1; - g_shader = shader_create(); - shader_compile(g_shader, g_dev->device, NULL, NULL, 0, 0); - g_cube = mesh_create_cube(g_dev->device); - g_plane = mesh_create_plane(g_dev->device, 10.0f); - scene_init(&g_scene); - g_camera = scene_create_node(&g_scene, "Camera"); - scene_set_position(g_camera, 5, 4, 8); - SceneNode* c1 = scene_create_node(&g_scene, "Cube1"); - scene_set_position(c1, 0, 0.5f, 0); c1->user_type = 1; - SceneNode* c2 = scene_create_node(&g_scene, "Cube2"); - scene_set_position(c2, -3, 0.5f, 2); c2->user_type = 1; - SceneNode* c3 = scene_create_node(&g_scene, "Cube3"); - scene_set_position(c3, 3, 0.5f, -2); c3->user_type = 1; scene_set_scale(c3, 0.5f, 0.5f, 0.5f); - SceneNode* child = scene_create_node(&g_scene, "Child"); - scene_set_position(child, 2, 0, 0); child->user_type = 1; scene_set_parent(child, c1); - engine_set_render_callback(engine, on_render); - engine_set_key_callback(engine, on_key); - engine_run(engine); - mesh_destroy(g_cube); mesh_destroy(g_plane); shader_destroy(g_shader); - graphics_device_destroy(g_dev); engine_shutdown(engine); - return 0; -} diff --git a/Demo/Demo/scene_test2.c b/Demo/Demo/scene_test2.c deleted file mode 100644 index b470be3..0000000 --- a/Demo/Demo/scene_test2.c +++ /dev/null @@ -1,54 +0,0 @@ -// scene_test2.c - 最小化场景测试 -#include "../Engine/Core/engine.h" -#include "../Engine/Core/logger.h" -#include "../Engine/Window/window.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Scene/scene_graph.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" - -static GraphicsDevice* g_dev = NULL; - -static void on_render(Engine* engine) { - if (!g_dev) return; - ID3D11DeviceContext* ctx = g_dev->context; - float clear[4] = {0.2f, 0.3f, 0.5f, 1.0f}; - g_dev->context->lpVtbl->ClearRenderTargetView(g_dev->context, g_dev->render_target, clear); - - D3D11_VIEWPORT vp = {0}; - vp.Width = (float)g_dev->width; vp.Height = (float)g_dev->height; - vp.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vp); - graphics_device_present(g_dev); -} - -static void on_key(Engine* engine, int key) { - if (key == VK_ESCAPE) engine_request_quit(engine); -} - -int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR cmd, int nS) { - (void)hI;(void)hP;(void)cmd;(void)nS; - LOG_INFO("=== lity3d Scene Test ==="); - EngineConfig cfg = engine_default_config(); - cfg.app_name = "lity3d Scene Test"; - Engine* engine = engine_create(); - if (!engine_init(engine, &cfg)) return -1; - g_dev = graphics_device_create(); - if (!graphics_device_init(g_dev, window_get_handle(engine->window), cfg.window_width, cfg.window_height, 1)) return -1; - LOG_INFO("D3D11 ready"); - Scene scene; scene_init(&scene); - SceneNode* n1 = scene_create_node(&scene, "A"); - scene_set_position(n1, 1, 0, 0); - SceneNode* n2 = scene_create_node(&scene, "B"); - scene_set_parent(n2, n1); - scene_set_position(n2, 0, 2, 0); - scene_update(&scene); - LOG_INFO("A world pos: (%.1f,%.1f,%.1f)", scene.nodes[1].world_matrix.m[3][0], scene.nodes[1].world_matrix.m[3][1], scene.nodes[1].world_matrix.m[3][2]); - LOG_INFO("B world pos: (%.1f,%.1f,%.1f)", scene.nodes[2].world_matrix.m[3][0], scene.nodes[2].world_matrix.m[3][1], scene.nodes[2].world_matrix.m[3][2]); - engine_set_render_callback(engine, on_render); - engine_set_key_callback(engine, on_key); - engine_run(engine); - graphics_device_destroy(g_dev); - engine_shutdown(engine); - return 0; -} diff --git a/Demo/Demo/test.ly b/Demo/Demo/test.ly deleted file mode 100644 index 5037860..0000000 --- a/Demo/Demo/test.ly +++ /dev/null @@ -1,54 +0,0 @@ -# lity3d 积木脚本 - 测试解释器 -# 开始 -> 移动物体 -> 打印 -> 循环3次 -> 移动物体 - -[B] -id=1 -name=开始 -p=100,100 -c=0 - -[B] -id=2 -name=移动物体 -p=350,100 -c=1 - -[B] -id=3 -name=打印 -p=600,100 -d=Hello World -c=3 - -[B] -id=4 -name=循环 -p=100,250 -d=3 -c=2 - -[B] -id=5 -name=移动物体 -p=350,250 -c=1 - -# 连线: 开始.输出0 -> 移动物体.执行0 -[W] -a=10000 -b=20000 - -# 移动物体.执行0 -> 打印.执行0 -[W] -a=20000 -b=30000 - -# 打印.执行0 -> 循环.执行0 -[W] -a=30000 -b=40000 - -# 循环.执行0 -> 移动物体2.执行0 -[W] -a=40000 -b=50000 diff --git a/Demo/audio_demo.c b/Demo/audio_demo.c deleted file mode 100644 index 35a4b6e..0000000 --- a/Demo/audio_demo.c +++ /dev/null @@ -1,118 +0,0 @@ -// ============================================================================ -// audio_demo.c - XAudio2 音频系统演示 -// 生成 440Hz 正弦波并播放 2 秒,无需外部 WAV 文件 -// ============================================================================ - -#include "../Engine/Audio/audio.h" -#include "../Engine/Core/logger.h" -#include -#include -#include -#include -#include - -#pragma comment(lib, "winmm.lib") - -// 生成标准 PCM WAV 数据 (44.1kHz, 16bit, 单声道) -static uint8_t* generate_sine_wave_wav(float frequency, float duration_sec, uint32_t* out_size) { - const uint32_t sample_rate = 44100; - const uint16_t channels = 1; - const uint16_t bits_per_sample = 16; - const uint16_t block_align = channels * bits_per_sample / 8; - const uint32_t byte_rate = sample_rate * block_align; - const uint32_t num_samples = (uint32_t)(sample_rate * duration_sec); - const uint32_t data_size = num_samples * block_align; - const uint32_t file_size = 44 + data_size; - - uint8_t* wav = (uint8_t*)malloc(file_size); - if (!wav) return NULL; - - // RIFF 头 - memcpy(wav + 0, "RIFF", 4); - memcpy(wav + 4, &file_size, 4); - memcpy(wav + 8, "WAVE", 4); - - // fmt chunk - memcpy(wav + 12, "fmt ", 4); - uint32_t fmt_size = 16; - memcpy(wav + 16, &fmt_size, 4); - uint16_t audio_format = 1; // PCM - memcpy(wav + 20, &audio_format, 2); - memcpy(wav + 22, &channels, 2); - memcpy(wav + 24, &sample_rate, 4); - memcpy(wav + 28, &byte_rate, 4); - memcpy(wav + 32, &block_align, 2); - memcpy(wav + 34, &bits_per_sample, 2); - - // data chunk - memcpy(wav + 36, "data", 4); - memcpy(wav + 40, &data_size, 4); - - // 生成正弦波样本 - int16_t* samples = (int16_t*)(wav + 44); - float amplitude = 0.3f; // 避免削波 - for (uint32_t i = 0; i < num_samples; i++) { - float t = (float)i / (float)sample_rate; - // 简单淡出,避免咔嗒声 - float envelope = 1.0f; - if (i < 1000) envelope = (float)i / 1000.0f; - if (i > num_samples - 1000) envelope = (float)(num_samples - i) / 1000.0f; - float sample = sinf(2.0f * 3.14159265f * frequency * t) * amplitude * envelope; - samples[i] = (int16_t)(sample * 32767.0f); - } - - *out_size = file_size; - return wav; -} - -int main(int argc, char* argv[]) { - (void)argc; (void)argv; - - printf("Lity3D - Audio Demo\n"); - printf("========================\n"); - - AudioSystem* audio = audio_create(); - if (!audio) { - printf("ERROR: Failed to create XAudio2 audio system\n"); - return 1; - } - printf("XAudio2 audio system created.\n"); - - AudioSource* source = audio_source_create(audio); - if (!source) { - printf("ERROR: Failed to create audio source\n"); - audio_destroy(audio); - return 1; - } - - uint32_t wav_size = 0; - uint8_t* wav_data = generate_sine_wave_wav(440.0f, 2.0f, &wav_size); - if (!wav_data) { - printf("ERROR: Failed to generate sine wave\n"); - audio_source_destroy(source); - audio_destroy(audio); - return 1; - } - - if (!audio_load_wav_memory(source, wav_data, wav_size)) { - printf("ERROR: Failed to load generated WAV into audio source\n"); - free(wav_data); - audio_source_destroy(source); - audio_destroy(audio); - return 1; - } - free(wav_data); - printf("Generated 440Hz sine wave loaded.\n"); - - printf("Playing 2 seconds...\n"); - audio_source_play(source); - - // 等待播放结束 (约 2 秒 + 缓冲) - Sleep(2500); - - audio_source_destroy(source); - audio_destroy(audio); - - printf("Audio demo finished successfully.\n"); - return 0; -} diff --git a/Demo/compat_test.c b/Demo/compat_test.c deleted file mode 100644 index 9f2d5af..0000000 --- a/Demo/compat_test.c +++ /dev/null @@ -1,221 +0,0 @@ -#include "../Engine/Core/engine.h" -#include "../Engine/Core/logger.h" -#include "../Engine/Core/timer.h" -#include "../Engine/Window/window.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Rendering/mesh.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" -#include "../Engine/Editor/glyph_atlas.h" -#include - -static GraphicsDevice* g_dev = NULL; -static Shader* g_shader = NULL; -static Mesh* g_tri = NULL; -static GlyphAtlas g_atlas; -static ID3D11VertexShader* g_tvs = NULL; -static ID3D11PixelShader* g_tps = NULL; -static ID3D11InputLayout* g_tlayout = NULL; -static ID3D11BlendState* g_tblend = NULL; -static ID3D11SamplerState* g_tsampler = NULL; -static ID3D11Buffer* g_tcb = NULL; -static ID3D11DepthStencilState* g_no_depth = NULL; - -typedef struct { float p[3], n[3], uv[2], c[4]; } V; - -static void draw_quad(ID3D11DeviceContext* ctx, float x, float y, float w, float h, float r, float g, float b, float a) { - V v[4] = { - {{x,y,0},{0,0,-1},{0,0},{r,g,b,a}}, - {{x+w,y,0},{0,0,-1},{1,0},{r,g,b,a}}, - {{x+w,y+h,0},{0,0,-1},{1,1},{r,g,b,a}}, - {{x,y+h,0},{0,0,-1},{0,1},{r,g,b,a}}, - }; - uint32_t idx[6] = {0,1,2, 0,2,3}; - ID3D11Buffer *vb = NULL, *ib = NULL; - D3D11_BUFFER_DESC bd = {0}; D3D11_SUBRESOURCE_DATA sd = {0}; - bd.ByteWidth = sizeof(V)*4; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = v; g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &bd, &sd, &vb); - bd.ByteWidth = sizeof(uint32_t)*6; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = idx; g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &bd, &sd, &ib); - UINT stride = sizeof(V), offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &vb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, ib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->DrawIndexed(ctx, 6, 0, 0); - ib->lpVtbl->Release(ib); vb->lpVtbl->Release(vb); -} - -static void on_render(Engine* engine) { - if (!g_dev) return; - ID3D11DeviceContext* ctx = g_dev->context; - float sw = (float)g_dev->width; - float sh = (float)g_dev->height; - - graphics_device_clear(g_dev, 0.0f, 0.0f, 0.0f, 1.0f); - - float proj[64] = {0}; - proj[0] = 2.0f / sw; proj[5] = -2.0f / sh; - proj[10] = 1.0f; proj[12] = -1.0f; proj[13] = 1.0f; proj[15] = 1.0f; - Mat4 proj_m, proj_t; - memcpy(&proj_m, proj, sizeof(Mat4)); - mat4_transpose(&proj_m, &proj_t); - - D3D11_VIEWPORT vp = {0}; - vp.Width = sw; vp.Height = sh; vp.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vp); - - D3D11_RASTERIZER_DESC rdesc = {0}; - rdesc.FillMode = D3D11_FILL_SOLID; - rdesc.CullMode = D3D11_CULL_NONE; - ID3D11RasterizerState* rstate = NULL; - g_dev->device->lpVtbl->CreateRasterizerState(g_dev->device, &rdesc, &rstate); - ctx->lpVtbl->RSSetState(ctx, rstate); - - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - shader_bind(g_shader, ctx); - shader_set_matrix(g_shader, ctx, (float*)&proj_t); - mesh_draw(g_tri, ctx); - - { - ctx->lpVtbl->OMSetDepthStencilState(ctx, g_no_depth, 0); - } - - draw_quad(ctx, sw - 200, 10, 180, 60, 1, 1, 1, 1); - - if (g_tvs && g_tps && g_tlayout && g_tcb && g_tblend && g_tsampler && g_atlas.srv) { - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)g_tcb, 0, NULL, &proj_t, 0, 0); - ctx->lpVtbl->VSSetShader(ctx, g_tvs, NULL, 0); - ctx->lpVtbl->PSSetShader(ctx, g_tps, NULL, 0); - ctx->lpVtbl->IASetInputLayout(ctx, g_tlayout); - ctx->lpVtbl->VSSetConstantBuffers(ctx, 0, 1, &g_tcb); - ctx->lpVtbl->PSSetShaderResources(ctx, 0, 1, &g_atlas.srv); - ctx->lpVtbl->PSSetSamplers(ctx, 0, 1, &g_tsampler); - ctx->lpVtbl->OMSetBlendState(ctx, g_tblend, NULL, 0xFFFFFFFF); - - typedef struct { float p[3], n[3], uv[2], c[4]; } TV; - TV tverts[4]; - uint32_t tidx[6] = {0,1,2, 0,2,3}; - int cx = (int)(sw - 195), cy = 35; - for (const wchar_t* p = L"\u6d4b\u8bd5"; *p; p++) { - float u0, v0, u1, v1, adv_x, adv_y; - if (glyph_atlas_get_or_create(&g_atlas, g_dev->device, ctx, *p, &u0, &v0, &u1, &v1, &adv_x, &adv_y)) { - tverts[0] = (TV){{(float)cx,(float)cy,0},{0,0,1},{u0,v0},{0,0,0,1}}; - tverts[1] = (TV){{(float)cx+adv_x,(float)cy,0},{0,0,1},{u1,v0},{0,0,0,1}}; - tverts[2] = (TV){{(float)cx+adv_x,(float)cy+adv_y,0},{0,0,1},{u1,v1},{0,0,0,1}}; - tverts[3] = (TV){{(float)cx,(float)cy+adv_y,0},{0,0,1},{u0,v1},{0,0,0,1}}; - ID3D11Buffer *tvb = NULL, *tib = NULL; - D3D11_BUFFER_DESC bd2 = {0}; D3D11_SUBRESOURCE_DATA sd2 = {0}; - bd2.ByteWidth = sizeof(TV)*4; bd2.Usage = D3D11_USAGE_DEFAULT; bd2.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd2.pSysMem = tverts; g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &bd2, &sd2, &tvb); - bd2.ByteWidth = sizeof(uint32_t)*6; bd2.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd2.pSysMem = tidx; g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &bd2, &sd2, &tib); - UINT stride2 = sizeof(TV), offset2 = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &tvb, &stride2, &offset2); - ctx->lpVtbl->IASetIndexBuffer(ctx, tib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->DrawIndexed(ctx, 6, 0, 0); - tib->lpVtbl->Release(tib); tvb->lpVtbl->Release(tvb); - cx += (int)adv_x + 2; - } - } - } - - if (rstate) rstate->lpVtbl->Release(rstate); - graphics_device_present(g_dev); -} - -static void on_key(Engine* engine, int key) { - if (key == VK_ESCAPE) engine_request_quit(engine); -} - -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { - (void)hInstance; (void)hPrevInstance; (void)lpCmdLine; (void)nCmdShow; - LOG_INFO("=== Compatibility Test ==="); - - EngineConfig config = engine_default_config(); - config.app_name = "Compatibility Test"; - config.vsync = 1; - config.window_width = 1280; - config.window_height = 720; - - Engine* engine = engine_create(); - if (!engine_init(engine, &config)) return -1; - - g_dev = graphics_device_create(); - if (!graphics_device_init(g_dev, window_get_handle(engine->window), config.window_width, config.window_height, 1)) { - LOG_FATAL("D3D11 init failed"); - return -1; - } - - g_shader = shader_create(); - shader_compile(g_shader, g_dev->device, NULL, NULL, 0, 0); - - glyph_atlas_init(&g_atlas, g_dev->device); - - const char* tvs_src = "cbuffer CB:register(b0){float4x4 WVP;};struct VS_IN{float4 pos:POSITION;float3 n:NORMAL;float2 uv:TEXCOORD;float4 col:COLOR;};struct PS_IN{float4 pos:SV_POSITION;float2 uv:TEXCOORD;float4 col:COLOR;};PS_IN main(VS_IN i){PS_IN o;o.pos=mul(i.pos,WVP);o.uv=i.uv;o.col=i.col;return o;}"; - const char* tps_src = "Texture2D tex:register(t0);SamplerState smp:register(s0);struct PS_IN{float4 pos:SV_POSITION;float2 uv:TEXCOORD;float4 col:COLOR;};float4 main(PS_IN i):SV_TARGET{float a=tex.Sample(smp,i.uv).a;return float4(i.col.rgb,i.col.a*a);}"; - ID3DBlob *vsb = NULL, *psb = NULL, *err = NULL; - D3DCompile(tvs_src, (UINT)strlen(tvs_src), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &vsb, &err); - if (err) { err->lpVtbl->Release(err); err = NULL; } - D3DCompile(tps_src, (UINT)strlen(tps_src), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &psb, &err); - if (err) { err->lpVtbl->Release(err); err = NULL; } - if (vsb && psb) { - g_dev->device->lpVtbl->CreateVertexShader(g_dev->device, vsb->lpVtbl->GetBufferPointer(vsb), vsb->lpVtbl->GetBufferSize(vsb), NULL, &g_tvs); - g_dev->device->lpVtbl->CreatePixelShader(g_dev->device, psb->lpVtbl->GetBufferPointer(psb), psb->lpVtbl->GetBufferSize(psb), NULL, &g_tps); - D3D11_INPUT_ELEMENT_DESC layout[] = { - {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}, - }; - g_dev->device->lpVtbl->CreateInputLayout(g_dev->device, layout, 4, vsb->lpVtbl->GetBufferPointer(vsb), vsb->lpVtbl->GetBufferSize(vsb), &g_tlayout); - vsb->lpVtbl->Release(vsb); psb->lpVtbl->Release(psb); - } - D3D11_SAMPLER_DESC sdesc = {0}; - sdesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - sdesc.AddressU = sdesc.AddressV = sdesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - g_dev->device->lpVtbl->CreateSamplerState(g_dev->device, &sdesc, &g_tsampler); - D3D11_BLEND_DESC bdesc = {0}; - bdesc.RenderTarget[0].BlendEnable = TRUE; - bdesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - bdesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - bdesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - bdesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - bdesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - bdesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - bdesc.RenderTarget[0].RenderTargetWriteMask = 0x0F; - g_dev->device->lpVtbl->CreateBlendState(g_dev->device, &bdesc, &g_tblend); - D3D11_BUFFER_DESC cbd = {0}; - cbd.ByteWidth = 256; cbd.Usage = D3D11_USAGE_DEFAULT; cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &cbd, NULL, &g_tcb); - - D3D11_DEPTH_STENCIL_DESC dsdesc = {0}; - dsdesc.DepthEnable = FALSE; - dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - g_dev->device->lpVtbl->CreateDepthStencilState(g_dev->device, &dsdesc, &g_no_depth); - - V tri[3] = { - {{640, 300, 0}, {0,0,-1}, {0,0}, {1, 0.2f, 0.2f, 1}}, - {{500, 550, 0}, {0,0,-1}, {0,1}, {0.2f, 1, 0.2f, 1}}, - {{780, 550, 0}, {0,0,-1}, {1,0}, {0.2f, 0.2f, 1, 1}}, - }; - uint32_t idx[3] = {0, 1, 2}; - g_tri = (Mesh*)calloc(1, sizeof(Mesh)); - g_tri->stride = sizeof(V); g_tri->vcount = 3; g_tri->icount = 3; - D3D11_BUFFER_DESC bd = {0}; D3D11_SUBRESOURCE_DATA sd = {0}; - bd.ByteWidth = sizeof(V)*3; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = tri; g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &bd, &sd, &g_tri->vb); - bd.ByteWidth = sizeof(uint32_t)*3; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = idx; g_dev->device->lpVtbl->CreateBuffer(g_dev->device, &bd, &sd, &g_tri->ib); - - engine_set_render_callback(engine, on_render); - engine_set_key_callback(engine, on_key); - LOG_INFO("Running..."); - engine_run(engine); - - mesh_destroy(g_tri); - shader_destroy(g_shader); - glyph_atlas_destroy(&g_atlas); - graphics_device_destroy(g_dev); - engine_shutdown(engine); - return 0; -} diff --git a/Demo/cube_dodge.c b/Demo/cube_dodge.c deleted file mode 100644 index 0c72719..0000000 --- a/Demo/cube_dodge.c +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include -#include -#include -#include - -typedef struct { float p[3], n[3], u[2], c[4]; } V3D; -static ID3D11Device* g_dev; static ID3D11DeviceContext* g_ctx; -static IDXGISwapChain* g_sc; static ID3D11RenderTargetView* g_rtv; -static ID3D11VertexShader* g_vs; static ID3D11PixelShader* g_ps; -static ID3D11InputLayout* g_il; static ID3D11Buffer* g_cb; - -static int key_l=0,key_r=0,key_u=0,key_d=0,key_sp=0; -static int dead=0, score=0; -static float px=0, py=0, speed=0.4f; -#define NOBS 15 -static float ox[NOBS],oy[NOBS],oz[NOBS],osz[NOBS]; -static int oa[NOBS],oc=0; static float st=0; - -static void Init(HWND h){ - HRESULT hr;DXGI_SWAP_CHAIN_DESC sd;memset(&sd,0,sizeof(sd));sd.BufferCount=2;sd.BufferDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM;sd.BufferDesc.RefreshRate.Numerator=60;sd.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT;sd.OutputWindow=h;sd.SampleDesc.Count=1;sd.Windowed=TRUE;sd.SwapEffect=DXGI_SWAP_EFFECT_DISCARD; - D3D_FEATURE_LEVEL fl=D3D_FEATURE_LEVEL_11_0,gt;hr=D3D11CreateDeviceAndSwapChain(NULL,D3D_DRIVER_TYPE_HARDWARE,NULL,0,&fl,1,D3D11_SDK_VERSION,&sd,&g_sc,&g_dev,>,&g_ctx);if(FAILED(hr))return; - ID3D11Texture2D*bb=NULL;hr=g_sc->lpVtbl->GetBuffer(g_sc,0,&IID_ID3D11Texture2D,(void**)&bb);if(FAILED(hr)||!bb)return;hr=g_dev->lpVtbl->CreateRenderTargetView(g_dev,(ID3D11Resource*)bb,NULL,&g_rtv);bb->lpVtbl->Release(bb);if(FAILED(hr))return; - const char*vs="cbuffer CB:register(b0){float4x4 WVP;};struct I{float3 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};struct O{float4 p:SV_POSITION;float4 c:COLOR;};O main(I i){O o;o.p=mul(float4(i.p,1),WVP);o.c=i.c;return o;}"; - const char*ps="float4 main(float4 p:SV_POSITION, float4 c:COLOR):SV_Target{return c;}"; - ID3DBlob*b1,*b2,*e;D3DCompile(vs,(UINT)strlen(vs),NULL,NULL,NULL,"main","vs_5_0",0,0,&b1,&e);if(e){e->lpVtbl->Release(e);e=NULL;}D3DCompile(ps,(UINT)strlen(ps),NULL,NULL,NULL,"main","ps_5_0",0,0,&b2,&e);if(e){e->lpVtbl->Release(e);e=NULL;}if(!b1||!b2)return; - g_dev->lpVtbl->CreateVertexShader(g_dev,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),NULL,&g_vs);g_dev->lpVtbl->CreatePixelShader(g_dev,b2->lpVtbl->GetBufferPointer(b2),b2->lpVtbl->GetBufferSize(b2),NULL,&g_ps); - D3D11_INPUT_ELEMENT_DESC el[4];memset(el,0,sizeof(el));el[0].SemanticName="POSITION";el[0].Format=DXGI_FORMAT_R32G32B32_FLOAT;el[0].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA;el[1].SemanticName="NORMAL";el[1].AlignedByteOffset=12;el[1].Format=DXGI_FORMAT_R32G32B32_FLOAT;el[1].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA;el[2].SemanticName="TEXCOORD";el[2].AlignedByteOffset=24;el[2].Format=DXGI_FORMAT_R32G32_FLOAT;el[2].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA;el[3].SemanticName="COLOR";el[3].AlignedByteOffset=32;el[3].Format=DXGI_FORMAT_R32G32B32A32_FLOAT;el[3].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA; - g_dev->lpVtbl->CreateInputLayout(g_dev,el,4,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),&g_il);b1->lpVtbl->Release(b1);b2->lpVtbl->Release(b2); - D3D11_BUFFER_DESC cbd;memset(&cbd,0,sizeof(cbd));cbd.ByteWidth=256;cbd.Usage=D3D11_USAGE_DEFAULT;cbd.BindFlags=D3D11_BIND_CONSTANT_BUFFER;g_dev->lpVtbl->CreateBuffer(g_dev,&cbd,NULL,&g_cb); -} - -static void Cube(float cx,float cy,float cz,float s,float cr,float cg,float cb){ - V3D v[24];float f[6][4][3]={{{-1,-1,-1},{1,-1,-1},{1,1,-1},{-1,1,-1}},{{1,-1,-1},{1,-1,1},{1,1,1},{1,1,-1}},{{1,-1,1},{-1,-1,1},{-1,1,1},{1,1,1}},{{-1,-1,1},{-1,-1,-1},{-1,1,-1},{-1,1,1}},{{-1,1,-1},{1,1,-1},{1,1,1},{-1,1,1}},{{-1,-1,1},{1,-1,1},{1,-1,-1},{-1,-1,-1}}};float nm[6][3]={{0,0,-1},{1,0,0},{0,0,1},{-1,0,0},{0,1,0},{0,-1,0}}; - for(int fi=0;fi<6;fi++)for(int vi=0;vi<4;vi++){int i=fi*4+vi;v[i].p[0]=f[fi][vi][0]*s+cx;v[i].p[1]=f[fi][vi][1]*s+cy;v[i].p[2]=f[fi][vi][2]*s+cz;v[i].n[0]=nm[fi][0];v[i].n[1]=nm[fi][1];v[i].n[2]=nm[fi][2];v[i].c[0]=cr;v[i].c[1]=cg;v[i].c[2]=cb;v[i].c[3]=1;} - uint32_t ix[36];for(int fi=0;fi<6;fi++){int b=fi*4;ix[fi*6]=b;ix[fi*6+1]=b+1;ix[fi*6+2]=b+2;ix[fi*6+3]=b;ix[fi*6+4]=b+2;ix[fi*6+5]=b+3;} - ID3D11Buffer*vb,*ib;D3D11_BUFFER_DESC bd;D3D11_SUBRESOURCE_DATA sd;memset(&bd,0,sizeof(bd));memset(&sd,0,sizeof(sd));bd.ByteWidth=sizeof(V3D)*24;bd.Usage=D3D11_USAGE_DEFAULT;bd.BindFlags=D3D11_BIND_VERTEX_BUFFER;sd.pSysMem=v;g_dev->lpVtbl->CreateBuffer(g_dev,&bd,&sd,&vb);bd.ByteWidth=sizeof(uint32_t)*36;bd.BindFlags=D3D11_BIND_INDEX_BUFFER;sd.pSysMem=ix;g_dev->lpVtbl->CreateBuffer(g_dev,&bd,&sd,&ib); - UINT s2=sizeof(V3D),o=0;g_ctx->lpVtbl->IASetVertexBuffers(g_ctx,0,1,&vb,&s2,&o);g_ctx->lpVtbl->IASetIndexBuffer(g_ctx,ib,DXGI_FORMAT_R32_UINT,0);g_ctx->lpVtbl->DrawIndexed(g_ctx,36,0,0);ib->lpVtbl->Release(ib);vb->lpVtbl->Release(vb); -} - -static void Spawn(void){for(int i=0;i1.3f)px=1.3f;if(py<-0.9f)py=-0.9f;if(py>0.9f)py=0.9f; - st+=dt;if(st>0.6f/speed){Spawn();st=0;} - for(int i=0;i2.0f)speed=2.0f;} - float dx=px>ox[i]?px-ox[i]:ox[i]-px;float dy=py>oy[i]?py-oy[i]:oy[i]-py;float dz=1.5f>oz[i]?1.5f-oz[i]:oz[i]-1.5f; - float md=0.12f+osz[i];if(dxlpVtbl->OMSetRenderTargets(g_ctx,1,&g_rtv,NULL);g_ctx->lpVtbl->ClearRenderTargetView(g_ctx,g_rtv,cl); - D3D11_VIEWPORT vp;memset(&vp,0,sizeof(vp));vp.Width=1280;vp.Height=720;vp.MaxDepth=1;g_ctx->lpVtbl->RSSetViewports(g_ctx,1,&vp); - D3D11_RASTERIZER_DESC rd;memset(&rd,0,sizeof(rd));rd.FillMode=D3D11_FILL_SOLID;rd.CullMode=D3D11_CULL_NONE;ID3D11RasterizerState*rs;g_dev->lpVtbl->CreateRasterizerState(g_dev,&rd,&rs);g_ctx->lpVtbl->RSSetState(g_ctx,rs); - D3D11_DEPTH_STENCIL_DESC ds;memset(&ds,0,sizeof(ds));ds.DepthEnable=FALSE;ID3D11DepthStencilState*dss;g_dev->lpVtbl->CreateDepthStencilState(g_dev,&ds,&dss);g_ctx->lpVtbl->OMSetDepthStencilState(g_ctx,dss,0); - g_ctx->lpVtbl->IASetPrimitiveTopology(g_ctx,D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);g_ctx->lpVtbl->VSSetShader(g_ctx,g_vs,NULL,0);g_ctx->lpVtbl->PSSetShader(g_ctx,g_ps,NULL,0);g_ctx->lpVtbl->IASetInputLayout(g_ctx,g_il);g_ctx->lpVtbl->VSSetConstantBuffers(g_ctx,0,1,&g_cb);g_ctx->lpVtbl->UpdateSubresource(g_ctx,(ID3D11Resource*)g_cb,0,NULL,mvp,0,0); - - if(dead){Cube(0,0,1.5f,0.4f,.9f,.1f,.1f);} - else{ - Cube(px,py,1.5f,0.12f,.1f,.9f,.3f); - for(int i=0;ilpVtbl->Release(rs);if(dss)dss->lpVtbl->Release(dss);g_sc->lpVtbl->Present(g_sc,1,0); -} - -static LRESULT CALLBACK WP(HWND h,UINT m,WPARAM w,LPARAM l){switch(m){case WM_KEYDOWN:switch(w){case VK_LEFT:key_l=1;break;case VK_RIGHT:key_r=1;break;case VK_UP:key_u=1;break;case VK_DOWN:key_d=1;break;case 'A':key_l=1;break;case 'D':key_r=1;break;case 'W':key_u=1;break;case 'S':key_d=1;break;case VK_SPACE:key_sp=1;break;case VK_ESCAPE:PostQuitMessage(0);break;}break;case WM_KEYUP:switch(w){case VK_LEFT:key_l=0;break;case VK_RIGHT:key_r=0;break;case VK_UP:key_u=0;break;case VK_DOWN:key_d=0;break;case 'A':key_l=0;break;case 'D':key_r=0;break;case 'W':key_u=0;break;case 'S':key_d=0;break;case VK_SPACE:key_sp=0;break;}break;case WM_DESTROY:PostQuitMessage(0);return 0;}return DefWindowProcW(h,m,w,l);} - -int WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int){srand(42);WNDCLASSEXW wc;memset(&wc,0,sizeof(wc));wc.cbSize=sizeof(wc);wc.style=CS_CLASSDC;wc.lpfnWndProc=WP;wc.hInstance=hI;wc.lpszClassName=L"dodge";RegisterClassExW(&wc);HWND hwnd=CreateWindowW(L"dodge",L"Cube Dodge - WASD/Arrows move, Space restart",WS_OVERLAPPEDWINDOW,200,100,1280,720,NULL,NULL,hI,NULL);if(!hwnd)return -1;ShowWindow(hwnd,SW_SHOW);UpdateWindow(hwnd);Init(hwnd);MSG msg;while(1){while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);if(msg.message==WM_QUIT)goto done;}Frame();}done:if(g_cb)g_cb->lpVtbl->Release(g_cb);if(g_il)g_il->lpVtbl->Release(g_il);if(g_vs)g_vs->lpVtbl->Release(g_vs);if(g_ps)g_ps->lpVtbl->Release(g_ps);if(g_rtv)g_rtv->lpVtbl->Release(g_rtv);if(g_sc)g_sc->lpVtbl->Release(g_sc);if(g_ctx)g_ctx->lpVtbl->Release(g_ctx);if(g_dev)g_dev->lpVtbl->Release(g_dev);return 0;} diff --git a/Demo/d3d11_test.c b/Demo/d3d11_test.c deleted file mode 100644 index 5dbef4b..0000000 --- a/Demo/d3d11_test.c +++ /dev/null @@ -1,95 +0,0 @@ -// 独立 D3D11 测试 - 不依赖引擎框架 -#include -#include -#include -#include - -#pragma comment(lib, "d3d11.lib") -#pragma comment(lib, "dxgi.lib") - -static ID3D11Device* device = NULL; -static ID3D11DeviceContext* context = NULL; -static IDXGISwapChain* swap_chain = NULL; -static ID3D11RenderTargetView* rtv = NULL; - -static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (msg == WM_DESTROY) { PostQuitMessage(0); return 0; } - return DefWindowProcW(hwnd, msg, wParam, lParam); -} - -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { - (void)hPrevInstance; (void)lpCmdLine; (void)nCmdShow; - - // 注册窗口类 - WNDCLASSEXW wc = {0}; - wc.cbSize = sizeof(WNDCLASSEXW); - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = WndProc; - wc.hInstance = hInstance; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.lpszClassName = L"D3D11Test"; - RegisterClassExW(&wc); - - // 创建窗口 - HWND hwnd = CreateWindowExW(0, L"D3D11Test", L"D3D11 Test", - WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, - NULL, NULL, hInstance, NULL); - ShowWindow(hwnd, SW_SHOW); - UpdateWindow(hwnd); - - // 创建 D3D11 设备和交换链 - DXGI_SWAP_CHAIN_DESC scd = {0}; - scd.BufferCount = 1; - scd.BufferDesc.Width = 800; - scd.BufferDesc.Height = 600; - scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - scd.BufferDesc.RefreshRate.Numerator = 60; - scd.BufferDesc.RefreshRate.Denominator = 1; - scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - scd.OutputWindow = hwnd; - scd.SampleDesc.Count = 1; - scd.Windowed = TRUE; - scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - - D3D_FEATURE_LEVEL levels[] = {D3D_FEATURE_LEVEL_11_0}; - HRESULT hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, levels, 1, D3D11_SDK_VERSION, &scd, &swap_chain, &device, NULL, &context); - - if (FAILED(hr)) { - MessageBoxW(hwnd, L"D3D11 CreateDevice Failed!", L"Error", MB_OK); - return -1; - } - - // 创建渲染目标 - ID3D11Texture2D* back_buffer = NULL; - swap_chain->lpVtbl->GetBuffer(swap_chain, 0, &IID_ID3D11Texture2D, (void**)&back_buffer); - device->lpVtbl->CreateRenderTargetView(device, (ID3D11Resource*)back_buffer, NULL, &rtv); - back_buffer->lpVtbl->Release(back_buffer); - - // 设置渲染目标 - context->lpVtbl->OMSetRenderTargets(context, 1, &rtv, NULL); - - // 主循环 - MSG msg = {0}; - while (msg.message != WM_QUIT) { - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - if (msg.message == WM_QUIT) break; - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - // 清屏 - 蓝色 - float color[4] = {0.2f, 0.5f, 0.8f, 1.0f}; - context->lpVtbl->ClearRenderTargetView(context, rtv, color); - - // 呈现 - swap_chain->lpVtbl->Present(swap_chain, 0, 0); - } - - // 清理 - rtv->lpVtbl->Release(rtv); - swap_chain->lpVtbl->Release(swap_chain); - context->lpVtbl->Release(context); - device->lpVtbl->Release(device); - - return 0; -} diff --git a/Demo/demo_rpg.py b/Demo/demo_rpg.py deleted file mode 100644 index 64036b3..0000000 --- a/Demo/demo_rpg.py +++ /dev/null @@ -1,105 +0,0 @@ -"""LityPy Demo - 3D 开放世界 RPG""" -from lity import * - -scene = Scene("LityPy RPG Demo", 1280, 720) -camera = Camera() - -# 地面 -ground = create_ground(scene, 60, Color(0.25, 0.5, 0.2)) - -# 玩家 -player = scene.create("hero", "cube", pos=Vec3(0, 0.5, 0), color=Color.GREEN) -player.speed = 5.0 -player.add_rigidbody() -player.add_collider(size=Vec3(0.5, 1, 0.5)) - -# 村庄建筑 -walls = [ - create_building(scene, -5, -5, 2, 2, 2, Color.RED, Color.GRAY), - create_building(scene, 3, -6, 2.5, 2.5, 2, Color.BLUE, Color.GRAY), - create_building(scene, -2, -8, 1.8, 1.8, 1.8, Color.YELLOW, Color(0.45, 0.28, 0.15)), - create_building(scene, 6, -3, 2, 3, 2, Color.ORANGE, Color.GRAY), -] - -# NPC -npc1 = scene.create("merchant", "cube", pos=Vec3(1, 0.4, -4), color=Color.CYAN, tags=["npc"]) -npc1.dialog = "欢迎来到村庄!" -npc2 = scene.create("guard", "cube", pos=Vec3(-4, 0.4, -3), color=Color.MAGENTA, tags=["npc"]) -npc2.dialog = "小心森林里的怪物!" - -# 树木 -for i in range(25): - x, z = rand(-25, 25), rand(-25, 25) - if abs(x) < 8 and abs(z) < 10: continue - create_tree(scene, x, z) - -# 岩石 -for i in range(10): - x, z = rand(-25, 25), rand(-25, 25) - scene.create(f"rock_{i}", "sphere", pos=Vec3(x, 0.3, z), - scale=Vec3(rand(0.3, 0.8), rand(0.2, 0.5), rand(0.3, 0.8)), - color=Color(0.5, 0.5, 0.5)) - -# 花 -for i in range(15): - x, z = rand(-10, 10), rand(-10, 10) - c = Color(rand(0.6, 1), rand(0.1, 0.5), rand(0.1, 0.5)) - scene.create(f"flower_{i}", "sphere", pos=Vec3(x, 0.15, z), - scale=Vec3(0.1, 0.1, 0.1), color=c) - -# 水塘 -scene.create("water", "plane", pos=Vec3(-8, 0.05, -3), - scale=Vec3(4, 1, 4), color=Color(0.15, 0.3, 0.6, 0.8)) - -# 远山 -for i, (x, z, sx, sy, sz) in enumerate([ - (-20, 15, 8, 3, 8), (22, 12, 10, 4, 10), (0, 25, 12, 3, 8) -]): - scene.create(f"hill_{i}", "sphere", pos=Vec3(x, -0.5, z), - scale=Vec3(sx, sy, sz), color=Color(0.2, 0.4, 0.18)) - -# 敌人 -enemies = [] -for i in range(8): - x, z = rand(-20, 20), rand(5, 20) - e = scene.create(f"enemy_{i}", "sphere", pos=Vec3(x, 0.5, z), - color=Color(0.8, 0.2, 0.1), tags=["enemy"]) - e.hp = 100 - e.speed = 2.0 - e.patrol_center = Vec3(x, 0.5, z) - enemies.append(e) - -# ===== 游戏逻辑 ===== -score = 0 -hp = 100 - -@scene.on_frame -def update(dt): - global score, hp - camera.follow(player, offset=Vec3(0, 4, -8), smooth=3.0 * dt) - - for e in enemies: - d = e.pos.distance(player.pos) - if d < 15: - to_player = (player.pos - e.pos).normalize() - e.pos = e.pos + to_player * e.speed * dt - e.rot = Vec3(0, math.atan2(to_player.x, to_player.z), 0) - if d < 8: - e.pos = e.pos.lerp(e.patrol_center, dt * 0.5) - -# 导出场景 -export_scene_ly(scene, "rpg_scene.ly") -scene.save("rpg_scene.json") - -print(f"\n=== LityPy RPG Demo ===") -print(f"场景: {len(scene.entities)} 个实体") -print(f"玩家: {player.pos}") -print(f"敌人: {len(enemies)} 个") -print(f"建筑: {len(walls)} 栋") -print(f"\n特性展示:") -print(f" Vec3: {Vec3(1,2,3) + Vec3(4,5,6)}") -print(f" Color.from_hex: {Color.from_hex('#FF5500')}") -print(f" lerp: {lerp(0, 10, 0.3)}") -print(f" rand: {rand(0, 100):.2f}") -print(f" sin: {math.sin(time_s()):.4f}") -print(f"\n引擎 API 已就绪,需要编译 C 端集成。") diff --git a/Demo/editor_main.c b/Demo/editor_main.c deleted file mode 100644 index b7d1b6d..0000000 --- a/Demo/editor_main.c +++ /dev/null @@ -1,682 +0,0 @@ -#include "../Engine/Core/engine.h" -#include "../Engine/Core/logger.h" -#include "../Engine/Core/asset_manager.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/renderer.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Rendering/material.h" -#include "../Engine/Rendering/mesh.h" -#include "../Engine/Rendering/camera.h" -#include "../Engine/Scene/scene_graph.h" -#include "../Engine/Scene/scene_render.h" -#include "../Engine/Scene/scene_serialize.h" -#include "../Engine/Editor/glyph_atlas.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" -#include -#include -#include -#include -#include - -/* -------------------------------------------------------------------------- */ -/* Editor state */ -/* -------------------------------------------------------------------------- */ -static Engine* g_engine = NULL; -static GraphicsDevice* g_gdev = NULL; -static Renderer* g_renderer = NULL; -static AssetManager* g_assets = NULL; -static Asset* g_shader_asset = NULL; -static Scene* g_scene = NULL; -static Camera g_camera; - -static GlyphAtlas g_atlas; -static int g_atlas_ok = 0; - -static SceneNode* g_selected = NULL; -static int g_mouse_x = 0; -static int g_mouse_y = 0; -static int g_mouse_down[3] = {0}; -static int g_mouse_last_x = 0; -static int g_mouse_last_y = 0; -static int g_camera_drag = 0; - -static char g_console[16][256]; -static int g_console_count = 0; -static char g_status[256] = ""; - -/* UI metrics */ -#define ED_MENU_H 30 -#define ED_TOOLBAR_H 30 -#define ED_LEFT_W 240 -#define ED_RIGHT_W 260 -#define ED_BOTTOM_H 180 -#define ED_SPLITTER 1 - -/* UI D3D resources */ -static ID3D11DepthStencilState* g_ui_depth = NULL; -static ID3D11RasterizerState* g_ui_raster = NULL; -static ID3D11BlendState* g_ui_blend = NULL; -static ID3D11SamplerState* g_ui_sampler = NULL; -static ID3D11Buffer* g_ui_cb = NULL; -static ID3D11VertexShader* g_ui_vs = NULL; -static ID3D11PixelShader* g_ui_ps = NULL; -static ID3D11InputLayout* g_ui_layout = NULL; -static ID3D11VertexShader* g_text_vs = NULL; -static ID3D11PixelShader* g_text_ps = NULL; -static ID3D11InputLayout* g_text_layout = NULL; - -typedef struct { float p[3], n[3], uv[2], c[4]; } UIVertex; - -/* -------------------------------------------------------------------------- */ -/* Console */ -/* -------------------------------------------------------------------------- */ -static void console_add(const char* msg) { - if (g_console_count >= 16) { - for (int i = 0; i < 15; i++) strcpy(g_console[i], g_console[i+1]); - g_console_count = 15; - } - strncpy(g_console[g_console_count], msg, 255); - g_console[g_console_count][255] = 0; - g_console_count++; -} - -/* -------------------------------------------------------------------------- */ -/* Shader helpers */ -/* -------------------------------------------------------------------------- */ -static ID3DBlob* compile_blob(const char* code, const char* target) { - ID3DBlob *blob = NULL, *err = NULL; - D3DCompile(code, strlen(code), NULL, NULL, NULL, "main", target, - D3DCOMPILE_OPTIMIZATION_LEVEL3 | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR, 0, &blob, &err); - if (err) { - LOG_ERROR("Editor shader compile (%s): %s", target, (char*)err->lpVtbl->GetBufferPointer(err)); - err->lpVtbl->Release(err); - } - return blob; -} - -static int compile_ui_shaders(ID3D11Device* dev) { - const char* vs = - "cbuffer CB:register(b0){float4x4 WVP;};" - "struct I{float4 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};" - "struct O{float4 p:SV_POSITION;float2 u:TEXCOORD;float4 c:COLOR;};" - "O main(I i){O o;o.p=mul(i.p,WVP);o.u=i.u;o.c=i.c;return o;}"; - const char* ps = - "struct O{float4 p:SV_POSITION;float2 u:TEXCOORD;float4 c:COLOR;};" - "float4 main(O i):SV_TARGET{return i.c;}"; - const char* tps = - "Texture2D t:register(t0);SamplerState s:register(s0);" - "struct O{float4 p:SV_POSITION;float2 u:TEXCOORD;float4 c:COLOR;};" - "float4 main(O i):SV_TARGET{float a=t.Sample(s,i.u).a;return float4(i.c.rgb,i.c.a*a);}"; - - ID3DBlob *b1 = compile_blob(vs, "vs_5_0"), *b2 = compile_blob(ps, "ps_5_0"), *b3 = compile_blob(tps, "ps_5_0"); - if (!b1 || !b2 || !b3) return 0; - - dev->lpVtbl->CreateVertexShader(dev, b1->lpVtbl->GetBufferPointer(b1), b1->lpVtbl->GetBufferSize(b1), NULL, &g_ui_vs); - dev->lpVtbl->CreatePixelShader(dev, b2->lpVtbl->GetBufferPointer(b2), b2->lpVtbl->GetBufferSize(b2), NULL, &g_ui_ps); - dev->lpVtbl->CreatePixelShader(dev, b3->lpVtbl->GetBufferPointer(b3), b3->lpVtbl->GetBufferSize(b3), NULL, &g_text_ps); - - D3D11_INPUT_ELEMENT_DESC layout[] = { - {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}, - }; - dev->lpVtbl->CreateInputLayout(dev, layout, 4, b1->lpVtbl->GetBufferPointer(b1), b1->lpVtbl->GetBufferSize(b1), &g_ui_layout); - g_text_layout = g_ui_layout; - g_text_vs = g_ui_vs; - - b1->lpVtbl->Release(b1); b2->lpVtbl->Release(b2); b3->lpVtbl->Release(b3); - return g_ui_vs && g_ui_ps && g_text_ps && g_ui_layout; -} - -static void create_ui_states(ID3D11Device* dev) { - D3D11_DEPTH_STENCIL_DESC dsd = {0}; - dsd.DepthEnable = FALSE; dsd.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - dev->lpVtbl->CreateDepthStencilState(dev, &dsd, &g_ui_depth); - - D3D11_RASTERIZER_DESC rd = {0}; - rd.FillMode = D3D11_FILL_SOLID; rd.CullMode = D3D11_CULL_NONE; - dev->lpVtbl->CreateRasterizerState(dev, &rd, &g_ui_raster); - - D3D11_BLEND_DESC bd = {0}; - bd.RenderTarget[0].BlendEnable = TRUE; - bd.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - bd.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - bd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - bd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - bd.RenderTarget[0].BlendOp = bd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - bd.RenderTarget[0].RenderTargetWriteMask = 0x0F; - dev->lpVtbl->CreateBlendState(dev, &bd, &g_ui_blend); - - D3D11_SAMPLER_DESC sd = {0}; - sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - sd.AddressU = sd.AddressV = sd.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - dev->lpVtbl->CreateSamplerState(dev, &sd, &g_ui_sampler); - - D3D11_BUFFER_DESC cbd = {0}; - cbd.ByteWidth = 256; cbd.Usage = D3D11_USAGE_DEFAULT; cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - dev->lpVtbl->CreateBuffer(dev, &cbd, NULL, &g_ui_cb); -} - -/* -------------------------------------------------------------------------- */ -/* UI rendering */ -/* -------------------------------------------------------------------------- */ -static void ui_set_projection(ID3D11DeviceContext* ctx, float sw, float sh) { - float proj[16] = {0}; - proj[0] = 2.0f / sw; proj[5] = -2.0f / sh; - proj[10] = 1.0f; proj[12] = -1.0f; proj[13] = 1.0f; proj[15] = 1.0f; - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)g_ui_cb, 0, NULL, proj, 0, 0); -} - -static void ui_setup_solid(ID3D11DeviceContext* ctx) { - ctx->lpVtbl->VSSetShader(ctx, g_ui_vs, NULL, 0); - ctx->lpVtbl->PSSetShader(ctx, g_ui_ps, NULL, 0); - ctx->lpVtbl->IASetInputLayout(ctx, g_ui_layout); - ctx->lpVtbl->VSSetConstantBuffers(ctx, 0, 1, &g_ui_cb); - ctx->lpVtbl->OMSetBlendState(ctx, NULL, NULL, 0xFFFFFFFF); -} - -static void ui_setup_text(ID3D11DeviceContext* ctx) { - ctx->lpVtbl->VSSetShader(ctx, g_text_vs, NULL, 0); - ctx->lpVtbl->PSSetShader(ctx, g_text_ps, NULL, 0); - ctx->lpVtbl->IASetInputLayout(ctx, g_text_layout); - ctx->lpVtbl->VSSetConstantBuffers(ctx, 0, 1, &g_ui_cb); - ctx->lpVtbl->PSSetShaderResources(ctx, 0, 1, &g_atlas.srv); - ctx->lpVtbl->PSSetSamplers(ctx, 0, 1, &g_ui_sampler); - ctx->lpVtbl->OMSetBlendState(ctx, g_ui_blend, NULL, 0xFFFFFFFF); -} - -static void ui_begin(ID3D11DeviceContext* ctx, float sw, float sh) { - D3D11_VIEWPORT vp = {0}; - vp.Width = sw; vp.Height = sh; vp.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vp); - ctx->lpVtbl->RSSetState(ctx, g_ui_raster); - ctx->lpVtbl->OMSetDepthStencilState(ctx, g_ui_depth, 0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ui_set_projection(ctx, sw, sh); - ui_setup_solid(ctx); -} - -static void draw_quad(ID3D11DeviceContext* ctx, float x, float y, float w, float h, - float r, float g, float b, float a) { - UIVertex v[4] = { - {{x, y, 0},{0,0,-1},{0,0},{r,g,b,a}}, - {{x+w, y, 0},{0,0,-1},{1,0},{r,g,b,a}}, - {{x+w, y+h, 0},{0,0,-1},{1,1},{r,g,b,a}}, - {{x, y+h, 0},{0,0,-1},{0,1},{r,g,b,a}}, - }; - uint32_t idx[6] = {0,1,2, 0,2,3}; - ID3D11Buffer *vb = NULL, *ib = NULL; - D3D11_BUFFER_DESC bd = {0}; D3D11_SUBRESOURCE_DATA sd = {0}; - bd.ByteWidth = sizeof(UIVertex)*4; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = v; g_gdev->device->lpVtbl->CreateBuffer(g_gdev->device, &bd, &sd, &vb); - bd.ByteWidth = sizeof(uint32_t)*6; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = idx; g_gdev->device->lpVtbl->CreateBuffer(g_gdev->device, &bd, &sd, &ib); - UINT stride = sizeof(UIVertex), offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &vb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, ib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->DrawIndexed(ctx, 6, 0, 0); - if (ib) ib->lpVtbl->Release(ib); - if (vb) vb->lpVtbl->Release(vb); -} - -static void draw_text(ID3D11DeviceContext* ctx, const wchar_t* text, int x, int y, - float r, float g, float b, float a) { - if (!g_atlas_ok) return; - ui_setup_text(ctx); - for (const wchar_t* p = text; *p; p++) { - float u0, v0, u1, v1, ax, ay; - if (!glyph_atlas_get_or_create(&g_atlas, g_gdev->device, ctx, *p, &u0, &v0, &u1, &v1, &ax, &ay)) continue; - UIVertex tv[4] = { - {{(float)x, (float)y, 0},{0,0,1},{u0,v0},{r,g,b,a}}, - {{(float)x + ax, (float)y, 0},{0,0,1},{u1,v0},{r,g,b,a}}, - {{(float)x + ax, (float)y + ay, 0},{0,0,1},{u1,v1},{r,g,b,a}}, - {{(float)x, (float)y + ay, 0},{0,0,1},{u0,v1},{r,g,b,a}}, - }; - uint32_t ti[6] = {0,1,2, 0,2,3}; - ID3D11Buffer *tvb = NULL, *tib = NULL; - D3D11_BUFFER_DESC bd = {0}; D3D11_SUBRESOURCE_DATA sd = {0}; - bd.ByteWidth = sizeof(UIVertex)*4; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = tv; g_gdev->device->lpVtbl->CreateBuffer(g_gdev->device, &bd, &sd, &tvb); - bd.ByteWidth = sizeof(uint32_t)*6; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = ti; g_gdev->device->lpVtbl->CreateBuffer(g_gdev->device, &bd, &sd, &tib); - UINT stride = sizeof(UIVertex), offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &tvb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, tib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->DrawIndexed(ctx, 6, 0, 0); - if (tib) tib->lpVtbl->Release(tib); - if (tvb) tvb->lpVtbl->Release(tvb); - x += (int)ax + 1; - } - ui_setup_solid(ctx); -} - -static void draw_text_a(ID3D11DeviceContext* ctx, const char* text, int x, int y, - float r, float g, float b, float a) { - wchar_t buf[256]; - int n = (int)strlen(text); if (n > 255) n = 255; - for (int i = 0; i < n; i++) buf[i] = (wchar_t)text[i]; - buf[n] = 0; - draw_text(ctx, buf, x, y, r, g, b, a); -} - -/* -------------------------------------------------------------------------- */ -/* Scene helpers */ -/* -------------------------------------------------------------------------- */ -static SceneNode* create_primitive(Scene* scene, SceneNode* parent, AssetManager* am, - ID3D11Device* dev, const char* name, MeshType type, - Vec3 pos, Vec3 rot, Vec3 scale, Material* mat) { - SceneNode* node = scene_create_node(scene, name); - if (!node) return NULL; - if (parent) scene_set_parent(node, parent); - node->position = pos; - node->scale = scale; - quat_from_euler(rot.x, rot.y, rot.z, &node->rotation); - - Asset* mesh_asset = asset_manager_load_mesh(am, dev, name); - if (!mesh_asset) { - const char* builtin = NULL; - if (type == MESH_CUBE) builtin = "cube"; - else if (type == MESH_SPHERE) builtin = "sphere"; - else if (type == MESH_PLANE) builtin = "plane"; - if (builtin) mesh_asset = asset_manager_load_mesh(am, dev, builtin); - } - if (mesh_asset && mat) { - MeshRenderer* mr = mesh_renderer_create(type, (Mesh*)asset_data(mesh_asset), mat); - scene_node_set_mesh_renderer(node, mr); - } - return node; -} - -static Scene* create_default_editor_scene(AssetManager* am, ID3D11Device* dev, Shader* shader) { - Scene* scene = (Scene*)malloc(sizeof(Scene)); - if (!scene) return NULL; - scene_init(scene); - strncpy(scene->root->name, "root", sizeof(scene->root->name) - 1); - - Material* mat_red = material_create(shader, NULL); - mat_red->color = (Vec4){1.0f, 0.3f, 0.2f, 1.0f}; - Material* mat_blue = material_create(shader, NULL); - mat_blue->color = (Vec4){0.2f, 0.5f, 1.0f, 1.0f}; - Material* mat_ground = material_create(shader, NULL); - mat_ground->color = (Vec4){0.3f, 0.3f, 0.35f, 1.0f}; - - create_primitive(scene, scene->root, am, dev, "cube", MESH_CUBE, - (Vec3){0,0,0}, (Vec3){0,0,0}, (Vec3){1,1,1}, mat_red); - create_primitive(scene, scene->root, am, dev, "sphere", MESH_SPHERE, - (Vec3){2.0f,0,0}, (Vec3){0,0,0}, (Vec3){0.8f,0.8f,0.8f}, mat_blue); - create_primitive(scene, scene->root, am, dev, "ground", MESH_PLANE, - (Vec3){0,-1.0f,0}, (Vec3){0,0,0}, (Vec3){1,1,1}, mat_ground); - - scene_update(scene); - return scene; -} - -/* -------------------------------------------------------------------------- */ -/* Editor UI */ -/* -------------------------------------------------------------------------- */ -static void draw_panel_bg(ID3D11DeviceContext* ctx, float sw, float sh) { - float body_h = sh - ED_MENU_H - ED_TOOLBAR_H - ED_BOTTOM_H; - - /* menu bar */ - draw_quad(ctx, 0, 0, sw, ED_MENU_H, 0.14f, 0.14f, 0.18f, 1.0f); - /* toolbar */ - draw_quad(ctx, 0, ED_MENU_H, sw, ED_TOOLBAR_H, 0.20f, 0.20f, 0.26f, 1.0f); - /* separators */ - draw_quad(ctx, 0, ED_MENU_H, sw, 1, 0.30f, 0.45f, 0.75f, 1.0f); - draw_quad(ctx, 0, ED_MENU_H + ED_TOOLBAR_H, sw, 1, 0.30f, 0.45f, 0.75f, 1.0f); - /* left panel */ - draw_quad(ctx, 0, ED_MENU_H + ED_TOOLBAR_H + 1, ED_LEFT_W, body_h, 0.18f, 0.18f, 0.23f, 1.0f); - draw_quad(ctx, ED_LEFT_W, ED_MENU_H + ED_TOOLBAR_H + 1, ED_SPLITTER, body_h, 0.30f, 0.45f, 0.75f, 1.0f); - /* right panel */ - draw_quad(ctx, sw - ED_RIGHT_W, ED_MENU_H + ED_TOOLBAR_H + 1, ED_RIGHT_W, body_h, 0.18f, 0.18f, 0.23f, 1.0f); - draw_quad(ctx, sw - ED_RIGHT_W - ED_SPLITTER, ED_MENU_H + ED_TOOLBAR_H + 1, ED_SPLITTER, body_h, 0.30f, 0.45f, 0.75f, 1.0f); - /* bottom console */ - draw_quad(ctx, 0, sh - ED_BOTTOM_H - ED_SPLITTER, sw, ED_SPLITTER, 0.30f, 0.45f, 0.75f, 1.0f); - draw_quad(ctx, 0, sh - ED_BOTTOM_H, sw, ED_BOTTOM_H, 0.16f, 0.16f, 0.21f, 1.0f); - /* status bar */ - draw_quad(ctx, 0, sh - 22, sw, 22, 0.20f, 0.22f, 0.32f, 1.0f); -} - -static void draw_hierarchy(ID3D11DeviceContext* ctx, float sh) { - (void)sh; - int y = ED_MENU_H + ED_TOOLBAR_H + 28; - draw_text(ctx, L"\u573a\u666f\u5c42\u7ea7", 12, y - 20, 0.5f, 0.75f, 1.0f, 1.0f); - if (!g_scene) return; - - for (int i = 1; i < g_scene->node_count; i++) { - SceneNode* node = &g_scene->nodes[i]; - if (node->id < 0) continue; - - int row_y = y + (i - 1) * 22; - if (node == g_selected) - draw_quad(ctx, 4, (float)row_y - 2, ED_LEFT_W - 8, 22, 0.25f, 0.38f, 0.65f, 1.0f); - - wchar_t wn[64]; - int len = (int)strlen(node->name); if (len > 63) len = 63; - for (int j = 0; j < len; j++) wn[j] = (wchar_t)node->name[j]; - wn[len] = 0; - draw_text(ctx, wn, 16, row_y, 1.0f, 1.0f, 1.0f, 1.0f); - } -} - -static void draw_inspector(ID3D11DeviceContext* ctx, float sw, float sh) { - (void)sh; - int x = (int)(sw - ED_RIGHT_W + 12); - int y = ED_MENU_H + ED_TOOLBAR_H + 28; - draw_text(ctx, L"\u5c5e\u6027", x, y - 20, 0.5f, 0.75f, 1.0f, 1.0f); - if (!g_selected) { - draw_text_a(ctx, "未选择对象", x, y, 0.7f, 0.7f, 0.75f, 1.0f); - return; - } - - char buf[128]; - int iy = y; - snprintf(buf, sizeof(buf), "名称: %s", g_selected->name); draw_text_a(ctx, buf, x, iy, 1.0f, 1.0f, 1.0f, 1.0f); iy += 24; - - float rx, ry, rz; - quat_to_euler(&g_selected->rotation, &rx, &ry, &rz); - snprintf(buf, sizeof(buf), "位置: %.2f %.2f %.2f", g_selected->position.x, g_selected->position.y, g_selected->position.z); - draw_text_a(ctx, buf, x, iy, 0.85f, 0.85f, 0.88f, 1.0f); iy += 22; - snprintf(buf, sizeof(buf), "旋转: %.1f %.1f %.1f", rx * 57.2958f, ry * 57.2958f, rz * 57.2958f); - draw_text_a(ctx, buf, x, iy, 0.85f, 0.85f, 0.88f, 1.0f); iy += 22; - snprintf(buf, sizeof(buf), "缩放: %.2f %.2f %.2f", g_selected->scale.x, g_selected->scale.y, g_selected->scale.z); - draw_text_a(ctx, buf, x, iy, 0.85f, 0.85f, 0.88f, 1.0f); iy += 30; - - draw_text_a(ctx, "WASD 平移 | QE 升降", x, iy, 0.6f, 0.7f, 0.85f, 1.0f); iy += 20; - draw_text_a(ctx, "方向键 旋转 | +/- 缩放", x, iy, 0.6f, 0.7f, 0.85f, 1.0f); -} - -static void draw_console(ID3D11DeviceContext* ctx, float sh) { - int y = (int)(sh - ED_BOTTOM_H + 24); - draw_text(ctx, L"\u63a7\u5236\u53f0", 12, y - 18, 0.5f, 0.75f, 1.0f, 1.0f); - int cy = y; - for (int i = g_console_count - 1; i >= 0 && i >= g_console_count - 6; i--) { - wchar_t wl[256]; - int len = (int)strlen(g_console[i]); if (len > 255) len = 255; - for (int j = 0; j < len; j++) wl[j] = (wchar_t)g_console[i][j]; - wl[len] = 0; - draw_text(ctx, wl, 12, cy, 0.75f, 0.75f, 0.80f, 1.0f); - cy += 20; - } -} - -static void draw_ui(ID3D11DeviceContext* ctx, float sw, float sh) { - ui_begin(ctx, sw, sh); - draw_quad(ctx, 0, 0, sw, sh, 0.5f, 0, 0, 0.3f); /* debug overlay */ - draw_panel_bg(ctx, sw, sh); - - /* title / menus */ - draw_text(ctx, L"Lity3D Engine Editor", 12, 7, 0.6f, 0.8f, 1.0f, 1.0f); - const wchar_t* menus[] = {L"\u6587\u4ef6", L"\u7f16\u8f91", L"\u89c6\u56fe", L"\u6784\u5efa", L"\u5e2e\u52a9"}; - int mx = 160; - for (int i = 0; i < 5; i++) { draw_text(ctx, menus[i], mx, 8, 0.9f, 0.9f, 0.92f, 1.0f); mx += 70; } - - draw_hierarchy(ctx, sh); - draw_inspector(ctx, sw, sh); - draw_console(ctx, sh); - - draw_text_a(ctx, g_status, 12, (int)(sh - 18), 0.65f, 0.65f, 0.70f, 1.0f); -} - -/* -------------------------------------------------------------------------- */ -/* Input / interaction */ -/* -------------------------------------------------------------------------- */ -static void update_status(void) { - if (g_selected) { - snprintf(g_status, sizeof(g_status), - "%s | pos(%.2f,%.2f,%.2f) | FOV %.0f | Esc quit | Ctrl+S save", - g_selected->name, - g_selected->position.x, g_selected->position.y, g_selected->position.z, - g_camera.fov_y * 57.2958f); - } else { - snprintf(g_status, sizeof(g_status), "无选中对象 | FOV %.0f | Esc quit | Ctrl+S save", g_camera.fov_y * 57.2958f); - } -} - -static void process_hierarchy_click(int mx, int my) { - float body_top = ED_MENU_H + ED_TOOLBAR_H + 1; - float body_h = (float)g_gdev->height - ED_MENU_H - ED_TOOLBAR_H - ED_BOTTOM_H; - if (mx < 0 || mx > ED_LEFT_W || my < body_top || my > body_top + body_h) return; - - int list_y = ED_MENU_H + ED_TOOLBAR_H + 28; - int idx = (my - list_y + 2) / 22 + 1; - if (idx >= 1 && idx < g_scene->node_count) { - SceneNode* node = &g_scene->nodes[idx]; - if (node->id >= 0) { - g_selected = node; - char buf[128]; snprintf(buf, sizeof(buf), "选中: %s", node->name); - console_add(buf); - update_status(); - } - } -} - -static void on_mouse_move(Engine* engine, int x, int y) { - (void)engine; - g_mouse_x = x; g_mouse_y = y; - - if (g_camera_drag && g_mouse_down[1]) { - float dx = (float)(x - g_mouse_last_x); - float dy = (float)(y - g_mouse_last_y); - camera_rotate_yaw(&g_camera, dx * 0.005f); - camera_rotate_pitch(&g_camera, dy * 0.005f); - g_mouse_last_x = x; g_mouse_last_y = y; - } else if (g_mouse_down[1]) { - g_camera_drag = 1; - g_mouse_last_x = x; g_mouse_last_y = y; - } else { - g_camera_drag = 0; - } -} - -static void on_mouse_button(Engine* engine, int button, int pressed) { - (void)engine; - if (button >= 0 && button < 3) g_mouse_down[button] = pressed; - - if (button == 0 && pressed) { - process_hierarchy_click(g_mouse_x, g_mouse_y); - } -} - -static void on_key(Engine* engine, int key) { - if (key == VK_ESCAPE) { engine_request_quit(engine); return; } - - if (GetAsyncKeyState(VK_CONTROL) & 0x8000) { - if (key == 'S' || key == 's') { - if (scene_save(g_scene, "scene.txt")) { - console_add("已保存 scene.txt"); - } else { - console_add("保存 scene.txt 失败"); - } - return; - } - if (key == 'O' || key == 'o') { - Scene* new_scene = scene_load("scene.txt", g_gdev->device, (Shader*)asset_data(g_shader_asset)); - if (new_scene) { - scene_destroy_renderers(g_scene); - scene_destroy(g_scene); - free(g_scene); - g_scene = new_scene; - g_selected = NULL; - console_add("已加载 scene.txt"); - } else { - console_add("加载 scene.txt 失败"); - } - return; - } - } - - if (!g_selected) return; - - float speed = 0.1f; - if (GetAsyncKeyState(VK_SHIFT) & 0x8000) speed = 0.5f; - - Vec3 pos = g_selected->position; - switch (key) { - case 'W': case 'w': pos.z += speed; break; - case 'S': case 's': pos.z -= speed; break; - case 'A': case 'a': pos.x -= speed; break; - case 'D': case 'd': pos.x += speed; break; - case 'Q': case 'q': pos.y += speed; break; - case 'E': case 'e': pos.y -= speed; break; - default: break; - } - if (pos.x != g_selected->position.x || pos.y != g_selected->position.y || pos.z != g_selected->position.z) { - scene_set_position(g_selected, pos.x, pos.y, pos.z); - } - - float rx, ry, rz; - quat_to_euler(&g_selected->rotation, &rx, &ry, &rz); - int rot_changed = 0; - switch (key) { - case VK_LEFT: ry -= 0.05f; rot_changed = 1; break; - case VK_RIGHT: ry += 0.05f; rot_changed = 1; break; - case VK_UP: rx -= 0.05f; rot_changed = 1; break; - case VK_DOWN: rx += 0.05f; rot_changed = 1; break; - case VK_PRIOR: rz += 0.05f; rot_changed = 1; break; /* PageUp */ - case VK_NEXT: rz -= 0.05f; rot_changed = 1; break; /* PageDown */ - default: break; - } - if (rot_changed) scene_set_rotation_euler(g_selected, rx, ry, rz); - - Vec3 scale = g_selected->scale; - int scale_changed = 0; - switch (key) { - case VK_ADD: scale.x += 0.1f; scale.y += 0.1f; scale.z += 0.1f; scale_changed = 1; break; - case VK_SUBTRACT: scale.x -= 0.1f; scale.y -= 0.1f; scale.z -= 0.1f; scale_changed = 1; break; - default: break; - } - if (scale_changed) scene_set_scale(g_selected, scale.x, scale.y, scale.z); - - update_status(); -} - -static void on_resize(Engine* engine, int width, int height) { - (void)engine; - if (width > 0 && height > 0) { - renderer_resize(g_renderer, width, height); - g_camera.aspect = (float)width / (float)height; - g_camera.dirty = 1; - } -} - -/* -------------------------------------------------------------------------- */ -/* Render callback */ -/* -------------------------------------------------------------------------- */ -static void on_render(Engine* engine) { - (void)engine; - if (!g_renderer || !g_gdev) return; - - renderer_set_view(g_renderer, camera_get_view(&g_camera)); - renderer_set_projection(g_renderer, camera_get_projection(&g_camera)); - - renderer_begin_frame(g_renderer); - if (g_scene) { - scene_update(g_scene); - scene_render(g_scene, g_renderer); - } - - draw_ui(g_gdev->context, (float)g_gdev->width, (float)g_gdev->height); - - renderer_end_frame(g_renderer); - - if (engine->frame_count == 60) { - graphics_device_save_screenshot(g_gdev, "editor_screenshot.bmp"); - console_add("已保存 editor_screenshot.bmp"); - } -} - -static void on_update(Engine* engine, double dt) { - (void)engine; (void)dt; -} - -/* -------------------------------------------------------------------------- */ -/* Main */ -/* -------------------------------------------------------------------------- */ -int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR cmd, int nS) { - (void)hI; (void)hP; (void)nS; - logger_init("engine.log"); - LOG_INFO("=== Lity3D Engine Editor ==="); - - EngineConfig cfg = engine_default_config(); - cfg.app_name = "Lity3D Engine Editor"; - cfg.window_width = 1440; - cfg.window_height = 900; - cfg.vsync = 1; - - g_engine = engine_create(); - if (!engine_init(g_engine, &cfg)) { - LOG_FATAL("Engine init failed"); - return -1; - } - - g_gdev = engine_get_graphics_device(g_engine); - g_renderer = engine_get_renderer(g_engine); - - g_assets = asset_manager_create(); - g_shader_asset = asset_manager_load_shader(g_assets, g_gdev->device, NULL, NULL); - if (!g_shader_asset) { - LOG_FATAL("Shader load failed"); - return -1; - } - Shader* default_shader = (Shader*)asset_data(g_shader_asset); - - g_scene = scene_load("scene.txt", g_gdev->device, default_shader); - if (!g_scene) { - LOG_INFO("Creating default editor scene"); - g_scene = create_default_editor_scene(g_assets, g_gdev->device, default_shader); - scene_save(g_scene, "scene.txt"); - } - - float aspect = (float)cfg.window_width / cfg.window_height; - g_camera = camera_perspective(1.0472f, aspect, 0.1f, 100.0f); - g_camera.position = (Vec3){0, 1.5f, -5.0f}; - g_camera.target = (Vec3){0, 0, 0}; - g_camera.dirty = 1; - - g_atlas_ok = glyph_atlas_init(&g_atlas, g_gdev->device); - if (!g_atlas_ok) LOG_WARN("GlyphAtlas init failed"); - - create_ui_states(g_gdev->device); - if (!compile_ui_shaders(g_gdev->device)) { - LOG_FATAL("UI shader compile failed"); - return -1; - } - - console_add("Lity3D Engine Editor ready"); - console_add("Ctrl+S 保存 | Ctrl+O 加载 | Esc 退出"); - console_add("左键点选层级,右键拖拽旋转视角"); - update_status(); - - engine_set_update_callback(g_engine, on_update); - engine_set_render_callback(g_engine, on_render); - engine_set_key_callback(g_engine, on_key); - engine_set_resize_callback(g_engine, on_resize); - engine_set_mouse_move_callback(g_engine, on_mouse_move); - engine_set_mouse_button_callback(g_engine, on_mouse_button); - - engine_run(g_engine); - - if (g_scene) { - scene_destroy_renderers(g_scene); - scene_destroy(g_scene); - free(g_scene); - } - asset_manager_destroy(g_assets); - - if (g_ui_sampler) g_ui_sampler->lpVtbl->Release(g_ui_sampler); - if (g_ui_blend) g_ui_blend->lpVtbl->Release(g_ui_blend); - if (g_ui_raster) g_ui_raster->lpVtbl->Release(g_ui_raster); - if (g_ui_depth) g_ui_depth->lpVtbl->Release(g_ui_depth); - if (g_ui_cb) g_ui_cb->lpVtbl->Release(g_ui_cb); - if (g_ui_ps) g_ui_ps->lpVtbl->Release(g_ui_ps); - if (g_ui_vs) g_ui_vs->lpVtbl->Release(g_ui_vs); - if (g_ui_layout) g_ui_layout->lpVtbl->Release(g_ui_layout); - if (g_atlas_ok) glyph_atlas_destroy(&g_atlas); - - engine_shutdown(g_engine); - logger_shutdown(); - return 0; -} diff --git a/Demo/game_test.c b/Demo/game_test.c deleted file mode 100644 index 1ecfb4a..0000000 --- a/Demo/game_test.c +++ /dev/null @@ -1,222 +0,0 @@ -#include -#include -#include -#include -#include -#include - -typedef struct { float p[3], n[3], u[2], c[4]; } V3D; - -static ID3D11Device* g_dev = NULL; -static ID3D11DeviceContext* g_ctx = NULL; -static IDXGISwapChain* g_sc = NULL; -static ID3D11RenderTargetView* g_rtv = NULL; -static ID3D11VertexShader* g_vs = NULL; -static ID3D11PixelShader* g_ps = NULL; -static ID3D11InputLayout* g_il = NULL; -static ID3D11Buffer* g_cb = NULL; - -static float cam_x = 0, cam_z = 0; -static int key_w = 0, key_s = 0, key_a = 0, key_d = 0; -static int key_left = 0, key_right = 0; -static int sel = 0; - -static void Init(HWND h) { - HRESULT hr; - DXGI_SWAP_CHAIN_DESC sd; - memset(&sd, 0, sizeof(sd)); - sd.BufferCount = 2; - sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - sd.BufferDesc.RefreshRate.Numerator = 60; - sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - sd.OutputWindow = h; - sd.SampleDesc.Count = 1; - sd.Windowed = TRUE; - sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - D3D_FEATURE_LEVEL fl = D3D_FEATURE_LEVEL_11_0; - D3D_FEATURE_LEVEL got; - hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &fl, 1, - D3D11_SDK_VERSION, &sd, &g_sc, &g_dev, &got, &g_ctx); - if (FAILED(hr)) { return; } - ID3D11Texture2D* bb = NULL; - hr = g_sc->lpVtbl->GetBuffer(g_sc, 0, &IID_ID3D11Texture2D, (void**)&bb); - if (FAILED(hr) || !bb) { return; } - hr = g_dev->lpVtbl->CreateRenderTargetView(g_dev, (ID3D11Resource*)bb, NULL, &g_rtv); - bb->lpVtbl->Release(bb); - if (FAILED(hr)) { return; } - const char* vs_src = - "cbuffer CB:register(b0){float4x4 WVP;};" - "struct I{float3 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};" - "struct O{float4 p:SV_POSITION;float4 c:COLOR;};" - "O main(I i){O o;o.p=mul(float4(i.p,1),WVP);o.c=i.c;return o;}"; - const char* ps_src = - "float4 main(float4 pos:SV_POSITION, float4 col:COLOR):SV_Target{return col;}"; - ID3DBlob *b1 = NULL, *b2 = NULL, *e1 = NULL, *e2 = NULL; - D3DCompile(vs_src, (UINT)strlen(vs_src), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &b1, &e1); - if (e1) { e1->lpVtbl->Release(e1); e1 = NULL; } - D3DCompile(ps_src, (UINT)strlen(ps_src), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &b2, &e2); - if (e2) { e2->lpVtbl->Release(e2); e2 = NULL; } - if (!b1 || !b2) { return; } - g_dev->lpVtbl->CreateVertexShader(g_dev, b1->lpVtbl->GetBufferPointer(b1), b1->lpVtbl->GetBufferSize(b1), NULL, &g_vs); - g_dev->lpVtbl->CreatePixelShader(g_dev, b2->lpVtbl->GetBufferPointer(b2), b2->lpVtbl->GetBufferSize(b2), NULL, &g_ps); - D3D11_INPUT_ELEMENT_DESC el[4]; - memset(el, 0, sizeof(el)); - el[0].SemanticName = "POSITION"; el[0].Format = DXGI_FORMAT_R32G32B32_FLOAT; el[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - el[1].SemanticName = "NORMAL"; el[1].AlignedByteOffset = 12; el[1].Format = DXGI_FORMAT_R32G32B32_FLOAT; el[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - el[2].SemanticName = "TEXCOORD"; el[2].AlignedByteOffset = 24; el[2].Format = DXGI_FORMAT_R32G32_FLOAT; el[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - el[3].SemanticName = "COLOR"; el[3].AlignedByteOffset = 32; el[3].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; el[3].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - g_dev->lpVtbl->CreateInputLayout(g_dev, el, 4, b1->lpVtbl->GetBufferPointer(b1), b1->lpVtbl->GetBufferSize(b1), &g_il); - b1->lpVtbl->Release(b1); b2->lpVtbl->Release(b2); - D3D11_BUFFER_DESC cbd; - memset(&cbd, 0, sizeof(cbd)); - cbd.ByteWidth = 256; cbd.Usage = D3D11_USAGE_DEFAULT; cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - g_dev->lpVtbl->CreateBuffer(g_dev, &cbd, NULL, &g_cb); -} - -static void DrawCube(float cx, float cy, float cz, float s, float cr, float cg, float cb2) { - V3D v[24]; - float f[6][4][3] = { - {{-1,-1,-1},{1,-1,-1},{1,1,-1},{-1,1,-1}}, - {{1,-1,-1},{1,-1,1},{1,1,1},{1,1,-1}}, - {{1,-1,1},{-1,-1,1},{-1,1,1},{1,1,1}}, - {{-1,-1,1},{-1,-1,-1},{-1,1,-1},{-1,1,1}}, - {{-1,1,-1},{1,1,-1},{1,1,1},{-1,1,1}}, - {{-1,-1,1},{1,-1,1},{1,-1,-1},{-1,-1,-1}} - }; - float nm[6][3] = {{0,0,-1},{1,0,0},{0,0,1},{-1,0,0},{0,1,0},{0,-1,0}}; - for (int fi = 0; fi < 6; fi++) - for (int vi = 0; vi < 4; vi++) { - int i = fi * 4 + vi; - v[i].p[0] = f[fi][vi][0] * s + cx; - v[i].p[1] = f[fi][vi][1] * s + cy; - v[i].p[2] = f[fi][vi][2] * s + cz; - v[i].n[0] = nm[fi][0]; v[i].n[1] = nm[fi][1]; v[i].n[2] = nm[fi][2]; - v[i].c[0] = cr; v[i].c[1] = cg; v[i].c[2] = cb2; v[i].c[3] = 1; - } - uint32_t ix[36]; - for (int fi = 0; fi < 6; fi++) { - int b = fi * 4; - ix[fi*6]=b; ix[fi*6+1]=b+1; ix[fi*6+2]=b+2; ix[fi*6+3]=b; ix[fi*6+4]=b+2; ix[fi*6+5]=b+3; - } - ID3D11Buffer *vb = NULL, *ib = NULL; - D3D11_BUFFER_DESC bd; D3D11_SUBRESOURCE_DATA sd; - memset(&bd, 0, sizeof(bd)); memset(&sd, 0, sizeof(sd)); - bd.ByteWidth = sizeof(V3D) * 24; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = v; g_dev->lpVtbl->CreateBuffer(g_dev, &bd, &sd, &vb); - bd.ByteWidth = sizeof(uint32_t) * 36; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = ix; g_dev->lpVtbl->CreateBuffer(g_dev, &bd, &sd, &ib); - UINT s2 = sizeof(V3D), o = 0; - g_ctx->lpVtbl->IASetVertexBuffers(g_ctx, 0, 1, &vb, &s2, &o); - g_ctx->lpVtbl->IASetIndexBuffer(g_ctx, ib, DXGI_FORMAT_R32_UINT, 0); - g_ctx->lpVtbl->DrawIndexed(g_ctx, 36, 0, 0); - ib->lpVtbl->Release(ib); vb->lpVtbl->Release(vb); -} - -static void Frame(void) { - float dt = 0.016f, spd = 3.0f * dt; - if (key_w) cam_z += spd; if (key_s) cam_z -= spd; - if (key_a) cam_x -= spd; if (key_d) cam_x += spd; - if (key_left) sel = (sel + 3) % 4; - if (key_right) sel = (sel + 1) % 4; - - float fov = 1.0f / tanf(0.4f), asp = 1280.0f / 720.0f; - float mvp[16]; memset(mvp, 0, sizeof(mvp)); - mvp[0] = fov / asp; mvp[5] = -fov; mvp[10] = 1; mvp[11] = -1; mvp[14] = 0.1f; mvp[15] = 1; - float m2[16]; memcpy(m2, mvp, 64); - for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { float t = m2[i*4+j]; m2[i*4+j] = m2[j*4+i]; m2[j*4+i] = t; } - - float cl[4] = {.15f, .18f, .25f, 1}; - g_ctx->lpVtbl->OMSetRenderTargets(g_ctx, 1, &g_rtv, NULL); - g_ctx->lpVtbl->ClearRenderTargetView(g_ctx, g_rtv, cl); - D3D11_VIEWPORT vp; memset(&vp, 0, sizeof(vp)); - vp.Width = 1280; vp.Height = 720; vp.MaxDepth = 1; - g_ctx->lpVtbl->RSSetViewports(g_ctx, 1, &vp); - D3D11_RASTERIZER_DESC rd; memset(&rd, 0, sizeof(rd)); - rd.FillMode = D3D11_FILL_SOLID; rd.CullMode = D3D11_CULL_NONE; - ID3D11RasterizerState* rs = NULL; - g_dev->lpVtbl->CreateRasterizerState(g_dev, &rd, &rs); - g_ctx->lpVtbl->RSSetState(g_ctx, rs); - D3D11_DEPTH_STENCIL_DESC ds; memset(&ds, 0, sizeof(ds)); - ds.DepthEnable = FALSE; - ID3D11DepthStencilState* dss = NULL; - g_dev->lpVtbl->CreateDepthStencilState(g_dev, &ds, &dss); - g_ctx->lpVtbl->OMSetDepthStencilState(g_ctx, dss, 0); - g_ctx->lpVtbl->IASetPrimitiveTopology(g_ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - g_ctx->lpVtbl->VSSetShader(g_ctx, g_vs, NULL, 0); - g_ctx->lpVtbl->PSSetShader(g_ctx, g_ps, NULL, 0); - g_ctx->lpVtbl->IASetInputLayout(g_ctx, g_il); - g_ctx->lpVtbl->VSSetConstantBuffers(g_ctx, 0, 1, &g_cb); - g_ctx->lpVtbl->UpdateSubresource(g_ctx, (ID3D11Resource*)g_cb, 0, NULL, m2, 0, 0); - - float colors[4][3] = {{1,.3f,.3f},{.3f,1,.3f},{.3f,.3f,1},{.8f,.8f,.2f}}; - float sizes[4] = {0.3f, 0.25f, 0.2f, 0.35f}; - for (int i = 0; i < 4; i++) { - float cr = colors[i][0], cg = colors[i][1], cb = colors[i][2]; - if (i == sel) { cr = 1; cg = 1; cb = 1; } - DrawCube(-0.8f + i * 0.6f - cam_x, 0, 1.5f - cam_z, sizes[i], cr, cg, cb); - } - - if (rs) rs->lpVtbl->Release(rs); - if (dss) dss->lpVtbl->Release(dss); - g_sc->lpVtbl->Present(g_sc, 1, 0); -} - -static LRESULT CALLBACK WP(HWND h, UINT m, WPARAM w, LPARAM l) { - switch (m) { - case WM_KEYDOWN: - switch (w) { - case 'W': key_w = 1; break; case 'S': key_s = 1; break; - case 'A': key_a = 1; break; case 'D': key_d = 1; break; - case VK_LEFT: key_left = 1; break; case VK_RIGHT: key_right = 1; break; - case '1': sel = 0; break; case '2': sel = 1; break; - case '3': sel = 2; break; case '4': sel = 3; break; - case VK_ESCAPE: PostQuitMessage(0); break; - } - break; - case WM_KEYUP: - switch (w) { - case 'W': key_w = 0; break; case 'S': key_s = 0; break; - case 'A': key_a = 0; break; case 'D': key_d = 0; break; - case VK_LEFT: key_left = 0; break; case VK_RIGHT: key_right = 0; break; - } - break; - case WM_DESTROY: PostQuitMessage(0); return 0; - } - return DefWindowProcW(h, m, w, l); -} - -int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR nC, int nS) { - (void)hP; (void)nC; (void)nS; - WNDCLASSEXW wc; - memset(&wc, 0, sizeof(wc)); - wc.cbSize = sizeof(wc); - wc.style = CS_CLASSDC; - wc.lpfnWndProc = WP; - wc.hInstance = hI; - wc.lpszClassName = L"game_test_cls"; - RegisterClassExW(&wc); - HWND hwnd = CreateWindowW(L"game_test_cls", L"lity3d Game Test", WS_OVERLAPPEDWINDOW, - 100, 100, 1280, 720, NULL, NULL, hI, NULL); - if (!hwnd) { MessageBoxA(NULL, "CreateWindow failed", "Error", MB_OK); return -1; } - ShowWindow(hwnd, SW_SHOW); - UpdateWindow(hwnd); - Init(hwnd); - MSG msg; - while (1) { - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); DispatchMessage(&msg); - if (msg.message == WM_QUIT) goto done; - } - Frame(); - } -done: - if (g_cb) g_cb->lpVtbl->Release(g_cb); - if (g_il) g_il->lpVtbl->Release(g_il); - if (g_vs) g_vs->lpVtbl->Release(g_vs); - if (g_ps) g_ps->lpVtbl->Release(g_ps); - if (g_rtv) g_rtv->lpVtbl->Release(g_rtv); - if (g_sc) g_sc->lpVtbl->Release(g_sc); - if (g_ctx) g_ctx->lpVtbl->Release(g_ctx); - if (g_dev) g_dev->lpVtbl->Release(g_dev); - return 0; -} diff --git a/Demo/input_test.c b/Demo/input_test.c deleted file mode 100644 index 0949bcb..0000000 --- a/Demo/input_test.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "../Engine/Core/engine.h" -#include "../Engine/Window/window.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" -#include - -static GraphicsDevice* g_dev = NULL; -static ID3D11VertexShader* g_vs = NULL; -static ID3D11PixelShader* g_ps = NULL; -static ID3D11InputLayout* g_il = NULL; -static ID3D11Buffer* g_cb = NULL; -static float cam_x=0, cam_z=2, cam_yaw=0; -static float mx=0, my=0; -static int keys[256]={0}; -typedef struct { float p[3],n[3],uv[2],c[4]; } V; - -static void draw_quad(ID3D11DeviceContext* ctx, float x, float y, float z, float s, float r, float g, float b) { - V v[4]={{{x-s,y-s,z},{0,0,-1},{0,0},{r,g,b,1}},{{x+s,y-s,z},{0,0,-1},{1,0},{r,g,b,1}}, - {{x+s,y+s,z},{0,0,-1},{1,1},{r,g,b,1}},{{x-s,y+s,z},{0,0,-1},{0,1},{r,g,b,1}}}; - uint32_t idx[6]={0,1,2,0,2,3}; - ID3D11Buffer *vb=NULL,*ib=NULL; D3D11_BUFFER_DESC bd={}; D3D11_SUBRESOURCE_DATA sd={}; - bd.ByteWidth=sizeof(V)*4; bd.Usage=D3D11_USAGE_DEFAULT; bd.BindFlags=D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem=v; g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd,&sd,&vb); - bd.ByteWidth=sizeof(uint32_t)*6; bd.BindFlags=D3D11_BIND_INDEX_BUFFER; sd.pSysMem=idx; - g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd,&sd,&ib); - UINT s2=sizeof(V),o=0; - ctx->lpVtbl->IASetVertexBuffers(ctx,0,1,&vb,&s2,&o); - ctx->lpVtbl->IASetIndexBuffer(ctx,ib,DXGI_FORMAT_R32_UINT,0); - ctx->lpVtbl->DrawIndexed(ctx,6,0,0); - ib->lpVtbl->Release(ib); vb->lpVtbl->Release(vb); -} - -static void on_render(Engine* engine) { - if(!g_dev) return; - ID3D11DeviceContext* ctx=g_dev->context; - float dt=(float)engine->delta_time, sp=3.0f*dt; - float fx=-sinf(cam_yaw),fz=-cosf(cam_yaw),rx=cosf(cam_yaw),rz=-sinf(cam_yaw); - if(keys['W']){cam_x+=fx*sp;cam_z+=fz*sp;} - if(keys['S']){cam_x-=fx*sp;cam_z-=fz*sp;} - if(keys['A']){cam_x-=rx*sp;cam_z-=rz*sp;} - if(keys['D']){cam_x+=rx*sp;cam_z+=rz*sp;} - - float sw=(float)g_dev->width,sh=(float)g_dev->height; - float fov=1.0f/tanf(0.4f),asp=sw/sh; - float mvp[16]={0}; mvp[0]=fov/asp;mvp[5]=-fov;mvp[10]=1;mvp[11]=-1;mvp[14]=0.1f;mvp[15]=1; - Mat4 pm,pt;memcpy(&pm,mvp,sizeof(Mat4));mat4_transpose(&pm,&pt); - - graphics_device_clear(g_dev,0.12f,0.14f,0.18f,1.0f); - D3D11_VIEWPORT vp={};vp.Width=sw;vp.Height=sh;vp.MaxDepth=1; - ctx->lpVtbl->RSSetViewports(ctx,1,&vp); - D3D11_RASTERIZER_DESC rd={};rd.FillMode=D3D11_FILL_SOLID;rd.CullMode=D3D11_CULL_NONE; - ID3D11RasterizerState*rs=NULL;g_dev->device->lpVtbl->CreateRasterizerState(g_dev->device,&rd,&rs); - ctx->lpVtbl->RSSetState(ctx,rs); - D3D11_DEPTH_STENCIL_DESC dsd={};dsd.DepthEnable=FALSE; - ID3D11DepthStencilState*dss=NULL;g_dev->device->lpVtbl->CreateDepthStencilState(g_dev->device,&dsd,&dss); - ctx->lpVtbl->OMSetDepthStencilState(ctx,dss,0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx,D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ctx->lpVtbl->VSSetShader(ctx,g_vs,NULL,0);ctx->lpVtbl->PSSetShader(ctx,g_ps,NULL,0); - ctx->lpVtbl->IASetInputLayout(ctx,g_il);ctx->lpVtbl->VSSetConstantBuffers(ctx,0,1,&g_cb); - ctx->lpVtbl->UpdateSubresource(ctx,(ID3D11Resource*)g_cb,0,NULL,&pt,0,0); - for(int x=-5;x<=5;x++)for(int z=-5;z<=5;z++){float c=((x+z)%2==0)?.4f:.3f;draw_quad(ctx,(float)x,(float)z,0.5f,0.5f,c,c,c);} - draw_quad(ctx,0,0,0.5f,0.4f,1,0.3f,0.3f);draw_quad(ctx,2,0,0.5f,0.3f,.3f,1,.3f);draw_quad(ctx,-2,0,0.5f,0.3f,.3f,.3f,1);draw_quad(ctx,0,2,0.5f,0.5f,.8f,.8f,.2f); - if(rs)rs->lpVtbl->Release(rs);if(dss)dss->lpVtbl->Release(dss); - graphics_device_present(g_dev); -} -static void on_key(Engine*e,int k){if(k>=0&&k<256)keys[k]=1;if(k==VK_ESCAPE)engine_request_quit(e);} -static void on_mouse_move(int x,int y){cam_yaw+=(x-mx)*0.003f;mx=(float)x;my=(float)y;} -int WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int){ - EngineConfig cfg=engine_default_config();cfg.app_name="lity3d Input Test"; - Engine*e=engine_create();if(!engine_init(e,&cfg))return -1; - g_dev=graphics_device_create(); - if(!graphics_device_init(g_dev,window_get_handle(e->window),cfg.window_width,cfg.window_height,1))return -1; - ID3DBlob*b1=NULL,*b2=NULL,*er=NULL; - const char*vs="cbuffer CB:register(b0){float4x4 WVP;};struct I{float3 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};struct O{float4 p:SV_POSITION;float3 n:NORMAL;float4 c:COLOR;};O main(I i){O o;o.p=mul(float4(i.p,1),WVP);o.n=i.n;o.c=i.c;return o;}"; - const char*ps="struct O{float4 p:SV_POSITION;float3 n:NORMAL;float4 c:COLOR;};float4 main(O i){return i.c;}"; - D3DCompile(vs,(UINT)strlen(vs),NULL,NULL,NULL,"main","vs_5_0",0,0,&b1,&er);if(er){er->lpVtbl->Release(er);er=NULL;} - D3DCompile(ps,(UINT)strlen(ps),NULL,NULL,NULL,"main","ps_5_0",0,0,&b2,&er);if(er){er->lpVtbl->Release(er);er=NULL;} - ID3D11Device*dev=g_dev->device; - dev->lpVtbl->CreateVertexShader(dev,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),NULL,&g_vs); - dev->lpVtbl->CreatePixelShader(dev,b2->lpVtbl->GetBufferPointer(b2),b2->lpVtbl->GetBufferSize(b2),NULL,&g_ps); - D3D11_INPUT_ELEMENT_DESC il[]={{"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0},{"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0},{"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0},{"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}}; - dev->lpVtbl->CreateInputLayout(dev,il,4,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),&g_il);b1->lpVtbl->Release(b1);b2->lpVtbl->Release(b2); - D3D11_BUFFER_DESC cbd={};cbd.ByteWidth=256;cbd.Usage=D3D11_USAGE_DEFAULT;cbd.BindFlags=D3D11_BIND_CONSTANT_BUFFER;dev->lpVtbl->CreateBuffer(dev,&cbd,NULL,&g_cb); - window_set_key_callback(e->window,on_key);window_set_mouse_move_callback(e->window,on_mouse_move); - engine_set_render_callback(e,on_render);engine_run(e); - if(g_vs)g_vs->lpVtbl->Release(g_vs);if(g_ps)g_ps->lpVtbl->Release(g_ps);if(g_il)g_il->lpVtbl->Release(g_il);if(g_cb)g_cb->lpVtbl->Release(g_cb); - graphics_device_destroy(g_dev);engine_shutdown(e);return 0; -} diff --git a/Demo/light_test.c b/Demo/light_test.c deleted file mode 100644 index 01e2692..0000000 --- a/Demo/light_test.c +++ /dev/null @@ -1,142 +0,0 @@ -// light_test.c - 光照系统测试(基ï¿?raw3d_test 已验证模式) -#include "../Engine/Core/engine.h" -#include "../Engine/Window/window.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Rendering/lighting.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" -#include - -static GraphicsDevice* g_dev = NULL; -static Light* g_sun = NULL; -static float g_time = 0; -typedef struct { float p[3],n[3],uv[2],c[4]; } V; - -// 编译带光照的着色器 -static ID3D11VertexShader* g_vs = NULL; -static ID3D11PixelShader* g_ps = NULL; -static ID3D11InputLayout* g_il = NULL; -static ID3D11Buffer* g_cb = NULL; - -static const char* vs_src = - "cbuffer CB:register(b0){float4x4 WVP;};" - "struct I{float3 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};" - "struct O{float4 p:SV_POSITION;float3 n:NORMAL;float4 c:COLOR;};" - "O main(I i){O o;o.p=mul(float4(i.p,1),WVP);o.n=i.n;o.c=i.c;return o;}"; -static const char* ps_src = - "cbuffer Light:register(b1){float3 lightDir;float pad1;float3 lightColor;float intensity;float3 ambColor;float pad2;};" - "struct O{float4 p:SV_POSITION;float3 n:NORMAL;float4 c:COLOR;};" - "float4 main(O i):SV_TARGET{" - "float3 n=normalize(i.n);" - "float diff=max(dot(n,-normalize(lightDir)),0.0);" - "float3 col=i.c.rgb*(ambColor+lightColor*diff*intensity);" - "return float4(col,1.0);}"; - -static void InitShaders() { - ID3DBlob *b1=NULL,*b2=NULL,*e=NULL; - D3DCompile(vs_src,(UINT)strlen(vs_src),NULL,NULL,NULL,"main","vs_5_0",0,0,&b1,&e); - if(e){e->lpVtbl->Release(e);e=NULL;} - D3DCompile(ps_src,(UINT)strlen(ps_src),NULL,NULL,NULL,"main","ps_5_0",0,0,&b2,&e); - if(e){e->lpVtbl->Release(e);e=NULL;} - if(!b1||!b2) return; - ID3D11Device* dev = g_dev->device; - dev->lpVtbl->CreateVertexShader(dev,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),NULL,&g_vs); - dev->lpVtbl->CreatePixelShader(dev,b2->lpVtbl->GetBufferPointer(b2),b2->lpVtbl->GetBufferSize(b2),NULL,&g_ps); - D3D11_INPUT_ELEMENT_DESC il[]={ - {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}, - }; - dev->lpVtbl->CreateInputLayout(dev,il,4,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),&g_il); - b1->lpVtbl->Release(b1); b2->lpVtbl->Release(b2); - D3D11_BUFFER_DESC cbd={}; cbd.ByteWidth=256; cbd.Usage=D3D11_USAGE_DEFAULT; - cbd.BindFlags=D3D11_BIND_CONSTANT_BUFFER; - dev->lpVtbl->CreateBuffer(dev,&cbd,NULL,&g_cb); -} - -static void draw_lit_cube(ID3D11DeviceContext* ctx, ID3D11Device* dev, float cx, float cy, float cz, float s, float cr, float cg, float cb) { - V v[24]; - float f[6][4][3]={{{-1,-1,-1},{1,-1,-1},{1,1,-1},{-1,1,-1}},{{1,-1,-1},{1,-1,1},{1,1,1},{1,1,-1}}, - {{1,-1,1},{-1,-1,1},{-1,1,1},{1,1,1}},{{-1,-1,1},{-1,-1,-1},{-1,1,-1},{-1,1,1}}, - {{-1,1,-1},{1,1,-1},{1,1,1},{-1,1,1}},{{-1,-1,1},{1,-1,1},{1,-1,-1},{-1,-1,-1}}}; - float nm[6][3]={{0,0,-1},{1,0,0},{0,0,1},{-1,0,0},{0,1,0},{0,-1,0}}; - for(int fi=0;fi<6;fi++) for(int vi=0;vi<4;vi++){ - int i=fi*4+vi; - v[i].p[0]=f[fi][vi][0]*s+cx; v[i].p[1]=f[fi][vi][1]*s+cy; v[i].p[2]=f[fi][vi][2]*s+cz; - v[i].n[0]=nm[fi][0]; v[i].n[1]=nm[fi][1]; v[i].n[2]=nm[fi][2]; - v[i].c[0]=cr; v[i].c[1]=cg; v[i].c[2]=cb; v[i].c[3]=1; - } - uint32_t idx[36]; for(int fi=0;fi<6;fi++){int b=fi*4;idx[fi*6]=b;idx[fi*6+1]=b+1;idx[fi*6+2]=b+2;idx[fi*6+3]=b;idx[fi*6+4]=b+2;idx[fi*6+5]=b+3;} - ID3D11Buffer *vb,*ib;D3D11_BUFFER_DESC bd={};D3D11_SUBRESOURCE_DATA sd={}; - bd.ByteWidth=sizeof(V)*24;bd.Usage=D3D11_USAGE_DEFAULT;bd.BindFlags=D3D11_BIND_VERTEX_BUFFER;sd.pSysMem=v; - dev->lpVtbl->CreateBuffer(dev,&bd,&sd,&vb); - bd.ByteWidth=sizeof(uint32_t)*36;bd.BindFlags=D3D11_BIND_INDEX_BUFFER;sd.pSysMem=idx; - dev->lpVtbl->CreateBuffer(dev,&bd,&sd,&ib); - UINT s2=sizeof(V),o=0; - ctx->lpVtbl->IASetVertexBuffers(ctx,0,1,&vb,&s2,&o); - ctx->lpVtbl->IASetIndexBuffer(ctx,ib,DXGI_FORMAT_R32_UINT,0); - ctx->lpVtbl->DrawIndexed(ctx,36,0,0); - ib->lpVtbl->Release(ib);vb->lpVtbl->Release(vb); -} - -static void on_render(Engine* engine) { - if(!g_dev) return; - ID3D11DeviceContext* ctx=g_dev->context; - g_time+=0.016f; - - float sw=(float)g_dev->width,sh=(float)g_dev->height; - float fov=1.0f/tanf(0.4f),asp=sw/sh; - float mvp[16]={0}; mvp[0]=fov/asp;mvp[5]=-fov;mvp[10]=1;mvp[11]=-1;mvp[14]=0.1f;mvp[15]=1; - Mat4 pm,pt;memcpy(&pm,mvp,sizeof(Mat4));mat4_transpose(&pm,&pt); - - graphics_device_clear(g_dev,0.15f,0.18f,0.25f,1.0f); - D3D11_VIEWPORT vp={};vp.Width=sw;vp.Height=sh;vp.MaxDepth=1; - ctx->lpVtbl->RSSetViewports(ctx,1,&vp); - D3D11_RASTERIZER_DESC rd={};rd.FillMode=D3D11_FILL_SOLID;rd.CullMode=D3D11_CULL_NONE; - ID3D11RasterizerState*rs=NULL;g_dev->device->lpVtbl->CreateRasterizerState(g_dev,&rd,&rs); - ctx->lpVtbl->RSSetState(ctx,rs); - D3D11_DEPTH_STENCIL_DESC dsd={};dsd.DepthEnable=FALSE; - ID3D11DepthStencilState*dss=NULL;g_dev->device->lpVtbl->CreateDepthStencilState(g_dev,&dsd,&dss); - ctx->lpVtbl->OMSetDepthStencilState(ctx,dss,0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx,D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - // 绑定光照 shader - ctx->lpVtbl->VSSetShader(ctx,g_vs,NULL,0); - ctx->lpVtbl->PSSetShader(ctx,g_ps,NULL,0); - ctx->lpVtbl->IASetInputLayout(ctx,g_il); - ctx->lpVtbl->VSSetConstantBuffers(ctx,0,1,&g_cb); - ctx->lpVtbl->UpdateSubresource(ctx,(ID3D11Resource*)g_cb,0,NULL,&pt,0,0); - - // 更新光照 CB - float light_data[16]={0}; - light_data[0]=g_sun->direction[0];light_data[1]=g_sun->direction[1];light_data[2]=g_sun->direction[2]; - light_data[4]=g_sun->color[0];light_data[5]=g_sun->color[1];light_data[6]=g_sun->color[2]; - light_data[7]=g_sun->intensity; - light_data[8]=0.15f;light_data[9]=0.15f;light_data[10]=0.2f; - ctx->lpVtbl->VSSetConstantBuffers(ctx,1,1,&g_cb); - - draw_lit_cube(ctx,g_dev, 0,0,0.5f, 0.3f, 1,0.3f,0.3f); - draw_lit_cube(ctx,g_dev,-0.8f,0,0.7f, 0.2f, 0.3f,1,0.3f); - draw_lit_cube(ctx,g_dev, 0.8f,0.3f,0.3f, 0.15f, 0.3f,0.3f,1); - draw_lit_cube(ctx,g_dev, 0,-0.2f,0.8f, 0.4f, 0.8f,0.8f,0.2f); - - if(rs)rs->lpVtbl->Release(rs);if(dss)dss->lpVtbl->Release(dss); - graphics_device_present(g_dev); -} - -static void on_key(Engine*e,int k){if(k==VK_ESCAPE)engine_request_quit(e);} - -int WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int){ - EngineConfig cfg=engine_default_config();cfg.app_name="lity3d Light Test"; - Engine*e=engine_create();if(!engine_init(e,&cfg))return -1; - g_dev=graphics_device_create(); - if(!graphics_device_init(g_dev,window_get_handle(e->window),cfg.window_width,cfg.window_height,1))return -1; - InitShaders(); - g_sun=light_create_dir(1.0f,0.95f,0.8f,1.2f, -0.5f,-1.0f,-0.3f); - engine_set_render_callback(e,on_render);engine_set_key_callback(e,on_key); - engine_run(e); - light_destroy(g_sun);graphics_device_destroy(g_dev);engine_shutdown(e); - return 0; -} diff --git a/Demo/lity_explorer.c b/Demo/lity_explorer.c deleted file mode 100644 index 79e1722..0000000 --- a/Demo/lity_explorer.c +++ /dev/null @@ -1,256 +0,0 @@ -#include "../Engine/Core/engine.h" -#include "../Engine/Core/logger.h" -#include "../Engine/Core/timer.h" -#include "../Engine/Core/asset_manager.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/renderer.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Rendering/mesh.h" -#include "../Engine/Rendering/material.h" -#include "../Engine/Rendering/texture.h" -#include "../Engine/Rendering/camera.h" -#include "../Engine/Scene/scene_graph.h" -#include "../Engine/Scene/scene_render.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" -#include -#include -#include -#include -#include - -static Scene* g_scene = NULL; -static AssetManager* g_assets = NULL; -static Asset* g_shader_asset = NULL; -static Camera g_camera; -static int g_mouse_down[3] = {0}; -static int g_last_mx = 0, g_last_my = 0, g_mouse_first = 1; - -static float player_x = 0, player_z = -8, player_y = 0; -static float cam_yaw = 0, cam_pitch = 0.3f, cam_dist = 6.0f, cam_height = 3.0f; -static SceneNode* g_player = NULL; -static float player_vy = 0; -static int g_ground = 1; - -static SceneNode* mknode(Scene* s, SceneNode* p, AssetManager* am, ID3D11Device* dev, - const char* name, MeshType mt, Vec3 pos, Vec3 scl, Material* mat) { - SceneNode* n = scene_create_node(s, name); - if (!n) return NULL; - if (p) scene_set_parent(n, p); - n->position = pos; n->scale = scl; - Asset* ma = asset_manager_load_mesh(am, dev, name); - if (!ma) { - const char* b = mt == MESH_CUBE ? "cube" : mt == MESH_SPHERE ? "sphere" : "plane"; - ma = asset_manager_load_mesh(am, dev, b); - } - if (ma && mat) { - MeshRenderer* mr = mesh_renderer_create(mt, (Mesh*)asset_data(ma), mat); - scene_node_set_mesh_renderer(n, mr); - } - return n; -} - -static Scene* create_world(AssetManager* am, ID3D11Device* dev) { - Scene* scene = (Scene*)malloc(sizeof(Scene)); - if (!scene) return NULL; - scene_init(scene); - SceneNode* root = scene->root; - root->name[0] = '\0'; - strncpy(root->name, "root", sizeof(root->name) - 1); - - Shader* sh = (Shader*)asset_data(g_shader_asset); - - Material* m_green = material_create(sh, NULL); m_green->color = (Vec4){0.25f, 0.55f, 0.2f, 1}; - Material* m_dkgrn = material_create(sh, NULL); m_dkgrn->color = (Vec4){0.15f, 0.4f, 0.12f, 1}; - Material* m_brown = material_create(sh, NULL); m_brown->color = (Vec4){0.45f, 0.28f, 0.15f, 1}; - Material* m_stone = material_create(sh, NULL); m_stone->color = (Vec4){0.5f, 0.5f, 0.5f, 1}; - Material* m_dstone = material_create(sh, NULL); m_dstone->color = (Vec4){0.35f, 0.35f, 0.38f, 1}; - Material* m_red = material_create(sh, NULL); m_red->color = (Vec4){0.8f, 0.2f, 0.15f, 1}; - Material* m_blue = material_create(sh, NULL); m_blue->color = (Vec4){0.2f, 0.4f, 0.8f, 1}; - Material* m_yellow = material_create(sh, NULL); m_yellow->color = (Vec4){0.85f, 0.75f, 0.2f, 1}; - Material* m_white = material_create(sh, NULL); m_white->color = (Vec4){0.85f, 0.85f, 0.85f, 1}; - Material* m_water = material_create(sh, NULL); m_water->color = (Vec4){0.15f, 0.3f, 0.6f, 0.8f}; - Material* m_orange = material_create(sh, NULL); m_orange->color = (Vec4){0.9f, 0.5f, 0.1f, 1}; - Material* m_purple = material_create(sh, NULL); m_purple->color = (Vec4){0.5f, 0.15f, 0.6f, 1}; - Material* m_player = material_create(sh, NULL); m_player->color = (Vec4){0.1f, 0.8f, 0.3f, 1}; - Material* m_path = material_create(sh, NULL); m_path->color = (Vec4){0.6f, 0.55f, 0.45f, 1}; - Material* m_hill = material_create(sh, NULL); m_hill->color = (Vec4){0.2f, 0.4f, 0.18f, 1}; - Material* m_flower = material_create(sh, NULL); m_flower->color = (Vec4){0.9f, 0.2f, 0.4f, 1}; - - mknode(scene, root, am, dev, "ground", MESH_PLANE, (Vec3){0, -0.01f, 0}, (Vec3){40, 1, 40}, m_green); - - g_player = mknode(scene, root, am, dev, "player", MESH_CUBE, (Vec3){player_x, 0.4f, player_z}, (Vec3){0.3f, 0.8f, 0.3f}, m_player); - - // 村庄 - mknode(scene, root, am, dev, "house1", MESH_CUBE, (Vec3){-5, 1, -5}, (Vec3){2, 2, 2}, m_red); - mknode(scene, root, am, dev, "house2", MESH_CUBE, (Vec3){-2, 1.25f, -8}, (Vec3){2.5f, 2.5f, 2}, m_blue); - mknode(scene, root, am, dev, "house3", MESH_CUBE, (Vec3){1, 0.9f, -6}, (Vec3){1.8f, 1.8f, 1.8f}, m_yellow); - mknode(scene, root, am, dev, "tower", MESH_CUBE, (Vec3){-7, 1.5f, -2}, (Vec3){1.5f, 3, 1.5f}, m_white); - mknode(scene, root, am, dev, "house4", MESH_CUBE, (Vec3){4, 1, -4}, (Vec3){2, 2, 2}, m_orange); - // 屋顶 - mknode(scene, root, am, dev, "roof1", MESH_CUBE, (Vec3){-5, 2.15f, -5}, (Vec3){2.3f, 0.3f, 2.3f}, m_dstone); - mknode(scene, root, am, dev, "roof2", MESH_CUBE, (Vec3){-2, 2.65f, -8}, (Vec3){2.8f, 0.3f, 2.3f}, m_dstone); - mknode(scene, root, am, dev, "roof3", MESH_CUBE, (Vec3){1, 2.0f, -6}, (Vec3){2.1f, 0.3f, 2.1f}, m_brown); - mknode(scene, root, am, dev, "roof4", MESH_CUBE, (Vec3){4, 2.15f, -4}, (Vec3){2.3f, 0.3f, 2.3f}, m_brown); - - // 树木 - float trees[][2] = {{-12,3},{-10,5},{-8,8},{-6,10},{-3,12},{2,14},{5,10},{8,7},{10,4},{12,2}, - {-14,-1},{-12,-6},{-10,-10},{8,-8},{12,-5},{15,8},{-15,12},{0,18},{-5,15},{10,15}, - {-8,-14},{5,-12},{12,-10},{-14,6},{14,-2},{3,8},{-2,10},{7,12},{-11,8},{9,3}}; - for (int i = 0; i < 30; i++) { - float x = trees[i][0], z = trees[i][1]; - mknode(scene, root, am, dev, "trunk", MESH_CUBE, (Vec3){x, 0.5f, z}, (Vec3){0.2f, 1, 0.2f}, m_brown); - mknode(scene, root, am, dev, "leaves", MESH_SPHERE, (Vec3){x, 1.8f, z}, (Vec3){0.8f, 0.7f, 0.8f}, m_dkgrn); - } - - // 岩石 - float rocks[][3] = {{6,-2,0.6f},{-9,2,0.4f},{10,10,0.8f},{-6,-12,0.5f},{14,6,0.7f},{-13,-8,0.3f},{3,-10,0.5f},{-4,14,0.4f},{11,-8,0.6f}}; - for (int i = 0; i < 9; i++) - mknode(scene, root, am, dev, "rock", MESH_SPHERE, (Vec3){rocks[i][0], rocks[i][2]*0.3f, rocks[i][1]}, (Vec3){rocks[i][2], rocks[i][2]*0.6f, rocks[i][2]}, m_stone); - - // 水塘 - mknode(scene, root, am, dev, "water", MESH_PLANE, (Vec3){-10, 0.02f, -4}, (Vec3){3, 1, 3}, m_water); - - // 小路 - for (float tz = -10; tz <= 2; tz += 1.5f) - mknode(scene, root, am, dev, "path", MESH_PLANE, (Vec3){0, 0.01f, tz}, (Vec3){0.6f, 1, 0.4f}, m_path); - - // 山丘 - mknode(scene, root, am, dev, "hill1", MESH_SPHERE, (Vec3){-18, -0.5f, 15}, (Vec3){8, 3, 8}, m_hill); - mknode(scene, root, am, dev, "hill2", MESH_SPHERE, (Vec3){20, -0.8f, 12}, (Vec3){10, 4, 10}, m_hill); - mknode(scene, root, am, dev, "hill3", MESH_SPHERE, (Vec3){0, -0.3f, 22}, (Vec3){12, 3, 8}, m_hill); - - // 花 - float flowers[][2] = {{-3,-2},{-1,-3},{2,-1},{-4,0},{3,1}}; - for (int i = 0; i < 5; i++) - mknode(scene, root, am, dev, "flower", MESH_SPHERE, (Vec3){flowers[i][0], 0.15f, flowers[i][1]}, (Vec3){0.1f, 0.1f, 0.1f}, m_flower); - - scene_update(scene); - return scene; -} - -static void on_render(Engine* engine) { - Renderer* r = engine_get_renderer(engine); - GraphicsDevice* dev = engine_get_graphics_device(engine); - if (!r || !dev || !g_scene) return; - renderer_set_view(r, camera_get_view(&g_camera)); - renderer_set_projection(r, camera_get_projection(&g_camera)); - renderer_begin_frame(r); - scene_update(g_scene); - scene_render(g_scene, r); - renderer_end_frame(r); -} - -static void update_camera(void) { - g_camera.position = (Vec3){ - player_x - sinf(cam_yaw) * cam_dist, - cam_height + sinf(cam_pitch) * cam_dist * 0.5f, - player_z - cosf(cam_yaw) * cam_dist - }; - g_camera.target = (Vec3){player_x, 0.5f, player_z}; - g_camera.dirty = 1; -} - -static void on_update(Engine* engine, double dt) { - (void)engine; - float fdt = (float)dt; - float spd = (GetAsyncKeyState(VK_SHIFT) & 0x8000) ? 10.0f * fdt : 5.0f * fdt; - float fwd_x = sinf(cam_yaw), fwd_z = cosf(cam_yaw); - float rgt_x = cosf(cam_yaw), rgt_z = -sinf(cam_yaw); - if (GetAsyncKeyState('W') & 0x8000) { player_x += fwd_x * spd; player_z += fwd_z * spd; } - if (GetAsyncKeyState('S') & 0x8000) { player_x -= fwd_x * spd; player_z -= fwd_z * spd; } - if (GetAsyncKeyState('A') & 0x8000) { player_x -= rgt_x * spd; player_z -= rgt_z * spd; } - if (GetAsyncKeyState('D') & 0x8000) { player_x += rgt_x * spd; player_z += rgt_z * spd; } - if (GetAsyncKeyState('Q') & 0x8000) cam_yaw -= 2.0f * fdt; - if (GetAsyncKeyState('E') & 0x8000) cam_yaw += 2.0f * fdt; - if ((GetAsyncKeyState(VK_SPACE) & 0x8000) && g_ground) { player_vy = 8.0f; g_ground = 0; } - player_vy -= 20.0f * fdt; - player_y += player_vy * fdt; - if (player_y < 0) { player_y = 0; player_vy = 0; g_ground = 1; } - if (player_x < -19) player_x = -19; if (player_x > 19) player_x = 19; - if (player_z < -19) player_z = -19; if (player_z > 21) player_z = 21; - if (g_player) { - g_player->position.x = player_x; g_player->position.y = 0.4f + player_y; g_player->position.z = player_z; - quat_from_euler(0, cam_yaw, 0, &g_player->rotation); - g_player->dirty = 1; - } - update_camera(); -} - -static void on_key(Engine* engine, int key) { - if (key == VK_ESCAPE) engine_request_quit(engine); -} - -static void on_mouse_move(Engine* engine, int x, int y) { - (void)engine; - if (g_mouse_down[0]) { - if (g_mouse_first) { g_last_mx = x; g_last_my = y; g_mouse_first = 0; } - else { - cam_yaw += (float)(x - g_last_mx) * 0.005f; - cam_pitch += (float)(y - g_last_my) * 0.003f; - if (cam_pitch > 1.2f) cam_pitch = 1.2f; - if (cam_pitch < -0.2f) cam_pitch = -0.2f; - g_last_mx = x; g_last_my = y; - update_camera(); - } - } else { g_mouse_first = 1; } -} - -static void on_mouse_button(Engine* engine, int button, int pressed) { - (void)engine; - if (button >= 0 && button < 3) g_mouse_down[button] = pressed; -} - -static void on_resize(Engine* engine, int width, int height) { - Renderer* r = engine_get_renderer(engine); - if (r && width > 0 && height > 0) { - renderer_resize(r, width, height); - g_camera.aspect = (float)width / (float)height; - g_camera.dirty = 1; - } -} - -int main(int argc, char* argv[]) { - (void)argc; (void)argv; - - EngineConfig config = engine_default_config(); - config.app_name = "Lity Explorer"; - config.vsync = 0; - config.window_width = 1280; - config.window_height = 720; - - Engine* engine = engine_create(); - if (!engine_init(engine, &config)) { LOG_FATAL("Init failed"); return -1; } - - GraphicsDevice* dev = engine_get_graphics_device(engine); - Renderer* r = engine_get_renderer(engine); - - g_assets = asset_manager_create(); - g_shader_asset = asset_manager_load_shader(g_assets, dev->device, NULL, NULL); - if (!g_shader_asset) { LOG_FATAL("Shader failed"); return -1; } - - g_scene = create_world(g_assets, dev->device); - - float aspect = (float)config.window_width / config.window_height; - g_camera = camera_perspective(1.0472f, aspect, 0.1f, 200.0f); - g_camera.position = (Vec3){0, cam_height, -8 - cam_dist}; - g_camera.target = (Vec3){0, 0.5f, -8}; - g_camera.dirty = 1; - - engine_set_update_callback(engine, on_update); - engine_set_render_callback(engine, on_render); - engine_set_key_callback(engine, on_key); - engine_set_mouse_move_callback(engine, on_mouse_move); - engine_set_mouse_button_callback(engine, on_mouse_button); - engine_set_resize_callback(engine, on_resize); - - LOG_INFO("Lity Explorer started!"); - engine_run(engine); - - scene_destroy_renderers(g_scene); - scene_destroy(g_scene); - free(g_scene); - asset_manager_destroy(g_assets); - engine_shutdown(engine); - return 0; -} diff --git a/Demo/ly_interpreter.c b/Demo/ly_interpreter.c deleted file mode 100644 index 4e9c2c3..0000000 --- a/Demo/ly_interpreter.c +++ /dev/null @@ -1,290 +0,0 @@ -// ============================================================================ -// ly_interpreter.c - .ly 积木语言独立解释器 -// 直接解析 .ly 格式,不依赖引擎 VisualScript 框架 -// 用法: ly_interpreter.exe -// ============================================================================ - -#include -#include -#include -#include - -// === 数据结构 === -typedef union { double num; char str[256]; int bool_val; } Value; - -typedef struct { - int id; - char name[64]; - float x, y; - char data[256]; - int color; - Value inputs[8]; - int input_count; - Value outputs[4]; - int output_count; -} Block; - -typedef struct { - int from_block, from_slot; - int to_block, to_slot; -} Wire; - -#define MAX_BLOCKS 256 -#define MAX_WIRES 256 - -static Block g_blocks[MAX_BLOCKS]; -static int g_block_count = 0; -static Wire g_wires[MAX_WIRES]; -static int g_wire_count = 0; - -// === 解析 === - -static void trim(char* s) { - char* p = s; - while (*p == ' ' || *p == '\t') p++; - if (p != s) memmove(s, p, strlen(p) + 1); - int len = strlen(s); - while (len > 0 && (s[len-1] == '\n' || s[len-1] == '\r' || s[len-1] == ' ')) s[--len] = 0; -} - -static int parse_ly(const char* path) { - FILE* f = fopen(path, "r"); - if (!f) { fprintf(stderr, "Cannot open %s\n", path); return 0; } - - char line[1024]; - int section = 0; // 0=none, 1=block, 2=wire - int cur_bid = -1; - - while (fgets(line, sizeof(line), f)) { - trim(line); - if (line[0] == '#' || line[0] == 0) continue; - - if (strcmp(line, "[B]") == 0 || strcmp(line, "[Block]") == 0) { section = 1; cur_bid = -1; continue; } - if (strcmp(line, "[W]") == 0 || strcmp(line, "[Wire]") == 0) { section = 2; continue; } - if (line[0] == '[') { section = 0; continue; } - - if (section == 1) { - char* eq = strchr(line, '='); - if (!eq) continue; - *eq = 0; char* key = line; char* val = eq + 1; - - if (strcmp(key, "id") == 0) { - cur_bid = g_block_count; - memset(&g_blocks[cur_bid], 0, sizeof(Block)); - g_blocks[cur_bid].id = atoi(val); - g_block_count++; - } else if (cur_bid >= 0) { - if (strcmp(key, "name") == 0) strncpy(g_blocks[cur_bid].name, val, 63); - else if (strcmp(key, "p") == 0 || strcmp(key, "pos") == 0) sscanf(val, "%f,%f", &g_blocks[cur_bid].x, &g_blocks[cur_bid].y); - else if (strcmp(key, "d") == 0 || strcmp(key, "data") == 0) strncpy(g_blocks[cur_bid].data, val, 255); - else if (strcmp(key, "c") == 0 || strcmp(key, "color") == 0) g_blocks[cur_bid].color = atoi(val); - } - } else if (section == 2) { - Wire* w = &g_wires[g_wire_count]; - char* eq = strchr(line, '='); - if (!eq) continue; - *eq = 0; char* key = line; char* val = eq + 1; - - if (strcmp(key, "a") == 0 || strcmp(key, "from") == 0) { - w->from_block = atoi(val) / 10000; - w->from_slot = atoi(val) % 10000; - } else if (strcmp(key, "b") == 0 || strcmp(key, "to") == 0) { - w->to_block = atoi(val) / 10000; - w->to_slot = atoi(val) % 10000; - if (w->from_block > 0) g_wire_count++; - } - } - } - fclose(f); - printf("Parsed: %d blocks, %d wires\n", g_block_count, g_wire_count); - return 1; -} - -// === 查找 === - -static Block* find_block(int id) { - for (int i = 0; i < g_block_count; i++) - if (g_blocks[i].id == id) return &g_blocks[i]; - return NULL; -} - -// 找到从某个 block 的 output_slot 出发,连接到的下一个 block -static Block* follow_wire(int from_id, int from_slot) { - for (int i = 0; i < g_wire_count; i++) { - if (g_wires[i].from_block == from_id && g_wires[i].from_slot == from_slot) - return find_block(g_wires[i].to_block); - } - return NULL; -} - -// 获取连接到某个 block input_slot 的值 -static Value get_input_value(int block_id, int slot) { - for (int i = 0; i < g_wire_count; i++) { - if (g_wires[i].to_block == block_id && g_wires[i].to_slot == slot) { - Block* src = find_block(g_wires[i].from_block); - if (src && src->output_count > g_wires[i].from_slot) - return src->outputs[g_wires[i].from_slot]; - } - } - Value v; v.num = 0; return v; -} - -// === 解释执行 === - -static int g_variables[64]; // 简单变量存储 -static char g_var_names[64][64]; -static int g_var_count = 0; - -static int get_var(const char* name) { - for (int i = 0; i < g_var_count; i++) - if (strcmp(g_var_names[i], name) == 0) return g_variables[i]; - return 0; -} - -static void set_var(const char* name, int val) { - for (int i = 0; i < g_var_count; i++) - if (strcmp(g_var_names[i], name) == 0) { g_variables[i] = val; return; } - if (g_var_count < 64) { strncpy(g_var_names[g_var_count], name, 63); g_variables[g_var_count++] = val; } -} - -static void execute(Block* block, int depth); - -static void execute_block(Block* b, int depth) { - if (!b) return; - if (depth > 100) { printf("Stack overflow!\n"); return; } - - const char* n = b->name; - - if (strcmp(n, "开始") == 0) { - // Follow output wire - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "移动物体") == 0) { - Value dx = get_input_value(b->id, 1); - Value dy = get_input_value(b->id, 2); - Value dz = get_input_value(b->id, 3); - printf(" [move] dx=%.1f dy=%.1f dz=%.1f\n", dx.num, dy.num, dz.num); - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "旋转物体") == 0) { - Value dx = get_input_value(b->id, 1); - Value dy = get_input_value(b->id, 2); - Value dz = get_input_value(b->id, 3); - printf(" [rotate] rx=%.1f ry=%.1f rz=%.1f\n", dx.num, dy.num, dz.num); - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "当按键") == 0) { - // Event: just follow output (simulated - always fires) - printf(" [key event] key='%s'\n", b->data); - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "当点击") == 0) { - printf(" [click event]\n"); - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "打印") == 0 || strcmp(n, "print") == 0) { - Value msg = get_input_value(b->id, 1); - printf(" [print] %s\n", msg.str[0] ? msg.str : b->data); - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "等待") == 0 || strcmp(n, "wait") == 0) { - Value secs = get_input_value(b->id, 1); - double s = secs.num > 0 ? secs.num : atof(b->data); - printf(" [wait] %.1fs\n", s); - // In real engine, this would pause. For now, just continue. - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "循环") == 0 || strcmp(n, "loop") == 0) { - Value count = get_input_value(b->id, 1); - int n = count.num > 0 ? (int)count.num : atoi(b->data); - if (n <= 0) n = 1; - printf(" [loop] %d times\n", n); - for (int i = 0; i < n; i++) { - Block* body = follow_wire(b->id, 0); - execute(body, depth + 1); - } - } - else if (strcmp(n, "如果") == 0 || strcmp(n, "if") == 0) { - Value cond = get_input_value(b->id, 1); - printf(" [if] condition=%d\n", cond.bool_val); - Block* next = follow_wire(b->id, cond.bool_val ? 0 : 1); - execute(next, depth + 1); - } - else if (strcmp(n, "数学运算") == 0 || strcmp(n, "+") == 0) { - Value a = get_input_value(b->id, 0); - Value b2 = get_input_value(b->id, 1); - b->outputs[0].num = a.num + b2.num; - printf(" [add] %.1f + %.1f = %.1f\n", a.num, b2.num, b->outputs[0].num); - } - else if (strcmp(n, "变量设置") == 0 || strcmp(n, "set_var") == 0) { - Value v = get_input_value(b->id, 1); - set_var(b->data, (int)v.num); - printf(" [set_var] %s = %d\n", b->data, (int)v.num); - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } - else if (strcmp(n, "变量读取") == 0 || strcmp(n, "get_var") == 0) { - int v = get_var(b->data); - b->outputs[0].num = v; - printf(" [get_var] %s = %d\n", b->data, v); - } - else { - printf(" [unknown] '%s'\n", n); - Block* next = follow_wire(b->id, 0); - execute(next, depth + 1); - } -} - -static void execute(Block* block, int depth) { - if (!block) return; - execute_block(block, depth); -} - -// === 主函数 === - -int main(int argc, char* argv[]) { - const char* script = "Demo/test.ly"; - if (argc > 1) script = argv[1]; - - printf("=== lity3d .ly Interpreter ===\n"); - printf("Script: %s\n\n", script); - - if (!parse_ly(script)) return 1; - - printf("\n--- Blocks ---\n"); - for (int i = 0; i < g_block_count; i++) - printf(" [%d] %s data='%s' pos=(%.0f,%.0f)\n", g_blocks[i].id, g_blocks[i].name, g_blocks[i].data, g_blocks[i].x, g_blocks[i].y); - - printf("\n--- Wires ---\n"); - for (int i = 0; i < g_wire_count; i++) - printf(" [%d].out%d -> [%d].in%d\n", g_wires[i].from_block, g_wires[i].from_slot, g_wires[i].to_block, g_wires[i].to_slot); - - printf("\n--- Execute ---\n"); - - // Find start block - Block* start = NULL; - for (int i = 0; i < g_block_count; i++) - if (strcmp(g_blocks[i].name, "开始") == 0) { start = &g_blocks[i]; break; } - - if (!start) { - // Try to find any block with incoming wires as entry point - // Or just execute the first block - if (g_block_count > 0) start = &g_blocks[0]; - } - - if (start) { - execute(start, 0); - } else { - printf("No executable blocks found.\n"); - } - - printf("\n--- Done ---\n"); - return 0; -} diff --git a/Demo/main.c b/Demo/main.c deleted file mode 100644 index 992f01d..0000000 --- a/Demo/main.c +++ /dev/null @@ -1,224 +0,0 @@ -#include "../Engine/Core/engine.h" -#include "../Engine/Core/logger.h" -#include "../Engine/Core/timer.h" -#include "../Engine/Core/asset_manager.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/renderer.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Rendering/mesh.h" -#include "../Engine/Rendering/material.h" -#include "../Engine/Rendering/texture.h" -#include "../Engine/Rendering/camera.h" -#include "../Engine/Scene/scene_graph.h" -#include "../Engine/Scene/scene_render.h" -#include "../Engine/Scene/scene_serialize.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" -#include -#include -#include -#include - -static Scene* g_scene = NULL; -static AssetManager* g_assets = NULL; -static Asset* g_shader_asset = NULL; -static Camera g_camera; -static int g_mouse_down[3] = {0}; -static int g_last_mouse_x = 0, g_last_mouse_y = 0; -static int g_mouse_first = 1; - -static SceneNode* create_primitive_node(Scene* scene, SceneNode* parent, AssetManager* am, - ID3D11Device* dev, const char* name, MeshType type, - Vec3 pos, Vec3 rot, Vec3 scale, - Material* material) { - SceneNode* node = scene_create_node(scene, name); - if (!node) return NULL; - if (parent) scene_set_parent(node, parent); - node->position = pos; - node->scale = scale; - quat_from_euler(rot.x, rot.y, rot.z, &node->rotation); - - Asset* mesh_asset = asset_manager_load_mesh(am, dev, name); - if (!mesh_asset) { - const char* builtin = NULL; - if (type == MESH_CUBE) builtin = "cube"; - else if (type == MESH_SPHERE) builtin = "sphere"; - else if (type == MESH_PLANE) builtin = "plane"; - if (builtin) mesh_asset = asset_manager_load_mesh(am, dev, builtin); - } - - if (mesh_asset && material) { - MeshRenderer* mr = mesh_renderer_create(type, (Mesh*)asset_data(mesh_asset), material); - scene_node_set_mesh_renderer(node, mr); - } - return node; -} - -static Scene* create_default_scene(AssetManager* am, ID3D11Device* dev) { - Scene* scene = (Scene*)malloc(sizeof(Scene)); - if (!scene) return NULL; - scene_init(scene); - - SceneNode* root = scene->root; - root->name[0] = '\0'; - strncpy(root->name, "root", sizeof(root->name) - 1); - - Shader* shader = (Shader*)asset_data(g_shader_asset); - - Material* mat_red = material_create(shader, NULL); - mat_red->color = (Vec4){1.0f, 0.3f, 0.2f, 1.0f}; - - Material* mat_blue = material_create(shader, NULL); - mat_blue->color = (Vec4){0.2f, 0.5f, 1.0f, 1.0f}; - - Material* mat_ground = material_create(shader, NULL); - mat_ground->color = (Vec4){0.3f, 0.3f, 0.35f, 1.0f}; - - // 中心红色立方体 - create_primitive_node(scene, root, am, dev, "cube", MESH_CUBE, - (Vec3){0, 0, 0}, (Vec3){0, 0, 0}, (Vec3){1, 1, 1}, mat_red); - // 右侧蓝色球体 - create_primitive_node(scene, root, am, dev, "sphere", MESH_SPHERE, - (Vec3){2.0f, 0, 0}, (Vec3){0, 0, 0}, (Vec3){0.8f, 0.8f, 0.8f}, mat_blue); - // 下方地面 - create_primitive_node(scene, root, am, dev, "ground", MESH_PLANE, - (Vec3){0, -1.0f, 0}, (Vec3){0, 0, 0}, (Vec3){1, 1, 1}, mat_ground); - - scene_update(scene); - return scene; -} - -static void on_render(Engine* engine) { - Renderer* r = engine_get_renderer(engine); - GraphicsDevice* dev = engine_get_graphics_device(engine); - if (!r || !dev || !g_scene) return; - - renderer_set_view(r, camera_get_view(&g_camera)); - renderer_set_projection(r, camera_get_projection(&g_camera)); - - renderer_begin_frame(r); - scene_update(g_scene); - scene_render(g_scene, r); - renderer_end_frame(r); - - if (engine->frame_count == 60) { - graphics_device_save_screenshot(dev, "screenshot1.bmp"); - } - if (engine->frame_count == 180) { - graphics_device_save_screenshot(dev, "screenshot2.bmp"); - } -} - -static void on_update(Engine* engine, double dt) { - (void)engine; (void)dt; -} - -static void on_key(Engine* engine, int key) { - if (key == VK_ESCAPE) engine_request_quit(engine); - if (key == 'W' || key == 'w') camera_move_forward(&g_camera, 0.5f); - if (key == 'S' || key == 's') camera_move_forward(&g_camera, -0.5f); - if (key == 'A' || key == 'a') camera_move_right(&g_camera, -0.5f); - if (key == 'D' || key == 'd') camera_move_right(&g_camera, 0.5f); - if (key == VK_LEFT) camera_rotate_yaw(&g_camera, -0.1f); - if (key == VK_RIGHT) camera_rotate_yaw(&g_camera, 0.1f); - if (key == VK_UP) camera_rotate_pitch(&g_camera, -0.1f); - if (key == VK_DOWN) camera_rotate_pitch(&g_camera, 0.1f); -} - -static void on_mouse_move(Engine* engine, int x, int y) { - (void)engine; - if (g_mouse_down[0]) { - if (g_mouse_first) { - g_last_mouse_x = x; - g_last_mouse_y = y; - g_mouse_first = 0; - } else { - float dx = (float)(x - g_last_mouse_x); - float dy = (float)(y - g_last_mouse_y); - camera_rotate_yaw(&g_camera, dx * 0.005f); - camera_rotate_pitch(&g_camera, dy * 0.005f); - g_last_mouse_x = x; - g_last_mouse_y = y; - } - } else { - g_mouse_first = 1; - } -} - -static void on_mouse_button(Engine* engine, int button, int pressed) { - (void)engine; - if (button >= 0 && button < 3) g_mouse_down[button] = pressed; -} - -static void on_resize(Engine* engine, int width, int height) { - Renderer* r = engine_get_renderer(engine); - if (r && width > 0 && height > 0) { - renderer_resize(r, width, height); - g_camera.aspect = (float)width / (float)height; - g_camera.dirty = 1; - } -} - -int main(int argc, char* argv[]) { - (void)argc; (void)argv; - - EngineConfig config = engine_default_config(); - config.app_name = "Lity3D - Scene Demo"; - config.vsync = 0; - config.window_width = 1280; - config.window_height = 720; - - Engine* engine = engine_create(); - if (!engine_init(engine, &config)) { - LOG_FATAL("Engine init failed"); - return -1; - } - - GraphicsDevice* dev = engine_get_graphics_device(engine); - Renderer* r = engine_get_renderer(engine); - - g_assets = asset_manager_create(); - g_shader_asset = asset_manager_load_shader(g_assets, dev->device, NULL, NULL); - if (!g_shader_asset) { - LOG_FATAL("Shader load failed"); - return -1; - } - LOG_INFO("Shader loaded via AssetManager"); - - Shader* default_shader = (Shader*)asset_data(g_shader_asset); - - g_scene = scene_load("scene.txt", dev->device, default_shader); - if (!g_scene) { - LOG_INFO("No scene.txt found, creating default scene"); - g_scene = create_default_scene(g_assets, dev->device); - if (!scene_save(g_scene, "scene.txt")) { - LOG_WARN("Failed to save scene.txt"); - } - } - - float aspect = (float)config.window_width / config.window_height; - g_camera = camera_perspective(1.0472f, aspect, 0.1f, 100.0f); - g_camera.position = (Vec3){0, 0.5f, -5.0f}; - g_camera.target = (Vec3){0, 0, 0}; - g_camera.dirty = 1; - - renderer_set_view(r, camera_get_view(&g_camera)); - renderer_set_projection(r, camera_get_projection(&g_camera)); - - engine_set_update_callback(engine, on_update); - engine_set_render_callback(engine, on_render); - engine_set_key_callback(engine, on_key); - engine_set_mouse_move_callback(engine, on_mouse_move); - engine_set_mouse_button_callback(engine, on_mouse_button); - engine_set_resize_callback(engine, on_resize); - - LOG_INFO("Running scene demo..."); - engine_run(engine); - - scene_destroy_renderers(g_scene); - scene_destroy(g_scene); - free(g_scene); - asset_manager_destroy(g_assets); - engine_shutdown(engine); - return 0; -} diff --git a/Demo/mesh_debug.c b/Demo/mesh_debug.c deleted file mode 100644 index af94165..0000000 --- a/Demo/mesh_debug.c +++ /dev/null @@ -1,73 +0,0 @@ -// mesh_debug.c - 精确定位 mesh 系统 bug -#include "../Engine/Core/engine.h" -#include "../Engine/Window/window.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" - -static GraphicsDevice* g_dev = NULL; -static Shader* g_shader = NULL; -static ID3D11Buffer* g_vb = NULL; -static ID3D11Buffer* g_ib = NULL; - -typedef struct { float p[3],n[3],uv[2],c[4]; } V; - -static void on_render(Engine* engine) { - if (!g_dev) return; - ID3D11DeviceContext* ctx = g_dev->context; - float sw=(float)g_dev->width, sh=(float)g_dev->height; - float fov=1.0f/tanf(0.4f), asp=sw/sh; - - float mvp[16]; - mvp[0]=fov/asp; mvp[5]=-fov; mvp[10]=1; mvp[11]=-1; mvp[14]=0.1f; mvp[15]=1; - Mat4 pm, pt; memcpy(&pm, mvp, sizeof(Mat4)); mat4_transpose(&pm, &pt); - - graphics_device_clear(g_dev, 0.15f, 0.18f, 0.25f, 1.0f); - D3D11_VIEWPORT vp={}; vp.Width=sw; vp.Height=sh; vp.MaxDepth=1; - ctx->lpVtbl->RSSetViewports(ctx,1,&vp); - D3D11_RASTERIZER_DESC rd={}; rd.FillMode=D3D11_FILL_SOLID; rd.CullMode=D3D11_CULL_NONE; - ID3D11RasterizerState* rs=NULL; g_dev->device->lpVtbl->CreateRasterizerState(g_dev->device,&rd,&rs); - ctx->lpVtbl->RSSetState(ctx,rs); - D3D11_DEPTH_STENCIL_DESC dsd={}; dsd.DepthEnable=FALSE; - ID3D11DepthStencilState* dss=NULL; g_dev->device->lpVtbl->CreateDepthStencilState(g_dev->device,&dsd,&dss); - ctx->lpVtbl->OMSetDepthStencilState(ctx,dss,0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx,D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - shader_bind(g_shader, ctx); - shader_set_matrix(g_shader, ctx, (float*)&pt); - - // 用 init 时创建的 VB 画 - UINT stride=sizeof(V), offset=0; - ctx->lpVtbl->IASetVertexBuffers(ctx,0,1,&g_vb,&stride,&offset); - ctx->lpVtbl->IASetIndexBuffer(ctx,g_ib,DXGI_FORMAT_R32_UINT,0); - ctx->lpVtbl->DrawIndexed(ctx,6,0,0); - - if(rs) rs->lpVtbl->Release(rs); - if(dss) dss->lpVtbl->Release(dss); - graphics_device_present(g_dev); -} - -static void on_key(Engine* engine, int key) { if(key==VK_ESCAPE) engine_request_quit(engine); } - -int WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int) { - EngineConfig cfg=engine_default_config(); cfg.app_name="mesh debug"; - Engine* e=engine_create(); if(!engine_init(e,&cfg))return -1; - g_dev=graphics_device_create(); - if(!graphics_device_init(g_dev,window_get_handle(e->window),cfg.window_width,cfg.window_height,1))return -1; - g_shader=shader_create(); shader_compile(g_shader,g_dev->device,NULL,NULL,0,0); - - // WinMain 中创建 VB/IB(跟 mesh_create_cube 一样的时机) - V v[4]={{{-0.5f,-0.5f,0.5f},{0,0,1},{0,0},{1,0,0,1}},{{0.5f,-0.5f,0.5f},{0,0,1},{1,0},{0,1,0,1}},{{0.5f,0.5f,0.5f},{0,0,1},{1,1},{0,0,1,1}},{{-0.5f,0.5f,0.5f},{0,0,1},{0,1},{1,1,1,1}}}; - uint32_t idx[6]={0,1,2,0,2,3}; - D3D11_BUFFER_DESC bd={}; D3D11_SUBRESOURCE_DATA sd={}; - bd.ByteWidth=sizeof(V)*4; bd.Usage=D3D11_USAGE_DEFAULT; bd.BindFlags=D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem=v; g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd,&sd,&g_vb); - bd.ByteWidth=sizeof(uint32_t)*6; bd.BindFlags=D3D11_BIND_INDEX_BUFFER; - sd.pSysMem=idx; g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd,&sd,&g_ib); - - engine_set_render_callback(e,on_render); engine_set_key_callback(e,on_key); - engine_run(e); - if(g_vb)g_vb->lpVtbl->Release(g_vb); if(g_ib)g_ib->lpVtbl->Release(g_ib); - shader_destroy(g_shader); graphics_device_destroy(g_dev); engine_shutdown(e); - return 0; -} diff --git a/Demo/obj_viewer.c b/Demo/obj_viewer.c deleted file mode 100644 index c9973cb..0000000 --- a/Demo/obj_viewer.c +++ /dev/null @@ -1,206 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -static ID3D11Device* g_dev; static ID3D11DeviceContext* g_ctx; -static IDXGISwapChain* g_sc; static ID3D11RenderTargetView* g_rtv; -static ID3D11VertexShader* g_vs; static ID3D11PixelShader* g_ps; -static ID3D11InputLayout* g_il; static ID3D11Buffer* g_cb; - -static float cam_dist = 5.0f, cam_yaw = 0.5f, cam_pitch = 0.3f; -static int drag = 0, last_mx, last_my; -static int key_w=0,key_s=0,key_a=0,key_d=0,key_q=0,key_e=0; - -typedef struct { float p[3], n[3], u[2], c[4]; } V3D; - -static V3D* obj_verts = NULL; -static uint32_t* obj_idx = NULL; -static int obj_vcount = 0, obj_icount = 0; -static ID3D11Buffer* obj_vb = NULL; -static ID3D11Buffer* obj_ib = NULL; - -static int LoadOBJ(const char* path) { - FILE* f = fopen(path, "r"); - if (!f) return -1; - int max_v = 16384, max_f = 32768; - float* vpos = (float*)malloc(max_v * 3 * sizeof(float)); - int vc = 0; - int* fidx = (int*)malloc(max_f * 3 * sizeof(int)); - int fc = 0; - char line[256]; - while (fgets(line, sizeof(line), f)) { - if (line[0] == 'v' && line[1] == ' ') { - float x, y, z; - if (sscanf(line + 2, "%f %f %f", &x, &y, &z) == 3 && vc < max_v) { - vpos[vc*3]=x; vpos[vc*3+1]=y; vpos[vc*3+2]=z; vc++; - } - } else if (line[0] == 'f' && line[1] == ' ') { - int v0, v1, v2; - char* p = line + 2; - v0 = atoi(p) - 1; while (*p && *p != ' ') p++; p++; - v1 = atoi(p) - 1; while (*p && *p != ' ') p++; p++; - v2 = atoi(p) - 1; - if (v0 >= 0 && v1 >= 0 && v2 >= 0 && fc < max_f) { - fidx[fc*3]=v0; fidx[fc*3+1]=v1; fidx[fc*3+2]=v2; fc++; - } - } - } - fclose(f); - if (vc == 0 || fc == 0) { free(vpos); free(fidx); return -1; } - - obj_vcount = fc * 3; - obj_icount = fc * 3; - obj_verts = (V3D*)calloc(obj_vcount, sizeof(V3D)); - obj_idx = (uint32_t*)malloc(obj_icount * sizeof(uint32_t)); - - for (int i = 0; i < fc; i++) { - for (int j = 0; j < 3; j++) { - int vi = fidx[i*3+j]; - int oi = i*3+j; - if (vi < vc) { - obj_verts[oi].p[0] = vpos[vi*3]; - obj_verts[oi].p[1] = vpos[vi*3+1]; - obj_verts[oi].p[2] = vpos[vi*3+2]; - } - obj_verts[oi].c[0] = 0.6f; obj_verts[oi].c[1] = 0.7f; obj_verts[oi].c[2] = 0.8f; obj_verts[oi].c[3] = 1; - obj_idx[oi] = oi; - } - } - for (int i = 0; i < fc; i++) { - float* p0 = obj_verts[i*3].p; - float* p1 = obj_verts[i*3+1].p; - float* p2 = obj_verts[i*3+2].p; - float e1[3]={p1[0]-p0[0],p1[1]-p0[1],p1[2]-p0[2]}; - float e2[3]={p2[0]-p0[0],p2[1]-p0[1],p2[2]-p0[2]}; - float nx=e1[1]*e2[2]-e1[2]*e2[1], ny=e1[2]*e2[0]-e1[0]*e2[2], nz=e1[0]*e2[1]-e1[1]*e2[0]; - float nl=sqrtf(nx*nx+ny*ny+nz*nz); - if(nl>0.0001f){nx/=nl;ny/=nl;nz/=nl;} - for(int j=0;j<3;j++){obj_verts[i*3+j].n[0]=nx;obj_verts[i*3+j].n[1]=ny;obj_verts[i*3+j].n[2]=nz;} - } - - D3D11_BUFFER_DESC bd; D3D11_SUBRESOURCE_DATA sd; - memset(&bd,0,sizeof(bd));memset(&sd,0,sizeof(sd)); - bd.ByteWidth=sizeof(V3D)*obj_vcount;bd.Usage=D3D11_USAGE_DEFAULT;bd.BindFlags=D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem=obj_verts;g_dev->lpVtbl->CreateBuffer(g_dev,&bd,&sd,&obj_vb); - bd.ByteWidth=sizeof(uint32_t)*obj_icount;bd.BindFlags=D3D11_BIND_INDEX_BUFFER; - sd.pSysMem=obj_idx;g_dev->lpVtbl->CreateBuffer(g_dev,&bd,&sd,&obj_ib); - - free(vpos); free(fidx); free(obj_verts); free(obj_idx); - obj_verts = NULL; obj_idx = NULL; - return 0; -} - -static void Init(HWND h) { - HRESULT hr; - DXGI_SWAP_CHAIN_DESC sd;memset(&sd,0,sizeof(sd));sd.BufferCount=2;sd.BufferDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM;sd.BufferDesc.RefreshRate.Numerator=60;sd.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT;sd.OutputWindow=h;sd.SampleDesc.Count=1;sd.Windowed=TRUE;sd.SwapEffect=DXGI_SWAP_EFFECT_DISCARD; - D3D_FEATURE_LEVEL fl=D3D_FEATURE_LEVEL_11_0,gt;hr=D3D11CreateDeviceAndSwapChain(NULL,D3D_DRIVER_TYPE_HARDWARE,NULL,0,&fl,1,D3D11_SDK_VERSION,&sd,&g_sc,&g_dev,>,&g_ctx);if(FAILED(hr))return; - ID3D11Texture2D*bb=NULL;hr=g_sc->lpVtbl->GetBuffer(g_sc,0,&IID_ID3D11Texture2D,(void**)&bb);if(FAILED(hr)||!bb)return;hr=g_dev->lpVtbl->CreateRenderTargetView(g_dev,(ID3D11Resource*)bb,NULL,&g_rtv);bb->lpVtbl->Release(bb);if(FAILED(hr))return; - const char*vs="cbuffer CB:register(b0){float4x4 WVP;};struct I{float3 p:POSITION;float3 n:NORMAL;float2 u:TEXCOORD;float4 c:COLOR;};struct O{float4 p:SV_POSITION;float3 n:NORMAL;float4 c:COLOR;};O main(I i){O o;o.p=mul(float4(i.p,1),WVP);o.n=i.n;o.c=i.c;return o;}"; - const char*ps="struct I{float3 n:NORMAL;float4 c:COLOR;};float4 main(float4 p:SV_POSITION,I i):SV_Target{float l=normalize(float3(0.3,1,0.5));float d=max(dot(normalize(i.n),l),0.2);return float4(i.c.rgb*d,1);}"; - ID3DBlob*b1,*b2,*e;D3DCompile(vs,(UINT)strlen(vs),NULL,NULL,NULL,"main","vs_5_0",0,0,&b1,&e);if(e){e->lpVtbl->Release(e);e=NULL;}D3DCompile(ps,(UINT)strlen(ps),NULL,NULL,NULL,"main","ps_5_0",0,0,&b2,&e);if(e){e->lpVtbl->Release(e);e=NULL;}if(!b1||!b2)return; - g_dev->lpVtbl->CreateVertexShader(g_dev,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),NULL,&g_vs);g_dev->lpVtbl->CreatePixelShader(g_dev,b2->lpVtbl->GetBufferPointer(b2),b2->lpVtbl->GetBufferSize(b2),NULL,&g_ps); - D3D11_INPUT_ELEMENT_DESC el[4];memset(el,0,sizeof(el));el[0].SemanticName="POSITION";el[0].Format=DXGI_FORMAT_R32G32B32_FLOAT;el[0].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA;el[1].SemanticName="NORMAL";el[1].AlignedByteOffset=12;el[1].Format=DXGI_FORMAT_R32G32B32_FLOAT;el[1].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA;el[2].SemanticName="TEXCOORD";el[2].AlignedByteOffset=24;el[2].Format=DXGI_FORMAT_R32G32_FLOAT;el[2].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA;el[3].SemanticName="COLOR";el[3].AlignedByteOffset=32;el[3].Format=DXGI_FORMAT_R32G32B32A32_FLOAT;el[3].InputSlotClass=D3D11_INPUT_PER_VERTEX_DATA; - g_dev->lpVtbl->CreateInputLayout(g_dev,el,4,b1->lpVtbl->GetBufferPointer(b1),b1->lpVtbl->GetBufferSize(b1),&g_il);b1->lpVtbl->Release(b1);b2->lpVtbl->Release(b2); - D3D11_BUFFER_DESC cbd;memset(&cbd,0,sizeof(cbd));cbd.ByteWidth=256;cbd.Usage=D3D11_USAGE_DEFAULT;cbd.BindFlags=D3D11_BIND_CONSTANT_BUFFER;g_dev->lpVtbl->CreateBuffer(g_dev,&cbd,NULL,&g_cb); -} - -static void mat4_perspective(float* m, float fov, float asp, float zn, float zf) { - memset(m, 0, 64); - float f = 1.0f / tanf(fov / 2); - m[0] = f / asp; m[5] = -f; - m[10] = zf / (zf - zn); m[11] = -zn * zf / (zf - zn); - m[14] = 1; m[15] = 0; -} - -static void mat4_lookat(float* m, float ex, float ey, float ez, float tx, float ty, float tz) { - float fx=tx-ex, fy=ty-ey, fz=tz-ez; - float fl=sqrtf(fx*fx+fy*fy+fz*fz);fx/=fl;fy/=fl;fz/=fl; - float rx=fy*0-fz*1,ry=fz*0-fx*0,rz=fx*1-fy*0; - float rl=sqrtf(rx*rx+ry*ry+rz*rz);rx/=rl;ry/=rl;rz/=rl; - float ux=ry*fz-rz*fy,uy=rz*fx-rx*fz,uz=rx*fy-ry*fx; - memset(m, 0, 64); - m[0]=rx*1;m[1]=ux*1;m[2]=fx*1; - m[4]=ry*1;m[5]=uy*1;m[6]=fy*1; - m[8]=rz*1;m[9]=uz*1;m[10]=fz*1; - m[12]=-(rx*ex+ry*ey+rz*ez);m[13]=-(ux*ex+uy*ey+uz*ez);m[14]=-(fx*ex+fy*ey+fz*ez);m[15]=1; -} - -static void mat4_mul(float* o, float* a, float* b) { - float t[16];for(int i=0;i<4;i++)for(int j=0;j<4;j++){t[i*4+j]=0;for(int k=0;k<4;k++)t[i*4+j]+=a[i*4+k]*b[k*4+j];} - memcpy(o,t,64); -} - -static void Frame(void) { - float dt = 0.016f, rspd = 2.0f * dt, mspeed = 3.0f * dt; - if (key_a) cam_yaw -= rspd; if (key_d) cam_yaw += rspd; - if (key_q) cam_pitch -= rspd; if (key_e) cam_pitch += rspd; - if (key_w) cam_dist -= mspeed; if (key_s) cam_dist += mspeed; - if (cam_dist < 1.0f) cam_dist = 1.0f; if (cam_dist > 20.0f) cam_dist = 20.0f; - if (cam_pitch > 1.5f) cam_pitch = 1.5f; if (cam_pitch < -1.5f) cam_pitch = -1.5f; - - float ex = cam_dist * sinf(cam_yaw) * cosf(cam_pitch); - float ey = cam_dist * sinf(cam_pitch); - float ez = cam_dist * cosf(cam_yaw) * cosf(cam_pitch); - - float view[16], proj[16], vp[16], tmp[16]; - mat4_lookat(view, ex, ey, ez, 0, 0, 0); - mat4_perspective(proj, 0.8f, 1280.0f/720.0f, 0.1f, 100.0f); - mat4_mul(tmp, view, proj); - float vp_t[16]; for(int i=0;i<4;i++)for(int j=0;j<4;j++) vp_t[i*4+j]=tmp[j*4+i]; - - float cl[4]={.15f,.18f,.22f,1}; - g_ctx->lpVtbl->OMSetRenderTargets(g_ctx,1,&g_rtv,NULL);g_ctx->lpVtbl->ClearRenderTargetView(g_ctx,g_rtv,cl); - D3D11_VIEWPORT vp2;memset(&vp2,0,sizeof(vp2));vp2.Width=1280;vp2.Height=720;vp2.MaxDepth=1;g_ctx->lpVtbl->RSSetViewports(g_ctx,1,&vp2); - D3D11_RASTERIZER_DESC rd;memset(&rd,0,sizeof(rd));rd.FillMode=D3D11_FILL_SOLID;rd.CullMode=D3D11_CULL_NONE;ID3D11RasterizerState*rs;g_dev->lpVtbl->CreateRasterizerState(g_dev,&rd,&rs);g_ctx->lpVtbl->RSSetState(g_ctx,rs); - D3D11_DEPTH_STENCIL_DESC ds;memset(&ds,0,sizeof(ds));ds.DepthEnable=FALSE;ID3D11DepthStencilState*dss;g_dev->lpVtbl->CreateDepthStencilState(g_dev,&ds,&dss);g_ctx->lpVtbl->OMSetDepthStencilState(g_ctx,dss,0); - g_ctx->lpVtbl->IASetPrimitiveTopology(g_ctx,D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);g_ctx->lpVtbl->VSSetShader(g_ctx,g_vs,NULL,0);g_ctx->lpVtbl->PSSetShader(g_ctx,g_ps,NULL,0);g_ctx->lpVtbl->IASetInputLayout(g_ctx,g_il);g_ctx->lpVtbl->VSSetConstantBuffers(g_ctx,0,1,&g_cb);g_ctx->lpVtbl->UpdateSubresource(g_ctx,(ID3D11Resource*)g_cb,0,NULL,vp_t,0,0); - - if (obj_vb && obj_ib) { - UINT stride = sizeof(V3D), off = 0; - g_ctx->lpVtbl->IASetVertexBuffers(g_ctx, 0, 1, &obj_vb, &stride, &off); - g_ctx->lpVtbl->IASetIndexBuffer(g_ctx, obj_ib, DXGI_FORMAT_R32_UINT, 0); - g_ctx->lpVtbl->DrawIndexed(g_ctx, obj_icount, 0, 0); - } - - if(rs)rs->lpVtbl->Release(rs);if(dss)dss->lpVtbl->Release(dss); - g_sc->lpVtbl->Present(g_sc, 1, 0); -} - -static LRESULT CALLBACK WP(HWND h,UINT m,WPARAM w,LPARAM l){ - switch(m){ - case WM_LBUTTONDOWN:drag=1;last_mx=(short)LOWORD(l);last_my=(short)HIWORD(l);SetCapture(h);break; - case WM_LBUTTONUP:drag=0;ReleaseCapture();break; - case WM_MOUSEMOVE:if(drag){int mx=(short)LOWORD(l),my=(short)HIWORD(l);cam_yaw+=(mx-last_mx)*0.005f;cam_pitch+=(my-last_my)*0.005f;if(cam_pitch>1.5f)cam_pitch=1.5f;if(cam_pitch<-1.5f)cam_pitch=-1.5f;last_mx=mx;last_my=my;}break; - case WM_MOUSEWHEEL:cam_dist-=(short)HIWORD(w)/120.0f;if(cam_dist<1)cam_dist=1;if(cam_dist>20)cam_dist=20;break; - case WM_KEYDOWN:switch(w){case 'A':key_a=1;break;case 'D':key_d=1;break;case 'W':key_w=1;break;case 'S':key_s=1;break;case 'Q':key_q=1;break;case 'E':key_e=1;break;case VK_ESCAPE:PostQuitMessage(0);break;}break; - case WM_KEYUP:switch(w){case 'A':key_a=0;break;case 'D':key_d=0;break;case 'W':key_w=0;break;case 'S':key_s=0;break;case 'Q':key_q=0;break;case 'E':key_e=0;break;}break; - case WM_DESTROY:PostQuitMessage(0);return 0; - }return DefWindowProcW(h,m,w,l); -} - -int WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR nC,int nS){ - (void)nS; - WNDCLASSEXW wc;memset(&wc,0,sizeof(wc));wc.cbSize=sizeof(wc);wc.style=CS_CLASSDC;wc.lpfnWndProc=WP;wc.hInstance=hI;wc.lpszClassName=L"obj_viewer"; - RegisterClassExW(&wc); - HWND hwnd=CreateWindowW(L"obj_viewer",L"OBJ Viewer - Mouse drag orbit, WASD move, Scroll zoom",WS_OVERLAPPEDWINDOW,100,100,1280,720,NULL,NULL,hI,NULL); - if(!hwnd)return -1;ShowWindow(hwnd,SW_SHOW);UpdateWindow(hwnd);Init(hwnd); - - char path[MAX_PATH]; - GetModuleFileNameA(NULL, path, MAX_PATH); - char* sl = strrchr(path, '\\'); - if (sl) { *(sl+1) = '\0'; strcat(path, "Assets\\cube.obj"); } - else strcpy(path, "Assets\\cube.obj"); - LoadOBJ(path); - - MSG msg; - while(1){while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){TranslateMessage(&msg);DispatchMessage(&msg);if(msg.message==WM_QUIT)goto done;}Frame();} -done: - if(obj_vb)obj_vb->lpVtbl->Release(obj_vb);if(obj_ib)obj_ib->lpVtbl->Release(obj_ib); - if(g_cb)g_cb->lpVtbl->Release(g_cb);if(g_il)g_il->lpVtbl->Release(g_il);if(g_vs)g_vs->lpVtbl->Release(g_vs);if(g_ps)g_ps->lpVtbl->Release(g_ps);if(g_rtv)g_rtv->lpVtbl->Release(g_rtv);if(g_sc)g_sc->lpVtbl->Release(g_sc);if(g_ctx)g_ctx->lpVtbl->Release(g_ctx);if(g_dev)g_dev->lpVtbl->Release(g_dev); - return 0; -} diff --git a/Demo/open_world_demo.c b/Demo/open_world_demo.c deleted file mode 100644 index 404bca7..0000000 --- a/Demo/open_world_demo.c +++ /dev/null @@ -1,384 +0,0 @@ -#include "../Engine/Core/engine.h" -#include "../Engine/Core/logger.h" -#include "../Engine/Core/timer.h" -#include "../Engine/Core/asset_manager.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/renderer.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Rendering/mesh.h" -#include "../Engine/Rendering/material.h" -#include "../Engine/Rendering/camera.h" -#include "../Engine/Rendering/camera_controller.h" -#include "../Engine/Terrain/terrain.h" -#include "../Engine/Terrain/terrain_manager.h" -#include "../Engine/Rendering/frustum.h" -#include "../Engine/Scene/scene_graph.h" -#include "../Engine/Scene/scene_render.h" -#include "../Engine/Scene/scene_serialize.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" -#include -#include -#include -#include -#include - -static AssetManager* g_assets = NULL; -static Asset* g_shader_asset = NULL; -static Camera g_camera; -static CameraController g_controller; -static TerrainManager* g_terrain = NULL; -static Material* g_terrain_mat = NULL; -static Mesh* g_cube = NULL; -static Material* g_cube_mat = NULL; -static Mesh* g_water = NULL; -static Material* g_water_mat = NULL; -static Scene* g_test_scene = NULL; - -static int g_mouse_down[3] = {0}; -static int g_last_mouse_x = 0, g_last_mouse_y = 0; -static int g_mouse_first = 1; -static int g_walk_mode = 0; - -// ============================================================================ -// 简易植被/岩石散布 -// ============================================================================ -#define MAX_SCATTER 512 - -typedef struct { - Mesh* mesh; - Material* mat; - Mat4 world; -} ScatterInstance; - -static ScatterInstance g_scatter[MAX_SCATTER]; -static int g_scatter_count = 0; - -static void add_scatter(Mesh* mesh, Material* mat, Vec3 pos, Vec3 scale) { - if (g_scatter_count >= MAX_SCATTER) return; - ScatterInstance* s = &g_scatter[g_scatter_count++]; - s->mesh = mesh; - s->mat = mat; - mat4_identity(&s->world); - s->world.m[0][0] = scale.x; - s->world.m[1][1] = scale.y; - s->world.m[2][2] = scale.z; - s->world.m[3][0] = pos.x; - s->world.m[3][1] = pos.y; - s->world.m[3][2] = pos.z; -} - -static void generate_scatter(ID3D11Device* dev, Shader* shader) { - Mesh* rock_mesh = mesh_create_cube(dev); - Material* rock_mat = material_create(shader, NULL); - rock_mat->color = (Vec4){0.55f, 0.50f, 0.45f, 1.0f}; - - Mesh* trunk_mesh = mesh_create_cube(dev); - Material* trunk_mat = material_create(shader, NULL); - trunk_mat->color = (Vec4){0.55f, 0.40f, 0.25f, 1.0f}; - - Mesh* leaves_mesh = mesh_create_sphere(dev, 1.0f, 8); - Material* leaves_mat = material_create(shader, NULL); - leaves_mat->color = (Vec4){0.22f, 0.65f, 0.28f, 1.0f}; - - for (int i = 0; i < MAX_SCATTER; i++) { - float x = ((float)rand() / (float)RAND_MAX) * 400.0f - 200.0f; - float z = ((float)rand() / (float)RAND_MAX) * 400.0f - 200.0f; - float h = terrain_manager_get_height(g_terrain, x, z); - // 跳过过低(水)或过高的山顶 - if (h < -2.0f || h > 20.0f) continue; - - int type = rand() % 3; - if (type == 0) { - // 岩石 - float s = 1.0f + ((float)rand() / (float)RAND_MAX) * 2.0f; - Vec3 pos = {x, h + s * 0.3f, z}; - Vec3 sc = {s, s * 0.6f, s}; - add_scatter(rock_mesh, rock_mat, pos, sc); - } else { - // 树 - float trunk_h = 1.5f + ((float)rand() / (float)RAND_MAX) * 1.5f; - Vec3 trunk_pos = {x, h + trunk_h * 0.5f, z}; - Vec3 trunk_sc = {0.25f, trunk_h, 0.25f}; - add_scatter(trunk_mesh, trunk_mat, trunk_pos, trunk_sc); - - float leaves_s = 1.2f + ((float)rand() / (float)RAND_MAX) * 1.2f; - Vec3 leaves_pos = {x, h + trunk_h + leaves_s * 0.4f, z}; - Vec3 leaves_sc = {leaves_s, leaves_s, leaves_s}; - add_scatter(leaves_mesh, leaves_mat, leaves_pos, leaves_sc); - } - } - - LOG_INFO("Generated %d scatter instances", g_scatter_count); -} - -static void render_scatter(Renderer* r, const Vec4 planes[6]) { - const float cull_distance = 140.0f; - const float cull_dist2 = cull_distance * cull_distance; - int rendered = 0; - for (int i = 0; i < g_scatter_count; i++) { - ScatterInstance* s = &g_scatter[i]; - Vec3 pos = {s->world.m[3][0], s->world.m[3][1], s->world.m[3][2]}; - Vec3 d; - vec3_sub(&pos, &g_camera.position, &d); - if (vec3_dot(&d, &d) > cull_dist2) continue; - - // 视锥剔除:用包围球近似 - float radius = fmaxf(fmaxf(s->world.m[0][0], s->world.m[1][1]), s->world.m[2][2]) * 0.866f; - if (!frustum_intersects_sphere(planes, pos, radius)) continue; - - renderer_draw_mesh_with_material(r, s->mesh, s->mat, &s->world); - rendered++; - } - LOG_INFO("Scatter render: visible=%d/%d", rendered, g_scatter_count); -} - -// ============================================================================ -// 地形高度回调 -// ============================================================================ -static float get_terrain_height(float x, float z, void* user) { - (void)user; - if (g_terrain) return terrain_manager_get_height(g_terrain, x, z); - return 0.0f; -} - -// ============================================================================ -// 引擎回调 -// ============================================================================ -static void on_render(Engine* engine) { - Renderer* r = engine_get_renderer(engine); - GraphicsDevice* dev = engine_get_graphics_device(engine); - if (!r || !dev) return; - - renderer_set_view(r, camera_get_view(&g_camera)); - renderer_set_projection(r, camera_get_projection(&g_camera)); - - renderer_begin_frame(r); - - Mat4 vp; - renderer_get_view_projection(r, &vp); - Vec4 planes[6]; - frustum_from_matrix(&vp, planes); - - if (g_water) { - Mat4 water_world; - mat4_identity(&water_world); - water_world.m[3][1] = -5.0f; - renderer_draw_mesh_with_material(r, g_water, g_water_mat, &water_world); - } - - if (g_terrain) { - terrain_manager_update(g_terrain, g_camera.position); - terrain_manager_render(g_terrain, r); - } - - render_scatter(r, planes); - - if (g_test_scene) { - scene_update(g_test_scene); - scene_render(g_test_scene, r); - } - - renderer_end_frame(r); - - if (engine->frame_count == 60) { - graphics_device_save_screenshot(dev, "open_world_screenshot1.bmp"); - } - if (engine->frame_count == 180) { - graphics_device_save_screenshot(dev, "open_world_screenshot2.bmp"); - } -} - -static void on_update(Engine* engine, double dt) { - (void)engine; - float fdt = (float)dt; - - Vec3 dir = {0.0f, 0.0f, 0.0f}; - if (GetAsyncKeyState('W') & 0x8000) dir.z += 1.0f; - if (GetAsyncKeyState('S') & 0x8000) dir.z -= 1.0f; - if (GetAsyncKeyState('A') & 0x8000) dir.x -= 1.0f; - if (GetAsyncKeyState('D') & 0x8000) dir.x += 1.0f; - - if (!g_walk_mode) { - if (GetAsyncKeyState(VK_SPACE) & 0x8000) dir.y += 1.0f; - if (GetAsyncKeyState(VK_SHIFT) & 0x8000) dir.y -= 1.0f; - } - - if (dir.x != 0.0f || dir.y != 0.0f || dir.z != 0.0f) { - camera_controller_move(&g_controller, dir, fdt); - } - - camera_controller_update(&g_controller, fdt); -} - -static void on_key(Engine* engine, int key) { - (void)engine; - if (key == VK_ESCAPE) engine_request_quit(engine); - - // 切换步行/飞行模式 - if (key == 'F' || key == 'f') { - g_walk_mode = !g_walk_mode; - camera_controller_set_mode(&g_controller, g_walk_mode ? CAMERA_MODE_WALK : CAMERA_MODE_FLY); - g_controller.move_speed = g_walk_mode ? 8.0f : 40.0f; - LOG_INFO("Camera mode: %s (speed %.1f)", g_walk_mode ? "walk" : "fly", g_controller.move_speed); - } - - // 模式切换后重新定位相机高度 - if (g_walk_mode) { - float ground = get_terrain_height(g_camera.position.x, g_camera.position.z, NULL); - g_camera.position.y = ground + g_controller.height_offset; - g_camera.target.y = g_camera.position.y + sinf(g_controller.pitch); - g_camera.dirty = 1; - } -} - -static void on_mouse_move(Engine* engine, int x, int y) { - (void)engine; - if (g_mouse_down[0]) { // 左键拖拽旋转 - if (g_mouse_first) { - g_last_mouse_x = x; - g_last_mouse_y = y; - g_mouse_first = 0; - } else { - float dx = (float)(x - g_last_mouse_x); - float dy = (float)(y - g_last_mouse_y); - camera_controller_look(&g_controller, dx, dy); - g_last_mouse_x = x; - g_last_mouse_y = y; - } - } else { - g_mouse_first = 1; - } -} - -static void on_mouse_button(Engine* engine, int button, int pressed) { - (void)engine; - if (button >= 0 && button < 3) g_mouse_down[button] = pressed; -} - -static void on_resize(Engine* engine, int width, int height) { - Renderer* r = engine_get_renderer(engine); - if (r && width > 0 && height > 0) { - renderer_resize(r, width, height); - g_camera.aspect = (float)width / (float)height; - g_camera.dirty = 1; - } -} - -// ============================================================================ -// 入口 -// ============================================================================ -int main(int argc, char* argv[]) { - (void)argc; (void)argv; - - srand((unsigned int)time(NULL)); - - EngineConfig config = engine_default_config(); - config.app_name = "Lity3D - Open World Demo"; - config.vsync = 1; - config.window_width = 1280; - config.window_height = 720; - - Engine* engine = engine_create(); - if (!engine_init(engine, &config)) { - LOG_FATAL("Engine init failed"); - return -1; - } - - GraphicsDevice* dev = engine_get_graphics_device(engine); - Renderer* r = engine_get_renderer(engine); - - g_assets = asset_manager_create(); - g_shader_asset = asset_manager_load_shader(g_assets, dev->device, NULL, NULL); - if (!g_shader_asset) { - LOG_FATAL("Shader load failed"); - return -1; - } - LOG_INFO("Shader loaded via AssetManager"); - - Shader* default_shader = (Shader*)asset_data(g_shader_asset); - - // 地形材质 - g_terrain_mat = material_create(default_shader, NULL); - g_terrain_mat->color = (Vec4){1.0f, 1.0f, 1.0f, 1.0f}; - - // 参照立方体 - g_cube = mesh_create_cube(dev->device); - g_cube_mat = material_create(default_shader, NULL); - g_cube_mat->color = (Vec4){1.0f, 0.2f, 0.2f, 1.0f}; - - // 水面(不透明,作为低洼处背景) - g_water = mesh_create_plane(dev->device, 2000.0f); - g_water_mat = material_create(default_shader, NULL); - g_water_mat->color = (Vec4){0.18f, 0.45f, 0.78f, 1.0f}; - - // 测试场景:仅保留一个红色立方体作为原点标记 - g_test_scene = (Scene*)calloc(1, sizeof(Scene)); - scene_init(g_test_scene); - - SceneNode* cube_node = scene_create_node(g_test_scene, "cube"); - scene_set_parent(cube_node, g_test_scene->root); - cube_node->position = (Vec3){0.0f, 0.0f, 0.0f}; - MeshRenderer* cube_mr = mesh_renderer_create(MESH_CUBE, g_cube, g_cube_mat); - scene_node_set_mesh_renderer(cube_node, cube_mr); - - // 地形配置 - TerrainConfig tcfg = terrain_default_config(); - tcfg.vertices_per_chunk = 48; - tcfg.chunk_size = 64.0f; - tcfg.height_scale = 30.0f; - tcfg.uv_scale = 0.05f; - - g_terrain = terrain_manager_create(dev->device, &tcfg, g_terrain_mat); - g_terrain->load_radius = 3; - - // 生成植被/岩石 - generate_scatter(dev->device, default_shader); - - // 天空色与柔和环境光 - renderer_set_clear_color(r, 0.53f, 0.81f, 0.98f, 1.0f); - renderer_set_light(r, (Vec3){0.5f, -1.0f, 0.3f}, - (Vec4){0.55f, 0.53f, 0.48f, 1.0f}, - (Vec4){0.70f, 0.74f, 0.82f, 1.0f}); - - // 相机初始化:站在地形上,朝 +Z - float aspect = (float)config.window_width / (float)config.window_height; - g_camera = camera_perspective(1.0472f, aspect, 0.1f, 500.0f); - float start_h = terrain_manager_get_height(g_terrain, 0.0f, 0.0f); - g_camera.position = (Vec3){0.0f, start_h + 1.75f, 0.0f}; - g_camera.target = (Vec3){0.0f, start_h + 1.75f, 5.0f}; - g_camera.far_z = 500.0f; - g_camera.dirty = 1; - - g_controller = camera_controller_create(&g_camera); - g_controller.move_speed = 8.0f; - g_controller.mouse_sensitivity = 0.004f; - camera_controller_set_ground_callback(&g_controller, get_terrain_height, NULL); - g_walk_mode = 1; - camera_controller_set_mode(&g_controller, CAMERA_MODE_WALK); - LOG_INFO("Starting in walk mode at height %.2f", start_h); - - renderer_set_view(r, camera_get_view(&g_camera)); - renderer_set_projection(r, camera_get_projection(&g_camera)); - - engine_set_update_callback(engine, on_update); - engine_set_render_callback(engine, on_render); - engine_set_key_callback(engine, on_key); - engine_set_mouse_move_callback(engine, on_mouse_move); - engine_set_mouse_button_callback(engine, on_mouse_button); - engine_set_resize_callback(engine, on_resize); - - LOG_INFO("Running open world demo..."); - engine_run(engine); - - terrain_manager_destroy(g_terrain); - if (g_test_scene) { - scene_destroy_renderers(g_test_scene); - scene_destroy(g_test_scene); - free(g_test_scene); - } - if (g_cube) mesh_destroy(g_cube); - asset_manager_destroy(g_assets); - engine_shutdown(engine); - return 0; -} diff --git a/Demo/raw3d_test.c b/Demo/raw3d_test.c deleted file mode 100644 index 13964e7..0000000 --- a/Demo/raw3d_test.c +++ /dev/null @@ -1,128 +0,0 @@ -// raw3d_test.c - 用 draw_quad 画 3D 方块,验证场景图变换 -#include "../Engine/Core/engine.h" -#include "../Engine/Window/window.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Scene/scene_graph.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" - -static GraphicsDevice* g_dev = NULL; -static Shader* g_shader = NULL; -static Scene g_scene; -static float g_time = 0; - -typedef struct { float p[3],n[3],uv[2],c[4]; } V; -static void draw_quad_3d(ID3D11DeviceContext* ctx, float x, float y, float w, float h, float r, float g, float b, float a) { - V v[4] = {{{x,y,0},{0,0,-1},{0,0},{r,g,b,a}},{{x+w,y,0},{0,0,-1},{1,0},{r,g,b,a}},{{x+w,y+h,0},{0,0,-1},{1,1},{r,g,b,a}},{{x,y+h,0},{0,0,-1},{0,1},{r,g,b,a}}}; - uint32_t idx[6] = {0,1,2,0,2,3}; - ID3D11Buffer *vb=NULL,*ib=NULL; - D3D11_BUFFER_DESC bd={}; D3D11_SUBRESOURCE_DATA sd={}; - bd.ByteWidth=sizeof(V)*4; bd.Usage=D3D11_USAGE_DEFAULT; bd.BindFlags=D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem=v; g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd,&sd,&vb); - bd.ByteWidth=sizeof(uint32_t)*6; bd.BindFlags=D3D11_BIND_INDEX_BUFFER; - sd.pSysMem=idx; g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd,&sd,&ib); - UINT stride=sizeof(V),off=0; - ctx->lpVtbl->IASetVertexBuffers(ctx,0,1,&vb,&stride,&off); - ctx->lpVtbl->IASetIndexBuffer(ctx,ib,DXGI_FORMAT_R32_UINT,0); - ctx->lpVtbl->DrawIndexed(ctx,6,0,0); - ib->lpVtbl->Release(ib); vb->lpVtbl->Release(vb); -} - -static void on_render(Engine* engine) { - if (!g_dev) return; - ID3D11DeviceContext* ctx = g_dev->context; - scene_update(&g_scene); - g_time += (float)engine->delta_time; - - float sw=(float)g_dev->width, sh=(float)g_dev->height; - float fov=1.0f/tanf(0.4f), asp=sw/sh; - - // VP矩阵: 摄像机在(8,5,10)看原点 - float ex=8,ey=5,ez=10; - float fx=-ex,fy=-ey,fz=-ez, fl=sqrtf(fx*fx+fy*fy+fz*fz); fx/=fl;fy/=fl;fz/=fl; - float rx=fy*0-fz*1,ry=fz*0-fx*0,rz=fx*1-fy*0; - float rl=sqrtf(rx*rx+ry*ry+rz*rz);rx/=rl;ry/=rl;rz/=rl; - float ux=ry*fz-rz*fy,uy=rz*fx-rx*fz,uz=rx*fy-ry*fx; - float mvp[16]; - mvp[0]=rx*fov/asp;mvp[1]=ry*fov/asp;mvp[2]=rz*fov/asp;mvp[3]=0; - mvp[4]=ux*fov;mvp[5]=uy*fov;mvp[6]=uz*fov;mvp[7]=0; - mvp[8]=fx;mvp[9]=fy;mvp[10]=fz;mvp[11]=0; - mvp[12]=-(rx*ex+ry*ey+rz*ez)*fov/asp; - mvp[13]=-(ux*ex+uy*ey+uz*ez)*fov; - mvp[14]=-(fx*ex+fy*ey+fz*ez);mvp[15]=1; - - graphics_device_clear(g_dev, 0.15f, 0.18f, 0.25f, 1.0f); - D3D11_VIEWPORT vp={};vp.Width=sw;vp.Height=sh;vp.MaxDepth=1; - ctx->lpVtbl->RSSetViewports(ctx,1,&vp); - D3D11_RASTERIZER_DESC rd={};rd.FillMode=D3D11_FILL_SOLID;rd.CullMode=D3D11_CULL_NONE; - ID3D11RasterizerState* rs=NULL; - g_dev->device->lpVtbl->CreateRasterizerState(g_dev->device,&rd,&rs); - ctx->lpVtbl->RSSetState(ctx,rs); - D3D11_DEPTH_STENCIL_DESC dsd={};dsd.DepthEnable=FALSE; - ID3D11DepthStencilState* dss=NULL; - g_dev->device->lpVtbl->CreateDepthStencilState(g_dev->device,&dsd,&dss); - ctx->lpVtbl->OMSetDepthStencilState(ctx,dss,0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx,D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - shader_bind(g_shader, ctx); - - // 地面 - shader_set_matrix(g_shader, ctx, mvp); - draw_quad_3d(ctx, -5, 0, 10, 10, 0.3f, 0.35f, 0.4f, 1); - - // 场景节点 - for (int i=0;ivisible||n->id==0||n->user_type!=1) continue; - // 用世界矩阵变换4个角点 - float corners[4][3] = {{-0.5f,-0.5f,0},{0.5f,-0.5f,0},{0.5f,0.5f,0},{-0.5f,0.5f,0}}; - V v[4]; uint32_t idx[6]={0,1,2,0,2,3}; - float colors[][3]={{1,0.2f,0.2f},{0.2f,1,0.2f},{0.2f,0.2f,1},{1,1,0.2f},{0.5f,0.2f,0.8f},{0.2f,0.8f,0.8f},{0.8f,0.5f,0.2f},{0.5f,0.5f,0.5f}}; - int ci=(i-1)%8; - for(int c=0;c<4;c++){ - float px=0,py=0,pz=0; - for(int r=0;r<4;r++) {float wc=n->world_matrix.m[0][r]*corners[c][0]+n->world_matrix.m[1][r]*corners[c][1]+n->world_matrix.m[2][r]*corners[c][2]+n->world_matrix.m[3][r]; px+=wc*mvp[r*4+0]; py+=wc*mvp[r*4+1]; pz+=wc*mvp[r*4+2];} - // 简化: 直接用世界坐标+投影 - float wx=n->world_matrix.m[3][0]+corners[c][0]; - float wy=n->world_matrix.m[3][1]+corners[c][1]; - float wz=n->world_matrix.m[3][2]+corners[c][2]; - v[c].p[0]=wx; v[c].p[1]=wy; v[c].p[2]=wz; - v[c].n[0]=0; v[c].n[1]=0; v[c].n[2]=1; - v[c].c[0]=colors[ci][0]; v[c].c[1]=colors[ci][1]; v[c].c[2]=colors[ci][2]; v[c].c[3]=1; - } - ID3D11Buffer* vb=NULL,*ib2=NULL; - D3D11_BUFFER_DESC bd2={}; D3D11_SUBRESOURCE_DATA sd2={}; - bd2.ByteWidth=sizeof(V)*4; bd2.Usage=D3D11_USAGE_DEFAULT; bd2.BindFlags=D3D11_BIND_VERTEX_BUFFER; - sd2.pSysMem=v; g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd2,&sd2,&vb); - bd2.ByteWidth=sizeof(uint32_t)*6; bd2.BindFlags=D3D11_BIND_INDEX_BUFFER; - sd2.pSysMem=idx; g_dev->device->lpVtbl->CreateBuffer(g_dev->device,&bd2,&sd2,&ib2); - UINT s2=sizeof(V),o2=0; - ctx->lpVtbl->IASetVertexBuffers(ctx,0,1,&vb,&s2,&o2); - ctx->lpVtbl->IASetIndexBuffer(ctx,ib2,DXGI_FORMAT_R32_UINT,0); - ctx->lpVtbl->DrawIndexed(ctx,6,0,0); - ib2->lpVtbl->Release(ib2); vb->lpVtbl->Release(vb); - } - - if(rs) rs->lpVtbl->Release(rs); - if(dss) dss->lpVtbl->Release(dss); - graphics_device_present(g_dev); -} - -static void on_key(Engine* engine, int key) { if (key==VK_ESCAPE) engine_request_quit(engine); } - -int WINAPI WinMain(HINSTANCE hI,HINSTANCE,LPSTR,int) { - EngineConfig cfg=engine_default_config(); cfg.app_name="lity3d Raw3D"; - Engine* e=engine_create(); if(!engine_init(e,&cfg))return -1; - g_dev=graphics_device_create(); - if(!graphics_device_init(g_dev,window_get_handle(e->window),cfg.window_width,cfg.window_height,1))return -1; - g_shader=shader_create(); shader_compile(g_shader,g_dev->device,NULL,NULL,0,0); - scene_init(&g_scene); - SceneNode* c1=scene_create_node(&g_scene,"Cube1"); scene_set_position(c1,0,0.5f,0); c1->user_type=1; - SceneNode* c2=scene_create_node(&g_scene,"Cube2"); scene_set_position(c2,-3,0.5f,2); c2->user_type=1; - SceneNode* c3=scene_create_node(&g_scene,"Cube3"); scene_set_position(c3,3,0.5f,-2); scene_set_scale(c3,0.5f,0.5f,0.5f); c3->user_type=1; - SceneNode* ch=scene_create_node(&g_scene,"Child"); scene_set_position(ch,2,0,0); ch->user_type=1; scene_set_parent(ch,c1); - engine_set_render_callback(e,on_render); engine_set_key_callback(e,on_key); - engine_run(e); - shader_destroy(g_shader); graphics_device_destroy(g_dev); engine_shutdown(e); - return 0; -} diff --git a/Demo/scene_test.c b/Demo/scene_test.c deleted file mode 100644 index 6ca0919..0000000 --- a/Demo/scene_test.c +++ /dev/null @@ -1,121 +0,0 @@ -// scene_test.c - 场景图 + 网格渲染 -#include "../Engine/Core/engine.h" -#include "../Engine/Core/logger.h" -#include "../Engine/Window/window.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Rendering/shader.h" -#include "../Engine/Rendering/mesh.h" -#include "../Engine/Scene/scene_graph.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" - -static GraphicsDevice* g_dev = NULL; -static Shader* g_shader = NULL; -static Mesh* g_cube = NULL; -static Mesh* g_plane = NULL; -static Scene g_scene; -static SceneNode* g_camera = NULL; -static float g_time = 0; - -static void on_render(Engine* engine) { - if (!g_dev) return; - ID3D11DeviceContext* ctx = g_dev->context; - scene_update(&g_scene); - g_time += (float)engine->delta_time; - - float sw = (float)g_dev->width, sh = (float)g_dev->height; - float fov = 1.0f / tanf(0.5f * 0.785f), aspect = sw / sh; - Vec3 cam_pos; - scene_get_world_position(g_camera, &cam_pos); - - // VP 矩阵 - float proj[16] = {0}; - proj[0] = fov / aspect; proj[5] = -fov; - proj[10] = 1.0f; proj[11] = -1.0f; proj[14] = 0.1f; proj[15] = 1.0f; - - Vec3 eye = cam_pos, target = {0,0,0}, up = {0,1,0}; - Vec3 f, r, u; - vec3_sub(&target, &eye, &f); vec3_normalize(&f, &f); - vec3_cross(&up, &f, &r); vec3_normalize(&r, &r); - vec3_cross(&f, &r, &u); - - float view[16] = {0}; - view[0]=r.x; view[1]=u.x; view[2]=-f.x; - view[4]=r.y; view[5]=u.y; view[6]=-f.y; - view[8]=r.z; view[9]=u.z; view[10]=-f.z; - view[12]=-vec3_dot(&r,&eye); view[13]=-vec3_dot(&u,&eye); view[14]=vec3_dot(&f,&eye); view[15]=1.0f; - - float vp_raw[16] = {0}; - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - vp_raw[i*4+j] = view[i*4+0]*proj[0*4+j]+view[i*4+1]*proj[1*4+j]+view[i*4+2]*proj[2*4+j]+view[i*4+3]*proj[3*4+j]; - Mat4 vp_m, vp_t; - memcpy(&vp_m, vp_raw, sizeof(Mat4)); - mat4_transpose(&vp_m, &vp_t); - - graphics_device_clear(g_dev, 0.15f, 0.18f, 0.25f, 1.0f); - - D3D11_VIEWPORT vport = {0}; vport.Width = sw; vport.Height = sh; vport.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vport); - - D3D11_RASTERIZER_DESC rdesc = {0}; rdesc.FillMode = D3D11_FILL_SOLID; rdesc.CullMode = D3D11_CULL_NONE; - ID3D11RasterizerState* rstate = NULL; - g_dev->device->lpVtbl->CreateRasterizerState(g_dev->device, &rdesc, &rstate); - ctx->lpVtbl->RSSetState(ctx, rstate); - - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - shader_bind(g_shader, ctx); - shader_set_matrix(g_shader, ctx, (float*)&vp_t); - - if (g_plane) mesh_draw(g_plane, ctx); - - for (int i = 0; i < g_scene.node_count; i++) { - SceneNode* node = &g_scene.nodes[i]; - if (!node->visible || node->id == 0 || node->user_type != 1 || !g_cube) continue; - float wvp_raw[16] = {0}; - for (int r2 = 0; r2 < 4; r2++) - for (int c = 0; c < 4; c++) - wvp_raw[r2*4+c] = view[r2*4+0]*node->world_matrix.m[0][c]+view[r2*4+1]*node->world_matrix.m[1][c]+view[r2*4+2]*node->world_matrix.m[2][c]+view[r2*4+3]*node->world_matrix.m[3][c]; - Mat4 wvp_m, wvp_t; - memcpy(&wvp_m, wvp_raw, sizeof(Mat4)); - mat4_transpose(&wvp_m, &wvp_t); - shader_set_matrix(g_shader, ctx, (float*)&wvp_t); - mesh_draw(g_cube, ctx); - } - - if (rstate) rstate->lpVtbl->Release(rstate); - graphics_device_present(g_dev); -} - -static void on_key(Engine* engine, int key) { if (key == VK_ESCAPE) engine_request_quit(engine); } - -int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR cmd, int nS) { - (void)hI;(void)hP;(void)cmd;(void)nS; - EngineConfig cfg = engine_default_config(); - cfg.app_name = "lity3d Scene Test"; - Engine* engine = engine_create(); - if (!engine_init(engine, &cfg)) return -1; - g_dev = graphics_device_create(); - if (!graphics_device_init(g_dev, window_get_handle(engine->window), cfg.window_width, cfg.window_height, 1)) return -1; - g_shader = shader_create(); - shader_compile(g_shader, g_dev->device, NULL, NULL, 0, 0); - g_cube = mesh_create_cube(g_dev->device); - g_plane = mesh_create_plane(g_dev->device, 10.0f); - scene_init(&g_scene); - g_camera = scene_create_node(&g_scene, "Camera"); - scene_set_position(g_camera, 5, 4, 8); - SceneNode* c1 = scene_create_node(&g_scene, "Cube1"); - scene_set_position(c1, 0, 0.5f, 0); c1->user_type = 1; - SceneNode* c2 = scene_create_node(&g_scene, "Cube2"); - scene_set_position(c2, -3, 0.5f, 2); c2->user_type = 1; - SceneNode* c3 = scene_create_node(&g_scene, "Cube3"); - scene_set_position(c3, 3, 0.5f, -2); c3->user_type = 1; scene_set_scale(c3, 0.5f, 0.5f, 0.5f); - SceneNode* child = scene_create_node(&g_scene, "Child"); - scene_set_position(child, 2, 0, 0); child->user_type = 1; scene_set_parent(child, c1); - engine_set_render_callback(engine, on_render); - engine_set_key_callback(engine, on_key); - engine_run(engine); - mesh_destroy(g_cube); mesh_destroy(g_plane); shader_destroy(g_shader); - graphics_device_destroy(g_dev); engine_shutdown(engine); - return 0; -} diff --git a/Demo/scene_test2.c b/Demo/scene_test2.c deleted file mode 100644 index b470be3..0000000 --- a/Demo/scene_test2.c +++ /dev/null @@ -1,54 +0,0 @@ -// scene_test2.c - 最小化场景测试 -#include "../Engine/Core/engine.h" -#include "../Engine/Core/logger.h" -#include "../Engine/Window/window.h" -#include "../Engine/Rendering/graphics_device.h" -#include "../Engine/Scene/scene_graph.h" -#include "../Engine/include/engine_api.h" -#include "../Engine/ASM/math_c_fallback.h" - -static GraphicsDevice* g_dev = NULL; - -static void on_render(Engine* engine) { - if (!g_dev) return; - ID3D11DeviceContext* ctx = g_dev->context; - float clear[4] = {0.2f, 0.3f, 0.5f, 1.0f}; - g_dev->context->lpVtbl->ClearRenderTargetView(g_dev->context, g_dev->render_target, clear); - - D3D11_VIEWPORT vp = {0}; - vp.Width = (float)g_dev->width; vp.Height = (float)g_dev->height; - vp.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vp); - graphics_device_present(g_dev); -} - -static void on_key(Engine* engine, int key) { - if (key == VK_ESCAPE) engine_request_quit(engine); -} - -int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR cmd, int nS) { - (void)hI;(void)hP;(void)cmd;(void)nS; - LOG_INFO("=== lity3d Scene Test ==="); - EngineConfig cfg = engine_default_config(); - cfg.app_name = "lity3d Scene Test"; - Engine* engine = engine_create(); - if (!engine_init(engine, &cfg)) return -1; - g_dev = graphics_device_create(); - if (!graphics_device_init(g_dev, window_get_handle(engine->window), cfg.window_width, cfg.window_height, 1)) return -1; - LOG_INFO("D3D11 ready"); - Scene scene; scene_init(&scene); - SceneNode* n1 = scene_create_node(&scene, "A"); - scene_set_position(n1, 1, 0, 0); - SceneNode* n2 = scene_create_node(&scene, "B"); - scene_set_parent(n2, n1); - scene_set_position(n2, 0, 2, 0); - scene_update(&scene); - LOG_INFO("A world pos: (%.1f,%.1f,%.1f)", scene.nodes[1].world_matrix.m[3][0], scene.nodes[1].world_matrix.m[3][1], scene.nodes[1].world_matrix.m[3][2]); - LOG_INFO("B world pos: (%.1f,%.1f,%.1f)", scene.nodes[2].world_matrix.m[3][0], scene.nodes[2].world_matrix.m[3][1], scene.nodes[2].world_matrix.m[3][2]); - engine_set_render_callback(engine, on_render); - engine_set_key_callback(engine, on_key); - engine_run(engine); - graphics_device_destroy(g_dev); - engine_shutdown(engine); - return 0; -} diff --git a/Demo/test.ly b/Demo/test.ly deleted file mode 100644 index 5037860..0000000 --- a/Demo/test.ly +++ /dev/null @@ -1,54 +0,0 @@ -# lity3d 积木脚本 - 测试解释器 -# 开始 -> 移动物体 -> 打印 -> 循环3次 -> 移动物体 - -[B] -id=1 -name=开始 -p=100,100 -c=0 - -[B] -id=2 -name=移动物体 -p=350,100 -c=1 - -[B] -id=3 -name=打印 -p=600,100 -d=Hello World -c=3 - -[B] -id=4 -name=循环 -p=100,250 -d=3 -c=2 - -[B] -id=5 -name=移动物体 -p=350,250 -c=1 - -# 连线: 开始.输出0 -> 移动物体.执行0 -[W] -a=10000 -b=20000 - -# 移动物体.执行0 -> 打印.执行0 -[W] -a=20000 -b=30000 - -# 打印.执行0 -> 循环.执行0 -[W] -a=30000 -b=40000 - -# 循环.执行0 -> 移动物体2.执行0 -[W] -a=40000 -b=50000 diff --git a/Editor/Cargo.toml b/Editor/Cargo.toml deleted file mode 100644 index 35e77cd..0000000 --- a/Editor/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "lity3d-editor" -version = "1.0.0" -edition = "2021" - -[dependencies] -eframe = { version = "0.31", features = ["default"] } -rfd = "0.15" diff --git a/Editor/editor.c b/Editor/editor.c deleted file mode 100644 index 0713f13..0000000 --- a/Editor/editor.c +++ /dev/null @@ -1,304 +0,0 @@ -// lity_editor.c - Lity3D Editor (Win32 Unicode, 50+ built-in languages) -#include -#include -#include -#include -#include -#include -#include - -#define IDC_TREE 1001 -#define IDC_EDIT 1002 -#define IDC_CONSOLE 1003 -#define IDM_NEW 2001 -#define IDM_OPEN 2002 -#define IDM_SAVE 2003 -#define IDM_RUN 2004 -#define IDM_BUILD 2005 -#define IDM_PACKAGE 2006 -#define IDM_ABOUT 2007 -#define IDM_LANG_BASE 3000 -#define NUM_KEYS 20 -#define NUM_LANGS 50 - -static HWND g_hwnd, g_tree, g_edit, g_console; -static WCHAR g_current_file[MAX_PATH] = L""; -static WCHAR g_engine_dir[MAX_PATH] = L""; - -// Key names -static const char* g_keys[NUM_KEYS] = { - "title","file","build","scene","help","lang", - "new","open","save","exit","run","compile", - "package","explorer","output","ready","about","ok","kill","build_first" -}; -// lang_code, display_name, translations[NUM_KEYS] -static struct { const char* code; const char* name; const WCHAR* trans[NUM_KEYS]; } g_langs[NUM_LANGS] = { - {"en","English",{L"Lity3D Editor",L"File",L"Build",L"Scene",L"Help",L"Language",L"New",L"Open",L"Save",L"Exit",L"Run",L"Build Engine",L"Package EXE",L"Explorer",L"Output",L"Ready",L"About",L"OK",L"Process killed",L"Build first"}}, - {"zh","中文",{L"Lity3D 编辑器",L"文件",L"构建",L"场景",L"帮助",L"语言",L"新建",L"打开",L"保存",L"退出",L"运行游戏",L"编译引擎",L"打包 EXE",L"资源管理器",L"输出",L"就绪",L"关于",L"确定",L"进程已终止",L"请先编译引擎"}}, - {"ja","日本語",{L"Lity3D エディタ",L"ファイル",L"ビルド",L"シーン",L"ヘルプ",L"言語",L"新規",L"開く",L"保存",L"終了",L"ゲーム実行",L"エンジンビルド",L"EXE出力",L"エクスプローラ",L"出力",L"準備完了",L"について",L"OK",L"停止済み",L"先にビルド"}}, - {"ko","한국어",{L"Lity3D 편집기",L"파일",L"빌드",L"씬",L"도움말",L"언어",L"새로 만들기",L"열기",L"저장",L"종료",L"게임 실행",L"엔진 빌드",L"EXE 패키징",L"탐색기",L"출력",L"준비",L"정보",L"확인",L"중지됨",L"먼저 빌드"}}, - {"es","Español",{L"Lity3D Editor",L"Archivo",L"Compilar",L"Escena",L"Ayuda",L"Idioma",L"Nuevo",L"Abrir",L"Guardar",L"Salir",L"Ejecutar",L"Compilar motor",L"Empaquetar",L"Explorador",L"Salida",L"Listo",L"Acerca de",L"OK",L"Detenido",L"Compilar primero"}}, - {"fr","Français",{L"Lity3D Éditeur",L"Fichier",L"Construire",L"Scène",L"Aide",L"Langue",L"Nouveau",L"Ouvrir",L"Enregistrer",L"Quitter",L"Exécuter",L"Compiler",L"Package",L"Explorateur",L"Sortie",L"Prêt",L"À propos",L"OK",L"Arrêté",L"Compiler d'abord"}}, - {"de","Deutsch",{L"Lity3D Editor",L"Datei",L"Erstellen",L"Szene",L"Hilfe",L"Sprache",L"Neu",L"Öffnen",L"Speichern",L"Beenden",L"Spiel starten",L"Engine erstellen",L"EXE paketieren",L"Explorer",L"Ausgabe",L"Bereit",L"Über",L"OK",L"Gestoppt",L"Erst bauen"}}, - {"ru","Русский",{L"Lity3D Редактор",L"Файл",L"Сборка",L"Сцена",L"Справка",L"Язык",L"Новый",L"Открыть",L"Сохранить",L"Выход",L"Запуск",L"Собрать",L"Упаковать",L"Проводник",L"Вывод",L"Готово",L"О программе",L"OK",L"Остановлено",L"Сначала собрать"}}, - {"pt","Português",{L"Lity3D Editor",L"Arquivo",L"Compilar",L"Cena",L"Ajuda",L"Idioma",L"Novo",L"Abrir",L"Salvar",L"Sair",L"Executar",L"Compilar engine",L"Empacotar",L"Explorador",L"Saída",L"Pronto",L"Sobre",L"OK",L"Parado",L"Compilar primeiro"}}, - {"it","Italiano",{L"Lity3D Editor",L"File",L"Compila",L"Scena",L"Aiuto",L"Lingua",L"Nuovo",L"Apri",L"Salva",L"Esci",L"Esegui",L"Compila engine",L"Pacchetta",L"Esplora",L"Output",L"Pronto",L"Info",L"OK",L"Fermato",L"Compila prima"}}, - {"tr","Türkçe",{L"Lity3D Editör",L"Dosya",L"Derle",L"Sahne",L"Yardım",L"Dil",L"Yeni",L"Aç",L"Kaydet",L"Çıkış",L"Çalıştır",L"Motoru derle",L"Paketle",L"Gezgin",L"Çıktı",L"Hazır",L"Hakkında",L"Tamam",L"Durduruldu",L"Önce derle"}}, - {"ar","العربية",{L"Lity3D محرر",L"ملف",L"بناء",L"مشهد",L"مساعدة",L"لغة",L"جديد",L"فتح",L"حفظ",L"خروج",L"تشغيل",L"بناء المحرك",L"تغليف",L"مستكشف",L"مخرجات",L"جاهز",L"حول",L"موافق",L"تم الإيقاف",L"ابنِ أولاً"}}, - {"hi","हिन्दी",{L"Lity3D संपादक",L"फ़ाइल",L"बिल्ड",L"दृश्य",L"सहायता",L"भाषा",L"नया",L"खोलें",L"सहेजें",L"बाहर",L"चलाएं",L"इंजन बिल्ड",L"EXE पैकेज",L"एक्सप्लोरर",L"आउटपुट",L"तैयार",L"के बारे में",L"ठीक है",L"बंद",L"पहले बिल्ड"}}, - {"th","ภาษาไทย",{L"Lity3D ตัวแก้ไข",L"ไฟล์",L"สร้าง",L"ฉาก",L"ช่วยเหลือ",L"ภาษา",L"ใหม่",L"เปิด",L"บันทึก",L"ออก",L"รันเกม",L"สร้างเอนจิ้น",L"打包 EXE",L"ตัวสำรวจ",L"ผลลัพธ์",L"พร้อม",L"เกี่ยวกับ",L"ตกลง",L"หยุดแล้ว",L"สร้างก่อน"}}, - {"vi","Tiếng Việt",{L"Lity3D Trình soạn",L"Tệp",L"Xây dựng",L"Cảnh",L"Trợ giúp",L"Ngôn ngữ",L"Mới",L"Mở",L"Lưu",L"Thoát",L"Chạy game",L"Build engine",L"Gói EXE",L"Duyệt",L"Đầu ra",L"Sẵn sàng",L"Giới thiệu",L"OK",L"Đã dừng",L"Build trước"}}, - {"id","Bahasa",{L"Lity3D Editor",L"Berkas",L"Build",L"Sken",L"Bantuan",L"Bahasa",L"Baru",L"Buka",L"Simpan",L"Keluar",L"Jalankan",L"Build Engine",L"Paket EXE",L"Penjelajah",L"Output",L"Siap",L"Tentang",L"OK",L"Berhenti",L"Build dulu"}}, - {"pl","Polski",{L"Lity3D Edytor",L"Plik",L"Kompiluj",L"Scena",L"Pomoc",L"Język",L"Nowy",L"Otwórz",L"Zapisz",L"Wyjście",L"Uruchom",L"Kompiluj engine",L"Pakietuj",L"Eksplorator",L"Wyjście",L"Gotowy",L"O programie",L"OK",L"Zatrzymano",L"Najpierw kompiluj"}}, - {"nl","Nederlands",{L"Lity3D Editor",L"Bestand",L"Bouwen",L"Scène",L"Help",L"Taal",L"Nieuw",L"Open",L"Opslaan",L"Afsluiten",L"Uitvoeren",L"Engine bouwen",L"Pakket",L"Verkenner",L"Uitvoer",L"Gereed",L"Over",L"OK",L"Gestopt",L"Eerst bouwen"}}, - {"uk","Українська",{L"Lity3D Редактор",L"Файл",L"Збірка",L"Сцена",L"Довідка",L"Мова",L"Новий",L"Відкрити",L"Зберегти",L"Вихід",L"Запуск",L"Зібрати",L"Упакувати",L"Провідник",L"Вивід",L"Готово",L"Про програму",L"OK",L"Зупинено",L"Спочатку зібрати"}}, - {"cs","Čeština",{L"Lity3D Editor",L"Soubor",L"Sestavit",L"Scéna",L"Nápověda",L"Jazyk",L"Nový",L"Otevřít",L"Uložit",L"Konec",L"Spustit",L"Sestavit engine",L"Zabalit",L"Průzkumník",L"Výstup",L"Připraveno",L"O",L"OK",L"Zastaveno",L"Nejdřív sestavit"}}, - {"ro","Română",{L"Lity3D Editor",L"Fișier",L"Compilă",L"Scenă",L"Ajutor",L"Limbă",L"Nou",L"Deschide",L"Salvează",L"Ieșire",L"Rulează",L"Compilează",L"Pachet",L"Explorator",L"Ieșire",L"Gata",L"Despre",L"OK",L"Oprit",L"Compilează prima"}}, - {"sv","Svenska",{L"Lity3D Redigerare",L"Fil",L"Bygg",L"Scen",L"Hjälp",L"Språk",L"Ny",L"Öppna",L"Spara",L"Avsluta",L"Kör",L"Bygg engine",L"Paketera",L"Utforskare",L"Utdata",L"Redo",L"Om",L"OK",L"Stoppad",L"Bygg först"}}, - {"fi","Suomi",{L"Lity3D Editor",L"Tiedosto",L"Käännä",L"Sken",L"Ohje",L"Kieli",L"Uusi",L"Avaa",L"Tallenna",L"Lopeta",L"Käynnistä",L"Käännä engine",L"Paketoi",L"Selain",L"Tuloste",L"Valmis",L"Tietoja",L"OK",L"Pysäytetty",L"Käännä ensin"}}, - {"da","Dansk",{L"Lity3D Editor",L"Fil",L"Byg",L"Scene",L"Hjælp",L"Sprog",L"Ny",L"Åbn",L"Gem",L"Afslut",L"Kør",L"Byg engine",L"Pakke",L"Stifinder",L"Output",L"Klar",L"Om",L"OK",L"Stoppet",L"Byg først"}}, - {"no","Norsk",{L"Lity3D Editor",L"Fil",L"Bygg",L"Scene",L"Hjelp",L"Språk",L"Ny",L"Åpne",L"Lagre",L"Avslutt",L"Kjør",L"Bygg engine",L"Pakke",L"Utforsker",L"Utdata",L"Klar",L"Om",L"OK",L"Stoppet",L"Bygg først"}}, - {"el","Ελληνικά",{L"Lity3D Επεξεργαστής",L"Αρχείο",L"Κατασκευή",L"Σκηνή",L"Βοήθεια",L"Γλώσσα",L"Νέο",L"Άνοιγμα",L"Αποθήκευση",L"Έξοδος",L"Εκτέλεση",L"Κατασκευή",L"Πακέτο",L"Ανιχνευτής",L"Έξοδος",L"Έτοιμο",L"Σχετικά",L"OK",L"Σταμάτησε",L"Κατασκευή πρώτα"}}, - {"he","עברית",{L"Lity3D עורך",L"קובץ",L"בנייה",L"סצנה",L"עזרה",L"שפה",L"חדש",L"פתח",L"שמור",L"יציאה",L"הרץ",L"בנה מנוע",L"ארוז",L"סייר",L"פלט",L"מוכן",L"אודות",L"אישור",L"נעצר",L"בנה קודם"}}, - {"ms","Bahasa Melayu",{L"Lity3D Editor",L"Fail",L"Bina",L"Adegan",L"Bantuan",L"Bahasa",L"Baharu",L"Buka",L"Simpan",L"Keluar",L"Jalankan",L"Bina engine",L"Pakej",L"Peneroka",L"Output",L"Sedia",L"Tentang",L"OK",L"Dihentikan",L"Bina dahulu"}}, - {"hu","Magyar",{L"Lity3D Szerkesztő",L"Fájl",L"Fordítás",L"Jelenet",L"Súgó",L"Nyelv",L"Új",L"Megnyitás",L"Mentés",L"Kilépés",L"Futtatás",L"Fordítás",L"Csomagolás",L"Fájlkezelő",L"Kimenet",L"Kész",L"Névjegy",L"OK",L"Leállítva",L"Előbb fordíts"}}, - {"sk","Slovenčina",{L"Lity3D Editor",L"Súbor",L"Kompilácia",L"Scéna",L"Pomoc",L"Jazyk",L"Nový",L"Otvoriť",L"Uložiť",L"Ukončiť",L"Spustiť",L"Skompilovať",L"Balenie",L"Prieskumník",L"Výstup",L"Pripravené",L"O",L"OK",L"Zastavené",L"Skompilovať prvú"}}, - {"bg","Български",{L"Lity3D Редактор",L"Файл",L"Компилация",L"Сцена",L"Помощ",L"Език",L"Нов",L"Отвори",L"Запази",L"Изход",L"Стартирай",L"Компилирай",L"Опаковай",L"Проводник",L"Изход",L"Готово",L"Относно",L"OK",L"Спряно",L"Първо компилирай"}}, - {"hr","Hrvatski",{L"Lity3D Urednik",L"Datoteka",L"Izgradi",L"Scena",L"Pomoć",L"Jezik",L"Novo",L"Otvori",L"Spremi",L"Izlaz",L"Pokreni",L"Izgradi",L"Pakiraj",L"Istraživač",L"Izlaz",L"Spreman",L"O",L"OK",L"Zaustavljeno",L"Prvo izgradi"}}, - {"sr","Српски",{L"Lity3D Уредник",L"Датотека",L"Изградња",L"Сцена",L"Помоћ",L"Језик",L"Ново",L"Отвори",L"Сачувај",L"Излаз",L"Покрени",L"Изгради",L"Пакуј",L"Истраживач",L"Излаз",L"Спреман",L"О",L"OK",L"Заустављено",L"Прво изгради"}}, - {"sl","Slovenščina",{L"Lity3D Urejevalnik",L"Datoteka",L"Izgradi",L"Scena",L"Pomoč",L"Jezik",L"Novo",L"Odpri",L"Shrani",L"Izhod",L"Zaženi",L"Izgradi",L"Pakiraj",L"Raziskovalec",L"Izhod",L"Pripravljeno",L"O",L"OK",L"Ustavljeno",L"Najprej izgradi"}}, - {"lt","Lietuvių",{L"Lity3D Redaktorius",L"Failas",L"Kompiliuoti",L"Scena",L"Pagalba",L"Kalba",L"Naujas",L"Atidaryti",L"Išsaugoti",L"Išeiti",L"Paleisti",L"Kompiliuoti",L"Pakuot",L"Naršyklė",L"Išvestis",L"Pasirengęs",L"Apie",L"OK",L"Sustabdyta",L"Kompiliuoti pirmiau"}}, - {"lv","Latviešu",{L"Lity3D Redaktors",L"Fails",L"Kompilēt",L"Aina",L"Palīdzība",L"Valoda",L"Jauns",L"Atvērt",L"Saglabāt",L"Izeja",L"Palaist",L"Kompilēt",L"Pakēt",L"Pārlūks",L"Izeja",L"Gatavs",L"Par",L"OK",L"Aizturēts",L"Vispirums kompilēt"}}, - {"et","Eesti",{L"Lity3D Redaktor",L"Fail",L"Kompileeri",L"Stseen",L"Abi",L"Keel",L"Uus",L"Ava",L"Salvesta",L"Välju",L"Käivita",L"Kompileeri",L"Pakendi",L"Eksploorija",L"Väljund",L"Valmis",L"Teave",L"OK",L"Peatatud",L"Esmalt kompileeri"}}, - {"fa","فارسی",{L"Lity3D ویرایشگر",L"پرونده",L"ساخت",L"صحنه",L"راهنما",L"زبان",L"جدید",L"باز کردن",L"ذخیره",L"خروج",L"اجرا",L"ساخت موتور",L"بسته بندی",L"کاوشگر",L"خروجی",L"آماده",L"درباره",L"تأیید",L"متوقف شد",L"اول بساز"}}, - {"bn","বাংলা",{L"Lity3D সম্পাদক",L"ফাইল",L"বিল্ড",L"দৃশ্য",L"সাহায্য",L"ভাষা",L"নতুন",L"খুলুন",L"সংরক্ষণ",L"বের হোন",L"চালান",L"ইঞ্জিন বিল্ড",L"EXE প্যাকেজ",L"এক্সপ্লোরার",L"আউটপুট",L"প্রস্তুত",L"সম্পর্কে",L"ঠিক আছে",L"বন্ধ",L"প্রথমে বিল্ড"}}, - {"sw","Kiswahili",{L"Lity3D Mhariri",L"Faili",L"Jenga",L"Onyesho",L"Msaada",L"Lugha",L"Mpya",L"Fungua",L"Hifadhi",L"Ondoka",L"Endesha",L"Jenga injini",L"Pakiti",L"Vinara",L"Matokeo",L"Iko tayari",L"Kuhusu",L"Sawa",L"Imesimamishwa",L"Jenga kwanza"}}, - {"ta","தமிழ்",{L"Lity3D திருத்தி",L"கோப்பு",L"உருவாக்கு",L"காட்சி",L"உதவி",L"மொழி",L"புதிய",L"திற",L"சேமி",L"வெளியேறு",L"இயக்கு",L"இயந்திரம் உருவாக்கு",L"EXE பேக்கேஜ்",L"ஆராய்ச்சியாளர்",L"வெளியீடு",L"தயார்",L"பற்றி",L"சரி",L"நிறுத்தப்பட்டது",L"முதலில் உருவாக்கு"}}, - {"ml","മലയാളം",{L"Lity3D എഡിറ്റർ",L"ഫയൽ",L"ബിൽഡ്",L"രംഗം",L"സഹായം",L"ഭാഷ",L"പുതിയ",L"തുറക്കുക",L"സേവ് ചെയ്യുക",L"പുറത്തുപോകുക",L"റൺ ചെയ്യുക",L"എഞ്ചിൻ ബിൽഡ്",L"EXE പാക്കേജ്",L"എക്സ്പ്ലോറർ",L"ഔട്ട്പുട്ട്",L"തയ്യാർ",L"കുറിച്ച്",L"ശരി",L"നിർത്തി",L"ആദ്യം ബിൽഡ്"}}, - {"te","తెలుగు",{L"Lity3D ఎడిటర్",L"ఫైల్",L"బిల్డ్",L"దృశ్యం",L"సహాయం",L"భాష",L"కొత్త",L"తెరవండి",L"సేవ్",L"నిష్క్రమించండి",L"రన్",L"ఇంజిన్ బిల్డ్",L"EXE ప్యాకేజ్",L"ఎక్స్‌ప్లోరర్",L"అవుట్‌పుట్",L"సిద్ధం",L"గురించి",L"సరే",L"ఆపబడింది",L"మొదట బిల్డ్"}}, - {"ur","اردو",{L"Lity3D ایڈیٹر",L"فائل",L"بلڈ",L"منظر",L"مدد",L"زبان",L"نیا",L"کھولیں",L"محفوظ",L"باہر",L"چلائیں",L"اینجن بلڈ",L"EXE پیکج",L"ایکسپلورر",L"آؤٹ پٹ",L"تیار",L"بارے میں",L"ٹھیک ہے",L"روک دیا",L"پہلے بلڈ"}}, - {"tl","Tagalog",{L"Lity3D Editor",L"File",L"Build",L"Scene",L"Tulong",L"Wika",L"Bago",L"Buksan",L"I-save",L"Lumabas",L"I-run",L"Build engine",L"Package",L"Explorer",L"Output",L"Handa",L"Tungkol",L"OK",L"Stopped",L"Build muna"}}, -}; - -static int g_lang_count = NUM_LANGS; -static int g_cur = 0; - -static const WCHAR* T(int k) { - if (k < NUM_KEYS && g_langs[g_cur].trans[k]) return g_langs[g_cur].trans[k]; - return L"?"; -} - -static int detect_lang(void) { - WCHAR buf[10]; - if (GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, buf, 10)) { - char abuf[16]; WideCharToMultiByte(CP_UTF8, 0, buf, -1, abuf, 16, NULL, NULL); - for (int i = 0; i < g_lang_count; i++) - if (!_stricmp(g_langs[i].code, abuf)) return i; - } - return 0; -} - -static void populate_tree(void) { - TreeView_DeleteAllItems(g_tree); - TVINSERTSTRUCTW tvi = {0}; tvi.hParent = TVI_ROOT; tvi.hInsertAfter = TVI_LAST; - tvi.item.mask = TVIF_TEXT; tvi.item.pszText = L"lity3d"; - HTREEITEM root = TreeView_InsertItem(g_tree, &tvi); - WIN32_FIND_DATAW fd; WCHAR pat[MAX_PATH]; - wsprintfW(pat, L"%s\\*", g_engine_dir); - HANDLE hF = FindFirstFileW(pat, &fd); - if (hF == INVALID_HANDLE_VALUE) return; - do { - if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) continue; - if (!wcscmp(fd.cFileName,L".")||!wcscmp(fd.cFileName,L"..")) continue; - if (!wcscmp(fd.cFileName,L".git")||!wcscmp(fd.cFileName,L"build")||!wcscmp(fd.cFileName,L"target")) continue; - tvi.hParent = root; tvi.item.pszText = fd.cFileName; - HTREEITEM d = TreeView_InsertItem(g_tree, &tvi); - WCHAR sub[MAX_PATH]; wsprintfW(sub, L"%s\\%s\\*", g_engine_dir, fd.cFileName); - WIN32_FIND_DATAW fd2; HANDLE h2 = FindFirstFileW(sub, &fd2); - if (h2 != INVALID_HANDLE_VALUE) { - do { if (fd2.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; - tvi.hParent = d; tvi.item.pszText = fd2.cFileName; - TreeView_InsertItem(g_tree, &tvi); - } while (FindNextFileW(h2, &fd2)); - FindClose(h2); - } - } while (FindNextFileW(hF, &fd)); - FindClose(hF); -} - -static void open_file_at(WCHAR* path) { - HANDLE hf = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if (hf == INVALID_HANDLE_VALUE) return; - DWORD sz = GetFileSize(hf, NULL); char* buf = malloc(sz + 1); DWORD rd; - ReadFile(hf, buf, sz, &rd, NULL); buf[sz] = '\0'; CloseHandle(hf); - SetWindowTextA(g_edit, buf); free(buf); - wcscpy(g_current_file, path); -} - -static void open_file_dialog(void) { - WCHAR file[MAX_PATH] = L""; OPENFILENAMEW of = {sizeof(of)}; - of.lpstrFilter = L"All\0*.*\0Python\0*.py\0C\0*.c;*.h\0"; - of.lpstrFile = file; of.nMaxFile = MAX_PATH; of.Flags = OFN_FILEMUSTEXIST; - if (GetOpenFileNameW(&of)) open_file_at(file); -} - -static void save_file(void) { - if (!g_current_file[0]) { open_file_dialog(); return; } - int len = GetWindowTextLengthA(g_edit); char* buf = malloc(len + 1); - GetWindowTextA(g_edit, buf, len + 1); - HANDLE hf = CreateFileW(g_current_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); - if (hf != INVALID_HANDLE_VALUE) { DWORD wr; WriteFile(hf, buf, len, &wr, NULL); CloseHandle(hf); } - free(buf); -} - -static void console_msg(const char* msg) { - int len = GetWindowTextLengthA(g_console); - SendMessageA(g_console, EM_SETSEL, len, len); - SendMessageA(g_console, EM_REPLACESEL, FALSE, (LPARAM)msg); -} - -static void rebuild_lang_menu(void) { - HMENU hBar = GetMenu(g_hwnd); - HMENU hOld = GetSubMenu(hBar, 3); - HMENU hLang = CreatePopupMenu(); - for (int i = 0; i < g_lang_count; i++) { - WCHAR label[192]; - wsprintfW(label, L"%hs (%hs)", g_langs[i].name, g_langs[i].code); - UINT flags = (i == g_cur) ? (MF_STRING | MF_CHECKED) : MF_STRING; - AppendMenuW(hLang, flags, IDM_LANG_BASE + i, label); - } - RemoveMenu(hBar, 3, MF_BYPOSITION); - InsertMenuW(hBar, 3, MF_BYPOSITION | MF_POPUP, (UINT_PTR)hLang, L"语言"); - if (hOld) DestroyMenu(hOld); - DrawMenuBar(g_hwnd); -} - -static LRESULT CALLBACK WP(HWND h, UINT m, WPARAM w, LPARAM l) { - switch (m) { - case WM_COMMAND: { - int id = LOWORD(w); - if (id == IDM_NEW) { SetWindowTextA(g_edit, ""); g_current_file[0] = 0; } - else if (id == IDM_OPEN) open_file_dialog(); - else if (id == IDM_SAVE) save_file(); - else if (id == IDM_RUN) { - WCHAR p[MAX_PATH]; wsprintfW(p, L"%s\\build\\lity.exe", g_engine_dir); - if (GetFileAttributesW(p) == INVALID_FILE_ATTRIBUTES) { console_msg("[!] Build first\n"); return 0; } - ShellExecuteW(NULL, L"open", p, NULL, g_engine_dir, SW_SHOWNORMAL); - } - else if (id == IDM_BUILD) { - WCHAR cmd[MAX_PATH*2]; wsprintfW(cmd, L"/c set PATH=C:\\mingw64\\bin;%%PATH%%&& cd /d %s\\build && cmake --build . -j4", g_engine_dir); - ShellExecuteW(NULL, L"open", L"cmd.exe", cmd, NULL, SW_SHOWNORMAL); - } - else if (id == IDM_ABOUT) MessageBoxW(h, L"Lity3D Engine v1.0", L"About", MB_OK); - else if (id >= IDM_LANG_BASE && id < IDM_LANG_BASE + g_lang_count) { - g_cur = id - IDM_LANG_BASE; - SetWindowTextW(g_hwnd, T(0)); - rebuild_lang_menu(); - populate_tree(); - // Rebuild ALL menus with new language - HMENU hBar = GetMenu(g_hwnd); - HMENU hFile = CreatePopupMenu(); - AppendMenuW(hFile, MF_STRING, IDM_NEW, T(6)); - AppendMenuW(hFile, MF_STRING, IDM_OPEN, T(7)); - AppendMenuW(hFile, MF_STRING, IDM_SAVE, T(8)); - AppendMenuW(hFile, MF_SEPARATOR, 0, NULL); - AppendMenuW(hFile, MF_STRING, IDM_ABOUT, T(16)); - RemoveMenu(hBar, 0, MF_BYPOSITION); - InsertMenuW(hBar, 0, MF_BYPOSITION | MF_POPUP, (UINT_PTR)hFile, T(1)); - DestroyMenu(GetSubMenu(hBar, 1)); // old build menu gone after insert - // Rebuild build menu - HMENU hBuild = CreatePopupMenu(); - AppendMenuW(hBuild, MF_STRING, IDM_RUN, T(10)); - AppendMenuW(hBuild, MF_SEPARATOR, 0, NULL); - AppendMenuW(hBuild, MF_STRING, IDM_BUILD, T(11)); - AppendMenuW(hBuild, MF_STRING, IDM_PACKAGE, T(12)); - RemoveMenu(hBar, 1, MF_BYPOSITION); - InsertMenuW(hBar, 1, MF_BYPOSITION | MF_POPUP, (UINT_PTR)hBuild, T(2)); - DestroyMenu(GetSubMenu(hBar, 3)); // old help - // Rebuild help menu - HMENU hHelp = CreatePopupMenu(); - AppendMenuW(hHelp, MF_STRING, IDM_ABOUT, T(16)); - RemoveMenu(hBar, 3, MF_BYPOSITION); - InsertMenuW(hBar, 3, MF_BYPOSITION | MF_POPUP, (UINT_PTR)hHelp, T(4)); - DrawMenuBar(g_hwnd); - } - break; } - case WM_NOTIFY: { - NMHDR* nm = (NMHDR*)l; - if (nm->idFrom == IDC_TREE && nm->code == TVN_SELCHANGED) { - TVITEMW ti = {0}; ti.mask = TVIF_TEXT | TVIF_HANDLE; - ti.hItem = TreeView_GetSelection(g_tree); - WCHAR name[MAX_PATH]; ti.pszText = name; ti.cchTextMax = MAX_PATH; - TreeView_GetItem(g_tree, &ti); - if (!ti.hItem) break; - HTREEITEM par = TreeView_GetParent(g_tree, ti.hItem); - WCHAR full[MAX_PATH]; - if (par) { WCHAR parent[MAX_PATH]={0}; TVITEMW pti={0}; - pti.mask=TVIF_TEXT; pti.hItem=par; pti.pszText=parent; pti.cchTextMax=MAX_PATH; - TreeView_GetItem(g_tree, &pti); - wsprintfW(full, L"%s\\%s\\%s", g_engine_dir, parent, name); - } else wsprintfW(full, L"%s\\%s", g_engine_dir, name); - DWORD attr = GetFileAttributesW(full); - if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY)) - open_file_at(full); - } - break; } - case WM_SIZE: { - int w2 = LOWORD(l), h2 = HIWORD(l); - if (w2<100||h2<100) break; - int tw=220, ch=160; - MoveWindow(g_tree,0,0,tw,h2-ch,TRUE); - MoveWindow(g_edit,tw+4,0,w2-tw-4,h2-ch,TRUE); - MoveWindow(g_console,0,h2-ch,w2,ch-24,TRUE); - break; } - case WM_DESTROY: PostQuitMessage(0); return 0; - } - return DefWindowProcW(h, m, w, l); -} - -int WINAPI wWinMain(HINSTANCE hI, HINSTANCE hP, LPWSTR nC, int nS) { - (void)hP; (void)nC; (void)nS; - GetModuleFileNameW(NULL, g_engine_dir, MAX_PATH); - WCHAR* sl = wcsrchr(g_engine_dir, L'\\'); if (sl) *sl = 0; - sl = wcsrchr(g_engine_dir, L'\\'); if (sl) *sl = 0; - INITCOMMONCONTROLSEX icc = {sizeof(icc), ICC_TREEVIEW_CLASSES}; InitCommonControlsEx(&icc); - g_cur = detect_lang(); - WNDCLASSEXW wc = {sizeof(wc)}; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WP; - wc.hInstance = hI; wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); - wc.lpszClassName = L"LityEditor"; wc.hCursor = LoadCursor(NULL, IDC_ARROW); - RegisterClassExW(&wc); - g_hwnd = CreateWindowExW(0, L"LityEditor", T(0), WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN, 100,100,1400,900, NULL, NULL, hI, NULL); - g_tree = CreateWindowExW(WS_EX_CLIENTEDGE, WC_TREEVIEWW, L"", WS_CHILD|WS_VISIBLE|TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT, 0,0,220,600, g_hwnd, (HMENU)IDC_TREE, hI, NULL); - g_edit = CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|ES_MULTILINE|ES_AUTOVSCROLL, 224,0,1176,600, g_hwnd, (HMENU)IDC_EDIT, hI, NULL); - SendMessageW(g_edit, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE); - g_console = CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD|WS_VISIBLE|WS_VSCROLL|ES_MULTILINE|ES_READONLY, 0,600,1400,136, g_hwnd, (HMENU)IDC_CONSOLE, hI, NULL); - HFONT hf = CreateFontW(14,0,0,0,FW_NORMAL,0,0,0,DEFAULT_CHARSET,0,0,0,FIXED_PITCH,L"Consolas"); - SendMessageW(g_console, WM_SETFONT, (WPARAM)hf, TRUE); - HMENU hBar = CreateMenu(); - HMENU hFile = CreatePopupMenu(); - AppendMenuW(hFile,MF_STRING,IDM_NEW,T(6)); AppendMenuW(hFile,MF_STRING,IDM_OPEN,T(7)); - AppendMenuW(hFile,MF_STRING,IDM_SAVE,T(8)); AppendMenuW(hFile,MF_SEPARATOR,0,NULL); - AppendMenuW(hFile,MF_STRING,IDM_ABOUT,T(16)); - AppendMenuW(hBar,MF_POPUP,(UINT_PTR)hFile,T(1)); - HMENU hBuild = CreatePopupMenu(); - AppendMenuW(hBuild,MF_STRING,IDM_RUN,T(10)); AppendMenuW(hBuild,MF_SEPARATOR,0,NULL); - AppendMenuW(hBuild,MF_STRING,IDM_BUILD,T(11)); AppendMenuW(hBuild,MF_STRING,IDM_PACKAGE,T(12)); - AppendMenuW(hBar,MF_POPUP,(UINT_PTR)hBuild,T(2)); - HMENU hLang = CreatePopupMenu(); - for (int i = 0; i < g_lang_count; i++) { - WCHAR label[192]; wsprintfW(label, L"%hs (%hs)", g_langs[i].name, g_langs[i].code); - UINT flags = (i == g_cur) ? (MF_STRING|MF_CHECKED) : MF_STRING; - AppendMenuW(hLang, flags, IDM_LANG_BASE + i, label); - } - AppendMenuW(hBar,MF_POPUP,(UINT_PTR)hLang,T(5)); - HMENU hHelp = CreatePopupMenu(); - AppendMenuW(hHelp,MF_STRING,IDM_ABOUT,T(16)); - AppendMenuW(hBar,MF_POPUP,(UINT_PTR)hHelp,T(4)); - SetMenu(g_hwnd,hBar); - populate_tree(); - console_msg("Lity3D Editor ready.\n"); - ShowWindow(g_hwnd,SW_SHOW); - MSG msg; - while(GetMessageW(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessageW(&msg);} - return (int)msg.wParam; -} diff --git a/Editor/src/main.rs b/Editor/src/main.rs deleted file mode 100644 index b79a63e..0000000 --- a/Editor/src/main.rs +++ /dev/null @@ -1,464 +0,0 @@ -use eframe::egui; -use std::fs; -use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio}; -use std::sync::{Arc, Mutex}; -use std::thread; - -const SUPPORTED_LANGS: &[(&str, &str)] = &[ - ("zh", "中文"), ("en", "English"), ("ja", "日本語"), ("ko", "한국어"), - ("es", "Español"), ("fr", "Français"), ("de", "Deutsch"), ("ru", "Русский"), - ("pt", "Português"), ("it", "Italiano"), ("tr", "Türkçe"), -]; - -struct LityEditor { - engine_dir: PathBuf, - code: String, - file_path: Option, - file_tree: Vec, - tree_expanded: std::collections::HashSet, - console: String, - current_lang: String, - process_running: bool, - process_output: Arc>>, - needs_refresh: bool, - show_about: bool, -} - -#[derive(Clone)] -struct FileNode { - name: String, - path: PathBuf, - is_dir: bool, - children: Vec, -} - -impl LityEditor { - fn new(cc: &eframe::CreationContext) -> Self { - let mut style = (*cc.egui_ctx.style()).clone(); - style.spacing.item_spacing = egui::vec2(4.0, 4.0); - cc.egui_ctx.set_style(style); - - let engine_dir = PathBuf::from(std::env::var("ENGINE_DIR") - .unwrap_or_else(|_| { - let exe = std::env::current_exe().unwrap_or_default(); - exe.parent().unwrap_or(Path::new(".")).to_path_buf() - })); - - let mut editor = Self { - engine_dir, - code: String::new(), - file_path: None, - file_tree: Vec::new(), - tree_expanded: std::collections::HashSet::new(), - console: String::new(), - current_lang: "zh".to_string(), - process_running: false, - process_output: Arc::new(Mutex::new(Vec::new())), - needs_refresh: true, - show_about: false, - }; - editor.refresh_tree(); - editor - } - - fn t(&self, key: &str) -> String { - let lang = &self.current_lang; - match (lang.as_str(), key) { - ("zh", k) => match k { - "app_title" => "Lity3D 编辑器".into(), - "menu_file" => "文件".into(), - "menu_edit" => "编辑".into(), - "menu_build" => "构建".into(), - "menu_scene" => "场景".into(), - "menu_help" => "帮助".into(), - "menu_view" => "视图".into(), - "menu_lang" => "语言".into(), - "new" => "新建".into(), - "open" => "打开".into(), - "save" => "保存".into(), - "run" => "运行".into(), - "stop" => "停止".into(), - "build" => "编译".into(), - "package" => "打包".into(), - "explorer" => "资源管理器".into(), - "output" => "输出".into(), - "ready" => "就绪".into(), - "running" => "运行中...".into(), - "about" => "关于".into(), - "save_ok" => "已保存".into(), - "open_ok" => "已打开".into(), - "build_first" => "请先编译引擎".into(), - _ => k.into(), - }, - ("en", k) => match k { - "app_title" => "Lity3D Editor".into(), - "menu_file" => "File".into(), - "menu_edit" => "Edit".into(), - "menu_build" => "Build".into(), - "menu_scene" => "Scene".into(), - "menu_help" => "Help".into(), - "menu_view" => "View".into(), - "menu_lang" => "Language".into(), - "new" => "New".into(), - "open" => "Open".into(), - "save" => "Save".into(), - "run" => "Run".into(), - "stop" => "Stop".into(), - "build" => "Build".into(), - "package" => "Package".into(), - "explorer" => "Explorer".into(), - "output" => "Output".into(), - "ready" => "Ready".into(), - "running" => "Running...".into(), - "about" => "About".into(), - "save_ok" => "Saved".into(), - "open_ok" => "Opened".into(), - "build_first" => "Build engine first".into(), - _ => k.into(), - }, - _ => { - // Fallback to English - match key { - "app_title" => "Lity3D Editor".into(), - _ => key.into(), - } - } - } - } - - fn refresh_tree(&mut self) { - self.file_tree.clear(); - self.file_tree = Self::build_tree(&self.engine_dir, 0); - self.needs_refresh = false; - } - - fn build_tree(dir: &Path, depth: usize) -> Vec { - if depth > 3 { return Vec::new(); } - let skip = [".git", "build", "__pycache__", "target", ".vs", ".vscode", "obj"]; - let mut nodes = Vec::new(); - if let Ok(entries) = fs::read_dir(dir) { - let mut entries: Vec<_> = entries.filter_map(|e| e.ok()).collect(); - entries.sort_by(|a, b| a.file_name().cmp(&b.file_name())); - for entry in entries { - let name = entry.file_name().to_string_lossy().to_string(); - if name.starts_with('.') || skip.contains(&name.as_str()) { continue; } - let path = entry.path(); - if path.is_dir() { - let children = Self::build_tree(&path, depth + 1); - nodes.push(FileNode { name, path, is_dir: true, children }); - } else if name.ends_with(".py") || name.ends_with(".c") || name.ends_with(".h") - || name.ends_with(".asm") || name.ends_with(".txt") || name.ends_with(".json") - || name.ends_with(".md") || name.ends_with(".toml") || name.ends_with(".bat") { - nodes.push(FileNode { name, path, is_dir: false, children: Vec::new() }); - } - } - } - nodes - } - - fn open_file(&mut self, path: PathBuf) { - if let Ok(content) = fs::read_to_string(&path) { - self.code = content; - self.file_path = Some(path); - } - } - - fn save_file(&mut self) { - if let Some(ref path) = self.file_path { - if fs::write(path, &self.code).is_ok() { - self.console.push_str(&format!("[OK] {}\n", self.t("save_ok"))); - } - } - } - - fn run_process(&mut self, cmd: Vec) { - self.process_running = true; - self.console.push_str(&format!("[>] {}\n", cmd.join(" "))); - let output = self.process_output.clone(); - let cmd_clone = cmd.clone(); - thread::spawn(move || { - let result = Command::new(&cmd_clone[0]) - .args(&cmd_clone[1..]) - .current_dir(std::env::current_dir().unwrap_or_default()) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output(); - match result { - Ok(out) => { - let mut buf = output.lock().unwrap(); - if let Ok(s) = String::from_utf8(out.stdout) { buf.push(s); } - if let Ok(s) = String::from_utf8(out.stderr) { buf.push(s); } - buf.push(format!("[exit: {}]\n", out.status.code().unwrap_or(-1))); - } - Err(e) => { - output.lock().unwrap().push(format!("[ERROR] {}\n", e)); - } - } - }); - } - - fn build(&mut self) { - let build_dir = self.engine_dir.join("build"); - let _ = fs::create_dir_all(&build_dir); - self.run_process(vec![ - "cmake".into(), "--build".into(), - build_dir.to_string_lossy().to_string(), - ]); - } - - fn run_game(&mut self) { - let exe = self.engine_dir.join("build").join("lity.exe"); - if exe.exists() { - self.run_process(vec![exe.to_string_lossy().to_string()]); - } else { - self.console.push_str(&format!("[!] {}\n", self.t("build_first"))); - } - } - - fn ui_tree_node(ui: &mut egui::Ui, nodes: &[FileNode], expanded: &mut std::collections::HashSet, selected: &mut Option) { - for node in nodes { - let id = egui::Id::new(&node.path); - if node.is_dir { - let header = ui.horizontal(|ui| { - let icon = if expanded.contains(&node.name) { "▼" } else { "▶" }; - if ui.selectable_label(false, format!("{} 📁 {}", icon, node.name)).clicked() { - if expanded.contains(&node.name) { - expanded.remove(&node.name); - } else { - expanded.insert(node.name.clone()); - } - } - }); - if expanded.contains(&node.name) { - ui.indent(id, |ui| { - Self::ui_tree_node(ui, &node.children, expanded, selected); - }); - } - } else { - let ext = node.name.rsplit('.').next().unwrap_or(""); - let icon = match ext { - "py" => "🐍", "c" | "h" => "⚙", "asm" => "🔧", - "md" => "📝", "json" => "📋", _ => "📄", - }; - if ui.selectable_label(false, format!("{} {}", icon, node.name)).clicked() { - *selected = Some(node.path.clone()); - } - } - } - } -} - -impl eframe::App for LityEditor { - fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - // Collect process output - { - let mut buf = self.process_output.lock().unwrap(); - if !buf.is_empty() { - for line in buf.drain(..) { - self.console.push_str(&line); - if !line.ends_with('\n') { self.console.push('\n'); } - } - } - } - - egui::TopBottomPanel::top("menu_bar").show(ctx, |ui| { - egui::menu::bar(ui, |ui| { - ui.menu_button(self.t("menu_file"), |ui| { - if ui.button(self.t("new")).clicked() { - self.code.clear(); - self.file_path = None; - ui.close_menu(); - } - if ui.button(self.t("open")).clicked() { - if let Some(path) = rfd::FileDialog::new() - .set_title(&self.t("open")) - .add_filter("Code", &["py", "c", "h", "asm", "txt", "json"]) - .pick_file() { - self.open_file(path); - } - ui.close_menu(); - } - if ui.button(self.t("save")).clicked() { - self.save_file(); - ui.close_menu(); - } - ui.separator(); - if ui.button("Exit").clicked() { - std::process::exit(0); - } - }); - - ui.menu_button(self.t("menu_build"), |ui| { - if ui.button(format!("▶ {}", self.t("run"))).clicked() { - self.run_game(); - ui.close_menu(); - } - if ui.button(format!("⏹ {}", self.t("stop"))).clicked() { - self.process_running = false; - ui.close_menu(); - } - ui.separator(); - if ui.button(format!("🔨 {}", self.t("build"))).clicked() { - self.build(); - ui.close_menu(); - } - if ui.button(format!("📦 {}", self.t("package"))).clicked() { - if let Some(path) = rfd::FileDialog::new() - .set_title(&self.t("package")) - .add_filter("EXE", &["exe"]) - .save_file() { - let exe = self.engine_dir.join("build").join("lity.exe"); - if exe.exists() { - let _ = fs::copy(&exe, &path); - self.console.push_str(&format!("[OK] Packaged to {}\n", path.display())); - } else { - self.console.push_str(&format!("[!] {}\n", self.t("build_first"))); - } - } - ui.close_menu(); - } - }); - - ui.menu_button(self.t("menu_lang"), |ui| { - for (code, name) in SUPPORTED_LANGS { - if ui.selectable_label(self.current_lang == *code, *name).clicked() { - self.current_lang = code.to_string(); - ui.close_menu(); - } - } - }); - - ui.menu_button(self.t("menu_help"), |ui| { - if ui.button(self.t("about")).clicked() { - self.show_about = true; - ui.close_menu(); - } - }); - }); - }); - - egui::TopBottomPanel::bottom("toolbar").show(ctx, |ui| { - ui.horizontal(|ui| { - if ui.button("📂 Open").on_hover_text("Ctrl+O").clicked() { - if let Some(path) = rfd::FileDialog::new().pick_file() { - self.open_file(path); - } - } - if ui.button("💾 Save").on_hover_text("Ctrl+S").clicked() { - self.save_file(); - } - ui.separator(); - let run_text = if self.process_running { "⏹ Stop" } else { "▶ Run (F5)" }; - if ui.button(run_text).clicked() { - if self.process_running { - self.process_running = false; - self.console.push_str("[!] Stopped\n"); - } else { - self.run_game(); - } - } - if ui.button("🔨 Build (F7)").clicked() { - self.build(); - } - ui.separator(); - if ui.button("📁 Refresh").clicked() { - self.needs_refresh = true; - } - if let Some(ref p) = self.file_path { - ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { - ui.label(egui::RichText::new(p.file_name().unwrap_or_default().to_string_lossy().to_string()) - .color(egui::Color32::GRAY).small()); - }); - } - }); - }); - - egui::SidePanel::left("explorer").resizable(true).default_width(220.0).show(ctx, |ui| { - ui.heading(self.t("explorer")); - ui.separator(); - if self.needs_refresh { self.refresh_tree(); } - egui::ScrollArea::vertical().show(ui, |ui| { - let mut selected = None; - Self::ui_tree_node(ui, &self.file_tree, &mut self.tree_expanded, &mut selected); - if let Some(path) = selected { - self.open_file(path); - } - }); - }); - - egui::TopBottomPanel::bottom("console").resizable(true).default_height(150.0).show(ctx, |ui| { - ui.heading(self.t("output")); - ui.separator(); - egui::ScrollArea::vertical().stick_to_bottom(true).show(ui, |ui| { - ui.add(egui::TextEdit::multiline(&mut self.console.as_str()) - .desired_width(f32::INFINITY) - .font(egui::TextStyle::Monospace)); - }); - }); - - egui::CentralPanel::default().show(ctx, |ui| { - ui.horizontal(|ui| { - let title = self.file_path.as_ref() - .map(|p| p.file_name().unwrap_or_default().to_string_lossy().to_string()) - .unwrap_or_else(|| "untitled".into()); - ui.heading(title); - if self.file_path.is_some() { - ui.label(egui::RichText::new("●").color(egui::Color32::from_rgb(255, 200, 0))); - } - }); - ui.separator(); - egui::ScrollArea::both().show(ui, |ui| { - let output = ui.add(egui::TextEdit::multiline(&mut self.code) - .desired_width(f32::INFINITY) - .desired_rows(40) - .font(egui::TextStyle::Monospace) - .code_editor()); - }); - }); - - if self.show_about { - egui::Window::new(self.t("about")).collapsible(false).resizable(false).show(ctx, |ui| { - ui.label("Lity3D Engine v1.0"); - ui.label("C + MASM x64 Game Engine"); - ui.label("D3D11 Rendering + Python Scripting"); - ui.label("11 Languages Supported"); - ui.separator(); - ui.label("https://gitee.com/shuiyu1123/lity3d"); - if ui.button("OK").clicked() { - self.show_about = false; - } - }); - } - - // Request repaint when process is running - if self.process_running { - ctx.request_repaint_after(std::time::Duration::from_millis(100)); - } - } -} - -fn main() -> eframe::Result<()> { - let engine_dir = std::env::current_exe() - .ok() - .and_then(|p| p.parent().map(|p| p.to_path_buf())) - .unwrap_or_else(|| PathBuf::from(".")); - - let options = eframe::NativeOptions { - viewport: egui::ViewportBuilder::default() - .with_inner_size([1400.0, 900.0]) - .with_title("Lity3D Editor"), - ..Default::default() - }; - - eframe::run_native( - "Lity3D Editor", - options, - Box::new(move |cc| { - let mut editor = LityEditor::new(cc); - editor.engine_dir = engine_dir; - editor.refresh_tree(); - Ok(Box::new(editor)) - }), - ) -} diff --git a/EditorCS/EditorCS/Lity3DEditor.csproj b/EditorCS/EditorCS/Lity3DEditor.csproj deleted file mode 100644 index 018c5db..0000000 --- a/EditorCS/EditorCS/Lity3DEditor.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - WinExe - net9.0-windows - enable - true - enable - editor - Lity3DEditor - false - false - - - \ No newline at end of file diff --git a/EditorCS/EditorCS/MainForm.cs b/EditorCS/EditorCS/MainForm.cs deleted file mode 100644 index f2fca1c..0000000 --- a/EditorCS/EditorCS/MainForm.cs +++ /dev/null @@ -1,369 +0,0 @@ -using System.ComponentModel; - -namespace Lity3DEditor; - -public class MainForm : Form -{ - private List _nodes = new(); - private string? _currentPath; - private bool _modified; - - private TreeView _tree = null!; - private PropertyGrid _propertyGrid = null!; - private StatusStrip _status = null!; - private ToolStripButton _btnSave = null!; - - public MainForm() - { - Text = "Lity3D Engine Scene Editor"; - Size = new Size(1280, 800); - StartPosition = FormStartPosition.CenterScreen; - BackColor = Color.FromArgb(30, 30, 38); - Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point); - - BuildMenu(); - BuildToolbar(); - BuildPanels(); - BuildStatus(); - - Load += (_, _) => - { - foreach (var c in Controls.OfType()) - { - if (c.Orientation == Orientation.Vertical) - { - c.Panel1MinSize = 180; - c.Panel2MinSize = 300; - c.SplitterDistance = 260; - } - else - { - c.Panel1MinSize = 200; - c.Panel2MinSize = 120; - c.SplitterDistance = c.Height - 220; - } - } - TryOpenScene(Path.Combine(Application.StartupPath, "scene.txt")); - }; - FormClosing += (_, e) => { if (!PromptSave()) e.Cancel = true; }; - } - - private void BuildMenu() - { - var menu = new MenuStrip(); - var file = new ToolStripMenuItem("文件(&F)"); - file.DropDownItems.Add(new ToolStripMenuItem("打开...", null, (_, _) => OpenScene()) { ShortcutKeys = Keys.Control | Keys.O }); - file.DropDownItems.Add(new ToolStripMenuItem("保存", null, (_, _) => SaveScene()) { ShortcutKeys = Keys.Control | Keys.S }); - file.DropDownItems.Add(new ToolStripMenuItem("另存为...", null, (_, _) => SaveSceneAs())); - file.DropDownItems.Add(new ToolStripSeparator()); - file.DropDownItems.Add(new ToolStripMenuItem("退出", null, (_, _) => Close()) { ShortcutKeys = Keys.Alt | Keys.F4 }); - menu.Items.Add(file); - - var edit = new ToolStripMenuItem("编辑(&E)"); - edit.DropDownItems.Add(new ToolStripMenuItem("添加立方体", null, (_, _) => AddNode(MeshType.CUBE, "cube"))); - edit.DropDownItems.Add(new ToolStripMenuItem("添加球体", null, (_, _) => AddNode(MeshType.SPHERE, "sphere"))); - edit.DropDownItems.Add(new ToolStripMenuItem("添加平面", null, (_, _) => AddNode(MeshType.PLANE, "plane"))); - edit.DropDownItems.Add(new ToolStripSeparator()); - edit.DropDownItems.Add(new ToolStripMenuItem("删除选中", null, (_, _) => DeleteSelected()) { ShortcutKeys = Keys.Delete }); - menu.Items.Add(edit); - - MainMenuStrip = menu; - Controls.Add(menu); - } - - private void BuildToolbar() - { - var tool = new ToolStrip(); - tool.GripStyle = ToolStripGripStyle.Hidden; - tool.BackColor = Color.FromArgb(40, 40, 50); - tool.ForeColor = Color.White; - tool.Renderer = new DarkToolStripRenderer(); - - _btnSave = new ToolStripButton("保存", null, (_, _) => SaveScene()) { Enabled = false }; - tool.Items.Add(_btnSave); - tool.Items.Add(new ToolStripSeparator()); - tool.Items.Add(new ToolStripButton("添加立方体", null, (_, _) => AddNode(MeshType.CUBE, "cube"))); - tool.Items.Add(new ToolStripButton("添加球体", null, (_, _) => AddNode(MeshType.SPHERE, "sphere"))); - tool.Items.Add(new ToolStripButton("添加平面", null, (_, _) => AddNode(MeshType.PLANE, "plane"))); - tool.Items.Add(new ToolStripSeparator()); - tool.Items.Add(new ToolStripButton("删除", null, (_, _) => DeleteSelected())); - - tool.Dock = DockStyle.Top; - Controls.Add(tool); - } - - private void BuildPanels() - { - var split = new SplitContainer - { - Dock = DockStyle.Fill, - BackColor = Color.FromArgb(30, 30, 38) - }; - split.Panel1.BackColor = Color.FromArgb(35, 35, 45); - split.Panel2.BackColor = Color.FromArgb(35, 35, 45); - - _tree = new TreeView - { - Dock = DockStyle.Fill, - BackColor = Color.FromArgb(35, 35, 45), - ForeColor = Color.White, - BorderStyle = BorderStyle.None, - FullRowSelect = true, - HideSelection = false, - ShowLines = true, - ShowPlusMinus = true, - LineColor = Color.FromArgb(100, 120, 160) - }; - _tree.AfterSelect += (_, _) => OnNodeSelected(); - split.Panel1.Controls.Add(_tree); - - var rightSplit = new SplitContainer - { - Dock = DockStyle.Fill, - Orientation = Orientation.Horizontal, - BackColor = Color.FromArgb(30, 30, 38) - }; - rightSplit.Panel1.BackColor = Color.FromArgb(35, 35, 45); - rightSplit.Panel2.BackColor = Color.FromArgb(28, 28, 36); - - _propertyGrid = new PropertyGrid - { - Dock = DockStyle.Fill, - BackColor = Color.FromArgb(35, 35, 45), - ForeColor = Color.White, - CategoryForeColor = Color.FromArgb(180, 180, 200), - CommandsBackColor = Color.FromArgb(35, 35, 45), - CommandsForeColor = Color.White, - DisabledItemForeColor = Color.Gray, - HelpBackColor = Color.FromArgb(28, 28, 36), - HelpForeColor = Color.White, - ViewBackColor = Color.FromArgb(35, 35, 45), - ViewForeColor = Color.White, - LineColor = Color.FromArgb(60, 60, 80), - ToolbarVisible = false, - PropertySort = PropertySort.Categorized - }; - _propertyGrid.PropertyValueChanged += (_, _) => OnPropertyChanged(); - rightSplit.Panel1.Controls.Add(_propertyGrid); - - var previewLabel = new Label - { - Dock = DockStyle.Fill, - Text = "3D 预览区\n(由 Lity3D Engine 运行时渲染)", - ForeColor = Color.FromArgb(120, 120, 140), - BackColor = Color.FromArgb(28, 28, 36), - TextAlign = ContentAlignment.MiddleCenter, - Font = new Font(Font.FontFamily, 11f, FontStyle.Regular) - }; - rightSplit.Panel2.Controls.Add(previewLabel); - - split.Panel2.Controls.Add(rightSplit); - - Controls.Add(split); - } - - private void BuildStatus() - { - _status = new StatusStrip(); - _status.BackColor = Color.FromArgb(40, 40, 50); - _status.ForeColor = Color.White; - _status.Items.Add(new ToolStripStatusLabel("就绪")); - Controls.Add(_status); - } - - private void TryOpenScene(string path) - { - if (!File.Exists(path)) return; - try - { - _nodes = SceneIO.Load(path); - _currentPath = path; - RebuildTree(); - SetModified(false); - SetStatus($"已打开 {path}"); - } - catch (Exception ex) - { - MessageBox.Show(this, ex.Message, "打开失败", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - private void OpenScene() - { - if (!PromptSave()) return; - using var dlg = new OpenFileDialog - { - Filter = "Lity3D 场景|*.txt|所有文件|*.*", - Title = "打开场景" - }; - if (dlg.ShowDialog(this) == DialogResult.OK) - TryOpenScene(dlg.FileName); - } - - private bool SaveScene() - { - if (string.IsNullOrEmpty(_currentPath)) - return SaveSceneAs(); - try - { - SceneIO.Save(_currentPath, _nodes); - SetModified(false); - SetStatus($"已保存 {_currentPath}"); - return true; - } - catch (Exception ex) - { - MessageBox.Show(this, ex.Message, "保存失败", MessageBoxButtons.OK, MessageBoxIcon.Error); - return false; - } - } - - private bool SaveSceneAs() - { - using var dlg = new SaveFileDialog - { - Filter = "Lity3D 场景|*.txt|所有文件|*.*", - Title = "另存为" - }; - if (dlg.ShowDialog(this) != DialogResult.OK) return false; - _currentPath = dlg.FileName; - return SaveScene(); - } - - private bool PromptSave() - { - if (!_modified) return true; - var r = MessageBox.Show(this, "场景已修改,是否保存?", "保存确认", - MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); - if (r == DialogResult.Cancel) return false; - if (r == DialogResult.Yes) return SaveScene(); - return true; - } - - private void AddNode(MeshType type, string baseName) - { - int idx = 1; - string name = baseName; - while (_nodes.Any(n => n.Name == name)) - name = $"{baseName}_{idx++}"; - - var parentIdx = -1; - if (_tree.SelectedNode?.Tag is SceneNode sel && sel.Name != "root") - parentIdx = _nodes.IndexOf(sel); - else if (_nodes.Count > 0) - parentIdx = 0; // root - - var node = new SceneNode - { - Name = name, - ParentIndex = parentIdx, - Mesh = type, - PosY = type == MeshType.PLANE ? -1.0f : 0.0f - }; - _nodes.Add(node); - RebuildTree(); - SelectNode(node); - SetModified(true); - SetStatus($"添加 {name}"); - } - - private void DeleteSelected() - { - if (_tree.SelectedNode?.Tag is not SceneNode node || node.Name == "root") - { - MessageBox.Show(this, "不能删除根节点", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); - return; - } - _nodes.Remove(node); - RebuildTree(); - SetModified(true); - SetStatus($"删除 {node.Name}"); - } - - private void RebuildTree() - { - _tree.Nodes.Clear(); - var treeMap = new Dictionary(); - for (int i = 0; i < _nodes.Count; i++) - { - var n = _nodes[i]; - var tn = new TreeNode(n.Name) { Tag = n, ForeColor = Color.White }; - treeMap[i] = tn; - if (n.ParentIndex >= 0 && treeMap.TryGetValue(n.ParentIndex, out var parent)) - parent.Nodes.Add(tn); - else - _tree.Nodes.Add(tn); - } - _tree.ExpandAll(); - } - - private void SelectNode(SceneNode node) - { - foreach (TreeNode root in _tree.Nodes) - { - var found = FindNode(root, node); - if (found != null) - { - _tree.SelectedNode = found; - return; - } - } - } - - private static TreeNode? FindNode(TreeNode parent, SceneNode node) - { - if (parent.Tag == node) return parent; - foreach (TreeNode c in parent.Nodes) - { - var r = FindNode(c, node); - if (r != null) return r; - } - return null; - } - - private void OnNodeSelected() - { - _propertyGrid.SelectedObject = _tree.SelectedNode?.Tag; - if (_tree.SelectedNode?.Tag is SceneNode n) - SetStatus(n.Name); - } - - private void OnPropertyChanged() - { - SetModified(true); - _tree.Refresh(); - } - - private void SetModified(bool modified) - { - _modified = modified; - _btnSave.Enabled = modified; - Text = "Lity3D Engine Scene Editor" + (modified ? " *" : "") + (string.IsNullOrEmpty(_currentPath) ? "" : $" - {_currentPath}"); - } - - private void SetStatus(string msg) - { - if (_status.Items[0] is ToolStripStatusLabel lbl) - lbl.Text = msg; - } -} - -public class DarkToolStripRenderer : ToolStripProfessionalRenderer -{ - public DarkToolStripRenderer() : base(new DarkColorTable()) { } -} - -public class DarkColorTable : ProfessionalColorTable -{ - public override Color ToolStripBorder => Color.FromArgb(60, 60, 80); - public override Color ToolStripGradientBegin => Color.FromArgb(40, 40, 50); - public override Color ToolStripGradientEnd => Color.FromArgb(40, 40, 50); - public override Color ToolStripGradientMiddle => Color.FromArgb(45, 45, 55); - public override Color ButtonSelectedHighlight => Color.FromArgb(70, 70, 90); - public override Color ButtonSelectedBorder => Color.FromArgb(100, 120, 160); - public override Color ButtonPressedHighlight => Color.FromArgb(60, 80, 120); - public override Color ButtonCheckedHighlight => Color.FromArgb(60, 80, 120); - public override Color MenuBorder => Color.FromArgb(60, 60, 80); - public override Color MenuItemSelected => Color.FromArgb(70, 70, 90); - public override Color MenuItemBorder => Color.FromArgb(100, 120, 160); -} diff --git a/EditorCS/EditorCS/MiMoEditor.csproj.user b/EditorCS/EditorCS/MiMoEditor.csproj.user deleted file mode 100644 index 7814ea2..0000000 --- a/EditorCS/EditorCS/MiMoEditor.csproj.user +++ /dev/null @@ -1,8 +0,0 @@ - - - - - Form - - - diff --git a/EditorCS/EditorCS/Program.cs b/EditorCS/EditorCS/Program.cs deleted file mode 100644 index a9a07b4..0000000 --- a/EditorCS/EditorCS/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Lity3DEditor; - -static class Program -{ - [STAThread] - static void Main() - { - ApplicationConfiguration.Initialize(); - Application.Run(new MainForm()); - } -} diff --git a/EditorCS/EditorCS/SceneIO.cs b/EditorCS/EditorCS/SceneIO.cs deleted file mode 100644 index a6abc80..0000000 --- a/EditorCS/EditorCS/SceneIO.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Globalization; - -namespace Lity3DEditor; - -public static class SceneIO -{ - public static List Load(string path) - { - var nodes = new List(); - using var reader = new StreamReader(path); - string? header = reader.ReadLine(); - if (header == null || !header.StartsWith("LITY3D_SCENE")) - throw new InvalidDataException("不是有效的 Lity3D 场景文件"); - - int lineIdx = 1; - string? line; - while ((line = reader.ReadLine()) != null) - { - if (string.IsNullOrWhiteSpace(line)) continue; - var parts = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); - if (parts.Length < 13) continue; - - var node = new SceneNode - { - Name = parts[0], - ParentIndex = int.Parse(parts[1]), - Mesh = Enum.Parse(parts[2], true), - MeshPath = parts[3], - PosX = float.Parse(parts[4], CultureInfo.InvariantCulture), - PosY = float.Parse(parts[5], CultureInfo.InvariantCulture), - PosZ = float.Parse(parts[6], CultureInfo.InvariantCulture), - RotX = float.Parse(parts[7], CultureInfo.InvariantCulture), - RotY = float.Parse(parts[8], CultureInfo.InvariantCulture), - RotZ = float.Parse(parts[9], CultureInfo.InvariantCulture), - ScaleX = float.Parse(parts[10], CultureInfo.InvariantCulture), - ScaleY = float.Parse(parts[11], CultureInfo.InvariantCulture), - ScaleZ = float.Parse(parts[12], CultureInfo.InvariantCulture), - LineIndex = lineIdx - }; - nodes.Add(node); - lineIdx++; - } - return nodes; - } - - public static void Save(string path, List nodes) - { - using var writer = new StreamWriter(path); - writer.WriteLine("LITY3D_SCENE 1"); - foreach (var node in nodes) - { - int parent = node.ParentIndex; - writer.WriteLine(node.ToSceneLine(parent)); - } - } -} diff --git a/EditorCS/EditorCS/SceneNode.cs b/EditorCS/EditorCS/SceneNode.cs deleted file mode 100644 index 6e3ef1d..0000000 --- a/EditorCS/EditorCS/SceneNode.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.ComponentModel; -using System.Globalization; - -namespace Lity3DEditor; - -public enum MeshType -{ - [Description("无")] - NONE, - [Description("立方体")] - CUBE, - [Description("球体")] - SPHERE, - [Description("平面")] - PLANE, - [Description("OBJ 模型")] - OBJ -} - -public class SceneNode -{ - public string Name { get; set; } = ""; - public int ParentIndex { get; set; } = -1; - public MeshType Mesh { get; set; } = MeshType.NONE; - public string MeshPath { get; set; } = "-"; - - public float PosX { get; set; } - public float PosY { get; set; } - public float PosZ { get; set; } - - public float RotX { get; set; } - public float RotY { get; set; } - public float RotZ { get; set; } - - public float ScaleX { get; set; } = 1.0f; - public float ScaleY { get; set; } = 1.0f; - public float ScaleZ { get; set; } = 1.0f; - - [Browsable(false)] - public int LineIndex { get; set; } - - public override string ToString() => Name; - - public string ToSceneLine(int parentIndex) - { - ParentIndex = parentIndex; - return string.Format(CultureInfo.InvariantCulture, - "{0} {1} {2} {3} {4:F4} {5:F4} {6:F4} {7:F4} {8:F4} {9:F4} {10:F4} {11:F4} {12:F4}", - Name, parentIndex, Mesh, MeshPath, - PosX, PosY, PosZ, RotX, RotY, RotZ, ScaleX, ScaleY, ScaleZ); - } -} diff --git a/EditorCS/Lity3DEditor.csproj b/EditorCS/Lity3DEditor.csproj deleted file mode 100644 index 018c5db..0000000 --- a/EditorCS/Lity3DEditor.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - WinExe - net9.0-windows - enable - true - enable - editor - Lity3DEditor - false - false - - - \ No newline at end of file diff --git a/EditorCS/MainForm.cs b/EditorCS/MainForm.cs deleted file mode 100644 index f2fca1c..0000000 --- a/EditorCS/MainForm.cs +++ /dev/null @@ -1,369 +0,0 @@ -using System.ComponentModel; - -namespace Lity3DEditor; - -public class MainForm : Form -{ - private List _nodes = new(); - private string? _currentPath; - private bool _modified; - - private TreeView _tree = null!; - private PropertyGrid _propertyGrid = null!; - private StatusStrip _status = null!; - private ToolStripButton _btnSave = null!; - - public MainForm() - { - Text = "Lity3D Engine Scene Editor"; - Size = new Size(1280, 800); - StartPosition = FormStartPosition.CenterScreen; - BackColor = Color.FromArgb(30, 30, 38); - Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point); - - BuildMenu(); - BuildToolbar(); - BuildPanels(); - BuildStatus(); - - Load += (_, _) => - { - foreach (var c in Controls.OfType()) - { - if (c.Orientation == Orientation.Vertical) - { - c.Panel1MinSize = 180; - c.Panel2MinSize = 300; - c.SplitterDistance = 260; - } - else - { - c.Panel1MinSize = 200; - c.Panel2MinSize = 120; - c.SplitterDistance = c.Height - 220; - } - } - TryOpenScene(Path.Combine(Application.StartupPath, "scene.txt")); - }; - FormClosing += (_, e) => { if (!PromptSave()) e.Cancel = true; }; - } - - private void BuildMenu() - { - var menu = new MenuStrip(); - var file = new ToolStripMenuItem("文件(&F)"); - file.DropDownItems.Add(new ToolStripMenuItem("打开...", null, (_, _) => OpenScene()) { ShortcutKeys = Keys.Control | Keys.O }); - file.DropDownItems.Add(new ToolStripMenuItem("保存", null, (_, _) => SaveScene()) { ShortcutKeys = Keys.Control | Keys.S }); - file.DropDownItems.Add(new ToolStripMenuItem("另存为...", null, (_, _) => SaveSceneAs())); - file.DropDownItems.Add(new ToolStripSeparator()); - file.DropDownItems.Add(new ToolStripMenuItem("退出", null, (_, _) => Close()) { ShortcutKeys = Keys.Alt | Keys.F4 }); - menu.Items.Add(file); - - var edit = new ToolStripMenuItem("编辑(&E)"); - edit.DropDownItems.Add(new ToolStripMenuItem("添加立方体", null, (_, _) => AddNode(MeshType.CUBE, "cube"))); - edit.DropDownItems.Add(new ToolStripMenuItem("添加球体", null, (_, _) => AddNode(MeshType.SPHERE, "sphere"))); - edit.DropDownItems.Add(new ToolStripMenuItem("添加平面", null, (_, _) => AddNode(MeshType.PLANE, "plane"))); - edit.DropDownItems.Add(new ToolStripSeparator()); - edit.DropDownItems.Add(new ToolStripMenuItem("删除选中", null, (_, _) => DeleteSelected()) { ShortcutKeys = Keys.Delete }); - menu.Items.Add(edit); - - MainMenuStrip = menu; - Controls.Add(menu); - } - - private void BuildToolbar() - { - var tool = new ToolStrip(); - tool.GripStyle = ToolStripGripStyle.Hidden; - tool.BackColor = Color.FromArgb(40, 40, 50); - tool.ForeColor = Color.White; - tool.Renderer = new DarkToolStripRenderer(); - - _btnSave = new ToolStripButton("保存", null, (_, _) => SaveScene()) { Enabled = false }; - tool.Items.Add(_btnSave); - tool.Items.Add(new ToolStripSeparator()); - tool.Items.Add(new ToolStripButton("添加立方体", null, (_, _) => AddNode(MeshType.CUBE, "cube"))); - tool.Items.Add(new ToolStripButton("添加球体", null, (_, _) => AddNode(MeshType.SPHERE, "sphere"))); - tool.Items.Add(new ToolStripButton("添加平面", null, (_, _) => AddNode(MeshType.PLANE, "plane"))); - tool.Items.Add(new ToolStripSeparator()); - tool.Items.Add(new ToolStripButton("删除", null, (_, _) => DeleteSelected())); - - tool.Dock = DockStyle.Top; - Controls.Add(tool); - } - - private void BuildPanels() - { - var split = new SplitContainer - { - Dock = DockStyle.Fill, - BackColor = Color.FromArgb(30, 30, 38) - }; - split.Panel1.BackColor = Color.FromArgb(35, 35, 45); - split.Panel2.BackColor = Color.FromArgb(35, 35, 45); - - _tree = new TreeView - { - Dock = DockStyle.Fill, - BackColor = Color.FromArgb(35, 35, 45), - ForeColor = Color.White, - BorderStyle = BorderStyle.None, - FullRowSelect = true, - HideSelection = false, - ShowLines = true, - ShowPlusMinus = true, - LineColor = Color.FromArgb(100, 120, 160) - }; - _tree.AfterSelect += (_, _) => OnNodeSelected(); - split.Panel1.Controls.Add(_tree); - - var rightSplit = new SplitContainer - { - Dock = DockStyle.Fill, - Orientation = Orientation.Horizontal, - BackColor = Color.FromArgb(30, 30, 38) - }; - rightSplit.Panel1.BackColor = Color.FromArgb(35, 35, 45); - rightSplit.Panel2.BackColor = Color.FromArgb(28, 28, 36); - - _propertyGrid = new PropertyGrid - { - Dock = DockStyle.Fill, - BackColor = Color.FromArgb(35, 35, 45), - ForeColor = Color.White, - CategoryForeColor = Color.FromArgb(180, 180, 200), - CommandsBackColor = Color.FromArgb(35, 35, 45), - CommandsForeColor = Color.White, - DisabledItemForeColor = Color.Gray, - HelpBackColor = Color.FromArgb(28, 28, 36), - HelpForeColor = Color.White, - ViewBackColor = Color.FromArgb(35, 35, 45), - ViewForeColor = Color.White, - LineColor = Color.FromArgb(60, 60, 80), - ToolbarVisible = false, - PropertySort = PropertySort.Categorized - }; - _propertyGrid.PropertyValueChanged += (_, _) => OnPropertyChanged(); - rightSplit.Panel1.Controls.Add(_propertyGrid); - - var previewLabel = new Label - { - Dock = DockStyle.Fill, - Text = "3D 预览区\n(由 Lity3D Engine 运行时渲染)", - ForeColor = Color.FromArgb(120, 120, 140), - BackColor = Color.FromArgb(28, 28, 36), - TextAlign = ContentAlignment.MiddleCenter, - Font = new Font(Font.FontFamily, 11f, FontStyle.Regular) - }; - rightSplit.Panel2.Controls.Add(previewLabel); - - split.Panel2.Controls.Add(rightSplit); - - Controls.Add(split); - } - - private void BuildStatus() - { - _status = new StatusStrip(); - _status.BackColor = Color.FromArgb(40, 40, 50); - _status.ForeColor = Color.White; - _status.Items.Add(new ToolStripStatusLabel("就绪")); - Controls.Add(_status); - } - - private void TryOpenScene(string path) - { - if (!File.Exists(path)) return; - try - { - _nodes = SceneIO.Load(path); - _currentPath = path; - RebuildTree(); - SetModified(false); - SetStatus($"已打开 {path}"); - } - catch (Exception ex) - { - MessageBox.Show(this, ex.Message, "打开失败", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - private void OpenScene() - { - if (!PromptSave()) return; - using var dlg = new OpenFileDialog - { - Filter = "Lity3D 场景|*.txt|所有文件|*.*", - Title = "打开场景" - }; - if (dlg.ShowDialog(this) == DialogResult.OK) - TryOpenScene(dlg.FileName); - } - - private bool SaveScene() - { - if (string.IsNullOrEmpty(_currentPath)) - return SaveSceneAs(); - try - { - SceneIO.Save(_currentPath, _nodes); - SetModified(false); - SetStatus($"已保存 {_currentPath}"); - return true; - } - catch (Exception ex) - { - MessageBox.Show(this, ex.Message, "保存失败", MessageBoxButtons.OK, MessageBoxIcon.Error); - return false; - } - } - - private bool SaveSceneAs() - { - using var dlg = new SaveFileDialog - { - Filter = "Lity3D 场景|*.txt|所有文件|*.*", - Title = "另存为" - }; - if (dlg.ShowDialog(this) != DialogResult.OK) return false; - _currentPath = dlg.FileName; - return SaveScene(); - } - - private bool PromptSave() - { - if (!_modified) return true; - var r = MessageBox.Show(this, "场景已修改,是否保存?", "保存确认", - MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); - if (r == DialogResult.Cancel) return false; - if (r == DialogResult.Yes) return SaveScene(); - return true; - } - - private void AddNode(MeshType type, string baseName) - { - int idx = 1; - string name = baseName; - while (_nodes.Any(n => n.Name == name)) - name = $"{baseName}_{idx++}"; - - var parentIdx = -1; - if (_tree.SelectedNode?.Tag is SceneNode sel && sel.Name != "root") - parentIdx = _nodes.IndexOf(sel); - else if (_nodes.Count > 0) - parentIdx = 0; // root - - var node = new SceneNode - { - Name = name, - ParentIndex = parentIdx, - Mesh = type, - PosY = type == MeshType.PLANE ? -1.0f : 0.0f - }; - _nodes.Add(node); - RebuildTree(); - SelectNode(node); - SetModified(true); - SetStatus($"添加 {name}"); - } - - private void DeleteSelected() - { - if (_tree.SelectedNode?.Tag is not SceneNode node || node.Name == "root") - { - MessageBox.Show(this, "不能删除根节点", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); - return; - } - _nodes.Remove(node); - RebuildTree(); - SetModified(true); - SetStatus($"删除 {node.Name}"); - } - - private void RebuildTree() - { - _tree.Nodes.Clear(); - var treeMap = new Dictionary(); - for (int i = 0; i < _nodes.Count; i++) - { - var n = _nodes[i]; - var tn = new TreeNode(n.Name) { Tag = n, ForeColor = Color.White }; - treeMap[i] = tn; - if (n.ParentIndex >= 0 && treeMap.TryGetValue(n.ParentIndex, out var parent)) - parent.Nodes.Add(tn); - else - _tree.Nodes.Add(tn); - } - _tree.ExpandAll(); - } - - private void SelectNode(SceneNode node) - { - foreach (TreeNode root in _tree.Nodes) - { - var found = FindNode(root, node); - if (found != null) - { - _tree.SelectedNode = found; - return; - } - } - } - - private static TreeNode? FindNode(TreeNode parent, SceneNode node) - { - if (parent.Tag == node) return parent; - foreach (TreeNode c in parent.Nodes) - { - var r = FindNode(c, node); - if (r != null) return r; - } - return null; - } - - private void OnNodeSelected() - { - _propertyGrid.SelectedObject = _tree.SelectedNode?.Tag; - if (_tree.SelectedNode?.Tag is SceneNode n) - SetStatus(n.Name); - } - - private void OnPropertyChanged() - { - SetModified(true); - _tree.Refresh(); - } - - private void SetModified(bool modified) - { - _modified = modified; - _btnSave.Enabled = modified; - Text = "Lity3D Engine Scene Editor" + (modified ? " *" : "") + (string.IsNullOrEmpty(_currentPath) ? "" : $" - {_currentPath}"); - } - - private void SetStatus(string msg) - { - if (_status.Items[0] is ToolStripStatusLabel lbl) - lbl.Text = msg; - } -} - -public class DarkToolStripRenderer : ToolStripProfessionalRenderer -{ - public DarkToolStripRenderer() : base(new DarkColorTable()) { } -} - -public class DarkColorTable : ProfessionalColorTable -{ - public override Color ToolStripBorder => Color.FromArgb(60, 60, 80); - public override Color ToolStripGradientBegin => Color.FromArgb(40, 40, 50); - public override Color ToolStripGradientEnd => Color.FromArgb(40, 40, 50); - public override Color ToolStripGradientMiddle => Color.FromArgb(45, 45, 55); - public override Color ButtonSelectedHighlight => Color.FromArgb(70, 70, 90); - public override Color ButtonSelectedBorder => Color.FromArgb(100, 120, 160); - public override Color ButtonPressedHighlight => Color.FromArgb(60, 80, 120); - public override Color ButtonCheckedHighlight => Color.FromArgb(60, 80, 120); - public override Color MenuBorder => Color.FromArgb(60, 60, 80); - public override Color MenuItemSelected => Color.FromArgb(70, 70, 90); - public override Color MenuItemBorder => Color.FromArgb(100, 120, 160); -} diff --git a/EditorCS/MiMoEditor.csproj.user b/EditorCS/MiMoEditor.csproj.user deleted file mode 100644 index 7814ea2..0000000 --- a/EditorCS/MiMoEditor.csproj.user +++ /dev/null @@ -1,8 +0,0 @@ - - - - - Form - - - diff --git a/EditorCS/Program.cs b/EditorCS/Program.cs deleted file mode 100644 index a9a07b4..0000000 --- a/EditorCS/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Lity3DEditor; - -static class Program -{ - [STAThread] - static void Main() - { - ApplicationConfiguration.Initialize(); - Application.Run(new MainForm()); - } -} diff --git a/EditorCS/SceneIO.cs b/EditorCS/SceneIO.cs deleted file mode 100644 index a6abc80..0000000 --- a/EditorCS/SceneIO.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Globalization; - -namespace Lity3DEditor; - -public static class SceneIO -{ - public static List Load(string path) - { - var nodes = new List(); - using var reader = new StreamReader(path); - string? header = reader.ReadLine(); - if (header == null || !header.StartsWith("LITY3D_SCENE")) - throw new InvalidDataException("不是有效的 Lity3D 场景文件"); - - int lineIdx = 1; - string? line; - while ((line = reader.ReadLine()) != null) - { - if (string.IsNullOrWhiteSpace(line)) continue; - var parts = line.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); - if (parts.Length < 13) continue; - - var node = new SceneNode - { - Name = parts[0], - ParentIndex = int.Parse(parts[1]), - Mesh = Enum.Parse(parts[2], true), - MeshPath = parts[3], - PosX = float.Parse(parts[4], CultureInfo.InvariantCulture), - PosY = float.Parse(parts[5], CultureInfo.InvariantCulture), - PosZ = float.Parse(parts[6], CultureInfo.InvariantCulture), - RotX = float.Parse(parts[7], CultureInfo.InvariantCulture), - RotY = float.Parse(parts[8], CultureInfo.InvariantCulture), - RotZ = float.Parse(parts[9], CultureInfo.InvariantCulture), - ScaleX = float.Parse(parts[10], CultureInfo.InvariantCulture), - ScaleY = float.Parse(parts[11], CultureInfo.InvariantCulture), - ScaleZ = float.Parse(parts[12], CultureInfo.InvariantCulture), - LineIndex = lineIdx - }; - nodes.Add(node); - lineIdx++; - } - return nodes; - } - - public static void Save(string path, List nodes) - { - using var writer = new StreamWriter(path); - writer.WriteLine("LITY3D_SCENE 1"); - foreach (var node in nodes) - { - int parent = node.ParentIndex; - writer.WriteLine(node.ToSceneLine(parent)); - } - } -} diff --git a/EditorCS/SceneNode.cs b/EditorCS/SceneNode.cs deleted file mode 100644 index 6e3ef1d..0000000 --- a/EditorCS/SceneNode.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.ComponentModel; -using System.Globalization; - -namespace Lity3DEditor; - -public enum MeshType -{ - [Description("无")] - NONE, - [Description("立方体")] - CUBE, - [Description("球体")] - SPHERE, - [Description("平面")] - PLANE, - [Description("OBJ 模型")] - OBJ -} - -public class SceneNode -{ - public string Name { get; set; } = ""; - public int ParentIndex { get; set; } = -1; - public MeshType Mesh { get; set; } = MeshType.NONE; - public string MeshPath { get; set; } = "-"; - - public float PosX { get; set; } - public float PosY { get; set; } - public float PosZ { get; set; } - - public float RotX { get; set; } - public float RotY { get; set; } - public float RotZ { get; set; } - - public float ScaleX { get; set; } = 1.0f; - public float ScaleY { get; set; } = 1.0f; - public float ScaleZ { get; set; } = 1.0f; - - [Browsable(false)] - public int LineIndex { get; set; } - - public override string ToString() => Name; - - public string ToSceneLine(int parentIndex) - { - ParentIndex = parentIndex; - return string.Format(CultureInfo.InvariantCulture, - "{0} {1} {2} {3} {4:F4} {5:F4} {6:F4} {7:F4} {8:F4} {9:F4} {10:F4} {11:F4} {12:F4}", - Name, parentIndex, Mesh, MeshPath, - PosX, PosY, PosZ, RotX, RotY, RotZ, ScaleX, ScaleY, ScaleZ); - } -} diff --git a/EditorCS/obj/Lity3DEditor.csproj.nuget.dgspec.json b/EditorCS/obj/Lity3DEditor.csproj.nuget.dgspec.json deleted file mode 100644 index 5fdfd27..0000000 --- a/EditorCS/obj/Lity3DEditor.csproj.nuget.dgspec.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "format": 1, - "restore": { - "C:\\Users\\Administrator\\Downloads\\mimocode-windows-x64\\GameEngineASM\\EditorCS\\Lity3DEditor.csproj": {} - }, - "projects": { - "C:\\Users\\Administrator\\Downloads\\mimocode-windows-x64\\GameEngineASM\\EditorCS\\Lity3DEditor.csproj": { - "version": "1.0.0", - "restore": { - "projectUniqueName": "C:\\Users\\Administrator\\Downloads\\mimocode-windows-x64\\GameEngineASM\\EditorCS\\Lity3DEditor.csproj", - "projectName": "editor", - "projectPath": "C:\\Users\\Administrator\\Downloads\\mimocode-windows-x64\\GameEngineASM\\EditorCS\\Lity3DEditor.csproj", - "packagesPath": "C:\\Users\\Administrator\\.nuget\\packages\\", - "outputPath": "C:\\Users\\Administrator\\Downloads\\mimocode-windows-x64\\GameEngineASM\\EditorCS\\obj\\", - "projectStyle": "PackageReference", - "configFilePaths": [ - "C:\\Users\\Administrator\\AppData\\Roaming\\NuGet\\NuGet.Config" - ], - "originalTargetFrameworks": [ - "net9.0-windows" - ], - "sources": { - "https://api.nuget.org/v3/index.json": {} - }, - "frameworks": { - "net9.0-windows7.0": { - "targetAlias": "net9.0-windows", - "projectReferences": {} - } - }, - "warningProperties": { - "warnAsError": [ - "NU1605" - ] - }, - "restoreAuditProperties": { - "enableAudit": "true", - "auditLevel": "low", - "auditMode": "direct" - }, - "SdkAnalysisLevel": "9.0.300" - }, - "frameworks": { - "net9.0-windows7.0": { - "targetAlias": "net9.0-windows", - "imports": [ - "net461", - "net462", - "net47", - "net471", - "net472", - "net48", - "net481" - ], - "assetTargetFallback": true, - "warn": true, - "frameworkReferences": { - "Microsoft.NETCore.App": { - "privateAssets": "all" - }, - "Microsoft.WindowsDesktop.App.WindowsForms": { - "privateAssets": "none" - } - }, - "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.315/PortableRuntimeIdentifierGraph.json" - } - } - } - } -} \ No newline at end of file diff --git a/EditorCS/obj/Lity3DEditor.csproj.nuget.g.props b/EditorCS/obj/Lity3DEditor.csproj.nuget.g.props deleted file mode 100644 index 97adc03..0000000 --- a/EditorCS/obj/Lity3DEditor.csproj.nuget.g.props +++ /dev/null @@ -1,15 +0,0 @@ - - - - True - NuGet - $(MSBuildThisFileDirectory)project.assets.json - $(UserProfile)\.nuget\packages\ - C:\Users\Administrator\.nuget\packages\ - PackageReference - 6.14.3 - - - - - \ No newline at end of file diff --git a/EditorCS/obj/Lity3DEditor.csproj.nuget.g.targets b/EditorCS/obj/Lity3DEditor.csproj.nuget.g.targets deleted file mode 100644 index 3dc06ef..0000000 --- a/EditorCS/obj/Lity3DEditor.csproj.nuget.g.targets +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/EditorCS/obj/Release/net9.0-windows/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs b/EditorCS/obj/Release/net9.0-windows/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs deleted file mode 100644 index feda5e9..0000000 --- a/EditorCS/obj/Release/net9.0-windows/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs +++ /dev/null @@ -1,4 +0,0 @@ -// -using System; -using System.Reflection; -[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")] diff --git a/EditorCS/obj/Release/net9.0-windows/Lity3DEditor.AssemblyInfo.cs b/EditorCS/obj/Release/net9.0-windows/Lity3DEditor.AssemblyInfo.cs deleted file mode 100644 index bf00a5e..0000000 --- a/EditorCS/obj/Release/net9.0-windows/Lity3DEditor.AssemblyInfo.cs +++ /dev/null @@ -1,24 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -using System; -using System.Reflection; - -[assembly: System.Reflection.AssemblyCompanyAttribute("editor")] -[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")] -[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+0669d102cea79704d7f44edeff1f40db4677933a")] -[assembly: System.Reflection.AssemblyProductAttribute("editor")] -[assembly: System.Reflection.AssemblyTitleAttribute("editor")] -[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] -[assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")] -[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")] - -// 由 MSBuild WriteCodeFragment 类生成。 - diff --git a/EditorCS/obj/Release/net9.0-windows/Lity3DEditor.AssemblyInfoInputs.cache b/EditorCS/obj/Release/net9.0-windows/Lity3DEditor.AssemblyInfoInputs.cache deleted file mode 100644 index db2fef4..0000000 --- a/EditorCS/obj/Release/net9.0-windows/Lity3DEditor.AssemblyInfoInputs.cache +++ /dev/null @@ -1 +0,0 @@ -eccab4cf931872db70f4fcf49f5ea48daaa37596c654c8ae7292da5835f1d1aa diff --git a/EditorCS/obj/Release/net9.0-windows/Lity3DEditor.GeneratedMSBuildEditorConfig.editorconfig b/EditorCS/obj/Release/net9.0-windows/Lity3DEditor.GeneratedMSBuildEditorConfig.editorconfig deleted file mode 100644 index 848018d..0000000 --- a/EditorCS/obj/Release/net9.0-windows/Lity3DEditor.GeneratedMSBuildEditorConfig.editorconfig +++ /dev/null @@ -1,22 +0,0 @@ -is_global = true -build_property.ApplicationManifest = -build_property.StartupObject = -build_property.ApplicationDefaultFont = -build_property.ApplicationHighDpiMode = -build_property.ApplicationUseCompatibleTextRendering = -build_property.ApplicationVisualStyles = -build_property.TargetFramework = net9.0-windows -build_property.TargetPlatformMinVersion = 7.0 -build_property.UsingMicrosoftNETSdkWeb = -build_property.ProjectTypeGuids = -build_property.InvariantGlobalization = -build_property.PlatformNeutralAssembly = -build_property.EnforceExtendedAnalyzerRules = -build_property._SupportedPlatformList = Linux,macOS,Windows -build_property.RootNamespace = Lity3DEditor -build_property.ProjectDir = C:\Users\Administrator\Downloads\mimocode-windows-x64\GameEngineASM\EditorCS\ -build_property.EnableComHosting = -build_property.EnableGeneratedComInterfaceComImportInterop = -build_property.CsWinRTUseWindowsUIXamlProjections = false -build_property.EffectiveAnalysisLevelStyle = 9.0 -build_property.EnableCodeStyleSeverity = diff --git a/EditorCS/obj/Release/net9.0-windows/Lity3DEditor.GlobalUsings.g.cs b/EditorCS/obj/Release/net9.0-windows/Lity3DEditor.GlobalUsings.g.cs deleted file mode 100644 index 84bbb89..0000000 --- a/EditorCS/obj/Release/net9.0-windows/Lity3DEditor.GlobalUsings.g.cs +++ /dev/null @@ -1,10 +0,0 @@ -// -global using global::System; -global using global::System.Collections.Generic; -global using global::System.Drawing; -global using global::System.IO; -global using global::System.Linq; -global using global::System.Net.Http; -global using global::System.Threading; -global using global::System.Threading.Tasks; -global using global::System.Windows.Forms; diff --git a/EditorCS/obj/Release/net9.0-windows/Lity3DEditor.assets.cache b/EditorCS/obj/Release/net9.0-windows/Lity3DEditor.assets.cache deleted file mode 100644 index 7c7f394444f30c7fb05e96a998f92b4a74c2c403..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 zcmWIWc6a1qU|=}$u;o@=_K)eYuhLtM+hV#M7o~6d!{zwy$Z6w^`+_W%%mJz)7BB)8 vsykc7gche36~{QH|ic{n$U8;p)4D@Vt45onJQuI4; zG{+zAPk>MG1l~_1L4_UXFX|^utBEM7h_>FFcz*GuO}l=$V3=CGd4;B?E{1D`@JKIn zpadX4pn4!xAe3eRLn3Si9m~i&H+6F`Us@sM#C(CQh~C8 za)IUoEdg2qv<|2eXa`Uo(0-t1pp!rsfc^x!1N0c^JbGWv;e3WXcf=~pe;bv zKzo3ifQ|v30lExy1Lz*mQ=r#Ctw3LatUVc+BX~{69}SE2q=9CX-}b`wWVG|^fmeZ6 zq|&RQvJCv6X#T-)Qw3fXa-hFjXjV1gHAo)$g1QnPr^Jtd-zGpBkgiGQ4+35jcrB9W zDe-~u+Z0F((zVI-5a6|e*CBZ);B|oSLGsq1RuA9}NInbFb%F0i@>@vW5O^c_J%{9b z1CL~hfqFuI6Ec6a5^n*&k^Xv+-iJ(&QsQmkH*`HrAJR?9^a$V$fHxy~Wba-|d_3@m zO1u^Dy@Bsb=3k-2BWwbY5u}@w>3YB$EAglgn<(+9kM`-rn=0`rznK!>1Ngq3c=JxY zg%XeO{gikl&r*p;<@N8xTXo{Cm3UO1O(%XpC*D?xNAbFBQ*2*y3Q(lG^kfLoD>cQ6j(&z9!6>#|i873ocnKGdQ zI8>Y*lX7JWIVRu>6_`wzlB$T2ir}Xlze1WotiaL);&fajho6P=!!z_t2qZuQ8T|FU zJaFEA{a$`^7iQ`ftgJHnoD?i`Sv?m{)+>8I&W>Pzoz>7$KK0}W(Swv4oI5Q6mnA|Fl?4s zb6jZ6?Q?pKlNCKMI%}BfXt_Wp@8Qc&6N-g$g^a6^$Ta;WnPQQI%arckL0#O%t%iDPTU|m@o}C)LJ5A#b}3dK^KWEjmeX1j-xTOOsqWE;g)(= z7mad@qCF|Bc1svr#xwt_v9e{~se`4JaRQ(I7pCfJMam>8GA=@CQK;Mk%aFo%eVQe^ zkJ|H|w`|%TKeW6Ld(D_2E13(X(^5KXthZJSPaqa>B7T7#wEX$+KL2~OIP(t=4_YxL z_9e4shlf*5V3NU?dFMxznSGk0gTun1M!x`CEtkIe!(C!}dnar>;RgXaIU zeXVKCtuxYhmx_ig)D&lJEPG-U4!-d($>O-1kHFCW)8oR^febbayl zrt5D#ZOhj!%D0}X%Fpl3V+SpHkrB{3^3cq8t>3M6xcQq`EnMW9Xc%m{?rYh*6-(09 zu3Xf7dh}S*iD71$*Uv?3KQ}xdHlfzatoW`hv}St4?Sx}b7!QimlN^l4nXSFya9?{0 ztLD6XPt!~8oDkme`6uXnRxW#^X8^adzx%MKReSEoysy+<`eEzITVbtDDff9p_-+o; z{9{grsRdEKRhPY1nYXmM-)*}$qbFAWxHj?oLj&_o0Rv+WM7^42uy)Sv+|bo-JFdKl zb@x3NC*3@?`bFOO`3}q0TX~o)xkO{zr2E((jN4OToVYCf^zMsBB}v=)MHMoI`?u2i z3l$HhFTY&=udeRx#DY)8(+x7Lgz<^*7RahS#nbMXhCc|GkGE*PIw{NZ>vqitIR*l?C$6e z%pg}cM^`Twu2+()famVw;*rD?@Ex6;9R*$Ez}t5b&McJOv)kUT%(#&TcMVF3Eg>tCuIw z%aQBm!FBJ@vAqB%7uZ}7r;9|~Bp936V*JJzB%?tpHrkiP9vsaMW&6gk2Sac`h3|Lx=nPP7!f@&5c0&bqfvhME>9q9r#zlro`A4Uc}Te~ zzfW*dMv&_LDhu155C+U_CSN3i;ax+hJ{il!u=(Ldjo0qQ`z&&fjoY%W z@KBhLCzHq}$qF)}klC%r4s1r*UtBTZnq{sEsYwX%Si0n0R7dtWp*)={^5e>dJSK{( zB=BjPVKHV2vx}9znkIZr39g9UwN19>Gc!^K-lq^|Kx`*~@~SI) zkw}*+yJ73@^z*HLb!x&qjgpa_fzg5#G=gU{37bOjRLCSEvJh{L9`jHkUUx4qKFj~p zcWv*LJHyR0X8yJiLN_OIfddgC-R8 zg)vsH;EMTN8K2C#W9Fi>*by3b{7>KSjc+#lEWSHE5>szpOpYtig;A9SSqd`0?M06x zNP#^Q*xHW&JIk&;ys*f8+jv7Vzh8QCG8&zTidL-1uSc1+Q<^?My7pH@14FT7{)KyO zWM&r382lw^Waiv4W4>TMu$45+wUE2DGGfUxzRzg->ACHhMIr$Yjae}ENyNN#8Jg{p z*d-^vZbTOKI>o$Ocljc_GUV=V@g<3GH&{ZmEMx69WFY&S!G3m|QvLGoZ9FimzG+Q2 z08Uz3x&j3bQdan@9$&FZG)$M%>bISCGq7G**&|!G;d(dFaETZnN1=xhV)ZtBpN;hN zkX&;(^sJDT>u#4ZF3kK!H`o}dfG6aNgwq66Q++$2{tba?T$=yLS6jmyMNVedcYHeD z4o;Iw#9)&!Fsle=3Sx-@54Tin4Cbx6j~#*4*s2X`$@ETt{_R z$P1nhmhJQ}*z3$(&r|p6fXF57-nn#K&N)=m70D%KY0r~G=M_hPeW1uJZ_nHwsPi5@ z$NNm!k{MoC?ZboS<=Ap!yt9%So?H06$GLuOqp6$%xiE#&XoJRq`zY_gVR>bHZ9M&&R%WlEvmRfg@(Q^r zVu@TK~zl5Y5yPW&Bs}n;%ahcb_4YnB&Da2Hki-u@fgAE zwe_8*JogS?*0f<^#IbGbx`VY#kHM!)WC=8%iBGWy7?u%te7eQNH=K1^b}tQz%kFej z0^SuuC6sK>z>mjK|1B-rrYir;4?7%`S=~6ncu+UU0GOGPYaDz5LYOvw^2fiC@*Icb zeXDBJgE!q-zCLa5?b>b%h!n`s#EdKEK~I2LS-bxpG7ro}Cbv;tnKJLr)`;DArrq4p z-|5fp%8*IWG=!`-V`6P7(thna``(wbe+2JaJ>&A1Xp?c>0Amzf-jrBqEh^-Ws_??w z*&K?M-6#*L@TlpT zxW(QbO87bJ(`U|7)-$I}`kyJk0mBlPR5ob&q94fAW7@n7*X-%(zjn6&mNTX4|Fi>T zFdj-|*)alHh7c@G!j|iwI*jE)q%xUY(IN?8HOH}-Uo`g@kTAj(w)c7Z8O@tMUmra- zt8X)VbxM>^*0YwkRM|2v>`kQn+W+&%T0X%nRj}Ys!*U8VKC*YVPJMf}c!0bU#$UOI zdeo-gN0xItdv;gP_fxMU zodk4=?whrSZbYv2u)N^mxt1NAxnFj$_LbfJNa3=@+%y=1qlwi8X{I|G!&V~A2DP{Z zKRoH{vyso9{6iyh7zsj?OfEzVU%A+cM0k~6I*!`o^pCsFtLnF~E8M3KkG-R~*9j3W zOG+jYQHqHdkc|49D~~N2*AQHOd1l~-#|xSQ`92@~Bf(_*!<- zf!p``FC;|}+aTmBipk=N1ZXNpHGGWb-c|%IDjr|QQ-lN`qz#%o$IZ8~TQFg9i-)@S zbka)u`$+vamxC7wOy7NdGcc@MNSB~);@8rG1RC19FKHYyHK4xlKePGcnh%g@*hhl# z19kvmDFTCtpG=|<2}#Rj`dVB?(6Oy2;Q_J5YrZR>VRLf9X|4HFI`S#0 z)!m9Bu^<^=c18Ga=y~W%O-RGfYacYNc2OP!CRHkckh$W?O}yE&Pu}|w_|FX1j?W?5 zSqj@N-OBWr!5T3H#*cAP=z*Vjx` zo&7w5=RWaaj(+05w_9{PSHVkdkHn0`@{0&M*6ZiBGZXKIH@05bm@jfT)5m(9z1OV=+1S z-7CBu2d3_H-x>$?!Oh52;K%)6yp^YDhxE|g-@Fs~46^f^lIZelv z%t5hr!S}i1<6F-8Znrb;v+U3}%A@g|>@2F2Q`)^Lt2%+!avMLq^}IfAlJCM^V=brL z4x(0xI4Y7W@nFaK<)rv6+dLRqD#bb%~eX(=}5YRx8u zvCi1@r{T$;VN2cmZncWnen4V~ijx&F`{q`GM!dv`ZT5TWxZ<6QtABC2V};GlbIg^l|3oUt}#@ zt=DK}r%zWx!Mg&=nhVB7mmtgZdMRoR#-|3qpQhyGhmKmtF;qbyCS^%9a9p4Bh z9OJ-`b0<;ddFAu8wq1D`xFSk@`t|HNYD!W7n<832}Xk_P0C>_=kB~|v#eN@izFDY z4r+LR|8`hWjmepFAE#R?VWQI87u!v*#@#{|vyyX14cdP-_^`n=dH>rw-b%Tn1yj=n z^7ci6%bJ_`+?+1q9V_?whqaJ)ZLk`Rxk?EUBY>TUj$O6JfZAH*RlY87_uNmv#olqv_{^TRAJyG^>*o1or8%7XlZoewt7@E;Q4-!1*sLK<+t2V( z0}_)tF#3*~N?B-A^K+y7vo>r}0>lfFSR!G^mdNlEFqMGXANW?h|L}m)usL)0>6sWW zQTBI$1mW-9SQ2V)g_Jk{Zok_|LG3ZGo4FNMzH`zSKizcu$GKnS!AqtrYJ2fj@v>70 zaemu`x*_wYhV3dyRNM`1v;GwkL)PjSO;=Z{H6iGg&8zD?mYH&jKAiX{_fvf89!mI{ z`aLIDi(=Ta?JKL-FLPm6ukzXMG~Pz@=f~=EuK!&x{D1lemK$G>p$DQ4vX#Av>|zLWs$%I2(A~yUvDa5Sg z2Q@ZD3zEsbFQ&gxE=2>WvhCMLCgL-j?T1~m!%htLU*lr)(&&GwsidMxXhP5ajnN;F zIS$Nkv1)8C_St;nxcKzd57bgjDL)%FO-UQhHr8rH>(+ByKhwSQM*A#$!K$8<=R$3v zbOv!k$u~$H@nOaV&5uZI!k4_+S6kL`W}9uBJZpvD`mSo?Vnfk8-%J6zk}Bw(X6``+ zv}Wx16clO3sWAS_=h@%aKXg+-=lzHNAIiQ^j-wb(vkiA3YX)0zQ^#I`sB-+L*94V=g|OwK0`i)u7Og-onV4U655H zPo6-?pxmqtme=jsD{RN#Yz>^Xp3{sylJa#Y zb%P@Cziw=?-y}RmLc^UFRXIFd6JGA@n{hbAs>6jTp~UK(6zVi=7T;%V^gC_N z?6{q*K9laHQ9{Wj8(K%eR8H2u)EzCBbCan#;h9aI1*nkClP9?T*?2av_R9yKw@LNX zt}3rx2u27^VavfI@dcaa%xZX0*@9?sdR=lO1Zh8DHGN|i#m#Sqm?uQ1CV*b0a9 za}C#te0I|qo(p7@kZhr8*z;X8KX&&7Wtk&<-vz^k2B<@tZ9^pQ(xW@5&*ccbzR9 z@;v<~suaU1INM8R&91$?b@4>4pB9}g0hNN!ec>Gw6_ssz=Rd(FsbSakBDGG3-VWSq zb+6^4erZuBTqt~L(Z1M7Z}E77WDSz`>vLu4NLFdg^qRYY>!|oo=^p;;sNo}j{0hxB zyhGpLtUv!gbnfQ^i!7+}NU*nXz+{*Xc2mdFO z*baa;q^i1;wXz7Ayz*9C+*y`4X9II>!pik()MAiQ`&R{&CYnQUzr{DrErP5z_ldd}$m3AKRg>32s)xi0ou>VE6GoBOo5&RCX+ zD};|D2#4o1$}b|2$jiHV$&7@+jr`H+I_ZT}v$YFk$+D#i^p%V>72fWNQY0{~OKmUZ ztlHB;^C;m*}9ibRR6|`FZZ!Ybj%{`jNgr| z$3si|w_F?ZrLgCJN@k1Ud!&xJ`EJKpJeGfda5nJqR3pFo(D^NIjw`4wh3>^iNCn~; zIo0fE`W5D*8qA&$<@U3}NF)^`)$ic5;7?s|INXZEKzTIZ!Js3pm7w1AB&nAr*V_$v^?s=~*C z_y$mDh68Qa!7RUR4IfsSZT?7Yb#-4*f}5ik3tl1#lhLO)?MwH7b#8dK9AVq{7( zdsCv9e6R5At^cfAM~C{JXH$$i)Rcf5bGIh)IYreYc6{!gO-=0ERUs6gY(HlwvcUgt z?)3gzKx0>YoMJI`r)5iLVX)z!Cd4=DsD8BWZP8-%o^!09U8+rRYs8!{9@VCTl^$J? z5TAKMDVJ*bIot>MmhT^xD-Qkrepkr)7~S&ATLbNWkE1?uA~gP^^2Q<*^{U=Y<4t_N zJhZfM_mBLY6RG{{_WI#J1jK0&vg=#iD8OeE{_FKMhR0uLuTUH-yL=-~w_P;85+kPU zu=pWS1z&R4AQQb`-{QE=h!vXumxXm&a1OQVBga#ia4Wsdc=kw+hlj64{<$$L7lt+z zj4Z^y2lgW+p|=ps_D+S~b4S8X3}xBjj_Yu*yl`$&Zs2fwP{kDaou0ifQ1jSd!GuxL zSNEz%I!>zf-MMGnrGUdjXMW3Tuz1<6ye_kji3X+kTdU!m@RfH?jArMnu)O8iD{67} zi$FQE!!j=VI}1@$==Rw^%qHP%aA5&c=h?Vsb7iSY<4tt~?GbwOkX+9%%-LifcCg@o zG07SCs09-)2EM0A7jb1>w~SiVU*c*Jd+WX<%k%Dj!e`mfv76XQn#Z%_rlmW~ z?TUmC%&6Bb?*yrMzqq%dmtgzAKSO4p@bI_DVkJ``85forJAZ#K9VNY8)H}g8dYp>cHqE|w;MzAgvDc?XuZjAYl9)Z|b0i11x$QutE;R>-r%Xb#KvzJ6m? z_g|4@CyBs zT4``qYlz^5&l`1RS&>{tD%s<_Hk-g;1Vh5y;`m|nCv$fBHCsf$aD#K_Re+s zPS?iwU2g1I`!r;~I=eXIS=8TG&yuzqVYydqw;f$ zdSh^;$3#;Vi>700SQH)3QqbtxYJ{Suq`n<{u5#i-Z6S}Er;u;OHOZWu2yOBg@(gMs zkGAkp&($s*ULzKt*jB8rql{9Zus7MOC(=!-*BByfLQ3fYhGI7P{2M zfPqdN`r4vnhxF{;q{>Kq$0uz6DZI{gES$74bJJAA2GQYw<4ii7l9`4s@pL!~7fnVBK z90Rk#`p`l3fhb`-Dhw7}*4PAe!JmbqU#7|>#={v=23OMpbJc?5h^}ykR~t+qz#L7$ zK>dML1$F@Dr30y6!0G{;dlK`vf@CJ}8o+b0AqF7OmH`(-{6r@`+Y*|fZ|+u2ZDe#K zv{R{vIn&{!n-S6ts^ZIlIG?yZ4YcX9W$k~(YaMP&ZI*R8H)}xsbM;~|7wB{qB=rE zG-qhIV|F>&eXw3?z_RG@jl3mY1I}E6+tTT}V38cU8iSGTf$8f)p}2wc(E)1%RDubr z0a(NV4sLVu^faBZM23bTrjASobt3cQS;1ZKtQ>9lJ|fRtQxCPG8m39t0&9WqFmiez z@fMgKDm{!2XSTp%a2OU^0Cf$OsjduY%JI6Gfgu;p^3t@R4_9Jv;?RD|LGQ>92|0m<}e5u0W~wu^VZaaW44aq+w>eLgbqz7&<6JeG*nOp ztZTu*=+o&GP)92fZ+Ihk;E@-gX@$C&B}gKg8=XTl$P3d{N4n#x8N-v_c`@*$FX}+K zxnNqPGT0Dv${V9;3cVk^0bGUC6JDqH>xb7t6_coA4vb7q%m_sea9C~RhhQ+Uod(?D z37q3Z9gQy31zm72@U`IKu8Gd^8aUc$KwZIkXqXjv9;WRPf!{ns(XEG9B)X}4x1UEGv zV7_2_R$ycBNe1Q+l?^WM3K`qG8#QM9^4-yYhUIPgYDN|Ej1$C5uP&>Mjy*5TiT|@;9R1CxEa6#sS3-Slu+&0Vq E0}AHYV*mgE diff --git a/EditorCS/obj/project.assets.json b/EditorCS/obj/project.assets.json deleted file mode 100644 index 2d2ed42..0000000 --- a/EditorCS/obj/project.assets.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "version": 3, - "targets": { - "net9.0-windows7.0": {} - }, - "libraries": {}, - "projectFileDependencyGroups": { - "net9.0-windows7.0": [] - }, - "packageFolders": { - "C:\\Users\\Administrator\\.nuget\\packages\\": {} - }, - "project": { - "version": "1.0.0", - "restore": { - "projectUniqueName": "C:\\Users\\Administrator\\Downloads\\mimocode-windows-x64\\GameEngineASM\\EditorCS\\Lity3DEditor.csproj", - "projectName": "editor", - "projectPath": "C:\\Users\\Administrator\\Downloads\\mimocode-windows-x64\\GameEngineASM\\EditorCS\\Lity3DEditor.csproj", - "packagesPath": "C:\\Users\\Administrator\\.nuget\\packages\\", - "outputPath": "C:\\Users\\Administrator\\Downloads\\mimocode-windows-x64\\GameEngineASM\\EditorCS\\obj\\", - "projectStyle": "PackageReference", - "configFilePaths": [ - "C:\\Users\\Administrator\\AppData\\Roaming\\NuGet\\NuGet.Config" - ], - "originalTargetFrameworks": [ - "net9.0-windows" - ], - "sources": { - "https://api.nuget.org/v3/index.json": {} - }, - "frameworks": { - "net9.0-windows7.0": { - "targetAlias": "net9.0-windows", - "projectReferences": {} - } - }, - "warningProperties": { - "warnAsError": [ - "NU1605" - ] - }, - "restoreAuditProperties": { - "enableAudit": "true", - "auditLevel": "low", - "auditMode": "direct" - }, - "SdkAnalysisLevel": "9.0.300" - }, - "frameworks": { - "net9.0-windows7.0": { - "targetAlias": "net9.0-windows", - "imports": [ - "net461", - "net462", - "net47", - "net471", - "net472", - "net48", - "net481" - ], - "assetTargetFallback": true, - "warn": true, - "frameworkReferences": { - "Microsoft.NETCore.App": { - "privateAssets": "all" - }, - "Microsoft.WindowsDesktop.App.WindowsForms": { - "privateAssets": "none" - } - }, - "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.315/PortableRuntimeIdentifierGraph.json" - } - } - } -} \ No newline at end of file diff --git a/EditorCS/obj/project.nuget.cache b/EditorCS/obj/project.nuget.cache deleted file mode 100644 index e4bd130..0000000 --- a/EditorCS/obj/project.nuget.cache +++ /dev/null @@ -1,8 +0,0 @@ -{ - "version": 2, - "dgSpecHash": "icz9DlDWgaA=", - "success": true, - "projectFilePath": "C:\\Users\\Administrator\\Downloads\\mimocode-windows-x64\\GameEngineASM\\EditorCS\\Lity3DEditor.csproj", - "expectedPackageFiles": [], - "logs": [] -} \ No newline at end of file diff --git a/Engine/ASM/asm_macros.inc b/Engine/ASM/asm_macros.inc deleted file mode 100644 index db7a7f4..0000000 --- a/Engine/ASM/asm_macros.inc +++ /dev/null @@ -1,137 +0,0 @@ -; ============================================================================ -; asm_macros.inc - MASM 通用宏定义 -; Windows x64 调用约定: RCX, RDX, R8, R9 传参, XMM0-XMM3 浮点 -; ============================================================================ - -; --- 函数帧管理宏 --- - -; PROLOGUE: 保存非易失寄存器, 分配栈空间 -; 使用: PROLOGUE 栈空间大小 -PROLOGUE MACRO stack_size:REQ - push rbx - push rbp - push rdi - push rsi - push r12 - push r13 - push r14 - push r15 - sub rsp, stack_size - ; 保存浮点参数寄存器 (如果有) - movsd qword ptr [rsp + stack_size - 8], xmm6 - movsd qword ptr [rsp + stack_size - 16], xmm7 -ENDM - -; EPILOGUE: 恢复非易失寄存器, 释放栈空间 -EPILOGUE MACRO stack_size:REQ - movsd xmm6, qword ptr [rsp + stack_size - 8] - movsd xmm7, qword ptr [rsp + stack_size - 16] - add rsp, stack_size - pop r15 - pop r14 - pop r13 - pop r12 - pop rsi - pop rdi - pop rbp - pop rbx - ret -ENDM - -; --- SSE/AVX 常量 --- -.DATA -ALIGN 16 -sse_mask_abs DD 07FFFFFFFH, 07FFFFFFFH, 07FFFFFFFH, 07FFFFFFFH ; 绝对值掩码 -sse_negate DD 80000000H, 80000000H, 80000000H, 80000000H ; 符号位掩码 -sse_one DD 3F800000H, 3F800000H, 3F800000H, 3F800000H ; 1.0f -sse_half DD 3F000000H, 3F000000H, 3F000000H, 3F000000H ; 0.5f -eps_float DD 33D6BF94H ; 1e-6f - -.CODE - -; --- 工具宏 --- - -; LOAD_VEC3: 从内存加载 Vec3 到 XMM 寄存器 (填充 w=1.0) -; ptr: 内存地址, reg: XMM 寄存器 -LOAD_VEC3 MACRO ptr, reg - movss xmm0, dword ptr [ptr] ; x - movss xmm1, dword ptr [ptr + 4] ; y - movss xmm2, dword ptr [ptr + 8] ; z - unpcklps xmm0, xmm1 ; {x, y, ?, ?} - movss xmm3, dword ptr [sse_one] ; w = 1.0 - unpcklps xmm2, xmm3 ; {z, 1.0, ?, ?} - movlhps xmm0, xmm2 ; {x, y, z, 1.0} - movaps reg, xmm0 -ENDM - -; STORE_VEC3: 将 XMM 寄存器的前3个float存储到内存 -STORE_VEC3 MACRO reg, ptr - movss dword ptr [ptr], xmm0 ; x - shufps xmm0, xmm0, 01010101b - movss dword ptr [ptr + 4], xmm0 ; y - shufps xmm0, xmm0, 10101010b - movss dword ptr [ptr + 8], xmm0 ; z -ENDM - -; --- 外部函数声明 --- -externdef vec3_add:PROC -externdef vec3_sub:PROC -externdef vec3_scale:PROC -externdef vec3_dot:PROC -externdef vec3_cross:PROC -externdef vec3_length:PROC -externdef vec3_normalize:PROC -externdef vec3_lerp:PROC -externdef vec3_distance:PROC - -externdef vec4_add:PROC -externdef vec4_sub:PROC -externdef vec4_mul:PROC -externdef vec4_dot:PROC -externdef vec4_length:PROC -externdef vec4_normalize:PROC - -externdef mat4_identity:PROC -externdef mat4_multiply:PROC -externdef mat4_transpose:PROC -externdef mat4_invert:PROC -externdef mat4_translate:PROC -externdef mat4_scale_f:PROC -externdef mat4_rotate_x:PROC -externdef mat4_rotate_y:PROC -externdef mat4_rotate_z:PROC -externdef mat4_perspective:PROC -externdef mat4_orthographic:PROC -externdef mat4_lookat:PROC - -externdef quat_multiply:PROC -externdef quat_conjugate:PROC -externdef quat_normalize:PROC -externdef quat_rotate_vec3:PROC -externdef quat_slerp:PROC -externdef quat_to_matrix:PROC -externdef quat_from_axis_angle:PROC -externdef quat_from_euler:PROC - -externdef mem_aligned_alloc:PROC -externdef mem_aligned_free:PROC -externdef mem_aligned_realloc:PROC - -externdef fast_memcpy:PROC -externdef fast_memset:PROC -externdef fast_strlen:PROC -externdef fast_strcmp:PROC - -externdef prof_rdtsc:PROC -externdef prof_cycles_to_ms:PROC -externdef prof_get_freq:PROC - -; C 数学运行时 -externdef cosf:PROC -externdef sinf:PROC -externdef tanf:PROC - -; Windows API -externdef Sleep:PROC -externdef QueryPerformanceFrequency:PROC -externdef QueryPerformanceCounter:PROC diff --git a/Engine/ASM/math.asm b/Engine/ASM/math.asm deleted file mode 100644 index f8d4d12..0000000 --- a/Engine/ASM/math.asm +++ /dev/null @@ -1,1189 +0,0 @@ -; ============================================================================ -; math.asm - SIMD 数学库 (x86-64 MASM) -; SSE4.1/AVX2/FMA 指令集加速 -; Windows x64 ABI: RCX, RDX, R8, R9 传参, XMM0-XMM3 浮点 -; ============================================================================ - -include asm_macros.inc - -.DATA -ALIGN 16 -_negate_mask DD 80000000H, 80000000H, 80000000H, 80000000H -_abs_mask DD 7FFFFFFFH, 7FFFFFFFH, 7FFFFFFFH, 7FFFFFFFH -_one DD 3F800000H, 3F800000H, 3F800000H, 3F800000H -_half DD 3F000000H, 3F000000H, 3F000000H, 3F000000H -_zero DD 0, 0, 0, 0 -_eps DD 33D6BF94H ; 1e-6 -_pi DD 40490FDBH ; 3.14159265 -_two_pi DD 40C90FDBH ; 2*PI -_half_pi DD 3FC90FDBH ; PI/2 -_deg_to_rad DD 3C8EFA35H ; PI/180 -_rad_to_deg DD 42652EE1H ; 180/PI - -.CODE - -; ============================================================================ -; Vector3 操作 -; ============================================================================ - -; void vec3_add(const Vec3* a, const Vec3* b, Vec3* out) -; RCX = a, RDX = b, R8 = out -vec3_add PROC - movss xmm0, dword ptr [rcx] ; a.x - addss xmm0, dword ptr [rdx] ; + b.x - movss dword ptr [r8], xmm0 ; out.x - - movss xmm0, dword ptr [rcx + 4] ; a.y - addss xmm0, dword ptr [rdx + 4] ; + b.y - movss dword ptr [r8 + 4], xmm0 ; out.y - - movss xmm0, dword ptr [rcx + 8] ; a.z - addss xmm0, dword ptr [rdx + 8] ; + b.z - movss dword ptr [r8 + 8], xmm0 ; out.z - - ret -vec3_add ENDP - -; void vec3_sub(const Vec3* a, const Vec3* b, Vec3* out) -vec3_sub PROC - movss xmm0, dword ptr [rcx] - subss xmm0, dword ptr [rdx] - movss dword ptr [r8], xmm0 - - movss xmm0, dword ptr [rcx + 4] - subss xmm0, dword ptr [rdx + 4] - movss dword ptr [r8 + 4], xmm0 - - movss xmm0, dword ptr [rcx + 8] - subss xmm0, dword ptr [rdx + 8] - movss dword ptr [r8 + 8], xmm0 - - ret -vec3_sub ENDP - -; void vec3_scale(const Vec3* a, float scalar, Vec3* out) -; RCX = a, XMM1 = scalar, RDX = out -vec3_scale PROC - movss xmm0, dword ptr [rcx] - mulss xmm0, xmm1 - movss dword ptr [rdx], xmm0 - - movss xmm0, dword ptr [rcx + 4] - mulss xmm0, xmm1 - movss dword ptr [rdx + 4], xmm0 - - movss xmm0, dword ptr [rcx + 8] - mulss xmm0, xmm1 - movss dword ptr [rdx + 8], xmm0 - - ret -vec3_scale ENDP - -; float vec3_dot(const Vec3* a, const Vec3* b) -> XMM0 -vec3_dot PROC - movss xmm0, dword ptr [rcx] ; a.x - mulss xmm0, dword ptr [rdx] ; * b.x - movss xmm1, dword ptr [rcx + 4] ; a.y - mulss xmm1, dword ptr [rdx + 4] ; * b.y - addss xmm0, xmm1 ; a.x*b.x + a.y*b.y - movss xmm1, dword ptr [rcx + 8] ; a.z - mulss xmm1, dword ptr [rdx + 8] ; * b.z - addss xmm0, xmm1 ; + a.z*b.z - ret -vec3_dot ENDP - -; void vec3_cross(const Vec3* a, const Vec3* b, Vec3* out) -vec3_cross PROC - ; out.x = a.y * b.z - a.z * b.y - movss xmm0, dword ptr [rcx + 4] ; a.y - mulss xmm0, dword ptr [rdx + 8] ; * b.z - movss xmm1, dword ptr [rcx + 8] ; a.z - mulss xmm1, dword ptr [rdx + 4] ; * b.y - subss xmm0, xmm1 - movss dword ptr [r8], xmm0 - - ; out.y = a.z * b.x - a.x * b.z - movss xmm0, dword ptr [rcx + 8] - mulss xmm0, dword ptr [rdx] - movss xmm1, dword ptr [rcx] - mulss xmm1, dword ptr [rdx + 8] - subss xmm0, xmm1 - movss dword ptr [r8 + 4], xmm0 - - ; out.z = a.x * b.y - a.y * b.x - movss xmm0, dword ptr [rcx] - mulss xmm0, dword ptr [rdx + 4] - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, dword ptr [rdx] - subss xmm0, xmm1 - movss dword ptr [r8 + 8], xmm0 - - ret -vec3_cross ENDP - -; float vec3_length(const Vec3* a) -> XMM0 -vec3_length PROC - movss xmm0, dword ptr [rcx] - mulss xmm0, xmm0 - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, xmm1 - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] - mulss xmm1, xmm1 - addss xmm0, xmm1 - sqrtss xmm0, xmm0 - ret -vec3_length ENDP - -; void vec3_normalize(const Vec3* a, Vec3* out) -vec3_normalize PROC - ; 计算长度 - movss xmm0, dword ptr [rcx] - mulss xmm0, xmm0 - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, xmm1 - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] - mulss xmm1, xmm1 - addss xmm0, xmm1 - sqrtss xmm0, xmm0 - - ; 检查零向量 - movss xmm1, dword ptr [_eps] - comiss xmm0, xmm1 - jb vec3_normalize_zero - - ; 归一化: 1.0 / length - movss xmm1, dword ptr [_one] - divss xmm1, xmm0 - - movss xmm0, dword ptr [rcx] - mulss xmm0, xmm1 - movss dword ptr [rdx], xmm0 - - movss xmm0, dword ptr [rcx + 4] - mulss xmm0, xmm1 - movss dword ptr [rdx + 4], xmm0 - - movss xmm0, dword ptr [rcx + 8] - mulss xmm0, xmm1 - movss dword ptr [rdx + 8], xmm0 - ret - -vec3_normalize_zero: - mov dword ptr [rdx], 0 - mov dword ptr [rdx + 4], 0 - mov dword ptr [rdx + 8], 0 - ret -vec3_normalize ENDP - -; void vec3_lerp(const Vec3* a, const Vec3* b, float t, Vec3* out) -; RCX = a, RDX = b, XMM2 = t, R8 = out -vec3_lerp PROC - ; out.x = a.x + (b.x - a.x) * t - movss xmm0, dword ptr [rdx] - subss xmm0, dword ptr [rcx] ; b.x - a.x - mulss xmm0, xmm2 ; * t - addss xmm0, dword ptr [rcx] ; + a.x - movss dword ptr [r8], xmm0 - - ; out.y - movss xmm0, dword ptr [rdx + 4] - subss xmm0, dword ptr [rcx + 4] - mulss xmm0, xmm2 - addss xmm0, dword ptr [rcx + 4] - movss dword ptr [r8 + 4], xmm0 - - ; out.z - movss xmm0, dword ptr [rdx + 8] - subss xmm0, dword ptr [rcx + 8] - mulss xmm0, xmm2 - addss xmm0, dword ptr [rcx + 8] - movss dword ptr [r8 + 8], xmm0 - - ret -vec3_lerp ENDP - -; float vec3_distance(const Vec3* a, const Vec3* b) -> XMM0 -vec3_distance PROC - ; 计算差向量然后求长度 - sub rsp, 16 - movss xmm0, dword ptr [rcx] - subss xmm0, dword ptr [rdx] - movss dword ptr [rsp], xmm0 - - movss xmm0, dword ptr [rcx + 4] - subss xmm0, dword ptr [rdx + 4] - movss dword ptr [rsp + 4], xmm0 - - movss xmm0, dword ptr [rcx + 8] - subss xmm0, dword ptr [rdx + 8] - movss dword ptr [rsp + 8], xmm0 - - ; 长度 - movss xmm0, dword ptr [rsp] - mulss xmm0, xmm0 - movss xmm1, dword ptr [rsp + 4] - mulss xmm1, xmm1 - addss xmm0, xmm1 - movss xmm1, dword ptr [rsp + 8] - mulss xmm1, xmm1 - addss xmm0, xmm1 - sqrtss xmm0, xmm0 - - add rsp, 16 - ret -vec3_distance ENDP - -; ============================================================================ -; Vector4 操作 (SSE 128-bit) -; ============================================================================ - -; void vec4_add(const Vec4* a, const Vec4* b, Vec4* out) -vec4_add PROC - movaps xmm0, xmmword ptr [rcx] - addps xmm0, xmmword ptr [rdx] - movaps xmmword ptr [r8], xmm0 - ret -vec4_add ENDP - -; void vec4_sub(const Vec4* a, const Vec4* b, Vec4* out) -vec4_sub PROC - movaps xmm0, xmmword ptr [rcx] - subps xmm0, xmmword ptr [rdx] - movaps xmmword ptr [r8], xmm0 - ret -vec4_sub ENDP - -; void vec4_mul(const Vec4* a, const Vec4* b, Vec4* out) -vec4_mul PROC - movaps xmm0, xmmword ptr [rcx] - mulps xmm0, xmmword ptr [rdx] - movaps xmmword ptr [r8], xmm0 - ret -vec4_mul ENDP - -; float vec4_dot(const Vec4* a, const Vec4* b) -> XMM0 -vec4_dot PROC - movaps xmm0, xmmword ptr [rcx] - mulps xmm0, xmmword ptr [rdx] ; 逐元素乘 - ; 水平求和: {x*y, ?, ?, ?} - movaps xmm1, xmm0 - shufps xmm1, xmm1, 01001110b ; swap pairs - addss xmm0, xmm1 ; x*y + z*w (低64位) - movhlps xmm1, xmm0 - addss xmm0, xmm1 ; 完整求和 - ret -vec4_dot ENDP - -; float vec4_length(const Vec4* a) -> XMM0 -vec4_length PROC - movaps xmm0, xmmword ptr [rcx] - mulps xmm0, xmm0 - movaps xmm1, xmm0 - shufps xmm1, xmm1, 01001110b - addss xmm0, xmm1 - movhlps xmm1, xmm0 - addss xmm0, xmm1 - sqrtss xmm0, xmm0 - ret -vec4_length ENDP - -; void vec4_normalize(const Vec4* a, Vec4* out) -vec4_normalize PROC - movaps xmm0, xmmword ptr [rcx] - mulps xmm0, xmm0 - movaps xmm1, xmm0 - shufps xmm1, xmm1, 01001110b - addss xmm0, xmm1 - movhlps xmm1, xmm0 - addss xmm0, xmm1 - sqrtss xmm0, xmm0 - ; 1.0 / length - movss xmm1, dword ptr [_one] - divss xmm1, xmm0 - ; 广播到所有通道 - shufps xmm1, xmm1, 0 - movaps xmm0, xmmword ptr [rcx] - mulps xmm0, xmm1 - movaps xmmword ptr [rdx], xmm0 - ret -vec4_normalize ENDP - -; ============================================================================ -; Matrix4x4 操作 -; ============================================================================ - -; void mat4_identity(Mat4* out) -; 输出 4x4 单位矩阵 -mat4_identity PROC - xorps xmm0, xmm0 ; 清零 - movaps xmmword ptr [rcx], xmm0 - movaps xmmword ptr [rcx + 16], xmm0 - movaps xmmword ptr [rcx + 32], xmm0 - movaps xmmword ptr [rcx + 48], xmm0 - movss dword ptr [rcx], xmm0 ; 已经是0, 下面设对角线 - mov dword ptr [rcx], 3F800000h ; m[0][0] = 1.0 - mov dword ptr [rcx + 20], 3F800000h ; m[1][1] = 1.0 - mov dword ptr [rcx + 40], 3F800000h ; m[2][2] = 1.0 - mov dword ptr [rcx + 60], 3F800000h ; m[3][3] = 1.0 - ret -mat4_identity ENDP - -; void mat4_multiply(const Mat4* a, const Mat4* b, Mat4* out) -; 4x4 矩阵乘法 - 按行主序存储 (行优先) -; a: RCX, b: RDX, out: R8 -mat4_multiply PROC - ; 逐行计算 out = a * b - ; out 的第 i 行 = a[i][0]*b行0 + a[i][1]*b行1 + a[i][2]*b行2 + a[i][3]*b行3 - - xor eax, eax ; 行索引 i = 0 -mat4_mul_row_loop: - ; 加载 a 的第 i 行的4个元素 - movss xmm4, dword ptr [rcx + rax*4] ; a[i][0] - shufps xmm4, xmm4, 0 ; 广播到所有通道 - movss xmm5, dword ptr [rcx + rax*4 + 16] ; a[i][1] - shufps xmm5, xmm5, 0 - movss xmm6, dword ptr [rcx + rax*4 + 32] ; a[i][2] - shufps xmm6, xmm6, 0 - movss xmm7, dword ptr [rcx + rax*4 + 48] ; a[i][3] - shufps xmm7, xmm7, 0 - - ; 加载 b 的4行, 乘以对应的 a[i][j], 累加 - movaps xmm0, xmmword ptr [rdx] ; b行0 - mulps xmm0, xmm4 - movaps xmm1, xmmword ptr [rdx + 16] ; b行1 - mulps xmm1, xmm5 - addps xmm0, xmm1 - movaps xmm1, xmmword ptr [rdx + 32] ; b行2 - mulps xmm1, xmm6 - addps xmm0, xmm1 - movaps xmm1, xmmword ptr [rdx + 48] ; b行3 - mulps xmm1, xmm7 - addps xmm0, xmm1 - - ; 存储到 out 的第 i 行 - movaps xmmword ptr [r8 + rax*4], xmm0 - - add eax, 4 ; 下一列 (行主序: 每4个float是一行) - cmp eax, 16 - jl mat4_mul_row_loop - ret -mat4_multiply ENDP - -; void mat4_transpose(const Mat4* a, Mat4* out) -mat4_transpose PROC - movaps xmm0, xmmword ptr [rcx] ; 行0 - movaps xmm1, xmmword ptr [rcx + 16] ; 行1 - movaps xmm2, xmmword ptr [rcx + 32] ; 行2 - movaps xmm3, xmmword ptr [rcx + 48] ; 行3 - - ; unpacklo/hi 交叉存取 - unpcklps xmm0, xmm1 ; {a00, a10, a01, a11} - unpcklps xmm2, xmm3 ; {a20, a30, a21, a31} - unpckhps xmm0, xmm1 ; {a02, a12, a03, a13} - unpckhps xmm2, xmm3 ; {a22, a32, a23, a33} - - movlhps xmm0, xmm2 ; 行0: {a00, a10, a20, a30} - movhlps xmm2, xmm0 ; 行1: {a01, a11, a21, a31} - - movaps xmmword ptr [rdx], xmm0 - movaps xmmword ptr [rdx + 16], xmm2 - - ; 继续处理后两行 - movaps xmm0, xmmword ptr [rcx] - movaps xmm1, xmmword ptr [rcx + 16] - movaps xmm2, xmmword ptr [rcx + 32] - movaps xmm3, xmmword ptr [rcx + 48] - - unpcklps xmm0, xmm1 - unpcklps xmm2, xmm3 - unpckhps xmm0, xmm1 - unpckhps xmm2, xmm3 - - movlhps xmm0, xmm2 - movhlps xmm2, xmm0 - - movaps xmmword ptr [rdx + 32], xmm2 - movaps xmmword ptr [rdx + 48], xmm0 - ret -mat4_transpose ENDP - -; int mat4_invert(const Mat4* a, Mat4* out) -> EAX (1=成功, 0=失败) -; 使用伴随矩阵法求逆 -mat4_invert PROC - PROLOGUE 128 - - ; 复制输入矩阵 - mov rdi, rsp ; rdi = 本地存储 - mov rsi, rcx ; rsi = 输入 - - ; 加载 4 行 - movaps xmm0, xmmword ptr [rsi] - movaps xmm1, xmmword ptr [rsi + 16] - movaps xmm2, xmmword ptr [rsi + 32] - movaps xmm3, xmmword ptr [rsi + 48] - - ; 存储到本地 - movaps xmmword ptr [rdi], xmm0 - movaps xmmword ptr [rdi + 16], xmm1 - movaps xmmword ptr [rdi + 32], xmm2 - movaps xmmword ptr [rdi + 48], xmm3 - - ; 简化实现: 对于单位矩阵附近的矩阵使用近似 - ; 完整实现需要高斯消元, 这里用 SIMD 优化的简化版本 - - ; 检查是否为单位矩阵 (快速路径) - movss xmm4, dword ptr [rsi] - movss xmm5, dword ptr [rsi + 20] - mulss xmm4, xmm5 - movss xmm6, dword ptr [rsi + 40] - mulss xmm4, xmm6 - movss xmm7, dword ptr [rsi + 60] - mulss xmm4, xmm7 ; det 主对角线乘积 - - ; 简化: 假设可逆, 直接计算 - ; 使用 4x4 行列式展开 - - EPILOGUE 128 -mat4_invert ENDP - -; void mat4_translate(float x, float y, float z, Mat4* out) -mat4_translate PROC - ; 初始化为单位矩阵 + 平移 - movss xmm0, dword ptr [rcx] ; x - movss xmm1, dword ptr [rdx] ; y - movss xmm2, dword ptr [r8] ; z - mov rax, r9 ; out - - ; 清零 - mov dword ptr [rax], 3F800000h ; m[0][0] = 1.0 - mov dword ptr [rax + 4], 0 - mov dword ptr [rax + 8], 0 - mov dword ptr [rax + 12], 0 - - mov dword ptr [rax + 16], 0 - mov dword ptr [rax + 20], 3F800000h ; m[1][1] = 1.0 - mov dword ptr [rax + 24], 0 - mov dword ptr [rax + 28], 0 - - mov dword ptr [rax + 32], 0 - mov dword ptr [rax + 36], 0 - mov dword ptr [rax + 40], 3F800000h ; m[2][2] = 1.0 - mov dword ptr [rax + 44], 0 - - movss dword ptr [rax + 48], xmm0 ; m[3][0] = x - movss dword ptr [rax + 52], xmm1 ; m[3][1] = y - movss dword ptr [rax + 56], xmm2 ; m[3][2] = z - mov dword ptr [rax + 60], 3F800000h ; m[3][3] = 1.0 - - ret -mat4_translate ENDP - -; void mat4_scale_f(float x, float y, float z, Mat4* out) -mat4_scale_f PROC - movss xmm0, dword ptr [rcx] ; x - movss xmm1, dword ptr [rdx] ; y - movss xmm2, dword ptr [r8] ; z - mov rax, r9 - - movss dword ptr [rax], xmm0 ; m[0][0] = x - mov dword ptr [rax + 4], 0 - mov dword ptr [rax + 8], 0 - mov dword ptr [rax + 12], 0 - - mov dword ptr [rax + 16], 0 - movss dword ptr [rax + 20], xmm1 ; m[1][1] = y - mov dword ptr [rax + 24], 0 - mov dword ptr [rax + 28], 0 - - mov dword ptr [rax + 32], 0 - mov dword ptr [rax + 36], 0 - movss dword ptr [rax + 40], xmm2 ; m[2][2] = z - mov dword ptr [rax + 44], 0 - - mov dword ptr [rax + 48], 0 - mov dword ptr [rax + 52], 0 - mov dword ptr [rax + 56], 0 - mov dword ptr [rax + 60], 3F800000h ; m[3][3] = 1.0 - - ret -mat4_scale_f ENDP - -; void mat4_rotate_x(float angle, Mat4* out) -mat4_rotate_x PROC - ; cos(angle), sin(angle) - movss xmm0, dword ptr [rcx] ; angle - movss xmm1, xmm0 ; save angle - call cosf ; xmm0 = cos - movss xmm2, xmm0 ; save cos - movss xmm0, xmm1 ; restore angle - call sinf ; xmm0 = sin - movss xmm1, xmm0 ; xmm1 = sin - movss xmm0, xmm2 ; xmm0 = cos - mov rax, rdx ; out - - movss dword ptr [rax], 3F800000h ; m[0][0] = 1.0 - mov dword ptr [rax + 4], 0 - mov dword ptr [rax + 8], 0 - mov dword ptr [rax + 12], 0 - - mov dword ptr [rax + 16], 0 - movss dword ptr [rax + 20], xmm0 ; m[1][1] = cos - ; m[1][2] = sin (需要取反 for row-major) - movss xmm2, xmm1 - movss dword ptr [rax + 24], xmm2 ; m[1][2] = sin - mov dword ptr [rax + 28], 0 - - mov dword ptr [rax + 32], 0 - ; m[2][1] = -sin - pxor xmm2, xmm2 - subss xmm2, xmm1 - movss dword ptr [rax + 36], xmm2 ; m[2][1] = -sin - movss dword ptr [rax + 40], xmm0 ; m[2][2] = cos - mov dword ptr [rax + 44], 0 - - mov dword ptr [rax + 48], 0 - mov dword ptr [rax + 52], 0 - mov dword ptr [rax + 56], 0 - mov dword ptr [rax + 60], 3F800000h - - ret -mat4_rotate_x ENDP - -; void mat4_rotate_y(float angle, Mat4* out) -mat4_rotate_y PROC - movss xmm0, dword ptr [rcx] - movss xmm1, xmm0 ; save angle - call cosf ; xmm0 = cos - movss xmm2, xmm0 ; save cos - movss xmm0, xmm1 ; restore angle - call sinf ; xmm0 = sin - movss xmm1, xmm0 ; xmm1 = sin - movss xmm0, xmm2 ; xmm0 = cos - mov rax, rdx - - movss dword ptr [rax], xmm0 ; m[0][0] = cos - mov dword ptr [rax + 4], 0 - movss xmm2, xmm1 - movss dword ptr [rax + 8], xmm2 ; m[0][2] = -sin - mov dword ptr [rax + 12], 0 - - mov dword ptr [rax + 16], 0 - mov dword ptr [rax + 20], 3F800000h - mov dword ptr [rax + 24], 0 - mov dword ptr [rax + 28], 0 - - ; m[2][0] = sin - movss dword ptr [rax + 32], xmm1 - mov dword ptr [rax + 36], 0 - movss dword ptr [rax + 40], xmm0 ; m[2][2] = cos - mov dword ptr [rax + 44], 0 - - mov dword ptr [rax + 48], 0 - mov dword ptr [rax + 52], 0 - mov dword ptr [rax + 56], 0 - mov dword ptr [rax + 60], 3F800000h - - ret -mat4_rotate_y ENDP - -; void mat4_rotate_z(float angle, Mat4* out) -mat4_rotate_z PROC - movss xmm0, dword ptr [rcx] - movss xmm1, xmm0 ; save angle - call cosf ; xmm0 = cos - movss xmm2, xmm0 ; save cos - movss xmm0, xmm1 ; restore angle - call sinf ; xmm0 = sin - movss xmm1, xmm0 ; xmm1 = sin - movss xmm0, xmm2 ; xmm0 = cos - mov rax, rdx - - movss dword ptr [rax], xmm0 ; m[0][0] = cos - movss xmm2, xmm1 - movss dword ptr [rax + 4], xmm2 ; m[0][1] = sin - mov dword ptr [rax + 8], 0 - mov dword ptr [rax + 12], 0 - - ; m[1][0] = -sin - pxor xmm2, xmm2 - subss xmm2, xmm1 - movss dword ptr [rax + 16], xmm2 - movss dword ptr [rax + 20], xmm0 ; m[1][1] = cos - mov dword ptr [rax + 24], 0 - mov dword ptr [rax + 28], 0 - - mov dword ptr [rax + 32], 0 - mov dword ptr [rax + 36], 0 - mov dword ptr [rax + 40], 3F800000h - mov dword ptr [rax + 44], 0 - - mov dword ptr [rax + 48], 0 - mov dword ptr [rax + 52], 0 - mov dword ptr [rax + 56], 0 - mov dword ptr [rax + 60], 3F800000h - - ret -mat4_rotate_z ENDP - -; void mat4_perspective(float fovY, float aspect, float nearZ, float farZ, Mat4* out) -; XMM0=fovY, XMM1=aspect, XMM2=nearZ, XMM3=farZ, RCX=out -mat4_perspective PROC - ; tan(fovY/2) - movss xmm4, xmm0 - mulss xmm4, dword ptr [_half] ; fovY/2 - movss xmm0, xmm4 - call tanf - movss xmm4, xmm0 ; xmm4 = tan(fovY/2) - - ; 1 / (aspect * tan) - movss xmm5, xmm1 - mulss xmm5, xmm4 ; aspect * tan - movss xmm6, dword ptr [_one] - divss xmm6, xmm5 ; 1 / (aspect * tan) - - ; 1 / tan - movss xmm7, dword ptr [_one] - divss xmm7, xmm4 ; 1 / tan - - ; far / (near - far) - movss xmm4, xmm2 - subss xmm4, xmm3 ; near - far - movss xmm5, xmm3 - divss xmm5, xmm4 ; far / (near - far) - - ; near * far / (near - far) - mulss xmm4, xmm2 ; (near - far) * near - ; 不对, 重新计算 - ; tmp = near * far / (near - far) - movss xmm4, xmm2 - mulss xmm4, xmm3 ; near * far - movss xmm7, xmm2 - subss xmm7, xmm3 ; near - far - divss xmm4, xmm7 ; near*far / (near-far) - - ; 填充矩阵 - mov rax, rcx - - ; 清零 - pxor xmm7, xmm7 - movaps xmmword ptr [rax], xmm7 - movaps xmmword ptr [rax + 16], xmm7 - movaps xmmword ptr [rax + 32], xmm7 - movaps xmmword ptr [rax + 48], xmm7 - - ; m[0][0] = 1 / (aspect * tan) - movss dword ptr [rax], xmm6 - ; m[1][1] = 1 / tan - movss dword ptr [rax + 20], xmm7 ; 需要重新加载 1/tan - ; 重新计算 - movss xmm0, dword ptr [rsp + 40] ; 从栈获取参数 (调用者可能已压栈) - ; 简化: 直接用寄存器值 - - mov rax, rcx - ; m[0][0] - movss dword ptr [rax], xmm6 - - ; 重新加载 1/tan 到 xmm7 - movss xmm7, dword ptr [_one] - divss xmm7, xmm4 ; 需要原始的 tan 值 - - ; 为了简化, 重新计算整个矩阵 - ; 用更清晰的方式 - pxor xmm7, xmm7 - movaps xmmword ptr [rax], xmm7 - movaps xmmword ptr [rax + 16], xmm7 - movaps xmmword ptr [rax + 32], xmm7 - movaps xmmword ptr [rax + 48], xmm7 - - ; 重新获取参数 - ; fovY 已在 xmm0 时的值, 但我们已经覆盖了 - ; 使用栈上的值 - - ; 简化: 使用标量方式设置 - ret -mat4_perspective ENDP - -; void mat4_orthographic(float width, float height, float nearZ, float farZ, Mat4* out) -mat4_orthographic PROC - movss xmm0, dword ptr [rcx] ; width - movss xmm1, dword ptr [rdx] ; height - movss xmm2, dword ptr [r8] ; nearZ - movss xmm3, dword ptr [r9] ; farZ - ; out 在 [rsp+40] (第5个参数) - mov r10, qword ptr [rsp + 40] - - ; 清零 - pxor xmm4, xmm4 - movaps xmmword ptr [r10], xmm4 - movaps xmmword ptr [r10 + 16], xmm4 - movaps xmmword ptr [r10 + 32], xmm4 - movaps xmmword ptr [r10 + 48], xmm4 - - ; 2/width - movss xmm4, dword ptr [_one] - addss xmm4, xmm4 ; 2.0 - divss xmm4, xmm0 ; 2/width - movss dword ptr [r10], xmm4 ; m[0][0] - - ; 2/height - movss xmm4, dword ptr [_one] - addss xmm4, xmm4 - divss xmm4, xmm1 - movss dword ptr [r10 + 20], xmm4 ; m[1][1] - - ; 1/(near-far) - movss xmm4, xmm2 - subss xmm4, xmm3 - movss xmm5, dword ptr [_one] - divss xmm5, xmm4 - movss dword ptr [r10 + 40], xmm5 ; m[2][2] - - ; near/(near-far) - mulss xmm4, xmm2 ; (near-far)*near... 不对 - ; 重新: near / (near - far) - movss xmm4, xmm2 - divss xmm4, [rsp + 32] ; near / (near-far) - 用原始值 - ; 简化 - movss xmm4, xmm2 - movss xmm5, xmm2 - subss xmm5, xmm3 - divss xmm4, xmm5 - movss dword ptr [r10 + 48], xmm4 ; m[3][2] - - mov dword ptr [r10 + 60], 3F800000h ; m[3][3] = 1.0 - - ret -mat4_orthographic ENDP - -; void mat4_lookat(const Vec3* eye, const Vec3* target, const Vec3* up, Mat4* out) -mat4_lookat PROC - PROLOGUE 64 - - ; zAxis = normalize(eye - target) - sub rsp, 32 - movss xmm0, dword ptr [rcx] ; eye.x - subss xmm0, dword ptr [rdx] ; - target.x - movss dword ptr [rsp], xmm0 - - movss xmm0, dword ptr [rcx + 4] - subss xmm0, dword ptr [rdx + 4] - movss dword ptr [rsp + 4], xmm0 - - movss xmm0, dword ptr [rcx + 8] - subss xmm0, dword ptr [rdx + 8] - movss dword ptr [rsp + 8], xmm0 - - ; normalize zAxis - movss xmm0, dword ptr [rsp] - mulss xmm0, xmm0 - movss xmm1, dword ptr [rsp + 4] - mulss xmm1, xmm1 - addss xmm0, xmm1 - movss xmm1, dword ptr [rsp + 8] - mulss xmm1, xmm1 - addss xmm0, xmm1 - sqrtss xmm0, xmm0 - movss xmm1, dword ptr [_one] - divss xmm1, xmm0 - - mulss xmm0, xmm1 - movss dword ptr [rsp], xmm0 - mulss xmm0, xmm1 - movss dword ptr [rsp + 4], xmm0 - mulss xmm0, xmm1 - movss dword ptr [rsp + 8], xmm0 - - ; xAxis = normalize(cross(up, zAxis)) - ; ... (简化实现) - - EPILOGUE 64 -mat4_lookat ENDP - -; ============================================================================ -; Quaternion 操作 -; ============================================================================ - -; void quat_multiply(const Quat* a, const Quat* b, Quat* out) -quat_multiply PROC - ; q = (x,y,z,w) - ; a = (ax,ay,az,aw), b = (bx,by,bz,bw) - ; out.x = aw*bx + ax*bw + ay*bz - az*by - ; out.y = aw*by - ax*bz + ay*bw + az*bx - ; out.z = aw*bz + ax*by - ay*bx + az*bw - ; out.w = aw*bw - ax*bx - ay*by - az*bz - - movss xmm0, dword ptr [rcx + 12] ; aw - mulss xmm0, dword ptr [rdx] ; aw*bx - movss xmm1, dword ptr [rcx] ; ax - mulss xmm1, dword ptr [rdx + 12] ; ax*bw - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 4] ; ay - mulss xmm1, dword ptr [rdx + 8] ; ay*bz - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] ; az - mulss xmm1, dword ptr [rdx + 4] ; az*by - subss xmm0, xmm1 - movss dword ptr [r8], xmm0 ; out.x - - ; out.y - movss xmm0, dword ptr [rcx + 12] - mulss xmm0, dword ptr [rdx + 4] - movss xmm1, dword ptr [rcx] - mulss xmm1, dword ptr [rdx + 8] - subss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, dword ptr [rdx + 12] - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] - mulss xmm1, dword ptr [rdx] - addss xmm0, xmm1 - movss dword ptr [r8 + 4], xmm0 - - ; out.z - movss xmm0, dword ptr [rcx + 12] - mulss xmm0, dword ptr [rdx + 8] - movss xmm1, dword ptr [rcx] - mulss xmm1, dword ptr [rdx + 4] - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, dword ptr [rdx] - subss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] - mulss xmm1, dword ptr [rdx + 12] - addss xmm0, xmm1 - movss dword ptr [r8 + 8], xmm0 - - ; out.w - movss xmm0, dword ptr [rcx + 12] - mulss xmm0, dword ptr [rdx + 12] - movss xmm1, dword ptr [rcx] - mulss xmm1, dword ptr [rdx] - subss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, dword ptr [rdx + 4] - subss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] - mulss xmm1, dword ptr [rdx + 8] - subss xmm0, xmm1 - movss dword ptr [r8 + 12], xmm0 - - ret -quat_multiply ENDP - -; void quat_conjugate(const Quat* q, Quat* out) -quat_conjugate PROC - movss xmm0, dword ptr [rcx] - movss xmm1, dword ptr [rcx + 4] - movss xmm2, dword ptr [rcx + 8] - movss xmm3, dword ptr [rcx + 12] - - pxor xmm4, xmm4 - subss xmm4, xmm0 ; -x - movss dword ptr [rdx], xmm4 - pxor xmm4, xmm4 - subss xmm4, xmm1 ; -y - movss dword ptr [rdx + 4], xmm4 - pxor xmm4, xmm4 - subss xmm4, xmm2 ; -z - movss dword ptr [rdx + 8], xmm4 - movss dword ptr [rdx + 12], xmm3 ; w 不变 - ret -quat_conjugate ENDP - -; void quat_normalize(const Quat* q, Quat* out) -quat_normalize PROC - ; 长度 = sqrt(x*x + y*y + z*z + w*w) - movss xmm0, dword ptr [rcx] - mulss xmm0, xmm0 - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, xmm1 - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] - mulss xmm1, xmm1 - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 12] - mulss xmm1, xmm1 - addss xmm0, xmm1 - sqrtss xmm0, xmm0 - - ; 1.0 / length - movss xmm1, dword ptr [_one] - divss xmm1, xmm0 - - ; 归一化 - movss xmm0, dword ptr [rcx] - mulss xmm0, xmm1 - movss dword ptr [rdx], xmm0 - movss xmm0, dword ptr [rcx + 4] - mulss xmm0, xmm1 - movss dword ptr [rdx + 4], xmm0 - movss xmm0, dword ptr [rcx + 8] - mulss xmm0, xmm1 - movss dword ptr [rdx + 8], xmm0 - movss xmm0, dword ptr [rcx + 12] - mulss xmm0, xmm1 - movss dword ptr [rdx + 12], xmm0 - ret -quat_normalize ENDP - -; void quat_rotate_vec3(const Quat* q, const Vec3* v, Vec3* out) -; 使用公式: v' = q * v * q_conjugate -quat_rotate_vec3 PROC - PROLOGUE 48 - - ; 计算 q * v (将v视为 w=0 的四元数) - ; 简化: 使用旋转公式 - ; v' = v + 2*w*(u x v) + 2*(u x (u x v)) - ; 其中 u = (x,y,z), w = quat.w - - movss xmm0, dword ptr [rcx] ; qx - movss xmm1, dword ptr [rcx + 4] ; qy - movss xmm2, dword ptr [rcx + 8] ; qz - movss xmm3, dword ptr [rcx + 12] ; qw - - ; u = (qx, qy, qz) - ; t = 2 * cross(u, v) - ; cross.x = qy*vz - qz*vy - movss xmm4, xmm1 - mulss xmm4, dword ptr [rdx + 8] ; qy * vz - movss xmm5, xmm2 - mulss xmm5, dword ptr [rdx + 4] ; qz * vy - subss xmm4, xmm5 ; cross.x - mulss xmm4, dword ptr [_one] ; * 2.0 (简化, 实际需要加) - ; ... (完整实现需要更多指令) - - ; 简化: 直接使用矩阵旋转 (先转四元数为矩阵) - ; 或使用优化的四元数旋转 - - EPILOGUE 48 -quat_rotate_vec3 ENDP - -; void quat_slerp(const Quat* a, const Quat* b, float t, Quat* out) -quat_slerp PROC - ; 计算点积 - movss xmm0, dword ptr [rcx] - mulss xmm0, dword ptr [rdx] - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, dword ptr [rdx + 4] - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] - mulss xmm1, dword ptr [rdx + 8] - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 12] - mulss xmm1, dword ptr [rdx + 12] - addss xmm0, xmm1 ; dot - - ; 如果 dot < 0, 翻转 b - pxor xmm1, xmm1 - comiss xmm0, xmm1 - jae slerp_no_flip - ; 翻转 b 的所有分量 - pxor xmm1, xmm1 - subss xmm1, dword ptr [rdx] - movss dword ptr [rsp - 16], xmm1 - ; ... (需要保存到临时空间) - movss xmm1, dword ptr [_negate_mask] ; 0x80000000 - xorps xmm0, xmm1 ; dot = -dot -slerp_no_flip: - - ; 简化: 线性插值 + 归一化 - ; out = normalize(a + t * (b - a)) - movss xmm1, xmm0 ; dot - ; 如果 dot 接近 1, 使用线性插值 - movss xmm2, dword ptr [_one] - subss xmm2, xmm1 ; 1 - dot - ; 简化实现 - ret -quat_slerp ENDP - -; void quat_to_matrix(const Quat* q, Mat4* out) -quat_to_matrix PROC - ; 从四元数构建旋转矩阵 - movss xmm0, dword ptr [rcx] ; x - movss xmm1, dword ptr [rcx + 4] ; y - movss xmm2, dword ptr [rcx + 8] ; z - movss xmm3, dword ptr [rcx + 12] ; w - - ; 预计算 - movss xmm4, xmm0 - addss xmm4, xmm0 ; 2x - movss xmm5, xmm1 - addss xmm5, xmm1 ; 2y - movss xmm6, xmm2 - addss xmm6, xmm2 ; 2z - - ; m[0][0] = 1 - 2y*y - 2z*z - movss xmm7, xmm1 - mulss xmm7, xmm5 ; 2y*y - movss xmm8, xmm2 - mulss xmm8, xmm6 ; 2z*z - addss xmm7, xmm8 - movss xmm8, dword ptr [_one] - subss xmm8, xmm7 - movss dword ptr [rdx], xmm8 - - ; m[0][1] = 2x*y + 2w*z - movss xmm7, xmm0 - mulss xmm7, xmm5 ; 2x*y - movss xmm8, xmm3 - mulss xmm8, xmm6 ; 2w*z - addss xmm7, xmm8 - movss dword ptr [rdx + 4], xmm7 - - ; m[0][2] = 2x*z - 2w*y - movss xmm7, xmm0 - mulss xmm7, xmm6 - movss xmm8, xmm3 - mulss xmm8, xmm5 - subss xmm7, xmm8 - movss dword ptr [rdx + 8], xmm7 - - mov dword ptr [rdx + 12], 0 - - ; 类似地计算其他行... (完整实现需要更多指令) - ; 这里省略重复代码 - - ret -quat_to_matrix ENDP - -; void quat_from_axis_angle(const Vec3* axis, float angle, Quat* out) -quat_from_axis_angle PROC - ; halfAngle = angle / 2 - movss xmm0, dword ptr [rdx] ; angle - mulss xmm0, dword ptr [_half] ; halfAngle - - ; s = sin(halfAngle) - movss xmm2, xmm0 ; save halfAngle - call sinf - movss xmm1, xmm0 ; xmm1 = sin - movss xmm0, xmm2 ; restore halfAngle - - ; 归一化轴 - movss xmm2, dword ptr [rcx] - mulss xmm2, xmm2 - movss xmm3, dword ptr [rcx + 4] - mulss xmm3, xmm3 - addss xmm2, xmm3 - movss xmm3, dword ptr [rcx + 8] - mulss xmm3, xmm3 - addss xmm2, xmm3 - sqrtss xmm2, xmm2 - movss xmm3, dword ptr [_one] - divss xmm3, xmm2 - - ; out.x = axis.x * s - movss xmm0, dword ptr [rcx] - mulss xmm0, xmm3 - mulss xmm0, xmm1 - movss dword ptr [r8], xmm0 - - ; out.y - movss xmm0, dword ptr [rcx + 4] - mulss xmm0, xmm3 - mulss xmm0, xmm1 - movss dword ptr [r8 + 4], xmm0 - - ; out.z - movss xmm0, dword ptr [rcx + 8] - mulss xmm0, xmm3 - mulss xmm0, xmm1 - movss dword ptr [r8 + 8], xmm0 - - ; out.w = cos(halfAngle) - call cosf - movss dword ptr [r8 + 12], xmm0 - - ret -quat_from_axis_angle ENDP - -; void quat_from_euler(float pitch, float yaw, float roll, Quat* out) -; XMM0=pitch, XMM1=yaw, XMM2=roll, RCX=out -quat_from_euler PROC - ; 半角 - mulss xmm0, dword ptr [_half] ; pitch/2 - mulss xmm1, dword ptr [_half] ; yaw/2 - mulss xmm2, dword ptr [_half] ; roll/2 - - ; 保存半角并计算 cos/sin - sub rsp, 48 - movss dword ptr [rsp + 0], xmm0 ; pitch/2 - movss dword ptr [rsp + 4], xmm1 ; yaw/2 - movss dword ptr [rsp + 8], xmm2 ; roll/2 - - call cosf - movss dword ptr [rsp + 12], xmm0 ; cp - movss xmm0, dword ptr [rsp + 0] - call sinf - movss dword ptr [rsp + 16], xmm0 ; sp - - movss xmm0, dword ptr [rsp + 4] - call cosf - movss dword ptr [rsp + 20], xmm0 ; cy - movss xmm0, dword ptr [rsp + 4] - call sinf - movss dword ptr [rsp + 24], xmm0 ; sy - - movss xmm0, dword ptr [rsp + 8] - call cosf - movss dword ptr [rsp + 28], xmm0 ; cr - movss xmm0, dword ptr [rsp + 8] - call sinf - movss dword ptr [rsp + 32], xmm0 ; sr - - movss xmm3, dword ptr [rsp + 12] ; cp - movss xmm4, dword ptr [rsp + 16] ; sp - movss xmm5, dword ptr [rsp + 20] ; cy - movss xmm6, dword ptr [rsp + 24] ; sy - movss xmm7, dword ptr [rsp + 28] ; cr - movss xmm2, dword ptr [rsp + 32] ; xmm2 = sr - add rsp, 48 - - ; out.x = sr*cp*cy - cr*sp*sy - movss xmm0, xmm2 ; sr - mulss xmm0, xmm3 ; sr*cp - mulss xmm0, xmm5 ; sr*cp*cy - movss xmm1, xmm7 ; cr - mulss xmm1, xmm4 ; cr*sp - mulss xmm1, xmm6 ; cr*sp*sy - subss xmm0, xmm1 - movss dword ptr [rcx], xmm0 - - ; out.y = cr*sp*cy + sr*cp*sy - movss xmm0, xmm7 - mulss xmm0, xmm4 - mulss xmm0, xmm5 - movss xmm1, xmm0 ; cr*sp*cy - movss xmm0, xmm2 ; sr (saved above in xmm2) - mulss xmm0, xmm3 - mulss xmm0, xmm6 - addss xmm0, xmm1 - movss dword ptr [rcx + 4], xmm0 - - ; out.z = cr*cp*sy - sr*sp*cy - movss xmm0, xmm7 - mulss xmm0, xmm3 - mulss xmm0, xmm6 - movss xmm1, xmm0 ; cr*cp*sy - movss xmm0, xmm2 ; sr - mulss xmm0, xmm4 - mulss xmm0, xmm5 - subss xmm1, xmm0 - movss dword ptr [rcx + 8], xmm1 - - ; out.w = cr*cp*cy + sr*sp*sy - movss xmm0, xmm7 - mulss xmm0, xmm3 - mulss xmm0, xmm5 - movss xmm1, xmm0 ; cr*cp*cy - movss xmm0, xmm2 ; sr - mulss xmm0, xmm4 - mulss xmm0, xmm6 - addss xmm0, xmm1 - movss dword ptr [rcx + 12], xmm0 - - ret -quat_from_euler ENDP - -END diff --git a/Engine/ASM/math_c_fallback.h b/Engine/ASM/math_c_fallback.h deleted file mode 100644 index 722ee59..0000000 --- a/Engine/ASM/math_c_fallback.h +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -#if !defined(MATH_ASM_AVAILABLE) || MATH_ASM_AVAILABLE == 0 - -typedef struct { float x, y, z; } Vec3; -typedef struct { float x, y, z, w; } Vec4; -typedef struct { float m[4][4]; } Mat4; -typedef struct { float x, y, z, w; } Quat; - -static inline void vec3_add(const Vec3* a, const Vec3* b, Vec3* o) { o->x=a->x+b->x; o->y=a->y+b->y; o->z=a->z+b->z; } -static inline void vec3_sub(const Vec3* a, const Vec3* b, Vec3* o) { o->x=a->x-b->x; o->y=a->y-b->y; o->z=a->z-b->z; } -static inline void vec3_scale(const Vec3* a, float s, Vec3* o) { o->x=a->x*s; o->y=a->y*s; o->z=a->z*s; } -static inline float vec3_dot(const Vec3* a, const Vec3* b) { return a->x*b->x+a->y*b->y+a->z*b->z; } -static inline void vec3_cross(const Vec3* a, const Vec3* b, Vec3* o) { o->x=a->y*b->z-a->z*b->y; o->y=a->z*b->x-a->x*b->z; o->z=a->x*b->y-a->y*b->x; } -static inline float vec3_length(const Vec3* a) { return sqrtf(a->x*a->x+a->y*a->y+a->z*a->z); } -static inline void vec3_normalize(const Vec3* a, Vec3* o) { float l=vec3_length(a); if(l<1e-6f){o->x=o->y=o->z=0;return;} float i=1.0f/l; o->x=a->x*i; o->y=a->y*i; o->z=a->z*i; } -static inline void vec3_lerp(const Vec3* a, const Vec3* b, float t, Vec3* o) { o->x=a->x+(b->x-a->x)*t; o->y=a->y+(b->y-a->y)*t; o->z=a->z+(b->z-a->z)*t; } -static inline float vec3_distance(const Vec3* a, const Vec3* b) { Vec3 d; vec3_sub(a,b,&d); return vec3_length(&d); } - -static inline void mat4_identity(Mat4* o) { memset(o,0,sizeof(Mat4)); o->m[0][0]=o->m[1][1]=o->m[2][2]=o->m[3][3]=1.0f; } -static inline void mat4_multiply(const Mat4* a, const Mat4* b, Mat4* o) { Mat4 r; int i,j,k; for(i=0;i<4;i++) for(j=0;j<4;j++) { r.m[i][j]=0; for(k=0;k<4;k++) r.m[i][j]+=a->m[i][k]*b->m[k][j]; } *o=r; } -static inline void mat4_translate(float x, float y, float z, Mat4* o) { mat4_identity(o); o->m[3][0]=x; o->m[3][1]=y; o->m[3][2]=z; } -static inline void mat4_rotate_y(float angle, Mat4* o) { float c=cosf(angle),s=sinf(angle); mat4_identity(o); o->m[0][0]=c; o->m[0][2]=-s; o->m[2][0]=s; o->m[2][2]=c; } -static inline void mat4_perspective(float fov, float aspect, float nearP, float farP, Mat4* o) { float t=tanf(fov*0.5f); memset(o,0,sizeof(Mat4)); o->m[0][0]=1.0f/(aspect*t); o->m[1][1]=1.0f/t; o->m[2][2]=farP/(nearP-farP); o->m[2][3]=-1.0f; o->m[3][2]=(nearP*farP)/(nearP-farP); } -static inline void mat4_orthographic(float w, float h, float nearP, float farP, Mat4* o) { memset(o,0,sizeof(Mat4)); o->m[0][0]=2.0f/w; o->m[1][1]=2.0f/h; o->m[2][2]=1.0f/(nearP-farP); o->m[3][2]=nearP/(nearP-farP); o->m[3][3]=1.0f; } -static inline void mat4_lookat(const Vec3* eye, const Vec3* target, const Vec3* up, Mat4* o) { Vec3 f,r,u; vec3_sub(target,eye,&f); vec3_normalize(&f,&f); vec3_cross(up,&f,&r); vec3_normalize(&r,&r); vec3_cross(&f,&r,&u); mat4_identity(o); o->m[0][0]=r.x; o->m[0][1]=u.x; o->m[0][2]=-f.x; o->m[1][0]=r.y; o->m[1][1]=u.y; o->m[1][2]=-f.y; o->m[2][0]=r.z; o->m[2][1]=u.z; o->m[2][2]=-f.z; o->m[3][0]=-vec3_dot(&r,eye); o->m[3][1]=-vec3_dot(&u,eye); o->m[3][2]=vec3_dot(&f,eye); } -static inline void mat4_transpose(const Mat4* in, Mat4* out) { for (int i=0;i<4;i++) for (int j=0;j<4;j++) out->m[i][j]=in->m[j][i]; } - -static inline void quat_conjugate_raw(const Quat* q, Quat* o) { o->x=-q->x; o->y=-q->y; o->z=-q->z; o->w=q->w; } -static inline void quat_multiply(const Quat* a, const Quat* b, Quat* o) { o->x=a->w*b->x+a->x*b->w+a->y*b->z-a->z*b->y; o->y=a->w*b->y-a->x*b->z+a->y*b->w+a->z*b->x; o->z=a->w*b->z+a->x*b->y-a->y*b->x+a->z*b->w; o->w=a->w*b->w-a->x*b->x-a->y*b->y-a->z*b->z; } -static inline void quat_normalize(const Quat* q, Quat* o) { float l=sqrtf(q->x*q->x+q->y*q->y+q->z*q->z+q->w*q->w); if(l<1e-6f){*o=*q;return;} float i=1.0f/l; o->x=q->x*i; o->y=q->y*i; o->z=q->z*i; o->w=q->w*i; } -static inline void quat_rotate_vec3(const Quat* q, const Vec3* v, Vec3* o) { Quat vq={v->x,v->y,v->z,0}; Quat qinv; quat_conjugate_raw(q,&qinv); Quat tmp; quat_multiply(q,&vq,&tmp); Quat result; quat_multiply(&tmp,&qinv,&result); o->x=result.x; o->y=result.y; o->z=result.z; } -static inline void quat_to_matrix(const Quat* q, Mat4* o) { float xx=q->x*q->x,yy=q->y*q->y,zz=q->z*q->z,xy=q->x*q->y,xz=q->x*q->z,yz=q->y*q->z,wx=q->w*q->x,wy=q->w*q->y,wz=q->w*q->z; mat4_identity(o); o->m[0][0]=1-2*(yy+zz); o->m[0][1]=2*(xy+wz); o->m[0][2]=2*(xz-wy); o->m[1][0]=2*(xy-wz); o->m[1][1]=1-2*(xx+zz); o->m[1][2]=2*(yz+wx); o->m[2][0]=2*(xz+wy); o->m[2][1]=2*(yz-wx); o->m[2][2]=1-2*(xx+yy); } - -static inline void quat_from_euler(float x, float y, float z, Quat* o) { - float cx = cosf(x * 0.5f), sx = sinf(x * 0.5f); - float cy = cosf(y * 0.5f), sy = sinf(y * 0.5f); - float cz = cosf(z * 0.5f), sz = sinf(z * 0.5f); - o->w = cx * cy * cz + sx * sy * sz; - o->x = sx * cy * cz - cx * sy * sz; - o->y = cx * sy * cz + sx * cy * sz; - o->z = cx * cy * sz - sx * sy * cz; -} - -static inline void quat_to_euler(const Quat* q, float* x, float* y, float* z) { - float sinr_cosp = 2.0f * (q->w * q->x + q->y * q->z); - float cosr_cosp = 1.0f - 2.0f * (q->x * q->x + q->y * q->y); - *x = atan2f(sinr_cosp, cosr_cosp); - - float sinp = 2.0f * (q->w * q->y - q->z * q->x); - if (fabsf(sinp) >= 1.0f) *y = copysignf(1.57079633f, sinp); - else *y = asinf(sinp); - - float siny_cosp = 2.0f * (q->w * q->z + q->x * q->y); - float cosy_cosp = 1.0f - 2.0f * (q->y * q->y + q->z * q->z); - *z = atan2f(siny_cosp, cosy_cosp); -} - -static inline void* mem_aligned_alloc(uint64_t size, uint64_t alignment) { void* p; p = _aligned_malloc(size, alignment); return p; } -static inline void mem_aligned_free(void* ptr) { _aligned_free(ptr); } - -static inline void fast_memcpy(void* dst, const void* src, uint64_t count) { memcpy(dst, src, (size_t)count); } -static inline void fast_memset(void* dst, int v, uint64_t count) { memset(dst, v, (size_t)count); } -static inline uint64_t fast_strlen(const char* s) { return strlen(s); } - -static inline uint64_t prof_rdtsc(void) { LARGE_INTEGER f,t; QueryPerformanceFrequency(&f); QueryPerformanceCounter(&t); return (uint64_t)(t.QuadPart * 1000000000ULL / f.QuadPart); } -static inline double prof_cycles_to_ms(uint64_t c) { return (double)c / 1000000.0; } -static inline uint64_t prof_get_freq(void) { LARGE_INTEGER f; QueryPerformanceFrequency(&f); return (uint64_t)f.QuadPart; } - -typedef struct { uint64_t start; uint64_t end; double elapsed_ms; } ProfTimer; -static inline void prof_timer_start(ProfTimer* t) { t->start = prof_rdtsc(); } -static inline void prof_timer_stop(ProfTimer* t) { t->end = prof_rdtsc(); t->elapsed_ms = prof_cycles_to_ms(t->end - t->start); } - -#endif diff --git a/Engine/ASM/memory.asm b/Engine/ASM/memory.asm deleted file mode 100644 index 2d67468..0000000 --- a/Engine/ASM/memory.asm +++ /dev/null @@ -1,180 +0,0 @@ -; ============================================================================ -; memory.asm - 对齐内存分配器 (x86-64 MASM) -; 支持 16/32/64 字节对齐 (SIMD 需要) -; ============================================================================ - -include asm_macros.inc - -.DATA -ALIGN 16 -_alloc_header_size EQU 32 ; 分配头大小 (包含对齐偏移和原始指针) - -.CODE - -; ============================================================================ -; 对齐内存分配 -; ============================================================================ - -; void* mem_aligned_alloc(uint64_t size, uint64_t alignment) -; RCX = size, RDX = alignment -; 返回: RAX = 对齐指针 -mem_aligned_alloc PROC - push rbx - push rdi - push rsi - sub rsp, 40 ; 保留栈空间 - - mov rbx, rcx ; rbx = size - mov rdi, rdx ; rdi = alignment - - ; 验证 alignment 是 2 的幂 - mov rax, rdi - dec rax - test rdi, rax - jnz alloc_invalid_alignment - - ; 确保 alignment >= 16 - cmp rdi, 16 - jae alloc_alignment_ok - mov rdi, 16 - -alloc_alignment_ok: - ; 需要的总大小 = size + alignment + header - mov rax, rbx - add rax, rdi ; + alignment - add rax, _alloc_header_size ; + header - mov rsi, rax ; rsi = total size - - ; 调用 malloc - mov rcx, rsi - call malloc - test rax, rax - jz alloc_failed - - ; rax = 原始指针 - ; 计算对齐后的地址 - mov rcx, rax - add rcx, _alloc_header_size ; 跳过 header - ; 对齐 - mov rdx, rdi - dec rdx - not rdx - add rcx, rdx ; 加上 alignment-1 - and rcx, rdx ; 对齐到 alignment - - ; rcx = 对齐后的指针 - ; 在对齐指针前存储原始指针 - mov [rcx - 8], rax ; 存储原始 malloc 指针 - mov [rcx - 16], rbx ; 存储请求的 size - mov [rcx - 24], rdi ; 存储 alignment - mov [rcx - 32], rsi ; 存储 total size - - mov rax, rcx ; 返回对齐指针 - jmp alloc_done - -alloc_invalid_alignment: - xor rax, rax ; 返回 NULL - jmp alloc_done - -alloc_failed: - xor rax, rax - -alloc_done: - add rsp, 40 - pop rsi - pop rdi - pop rbx - ret -mem_aligned_alloc ENDP - -; void mem_aligned_free(void* ptr) -; RCX = ptr (对齐指针) -mem_aligned_free PROC - test rcx, rcx - jz free_done - - ; 获取原始 malloc 指针 - mov rax, [rcx - 8] - test rax, rax - jz free_done - - ; 调用 free - mov rcx, rax - call free - -free_done: - ret -mem_aligned_free ENDP - -; void* mem_aligned_realloc(void* ptr, uint64_t size, uint64_t alignment) -; RCX = ptr, RDX = size, R8 = alignment -; 返回: RAX = 新对齐指针 -mem_aligned_realloc PROC - push rbx - push rdi - push rsi - push r12 - sub rsp, 56 ; shadow + 3 saved qwords - - mov rbx, rdx ; rbx = new size - mov rdi, r8 ; rdi = alignment - - ; 如果 ptr 为 NULL, 直接分配 - test rcx, rcx - jz realloc_alloc - - ; 保存旧信息 - mov [rsp + 32], rcx ; 旧对齐指针(即用户数据起始) - mov rax, [rcx - 8] - mov [rsp + 24], rax ; 旧原始 malloc 指针 - mov rax, [rcx - 16] - mov [rsp + 16], rax ; 旧 size - - ; 分配新内存 - mov rcx, rbx - mov rdx, rdi - call mem_aligned_alloc - test rax, rax - jz realloc_failed - - mov rsi, rax ; rsi = 新对齐指针 - - ; 复制旧数据 (取较小值) - mov rdx, [rsp + 16] ; 旧 size - cmp rdx, rbx - jbe realloc_copy_ok - mov rdx, rbx - -realloc_copy_ok: - ; fast_memcpy(dst, src, count): rcx=dst, rdx=src, r8=count - mov rcx, rsi - mov r8, rdx - mov rdx, [rsp + 32] ; 旧对齐指针 - call fast_memcpy - - ; 释放旧内存(使用原始 malloc 指针) - mov rcx, [rsp + 24] - call mem_aligned_free - - mov rax, rsi ; 返回新指针 - jmp realloc_done - -realloc_alloc: - mov rcx, rbx - mov rdx, rdi - call mem_aligned_alloc - jmp realloc_done - -realloc_failed: - xor rax, rax - -realloc_done: - add rsp, 56 - pop r12 - pop rsi - pop rdi - pop rbx - ret -mem_aligned_realloc ENDP - -END diff --git a/Engine/ASM/profiling.asm b/Engine/ASM/profiling.asm deleted file mode 100644 index 5b15edc..0000000 --- a/Engine/ASM/profiling.asm +++ /dev/null @@ -1,148 +0,0 @@ -; ============================================================================ -; profiling.asm - 性能分析工具 (x86-64 MASM) -; 使用 RDTSC/RDTSCP 进行高精度计时 -; ============================================================================ - -include asm_macros.inc - -.DATA -ALIGN 8 -cpu_freq DQ 0 ; CPU 频率 (Hz) -cpu_freq_init DB 0 ; 是否已初始化 - -.CODE - -; ============================================================================ -; RDTSC 计时 -; ============================================================================ - -; uint64_t prof_rdtsc(void) -> RAX -; 返回: TSC (Time Stamp Counter) 值 -prof_rdtsc PROC - ; 使用 RDTSCP 获取有序的 TSC - rdtscp - ; EDX:EAX = TSC - shl rdx, 32 - or rax, rdx - ret -prof_rdtsc ENDP - -; uint64_t prof_get_freq(void) -> RAX -; 获取 CPU 频率 (Hz), 使用 QPC 校准 TSC -prof_get_freq PROC - ; 检查是否已初始化 - cmp byte ptr [cpu_freq_init], 0 - jnz prof_freq_return - - push rbx - push rdi - push rsi - sub rsp, 40 - - ; 获取 QPC 频率 - lea rcx, [rsp + 32] - call QueryPerformanceFrequency - - ; 获取起始 QPC 和 TSC - lea rcx, [rsp + 24] - call QueryPerformanceCounter - rdtscp - shl rdx, 32 - or rax, rdx - mov rbx, rax ; rbx = 起始 TSC - - ; 等待约 10ms - mov rcx, 10 ; 10 毫秒 - call Sleep - - ; 获取结束 QPC 和 TSC - lea rcx, [rsp + 16] - call QueryPerformanceCounter - rdtscp - shl rdx, 32 - or rax, rdx - mov rdi, rax ; rdi = 结束 TSC - - ; qpc_diff = end_qpc - start_qpc - mov rax, [rsp + 16] - sub rax, [rsp + 24] - mov rsi, rax ; rsi = qpc_diff - - ; tsc_diff = end_tsc - start_tsc - mov rcx, rdi - sub rcx, rbx ; rcx = tsc_diff - - ; cpu_freq = tsc_diff * qpc_freq / qpc_diff - mov rax, rcx ; rax = tsc_diff - mov rdx, [rsp + 32] ; rdx = qpc_freq - mul rdx ; rdx:rax = tsc_diff * qpc_freq - div rsi ; rax = freq (Hz) - - mov [cpu_freq], rax - mov byte ptr [cpu_freq_init], 1 - - add rsp, 40 - pop rsi - pop rdi - pop rbx - -prof_freq_return: - mov rax, [cpu_freq] - ret -prof_get_freq ENDP - -; double prof_cycles_to_ms(uint64_t cycles) -> XMM0 -; 将 TSC cycles 转换为毫秒: ms = cycles * 1000 / freq -prof_cycles_to_ms PROC - mov rdx, rcx ; 保存 cycles - call prof_get_freq ; rax = CPU freq (Hz) - - cvtsi2sd xmm0, rdx ; xmm0 = cycles (double) - mov rcx, 1000 - cvtsi2sd xmm1, rcx ; xmm1 = 1000.0 - mulsd xmm0, xmm1 ; cycles * 1000 - cvtsi2sd xmm1, rax ; xmm1 = freq - divsd xmm0, xmm1 ; ms - ret -prof_cycles_to_ms ENDP - -; ============================================================================ -; 内联性能宏 (在 C 代码中使用) -; ============================================================================ - -; 获取当前时间戳 (直接 RDTSC, 无函数调用开销) -; 在 C 中使用: __rdtsc() 内联函数 - -; 高精度计时器结构 -; struct ProfTimer { -; uint64_t start; -; uint64_t end; -; double elapsed_ms; -; }; - -; void prof_timer_start(ProfTimer* timer) -prof_timer_start PROC - rdtscp - shl rdx, 32 - or rax, rdx - mov [rcx], rax ; timer->start = tsc - ret -prof_timer_start ENDP - -; void prof_timer_stop(ProfTimer* timer) -prof_timer_stop PROC - rdtscp - shl rdx, 32 - or rax, rdx - mov [rcx + 8], rax ; timer->end = tsc - - ; 计算 elapsed_ms - mov rax, [rcx + 8] - sub rax, [rcx] ; cycles - ; 转换为 ms - call prof_cycles_to_ms - movsd qword ptr [rcx + 16], xmm0 ; timer->elapsed_ms - ret -prof_timer_stop ENDP - -END diff --git a/Engine/ASM/string_ops.asm b/Engine/ASM/string_ops.asm deleted file mode 100644 index 65dc5f0..0000000 --- a/Engine/ASM/string_ops.asm +++ /dev/null @@ -1,304 +0,0 @@ -; ============================================================================ -; string_ops.asm - 快速字符串/内存操作 (x86-64 MASM) -; 使用 SSE4.1 加速 memcpy/memset/strlen -; ============================================================================ - -include asm_macros.inc - -.CODE - -; ============================================================================ -; 内存操作 -; ============================================================================ - -; void fast_memcpy(void* dst, const void* src, uint64_t count) -; RCX = dst, RDX = src, R8 = count -fast_memcpy PROC - mov rax, rcx ; rax = dst - mov r9, r8 ; r9 = count - - ; 小于 16 字节: 逐字节复制 - cmp r9, 16 - jb memcpy_small - - ; 16-32 字节: 两次 128-bit 加载 - cmp r9, 32 - jb memcpy_16_32 - - ; 32-64 字节: 四次 128-bit 加载 - cmp r9, 64 - jb memcpy_32_64 - - ; >= 64 字节: SSE 批量复制 - ; 确保 16 字节对齐 - mov r10, rcx - and r10, 0Fh ; 检查 dst 对齐 - jnz memcpy_unaligned - -memcpy_aligned_loop: - cmp r9, 64 - jb memcpy_tail - - ; 每次复制 64 字节 (4x128-bit) - movaps xmm0, xmmword ptr [rdx] - movaps xmm1, xmmword ptr [rdx + 16] - movaps xmm2, xmmword ptr [rdx + 32] - movaps xmm3, xmmword ptr [rdx + 48] - - movaps xmmword ptr [rcx], xmm0 - movaps xmmword ptr [rcx + 16], xmm1 - movaps xmmword ptr [rcx + 32], xmm2 - movaps xmmword ptr [rcx + 48], xmm3 - - add rcx, 64 - add rdx, 64 - sub r9, 64 - jmp memcpy_aligned_loop - -memcpy_tail: - ; 处理剩余 0-63 字节 - test r9, 32 - jz memcpy_tail_16 - movaps xmm0, xmmword ptr [rdx] - movaps xmm1, xmmword ptr [rdx + 16] - movaps xmmword ptr [rcx], xmm0 - movaps xmmword ptr [rcx + 16], xmm1 - add rcx, 32 - add rdx, 32 - sub r9, 32 - -memcpy_tail_16: - test r9, 16 - jz memcpy_tail_8 - movaps xmm0, xmmword ptr [rdx] - movaps xmmword ptr [rcx], xmm0 - -memcpy_tail_8: - test r9, 8 - jz memcpy_tail_4 - mov r10, qword ptr [rdx] - mov qword ptr [rcx], r10 - -memcpy_tail_4: - test r9, 4 - jz memcpy_tail_2 - mov r10d, dword ptr [rdx] - mov dword ptr [rcx], r10d - -memcpy_tail_2: - test r9, 2 - jz memcpy_tail_1 - mov r10w, word ptr [rdx] - mov word ptr [rcx], r10w - -memcpy_tail_1: - test r9, 1 - jz memcpy_done - mov r10b, byte ptr [rdx] - mov byte ptr [rcx], r10b - jmp memcpy_done - -memcpy_unaligned: - ; 非对齐时使用 movups - movups xmm0, xmmword ptr [rdx] - movups xmmword ptr [rcx], xmm0 - add rcx, 16 - add rdx, 16 - sub r9, 16 - jmp memcpy_aligned_loop - -memcpy_32_64: - mov r10, qword ptr [rdx] - mov qword ptr [rcx], r10 - mov r10, qword ptr [rdx + 8] - mov qword ptr [rcx + 8], r10 - mov r10, qword ptr [rdx + 16] - mov qword ptr [rcx + 16], r10 - mov r10, qword ptr [rdx + 24] - mov qword ptr [rcx + 24], r10 - sub r9, 32 - add rdx, 32 - add rcx, 32 - jmp memcpy_small - -memcpy_16_32: - mov r10, qword ptr [rdx] - mov qword ptr [rcx], r10 - mov r10, qword ptr [rdx + 8] - mov qword ptr [rcx + 8], r10 - test r9, 8 - jz memcpy_16_32_done - mov r10, qword ptr [rdx + 16] - mov qword ptr [rcx + 16], r10 -memcpy_16_32_done: - jmp memcpy_done - -memcpy_small: - test r9, r9 - jz memcpy_done - - mov r10, r9 - and r10, 7 ; r10 = count % 8 - shr r9, 3 ; r9 = count / 8 - - ; 复制完整 8 字节 -memcpy_small_loop: - test r9, r9 - jz memcpy_small_tail - mov r11, qword ptr [rdx] - mov qword ptr [rcx], r11 - add rdx, 8 - add rcx, 8 - dec r9 - jmp memcpy_small_loop - -memcpy_small_tail: - ; 复制剩余字节 - test r10, r10 - jz memcpy_done - mov r11b, byte ptr [rdx] - mov byte ptr [rcx], r11b - inc rdx - inc rcx - dec r10 - jmp memcpy_small_tail - -memcpy_done: - mov rax, rax ; 返回 dst - ret -fast_memcpy ENDP - -; void fast_memset(void* dst, int value, uint64_t count) -; RCX = dst, EDX = value, R8 = count -fast_memset PROC - mov rax, rcx - mov r9, r8 - - ; 将 value 扩展到所有字节 - movsx rdx, dl ; 符号扩展 - mov rcx, rdx - shl rcx, 8 - or rdx, rcx - mov rcx, rdx - shl rcx, 16 - or rdx, rcx ; rdx = value 重复4次 - mov rcx, rdx - shl rcx, 32 - or rdx, rcx ; rdx = value 重复8次 - - ; 复制到 XMM 寄存器 - vmovq xmm0, rdx - vinsertf128 ymm0, ymm0, xmm0, 1 ; 256-bit 广播 - - ; >= 32 字节: AVX 批量 - cmp r9, 32 - jb memset_small - -memset_avx_loop: - cmp r9, 32 - jb memset_tail - - vmovdqu ymmword ptr [rax], ymm0 - add rax, 32 - sub r9, 32 - jmp memset_avx_loop - -memset_tail: - ; 处理剩余 0-31 字节 - test r9, 16 - jz memset_tail_8 - movups xmmword ptr [rax], xmm0 - add rax, 16 - sub r9, 16 - -memset_tail_8: - test r9, 8 - jz memset_tail_4 - mov qword ptr [rax], rdx - add rax, 8 - -memset_tail_4: - test r9, 4 - jz memset_tail_2 - mov dword ptr [rax], edx - add rax, 4 - -memset_tail_2: - test r9, 2 - jz memset_tail_1 - mov word ptr [rax], dx - add rax, 2 - -memset_tail_1: - test r9, 1 - jz memset_done - mov byte ptr [rax], dl - jmp memset_done - -memset_small: - test r9, r9 - jz memset_done - mov byte ptr [rax], dl - inc rax - dec r9 - jmp memset_small - -memset_done: - vzeroupper - ret -fast_memset ENDP - -; ============================================================================ -; 字符串操作 -; ============================================================================ - -; uint64_t fast_strlen(const char* str) -> RAX -; 使用 SSE4.2 PCMPESTRI 搜索 null terminator -fast_strlen PROC - mov rdx, rcx ; rdx = original str - pxor xmm0, xmm0 ; 搜索 0 - -strlen_sse_loop: - mov rax, rcx ; rax = 当前 16 字节块起始 - movdqu xmm1, xmmword ptr [rcx] - pcmpestri xmm0, xmm1, 00001000b ; 搜索 0, CF=1 表示找到, ECX=偏移 - jc strlen_found - add rcx, 16 - jmp strlen_sse_loop - -strlen_found: - ; rax = 块起始, rcx (ecx) = 块内偏移 - add rax, rcx - sub rax, rdx - ret -fast_strlen ENDP - -; int fast_strcmp(const char* a, const char* b) -> EAX -; 返回: 0=相等, <0=a0=a>b -fast_strcmp PROC - xor rax, rax - -strcmp_loop: - movzx r8d, byte ptr [rcx + rax] - movzx r9d, byte ptr [rdx + rax] - - cmp r8b, r9b - jne strcmp_diff - - test r8b, r8b - jz strcmp_equal - - inc rax - jmp strcmp_loop - -strcmp_diff: - mov eax, r8d - sub eax, r9d - ret - -strcmp_equal: - xor eax, eax - ret -fast_strcmp ENDP - -END diff --git a/Engine/Asset/mesh.h b/Engine/Asset/mesh.h deleted file mode 100644 index bdedd37..0000000 --- a/Engine/Asset/mesh.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -// ============================================================================ -// mesh.h - 网格 (顶点缓冲 + 索引缓冲) -// ============================================================================ - -#include -#include - -typedef struct { - ID3D11Buffer* vertex_buffer; - ID3D11Buffer* index_buffer; - uint32_t vertex_count; - uint32_t index_count; - uint32_t vertex_stride; -} MeshBuffer; - -// 从内存数据创建网格 -MeshBuffer* mesh_create(ID3D11Device* device, - const void* vertices, uint32_t vertex_count, uint32_t vertex_stride, - const uint32_t* indices, uint32_t index_count); - -// 从 OBJ 文件加载网格 (简化版: 仅顶点+面) -MeshBuffer* mesh_load_obj(ID3D11Device* device, const char* filepath); - -// 销毁 -void mesh_destroy(MeshBuffer* mesh); - -// 绘制 -void mesh_draw(ID3D11DeviceContext* ctx, MeshBuffer* mesh); diff --git a/Engine/Asset/texture.h b/Engine/Asset/texture.h deleted file mode 100644 index 412886d..0000000 --- a/Engine/Asset/texture.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include - -typedef struct { - ID3D11Texture2D* texture; - ID3D11ShaderResourceView* srv; - uint32_t width, height; -} Texture; - -Texture* texture_load_bmp(ID3D11Device* dev, const char* path); -Texture* texture_create_white(ID3D11Device* dev, uint32_t w, uint32_t h); -void texture_destroy(Texture* tex); diff --git a/Engine/Audio/audio.c b/Engine/Audio/audio.c deleted file mode 100644 index 71a1acd..0000000 --- a/Engine/Audio/audio.c +++ /dev/null @@ -1,277 +0,0 @@ -#include "audio.h" - -#include -#include -#include -#include - -#pragma comment(lib, "xaudio2.lib") - -// MinGW 没有 xaudio2.lib,通过系统 DLL 动态加载 XAudio2Create -typedef HRESULT (WINAPI *XAudio2CreateFunc)(IXAudio2** ppxaudio2, UINT32 flags, XAUDIO2_PROCESSOR processor); - -static HRESULT engine_xaudio2_create(IXAudio2** ppxaudio2, UINT32 flags, XAUDIO2_PROCESSOR processor) { - static HMODULE mod = NULL; - static XAudio2CreateFunc func = NULL; - if (!func) { - mod = LoadLibraryA("xaudio2_9.dll"); - if (!mod) mod = LoadLibraryA("xaudio2_8.dll"); - if (!mod) mod = LoadLibraryA("xaudio2_7.dll"); - if (mod) func = (XAudio2CreateFunc)GetProcAddress(mod, "XAudio2Create"); - } - if (!func) return E_FAIL; - return func(ppxaudio2, flags, processor); -} - -typedef struct { - WAVEFORMATEX format; - uint8_t* data; - uint32_t size; -} WavData; - -static int wav_load(const uint8_t* file_data, uint32_t file_size, WavData* out) { - memset(out, 0, sizeof(*out)); - if (file_size < 12) return 0; - if (memcmp(file_data, "RIFF", 4) != 0) return 0; - if (memcmp(file_data + 8, "WAVE", 4) != 0) return 0; - - uint32_t offset = 12; - int has_fmt = 0; - int has_data = 0; - - while (offset + 8 <= file_size) { - const uint8_t* chunk_id = file_data + offset; - uint32_t chunk_size = *(const uint32_t*)(file_data + offset + 4); - const uint8_t* chunk_data = file_data + offset + 8; - - if (offset + 8 + chunk_size > file_size) return 0; - - if (memcmp(chunk_id, "fmt ", 4) == 0 && chunk_size >= 16) { - uint32_t copy_size = chunk_size >= sizeof(WAVEFORMATEX) ? sizeof(WAVEFORMATEX) : chunk_size; - memcpy(&out->format, chunk_data, copy_size); - if (out->format.wFormatTag != WAVE_FORMAT_PCM && out->format.wFormatTag != WAVE_FORMAT_IEEE_FLOAT) { - return 0; - } - if (out->format.cbSize != 0) { - out->format.cbSize = 0; - } - has_fmt = 1; - } else if (memcmp(chunk_id, "data", 4) == 0) { - out->data = (uint8_t*)chunk_data; - out->size = chunk_size; - has_data = 1; - } - - offset += 8 + chunk_size; - if (chunk_size & 1) offset += 1; // 对齐到偶数字节 - } - - return has_fmt && has_data; -} - -AudioSystem* audio_create(void) { - CoInitializeEx(NULL, COINIT_MULTITHREADED); - - AudioSystem* audio = (AudioSystem*)calloc(1, sizeof(AudioSystem)); - if (!audio) return NULL; - - HRESULT hr = engine_xaudio2_create(&audio->xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR); - if (FAILED(hr) || !audio->xaudio2) { - free(audio); - return NULL; - } - - hr = audio->xaudio2->lpVtbl->CreateMasteringVoice( - audio->xaudio2, - &audio->mastering_voice, - XAUDIO2_DEFAULT_CHANNELS, - XAUDIO2_DEFAULT_SAMPLERATE, - 0, - NULL, - NULL, - AudioCategory_GameEffects); - if (FAILED(hr)) { - audio->xaudio2->lpVtbl->Release(audio->xaudio2); - free(audio); - return NULL; - } - - return audio; -} - -void audio_destroy(AudioSystem* audio) { - if (!audio) return; - if (audio->mastering_voice) { - audio->mastering_voice->lpVtbl->DestroyVoice(audio->mastering_voice); - } - if (audio->xaudio2) { - audio->xaudio2->lpVtbl->Release(audio->xaudio2); - } - free(audio); - CoUninitialize(); -} - -AudioSource* audio_source_create(AudioSystem* audio) { - if (!audio) return NULL; - AudioSource* source = (AudioSource*)calloc(1, sizeof(AudioSource)); - if (!source) return NULL; - source->system = audio; - source->volume = 1.0f; - source->pitch = 1.0f; - source->loop = 0; - source->state = AUDIO_STOPPED; - return source; -} - -void audio_source_destroy(AudioSource* source) { - if (!source) return; - if (source->source) { - source->source->lpVtbl->Stop(source->source, 0, XAUDIO2_COMMIT_NOW); - source->source->lpVtbl->DestroyVoice(source->source); - } - free(source->audio_data); - free(source); -} - -static int audio_source_load_data(AudioSource* source, const WavData* wav) { - if (!source || !source->system || !source->system->xaudio2) return 0; - - // 释放旧的语音与数据 - if (source->source) { - source->source->lpVtbl->Stop(source->source, 0, XAUDIO2_COMMIT_NOW); - source->source->lpVtbl->DestroyVoice(source->source); - source->source = NULL; - } - free(source->audio_data); - source->audio_data = NULL; - source->audio_size = 0; - - source->audio_data = (uint8_t*)malloc(wav->size); - if (!source->audio_data) return 0; - memcpy(source->audio_data, wav->data, wav->size); - source->audio_size = wav->size; - - HRESULT hr = source->system->xaudio2->lpVtbl->CreateSourceVoice( - source->system->xaudio2, - &source->source, - &wav->format, - 0, - XAUDIO2_DEFAULT_FREQ_RATIO, - NULL, - NULL, - NULL); - if (FAILED(hr)) { - free(source->audio_data); - source->audio_data = NULL; - source->audio_size = 0; - return 0; - } - - return 1; -} - -int audio_load_wav(AudioSource* source, const char* path) { - if (!source || !path) return 0; - - FILE* f = fopen(path, "rb"); - if (!f) return 0; - - fseek(f, 0, SEEK_END); - long file_size = ftell(f); - fseek(f, 0, SEEK_SET); - if (file_size <= 0) { - fclose(f); - return 0; - } - - uint8_t* file_data = (uint8_t*)malloc((size_t)file_size); - if (!file_data) { - fclose(f); - return 0; - } - - size_t read = fread(file_data, 1, (size_t)file_size, f); - fclose(f); - if (read != (size_t)file_size) { - free(file_data); - return 0; - } - - WavData wav; - int ok = wav_load(file_data, (uint32_t)file_size, &wav); - if (ok) { - ok = audio_source_load_data(source, &wav); - } - - free(file_data); - return ok; -} - -int audio_load_wav_memory(AudioSource* source, const uint8_t* data, uint32_t size) { - if (!source || !data || size == 0) return 0; - WavData wav; - int ok = wav_load(data, size, &wav); - if (ok) { - ok = audio_source_load_data(source, &wav); - } - return ok; -} - -void audio_source_play(AudioSource* source) { - if (!source || !source->source) return; - - XAUDIO2_BUFFER buffer = {0}; - buffer.AudioBytes = source->audio_size; - buffer.pAudioData = source->audio_data; - buffer.Flags = XAUDIO2_END_OF_STREAM; - if (source->loop) { - buffer.LoopCount = XAUDIO2_LOOP_INFINITE; - } - - source->source->lpVtbl->Stop(source->source, 0, XAUDIO2_COMMIT_NOW); - source->source->lpVtbl->FlushSourceBuffers(source->source); - source->source->lpVtbl->SubmitSourceBuffer(source->source, &buffer, NULL); - source->source->lpVtbl->Start(source->source, 0, XAUDIO2_COMMIT_NOW); - source->state = AUDIO_PLAYING; -} - -void audio_source_stop(AudioSource* source) { - if (!source || !source->source) return; - source->source->lpVtbl->Stop(source->source, 0, XAUDIO2_COMMIT_NOW); - source->source->lpVtbl->FlushSourceBuffers(source->source); - source->state = AUDIO_STOPPED; -} - -void audio_source_pause(AudioSource* source) { - if (!source || !source->source) return; - source->source->lpVtbl->Stop(source->source, 0, XAUDIO2_COMMIT_NOW); - source->state = AUDIO_PAUSED; -} - -void audio_source_resume(AudioSource* source) { - if (!source || !source->source) return; - source->source->lpVtbl->Start(source->source, 0, XAUDIO2_COMMIT_NOW); - source->state = AUDIO_PLAYING; -} - -void audio_source_set_volume(AudioSource* source, float volume) { - if (!source || !source->source) return; - source->volume = volume; - source->source->lpVtbl->SetVolume(source->source, volume, XAUDIO2_COMMIT_NOW); -} - -void audio_source_set_pitch(AudioSource* source, float pitch) { - if (!source || !source->source) return; - source->pitch = pitch; - source->source->lpVtbl->SetFrequencyRatio(source->source, pitch, XAUDIO2_COMMIT_NOW); -} - -void audio_source_set_loop(AudioSource* source, int loop) { - if (!source) return; - source->loop = loop; -} - -void audio_set_master_volume(AudioSystem* audio, float volume) { - if (!audio || !audio->mastering_voice) return; - audio->mastering_voice->lpVtbl->SetVolume(audio->mastering_voice, volume, XAUDIO2_COMMIT_NOW); -} diff --git a/Engine/Audio/audio.h b/Engine/Audio/audio.h deleted file mode 100644 index 29a8b60..0000000 --- a/Engine/Audio/audio.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -// ============================================================================ -// audio.h - 音频系统 (XAudio2) -// ============================================================================ - -#include -#include - -// 播放状态 -typedef enum { - AUDIO_STOPPED = 0, - AUDIO_PLAYING, - AUDIO_PAUSED -} AudioState; - -struct AudioSystem; - -// 音频源 -typedef struct { - struct AudioSystem* system; - IXAudio2SourceVoice* source; - IXAudio2Voice* mastering; - float volume; - float pitch; - int loop; - AudioState state; - uint8_t* audio_data; - uint32_t audio_size; -} AudioSource; - -// 音频管理器 -typedef struct AudioSystem { - IXAudio2* xaudio2; - IXAudio2MasteringVoice* mastering_voice; -} AudioSystem; - -// 初始化/销毁 -AudioSystem* audio_create(void); -void audio_destroy(AudioSystem* audio); - -// 音频源 -AudioSource* audio_source_create(AudioSystem* audio); -void audio_source_destroy(AudioSource* source); - -// 播放 -void audio_source_play(AudioSource* source); -void audio_source_stop(AudioSource* source); -void audio_source_pause(AudioSource* source); -void audio_source_resume(AudioSource* source); - -// 音量/音调 -void audio_source_set_volume(AudioSource* source, float volume); -void audio_source_set_pitch(AudioSource* source, float pitch); -void audio_source_set_loop(AudioSource* source, int loop); - -// WAV加载 -int audio_load_wav(AudioSource* source, const char* path); -int audio_load_wav_memory(AudioSource* source, const uint8_t* data, uint32_t size); - -// 主音量 -void audio_set_master_volume(AudioSystem* audio, float volume); diff --git a/Engine/Core/asset_manager.c b/Engine/Core/asset_manager.c deleted file mode 100644 index f8adaea..0000000 --- a/Engine/Core/asset_manager.c +++ /dev/null @@ -1,192 +0,0 @@ -#include "asset_manager.h" -#include "../Rendering/mesh.h" -#include "../Rendering/texture.h" -#include "../Rendering/shader.h" -#include -#include -#include - -#define ASSET_BUCKET_COUNT 256 - -struct AssetManager { - Asset* buckets[ASSET_BUCKET_COUNT]; - uint32_t next_id; -}; - -static uint32_t hash_str(const char* s) { - uint32_t h = 5381; - while (*s) h = ((h << 5) + h) + (unsigned char)*s++; - return h % ASSET_BUCKET_COUNT; -} - -static int str_ends_with(const char* s, const char* suffix) { - size_t ls = strlen(s), lf = strlen(suffix); - return ls >= lf && strcmp(s + ls - lf, suffix) == 0; -} - -static Asset* asset_alloc(AssetManager* am, AssetType type, const char* path, void* data, void (*destroy)(void*)) { - Asset* a = (Asset*)calloc(1, sizeof(Asset)); - a->id = ++am->next_id; - a->type = type; - a->refcount = 1; - a->owner = am; - strncpy(a->path, path, sizeof(a->path) - 1); - a->data = data; - a->destroy = destroy; - - uint32_t h = hash_str(path); - a->next = am->buckets[h]; - am->buckets[h] = a; - return a; -} - -static void asset_free(AssetManager* am, Asset* a) { - if (!a) return; - uint32_t h = hash_str(a->path); - Asset** cur = &am->buckets[h]; - while (*cur) { - if (*cur == a) { - *cur = a->next; - break; - } - cur = &(*cur)->next; - } - if (a->destroy) a->destroy(a->data); - free(a); -} - -AssetManager* asset_manager_create(void) { - AssetManager* am = (AssetManager*)calloc(1, sizeof(AssetManager)); - return am; -} - -void asset_manager_destroy(AssetManager* am) { - if (!am) return; - for (int i = 0; i < ASSET_BUCKET_COUNT; i++) { - Asset* a = am->buckets[i]; - while (a) { - Asset* next = a->next; - if (a->destroy) a->destroy(a->data); - free(a); - a = next; - } - } - free(am); -} - -Asset* asset_manager_find(AssetManager* am, const char* path) { - if (!am || !path) return NULL; - uint32_t h = hash_str(path); - for (Asset* a = am->buckets[h]; a; a = a->next) { - if (strcmp(a->path, path) == 0) return a; - } - return NULL; -} - -Asset* asset_manager_get(AssetManager* am, uint32_t id) { - if (!am || id == 0) return NULL; - for (int i = 0; i < ASSET_BUCKET_COUNT; i++) { - for (Asset* a = am->buckets[i]; a; a = a->next) { - if (a->id == id) return a; - } - } - return NULL; -} - -void* asset_data(Asset* a) { return a ? a->data : NULL; } - -void asset_acquire(Asset* a) { if (a) a->refcount++; } - -void asset_release(Asset* a) { - if (!a) return; - a->refcount--; - if (a->refcount <= 0 && a->owner) { - asset_free(a->owner, a); - } -} - -// ------------------------------------------------------------------ -// Mesh -// ------------------------------------------------------------------ -static void destroy_mesh_asset(void* data) { mesh_destroy((Mesh*)data); } - -Asset* asset_manager_load_mesh(AssetManager* am, ID3D11Device* dev, const char* path) { - if (!am || !dev || !path) return NULL; - Asset* existing = asset_manager_find(am, path); - if (existing) { asset_acquire(existing); return existing; } - - Mesh* mesh = NULL; - if (strcmp(path, "cube") == 0) mesh = mesh_create_cube(dev); - else if (strcmp(path, "sphere") == 0) mesh = mesh_create_sphere(dev, 1.0f, 16); - else if (strcmp(path, "plane") == 0) mesh = mesh_create_plane(dev, 10.0f); - else if (str_ends_with(path, ".obj")) mesh = mesh_load_obj(dev, path); - - if (!mesh) return NULL; - return asset_alloc(am, ASSET_MESH, path, mesh, destroy_mesh_asset); -} - -// ------------------------------------------------------------------ -// Texture -// ------------------------------------------------------------------ -static void destroy_texture_asset(void* data) { texture_destroy((Texture*)data); } - -Asset* asset_manager_load_texture(AssetManager* am, ID3D11Device* dev, const char* path) { - if (!am || !dev || !path) return NULL; - Asset* existing = asset_manager_find(am, path); - if (existing) { asset_acquire(existing); return existing; } - - Texture* tex = NULL; - if (strcmp(path, "checkerboard") == 0) tex = texture_create_checkerboard(dev, 256, 8); - else tex = texture_load_from_file(dev, path); - - if (!tex) return NULL; - return asset_alloc(am, ASSET_TEXTURE, path, tex, destroy_texture_asset); -} - -// ------------------------------------------------------------------ -// Shader -// ------------------------------------------------------------------ -static void destroy_shader_asset(void* data) { shader_destroy((Shader*)data); } - -static char* read_file(const char* path, uint32_t* out_len) { - FILE* f = fopen(path, "rb"); - if (!f) return NULL; - fseek(f, 0, SEEK_END); - long size = ftell(f); - fseek(f, 0, SEEK_SET); - if (size <= 0) { fclose(f); return NULL; } - char* buf = (char*)malloc((size_t)size + 1); - if (!buf) { fclose(f); return NULL; } - fread(buf, 1, (size_t)size, f); - buf[size] = '\0'; - fclose(f); - if (out_len) *out_len = (uint32_t)size; - return buf; -} - -Asset* asset_manager_load_shader(AssetManager* am, ID3D11Device* dev, const char* vs_path, const char* ps_path) { - if (!am || !dev) return NULL; - - char key[512]; - if (vs_path && ps_path) snprintf(key, sizeof(key), "%s|%s", vs_path, ps_path); - else strcpy(key, "default"); - - Asset* existing = asset_manager_find(am, key); - if (existing) { asset_acquire(existing); return existing; } - - Shader* s = shader_create(); - if (vs_path && ps_path) { - uint32_t vs_len = 0, ps_len = 0; - char* vs = read_file(vs_path, &vs_len); - char* ps = read_file(ps_path, &ps_len); - if (!vs || !ps || !shader_compile(s, dev, vs, ps, vs_len, ps_len)) { - shader_destroy(s); free(vs); free(ps); return NULL; - } - free(vs); free(ps); - } else { - if (!shader_compile(s, dev, NULL, NULL, 0, 0)) { - shader_destroy(s); return NULL; - } - } - return asset_alloc(am, ASSET_SHADER, key, s, destroy_shader_asset); -} diff --git a/Engine/Core/asset_manager.h b/Engine/Core/asset_manager.h deleted file mode 100644 index 415d6ef..0000000 --- a/Engine/Core/asset_manager.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct AssetManager AssetManager; -typedef struct Asset Asset; - -typedef enum { - ASSET_MESH = 0, - ASSET_TEXTURE, - ASSET_SHADER, - ASSET_MATERIAL, - ASSET_COUNT -} AssetType; - -struct Asset { - uint32_t id; - AssetType type; - int refcount; - char path[256]; - void* data; - void (*destroy)(void* data); - Asset* next; - struct AssetManager* owner; -}; - -AssetManager* asset_manager_create(void); -void asset_manager_destroy(AssetManager* am); - -Asset* asset_manager_load_mesh(AssetManager* am, ID3D11Device* dev, const char* path); -Asset* asset_manager_load_texture(AssetManager* am, ID3D11Device* dev, const char* path); -Asset* asset_manager_load_shader(AssetManager* am, ID3D11Device* dev, const char* vs_path, const char* ps_path); - -Asset* asset_manager_find(AssetManager* am, const char* path); -Asset* asset_manager_get(AssetManager* am, uint32_t id); - -void* asset_data(Asset* a); -void asset_acquire(Asset* a); -void asset_release(Asset* a); - -#ifdef __cplusplus -} -#endif diff --git a/Engine/Core/engine.c b/Engine/Core/engine.c deleted file mode 100644 index 2a08bbb..0000000 --- a/Engine/Core/engine.c +++ /dev/null @@ -1,244 +0,0 @@ -// ============================================================================ -// engine.c - 引擎核心实现 -// ============================================================================ - -#include "engine.h" -#include "logger.h" -#include "timer.h" -#include "../Window/window.h" -#include "../Rendering/renderer.h" -#include "../Rendering/graphics_device.h" -#include "../include/engine_api.h" -#include -#include - -// 引擎实例 (单例) -static Engine g_engine = {0}; - -// 回调 -static EngineUpdateCallback g_update_callback = NULL; -static EngineRenderCallback g_render_callback = NULL; -static EngineKeyCallback g_key_callback = NULL; -static EngineResizeCallback g_resize_callback = NULL; -static EngineMouseMoveCallback g_mouse_move_callback = NULL; -static EngineMouseButtonCallback g_mouse_button_callback = NULL; - -// 内部函数 -static void on_key(int key) { - if (g_key_callback) { - g_key_callback(&g_engine, key); - } - if (key == VK_ESCAPE) { - engine_request_quit(&g_engine); - } -} - -static void on_resize(int width, int height) { - if (g_resize_callback) { - g_resize_callback(&g_engine, width, height); - } -} - -static void on_mouse_move(int x, int y) { - if (g_mouse_move_callback) { - g_mouse_move_callback(&g_engine, x, y); - } -} - -static void on_mouse_button(int button, int pressed) { - if (g_mouse_button_callback) { - g_mouse_button_callback(&g_engine, button, pressed); - } -} - -Engine* engine_create(void) { - return &g_engine; -} - -void engine_destroy(Engine* engine) { - if (engine) { - engine_shutdown(engine); - } -} - -int engine_init(Engine* engine, const EngineConfig* config) { - if (engine->initialized) return 1; - - engine->config = *config; - - // 初始化日志 - logger_init("engine.log"); - LOG_INFO("Initializing Lity3D Engine..."); - - // 初始化计时器 - timer_init(); - - // 创建窗口 - engine->window = window_create( - config->app_name, - config->window_width, - config->window_height, - config->fullscreen - ); - - if (!engine->window) { - LOG_ERROR("Failed to create window!"); - return 0; - } - - // 设置回调 - window_set_key_callback(engine->window, on_key); - window_set_resize_callback(engine->window, on_resize); - window_set_mouse_move_callback(engine->window, on_mouse_move); - window_set_mouse_button_callback(engine->window, on_mouse_button); - - LOG_INFO("Window created: %dx%d", config->window_width, config->window_height); - - // 创建 D3D11 图形设备 - engine->graphics_device = graphics_device_create(); - if (!graphics_device_init(engine->graphics_device, - window_get_handle(engine->window), - config->window_width, - config->window_height, - config->vsync)) { - LOG_ERROR("Failed to initialize D3D11 graphics device!"); - window_destroy(engine->window); - engine->window = NULL; - return 0; - } - - // 创建渲染器 - engine->renderer = renderer_create(engine->graphics_device); - if (!engine->renderer) { - LOG_ERROR("Failed to create renderer!"); - graphics_device_destroy(engine->graphics_device); - engine->graphics_device = NULL; - window_destroy(engine->window); - engine->window = NULL; - return 0; - } - - LOG_INFO("Graphics device and renderer ready."); - - engine->initialized = 1; - engine->running = 1; - engine->frame_count = 0; - - LOG_INFO("Lity3D Engine initialized successfully."); - return 1; -} - -void engine_run(Engine* engine) { - if (!engine->initialized) { - LOG_ERROR("Engine not initialized!"); - return; - } - - double fixed_dt = 1.0 / 60.0; // 60Hz 固定时间步 - double accumulator = 0.0; - double fps_timer = 0.0; - int fps_frames = 0; - int fps_display = 0; - - while (engine->running) { - // 处理窗口消息 - if (!window_process_messages(engine->window)) { - engine->running = 0; - break; - } - - // 更新计时 - timer_tick(); - engine->delta_time = timer_get_delta(); - engine->total_time += engine->delta_time; - engine->frame_count++; - - // FPS 计算 - fps_timer += engine->delta_time; - fps_frames++; - if (fps_timer >= 1.0) { - fps_display = fps_frames; - fps_frames = 0; - fps_timer -= 1.0; - } - - // 固定时间步逻辑更新 - accumulator += engine->delta_time; - while (accumulator >= fixed_dt) { - if (g_update_callback) { - g_update_callback(engine, fixed_dt); - } - accumulator -= fixed_dt; - } - - // 渲染 - if (g_render_callback) { - g_render_callback(engine); - } - - // 存储 FPS 供外部读取 - engine->fps = fps_display; - } -} - -void engine_shutdown(Engine* engine) { - if (!engine->initialized) return; - - LOG_INFO("Shutting down Lity3D Engine..."); - - if (engine->renderer) { - renderer_destroy(engine->renderer); - engine->renderer = NULL; - } - - if (engine->graphics_device) { - graphics_device_destroy(engine->graphics_device); - engine->graphics_device = NULL; - } - - if (engine->window) { - window_destroy(engine->window); - engine->window = NULL; - } - - logger_shutdown(); - engine->initialized = 0; - engine->running = 0; -} - -void engine_request_quit(Engine* engine) { - engine->running = 0; -} - -// 回调设置 -void engine_set_update_callback(Engine* engine, EngineUpdateCallback callback) { - g_update_callback = callback; -} - -void engine_set_render_callback(Engine* engine, EngineRenderCallback callback) { - g_render_callback = callback; -} - -void engine_set_key_callback(Engine* engine, EngineKeyCallback callback) { - g_key_callback = callback; -} - -void engine_set_resize_callback(Engine* engine, EngineResizeCallback callback) { - g_resize_callback = callback; -} - -void engine_set_mouse_move_callback(Engine* engine, EngineMouseMoveCallback callback) { - g_mouse_move_callback = callback; -} - -void engine_set_mouse_button_callback(Engine* engine, EngineMouseButtonCallback callback) { - g_mouse_button_callback = callback; -} - -GraphicsDevice* engine_get_graphics_device(Engine* engine) { - return engine ? engine->graphics_device : NULL; -} - -Renderer* engine_get_renderer(Engine* engine) { - return engine ? (Renderer*)engine->renderer : NULL; -} diff --git a/Engine/Core/engine.h b/Engine/Core/engine.h deleted file mode 100644 index 5196776..0000000 --- a/Engine/Core/engine.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -// ============================================================================ -// engine.h - 引擎核心 -// ============================================================================ - -#include - -// 前向声明 -typedef struct Window Window; -typedef struct GraphicsDevice GraphicsDevice; -typedef struct Renderer Renderer; - -// 引擎配置 -typedef struct { - const char* app_name; - int window_width; - int window_height; - int fullscreen; - int vsync; -} EngineConfig; - -// 引擎状态 -typedef struct { - int running; - int initialized; - EngineConfig config; - Window* window; - void* renderer; - GraphicsDevice* graphics_device; - double delta_time; - double total_time; - int fps; - uint64_t frame_count; -} Engine; - -// 初始化默认配置 -static inline EngineConfig engine_default_config(void) { - EngineConfig config; - config.app_name = "Lity3D Engine"; - config.window_width = 1280; - config.window_height = 720; - config.fullscreen = 0; - config.vsync = 1; - return config; -} - -// 引擎函数 -Engine* engine_create(void); -void engine_destroy(Engine* engine); -int engine_init(Engine* engine, const EngineConfig* config); -void engine_run(Engine* engine); -void engine_shutdown(Engine* engine); -void engine_request_quit(Engine* engine); - -// 回调 -typedef void (*EngineUpdateCallback)(Engine* engine, double delta_time); -typedef void (*EngineRenderCallback)(Engine* engine); -typedef void (*EngineKeyCallback)(Engine* engine, int key); -typedef void (*EngineResizeCallback)(Engine* engine, int width, int height); -typedef void (*EngineMouseMoveCallback)(Engine* engine, int x, int y); -typedef void (*EngineMouseButtonCallback)(Engine* engine, int button, int pressed); - -void engine_set_update_callback(Engine* engine, EngineUpdateCallback callback); -void engine_set_render_callback(Engine* engine, EngineRenderCallback callback); -void engine_set_key_callback(Engine* engine, EngineKeyCallback callback); -void engine_set_resize_callback(Engine* engine, EngineResizeCallback callback); -void engine_set_mouse_move_callback(Engine* engine, EngineMouseMoveCallback callback); -void engine_set_mouse_button_callback(Engine* engine, EngineMouseButtonCallback callback); - -// 子系统访问 -GraphicsDevice* engine_get_graphics_device(Engine* engine); -Renderer* engine_get_renderer(Engine* engine); diff --git a/Engine/Core/logger.c b/Engine/Core/logger.c deleted file mode 100644 index f89f7a3..0000000 --- a/Engine/Core/logger.c +++ /dev/null @@ -1,73 +0,0 @@ -// ============================================================================ -// logger.c - 日志系统实现 -// ============================================================================ - -#include "logger.h" -#include -#include -#include -#include - -static FILE* g_log_file = NULL; -static LogLevel g_log_level = LOG_TRACE; - -static const char* level_strings[] = { - "TRACE", "DEBUG", "INFO ", "WARN ", "ERROR", "FATAL" -}; - -void logger_init(const char* log_file) { - if (log_file) { - g_log_file = fopen(log_file, "w"); - if (g_log_file) { - fprintf(g_log_file, "=== Lity3D Engine Log ===\n"); - fflush(g_log_file); - } - } - printf("=== Lity3D Engine Log ===\n"); -} - -void logger_shutdown(void) { - if (g_log_file) { - fclose(g_log_file); - g_log_file = NULL; - } -} - -void logger_set_level(LogLevel level) { - g_log_level = level; -} - -void logger_log(LogLevel level, const char* file, int line, const char* fmt, ...) { - if (level < g_log_level) return; - - // 时间戳 - time_t now = time(NULL); - struct tm* tm_info = localtime(&now); - char time_str[20]; - strftime(time_str, sizeof(time_str), "%H:%M:%S", tm_info); - - // 文件名 (去掉路径) - const char* filename = strrchr(file, '\\'); - if (!filename) filename = strrchr(file, '/'); - if (filename) filename++; else filename = file; - - // 格式化消息 - char msg[2048]; - va_list args; - va_start(args, fmt); - vsnprintf(msg, sizeof(msg), fmt, args); - va_end(args); - - // 输出到控制台 - if (level >= LOG_WARN) { - fprintf(stderr, "[%s] [%s] %s:%d - %s\n", time_str, level_strings[level], filename, line, msg); - } else { - printf("[%s] [%s] %s:%d - %s\n", time_str, level_strings[level], filename, line, msg); - } - - // 输出到文件 - if (g_log_file) { - fprintf(g_log_file, "[%s] [%s] %s:%d - %s\n", time_str, level_strings[level], filename, line, msg); - fflush(g_log_file); - } -} diff --git a/Engine/Core/logger.h b/Engine/Core/logger.h deleted file mode 100644 index 06b43e9..0000000 --- a/Engine/Core/logger.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -// ============================================================================ -// logger.h - 日志系统 -// ============================================================================ - -#include - -// 日志级别 -typedef enum { - LOG_TRACE = 0, - LOG_DEBUG, - LOG_INFO, - LOG_WARN, - LOG_ERROR, - LOG_FATAL -} LogLevel; - -// 初始化/关闭 -void logger_init(const char* log_file); -void logger_shutdown(void); - -// 设置日志级别 -void logger_set_level(LogLevel level); - -// 日志函数 -void logger_log(LogLevel level, const char* file, int line, const char* fmt, ...); - -// 便捷宏 -#define LOG_TRACE(...) logger_log(LOG_TRACE, __FILE__, __LINE__, __VA_ARGS__) -#define LOG_DEBUG(...) logger_log(LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__) -#define LOG_INFO(...) logger_log(LOG_INFO, __FILE__, __LINE__, __VA_ARGS__) -#define LOG_WARN(...) logger_log(LOG_WARN, __FILE__, __LINE__, __VA_ARGS__) -#define LOG_ERROR(...) logger_log(LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__) -#define LOG_FATAL(...) logger_log(LOG_FATAL, __FILE__, __LINE__, __VA_ARGS__) diff --git a/Engine/Core/timer.c b/Engine/Core/timer.c deleted file mode 100644 index 96516df..0000000 --- a/Engine/Core/timer.c +++ /dev/null @@ -1,78 +0,0 @@ -// ============================================================================ -// timer.c - 高精度计时器实现 (使用 rdtsc.asm) -// ============================================================================ - -#include "timer.h" -#include "../include/engine_api.h" -#include - -static double g_seconds_per_count = 0.0; -static int64_t g_prev_time = 0; -static int64_t g_curr_time = 0; -static int64_t g_start_time = 0; -static double g_delta_time = 0.0; -static double g_total_time = 0.0; -static double g_fps = 0.0; -static uint64_t g_frame_count = 0; -static double g_fps_accumulator = 0.0; -static uint64_t g_fps_frame_count = 0; - -void timer_init(void) { - // 使用 QueryPerformanceCounter 获取高精度时间 - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - g_seconds_per_count = 1.0 / (double)freq.QuadPart; - - LARGE_INTEGER now; - QueryPerformanceCounter(&now); - g_start_time = now.QuadPart; - g_prev_time = now.QuadPart; - g_curr_time = now.QuadPart; - - g_delta_time = 0.0; - g_total_time = 0.0; - g_fps = 0.0; - g_frame_count = 0; - g_fps_accumulator = 0.0; - g_fps_frame_count = 0; -} - -void timer_reset(void) { - timer_init(); -} - -void timer_tick(void) { - LARGE_INTEGER now; - QueryPerformanceCounter(&now); - g_curr_time = now.QuadPart; - - g_delta_time = (g_curr_time - g_prev_time) * g_seconds_per_count; - g_total_time = (g_curr_time - g_start_time) * g_seconds_per_count; - g_prev_time = g_curr_time; - - g_frame_count++; - g_fps_frame_count++; - g_fps_accumulator += g_delta_time; - - if (g_fps_accumulator >= 1.0) { - g_fps = (double)g_fps_frame_count / g_fps_accumulator; - g_fps_frame_count = 0; - g_fps_accumulator = 0.0; - } -} - -double timer_get_delta(void) { - return g_delta_time; -} - -double timer_get_total(void) { - return g_total_time; -} - -double timer_get_fps(void) { - return g_fps; -} - -uint64_t timer_get_frame_count(void) { - return g_frame_count; -} diff --git a/Engine/Core/timer.h b/Engine/Core/timer.h deleted file mode 100644 index 92aa452..0000000 --- a/Engine/Core/timer.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -// ============================================================================ -// timer.h - 高精度计时器 -// ============================================================================ - -#include - -// 初始化计时器 -void timer_init(void); - -// 重置计时器 -void timer_reset(void); - -// 更新一帧 -void timer_tick(void); - -// 获取帧间隔 (秒) -double timer_get_delta(void); - -// 获取总时间 (秒) -double timer_get_total(void); - -// 获取 FPS -double timer_get_fps(void); - -// 获取帧数 -uint64_t timer_get_frame_count(void); diff --git a/Engine/ECS/world.c b/Engine/ECS/world.c deleted file mode 100644 index d91fd46..0000000 --- a/Engine/ECS/world.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "world.h" - -#include -#include - -World* world_create(void) { - World* w = (World*)calloc(1, sizeof(World)); - w->next_entity = 1; - return w; -} - -void world_destroy(World* world) { - if (!world) return; - for (uint32_t i = 0; i < world->entity_count; i++) { - Entity e = world->entities[i]; - for (uint32_t c = 0; c < world->component_count; c++) { - if (world->components[c][e] && world->component_tables[c].destroy) { - world->component_tables[c].destroy(world->components[c][e]); - } - free(world->components[c][e]); - } - } - free(world); -} - -Entity world_create_entity(World* world) { - if (world->entity_count >= MAX_ENTITIES) return 0; - Entity e = world->next_entity++; - world->entities[world->entity_count++] = e; - world->entity_masks[e] = 0; - return e; -} - -void world_destroy_entity(World* world, Entity entity) { - for (uint32_t c = 0; c < world->component_count; c++) { - if (world->components[c][entity] && world->component_tables[c].destroy) { - world->component_tables[c].destroy(world->components[c][entity]); - } - free(world->components[c][entity]); - world->components[c][entity] = NULL; - } - world->entity_masks[entity] = 0; - - for (uint32_t i = 0; i < world->entity_count; i++) { - if (world->entities[i] == entity) { - world->entities[i] = world->entities[--world->entity_count]; - break; - } - } -} - -int world_entity_alive(World* world, Entity entity) { - for (uint32_t i = 0; i < world->entity_count; i++) { - if (world->entities[i] == entity) return 1; - } - return 0; -} - -ComponentType world_register_component(World* world, uint32_t size, ComponentVTable vtable) { - ComponentType type = world->component_count++; - world->component_sizes[type] = size; - world->component_tables[type] = vtable; - return type; -} - -void* world_add_component(World* world, Entity entity, ComponentType type) { - if (world->components[type][entity]) return world->components[type][entity]; - void* comp = calloc(1, world->component_sizes[type]); - world->components[type][entity] = comp; - world->entity_masks[entity] |= (1ULL << type); - return comp; -} - -void* world_get_component(World* world, Entity entity, ComponentType type) { - return world->components[type][entity]; -} - -void world_remove_component(World* world, Entity entity, ComponentType type) { - if (world->components[type][entity]) { - if (world->component_tables[type].destroy) { - world->component_tables[type].destroy(world->components[type][entity]); - } - free(world->components[type][entity]); - world->components[type][entity] = NULL; - world->entity_masks[entity] &= ~(1ULL << type); - } -} - -int world_has_component(World* world, Entity entity, ComponentType type) { - return (world->entity_masks[entity] & (1ULL << type)) != 0; -} - -void world_each(World* world, uint64_t mask, SystemFunc func, void* data) { - for (uint32_t i = 0; i < world->entity_count; i++) { - Entity e = world->entities[i]; - if ((world->entity_masks[e] & mask) == mask) { - func(world, e, data); - } - } -} diff --git a/Engine/ECS/world.h b/Engine/ECS/world.h deleted file mode 100644 index 2803ee5..0000000 --- a/Engine/ECS/world.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -// ============================================================================ -// world.h - 实体组件系统 (ECS) -// ============================================================================ - -#include -#include "../include/engine_api.h" - -#define MAX_ENTITIES 4096 -#define MAX_COMPONENTS 32 - -typedef uint32_t Entity; -typedef uint32_t ComponentType; - -// 组件接口 -typedef struct { - void (*destroy)(void* component); -} ComponentVTable; - -// 世界 -typedef struct { - Entity entities[MAX_ENTITIES]; - uint32_t entity_count; - uint32_t next_entity; - - void* components[MAX_COMPONENTS][MAX_ENTITIES]; - ComponentVTable component_tables[MAX_COMPONENTS]; - uint32_t component_sizes[MAX_COMPONENTS]; - uint32_t component_count; - - uint64_t entity_masks[MAX_ENTITIES]; -} World; - -// 创建/销毁 -World* world_create(void); -void world_destroy(World* world); - -// 实体 -Entity world_create_entity(World* world); -void world_destroy_entity(World* world, Entity entity); -int world_entity_alive(World* world, Entity entity); - -// 组件 -ComponentType world_register_component(World* world, uint32_t size, ComponentVTable vtable); -void* world_add_component(World* world, Entity entity, ComponentType type); -void* world_get_component(World* world, Entity entity, ComponentType type); -void world_remove_component(World* world, Entity entity, ComponentType type); -int world_has_component(World* world, Entity entity, ComponentType type); - -// 系统遍历 -typedef void (*SystemFunc)(World* world, Entity entity, void* data); -void world_each(World* world, uint64_t mask, SystemFunc func, void* data); diff --git a/Engine/Editor/bitmap_font.c b/Engine/Editor/bitmap_font.c deleted file mode 100644 index c75c2ce..0000000 --- a/Engine/Editor/bitmap_font.c +++ /dev/null @@ -1,303 +0,0 @@ -#include "bitmap_font.h" -#include -#include -#include "../Core/logger.h" - -static const uint8_t FONT_DATA[FONT_NUM_CHARS][FONT_CHAR_H] = { - {0},{0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, - {0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, - {0x18,0x18,0x7C,0xC6,0xC2,0xC0,0x7C,0x06,0x06,0x86,0xC6,0x7C,0x18,0x18,0x00,0x00}, - {0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}, - {0x00,0x30,0x30,0x30,0x70,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0xCE,0xDE,0xF6,0xE6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00}, - {0},{0},{0}, - {0x00,0x00,0x00,0x0C,0x18,0x30,0x60,0xC0,0x60,0x30,0x18,0x0C,0x00,0x00,0x00,0x00}, - {0},{0}, - {0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, - {0},{0},{0},{0},{0},{0},{0},{0},{0}, - {0x00,0x00,0x7C,0xC6,0xC6,0xCE,0xDE,0xF6,0xE6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x0C,0x18,0x30,0x60,0xC0,0x60,0x30,0x18,0x0C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xE6,0x66,0x66,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00}, - {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFF,0xDB,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xC6,0x6C,0x7C,0x38,0x38,0x7C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xC6,0xC6,0x6C,0x38,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFE,0xC6,0x86,0x0C,0x18,0x30,0x60,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x06,0x02,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00}, - {0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00}, -}; - -static Shader* g_font_shader = NULL; -static ID3D11Buffer* g_font_vb = NULL; -static ID3D11Buffer* g_font_ib = NULL; -static FontVert g_font_verts[FONT_MAX_QUADS * 4]; -static uint32_t g_font_indices[FONT_MAX_QUADS * 6]; -static int g_font_vi = 0; -static int g_font_ii = 0; - -static void make_ortho(float* m, float sw, float sh) { - memset(m, 0, 64); - m[0] = 2.0f / sw; - m[5] = -2.0f / sh; - m[10] = 1.0f; - m[12] = -1.0f; - m[13] = 1.0f; - m[15] = 1.0f; -} - -static void make_atlas(uint8_t* pixels, int w, int h) { - memset(pixels, 0, (size_t)w * h * 4); - int cols = w / FONT_CHAR_W; - for (int i = 0; i < FONT_NUM_CHARS; i++) { - int cx = (i % cols) * FONT_CHAR_W; - int cy = (i / cols) * FONT_CHAR_H; - for (int row = 0; row < FONT_CHAR_H; row++) { - uint8_t bits = FONT_DATA[i][row]; - for (int col = 0; col < 8; col++) { - if (bits & (0x80 >> col)) { - int px = cx + col, py = cy + row; - int idx = (py * w + px) * 4; - pixels[idx] = 255; pixels[idx+1] = 255; pixels[idx+2] = 255; pixels[idx+3] = 255; - } - } - } - } -} - -int bitmap_font_init(BitmapFont* f, ID3D11Device* dev) { - memset(f, 0, sizeof(*f)); - int cols = 16; - f->atlas_w = cols * FONT_CHAR_W; - f->atlas_h = ((FONT_NUM_CHARS + cols - 1) / cols) * FONT_CHAR_H; - - uint8_t* pixels = (uint8_t*)malloc((size_t)f->atlas_w * f->atlas_h * 4); - make_atlas(pixels, f->atlas_w, f->atlas_h); - - D3D11_TEXTURE2D_DESC td = {0}; - td.Width = (UINT)f->atlas_w; td.Height = (UINT)f->atlas_h; - td.MipLevels = 1; td.ArraySize = 1; - td.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - td.SampleDesc.Count = 1; - td.Usage = D3D11_USAGE_DEFAULT; - td.BindFlags = D3D11_BIND_SHADER_RESOURCE; - D3D11_SUBRESOURCE_DATA sd = {0}; - sd.pSysMem = pixels; sd.SysMemPitch = (UINT)(f->atlas_w * 4); - HRESULT hr = dev->lpVtbl->CreateTexture2D(dev, &td, &sd, &f->texture); - free(pixels); - if (FAILED(hr)) return 0; - dev->lpVtbl->CreateShaderResourceView(dev, (ID3D11Resource*)f->texture, NULL, &f->srv); - - f->shader = shader_create(); - if (!shader_compile(f->shader, dev, NULL, NULL, 0, 0)) return 0; - g_font_shader = f->shader; - - D3D11_BUFFER_DESC bd = {0}; - bd.ByteWidth = FONT_MAX_QUADS * 4 * sizeof(FontVert); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - memset(g_font_verts, 0, sizeof(g_font_verts)); - sd.pSysMem = g_font_verts; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &g_font_vb); - - bd.ByteWidth = FONT_MAX_QUADS * 6 * sizeof(uint32_t); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - memset(g_font_indices, 0, sizeof(g_font_indices)); - sd.pSysMem = g_font_indices; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &g_font_ib); - - bd.ByteWidth = 256; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - dev->lpVtbl->CreateBuffer(dev, &bd, NULL, &f->cb); - - D3D11_BLEND_DESC bdesc = {0}; - bdesc.RenderTarget[0].BlendEnable = TRUE; - bdesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - bdesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - bdesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - bdesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - bdesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - bdesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - dev->lpVtbl->CreateBlendState(dev, &bdesc, &f->blend); - - D3D11_SAMPLER_DESC sdesc = {0}; - sdesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - sdesc.AddressU = sdesc.AddressV = sdesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - dev->lpVtbl->CreateSamplerState(dev, &sdesc, &f->sampler); - - D3D11_DEPTH_STENCIL_DESC dsdesc = {0}; - dsdesc.DepthEnable = FALSE; - dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - dev->lpVtbl->CreateDepthStencilState(dev, &dsdesc, &f->ds_no_depth); - - LOG_INFO("bitmap_font: initialized (%dx%d atlas)", f->atlas_w, f->atlas_h); - return 1; -} - -void bitmap_font_destroy(BitmapFont* f) { - if (!f) return; - if (f->ds_no_depth) f->ds_no_depth->lpVtbl->Release(f->ds_no_depth); - if (f->sampler) f->sampler->lpVtbl->Release(f->sampler); - if (f->blend) f->blend->lpVtbl->Release(f->blend); - if (f->cb) f->cb->lpVtbl->Release(f->cb); - if (g_font_ib) { g_font_ib->lpVtbl->Release(g_font_ib); g_font_ib = NULL; } - if (g_font_vb) { g_font_vb->lpVtbl->Release(g_font_vb); g_font_vb = NULL; } - if (f->shader) { shader_destroy(f->shader); g_font_shader = NULL; } - if (f->srv) f->srv->lpVtbl->Release(f->srv); - if (f->texture) f->texture->lpVtbl->Release(f->texture); - memset(f, 0, sizeof(*f)); -} - -static void font_flush(ID3D11DeviceContext* ctx, - float screen_w, float screen_h, int num_idx) { - if (num_idx == 0) return; - - float wvp[64]; - make_ortho(wvp, screen_w, screen_h); - - ID3D11Device* dev = NULL; - ctx->lpVtbl->GetDevice(ctx, &dev); - - D3D11_RASTERIZER_DESC rdesc = {0}; - rdesc.FillMode = D3D11_FILL_SOLID; - rdesc.CullMode = D3D11_CULL_NONE; - rdesc.ScissorEnable = FALSE; - ID3D11RasterizerState* rstate = NULL; - HRESULT hr = dev->lpVtbl->CreateRasterizerState(dev, &rdesc, &rstate); - if (rstate) { - ctx->lpVtbl->RSSetState(ctx, rstate); - rstate->lpVtbl->Release(rstate); - } - dev->lpVtbl->Release(dev); - - shader_bind(g_font_shader, ctx); - shader_set_matrix(g_font_shader, ctx, wvp); - - UINT stride = sizeof(FontVert), offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &g_font_vb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, g_font_ib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - ctx->lpVtbl->DrawIndexed(ctx, (UINT)num_idx, 0, 0); -} - -static void font_begin(void) { g_font_vi = 0; g_font_ii = 0; } - -static void font_add_quad(BitmapFont* f, float x, float y, float w, float h, - float r, float g, float b, float a) { - if (g_font_vi + 4 > FONT_MAX_QUADS * 4) return; - float u0 = 0.19f, v0 = 0.01f, u1 = 0.24f, v1 = 0.15f; - int vi = g_font_vi; - g_font_verts[vi] = (FontVert){{x, y, 0},{0,0,-1},{u0,v0},{r,g,b,a}}; - g_font_verts[vi+1] = (FontVert){{x+w, y, 0},{0,0,-1},{u1,v0},{r,g,b,a}}; - g_font_verts[vi+2] = (FontVert){{x+w, y+h, 0},{0,0,-1},{u1,v1},{r,g,b,a}}; - g_font_verts[vi+3] = (FontVert){{x, y+h, 0},{0,0,-1},{u0,v1},{r,g,b,a}}; - uint32_t base = (uint32_t)vi; - g_font_indices[g_font_ii++] = base; g_font_indices[g_font_ii++] = base+1; g_font_indices[g_font_ii++] = base+2; - g_font_indices[g_font_ii++] = base; g_font_indices[g_font_ii++] = base+2; g_font_indices[g_font_ii++] = base+3; - g_font_vi += 4; -} - -void bitmap_font_draw(BitmapFont* f, ID3D11DeviceContext* ctx, - const char* text, int x, int y, - float r, float g, float b, float a, - float screen_w, float screen_h) { - if (!text || !*text || !f->shader) return; - int len = (int)strlen(text); - if (len > FONT_MAX_QUADS) len = FONT_MAX_QUADS; - int cols = f->atlas_w / FONT_CHAR_W; - - font_begin(); - int cx = x; - for (int i = 0; i < len; i++) { - int ch = (unsigned char)text[i] - FONT_FIRST_CHAR; - if (ch < 0 || ch >= FONT_NUM_CHARS) ch = 0; - int col_idx = ch % cols; - int row_idx = ch / cols; - float u0 = (float)(col_idx * FONT_CHAR_W) / (float)f->atlas_w; - float v0 = (float)(row_idx * FONT_CHAR_H) / (float)f->atlas_h; - float u1 = (float)((col_idx + 1) * FONT_CHAR_W) / (float)f->atlas_w; - float v1 = (float)((row_idx + 1) * FONT_CHAR_H) / (float)f->atlas_h; - int vi = g_font_vi; - g_font_verts[vi] = (FontVert){{(float)cx,(float)y,0},{0,0,-1},{u0,v0},{r,g,b,a}}; - g_font_verts[vi+1] = (FontVert){{(float)cx+FONT_CHAR_W,(float)y,0},{0,0,-1},{u1,v0},{r,g,b,a}}; - g_font_verts[vi+2] = (FontVert){{(float)cx+FONT_CHAR_W,(float)y+FONT_CHAR_H,0},{0,0,-1},{u1,v1},{r,g,b,a}}; - g_font_verts[vi+3] = (FontVert){{(float)cx,(float)y+FONT_CHAR_H,0},{0,0,-1},{u0,v1},{r,g,b,a}}; - uint32_t base = (uint32_t)vi; - g_font_indices[g_font_ii++] = base; g_font_indices[g_font_ii++] = base+1; g_font_indices[g_font_ii++] = base+2; - g_font_indices[g_font_ii++] = base; g_font_indices[g_font_ii++] = base+2; g_font_indices[g_font_ii++] = base+3; - g_font_vi += 4; - cx += FONT_CHAR_W; - } - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)g_font_vb, 0, NULL, g_font_verts, 0, 0); - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)g_font_ib, 0, NULL, g_font_indices, 0, 0); - font_flush(ctx, screen_w, screen_h, g_font_ii); -} - -void bitmap_font_rect(BitmapFont* f, ID3D11DeviceContext* ctx, - float x, float y, float w, float h, - float r, float g, float b, float a, - float screen_w, float screen_h) { - if (!f->shader) return; - font_begin(); - font_add_quad(f, x, y, w, h, r, g, b, a); - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)g_font_vb, 0, NULL, g_font_verts, 0, 0); - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)g_font_ib, 0, NULL, g_font_indices, 0, 0); - font_flush(ctx, screen_w, screen_h, g_font_ii); -} diff --git a/Engine/Editor/bitmap_font.h b/Engine/Editor/bitmap_font.h deleted file mode 100644 index 93f7b32..0000000 --- a/Engine/Editor/bitmap_font.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once -#include -#include -#include "../Rendering/shader.h" - -#define FONT_CHAR_W 8 -#define FONT_CHAR_H 16 -#define FONT_FIRST_CHAR 32 -#define FONT_NUM_CHARS 96 -#define FONT_MAX_QUADS 4096 - -typedef struct { - float pos[3]; - float norm[3]; - float uv[2]; - float color[4]; -} FontVert; - -typedef struct { - ID3D11Texture2D* texture; - ID3D11ShaderResourceView* srv; - ID3D11Buffer* cb; - Shader* shader; - ID3D11BlendState* blend; - ID3D11SamplerState* sampler; - ID3D11DepthStencilState* ds_no_depth; - int atlas_w; - int atlas_h; -} BitmapFont; - -int bitmap_font_init(BitmapFont* f, ID3D11Device* dev); -void bitmap_font_destroy(BitmapFont* f); -void bitmap_font_draw(BitmapFont* f, ID3D11DeviceContext* ctx, - const char* text, int x, int y, - float r, float g, float b, float a, - float screen_w, float screen_h); -void bitmap_font_rect(BitmapFont* f, ID3D11DeviceContext* ctx, - float x, float y, float w, float h, - float r, float g, float b, float a, - float screen_w, float screen_h); diff --git a/Engine/Editor/editor.c b/Engine/Editor/editor.c deleted file mode 100644 index 3811221..0000000 --- a/Engine/Editor/editor.c +++ /dev/null @@ -1,122 +0,0 @@ -#include "editor.h" -#include "../Core/logger.h" -#include -#include -#include - -static const float BG_DARK[] = {0.12f, 0.12f, 0.14f}; -static const float BG_PANEL[] = {0.16f, 0.16f, 0.18f}; -static const float BG_TITLE[] = {0.20f, 0.20f, 0.24f}; -static const float BG_INPUT[] = {0.10f, 0.10f, 0.12f}; - -int editor_init(Editor* ed, GraphicsDevice* dev) { - memset(ed, 0, sizeof(*ed)); - ed->device = dev; - - if (!uilayer_init(&ed->ui, dev->device, (float)dev->width, (float)dev->height)) return 0; - - int sw = dev->width, sh = dev->height; - int menu_h = 28; - ed->panels[0] = (EditorPanel){PANEL_VIEWPORT, "Viewport", 220, menu_h, sw-440, sh-menu_h-200, 1, 0, 0}; - ed->panels[1] = (EditorPanel){PANEL_SCENE, "Scene", 0, menu_h, 220, sh-menu_h-200, 1, 0, 0}; - ed->panels[2] = (EditorPanel){PANEL_INSPECTOR, "Inspector", sw-220, menu_h, 220, sh-menu_h-200, 1, 0, 0}; - ed->panels[3] = (EditorPanel){PANEL_CONSOLE, "Console", 0, sh-200, sw, 200, 1, 0, 0}; - ed->panel_count = 4; - - ed->scene_entities_count = 8; - strcpy(ed->selected_entity, "Cube"); - - LOG_INFO("Editor initialized"); - return 1; -} - -void editor_shutdown(Editor* ed) { - uilayer_destroy(&ed->ui); -} - -void editor_update(Editor* ed, float dt) { - ed->time += dt; - ed->viewport_rotation += dt * 0.5f; -} - -void editor_render(Editor* ed) { - ID3D11DeviceContext* ctx = ed->device->context; - float sw = (float)ed->device->width; - float sh = (float)ed->device->height; - - graphics_device_clear(ed->device, BG_DARK[0], BG_DARK[1], BG_DARK[2], 1.0f); - - uilayer_begin(&ed->ui); - - uilayer_rect(&ed->ui, 0, 0, sw, 28, 1.0f, 0.0f, 0.0f, 1.0f); - uilayer_rect(&ed->ui, 0, 28, sw, 28, 0.0f, 1.0f, 0.0f, 1.0f); - uilayer_rect(&ed->ui, 0, 56, sw/3, sh-256, 0.0f, 0.0f, 1.0f, 1.0f); - uilayer_rect(&ed->ui, sw/3, 56, sw/3, sh-256, 1.0f, 1.0f, 0.0f, 1.0f); - uilayer_rect(&ed->ui, 2*sw/3, 56, sw/3, sh-256, 1.0f, 0.0f, 1.0f, 1.0f); - uilayer_rect(&ed->ui, 0, sh-200, sw, 200, 0.0f, 1.0f, 1.0f, 1.0f); - uilayer_rect(&ed->ui, 0, sh-22, sw, 22, 1.0f, 0.5f, 0.0f, 1.0f); - - uilayer_flush(&ed->ui, ctx); - - float sw2 = sw, sh2 = sh; - bitmap_font_draw(&ed->font, ctx, "Lity3D Engine Editor", 10, 6, - 0.4f, 0.75f, 1.0f, 1.0f, sw2, sh2); - - const char* menu[] = {"File", "Edit", "View", "Build", "Help"}; - int mx = 180; - for (int i = 0; i < 5; i++) { - bitmap_font_draw(&ed->font, ctx, menu[i], mx + 8, 6, - 0.9f, 0.9f, 0.92f, 1.0f, sw2, sh2); - mx += (int)strlen(menu[i]) * 8 + 16; - } - - const char* tools[] = {"Select", "Move", "Rotate", "Scale"}; - int tx = 6; - for (int i = 0; i < 4; i++) { - bitmap_font_draw(&ed->font, ctx, tools[i], tx + 4, 34, - 0.9f, 0.9f, 0.92f, 1.0f, sw2, sh2); - tx += (int)strlen(tools[i]) * 8 + 16; - } - - for (int i = 0; i < ed->panel_count; i++) { - EditorPanel* p = &ed->panels[i]; - if (!p->visible) continue; - bitmap_font_draw(&ed->font, ctx, p->title, p->x + 6, p->y + 6, - 0.9f, 0.9f, 0.92f, 1.0f, sw2, sh2); - } - - bitmap_font_draw(&ed->font, ctx, ed->selected_entity, 226, 56, - 0.4f, 0.75f, 1.0f, 1.0f, sw2, sh2); - - const char* entities[] = {"Light", "Camera", "Cube", "Plane", "Sphere", "Particles", "Audio", "Skybox"}; - for (int i = 0; i < 8; i++) { - bitmap_font_draw(&ed->font, ctx, entities[i], 226, 78 + i * 22, - 0.9f, 0.9f, 0.92f, 1.0f, sw2, sh2); - } - - const char* sections[] = {"Transform", "Mesh Filter", "Material", "Collider"}; - int sy = 56; - for (int s = 0; s < 4; s++) { - bitmap_font_draw(&ed->font, ctx, sections[s], (int)sw - 214, sy, - 0.9f, 0.9f, 0.92f, 1.0f, sw2, sh2); - sy += 26; - } - - char status[128]; - snprintf(status, sizeof(status), "Entities: %d | Time: %.1fs", ed->scene_entities_count, ed->time); - bitmap_font_draw(&ed->font, ctx, status, 10, (int)sh - 18, - 0.55f, 0.55f, 0.6f, 1.0f, sw2, sh2); -} - -void editor_handle_input(Editor* ed, int msg, int wp, int lp) { - (void)lp; - switch (msg) { - case 0x0200: ed->input.mouse_x = wp & 0xFFFF; ed->input.mouse_y = (wp >> 16) & 0x7FFF; break; - case 0x0201: ed->input.mouse_lbtn = 1; break; - case 0x0202: ed->input.mouse_lbtn = 0; break; - case 0x0204: ed->input.mouse_rbtn = 1; break; - case 0x0205: ed->input.mouse_rbtn = 0; break; - case 0x0100: if (wp < 256) ed->input.key_down[wp] = 1; break; - case 0x0101: if (wp < 256) ed->input.key_down[wp] = 0; break; - } -} diff --git a/Engine/Editor/editor.h b/Engine/Editor/editor.h deleted file mode 100644 index bb51368..0000000 --- a/Engine/Editor/editor.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once -#include "uilayer.h" -#include "bitmap_font.h" -#include "../Rendering/graphics_device.h" -#include - -#define EDITOR_MAX_PANELS 16 - -typedef enum { - PANEL_SCENE, - PANEL_INSPECTOR, - PANEL_CONSOLE, - PANEL_ASSETS, - PANEL_VIEWPORT, -} PanelType; - -typedef struct { - PanelType type; - const char* title; - int x, y, w, h; - int visible; - int collapsed; - int active_tab; -} EditorPanel; - -typedef struct { - int mouse_x, mouse_y; - int mouse_lbtn; - int mouse_rbtn; - int key_down[256]; - char text_input[256]; - int text_len; -} EditorInput; - -typedef struct { - GraphicsDevice* device; - UILayer ui; - BitmapFont font; - EditorPanel panels[EDITOR_MAX_PANELS]; - int panel_count; - EditorInput input; - float time; - char console_lines[32][256]; - int console_count; - int console_scroll; - char selected_entity[128]; - int scene_entities_count; - float viewport_rotation; -} Editor; - -int editor_init(Editor* ed, GraphicsDevice* dev); -void editor_shutdown(Editor* ed); -void editor_update(Editor* ed, float dt); -void editor_render(Editor* ed); -void editor_handle_input(Editor* ed, int msg, int wp, int lp); diff --git a/Engine/Editor/editor_2d.c b/Engine/Editor/editor_2d.c deleted file mode 100644 index 2017ac9..0000000 --- a/Engine/Editor/editor_2d.c +++ /dev/null @@ -1,124 +0,0 @@ -#include "editor_2d.h" -#include -#include - -int editor2d_init(Editor2D* e, ID3D11Device* dev) { - memset(e, 0, sizeof(*e)); - - e->shader = shader_create(); - if (!shader_compile(e->shader, dev, NULL, NULL, 0, 0)) return 0; - - D3D11_BUFFER_DESC bd = {0}; - bd.ByteWidth = ED2D_MAX_QUADS * 4 * sizeof(Ed2DVert); - bd.Usage = D3D11_USAGE_DYNAMIC; - bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - if (FAILED(dev->lpVtbl->CreateBuffer(dev, &bd, NULL, &e->vb))) return 0; - - bd.ByteWidth = ED2D_MAX_QUADS * 6 * sizeof(uint32_t); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - bd.CPUAccessFlags = 0; - uint32_t* idx = (uint32_t*)malloc(ED2D_MAX_QUADS * 6 * sizeof(uint32_t)); - for (int i = 0; i < ED2D_MAX_QUADS; i++) { - uint32_t b2 = i * 4; - idx[i*6]=b2; idx[i*6+1]=b2+1; idx[i*6+2]=b2+2; - idx[i*6+3]=b2; idx[i*6+4]=b2+2; idx[i*6+5]=b2+3; - } - D3D11_SUBRESOURCE_DATA sd = {0}; sd.pSysMem = idx; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &e->ib); - free(idx); - - e->verts = (Ed2DVert*)malloc(ED2D_MAX_QUADS * 4 * sizeof(Ed2DVert)); - - D3D11_BLEND_DESC bdesc = {0}; - bdesc.RenderTarget[0].BlendEnable = TRUE; - bdesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - bdesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - bdesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - bdesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - bdesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - bdesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - dev->lpVtbl->CreateBlendState(dev, &bdesc, &e->blend); - - D3D11_DEPTH_STENCIL_DESC dsdesc = {0}; - dsdesc.DepthEnable = FALSE; - dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - dev->lpVtbl->CreateDepthStencilState(dev, &dsdesc, &e->ds_no_depth); - - return 1; -} - -void editor2d_destroy(Editor2D* e) { - if (!e) return; - if (e->ds_no_depth) e->ds_no_depth->lpVtbl->Release(e->ds_no_depth); - if (e->blend) e->blend->lpVtbl->Release(e->blend); - if (e->ib) e->ib->lpVtbl->Release(e->ib); - if (e->vb) e->vb->lpVtbl->Release(e->vb); - shader_destroy(e->shader); - free(e->verts); - memset(e, 0, sizeof(*e)); -} - -void editor2d_begin(Editor2D* e, float sw, float sh) { - e->quad_count = 0; - e->screen_w = sw; - e->screen_h = sh; - - memset(e->wvp, 0, sizeof(e->wvp)); - e->wvp[0] = 2.0f / sw; - e->wvp[5] = -2.0f / sh; - e->wvp[12] = -1.0f; - e->wvp[13] = 1.0f; - e->wvp[15] = 1.0f; -} - -void editor2d_rect(Editor2D* e, float x, float y, float w, float h, float r, float g, float b, float a) { - if (e->quad_count >= ED2D_MAX_QUADS) return; - int vi = e->quad_count * 4; - e->verts[vi+0] = (Ed2DVert){x, y, 0, 0,0,-1, 0,1, r,g,b,a}; - e->verts[vi+1] = (Ed2DVert){x+w, y, 0, 0,0,-1, 1,1, r,g,b,a}; - e->verts[vi+2] = (Ed2DVert){x+w, y+h, 0, 0,0,-1, 1,0, r,g,b,a}; - e->verts[vi+3] = (Ed2DVert){x, y+h, 0, 0,0,-1, 0,0, r,g,b,a}; - e->quad_count++; -} - -void editor2d_rect_border(Editor2D* e, float x, float y, float w, float h, float r, float g, float b, float a, float t) { - editor2d_rect(e, x, y, w, t, r, g, b, a); - editor2d_rect(e, x, y+h-t, w, t, r, g, b, a); - editor2d_rect(e, x, y, t, h, r, g, b, a); - editor2d_rect(e, x+w-t, y, t, h, r, g, b, a); -} - -void editor2d_end(Editor2D* e, ID3D11DeviceContext* ctx) { - if (e->quad_count == 0) return; - - D3D11_MAPPED_SUBRESOURCE mapped; - if (FAILED(ctx->lpVtbl->Map(ctx, (ID3D11Resource*)e->vb, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped))) return; - memcpy(mapped.pData, e->verts, (size_t)e->quad_count * 4 * sizeof(Ed2DVert)); - ctx->lpVtbl->Unmap(ctx, (ID3D11Resource*)e->vb, 0); - - if (e->rtv) { - ctx->lpVtbl->OMSetRenderTargets(ctx, 1, &e->rtv, NULL); - } - - D3D11_VIEWPORT vp = {0}; - vp.Width = e->screen_w; - vp.Height = e->screen_h; - vp.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vp); - - shader_bind(e->shader, ctx); - shader_set_matrix(e->shader, ctx, e->wvp); - - UINT stride = sizeof(Ed2DVert), offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &e->vb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, e->ib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - float bf[4] = {0}; - ctx->lpVtbl->OMSetBlendState(ctx, e->blend, bf, 0xFFFFFFFF); - ctx->lpVtbl->OMSetDepthStencilState(ctx, e->ds_no_depth, 0); - - ctx->lpVtbl->DrawIndexed(ctx, (UINT)(e->quad_count * 6), 0, 0); -} diff --git a/Engine/Editor/editor_2d.h b/Engine/Editor/editor_2d.h deleted file mode 100644 index 13bd05f..0000000 --- a/Engine/Editor/editor_2d.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include -#include -#include "../Rendering/shader.h" -#include "../Rendering/mesh.h" - -#define ED2D_MAX_QUADS 8192 - -typedef struct { - float x, y, z; - float nx, ny, nz; - float u, v; - float r, g, b, a; -} Ed2DVert; - -typedef struct { - Shader* shader; - ID3D11Buffer* vb; - ID3D11Buffer* ib; - ID3D11BlendState* blend; - ID3D11DepthStencilState* ds_no_depth; - ID3D11RenderTargetView* rtv; - Ed2DVert* verts; - int quad_count; - float screen_w; - float screen_h; - float wvp[16]; -} Editor2D; - -int editor2d_init(Editor2D* e, ID3D11Device* dev); -void editor2d_destroy(Editor2D* e); -void editor2d_begin(Editor2D* e, float sw, float sh); -void editor2d_rect(Editor2D* e, float x, float y, float w, float h, float r, float g, float b, float a); -void editor2d_rect_border(Editor2D* e, float x, float y, float w, float h, float r, float g, float b, float a, float thickness); -void editor2d_end(Editor2D* e, ID3D11DeviceContext* ctx); diff --git a/Engine/Editor/glyph_atlas.c b/Engine/Editor/glyph_atlas.c deleted file mode 100644 index fe9af28..0000000 --- a/Engine/Editor/glyph_atlas.c +++ /dev/null @@ -1,171 +0,0 @@ -#include "glyph_atlas.h" -#include -#include -#include -#include -#include "../Core/logger.h" - -typedef struct { - wchar_t ch; - int x, y; - int w, h; - float u0, v0, u1, v1; - float advance_x; -} GlyphEntry; - -#define MAX_GLYPHS 1024 -static GlyphEntry g_entries[MAX_GLYPHS]; -static int g_entry_count = 0; - -int glyph_atlas_init(GlyphAtlas* ga, ID3D11Device* dev) { - memset(ga, 0, sizeof(*ga)); - ga->cell_w = GLYPH_CELL_W; - ga->cell_h = GLYPH_CELL_H; - ga->atlas_w = GLYPH_ATLAS_SIZE; - ga->atlas_h = GLYPH_ATLAS_SIZE; - ga->next_x = 0; - ga->next_y = 0; - ga->u_scale = 1.0f / (float)ga->atlas_w; - ga->v_scale = 1.0f / (float)ga->atlas_h; - - uint8_t* pixels = (uint8_t*)calloc(ga->atlas_w * ga->atlas_h * 4, 1); - - D3D11_TEXTURE2D_DESC td = {0}; - td.Width = ga->atlas_w; - td.Height = ga->atlas_h; - td.MipLevels = 1; - td.ArraySize = 1; - td.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - td.SampleDesc.Count = 1; - td.Usage = D3D11_USAGE_DEFAULT; - td.BindFlags = D3D11_BIND_SHADER_RESOURCE; - D3D11_SUBRESOURCE_DATA sd = {0}; - sd.pSysMem = pixels; - sd.SysMemPitch = ga->atlas_w * 4; - HRESULT hr = dev->lpVtbl->CreateTexture2D(dev, &td, &sd, &ga->texture); - free(pixels); - if (FAILED(hr)) return 0; - - dev->lpVtbl->CreateShaderResourceView(dev, (ID3D11Resource*)ga->texture, NULL, &ga->srv); - - LOG_INFO("GlyphAtlas: initialized (%dx%d, max %d glyphs)", ga->atlas_w, ga->atlas_h, MAX_GLYPHS); - return 1; -} - -void glyph_atlas_destroy(GlyphAtlas* ga) { - if (!ga) return; - if (ga->srv) ga->srv->lpVtbl->Release(ga->srv); - if (ga->texture) ga->texture->lpVtbl->Release(ga->texture); - memset(ga, 0, sizeof(*ga)); - g_entry_count = 0; -} - -static int find_glyph(wchar_t ch) { - for (int i = 0; i < g_entry_count; i++) { - if (g_entries[i].ch == ch) return i; - } - return -1; -} - -int glyph_atlas_get_or_create(GlyphAtlas* ga, ID3D11Device* dev, ID3D11DeviceContext* ctx, wchar_t ch, - float* u0, float* v0, float* u1, float* v1, - float* advance_x, float* advance_y) { - int idx = find_glyph(ch); - if (idx >= 0) { - *u0 = g_entries[idx].u0; - *v0 = g_entries[idx].v0; - *u1 = g_entries[idx].u1; - *v1 = g_entries[idx].v1; - *advance_x = g_entries[idx].advance_x; - *advance_y = (float)g_entries[idx].h; - return 1; - } - - if (g_entry_count >= MAX_GLYPHS) return 0; - - if (ga->next_x + ga->cell_w > ga->atlas_w) { - ga->next_x = 0; - ga->next_y += ga->cell_h; - } - if (ga->next_y + ga->cell_h > ga->atlas_h) return 0; - - HDC hdc = GetDC(NULL); - HFONT hfont = CreateFontW( - ga->cell_h - 4, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, - DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, - CLEARTYPE_QUALITY, FIXED_PITCH | FF_DONTCARE, L"Microsoft YaHei" - ); - HFONT old = (HFONT)SelectObject(hdc, hfont); - - GLYPHMETRICS gm = {0}; - MAT2 mat = {{0,0},{0,0},{0,0},{0,0}}; - mat.eM11.value = 1; mat.eM22.value = 1; - - DWORD size = GetGlyphOutlineW(hdc, ch, GGO_GRAY8_BITMAP, &gm, 0, NULL, &mat); - - int gw = gm.gmBlackBoxX; - int gh = gm.gmBlackBoxY; - int gx = ga->next_x; - int gy = ga->next_y; - - if (size > 0 && gw > 0 && gh > 0) { - uint8_t* buf = (uint8_t*)malloc(size); - GetGlyphOutlineW(hdc, ch, GGO_GRAY8_BITMAP, &gm, size, buf, &mat); - - uint8_t* pixels = (uint8_t*)calloc(gw * gh * 4, 1); - - int row_bytes = ((gw + 3) / 4) * 4; - - for (int row = 0; row < gh; row++) { - for (int col = 0; col < gw; col++) { - int src_idx = row * row_bytes + col; - if (src_idx < (int)size) { - uint8_t gray = buf[src_idx]; - uint8_t alpha = (gray > 200) ? 255 : (gray > 100) ? 200 : (gray > 30) ? 128 : 0; - int idx = (row * gw + col) * 4; - pixels[idx] = 255; - pixels[idx + 1] = 255; - pixels[idx + 2] = 255; - pixels[idx + 3] = alpha; - } - } - } - - D3D11_BOX box = {0}; - box.left = gx; - box.top = gy; - box.front = 0; - box.right = gx + gw; - box.bottom = gy + gh; - box.back = 1; - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)ga->texture, 0, &box, pixels, gw * 4, 0); - free(buf); - free(pixels); - } - - SelectObject(hdc, old); - DeleteObject(hfont); - ReleaseDC(NULL, hdc); - - GlyphEntry* e = &g_entries[g_entry_count++]; - e->ch = ch; - e->x = gx; - e->y = gy; - e->w = gw > 0 ? gw : ga->cell_w / 2; - e->h = gh > 0 ? gh : ga->cell_h; - e->u0 = (float)gx * ga->u_scale; - e->v0 = (float)gy * ga->v_scale; - e->u1 = (float)(gx + e->w) * ga->u_scale; - e->v1 = (float)(gy + e->h) * ga->v_scale; - e->advance_x = (float)(gm.gmCellIncX > 0 ? gm.gmCellIncX : ga->cell_w / 2); - - ga->next_x += ga->cell_w; - - *u0 = e->u0; - *v0 = e->v0; - *u1 = e->u1; - *v1 = e->v1; - *advance_x = e->advance_x; - *advance_y = (float)e->h; - return 1; -} diff --git a/Engine/Editor/glyph_atlas.h b/Engine/Editor/glyph_atlas.h deleted file mode 100644 index bb47559..0000000 --- a/Engine/Editor/glyph_atlas.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -#include -#include - -#define GLYPH_CELL_W 32 -#define GLYPH_CELL_H 32 -#define GLYPH_ATLAS_COLS 16 -#define GLYPH_ATLAS_ROWS 16 -#define GLYPH_ATLAS_SIZE (GLYPH_ATLAS_COLS * GLYPH_CELL_W) - -typedef struct { - ID3D11Texture2D* texture; - ID3D11ShaderResourceView* srv; - int atlas_w; - int atlas_h; - int next_x; - int next_y; - int cell_w; - int cell_h; - float u_scale; - float v_scale; -} GlyphAtlas; - -int glyph_atlas_init(GlyphAtlas* ga, ID3D11Device* dev); -void glyph_atlas_destroy(GlyphAtlas* ga); -int glyph_atlas_get_or_create(GlyphAtlas* ga, ID3D11Device* dev, ID3D11DeviceContext* ctx, wchar_t ch, - float* u0, float* v0, float* u1, float* v1, - float* advance_x, float* advance_y); diff --git a/Engine/Editor/textlayer.h b/Engine/Editor/textlayer.h deleted file mode 100644 index 680e6cb..0000000 --- a/Engine/Editor/textlayer.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "uilayer.h" -#include "bitmap_font.h" - -int textlayer_init(TextLayer* t, ID3D11Device* dev, BitmapFont* font, UILayer* ui); -void textlayer_destroy(TextLayer* t); -void textlayer_draw(TextLayer* t, ID3D11DeviceContext* ctx, - const char* text, int x, int y, - float r, float g, float b, float a, - float screen_w, float screen_h); diff --git a/Engine/Editor/uilayer.c b/Engine/Editor/uilayer.c deleted file mode 100644 index a3b898e..0000000 --- a/Engine/Editor/uilayer.c +++ /dev/null @@ -1,252 +0,0 @@ -#include "uilayer.h" -#include -#include -#include "../Core/logger.h" - -#define UI_MAX_VERTS (UI_MAX_QUADS * 4) -#define UI_MAX_IDXS (UI_MAX_QUADS * 6) - -typedef struct { float p[3], n[3], uv[2], c[4]; } UIVert; - -static UIVert g_verts[UI_MAX_VERTS]; -static uint32_t g_indices[UI_MAX_IDXS]; -static int g_vi = 0; -static int g_ii = 0; - -static UIVert g_text_verts[UI_MAX_VERTS]; -static uint32_t g_text_indices[UI_MAX_IDXS]; -static int g_tvi = 0; -static int g_tii = 0; -static ID3D11ShaderResourceView* g_text_srv = NULL; - -static void screen_to_world(float sx, float sy, float sw, float sh, float z, float* wx, float* wy) { - *wx = sx - sw * 0.5f; - *wy = -(sy - sh * 0.5f); -} - -int uilayer_init(UILayer* u, ID3D11Device* dev, float screen_w, float screen_h) { - memset(u, 0, sizeof(*u)); - u->screen_w = screen_w; - u->screen_h = screen_h; - u->z_plane = 0.0f; - - u->camera = camera_orthographic(screen_w, screen_h, 0.1f, 200.0f); - u->camera.position = (Vec3){0, 0, 100}; - u->camera.target = (Vec3){0, 0, 0}; - u->camera.dirty = 1; - camera_update(&u->camera); - - u->shader = shader_create(); - if (!shader_compile(u->shader, dev, NULL, NULL, 0, 0)) { - LOG_ERROR("UILayer: shader compile failed"); - return 0; - } - - D3D11_BUFFER_DESC bd = {0}; - D3D11_SUBRESOURCE_DATA sd = {0}; - - UIVert* empty = (UIVert*)calloc(UI_MAX_VERTS, sizeof(UIVert)); - bd.ByteWidth = UI_MAX_VERTS * sizeof(UIVert); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = empty; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &u->vb); - free(empty); - - uint32_t* eidx = (uint32_t*)calloc(UI_MAX_IDXS, sizeof(uint32_t)); - bd.ByteWidth = UI_MAX_IDXS * sizeof(uint32_t); - bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = eidx; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &u->ib); - free(eidx); - - UIVert* empty2 = (UIVert*)calloc(UI_MAX_VERTS, sizeof(UIVert)); - bd.ByteWidth = UI_MAX_VERTS * sizeof(UIVert); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = empty2; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &u->text_vb); - free(empty2); - - uint32_t* eidx2 = (uint32_t*)calloc(UI_MAX_IDXS, sizeof(uint32_t)); - bd.ByteWidth = UI_MAX_IDXS * sizeof(uint32_t); - bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = eidx2; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &u->text_ib); - free(eidx2); - - D3D11_RASTERIZER_DESC rdesc = {0}; - rdesc.FillMode = D3D11_FILL_SOLID; - rdesc.CullMode = D3D11_CULL_NONE; - dev->lpVtbl->CreateRasterizerState(dev, &rdesc, &u->rstate); - - D3D11_DEPTH_STENCIL_DESC dsdesc = {0}; - dsdesc.DepthEnable = FALSE; - dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - dev->lpVtbl->CreateDepthStencilState(dev, &dsdesc, &u->ds_state); - - D3D11_BLEND_DESC bdesc = {0}; - bdesc.RenderTarget[0].BlendEnable = TRUE; - bdesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - bdesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - bdesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - bdesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - bdesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - bdesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - dev->lpVtbl->CreateBlendState(dev, &bdesc, &u->text_blend); - - D3D11_SAMPLER_DESC sdesc = {0}; - sdesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - sdesc.AddressU = sdesc.AddressV = sdesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - dev->lpVtbl->CreateSamplerState(dev, &sdesc, &u->text_sampler); - - const char* text_vs_src = - "cbuffer CB:register(b0){float4x4 WVP;};" - "struct VS_IN{float4 pos:POSITION;float3 n:NORMAL;float2 uv:TEXCOORD;float4 col:COLOR;};" - "struct PS_IN{float4 pos:SV_POSITION;float2 uv:TEXCOORD;float4 col:COLOR;};" - "PS_IN main(VS_IN i){PS_IN o;o.pos=mul(i.pos,WVP);o.uv=i.uv;o.col=i.col;return o;}"; - const char* text_ps_src = - "Texture2D tex:register(t0);SamplerState smp:register(s0);" - "struct PS_IN{float4 pos:SV_POSITION;float2 uv:TEXCOORD;float4 col:COLOR;};" - "float4 main(PS_IN i):SV_TARGET{float a=tex.Sample(smp,i.uv).a;return float4(i.col.rgb,i.col.a*a);}"; - - ID3DBlob *vsb = NULL, *psb = NULL; - D3DCompile(text_vs_src, (UINT)strlen(text_vs_src), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &vsb, NULL); - D3DCompile(text_ps_src, (UINT)strlen(text_ps_src), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &psb, NULL); - if (vsb && psb) { - dev->lpVtbl->CreateVertexShader(dev, vsb->lpVtbl->GetBufferPointer(vsb), vsb->lpVtbl->GetBufferSize(vsb), NULL, &u->text_vs); - dev->lpVtbl->CreatePixelShader(dev, psb->lpVtbl->GetBufferPointer(psb), psb->lpVtbl->GetBufferSize(psb), NULL, &u->text_ps); - D3D11_INPUT_ELEMENT_DESC layout[] = { - {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}, - }; - dev->lpVtbl->CreateInputLayout(dev, layout, 4, vsb->lpVtbl->GetBufferPointer(vsb), vsb->lpVtbl->GetBufferSize(vsb), &u->text_layout); - vsb->lpVtbl->Release(vsb); - psb->lpVtbl->Release(psb); - } - - LOG_INFO("UILayer: initialized (%.0fx%.0f)", screen_w, screen_h); - return 1; -} - -void uilayer_destroy(UILayer* u) { - if (!u) return; - if (u->text_sampler) u->text_sampler->lpVtbl->Release(u->text_sampler); - if (u->text_blend) u->text_blend->lpVtbl->Release(u->text_blend); - if (u->text_layout) u->text_layout->lpVtbl->Release(u->text_layout); - if (u->text_ps) u->text_ps->lpVtbl->Release(u->text_ps); - if (u->text_vs) u->text_vs->lpVtbl->Release(u->text_vs); - if (u->text_ib) u->text_ib->lpVtbl->Release(u->text_ib); - if (u->text_vb) u->text_vb->lpVtbl->Release(u->text_vb); - if (u->ds_state) u->ds_state->lpVtbl->Release(u->ds_state); - if (u->rstate) u->rstate->lpVtbl->Release(u->rstate); - if (u->ib) u->ib->lpVtbl->Release(u->ib); - if (u->vb) u->vb->lpVtbl->Release(u->vb); - if (u->shader) shader_destroy(u->shader); - memset(u, 0, sizeof(*u)); -} - -void uilayer_begin(UILayer* u) { - (void)u; - g_vi = 0; g_ii = 0; - g_tvi = 0; g_tii = 0; - g_text_srv = NULL; -} - -void uilayer_rect(UILayer* u, float x, float y, float w, float h, - float r, float g, float b, float a) { - if (g_vi + 4 > UI_MAX_VERTS) return; - float x0, y0, x1, y1; - screen_to_world(x, y, u->screen_w, u->screen_h, u->z_plane, &x0, &y0); - screen_to_world(x + w, y + h, u->screen_w, u->screen_h, u->z_plane, &x1, &y1); - float z = u->z_plane; - uint32_t base = (uint32_t)g_vi; - g_verts[g_vi] = (UIVert){{x0,y0,z},{0,0,1},{0,0},{r,g,b,a}}; g_vi++; - g_verts[g_vi] = (UIVert){{x1,y0,z},{0,0,1},{1,0},{r,g,b,a}}; g_vi++; - g_verts[g_vi] = (UIVert){{x1,y1,z},{0,0,1},{1,1},{r,g,b,a}}; g_vi++; - g_verts[g_vi] = (UIVert){{x0,y1,z},{0,0,1},{0,1},{r,g,b,a}}; g_vi++; - g_indices[g_ii++] = base; g_indices[g_ii++] = base+1; g_indices[g_ii++] = base+2; - g_indices[g_ii++] = base; g_indices[g_ii++] = base+2; g_indices[g_ii++] = base+3; -} - -void uilayer_textured_rect(UILayer* u, ID3D11DeviceContext* ctx, - ID3D11ShaderResourceView* srv, - float x, float y, float w, float h, - float u0, float v0, float u1, float v1, - float r, float g, float b, float a) { - (void)ctx; - if (!srv || g_tvi + 4 > UI_MAX_VERTS) return; - float x0, y0, x1, y1; - screen_to_world(x, y, u->screen_w, u->screen_h, u->z_plane, &x0, &y0); - screen_to_world(x + w, y + h, u->screen_w, u->screen_h, u->z_plane, &x1, &y1); - float z = u->z_plane; - uint32_t base = (uint32_t)g_tvi; - g_text_verts[g_tvi] = (UIVert){{x0,y0,z},{0,0,1},{u0,v0},{r,g,b,a}}; g_tvi++; - g_text_verts[g_tvi] = (UIVert){{x1,y0,z},{0,0,1},{u1,v0},{r,g,b,a}}; g_tvi++; - g_text_verts[g_tvi] = (UIVert){{x1,y1,z},{0,0,1},{u1,v1},{r,g,b,a}}; g_tvi++; - g_text_verts[g_tvi] = (UIVert){{x0,y1,z},{0,0,1},{u0,v1},{r,g,b,a}}; g_tvi++; - g_text_indices[g_tii++] = base; g_text_indices[g_tii++] = base+1; g_text_indices[g_tii++] = base+2; - g_text_indices[g_tii++] = base; g_text_indices[g_tii++] = base+2; g_text_indices[g_tii++] = base+3; - g_text_srv = srv; -} - -static void flush_batch(ID3D11DeviceContext* ctx, UIVert* verts, uint32_t* indices, - int num_idx, ID3D11Buffer* vb, ID3D11Buffer* ib) { - if (num_idx == 0) return; - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)vb, 0, NULL, verts, 0, 0); - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)ib, 0, NULL, indices, 0, 0); - UINT stride = sizeof(UIVert), offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &vb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, ib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->DrawIndexed(ctx, (UINT)num_idx, 0, 0); -} - -void uilayer_flush(UILayer* u, ID3D11DeviceContext* ctx) { - if (g_ii == 0) return; - Mat4 view = u->camera.view; - Mat4 proj = u->camera.projection; - Mat4 vp, vp_t; - mat4_multiply(&view, &proj, &vp); - mat4_transpose(&vp, &vp_t); - - D3D11_VIEWPORT vport = {0}; - vport.Width = u->screen_w; vport.Height = u->screen_h; vport.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vport); - ctx->lpVtbl->RSSetState(ctx, u->rstate); - ctx->lpVtbl->OMSetDepthStencilState(ctx, u->ds_state, 0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - shader_bind(u->shader, ctx); - shader_set_matrix(u->shader, ctx, (float*)&vp_t); - flush_batch(ctx, g_verts, g_indices, g_ii, u->vb, u->ib); -} - -void uilayer_flush_text(UILayer* u, ID3D11DeviceContext* ctx) { - if (g_tii == 0 || !g_text_srv || !u->text_vs || !u->text_ps) return; - Mat4 view = u->camera.view; - Mat4 proj = u->camera.projection; - Mat4 vp, vp_t; - mat4_multiply(&view, &proj, &vp); - mat4_transpose(&vp, &vp_t); - - D3D11_VIEWPORT vport = {0}; - vport.Width = u->screen_w; vport.Height = u->screen_h; vport.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vport); - ctx->lpVtbl->RSSetState(ctx, u->rstate); - ctx->lpVtbl->OMSetDepthStencilState(ctx, u->ds_state, 0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - ctx->lpVtbl->VSSetShader(ctx, u->text_vs, NULL, 0); - ctx->lpVtbl->PSSetShader(ctx, u->text_ps, NULL, 0); - ctx->lpVtbl->IASetInputLayout(ctx, u->text_layout); - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)u->shader->cb, 0, NULL, &vp_t, 0, 0); - ctx->lpVtbl->VSSetConstantBuffers(ctx, 0, 1, &u->shader->cb); - - float bf[4] = {0}; - ctx->lpVtbl->OMSetBlendState(ctx, u->text_blend, bf, 0xFFFFFFFF); - ctx->lpVtbl->PSSetShaderResources(ctx, 0, 1, &g_text_srv); - ctx->lpVtbl->PSSetSamplers(ctx, 0, 1, &u->text_sampler); - - flush_batch(ctx, g_text_verts, g_text_indices, g_tii, u->text_vb, u->text_ib); -} diff --git a/Engine/Editor/uilayer.h b/Engine/Editor/uilayer.h deleted file mode 100644 index 241cf12..0000000 --- a/Engine/Editor/uilayer.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once -#include "../Rendering/camera.h" -#include "../Rendering/shader.h" -#include "../Rendering/mesh.h" -#include "../Rendering/graphics_device.h" -#include "../ASM/math_c_fallback.h" - -#define UI_MAX_QUADS 8192 - -typedef struct { - Camera camera; - Shader* shader; - ID3D11Buffer* vb; - ID3D11Buffer* ib; - ID3D11Buffer* text_vb; - ID3D11Buffer* text_ib; - ID3D11RasterizerState* rstate; - ID3D11DepthStencilState* ds_state; - ID3D11VertexShader* text_vs; - ID3D11PixelShader* text_ps; - ID3D11InputLayout* text_layout; - ID3D11BlendState* text_blend; - ID3D11SamplerState* text_sampler; - float screen_w; - float screen_h; - float z_plane; -} UILayer; - -int uilayer_init(UILayer* u, ID3D11Device* dev, float screen_w, float screen_h); -void uilayer_destroy(UILayer* u); -void uilayer_begin(UILayer* u); -void uilayer_rect(UILayer* u, - float x, float y, float w, float h, - float r, float g, float b, float a); -void uilayer_textured_rect(UILayer* u, ID3D11DeviceContext* ctx, - ID3D11ShaderResourceView* srv, - float x, float y, float w, float h, - float u0, float v0, float u1, float v1, - float r, float g, float b, float a); -void uilayer_flush(UILayer* u, ID3D11DeviceContext* ctx); -void uilayer_flush_text(UILayer* u, ID3D11DeviceContext* ctx); diff --git a/Engine/Engine.vcxproj b/Engine/Engine.vcxproj deleted file mode 100644 index d47cc3f..0000000 --- a/Engine/Engine.vcxproj +++ /dev/null @@ -1,124 +0,0 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - {B5C5B5B5-5B5B-5B5B-5B5B-5B5B5B5B5B5B} - Engine - 10.0 - - - - StaticLibrary - true - v143 - Unicode - - - StaticLibrary - false - v143 - true - Unicode - - - - - - - - - - - - - - - NotUsing - Level4 - true - _DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) - true - stdc17 - $(ProjectDir);$(ProjectDir)include;%(AdditionalIncludeDirectories) - AdvancedVectorExtensions2 - - - %(AdditionalLibraryDirectories) - - - - - NotUsing - Level4 - true - true - true - NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) - true - stdc17 - $(ProjectDir);$(ProjectDir)include;%(AdditionalIncludeDirectories) - AdvancedVectorExtensions2 - - - %(AdditionalLibraryDirectories) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Engine/Engine/ASM/asm_macros.inc b/Engine/Engine/ASM/asm_macros.inc deleted file mode 100644 index db7a7f4..0000000 --- a/Engine/Engine/ASM/asm_macros.inc +++ /dev/null @@ -1,137 +0,0 @@ -; ============================================================================ -; asm_macros.inc - MASM 通用宏定义 -; Windows x64 调用约定: RCX, RDX, R8, R9 传参, XMM0-XMM3 浮点 -; ============================================================================ - -; --- 函数帧管理宏 --- - -; PROLOGUE: 保存非易失寄存器, 分配栈空间 -; 使用: PROLOGUE 栈空间大小 -PROLOGUE MACRO stack_size:REQ - push rbx - push rbp - push rdi - push rsi - push r12 - push r13 - push r14 - push r15 - sub rsp, stack_size - ; 保存浮点参数寄存器 (如果有) - movsd qword ptr [rsp + stack_size - 8], xmm6 - movsd qword ptr [rsp + stack_size - 16], xmm7 -ENDM - -; EPILOGUE: 恢复非易失寄存器, 释放栈空间 -EPILOGUE MACRO stack_size:REQ - movsd xmm6, qword ptr [rsp + stack_size - 8] - movsd xmm7, qword ptr [rsp + stack_size - 16] - add rsp, stack_size - pop r15 - pop r14 - pop r13 - pop r12 - pop rsi - pop rdi - pop rbp - pop rbx - ret -ENDM - -; --- SSE/AVX 常量 --- -.DATA -ALIGN 16 -sse_mask_abs DD 07FFFFFFFH, 07FFFFFFFH, 07FFFFFFFH, 07FFFFFFFH ; 绝对值掩码 -sse_negate DD 80000000H, 80000000H, 80000000H, 80000000H ; 符号位掩码 -sse_one DD 3F800000H, 3F800000H, 3F800000H, 3F800000H ; 1.0f -sse_half DD 3F000000H, 3F000000H, 3F000000H, 3F000000H ; 0.5f -eps_float DD 33D6BF94H ; 1e-6f - -.CODE - -; --- 工具宏 --- - -; LOAD_VEC3: 从内存加载 Vec3 到 XMM 寄存器 (填充 w=1.0) -; ptr: 内存地址, reg: XMM 寄存器 -LOAD_VEC3 MACRO ptr, reg - movss xmm0, dword ptr [ptr] ; x - movss xmm1, dword ptr [ptr + 4] ; y - movss xmm2, dword ptr [ptr + 8] ; z - unpcklps xmm0, xmm1 ; {x, y, ?, ?} - movss xmm3, dword ptr [sse_one] ; w = 1.0 - unpcklps xmm2, xmm3 ; {z, 1.0, ?, ?} - movlhps xmm0, xmm2 ; {x, y, z, 1.0} - movaps reg, xmm0 -ENDM - -; STORE_VEC3: 将 XMM 寄存器的前3个float存储到内存 -STORE_VEC3 MACRO reg, ptr - movss dword ptr [ptr], xmm0 ; x - shufps xmm0, xmm0, 01010101b - movss dword ptr [ptr + 4], xmm0 ; y - shufps xmm0, xmm0, 10101010b - movss dword ptr [ptr + 8], xmm0 ; z -ENDM - -; --- 外部函数声明 --- -externdef vec3_add:PROC -externdef vec3_sub:PROC -externdef vec3_scale:PROC -externdef vec3_dot:PROC -externdef vec3_cross:PROC -externdef vec3_length:PROC -externdef vec3_normalize:PROC -externdef vec3_lerp:PROC -externdef vec3_distance:PROC - -externdef vec4_add:PROC -externdef vec4_sub:PROC -externdef vec4_mul:PROC -externdef vec4_dot:PROC -externdef vec4_length:PROC -externdef vec4_normalize:PROC - -externdef mat4_identity:PROC -externdef mat4_multiply:PROC -externdef mat4_transpose:PROC -externdef mat4_invert:PROC -externdef mat4_translate:PROC -externdef mat4_scale_f:PROC -externdef mat4_rotate_x:PROC -externdef mat4_rotate_y:PROC -externdef mat4_rotate_z:PROC -externdef mat4_perspective:PROC -externdef mat4_orthographic:PROC -externdef mat4_lookat:PROC - -externdef quat_multiply:PROC -externdef quat_conjugate:PROC -externdef quat_normalize:PROC -externdef quat_rotate_vec3:PROC -externdef quat_slerp:PROC -externdef quat_to_matrix:PROC -externdef quat_from_axis_angle:PROC -externdef quat_from_euler:PROC - -externdef mem_aligned_alloc:PROC -externdef mem_aligned_free:PROC -externdef mem_aligned_realloc:PROC - -externdef fast_memcpy:PROC -externdef fast_memset:PROC -externdef fast_strlen:PROC -externdef fast_strcmp:PROC - -externdef prof_rdtsc:PROC -externdef prof_cycles_to_ms:PROC -externdef prof_get_freq:PROC - -; C 数学运行时 -externdef cosf:PROC -externdef sinf:PROC -externdef tanf:PROC - -; Windows API -externdef Sleep:PROC -externdef QueryPerformanceFrequency:PROC -externdef QueryPerformanceCounter:PROC diff --git a/Engine/Engine/ASM/math.asm b/Engine/Engine/ASM/math.asm deleted file mode 100644 index f8d4d12..0000000 --- a/Engine/Engine/ASM/math.asm +++ /dev/null @@ -1,1189 +0,0 @@ -; ============================================================================ -; math.asm - SIMD 数学库 (x86-64 MASM) -; SSE4.1/AVX2/FMA 指令集加速 -; Windows x64 ABI: RCX, RDX, R8, R9 传参, XMM0-XMM3 浮点 -; ============================================================================ - -include asm_macros.inc - -.DATA -ALIGN 16 -_negate_mask DD 80000000H, 80000000H, 80000000H, 80000000H -_abs_mask DD 7FFFFFFFH, 7FFFFFFFH, 7FFFFFFFH, 7FFFFFFFH -_one DD 3F800000H, 3F800000H, 3F800000H, 3F800000H -_half DD 3F000000H, 3F000000H, 3F000000H, 3F000000H -_zero DD 0, 0, 0, 0 -_eps DD 33D6BF94H ; 1e-6 -_pi DD 40490FDBH ; 3.14159265 -_two_pi DD 40C90FDBH ; 2*PI -_half_pi DD 3FC90FDBH ; PI/2 -_deg_to_rad DD 3C8EFA35H ; PI/180 -_rad_to_deg DD 42652EE1H ; 180/PI - -.CODE - -; ============================================================================ -; Vector3 操作 -; ============================================================================ - -; void vec3_add(const Vec3* a, const Vec3* b, Vec3* out) -; RCX = a, RDX = b, R8 = out -vec3_add PROC - movss xmm0, dword ptr [rcx] ; a.x - addss xmm0, dword ptr [rdx] ; + b.x - movss dword ptr [r8], xmm0 ; out.x - - movss xmm0, dword ptr [rcx + 4] ; a.y - addss xmm0, dword ptr [rdx + 4] ; + b.y - movss dword ptr [r8 + 4], xmm0 ; out.y - - movss xmm0, dword ptr [rcx + 8] ; a.z - addss xmm0, dword ptr [rdx + 8] ; + b.z - movss dword ptr [r8 + 8], xmm0 ; out.z - - ret -vec3_add ENDP - -; void vec3_sub(const Vec3* a, const Vec3* b, Vec3* out) -vec3_sub PROC - movss xmm0, dword ptr [rcx] - subss xmm0, dword ptr [rdx] - movss dword ptr [r8], xmm0 - - movss xmm0, dword ptr [rcx + 4] - subss xmm0, dword ptr [rdx + 4] - movss dword ptr [r8 + 4], xmm0 - - movss xmm0, dword ptr [rcx + 8] - subss xmm0, dword ptr [rdx + 8] - movss dword ptr [r8 + 8], xmm0 - - ret -vec3_sub ENDP - -; void vec3_scale(const Vec3* a, float scalar, Vec3* out) -; RCX = a, XMM1 = scalar, RDX = out -vec3_scale PROC - movss xmm0, dword ptr [rcx] - mulss xmm0, xmm1 - movss dword ptr [rdx], xmm0 - - movss xmm0, dword ptr [rcx + 4] - mulss xmm0, xmm1 - movss dword ptr [rdx + 4], xmm0 - - movss xmm0, dword ptr [rcx + 8] - mulss xmm0, xmm1 - movss dword ptr [rdx + 8], xmm0 - - ret -vec3_scale ENDP - -; float vec3_dot(const Vec3* a, const Vec3* b) -> XMM0 -vec3_dot PROC - movss xmm0, dword ptr [rcx] ; a.x - mulss xmm0, dword ptr [rdx] ; * b.x - movss xmm1, dword ptr [rcx + 4] ; a.y - mulss xmm1, dword ptr [rdx + 4] ; * b.y - addss xmm0, xmm1 ; a.x*b.x + a.y*b.y - movss xmm1, dword ptr [rcx + 8] ; a.z - mulss xmm1, dword ptr [rdx + 8] ; * b.z - addss xmm0, xmm1 ; + a.z*b.z - ret -vec3_dot ENDP - -; void vec3_cross(const Vec3* a, const Vec3* b, Vec3* out) -vec3_cross PROC - ; out.x = a.y * b.z - a.z * b.y - movss xmm0, dword ptr [rcx + 4] ; a.y - mulss xmm0, dword ptr [rdx + 8] ; * b.z - movss xmm1, dword ptr [rcx + 8] ; a.z - mulss xmm1, dword ptr [rdx + 4] ; * b.y - subss xmm0, xmm1 - movss dword ptr [r8], xmm0 - - ; out.y = a.z * b.x - a.x * b.z - movss xmm0, dword ptr [rcx + 8] - mulss xmm0, dword ptr [rdx] - movss xmm1, dword ptr [rcx] - mulss xmm1, dword ptr [rdx + 8] - subss xmm0, xmm1 - movss dword ptr [r8 + 4], xmm0 - - ; out.z = a.x * b.y - a.y * b.x - movss xmm0, dword ptr [rcx] - mulss xmm0, dword ptr [rdx + 4] - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, dword ptr [rdx] - subss xmm0, xmm1 - movss dword ptr [r8 + 8], xmm0 - - ret -vec3_cross ENDP - -; float vec3_length(const Vec3* a) -> XMM0 -vec3_length PROC - movss xmm0, dword ptr [rcx] - mulss xmm0, xmm0 - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, xmm1 - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] - mulss xmm1, xmm1 - addss xmm0, xmm1 - sqrtss xmm0, xmm0 - ret -vec3_length ENDP - -; void vec3_normalize(const Vec3* a, Vec3* out) -vec3_normalize PROC - ; 计算长度 - movss xmm0, dword ptr [rcx] - mulss xmm0, xmm0 - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, xmm1 - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] - mulss xmm1, xmm1 - addss xmm0, xmm1 - sqrtss xmm0, xmm0 - - ; 检查零向量 - movss xmm1, dword ptr [_eps] - comiss xmm0, xmm1 - jb vec3_normalize_zero - - ; 归一化: 1.0 / length - movss xmm1, dword ptr [_one] - divss xmm1, xmm0 - - movss xmm0, dword ptr [rcx] - mulss xmm0, xmm1 - movss dword ptr [rdx], xmm0 - - movss xmm0, dword ptr [rcx + 4] - mulss xmm0, xmm1 - movss dword ptr [rdx + 4], xmm0 - - movss xmm0, dword ptr [rcx + 8] - mulss xmm0, xmm1 - movss dword ptr [rdx + 8], xmm0 - ret - -vec3_normalize_zero: - mov dword ptr [rdx], 0 - mov dword ptr [rdx + 4], 0 - mov dword ptr [rdx + 8], 0 - ret -vec3_normalize ENDP - -; void vec3_lerp(const Vec3* a, const Vec3* b, float t, Vec3* out) -; RCX = a, RDX = b, XMM2 = t, R8 = out -vec3_lerp PROC - ; out.x = a.x + (b.x - a.x) * t - movss xmm0, dword ptr [rdx] - subss xmm0, dword ptr [rcx] ; b.x - a.x - mulss xmm0, xmm2 ; * t - addss xmm0, dword ptr [rcx] ; + a.x - movss dword ptr [r8], xmm0 - - ; out.y - movss xmm0, dword ptr [rdx + 4] - subss xmm0, dword ptr [rcx + 4] - mulss xmm0, xmm2 - addss xmm0, dword ptr [rcx + 4] - movss dword ptr [r8 + 4], xmm0 - - ; out.z - movss xmm0, dword ptr [rdx + 8] - subss xmm0, dword ptr [rcx + 8] - mulss xmm0, xmm2 - addss xmm0, dword ptr [rcx + 8] - movss dword ptr [r8 + 8], xmm0 - - ret -vec3_lerp ENDP - -; float vec3_distance(const Vec3* a, const Vec3* b) -> XMM0 -vec3_distance PROC - ; 计算差向量然后求长度 - sub rsp, 16 - movss xmm0, dword ptr [rcx] - subss xmm0, dword ptr [rdx] - movss dword ptr [rsp], xmm0 - - movss xmm0, dword ptr [rcx + 4] - subss xmm0, dword ptr [rdx + 4] - movss dword ptr [rsp + 4], xmm0 - - movss xmm0, dword ptr [rcx + 8] - subss xmm0, dword ptr [rdx + 8] - movss dword ptr [rsp + 8], xmm0 - - ; 长度 - movss xmm0, dword ptr [rsp] - mulss xmm0, xmm0 - movss xmm1, dword ptr [rsp + 4] - mulss xmm1, xmm1 - addss xmm0, xmm1 - movss xmm1, dword ptr [rsp + 8] - mulss xmm1, xmm1 - addss xmm0, xmm1 - sqrtss xmm0, xmm0 - - add rsp, 16 - ret -vec3_distance ENDP - -; ============================================================================ -; Vector4 操作 (SSE 128-bit) -; ============================================================================ - -; void vec4_add(const Vec4* a, const Vec4* b, Vec4* out) -vec4_add PROC - movaps xmm0, xmmword ptr [rcx] - addps xmm0, xmmword ptr [rdx] - movaps xmmword ptr [r8], xmm0 - ret -vec4_add ENDP - -; void vec4_sub(const Vec4* a, const Vec4* b, Vec4* out) -vec4_sub PROC - movaps xmm0, xmmword ptr [rcx] - subps xmm0, xmmword ptr [rdx] - movaps xmmword ptr [r8], xmm0 - ret -vec4_sub ENDP - -; void vec4_mul(const Vec4* a, const Vec4* b, Vec4* out) -vec4_mul PROC - movaps xmm0, xmmword ptr [rcx] - mulps xmm0, xmmword ptr [rdx] - movaps xmmword ptr [r8], xmm0 - ret -vec4_mul ENDP - -; float vec4_dot(const Vec4* a, const Vec4* b) -> XMM0 -vec4_dot PROC - movaps xmm0, xmmword ptr [rcx] - mulps xmm0, xmmword ptr [rdx] ; 逐元素乘 - ; 水平求和: {x*y, ?, ?, ?} - movaps xmm1, xmm0 - shufps xmm1, xmm1, 01001110b ; swap pairs - addss xmm0, xmm1 ; x*y + z*w (低64位) - movhlps xmm1, xmm0 - addss xmm0, xmm1 ; 完整求和 - ret -vec4_dot ENDP - -; float vec4_length(const Vec4* a) -> XMM0 -vec4_length PROC - movaps xmm0, xmmword ptr [rcx] - mulps xmm0, xmm0 - movaps xmm1, xmm0 - shufps xmm1, xmm1, 01001110b - addss xmm0, xmm1 - movhlps xmm1, xmm0 - addss xmm0, xmm1 - sqrtss xmm0, xmm0 - ret -vec4_length ENDP - -; void vec4_normalize(const Vec4* a, Vec4* out) -vec4_normalize PROC - movaps xmm0, xmmword ptr [rcx] - mulps xmm0, xmm0 - movaps xmm1, xmm0 - shufps xmm1, xmm1, 01001110b - addss xmm0, xmm1 - movhlps xmm1, xmm0 - addss xmm0, xmm1 - sqrtss xmm0, xmm0 - ; 1.0 / length - movss xmm1, dword ptr [_one] - divss xmm1, xmm0 - ; 广播到所有通道 - shufps xmm1, xmm1, 0 - movaps xmm0, xmmword ptr [rcx] - mulps xmm0, xmm1 - movaps xmmword ptr [rdx], xmm0 - ret -vec4_normalize ENDP - -; ============================================================================ -; Matrix4x4 操作 -; ============================================================================ - -; void mat4_identity(Mat4* out) -; 输出 4x4 单位矩阵 -mat4_identity PROC - xorps xmm0, xmm0 ; 清零 - movaps xmmword ptr [rcx], xmm0 - movaps xmmword ptr [rcx + 16], xmm0 - movaps xmmword ptr [rcx + 32], xmm0 - movaps xmmword ptr [rcx + 48], xmm0 - movss dword ptr [rcx], xmm0 ; 已经是0, 下面设对角线 - mov dword ptr [rcx], 3F800000h ; m[0][0] = 1.0 - mov dword ptr [rcx + 20], 3F800000h ; m[1][1] = 1.0 - mov dword ptr [rcx + 40], 3F800000h ; m[2][2] = 1.0 - mov dword ptr [rcx + 60], 3F800000h ; m[3][3] = 1.0 - ret -mat4_identity ENDP - -; void mat4_multiply(const Mat4* a, const Mat4* b, Mat4* out) -; 4x4 矩阵乘法 - 按行主序存储 (行优先) -; a: RCX, b: RDX, out: R8 -mat4_multiply PROC - ; 逐行计算 out = a * b - ; out 的第 i 行 = a[i][0]*b行0 + a[i][1]*b行1 + a[i][2]*b行2 + a[i][3]*b行3 - - xor eax, eax ; 行索引 i = 0 -mat4_mul_row_loop: - ; 加载 a 的第 i 行的4个元素 - movss xmm4, dword ptr [rcx + rax*4] ; a[i][0] - shufps xmm4, xmm4, 0 ; 广播到所有通道 - movss xmm5, dword ptr [rcx + rax*4 + 16] ; a[i][1] - shufps xmm5, xmm5, 0 - movss xmm6, dword ptr [rcx + rax*4 + 32] ; a[i][2] - shufps xmm6, xmm6, 0 - movss xmm7, dword ptr [rcx + rax*4 + 48] ; a[i][3] - shufps xmm7, xmm7, 0 - - ; 加载 b 的4行, 乘以对应的 a[i][j], 累加 - movaps xmm0, xmmword ptr [rdx] ; b行0 - mulps xmm0, xmm4 - movaps xmm1, xmmword ptr [rdx + 16] ; b行1 - mulps xmm1, xmm5 - addps xmm0, xmm1 - movaps xmm1, xmmword ptr [rdx + 32] ; b行2 - mulps xmm1, xmm6 - addps xmm0, xmm1 - movaps xmm1, xmmword ptr [rdx + 48] ; b行3 - mulps xmm1, xmm7 - addps xmm0, xmm1 - - ; 存储到 out 的第 i 行 - movaps xmmword ptr [r8 + rax*4], xmm0 - - add eax, 4 ; 下一列 (行主序: 每4个float是一行) - cmp eax, 16 - jl mat4_mul_row_loop - ret -mat4_multiply ENDP - -; void mat4_transpose(const Mat4* a, Mat4* out) -mat4_transpose PROC - movaps xmm0, xmmword ptr [rcx] ; 行0 - movaps xmm1, xmmword ptr [rcx + 16] ; 行1 - movaps xmm2, xmmword ptr [rcx + 32] ; 行2 - movaps xmm3, xmmword ptr [rcx + 48] ; 行3 - - ; unpacklo/hi 交叉存取 - unpcklps xmm0, xmm1 ; {a00, a10, a01, a11} - unpcklps xmm2, xmm3 ; {a20, a30, a21, a31} - unpckhps xmm0, xmm1 ; {a02, a12, a03, a13} - unpckhps xmm2, xmm3 ; {a22, a32, a23, a33} - - movlhps xmm0, xmm2 ; 行0: {a00, a10, a20, a30} - movhlps xmm2, xmm0 ; 行1: {a01, a11, a21, a31} - - movaps xmmword ptr [rdx], xmm0 - movaps xmmword ptr [rdx + 16], xmm2 - - ; 继续处理后两行 - movaps xmm0, xmmword ptr [rcx] - movaps xmm1, xmmword ptr [rcx + 16] - movaps xmm2, xmmword ptr [rcx + 32] - movaps xmm3, xmmword ptr [rcx + 48] - - unpcklps xmm0, xmm1 - unpcklps xmm2, xmm3 - unpckhps xmm0, xmm1 - unpckhps xmm2, xmm3 - - movlhps xmm0, xmm2 - movhlps xmm2, xmm0 - - movaps xmmword ptr [rdx + 32], xmm2 - movaps xmmword ptr [rdx + 48], xmm0 - ret -mat4_transpose ENDP - -; int mat4_invert(const Mat4* a, Mat4* out) -> EAX (1=成功, 0=失败) -; 使用伴随矩阵法求逆 -mat4_invert PROC - PROLOGUE 128 - - ; 复制输入矩阵 - mov rdi, rsp ; rdi = 本地存储 - mov rsi, rcx ; rsi = 输入 - - ; 加载 4 行 - movaps xmm0, xmmword ptr [rsi] - movaps xmm1, xmmword ptr [rsi + 16] - movaps xmm2, xmmword ptr [rsi + 32] - movaps xmm3, xmmword ptr [rsi + 48] - - ; 存储到本地 - movaps xmmword ptr [rdi], xmm0 - movaps xmmword ptr [rdi + 16], xmm1 - movaps xmmword ptr [rdi + 32], xmm2 - movaps xmmword ptr [rdi + 48], xmm3 - - ; 简化实现: 对于单位矩阵附近的矩阵使用近似 - ; 完整实现需要高斯消元, 这里用 SIMD 优化的简化版本 - - ; 检查是否为单位矩阵 (快速路径) - movss xmm4, dword ptr [rsi] - movss xmm5, dword ptr [rsi + 20] - mulss xmm4, xmm5 - movss xmm6, dword ptr [rsi + 40] - mulss xmm4, xmm6 - movss xmm7, dword ptr [rsi + 60] - mulss xmm4, xmm7 ; det 主对角线乘积 - - ; 简化: 假设可逆, 直接计算 - ; 使用 4x4 行列式展开 - - EPILOGUE 128 -mat4_invert ENDP - -; void mat4_translate(float x, float y, float z, Mat4* out) -mat4_translate PROC - ; 初始化为单位矩阵 + 平移 - movss xmm0, dword ptr [rcx] ; x - movss xmm1, dword ptr [rdx] ; y - movss xmm2, dword ptr [r8] ; z - mov rax, r9 ; out - - ; 清零 - mov dword ptr [rax], 3F800000h ; m[0][0] = 1.0 - mov dword ptr [rax + 4], 0 - mov dword ptr [rax + 8], 0 - mov dword ptr [rax + 12], 0 - - mov dword ptr [rax + 16], 0 - mov dword ptr [rax + 20], 3F800000h ; m[1][1] = 1.0 - mov dword ptr [rax + 24], 0 - mov dword ptr [rax + 28], 0 - - mov dword ptr [rax + 32], 0 - mov dword ptr [rax + 36], 0 - mov dword ptr [rax + 40], 3F800000h ; m[2][2] = 1.0 - mov dword ptr [rax + 44], 0 - - movss dword ptr [rax + 48], xmm0 ; m[3][0] = x - movss dword ptr [rax + 52], xmm1 ; m[3][1] = y - movss dword ptr [rax + 56], xmm2 ; m[3][2] = z - mov dword ptr [rax + 60], 3F800000h ; m[3][3] = 1.0 - - ret -mat4_translate ENDP - -; void mat4_scale_f(float x, float y, float z, Mat4* out) -mat4_scale_f PROC - movss xmm0, dword ptr [rcx] ; x - movss xmm1, dword ptr [rdx] ; y - movss xmm2, dword ptr [r8] ; z - mov rax, r9 - - movss dword ptr [rax], xmm0 ; m[0][0] = x - mov dword ptr [rax + 4], 0 - mov dword ptr [rax + 8], 0 - mov dword ptr [rax + 12], 0 - - mov dword ptr [rax + 16], 0 - movss dword ptr [rax + 20], xmm1 ; m[1][1] = y - mov dword ptr [rax + 24], 0 - mov dword ptr [rax + 28], 0 - - mov dword ptr [rax + 32], 0 - mov dword ptr [rax + 36], 0 - movss dword ptr [rax + 40], xmm2 ; m[2][2] = z - mov dword ptr [rax + 44], 0 - - mov dword ptr [rax + 48], 0 - mov dword ptr [rax + 52], 0 - mov dword ptr [rax + 56], 0 - mov dword ptr [rax + 60], 3F800000h ; m[3][3] = 1.0 - - ret -mat4_scale_f ENDP - -; void mat4_rotate_x(float angle, Mat4* out) -mat4_rotate_x PROC - ; cos(angle), sin(angle) - movss xmm0, dword ptr [rcx] ; angle - movss xmm1, xmm0 ; save angle - call cosf ; xmm0 = cos - movss xmm2, xmm0 ; save cos - movss xmm0, xmm1 ; restore angle - call sinf ; xmm0 = sin - movss xmm1, xmm0 ; xmm1 = sin - movss xmm0, xmm2 ; xmm0 = cos - mov rax, rdx ; out - - movss dword ptr [rax], 3F800000h ; m[0][0] = 1.0 - mov dword ptr [rax + 4], 0 - mov dword ptr [rax + 8], 0 - mov dword ptr [rax + 12], 0 - - mov dword ptr [rax + 16], 0 - movss dword ptr [rax + 20], xmm0 ; m[1][1] = cos - ; m[1][2] = sin (需要取反 for row-major) - movss xmm2, xmm1 - movss dword ptr [rax + 24], xmm2 ; m[1][2] = sin - mov dword ptr [rax + 28], 0 - - mov dword ptr [rax + 32], 0 - ; m[2][1] = -sin - pxor xmm2, xmm2 - subss xmm2, xmm1 - movss dword ptr [rax + 36], xmm2 ; m[2][1] = -sin - movss dword ptr [rax + 40], xmm0 ; m[2][2] = cos - mov dword ptr [rax + 44], 0 - - mov dword ptr [rax + 48], 0 - mov dword ptr [rax + 52], 0 - mov dword ptr [rax + 56], 0 - mov dword ptr [rax + 60], 3F800000h - - ret -mat4_rotate_x ENDP - -; void mat4_rotate_y(float angle, Mat4* out) -mat4_rotate_y PROC - movss xmm0, dword ptr [rcx] - movss xmm1, xmm0 ; save angle - call cosf ; xmm0 = cos - movss xmm2, xmm0 ; save cos - movss xmm0, xmm1 ; restore angle - call sinf ; xmm0 = sin - movss xmm1, xmm0 ; xmm1 = sin - movss xmm0, xmm2 ; xmm0 = cos - mov rax, rdx - - movss dword ptr [rax], xmm0 ; m[0][0] = cos - mov dword ptr [rax + 4], 0 - movss xmm2, xmm1 - movss dword ptr [rax + 8], xmm2 ; m[0][2] = -sin - mov dword ptr [rax + 12], 0 - - mov dword ptr [rax + 16], 0 - mov dword ptr [rax + 20], 3F800000h - mov dword ptr [rax + 24], 0 - mov dword ptr [rax + 28], 0 - - ; m[2][0] = sin - movss dword ptr [rax + 32], xmm1 - mov dword ptr [rax + 36], 0 - movss dword ptr [rax + 40], xmm0 ; m[2][2] = cos - mov dword ptr [rax + 44], 0 - - mov dword ptr [rax + 48], 0 - mov dword ptr [rax + 52], 0 - mov dword ptr [rax + 56], 0 - mov dword ptr [rax + 60], 3F800000h - - ret -mat4_rotate_y ENDP - -; void mat4_rotate_z(float angle, Mat4* out) -mat4_rotate_z PROC - movss xmm0, dword ptr [rcx] - movss xmm1, xmm0 ; save angle - call cosf ; xmm0 = cos - movss xmm2, xmm0 ; save cos - movss xmm0, xmm1 ; restore angle - call sinf ; xmm0 = sin - movss xmm1, xmm0 ; xmm1 = sin - movss xmm0, xmm2 ; xmm0 = cos - mov rax, rdx - - movss dword ptr [rax], xmm0 ; m[0][0] = cos - movss xmm2, xmm1 - movss dword ptr [rax + 4], xmm2 ; m[0][1] = sin - mov dword ptr [rax + 8], 0 - mov dword ptr [rax + 12], 0 - - ; m[1][0] = -sin - pxor xmm2, xmm2 - subss xmm2, xmm1 - movss dword ptr [rax + 16], xmm2 - movss dword ptr [rax + 20], xmm0 ; m[1][1] = cos - mov dword ptr [rax + 24], 0 - mov dword ptr [rax + 28], 0 - - mov dword ptr [rax + 32], 0 - mov dword ptr [rax + 36], 0 - mov dword ptr [rax + 40], 3F800000h - mov dword ptr [rax + 44], 0 - - mov dword ptr [rax + 48], 0 - mov dword ptr [rax + 52], 0 - mov dword ptr [rax + 56], 0 - mov dword ptr [rax + 60], 3F800000h - - ret -mat4_rotate_z ENDP - -; void mat4_perspective(float fovY, float aspect, float nearZ, float farZ, Mat4* out) -; XMM0=fovY, XMM1=aspect, XMM2=nearZ, XMM3=farZ, RCX=out -mat4_perspective PROC - ; tan(fovY/2) - movss xmm4, xmm0 - mulss xmm4, dword ptr [_half] ; fovY/2 - movss xmm0, xmm4 - call tanf - movss xmm4, xmm0 ; xmm4 = tan(fovY/2) - - ; 1 / (aspect * tan) - movss xmm5, xmm1 - mulss xmm5, xmm4 ; aspect * tan - movss xmm6, dword ptr [_one] - divss xmm6, xmm5 ; 1 / (aspect * tan) - - ; 1 / tan - movss xmm7, dword ptr [_one] - divss xmm7, xmm4 ; 1 / tan - - ; far / (near - far) - movss xmm4, xmm2 - subss xmm4, xmm3 ; near - far - movss xmm5, xmm3 - divss xmm5, xmm4 ; far / (near - far) - - ; near * far / (near - far) - mulss xmm4, xmm2 ; (near - far) * near - ; 不对, 重新计算 - ; tmp = near * far / (near - far) - movss xmm4, xmm2 - mulss xmm4, xmm3 ; near * far - movss xmm7, xmm2 - subss xmm7, xmm3 ; near - far - divss xmm4, xmm7 ; near*far / (near-far) - - ; 填充矩阵 - mov rax, rcx - - ; 清零 - pxor xmm7, xmm7 - movaps xmmword ptr [rax], xmm7 - movaps xmmword ptr [rax + 16], xmm7 - movaps xmmword ptr [rax + 32], xmm7 - movaps xmmword ptr [rax + 48], xmm7 - - ; m[0][0] = 1 / (aspect * tan) - movss dword ptr [rax], xmm6 - ; m[1][1] = 1 / tan - movss dword ptr [rax + 20], xmm7 ; 需要重新加载 1/tan - ; 重新计算 - movss xmm0, dword ptr [rsp + 40] ; 从栈获取参数 (调用者可能已压栈) - ; 简化: 直接用寄存器值 - - mov rax, rcx - ; m[0][0] - movss dword ptr [rax], xmm6 - - ; 重新加载 1/tan 到 xmm7 - movss xmm7, dword ptr [_one] - divss xmm7, xmm4 ; 需要原始的 tan 值 - - ; 为了简化, 重新计算整个矩阵 - ; 用更清晰的方式 - pxor xmm7, xmm7 - movaps xmmword ptr [rax], xmm7 - movaps xmmword ptr [rax + 16], xmm7 - movaps xmmword ptr [rax + 32], xmm7 - movaps xmmword ptr [rax + 48], xmm7 - - ; 重新获取参数 - ; fovY 已在 xmm0 时的值, 但我们已经覆盖了 - ; 使用栈上的值 - - ; 简化: 使用标量方式设置 - ret -mat4_perspective ENDP - -; void mat4_orthographic(float width, float height, float nearZ, float farZ, Mat4* out) -mat4_orthographic PROC - movss xmm0, dword ptr [rcx] ; width - movss xmm1, dword ptr [rdx] ; height - movss xmm2, dword ptr [r8] ; nearZ - movss xmm3, dword ptr [r9] ; farZ - ; out 在 [rsp+40] (第5个参数) - mov r10, qword ptr [rsp + 40] - - ; 清零 - pxor xmm4, xmm4 - movaps xmmword ptr [r10], xmm4 - movaps xmmword ptr [r10 + 16], xmm4 - movaps xmmword ptr [r10 + 32], xmm4 - movaps xmmword ptr [r10 + 48], xmm4 - - ; 2/width - movss xmm4, dword ptr [_one] - addss xmm4, xmm4 ; 2.0 - divss xmm4, xmm0 ; 2/width - movss dword ptr [r10], xmm4 ; m[0][0] - - ; 2/height - movss xmm4, dword ptr [_one] - addss xmm4, xmm4 - divss xmm4, xmm1 - movss dword ptr [r10 + 20], xmm4 ; m[1][1] - - ; 1/(near-far) - movss xmm4, xmm2 - subss xmm4, xmm3 - movss xmm5, dword ptr [_one] - divss xmm5, xmm4 - movss dword ptr [r10 + 40], xmm5 ; m[2][2] - - ; near/(near-far) - mulss xmm4, xmm2 ; (near-far)*near... 不对 - ; 重新: near / (near - far) - movss xmm4, xmm2 - divss xmm4, [rsp + 32] ; near / (near-far) - 用原始值 - ; 简化 - movss xmm4, xmm2 - movss xmm5, xmm2 - subss xmm5, xmm3 - divss xmm4, xmm5 - movss dword ptr [r10 + 48], xmm4 ; m[3][2] - - mov dword ptr [r10 + 60], 3F800000h ; m[3][3] = 1.0 - - ret -mat4_orthographic ENDP - -; void mat4_lookat(const Vec3* eye, const Vec3* target, const Vec3* up, Mat4* out) -mat4_lookat PROC - PROLOGUE 64 - - ; zAxis = normalize(eye - target) - sub rsp, 32 - movss xmm0, dword ptr [rcx] ; eye.x - subss xmm0, dword ptr [rdx] ; - target.x - movss dword ptr [rsp], xmm0 - - movss xmm0, dword ptr [rcx + 4] - subss xmm0, dword ptr [rdx + 4] - movss dword ptr [rsp + 4], xmm0 - - movss xmm0, dword ptr [rcx + 8] - subss xmm0, dword ptr [rdx + 8] - movss dword ptr [rsp + 8], xmm0 - - ; normalize zAxis - movss xmm0, dword ptr [rsp] - mulss xmm0, xmm0 - movss xmm1, dword ptr [rsp + 4] - mulss xmm1, xmm1 - addss xmm0, xmm1 - movss xmm1, dword ptr [rsp + 8] - mulss xmm1, xmm1 - addss xmm0, xmm1 - sqrtss xmm0, xmm0 - movss xmm1, dword ptr [_one] - divss xmm1, xmm0 - - mulss xmm0, xmm1 - movss dword ptr [rsp], xmm0 - mulss xmm0, xmm1 - movss dword ptr [rsp + 4], xmm0 - mulss xmm0, xmm1 - movss dword ptr [rsp + 8], xmm0 - - ; xAxis = normalize(cross(up, zAxis)) - ; ... (简化实现) - - EPILOGUE 64 -mat4_lookat ENDP - -; ============================================================================ -; Quaternion 操作 -; ============================================================================ - -; void quat_multiply(const Quat* a, const Quat* b, Quat* out) -quat_multiply PROC - ; q = (x,y,z,w) - ; a = (ax,ay,az,aw), b = (bx,by,bz,bw) - ; out.x = aw*bx + ax*bw + ay*bz - az*by - ; out.y = aw*by - ax*bz + ay*bw + az*bx - ; out.z = aw*bz + ax*by - ay*bx + az*bw - ; out.w = aw*bw - ax*bx - ay*by - az*bz - - movss xmm0, dword ptr [rcx + 12] ; aw - mulss xmm0, dword ptr [rdx] ; aw*bx - movss xmm1, dword ptr [rcx] ; ax - mulss xmm1, dword ptr [rdx + 12] ; ax*bw - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 4] ; ay - mulss xmm1, dword ptr [rdx + 8] ; ay*bz - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] ; az - mulss xmm1, dword ptr [rdx + 4] ; az*by - subss xmm0, xmm1 - movss dword ptr [r8], xmm0 ; out.x - - ; out.y - movss xmm0, dword ptr [rcx + 12] - mulss xmm0, dword ptr [rdx + 4] - movss xmm1, dword ptr [rcx] - mulss xmm1, dword ptr [rdx + 8] - subss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, dword ptr [rdx + 12] - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] - mulss xmm1, dword ptr [rdx] - addss xmm0, xmm1 - movss dword ptr [r8 + 4], xmm0 - - ; out.z - movss xmm0, dword ptr [rcx + 12] - mulss xmm0, dword ptr [rdx + 8] - movss xmm1, dword ptr [rcx] - mulss xmm1, dword ptr [rdx + 4] - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, dword ptr [rdx] - subss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] - mulss xmm1, dword ptr [rdx + 12] - addss xmm0, xmm1 - movss dword ptr [r8 + 8], xmm0 - - ; out.w - movss xmm0, dword ptr [rcx + 12] - mulss xmm0, dword ptr [rdx + 12] - movss xmm1, dword ptr [rcx] - mulss xmm1, dword ptr [rdx] - subss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, dword ptr [rdx + 4] - subss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] - mulss xmm1, dword ptr [rdx + 8] - subss xmm0, xmm1 - movss dword ptr [r8 + 12], xmm0 - - ret -quat_multiply ENDP - -; void quat_conjugate(const Quat* q, Quat* out) -quat_conjugate PROC - movss xmm0, dword ptr [rcx] - movss xmm1, dword ptr [rcx + 4] - movss xmm2, dword ptr [rcx + 8] - movss xmm3, dword ptr [rcx + 12] - - pxor xmm4, xmm4 - subss xmm4, xmm0 ; -x - movss dword ptr [rdx], xmm4 - pxor xmm4, xmm4 - subss xmm4, xmm1 ; -y - movss dword ptr [rdx + 4], xmm4 - pxor xmm4, xmm4 - subss xmm4, xmm2 ; -z - movss dword ptr [rdx + 8], xmm4 - movss dword ptr [rdx + 12], xmm3 ; w 不变 - ret -quat_conjugate ENDP - -; void quat_normalize(const Quat* q, Quat* out) -quat_normalize PROC - ; 长度 = sqrt(x*x + y*y + z*z + w*w) - movss xmm0, dword ptr [rcx] - mulss xmm0, xmm0 - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, xmm1 - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] - mulss xmm1, xmm1 - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 12] - mulss xmm1, xmm1 - addss xmm0, xmm1 - sqrtss xmm0, xmm0 - - ; 1.0 / length - movss xmm1, dword ptr [_one] - divss xmm1, xmm0 - - ; 归一化 - movss xmm0, dword ptr [rcx] - mulss xmm0, xmm1 - movss dword ptr [rdx], xmm0 - movss xmm0, dword ptr [rcx + 4] - mulss xmm0, xmm1 - movss dword ptr [rdx + 4], xmm0 - movss xmm0, dword ptr [rcx + 8] - mulss xmm0, xmm1 - movss dword ptr [rdx + 8], xmm0 - movss xmm0, dword ptr [rcx + 12] - mulss xmm0, xmm1 - movss dword ptr [rdx + 12], xmm0 - ret -quat_normalize ENDP - -; void quat_rotate_vec3(const Quat* q, const Vec3* v, Vec3* out) -; 使用公式: v' = q * v * q_conjugate -quat_rotate_vec3 PROC - PROLOGUE 48 - - ; 计算 q * v (将v视为 w=0 的四元数) - ; 简化: 使用旋转公式 - ; v' = v + 2*w*(u x v) + 2*(u x (u x v)) - ; 其中 u = (x,y,z), w = quat.w - - movss xmm0, dword ptr [rcx] ; qx - movss xmm1, dword ptr [rcx + 4] ; qy - movss xmm2, dword ptr [rcx + 8] ; qz - movss xmm3, dword ptr [rcx + 12] ; qw - - ; u = (qx, qy, qz) - ; t = 2 * cross(u, v) - ; cross.x = qy*vz - qz*vy - movss xmm4, xmm1 - mulss xmm4, dword ptr [rdx + 8] ; qy * vz - movss xmm5, xmm2 - mulss xmm5, dword ptr [rdx + 4] ; qz * vy - subss xmm4, xmm5 ; cross.x - mulss xmm4, dword ptr [_one] ; * 2.0 (简化, 实际需要加) - ; ... (完整实现需要更多指令) - - ; 简化: 直接使用矩阵旋转 (先转四元数为矩阵) - ; 或使用优化的四元数旋转 - - EPILOGUE 48 -quat_rotate_vec3 ENDP - -; void quat_slerp(const Quat* a, const Quat* b, float t, Quat* out) -quat_slerp PROC - ; 计算点积 - movss xmm0, dword ptr [rcx] - mulss xmm0, dword ptr [rdx] - movss xmm1, dword ptr [rcx + 4] - mulss xmm1, dword ptr [rdx + 4] - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 8] - mulss xmm1, dword ptr [rdx + 8] - addss xmm0, xmm1 - movss xmm1, dword ptr [rcx + 12] - mulss xmm1, dword ptr [rdx + 12] - addss xmm0, xmm1 ; dot - - ; 如果 dot < 0, 翻转 b - pxor xmm1, xmm1 - comiss xmm0, xmm1 - jae slerp_no_flip - ; 翻转 b 的所有分量 - pxor xmm1, xmm1 - subss xmm1, dword ptr [rdx] - movss dword ptr [rsp - 16], xmm1 - ; ... (需要保存到临时空间) - movss xmm1, dword ptr [_negate_mask] ; 0x80000000 - xorps xmm0, xmm1 ; dot = -dot -slerp_no_flip: - - ; 简化: 线性插值 + 归一化 - ; out = normalize(a + t * (b - a)) - movss xmm1, xmm0 ; dot - ; 如果 dot 接近 1, 使用线性插值 - movss xmm2, dword ptr [_one] - subss xmm2, xmm1 ; 1 - dot - ; 简化实现 - ret -quat_slerp ENDP - -; void quat_to_matrix(const Quat* q, Mat4* out) -quat_to_matrix PROC - ; 从四元数构建旋转矩阵 - movss xmm0, dword ptr [rcx] ; x - movss xmm1, dword ptr [rcx + 4] ; y - movss xmm2, dword ptr [rcx + 8] ; z - movss xmm3, dword ptr [rcx + 12] ; w - - ; 预计算 - movss xmm4, xmm0 - addss xmm4, xmm0 ; 2x - movss xmm5, xmm1 - addss xmm5, xmm1 ; 2y - movss xmm6, xmm2 - addss xmm6, xmm2 ; 2z - - ; m[0][0] = 1 - 2y*y - 2z*z - movss xmm7, xmm1 - mulss xmm7, xmm5 ; 2y*y - movss xmm8, xmm2 - mulss xmm8, xmm6 ; 2z*z - addss xmm7, xmm8 - movss xmm8, dword ptr [_one] - subss xmm8, xmm7 - movss dword ptr [rdx], xmm8 - - ; m[0][1] = 2x*y + 2w*z - movss xmm7, xmm0 - mulss xmm7, xmm5 ; 2x*y - movss xmm8, xmm3 - mulss xmm8, xmm6 ; 2w*z - addss xmm7, xmm8 - movss dword ptr [rdx + 4], xmm7 - - ; m[0][2] = 2x*z - 2w*y - movss xmm7, xmm0 - mulss xmm7, xmm6 - movss xmm8, xmm3 - mulss xmm8, xmm5 - subss xmm7, xmm8 - movss dword ptr [rdx + 8], xmm7 - - mov dword ptr [rdx + 12], 0 - - ; 类似地计算其他行... (完整实现需要更多指令) - ; 这里省略重复代码 - - ret -quat_to_matrix ENDP - -; void quat_from_axis_angle(const Vec3* axis, float angle, Quat* out) -quat_from_axis_angle PROC - ; halfAngle = angle / 2 - movss xmm0, dword ptr [rdx] ; angle - mulss xmm0, dword ptr [_half] ; halfAngle - - ; s = sin(halfAngle) - movss xmm2, xmm0 ; save halfAngle - call sinf - movss xmm1, xmm0 ; xmm1 = sin - movss xmm0, xmm2 ; restore halfAngle - - ; 归一化轴 - movss xmm2, dword ptr [rcx] - mulss xmm2, xmm2 - movss xmm3, dword ptr [rcx + 4] - mulss xmm3, xmm3 - addss xmm2, xmm3 - movss xmm3, dword ptr [rcx + 8] - mulss xmm3, xmm3 - addss xmm2, xmm3 - sqrtss xmm2, xmm2 - movss xmm3, dword ptr [_one] - divss xmm3, xmm2 - - ; out.x = axis.x * s - movss xmm0, dword ptr [rcx] - mulss xmm0, xmm3 - mulss xmm0, xmm1 - movss dword ptr [r8], xmm0 - - ; out.y - movss xmm0, dword ptr [rcx + 4] - mulss xmm0, xmm3 - mulss xmm0, xmm1 - movss dword ptr [r8 + 4], xmm0 - - ; out.z - movss xmm0, dword ptr [rcx + 8] - mulss xmm0, xmm3 - mulss xmm0, xmm1 - movss dword ptr [r8 + 8], xmm0 - - ; out.w = cos(halfAngle) - call cosf - movss dword ptr [r8 + 12], xmm0 - - ret -quat_from_axis_angle ENDP - -; void quat_from_euler(float pitch, float yaw, float roll, Quat* out) -; XMM0=pitch, XMM1=yaw, XMM2=roll, RCX=out -quat_from_euler PROC - ; 半角 - mulss xmm0, dword ptr [_half] ; pitch/2 - mulss xmm1, dword ptr [_half] ; yaw/2 - mulss xmm2, dword ptr [_half] ; roll/2 - - ; 保存半角并计算 cos/sin - sub rsp, 48 - movss dword ptr [rsp + 0], xmm0 ; pitch/2 - movss dword ptr [rsp + 4], xmm1 ; yaw/2 - movss dword ptr [rsp + 8], xmm2 ; roll/2 - - call cosf - movss dword ptr [rsp + 12], xmm0 ; cp - movss xmm0, dword ptr [rsp + 0] - call sinf - movss dword ptr [rsp + 16], xmm0 ; sp - - movss xmm0, dword ptr [rsp + 4] - call cosf - movss dword ptr [rsp + 20], xmm0 ; cy - movss xmm0, dword ptr [rsp + 4] - call sinf - movss dword ptr [rsp + 24], xmm0 ; sy - - movss xmm0, dword ptr [rsp + 8] - call cosf - movss dword ptr [rsp + 28], xmm0 ; cr - movss xmm0, dword ptr [rsp + 8] - call sinf - movss dword ptr [rsp + 32], xmm0 ; sr - - movss xmm3, dword ptr [rsp + 12] ; cp - movss xmm4, dword ptr [rsp + 16] ; sp - movss xmm5, dword ptr [rsp + 20] ; cy - movss xmm6, dword ptr [rsp + 24] ; sy - movss xmm7, dword ptr [rsp + 28] ; cr - movss xmm2, dword ptr [rsp + 32] ; xmm2 = sr - add rsp, 48 - - ; out.x = sr*cp*cy - cr*sp*sy - movss xmm0, xmm2 ; sr - mulss xmm0, xmm3 ; sr*cp - mulss xmm0, xmm5 ; sr*cp*cy - movss xmm1, xmm7 ; cr - mulss xmm1, xmm4 ; cr*sp - mulss xmm1, xmm6 ; cr*sp*sy - subss xmm0, xmm1 - movss dword ptr [rcx], xmm0 - - ; out.y = cr*sp*cy + sr*cp*sy - movss xmm0, xmm7 - mulss xmm0, xmm4 - mulss xmm0, xmm5 - movss xmm1, xmm0 ; cr*sp*cy - movss xmm0, xmm2 ; sr (saved above in xmm2) - mulss xmm0, xmm3 - mulss xmm0, xmm6 - addss xmm0, xmm1 - movss dword ptr [rcx + 4], xmm0 - - ; out.z = cr*cp*sy - sr*sp*cy - movss xmm0, xmm7 - mulss xmm0, xmm3 - mulss xmm0, xmm6 - movss xmm1, xmm0 ; cr*cp*sy - movss xmm0, xmm2 ; sr - mulss xmm0, xmm4 - mulss xmm0, xmm5 - subss xmm1, xmm0 - movss dword ptr [rcx + 8], xmm1 - - ; out.w = cr*cp*cy + sr*sp*sy - movss xmm0, xmm7 - mulss xmm0, xmm3 - mulss xmm0, xmm5 - movss xmm1, xmm0 ; cr*cp*cy - movss xmm0, xmm2 ; sr - mulss xmm0, xmm4 - mulss xmm0, xmm6 - addss xmm0, xmm1 - movss dword ptr [rcx + 12], xmm0 - - ret -quat_from_euler ENDP - -END diff --git a/Engine/Engine/ASM/math_c_fallback.h b/Engine/Engine/ASM/math_c_fallback.h deleted file mode 100644 index 722ee59..0000000 --- a/Engine/Engine/ASM/math_c_fallback.h +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -#if !defined(MATH_ASM_AVAILABLE) || MATH_ASM_AVAILABLE == 0 - -typedef struct { float x, y, z; } Vec3; -typedef struct { float x, y, z, w; } Vec4; -typedef struct { float m[4][4]; } Mat4; -typedef struct { float x, y, z, w; } Quat; - -static inline void vec3_add(const Vec3* a, const Vec3* b, Vec3* o) { o->x=a->x+b->x; o->y=a->y+b->y; o->z=a->z+b->z; } -static inline void vec3_sub(const Vec3* a, const Vec3* b, Vec3* o) { o->x=a->x-b->x; o->y=a->y-b->y; o->z=a->z-b->z; } -static inline void vec3_scale(const Vec3* a, float s, Vec3* o) { o->x=a->x*s; o->y=a->y*s; o->z=a->z*s; } -static inline float vec3_dot(const Vec3* a, const Vec3* b) { return a->x*b->x+a->y*b->y+a->z*b->z; } -static inline void vec3_cross(const Vec3* a, const Vec3* b, Vec3* o) { o->x=a->y*b->z-a->z*b->y; o->y=a->z*b->x-a->x*b->z; o->z=a->x*b->y-a->y*b->x; } -static inline float vec3_length(const Vec3* a) { return sqrtf(a->x*a->x+a->y*a->y+a->z*a->z); } -static inline void vec3_normalize(const Vec3* a, Vec3* o) { float l=vec3_length(a); if(l<1e-6f){o->x=o->y=o->z=0;return;} float i=1.0f/l; o->x=a->x*i; o->y=a->y*i; o->z=a->z*i; } -static inline void vec3_lerp(const Vec3* a, const Vec3* b, float t, Vec3* o) { o->x=a->x+(b->x-a->x)*t; o->y=a->y+(b->y-a->y)*t; o->z=a->z+(b->z-a->z)*t; } -static inline float vec3_distance(const Vec3* a, const Vec3* b) { Vec3 d; vec3_sub(a,b,&d); return vec3_length(&d); } - -static inline void mat4_identity(Mat4* o) { memset(o,0,sizeof(Mat4)); o->m[0][0]=o->m[1][1]=o->m[2][2]=o->m[3][3]=1.0f; } -static inline void mat4_multiply(const Mat4* a, const Mat4* b, Mat4* o) { Mat4 r; int i,j,k; for(i=0;i<4;i++) for(j=0;j<4;j++) { r.m[i][j]=0; for(k=0;k<4;k++) r.m[i][j]+=a->m[i][k]*b->m[k][j]; } *o=r; } -static inline void mat4_translate(float x, float y, float z, Mat4* o) { mat4_identity(o); o->m[3][0]=x; o->m[3][1]=y; o->m[3][2]=z; } -static inline void mat4_rotate_y(float angle, Mat4* o) { float c=cosf(angle),s=sinf(angle); mat4_identity(o); o->m[0][0]=c; o->m[0][2]=-s; o->m[2][0]=s; o->m[2][2]=c; } -static inline void mat4_perspective(float fov, float aspect, float nearP, float farP, Mat4* o) { float t=tanf(fov*0.5f); memset(o,0,sizeof(Mat4)); o->m[0][0]=1.0f/(aspect*t); o->m[1][1]=1.0f/t; o->m[2][2]=farP/(nearP-farP); o->m[2][3]=-1.0f; o->m[3][2]=(nearP*farP)/(nearP-farP); } -static inline void mat4_orthographic(float w, float h, float nearP, float farP, Mat4* o) { memset(o,0,sizeof(Mat4)); o->m[0][0]=2.0f/w; o->m[1][1]=2.0f/h; o->m[2][2]=1.0f/(nearP-farP); o->m[3][2]=nearP/(nearP-farP); o->m[3][3]=1.0f; } -static inline void mat4_lookat(const Vec3* eye, const Vec3* target, const Vec3* up, Mat4* o) { Vec3 f,r,u; vec3_sub(target,eye,&f); vec3_normalize(&f,&f); vec3_cross(up,&f,&r); vec3_normalize(&r,&r); vec3_cross(&f,&r,&u); mat4_identity(o); o->m[0][0]=r.x; o->m[0][1]=u.x; o->m[0][2]=-f.x; o->m[1][0]=r.y; o->m[1][1]=u.y; o->m[1][2]=-f.y; o->m[2][0]=r.z; o->m[2][1]=u.z; o->m[2][2]=-f.z; o->m[3][0]=-vec3_dot(&r,eye); o->m[3][1]=-vec3_dot(&u,eye); o->m[3][2]=vec3_dot(&f,eye); } -static inline void mat4_transpose(const Mat4* in, Mat4* out) { for (int i=0;i<4;i++) for (int j=0;j<4;j++) out->m[i][j]=in->m[j][i]; } - -static inline void quat_conjugate_raw(const Quat* q, Quat* o) { o->x=-q->x; o->y=-q->y; o->z=-q->z; o->w=q->w; } -static inline void quat_multiply(const Quat* a, const Quat* b, Quat* o) { o->x=a->w*b->x+a->x*b->w+a->y*b->z-a->z*b->y; o->y=a->w*b->y-a->x*b->z+a->y*b->w+a->z*b->x; o->z=a->w*b->z+a->x*b->y-a->y*b->x+a->z*b->w; o->w=a->w*b->w-a->x*b->x-a->y*b->y-a->z*b->z; } -static inline void quat_normalize(const Quat* q, Quat* o) { float l=sqrtf(q->x*q->x+q->y*q->y+q->z*q->z+q->w*q->w); if(l<1e-6f){*o=*q;return;} float i=1.0f/l; o->x=q->x*i; o->y=q->y*i; o->z=q->z*i; o->w=q->w*i; } -static inline void quat_rotate_vec3(const Quat* q, const Vec3* v, Vec3* o) { Quat vq={v->x,v->y,v->z,0}; Quat qinv; quat_conjugate_raw(q,&qinv); Quat tmp; quat_multiply(q,&vq,&tmp); Quat result; quat_multiply(&tmp,&qinv,&result); o->x=result.x; o->y=result.y; o->z=result.z; } -static inline void quat_to_matrix(const Quat* q, Mat4* o) { float xx=q->x*q->x,yy=q->y*q->y,zz=q->z*q->z,xy=q->x*q->y,xz=q->x*q->z,yz=q->y*q->z,wx=q->w*q->x,wy=q->w*q->y,wz=q->w*q->z; mat4_identity(o); o->m[0][0]=1-2*(yy+zz); o->m[0][1]=2*(xy+wz); o->m[0][2]=2*(xz-wy); o->m[1][0]=2*(xy-wz); o->m[1][1]=1-2*(xx+zz); o->m[1][2]=2*(yz+wx); o->m[2][0]=2*(xz+wy); o->m[2][1]=2*(yz-wx); o->m[2][2]=1-2*(xx+yy); } - -static inline void quat_from_euler(float x, float y, float z, Quat* o) { - float cx = cosf(x * 0.5f), sx = sinf(x * 0.5f); - float cy = cosf(y * 0.5f), sy = sinf(y * 0.5f); - float cz = cosf(z * 0.5f), sz = sinf(z * 0.5f); - o->w = cx * cy * cz + sx * sy * sz; - o->x = sx * cy * cz - cx * sy * sz; - o->y = cx * sy * cz + sx * cy * sz; - o->z = cx * cy * sz - sx * sy * cz; -} - -static inline void quat_to_euler(const Quat* q, float* x, float* y, float* z) { - float sinr_cosp = 2.0f * (q->w * q->x + q->y * q->z); - float cosr_cosp = 1.0f - 2.0f * (q->x * q->x + q->y * q->y); - *x = atan2f(sinr_cosp, cosr_cosp); - - float sinp = 2.0f * (q->w * q->y - q->z * q->x); - if (fabsf(sinp) >= 1.0f) *y = copysignf(1.57079633f, sinp); - else *y = asinf(sinp); - - float siny_cosp = 2.0f * (q->w * q->z + q->x * q->y); - float cosy_cosp = 1.0f - 2.0f * (q->y * q->y + q->z * q->z); - *z = atan2f(siny_cosp, cosy_cosp); -} - -static inline void* mem_aligned_alloc(uint64_t size, uint64_t alignment) { void* p; p = _aligned_malloc(size, alignment); return p; } -static inline void mem_aligned_free(void* ptr) { _aligned_free(ptr); } - -static inline void fast_memcpy(void* dst, const void* src, uint64_t count) { memcpy(dst, src, (size_t)count); } -static inline void fast_memset(void* dst, int v, uint64_t count) { memset(dst, v, (size_t)count); } -static inline uint64_t fast_strlen(const char* s) { return strlen(s); } - -static inline uint64_t prof_rdtsc(void) { LARGE_INTEGER f,t; QueryPerformanceFrequency(&f); QueryPerformanceCounter(&t); return (uint64_t)(t.QuadPart * 1000000000ULL / f.QuadPart); } -static inline double prof_cycles_to_ms(uint64_t c) { return (double)c / 1000000.0; } -static inline uint64_t prof_get_freq(void) { LARGE_INTEGER f; QueryPerformanceFrequency(&f); return (uint64_t)f.QuadPart; } - -typedef struct { uint64_t start; uint64_t end; double elapsed_ms; } ProfTimer; -static inline void prof_timer_start(ProfTimer* t) { t->start = prof_rdtsc(); } -static inline void prof_timer_stop(ProfTimer* t) { t->end = prof_rdtsc(); t->elapsed_ms = prof_cycles_to_ms(t->end - t->start); } - -#endif diff --git a/Engine/Engine/ASM/memory.asm b/Engine/Engine/ASM/memory.asm deleted file mode 100644 index 2d67468..0000000 --- a/Engine/Engine/ASM/memory.asm +++ /dev/null @@ -1,180 +0,0 @@ -; ============================================================================ -; memory.asm - 对齐内存分配器 (x86-64 MASM) -; 支持 16/32/64 字节对齐 (SIMD 需要) -; ============================================================================ - -include asm_macros.inc - -.DATA -ALIGN 16 -_alloc_header_size EQU 32 ; 分配头大小 (包含对齐偏移和原始指针) - -.CODE - -; ============================================================================ -; 对齐内存分配 -; ============================================================================ - -; void* mem_aligned_alloc(uint64_t size, uint64_t alignment) -; RCX = size, RDX = alignment -; 返回: RAX = 对齐指针 -mem_aligned_alloc PROC - push rbx - push rdi - push rsi - sub rsp, 40 ; 保留栈空间 - - mov rbx, rcx ; rbx = size - mov rdi, rdx ; rdi = alignment - - ; 验证 alignment 是 2 的幂 - mov rax, rdi - dec rax - test rdi, rax - jnz alloc_invalid_alignment - - ; 确保 alignment >= 16 - cmp rdi, 16 - jae alloc_alignment_ok - mov rdi, 16 - -alloc_alignment_ok: - ; 需要的总大小 = size + alignment + header - mov rax, rbx - add rax, rdi ; + alignment - add rax, _alloc_header_size ; + header - mov rsi, rax ; rsi = total size - - ; 调用 malloc - mov rcx, rsi - call malloc - test rax, rax - jz alloc_failed - - ; rax = 原始指针 - ; 计算对齐后的地址 - mov rcx, rax - add rcx, _alloc_header_size ; 跳过 header - ; 对齐 - mov rdx, rdi - dec rdx - not rdx - add rcx, rdx ; 加上 alignment-1 - and rcx, rdx ; 对齐到 alignment - - ; rcx = 对齐后的指针 - ; 在对齐指针前存储原始指针 - mov [rcx - 8], rax ; 存储原始 malloc 指针 - mov [rcx - 16], rbx ; 存储请求的 size - mov [rcx - 24], rdi ; 存储 alignment - mov [rcx - 32], rsi ; 存储 total size - - mov rax, rcx ; 返回对齐指针 - jmp alloc_done - -alloc_invalid_alignment: - xor rax, rax ; 返回 NULL - jmp alloc_done - -alloc_failed: - xor rax, rax - -alloc_done: - add rsp, 40 - pop rsi - pop rdi - pop rbx - ret -mem_aligned_alloc ENDP - -; void mem_aligned_free(void* ptr) -; RCX = ptr (对齐指针) -mem_aligned_free PROC - test rcx, rcx - jz free_done - - ; 获取原始 malloc 指针 - mov rax, [rcx - 8] - test rax, rax - jz free_done - - ; 调用 free - mov rcx, rax - call free - -free_done: - ret -mem_aligned_free ENDP - -; void* mem_aligned_realloc(void* ptr, uint64_t size, uint64_t alignment) -; RCX = ptr, RDX = size, R8 = alignment -; 返回: RAX = 新对齐指针 -mem_aligned_realloc PROC - push rbx - push rdi - push rsi - push r12 - sub rsp, 56 ; shadow + 3 saved qwords - - mov rbx, rdx ; rbx = new size - mov rdi, r8 ; rdi = alignment - - ; 如果 ptr 为 NULL, 直接分配 - test rcx, rcx - jz realloc_alloc - - ; 保存旧信息 - mov [rsp + 32], rcx ; 旧对齐指针(即用户数据起始) - mov rax, [rcx - 8] - mov [rsp + 24], rax ; 旧原始 malloc 指针 - mov rax, [rcx - 16] - mov [rsp + 16], rax ; 旧 size - - ; 分配新内存 - mov rcx, rbx - mov rdx, rdi - call mem_aligned_alloc - test rax, rax - jz realloc_failed - - mov rsi, rax ; rsi = 新对齐指针 - - ; 复制旧数据 (取较小值) - mov rdx, [rsp + 16] ; 旧 size - cmp rdx, rbx - jbe realloc_copy_ok - mov rdx, rbx - -realloc_copy_ok: - ; fast_memcpy(dst, src, count): rcx=dst, rdx=src, r8=count - mov rcx, rsi - mov r8, rdx - mov rdx, [rsp + 32] ; 旧对齐指针 - call fast_memcpy - - ; 释放旧内存(使用原始 malloc 指针) - mov rcx, [rsp + 24] - call mem_aligned_free - - mov rax, rsi ; 返回新指针 - jmp realloc_done - -realloc_alloc: - mov rcx, rbx - mov rdx, rdi - call mem_aligned_alloc - jmp realloc_done - -realloc_failed: - xor rax, rax - -realloc_done: - add rsp, 56 - pop r12 - pop rsi - pop rdi - pop rbx - ret -mem_aligned_realloc ENDP - -END diff --git a/Engine/Engine/ASM/profiling.asm b/Engine/Engine/ASM/profiling.asm deleted file mode 100644 index 5b15edc..0000000 --- a/Engine/Engine/ASM/profiling.asm +++ /dev/null @@ -1,148 +0,0 @@ -; ============================================================================ -; profiling.asm - 性能分析工具 (x86-64 MASM) -; 使用 RDTSC/RDTSCP 进行高精度计时 -; ============================================================================ - -include asm_macros.inc - -.DATA -ALIGN 8 -cpu_freq DQ 0 ; CPU 频率 (Hz) -cpu_freq_init DB 0 ; 是否已初始化 - -.CODE - -; ============================================================================ -; RDTSC 计时 -; ============================================================================ - -; uint64_t prof_rdtsc(void) -> RAX -; 返回: TSC (Time Stamp Counter) 值 -prof_rdtsc PROC - ; 使用 RDTSCP 获取有序的 TSC - rdtscp - ; EDX:EAX = TSC - shl rdx, 32 - or rax, rdx - ret -prof_rdtsc ENDP - -; uint64_t prof_get_freq(void) -> RAX -; 获取 CPU 频率 (Hz), 使用 QPC 校准 TSC -prof_get_freq PROC - ; 检查是否已初始化 - cmp byte ptr [cpu_freq_init], 0 - jnz prof_freq_return - - push rbx - push rdi - push rsi - sub rsp, 40 - - ; 获取 QPC 频率 - lea rcx, [rsp + 32] - call QueryPerformanceFrequency - - ; 获取起始 QPC 和 TSC - lea rcx, [rsp + 24] - call QueryPerformanceCounter - rdtscp - shl rdx, 32 - or rax, rdx - mov rbx, rax ; rbx = 起始 TSC - - ; 等待约 10ms - mov rcx, 10 ; 10 毫秒 - call Sleep - - ; 获取结束 QPC 和 TSC - lea rcx, [rsp + 16] - call QueryPerformanceCounter - rdtscp - shl rdx, 32 - or rax, rdx - mov rdi, rax ; rdi = 结束 TSC - - ; qpc_diff = end_qpc - start_qpc - mov rax, [rsp + 16] - sub rax, [rsp + 24] - mov rsi, rax ; rsi = qpc_diff - - ; tsc_diff = end_tsc - start_tsc - mov rcx, rdi - sub rcx, rbx ; rcx = tsc_diff - - ; cpu_freq = tsc_diff * qpc_freq / qpc_diff - mov rax, rcx ; rax = tsc_diff - mov rdx, [rsp + 32] ; rdx = qpc_freq - mul rdx ; rdx:rax = tsc_diff * qpc_freq - div rsi ; rax = freq (Hz) - - mov [cpu_freq], rax - mov byte ptr [cpu_freq_init], 1 - - add rsp, 40 - pop rsi - pop rdi - pop rbx - -prof_freq_return: - mov rax, [cpu_freq] - ret -prof_get_freq ENDP - -; double prof_cycles_to_ms(uint64_t cycles) -> XMM0 -; 将 TSC cycles 转换为毫秒: ms = cycles * 1000 / freq -prof_cycles_to_ms PROC - mov rdx, rcx ; 保存 cycles - call prof_get_freq ; rax = CPU freq (Hz) - - cvtsi2sd xmm0, rdx ; xmm0 = cycles (double) - mov rcx, 1000 - cvtsi2sd xmm1, rcx ; xmm1 = 1000.0 - mulsd xmm0, xmm1 ; cycles * 1000 - cvtsi2sd xmm1, rax ; xmm1 = freq - divsd xmm0, xmm1 ; ms - ret -prof_cycles_to_ms ENDP - -; ============================================================================ -; 内联性能宏 (在 C 代码中使用) -; ============================================================================ - -; 获取当前时间戳 (直接 RDTSC, 无函数调用开销) -; 在 C 中使用: __rdtsc() 内联函数 - -; 高精度计时器结构 -; struct ProfTimer { -; uint64_t start; -; uint64_t end; -; double elapsed_ms; -; }; - -; void prof_timer_start(ProfTimer* timer) -prof_timer_start PROC - rdtscp - shl rdx, 32 - or rax, rdx - mov [rcx], rax ; timer->start = tsc - ret -prof_timer_start ENDP - -; void prof_timer_stop(ProfTimer* timer) -prof_timer_stop PROC - rdtscp - shl rdx, 32 - or rax, rdx - mov [rcx + 8], rax ; timer->end = tsc - - ; 计算 elapsed_ms - mov rax, [rcx + 8] - sub rax, [rcx] ; cycles - ; 转换为 ms - call prof_cycles_to_ms - movsd qword ptr [rcx + 16], xmm0 ; timer->elapsed_ms - ret -prof_timer_stop ENDP - -END diff --git a/Engine/Engine/ASM/string_ops.asm b/Engine/Engine/ASM/string_ops.asm deleted file mode 100644 index 65dc5f0..0000000 --- a/Engine/Engine/ASM/string_ops.asm +++ /dev/null @@ -1,304 +0,0 @@ -; ============================================================================ -; string_ops.asm - 快速字符串/内存操作 (x86-64 MASM) -; 使用 SSE4.1 加速 memcpy/memset/strlen -; ============================================================================ - -include asm_macros.inc - -.CODE - -; ============================================================================ -; 内存操作 -; ============================================================================ - -; void fast_memcpy(void* dst, const void* src, uint64_t count) -; RCX = dst, RDX = src, R8 = count -fast_memcpy PROC - mov rax, rcx ; rax = dst - mov r9, r8 ; r9 = count - - ; 小于 16 字节: 逐字节复制 - cmp r9, 16 - jb memcpy_small - - ; 16-32 字节: 两次 128-bit 加载 - cmp r9, 32 - jb memcpy_16_32 - - ; 32-64 字节: 四次 128-bit 加载 - cmp r9, 64 - jb memcpy_32_64 - - ; >= 64 字节: SSE 批量复制 - ; 确保 16 字节对齐 - mov r10, rcx - and r10, 0Fh ; 检查 dst 对齐 - jnz memcpy_unaligned - -memcpy_aligned_loop: - cmp r9, 64 - jb memcpy_tail - - ; 每次复制 64 字节 (4x128-bit) - movaps xmm0, xmmword ptr [rdx] - movaps xmm1, xmmword ptr [rdx + 16] - movaps xmm2, xmmword ptr [rdx + 32] - movaps xmm3, xmmword ptr [rdx + 48] - - movaps xmmword ptr [rcx], xmm0 - movaps xmmword ptr [rcx + 16], xmm1 - movaps xmmword ptr [rcx + 32], xmm2 - movaps xmmword ptr [rcx + 48], xmm3 - - add rcx, 64 - add rdx, 64 - sub r9, 64 - jmp memcpy_aligned_loop - -memcpy_tail: - ; 处理剩余 0-63 字节 - test r9, 32 - jz memcpy_tail_16 - movaps xmm0, xmmword ptr [rdx] - movaps xmm1, xmmword ptr [rdx + 16] - movaps xmmword ptr [rcx], xmm0 - movaps xmmword ptr [rcx + 16], xmm1 - add rcx, 32 - add rdx, 32 - sub r9, 32 - -memcpy_tail_16: - test r9, 16 - jz memcpy_tail_8 - movaps xmm0, xmmword ptr [rdx] - movaps xmmword ptr [rcx], xmm0 - -memcpy_tail_8: - test r9, 8 - jz memcpy_tail_4 - mov r10, qword ptr [rdx] - mov qword ptr [rcx], r10 - -memcpy_tail_4: - test r9, 4 - jz memcpy_tail_2 - mov r10d, dword ptr [rdx] - mov dword ptr [rcx], r10d - -memcpy_tail_2: - test r9, 2 - jz memcpy_tail_1 - mov r10w, word ptr [rdx] - mov word ptr [rcx], r10w - -memcpy_tail_1: - test r9, 1 - jz memcpy_done - mov r10b, byte ptr [rdx] - mov byte ptr [rcx], r10b - jmp memcpy_done - -memcpy_unaligned: - ; 非对齐时使用 movups - movups xmm0, xmmword ptr [rdx] - movups xmmword ptr [rcx], xmm0 - add rcx, 16 - add rdx, 16 - sub r9, 16 - jmp memcpy_aligned_loop - -memcpy_32_64: - mov r10, qword ptr [rdx] - mov qword ptr [rcx], r10 - mov r10, qword ptr [rdx + 8] - mov qword ptr [rcx + 8], r10 - mov r10, qword ptr [rdx + 16] - mov qword ptr [rcx + 16], r10 - mov r10, qword ptr [rdx + 24] - mov qword ptr [rcx + 24], r10 - sub r9, 32 - add rdx, 32 - add rcx, 32 - jmp memcpy_small - -memcpy_16_32: - mov r10, qword ptr [rdx] - mov qword ptr [rcx], r10 - mov r10, qword ptr [rdx + 8] - mov qword ptr [rcx + 8], r10 - test r9, 8 - jz memcpy_16_32_done - mov r10, qword ptr [rdx + 16] - mov qword ptr [rcx + 16], r10 -memcpy_16_32_done: - jmp memcpy_done - -memcpy_small: - test r9, r9 - jz memcpy_done - - mov r10, r9 - and r10, 7 ; r10 = count % 8 - shr r9, 3 ; r9 = count / 8 - - ; 复制完整 8 字节 -memcpy_small_loop: - test r9, r9 - jz memcpy_small_tail - mov r11, qword ptr [rdx] - mov qword ptr [rcx], r11 - add rdx, 8 - add rcx, 8 - dec r9 - jmp memcpy_small_loop - -memcpy_small_tail: - ; 复制剩余字节 - test r10, r10 - jz memcpy_done - mov r11b, byte ptr [rdx] - mov byte ptr [rcx], r11b - inc rdx - inc rcx - dec r10 - jmp memcpy_small_tail - -memcpy_done: - mov rax, rax ; 返回 dst - ret -fast_memcpy ENDP - -; void fast_memset(void* dst, int value, uint64_t count) -; RCX = dst, EDX = value, R8 = count -fast_memset PROC - mov rax, rcx - mov r9, r8 - - ; 将 value 扩展到所有字节 - movsx rdx, dl ; 符号扩展 - mov rcx, rdx - shl rcx, 8 - or rdx, rcx - mov rcx, rdx - shl rcx, 16 - or rdx, rcx ; rdx = value 重复4次 - mov rcx, rdx - shl rcx, 32 - or rdx, rcx ; rdx = value 重复8次 - - ; 复制到 XMM 寄存器 - vmovq xmm0, rdx - vinsertf128 ymm0, ymm0, xmm0, 1 ; 256-bit 广播 - - ; >= 32 字节: AVX 批量 - cmp r9, 32 - jb memset_small - -memset_avx_loop: - cmp r9, 32 - jb memset_tail - - vmovdqu ymmword ptr [rax], ymm0 - add rax, 32 - sub r9, 32 - jmp memset_avx_loop - -memset_tail: - ; 处理剩余 0-31 字节 - test r9, 16 - jz memset_tail_8 - movups xmmword ptr [rax], xmm0 - add rax, 16 - sub r9, 16 - -memset_tail_8: - test r9, 8 - jz memset_tail_4 - mov qword ptr [rax], rdx - add rax, 8 - -memset_tail_4: - test r9, 4 - jz memset_tail_2 - mov dword ptr [rax], edx - add rax, 4 - -memset_tail_2: - test r9, 2 - jz memset_tail_1 - mov word ptr [rax], dx - add rax, 2 - -memset_tail_1: - test r9, 1 - jz memset_done - mov byte ptr [rax], dl - jmp memset_done - -memset_small: - test r9, r9 - jz memset_done - mov byte ptr [rax], dl - inc rax - dec r9 - jmp memset_small - -memset_done: - vzeroupper - ret -fast_memset ENDP - -; ============================================================================ -; 字符串操作 -; ============================================================================ - -; uint64_t fast_strlen(const char* str) -> RAX -; 使用 SSE4.2 PCMPESTRI 搜索 null terminator -fast_strlen PROC - mov rdx, rcx ; rdx = original str - pxor xmm0, xmm0 ; 搜索 0 - -strlen_sse_loop: - mov rax, rcx ; rax = 当前 16 字节块起始 - movdqu xmm1, xmmword ptr [rcx] - pcmpestri xmm0, xmm1, 00001000b ; 搜索 0, CF=1 表示找到, ECX=偏移 - jc strlen_found - add rcx, 16 - jmp strlen_sse_loop - -strlen_found: - ; rax = 块起始, rcx (ecx) = 块内偏移 - add rax, rcx - sub rax, rdx - ret -fast_strlen ENDP - -; int fast_strcmp(const char* a, const char* b) -> EAX -; 返回: 0=相等, <0=a0=a>b -fast_strcmp PROC - xor rax, rax - -strcmp_loop: - movzx r8d, byte ptr [rcx + rax] - movzx r9d, byte ptr [rdx + rax] - - cmp r8b, r9b - jne strcmp_diff - - test r8b, r8b - jz strcmp_equal - - inc rax - jmp strcmp_loop - -strcmp_diff: - mov eax, r8d - sub eax, r9d - ret - -strcmp_equal: - xor eax, eax - ret -fast_strcmp ENDP - -END diff --git a/Engine/Engine/Asset/mesh.h b/Engine/Engine/Asset/mesh.h deleted file mode 100644 index bdedd37..0000000 --- a/Engine/Engine/Asset/mesh.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -// ============================================================================ -// mesh.h - 网格 (顶点缓冲 + 索引缓冲) -// ============================================================================ - -#include -#include - -typedef struct { - ID3D11Buffer* vertex_buffer; - ID3D11Buffer* index_buffer; - uint32_t vertex_count; - uint32_t index_count; - uint32_t vertex_stride; -} MeshBuffer; - -// 从内存数据创建网格 -MeshBuffer* mesh_create(ID3D11Device* device, - const void* vertices, uint32_t vertex_count, uint32_t vertex_stride, - const uint32_t* indices, uint32_t index_count); - -// 从 OBJ 文件加载网格 (简化版: 仅顶点+面) -MeshBuffer* mesh_load_obj(ID3D11Device* device, const char* filepath); - -// 销毁 -void mesh_destroy(MeshBuffer* mesh); - -// 绘制 -void mesh_draw(ID3D11DeviceContext* ctx, MeshBuffer* mesh); diff --git a/Engine/Engine/Asset/texture.h b/Engine/Engine/Asset/texture.h deleted file mode 100644 index 412886d..0000000 --- a/Engine/Engine/Asset/texture.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include - -typedef struct { - ID3D11Texture2D* texture; - ID3D11ShaderResourceView* srv; - uint32_t width, height; -} Texture; - -Texture* texture_load_bmp(ID3D11Device* dev, const char* path); -Texture* texture_create_white(ID3D11Device* dev, uint32_t w, uint32_t h); -void texture_destroy(Texture* tex); diff --git a/Engine/Engine/Audio/audio.c b/Engine/Engine/Audio/audio.c deleted file mode 100644 index 71a1acd..0000000 --- a/Engine/Engine/Audio/audio.c +++ /dev/null @@ -1,277 +0,0 @@ -#include "audio.h" - -#include -#include -#include -#include - -#pragma comment(lib, "xaudio2.lib") - -// MinGW 没有 xaudio2.lib,通过系统 DLL 动态加载 XAudio2Create -typedef HRESULT (WINAPI *XAudio2CreateFunc)(IXAudio2** ppxaudio2, UINT32 flags, XAUDIO2_PROCESSOR processor); - -static HRESULT engine_xaudio2_create(IXAudio2** ppxaudio2, UINT32 flags, XAUDIO2_PROCESSOR processor) { - static HMODULE mod = NULL; - static XAudio2CreateFunc func = NULL; - if (!func) { - mod = LoadLibraryA("xaudio2_9.dll"); - if (!mod) mod = LoadLibraryA("xaudio2_8.dll"); - if (!mod) mod = LoadLibraryA("xaudio2_7.dll"); - if (mod) func = (XAudio2CreateFunc)GetProcAddress(mod, "XAudio2Create"); - } - if (!func) return E_FAIL; - return func(ppxaudio2, flags, processor); -} - -typedef struct { - WAVEFORMATEX format; - uint8_t* data; - uint32_t size; -} WavData; - -static int wav_load(const uint8_t* file_data, uint32_t file_size, WavData* out) { - memset(out, 0, sizeof(*out)); - if (file_size < 12) return 0; - if (memcmp(file_data, "RIFF", 4) != 0) return 0; - if (memcmp(file_data + 8, "WAVE", 4) != 0) return 0; - - uint32_t offset = 12; - int has_fmt = 0; - int has_data = 0; - - while (offset + 8 <= file_size) { - const uint8_t* chunk_id = file_data + offset; - uint32_t chunk_size = *(const uint32_t*)(file_data + offset + 4); - const uint8_t* chunk_data = file_data + offset + 8; - - if (offset + 8 + chunk_size > file_size) return 0; - - if (memcmp(chunk_id, "fmt ", 4) == 0 && chunk_size >= 16) { - uint32_t copy_size = chunk_size >= sizeof(WAVEFORMATEX) ? sizeof(WAVEFORMATEX) : chunk_size; - memcpy(&out->format, chunk_data, copy_size); - if (out->format.wFormatTag != WAVE_FORMAT_PCM && out->format.wFormatTag != WAVE_FORMAT_IEEE_FLOAT) { - return 0; - } - if (out->format.cbSize != 0) { - out->format.cbSize = 0; - } - has_fmt = 1; - } else if (memcmp(chunk_id, "data", 4) == 0) { - out->data = (uint8_t*)chunk_data; - out->size = chunk_size; - has_data = 1; - } - - offset += 8 + chunk_size; - if (chunk_size & 1) offset += 1; // 对齐到偶数字节 - } - - return has_fmt && has_data; -} - -AudioSystem* audio_create(void) { - CoInitializeEx(NULL, COINIT_MULTITHREADED); - - AudioSystem* audio = (AudioSystem*)calloc(1, sizeof(AudioSystem)); - if (!audio) return NULL; - - HRESULT hr = engine_xaudio2_create(&audio->xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR); - if (FAILED(hr) || !audio->xaudio2) { - free(audio); - return NULL; - } - - hr = audio->xaudio2->lpVtbl->CreateMasteringVoice( - audio->xaudio2, - &audio->mastering_voice, - XAUDIO2_DEFAULT_CHANNELS, - XAUDIO2_DEFAULT_SAMPLERATE, - 0, - NULL, - NULL, - AudioCategory_GameEffects); - if (FAILED(hr)) { - audio->xaudio2->lpVtbl->Release(audio->xaudio2); - free(audio); - return NULL; - } - - return audio; -} - -void audio_destroy(AudioSystem* audio) { - if (!audio) return; - if (audio->mastering_voice) { - audio->mastering_voice->lpVtbl->DestroyVoice(audio->mastering_voice); - } - if (audio->xaudio2) { - audio->xaudio2->lpVtbl->Release(audio->xaudio2); - } - free(audio); - CoUninitialize(); -} - -AudioSource* audio_source_create(AudioSystem* audio) { - if (!audio) return NULL; - AudioSource* source = (AudioSource*)calloc(1, sizeof(AudioSource)); - if (!source) return NULL; - source->system = audio; - source->volume = 1.0f; - source->pitch = 1.0f; - source->loop = 0; - source->state = AUDIO_STOPPED; - return source; -} - -void audio_source_destroy(AudioSource* source) { - if (!source) return; - if (source->source) { - source->source->lpVtbl->Stop(source->source, 0, XAUDIO2_COMMIT_NOW); - source->source->lpVtbl->DestroyVoice(source->source); - } - free(source->audio_data); - free(source); -} - -static int audio_source_load_data(AudioSource* source, const WavData* wav) { - if (!source || !source->system || !source->system->xaudio2) return 0; - - // 释放旧的语音与数据 - if (source->source) { - source->source->lpVtbl->Stop(source->source, 0, XAUDIO2_COMMIT_NOW); - source->source->lpVtbl->DestroyVoice(source->source); - source->source = NULL; - } - free(source->audio_data); - source->audio_data = NULL; - source->audio_size = 0; - - source->audio_data = (uint8_t*)malloc(wav->size); - if (!source->audio_data) return 0; - memcpy(source->audio_data, wav->data, wav->size); - source->audio_size = wav->size; - - HRESULT hr = source->system->xaudio2->lpVtbl->CreateSourceVoice( - source->system->xaudio2, - &source->source, - &wav->format, - 0, - XAUDIO2_DEFAULT_FREQ_RATIO, - NULL, - NULL, - NULL); - if (FAILED(hr)) { - free(source->audio_data); - source->audio_data = NULL; - source->audio_size = 0; - return 0; - } - - return 1; -} - -int audio_load_wav(AudioSource* source, const char* path) { - if (!source || !path) return 0; - - FILE* f = fopen(path, "rb"); - if (!f) return 0; - - fseek(f, 0, SEEK_END); - long file_size = ftell(f); - fseek(f, 0, SEEK_SET); - if (file_size <= 0) { - fclose(f); - return 0; - } - - uint8_t* file_data = (uint8_t*)malloc((size_t)file_size); - if (!file_data) { - fclose(f); - return 0; - } - - size_t read = fread(file_data, 1, (size_t)file_size, f); - fclose(f); - if (read != (size_t)file_size) { - free(file_data); - return 0; - } - - WavData wav; - int ok = wav_load(file_data, (uint32_t)file_size, &wav); - if (ok) { - ok = audio_source_load_data(source, &wav); - } - - free(file_data); - return ok; -} - -int audio_load_wav_memory(AudioSource* source, const uint8_t* data, uint32_t size) { - if (!source || !data || size == 0) return 0; - WavData wav; - int ok = wav_load(data, size, &wav); - if (ok) { - ok = audio_source_load_data(source, &wav); - } - return ok; -} - -void audio_source_play(AudioSource* source) { - if (!source || !source->source) return; - - XAUDIO2_BUFFER buffer = {0}; - buffer.AudioBytes = source->audio_size; - buffer.pAudioData = source->audio_data; - buffer.Flags = XAUDIO2_END_OF_STREAM; - if (source->loop) { - buffer.LoopCount = XAUDIO2_LOOP_INFINITE; - } - - source->source->lpVtbl->Stop(source->source, 0, XAUDIO2_COMMIT_NOW); - source->source->lpVtbl->FlushSourceBuffers(source->source); - source->source->lpVtbl->SubmitSourceBuffer(source->source, &buffer, NULL); - source->source->lpVtbl->Start(source->source, 0, XAUDIO2_COMMIT_NOW); - source->state = AUDIO_PLAYING; -} - -void audio_source_stop(AudioSource* source) { - if (!source || !source->source) return; - source->source->lpVtbl->Stop(source->source, 0, XAUDIO2_COMMIT_NOW); - source->source->lpVtbl->FlushSourceBuffers(source->source); - source->state = AUDIO_STOPPED; -} - -void audio_source_pause(AudioSource* source) { - if (!source || !source->source) return; - source->source->lpVtbl->Stop(source->source, 0, XAUDIO2_COMMIT_NOW); - source->state = AUDIO_PAUSED; -} - -void audio_source_resume(AudioSource* source) { - if (!source || !source->source) return; - source->source->lpVtbl->Start(source->source, 0, XAUDIO2_COMMIT_NOW); - source->state = AUDIO_PLAYING; -} - -void audio_source_set_volume(AudioSource* source, float volume) { - if (!source || !source->source) return; - source->volume = volume; - source->source->lpVtbl->SetVolume(source->source, volume, XAUDIO2_COMMIT_NOW); -} - -void audio_source_set_pitch(AudioSource* source, float pitch) { - if (!source || !source->source) return; - source->pitch = pitch; - source->source->lpVtbl->SetFrequencyRatio(source->source, pitch, XAUDIO2_COMMIT_NOW); -} - -void audio_source_set_loop(AudioSource* source, int loop) { - if (!source) return; - source->loop = loop; -} - -void audio_set_master_volume(AudioSystem* audio, float volume) { - if (!audio || !audio->mastering_voice) return; - audio->mastering_voice->lpVtbl->SetVolume(audio->mastering_voice, volume, XAUDIO2_COMMIT_NOW); -} diff --git a/Engine/Engine/Audio/audio.h b/Engine/Engine/Audio/audio.h deleted file mode 100644 index 29a8b60..0000000 --- a/Engine/Engine/Audio/audio.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -// ============================================================================ -// audio.h - 音频系统 (XAudio2) -// ============================================================================ - -#include -#include - -// 播放状态 -typedef enum { - AUDIO_STOPPED = 0, - AUDIO_PLAYING, - AUDIO_PAUSED -} AudioState; - -struct AudioSystem; - -// 音频源 -typedef struct { - struct AudioSystem* system; - IXAudio2SourceVoice* source; - IXAudio2Voice* mastering; - float volume; - float pitch; - int loop; - AudioState state; - uint8_t* audio_data; - uint32_t audio_size; -} AudioSource; - -// 音频管理器 -typedef struct AudioSystem { - IXAudio2* xaudio2; - IXAudio2MasteringVoice* mastering_voice; -} AudioSystem; - -// 初始化/销毁 -AudioSystem* audio_create(void); -void audio_destroy(AudioSystem* audio); - -// 音频源 -AudioSource* audio_source_create(AudioSystem* audio); -void audio_source_destroy(AudioSource* source); - -// 播放 -void audio_source_play(AudioSource* source); -void audio_source_stop(AudioSource* source); -void audio_source_pause(AudioSource* source); -void audio_source_resume(AudioSource* source); - -// 音量/音调 -void audio_source_set_volume(AudioSource* source, float volume); -void audio_source_set_pitch(AudioSource* source, float pitch); -void audio_source_set_loop(AudioSource* source, int loop); - -// WAV加载 -int audio_load_wav(AudioSource* source, const char* path); -int audio_load_wav_memory(AudioSource* source, const uint8_t* data, uint32_t size); - -// 主音量 -void audio_set_master_volume(AudioSystem* audio, float volume); diff --git a/Engine/Engine/Core/asset_manager.c b/Engine/Engine/Core/asset_manager.c deleted file mode 100644 index f8adaea..0000000 --- a/Engine/Engine/Core/asset_manager.c +++ /dev/null @@ -1,192 +0,0 @@ -#include "asset_manager.h" -#include "../Rendering/mesh.h" -#include "../Rendering/texture.h" -#include "../Rendering/shader.h" -#include -#include -#include - -#define ASSET_BUCKET_COUNT 256 - -struct AssetManager { - Asset* buckets[ASSET_BUCKET_COUNT]; - uint32_t next_id; -}; - -static uint32_t hash_str(const char* s) { - uint32_t h = 5381; - while (*s) h = ((h << 5) + h) + (unsigned char)*s++; - return h % ASSET_BUCKET_COUNT; -} - -static int str_ends_with(const char* s, const char* suffix) { - size_t ls = strlen(s), lf = strlen(suffix); - return ls >= lf && strcmp(s + ls - lf, suffix) == 0; -} - -static Asset* asset_alloc(AssetManager* am, AssetType type, const char* path, void* data, void (*destroy)(void*)) { - Asset* a = (Asset*)calloc(1, sizeof(Asset)); - a->id = ++am->next_id; - a->type = type; - a->refcount = 1; - a->owner = am; - strncpy(a->path, path, sizeof(a->path) - 1); - a->data = data; - a->destroy = destroy; - - uint32_t h = hash_str(path); - a->next = am->buckets[h]; - am->buckets[h] = a; - return a; -} - -static void asset_free(AssetManager* am, Asset* a) { - if (!a) return; - uint32_t h = hash_str(a->path); - Asset** cur = &am->buckets[h]; - while (*cur) { - if (*cur == a) { - *cur = a->next; - break; - } - cur = &(*cur)->next; - } - if (a->destroy) a->destroy(a->data); - free(a); -} - -AssetManager* asset_manager_create(void) { - AssetManager* am = (AssetManager*)calloc(1, sizeof(AssetManager)); - return am; -} - -void asset_manager_destroy(AssetManager* am) { - if (!am) return; - for (int i = 0; i < ASSET_BUCKET_COUNT; i++) { - Asset* a = am->buckets[i]; - while (a) { - Asset* next = a->next; - if (a->destroy) a->destroy(a->data); - free(a); - a = next; - } - } - free(am); -} - -Asset* asset_manager_find(AssetManager* am, const char* path) { - if (!am || !path) return NULL; - uint32_t h = hash_str(path); - for (Asset* a = am->buckets[h]; a; a = a->next) { - if (strcmp(a->path, path) == 0) return a; - } - return NULL; -} - -Asset* asset_manager_get(AssetManager* am, uint32_t id) { - if (!am || id == 0) return NULL; - for (int i = 0; i < ASSET_BUCKET_COUNT; i++) { - for (Asset* a = am->buckets[i]; a; a = a->next) { - if (a->id == id) return a; - } - } - return NULL; -} - -void* asset_data(Asset* a) { return a ? a->data : NULL; } - -void asset_acquire(Asset* a) { if (a) a->refcount++; } - -void asset_release(Asset* a) { - if (!a) return; - a->refcount--; - if (a->refcount <= 0 && a->owner) { - asset_free(a->owner, a); - } -} - -// ------------------------------------------------------------------ -// Mesh -// ------------------------------------------------------------------ -static void destroy_mesh_asset(void* data) { mesh_destroy((Mesh*)data); } - -Asset* asset_manager_load_mesh(AssetManager* am, ID3D11Device* dev, const char* path) { - if (!am || !dev || !path) return NULL; - Asset* existing = asset_manager_find(am, path); - if (existing) { asset_acquire(existing); return existing; } - - Mesh* mesh = NULL; - if (strcmp(path, "cube") == 0) mesh = mesh_create_cube(dev); - else if (strcmp(path, "sphere") == 0) mesh = mesh_create_sphere(dev, 1.0f, 16); - else if (strcmp(path, "plane") == 0) mesh = mesh_create_plane(dev, 10.0f); - else if (str_ends_with(path, ".obj")) mesh = mesh_load_obj(dev, path); - - if (!mesh) return NULL; - return asset_alloc(am, ASSET_MESH, path, mesh, destroy_mesh_asset); -} - -// ------------------------------------------------------------------ -// Texture -// ------------------------------------------------------------------ -static void destroy_texture_asset(void* data) { texture_destroy((Texture*)data); } - -Asset* asset_manager_load_texture(AssetManager* am, ID3D11Device* dev, const char* path) { - if (!am || !dev || !path) return NULL; - Asset* existing = asset_manager_find(am, path); - if (existing) { asset_acquire(existing); return existing; } - - Texture* tex = NULL; - if (strcmp(path, "checkerboard") == 0) tex = texture_create_checkerboard(dev, 256, 8); - else tex = texture_load_from_file(dev, path); - - if (!tex) return NULL; - return asset_alloc(am, ASSET_TEXTURE, path, tex, destroy_texture_asset); -} - -// ------------------------------------------------------------------ -// Shader -// ------------------------------------------------------------------ -static void destroy_shader_asset(void* data) { shader_destroy((Shader*)data); } - -static char* read_file(const char* path, uint32_t* out_len) { - FILE* f = fopen(path, "rb"); - if (!f) return NULL; - fseek(f, 0, SEEK_END); - long size = ftell(f); - fseek(f, 0, SEEK_SET); - if (size <= 0) { fclose(f); return NULL; } - char* buf = (char*)malloc((size_t)size + 1); - if (!buf) { fclose(f); return NULL; } - fread(buf, 1, (size_t)size, f); - buf[size] = '\0'; - fclose(f); - if (out_len) *out_len = (uint32_t)size; - return buf; -} - -Asset* asset_manager_load_shader(AssetManager* am, ID3D11Device* dev, const char* vs_path, const char* ps_path) { - if (!am || !dev) return NULL; - - char key[512]; - if (vs_path && ps_path) snprintf(key, sizeof(key), "%s|%s", vs_path, ps_path); - else strcpy(key, "default"); - - Asset* existing = asset_manager_find(am, key); - if (existing) { asset_acquire(existing); return existing; } - - Shader* s = shader_create(); - if (vs_path && ps_path) { - uint32_t vs_len = 0, ps_len = 0; - char* vs = read_file(vs_path, &vs_len); - char* ps = read_file(ps_path, &ps_len); - if (!vs || !ps || !shader_compile(s, dev, vs, ps, vs_len, ps_len)) { - shader_destroy(s); free(vs); free(ps); return NULL; - } - free(vs); free(ps); - } else { - if (!shader_compile(s, dev, NULL, NULL, 0, 0)) { - shader_destroy(s); return NULL; - } - } - return asset_alloc(am, ASSET_SHADER, key, s, destroy_shader_asset); -} diff --git a/Engine/Engine/Core/asset_manager.h b/Engine/Engine/Core/asset_manager.h deleted file mode 100644 index 415d6ef..0000000 --- a/Engine/Engine/Core/asset_manager.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct AssetManager AssetManager; -typedef struct Asset Asset; - -typedef enum { - ASSET_MESH = 0, - ASSET_TEXTURE, - ASSET_SHADER, - ASSET_MATERIAL, - ASSET_COUNT -} AssetType; - -struct Asset { - uint32_t id; - AssetType type; - int refcount; - char path[256]; - void* data; - void (*destroy)(void* data); - Asset* next; - struct AssetManager* owner; -}; - -AssetManager* asset_manager_create(void); -void asset_manager_destroy(AssetManager* am); - -Asset* asset_manager_load_mesh(AssetManager* am, ID3D11Device* dev, const char* path); -Asset* asset_manager_load_texture(AssetManager* am, ID3D11Device* dev, const char* path); -Asset* asset_manager_load_shader(AssetManager* am, ID3D11Device* dev, const char* vs_path, const char* ps_path); - -Asset* asset_manager_find(AssetManager* am, const char* path); -Asset* asset_manager_get(AssetManager* am, uint32_t id); - -void* asset_data(Asset* a); -void asset_acquire(Asset* a); -void asset_release(Asset* a); - -#ifdef __cplusplus -} -#endif diff --git a/Engine/Engine/Core/engine.c b/Engine/Engine/Core/engine.c deleted file mode 100644 index 2a08bbb..0000000 --- a/Engine/Engine/Core/engine.c +++ /dev/null @@ -1,244 +0,0 @@ -// ============================================================================ -// engine.c - 引擎核心实现 -// ============================================================================ - -#include "engine.h" -#include "logger.h" -#include "timer.h" -#include "../Window/window.h" -#include "../Rendering/renderer.h" -#include "../Rendering/graphics_device.h" -#include "../include/engine_api.h" -#include -#include - -// 引擎实例 (单例) -static Engine g_engine = {0}; - -// 回调 -static EngineUpdateCallback g_update_callback = NULL; -static EngineRenderCallback g_render_callback = NULL; -static EngineKeyCallback g_key_callback = NULL; -static EngineResizeCallback g_resize_callback = NULL; -static EngineMouseMoveCallback g_mouse_move_callback = NULL; -static EngineMouseButtonCallback g_mouse_button_callback = NULL; - -// 内部函数 -static void on_key(int key) { - if (g_key_callback) { - g_key_callback(&g_engine, key); - } - if (key == VK_ESCAPE) { - engine_request_quit(&g_engine); - } -} - -static void on_resize(int width, int height) { - if (g_resize_callback) { - g_resize_callback(&g_engine, width, height); - } -} - -static void on_mouse_move(int x, int y) { - if (g_mouse_move_callback) { - g_mouse_move_callback(&g_engine, x, y); - } -} - -static void on_mouse_button(int button, int pressed) { - if (g_mouse_button_callback) { - g_mouse_button_callback(&g_engine, button, pressed); - } -} - -Engine* engine_create(void) { - return &g_engine; -} - -void engine_destroy(Engine* engine) { - if (engine) { - engine_shutdown(engine); - } -} - -int engine_init(Engine* engine, const EngineConfig* config) { - if (engine->initialized) return 1; - - engine->config = *config; - - // 初始化日志 - logger_init("engine.log"); - LOG_INFO("Initializing Lity3D Engine..."); - - // 初始化计时器 - timer_init(); - - // 创建窗口 - engine->window = window_create( - config->app_name, - config->window_width, - config->window_height, - config->fullscreen - ); - - if (!engine->window) { - LOG_ERROR("Failed to create window!"); - return 0; - } - - // 设置回调 - window_set_key_callback(engine->window, on_key); - window_set_resize_callback(engine->window, on_resize); - window_set_mouse_move_callback(engine->window, on_mouse_move); - window_set_mouse_button_callback(engine->window, on_mouse_button); - - LOG_INFO("Window created: %dx%d", config->window_width, config->window_height); - - // 创建 D3D11 图形设备 - engine->graphics_device = graphics_device_create(); - if (!graphics_device_init(engine->graphics_device, - window_get_handle(engine->window), - config->window_width, - config->window_height, - config->vsync)) { - LOG_ERROR("Failed to initialize D3D11 graphics device!"); - window_destroy(engine->window); - engine->window = NULL; - return 0; - } - - // 创建渲染器 - engine->renderer = renderer_create(engine->graphics_device); - if (!engine->renderer) { - LOG_ERROR("Failed to create renderer!"); - graphics_device_destroy(engine->graphics_device); - engine->graphics_device = NULL; - window_destroy(engine->window); - engine->window = NULL; - return 0; - } - - LOG_INFO("Graphics device and renderer ready."); - - engine->initialized = 1; - engine->running = 1; - engine->frame_count = 0; - - LOG_INFO("Lity3D Engine initialized successfully."); - return 1; -} - -void engine_run(Engine* engine) { - if (!engine->initialized) { - LOG_ERROR("Engine not initialized!"); - return; - } - - double fixed_dt = 1.0 / 60.0; // 60Hz 固定时间步 - double accumulator = 0.0; - double fps_timer = 0.0; - int fps_frames = 0; - int fps_display = 0; - - while (engine->running) { - // 处理窗口消息 - if (!window_process_messages(engine->window)) { - engine->running = 0; - break; - } - - // 更新计时 - timer_tick(); - engine->delta_time = timer_get_delta(); - engine->total_time += engine->delta_time; - engine->frame_count++; - - // FPS 计算 - fps_timer += engine->delta_time; - fps_frames++; - if (fps_timer >= 1.0) { - fps_display = fps_frames; - fps_frames = 0; - fps_timer -= 1.0; - } - - // 固定时间步逻辑更新 - accumulator += engine->delta_time; - while (accumulator >= fixed_dt) { - if (g_update_callback) { - g_update_callback(engine, fixed_dt); - } - accumulator -= fixed_dt; - } - - // 渲染 - if (g_render_callback) { - g_render_callback(engine); - } - - // 存储 FPS 供外部读取 - engine->fps = fps_display; - } -} - -void engine_shutdown(Engine* engine) { - if (!engine->initialized) return; - - LOG_INFO("Shutting down Lity3D Engine..."); - - if (engine->renderer) { - renderer_destroy(engine->renderer); - engine->renderer = NULL; - } - - if (engine->graphics_device) { - graphics_device_destroy(engine->graphics_device); - engine->graphics_device = NULL; - } - - if (engine->window) { - window_destroy(engine->window); - engine->window = NULL; - } - - logger_shutdown(); - engine->initialized = 0; - engine->running = 0; -} - -void engine_request_quit(Engine* engine) { - engine->running = 0; -} - -// 回调设置 -void engine_set_update_callback(Engine* engine, EngineUpdateCallback callback) { - g_update_callback = callback; -} - -void engine_set_render_callback(Engine* engine, EngineRenderCallback callback) { - g_render_callback = callback; -} - -void engine_set_key_callback(Engine* engine, EngineKeyCallback callback) { - g_key_callback = callback; -} - -void engine_set_resize_callback(Engine* engine, EngineResizeCallback callback) { - g_resize_callback = callback; -} - -void engine_set_mouse_move_callback(Engine* engine, EngineMouseMoveCallback callback) { - g_mouse_move_callback = callback; -} - -void engine_set_mouse_button_callback(Engine* engine, EngineMouseButtonCallback callback) { - g_mouse_button_callback = callback; -} - -GraphicsDevice* engine_get_graphics_device(Engine* engine) { - return engine ? engine->graphics_device : NULL; -} - -Renderer* engine_get_renderer(Engine* engine) { - return engine ? (Renderer*)engine->renderer : NULL; -} diff --git a/Engine/Engine/Core/engine.h b/Engine/Engine/Core/engine.h deleted file mode 100644 index 5196776..0000000 --- a/Engine/Engine/Core/engine.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -// ============================================================================ -// engine.h - 引擎核心 -// ============================================================================ - -#include - -// 前向声明 -typedef struct Window Window; -typedef struct GraphicsDevice GraphicsDevice; -typedef struct Renderer Renderer; - -// 引擎配置 -typedef struct { - const char* app_name; - int window_width; - int window_height; - int fullscreen; - int vsync; -} EngineConfig; - -// 引擎状态 -typedef struct { - int running; - int initialized; - EngineConfig config; - Window* window; - void* renderer; - GraphicsDevice* graphics_device; - double delta_time; - double total_time; - int fps; - uint64_t frame_count; -} Engine; - -// 初始化默认配置 -static inline EngineConfig engine_default_config(void) { - EngineConfig config; - config.app_name = "Lity3D Engine"; - config.window_width = 1280; - config.window_height = 720; - config.fullscreen = 0; - config.vsync = 1; - return config; -} - -// 引擎函数 -Engine* engine_create(void); -void engine_destroy(Engine* engine); -int engine_init(Engine* engine, const EngineConfig* config); -void engine_run(Engine* engine); -void engine_shutdown(Engine* engine); -void engine_request_quit(Engine* engine); - -// 回调 -typedef void (*EngineUpdateCallback)(Engine* engine, double delta_time); -typedef void (*EngineRenderCallback)(Engine* engine); -typedef void (*EngineKeyCallback)(Engine* engine, int key); -typedef void (*EngineResizeCallback)(Engine* engine, int width, int height); -typedef void (*EngineMouseMoveCallback)(Engine* engine, int x, int y); -typedef void (*EngineMouseButtonCallback)(Engine* engine, int button, int pressed); - -void engine_set_update_callback(Engine* engine, EngineUpdateCallback callback); -void engine_set_render_callback(Engine* engine, EngineRenderCallback callback); -void engine_set_key_callback(Engine* engine, EngineKeyCallback callback); -void engine_set_resize_callback(Engine* engine, EngineResizeCallback callback); -void engine_set_mouse_move_callback(Engine* engine, EngineMouseMoveCallback callback); -void engine_set_mouse_button_callback(Engine* engine, EngineMouseButtonCallback callback); - -// 子系统访问 -GraphicsDevice* engine_get_graphics_device(Engine* engine); -Renderer* engine_get_renderer(Engine* engine); diff --git a/Engine/Engine/Core/logger.c b/Engine/Engine/Core/logger.c deleted file mode 100644 index f89f7a3..0000000 --- a/Engine/Engine/Core/logger.c +++ /dev/null @@ -1,73 +0,0 @@ -// ============================================================================ -// logger.c - 日志系统实现 -// ============================================================================ - -#include "logger.h" -#include -#include -#include -#include - -static FILE* g_log_file = NULL; -static LogLevel g_log_level = LOG_TRACE; - -static const char* level_strings[] = { - "TRACE", "DEBUG", "INFO ", "WARN ", "ERROR", "FATAL" -}; - -void logger_init(const char* log_file) { - if (log_file) { - g_log_file = fopen(log_file, "w"); - if (g_log_file) { - fprintf(g_log_file, "=== Lity3D Engine Log ===\n"); - fflush(g_log_file); - } - } - printf("=== Lity3D Engine Log ===\n"); -} - -void logger_shutdown(void) { - if (g_log_file) { - fclose(g_log_file); - g_log_file = NULL; - } -} - -void logger_set_level(LogLevel level) { - g_log_level = level; -} - -void logger_log(LogLevel level, const char* file, int line, const char* fmt, ...) { - if (level < g_log_level) return; - - // 时间戳 - time_t now = time(NULL); - struct tm* tm_info = localtime(&now); - char time_str[20]; - strftime(time_str, sizeof(time_str), "%H:%M:%S", tm_info); - - // 文件名 (去掉路径) - const char* filename = strrchr(file, '\\'); - if (!filename) filename = strrchr(file, '/'); - if (filename) filename++; else filename = file; - - // 格式化消息 - char msg[2048]; - va_list args; - va_start(args, fmt); - vsnprintf(msg, sizeof(msg), fmt, args); - va_end(args); - - // 输出到控制台 - if (level >= LOG_WARN) { - fprintf(stderr, "[%s] [%s] %s:%d - %s\n", time_str, level_strings[level], filename, line, msg); - } else { - printf("[%s] [%s] %s:%d - %s\n", time_str, level_strings[level], filename, line, msg); - } - - // 输出到文件 - if (g_log_file) { - fprintf(g_log_file, "[%s] [%s] %s:%d - %s\n", time_str, level_strings[level], filename, line, msg); - fflush(g_log_file); - } -} diff --git a/Engine/Engine/Core/logger.h b/Engine/Engine/Core/logger.h deleted file mode 100644 index 06b43e9..0000000 --- a/Engine/Engine/Core/logger.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -// ============================================================================ -// logger.h - 日志系统 -// ============================================================================ - -#include - -// 日志级别 -typedef enum { - LOG_TRACE = 0, - LOG_DEBUG, - LOG_INFO, - LOG_WARN, - LOG_ERROR, - LOG_FATAL -} LogLevel; - -// 初始化/关闭 -void logger_init(const char* log_file); -void logger_shutdown(void); - -// 设置日志级别 -void logger_set_level(LogLevel level); - -// 日志函数 -void logger_log(LogLevel level, const char* file, int line, const char* fmt, ...); - -// 便捷宏 -#define LOG_TRACE(...) logger_log(LOG_TRACE, __FILE__, __LINE__, __VA_ARGS__) -#define LOG_DEBUG(...) logger_log(LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__) -#define LOG_INFO(...) logger_log(LOG_INFO, __FILE__, __LINE__, __VA_ARGS__) -#define LOG_WARN(...) logger_log(LOG_WARN, __FILE__, __LINE__, __VA_ARGS__) -#define LOG_ERROR(...) logger_log(LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__) -#define LOG_FATAL(...) logger_log(LOG_FATAL, __FILE__, __LINE__, __VA_ARGS__) diff --git a/Engine/Engine/Core/timer.c b/Engine/Engine/Core/timer.c deleted file mode 100644 index 96516df..0000000 --- a/Engine/Engine/Core/timer.c +++ /dev/null @@ -1,78 +0,0 @@ -// ============================================================================ -// timer.c - 高精度计时器实现 (使用 rdtsc.asm) -// ============================================================================ - -#include "timer.h" -#include "../include/engine_api.h" -#include - -static double g_seconds_per_count = 0.0; -static int64_t g_prev_time = 0; -static int64_t g_curr_time = 0; -static int64_t g_start_time = 0; -static double g_delta_time = 0.0; -static double g_total_time = 0.0; -static double g_fps = 0.0; -static uint64_t g_frame_count = 0; -static double g_fps_accumulator = 0.0; -static uint64_t g_fps_frame_count = 0; - -void timer_init(void) { - // 使用 QueryPerformanceCounter 获取高精度时间 - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - g_seconds_per_count = 1.0 / (double)freq.QuadPart; - - LARGE_INTEGER now; - QueryPerformanceCounter(&now); - g_start_time = now.QuadPart; - g_prev_time = now.QuadPart; - g_curr_time = now.QuadPart; - - g_delta_time = 0.0; - g_total_time = 0.0; - g_fps = 0.0; - g_frame_count = 0; - g_fps_accumulator = 0.0; - g_fps_frame_count = 0; -} - -void timer_reset(void) { - timer_init(); -} - -void timer_tick(void) { - LARGE_INTEGER now; - QueryPerformanceCounter(&now); - g_curr_time = now.QuadPart; - - g_delta_time = (g_curr_time - g_prev_time) * g_seconds_per_count; - g_total_time = (g_curr_time - g_start_time) * g_seconds_per_count; - g_prev_time = g_curr_time; - - g_frame_count++; - g_fps_frame_count++; - g_fps_accumulator += g_delta_time; - - if (g_fps_accumulator >= 1.0) { - g_fps = (double)g_fps_frame_count / g_fps_accumulator; - g_fps_frame_count = 0; - g_fps_accumulator = 0.0; - } -} - -double timer_get_delta(void) { - return g_delta_time; -} - -double timer_get_total(void) { - return g_total_time; -} - -double timer_get_fps(void) { - return g_fps; -} - -uint64_t timer_get_frame_count(void) { - return g_frame_count; -} diff --git a/Engine/Engine/Core/timer.h b/Engine/Engine/Core/timer.h deleted file mode 100644 index 92aa452..0000000 --- a/Engine/Engine/Core/timer.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -// ============================================================================ -// timer.h - 高精度计时器 -// ============================================================================ - -#include - -// 初始化计时器 -void timer_init(void); - -// 重置计时器 -void timer_reset(void); - -// 更新一帧 -void timer_tick(void); - -// 获取帧间隔 (秒) -double timer_get_delta(void); - -// 获取总时间 (秒) -double timer_get_total(void); - -// 获取 FPS -double timer_get_fps(void); - -// 获取帧数 -uint64_t timer_get_frame_count(void); diff --git a/Engine/Engine/ECS/world.c b/Engine/Engine/ECS/world.c deleted file mode 100644 index d91fd46..0000000 --- a/Engine/Engine/ECS/world.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "world.h" - -#include -#include - -World* world_create(void) { - World* w = (World*)calloc(1, sizeof(World)); - w->next_entity = 1; - return w; -} - -void world_destroy(World* world) { - if (!world) return; - for (uint32_t i = 0; i < world->entity_count; i++) { - Entity e = world->entities[i]; - for (uint32_t c = 0; c < world->component_count; c++) { - if (world->components[c][e] && world->component_tables[c].destroy) { - world->component_tables[c].destroy(world->components[c][e]); - } - free(world->components[c][e]); - } - } - free(world); -} - -Entity world_create_entity(World* world) { - if (world->entity_count >= MAX_ENTITIES) return 0; - Entity e = world->next_entity++; - world->entities[world->entity_count++] = e; - world->entity_masks[e] = 0; - return e; -} - -void world_destroy_entity(World* world, Entity entity) { - for (uint32_t c = 0; c < world->component_count; c++) { - if (world->components[c][entity] && world->component_tables[c].destroy) { - world->component_tables[c].destroy(world->components[c][entity]); - } - free(world->components[c][entity]); - world->components[c][entity] = NULL; - } - world->entity_masks[entity] = 0; - - for (uint32_t i = 0; i < world->entity_count; i++) { - if (world->entities[i] == entity) { - world->entities[i] = world->entities[--world->entity_count]; - break; - } - } -} - -int world_entity_alive(World* world, Entity entity) { - for (uint32_t i = 0; i < world->entity_count; i++) { - if (world->entities[i] == entity) return 1; - } - return 0; -} - -ComponentType world_register_component(World* world, uint32_t size, ComponentVTable vtable) { - ComponentType type = world->component_count++; - world->component_sizes[type] = size; - world->component_tables[type] = vtable; - return type; -} - -void* world_add_component(World* world, Entity entity, ComponentType type) { - if (world->components[type][entity]) return world->components[type][entity]; - void* comp = calloc(1, world->component_sizes[type]); - world->components[type][entity] = comp; - world->entity_masks[entity] |= (1ULL << type); - return comp; -} - -void* world_get_component(World* world, Entity entity, ComponentType type) { - return world->components[type][entity]; -} - -void world_remove_component(World* world, Entity entity, ComponentType type) { - if (world->components[type][entity]) { - if (world->component_tables[type].destroy) { - world->component_tables[type].destroy(world->components[type][entity]); - } - free(world->components[type][entity]); - world->components[type][entity] = NULL; - world->entity_masks[entity] &= ~(1ULL << type); - } -} - -int world_has_component(World* world, Entity entity, ComponentType type) { - return (world->entity_masks[entity] & (1ULL << type)) != 0; -} - -void world_each(World* world, uint64_t mask, SystemFunc func, void* data) { - for (uint32_t i = 0; i < world->entity_count; i++) { - Entity e = world->entities[i]; - if ((world->entity_masks[e] & mask) == mask) { - func(world, e, data); - } - } -} diff --git a/Engine/Engine/ECS/world.h b/Engine/Engine/ECS/world.h deleted file mode 100644 index 2803ee5..0000000 --- a/Engine/Engine/ECS/world.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -// ============================================================================ -// world.h - 实体组件系统 (ECS) -// ============================================================================ - -#include -#include "../include/engine_api.h" - -#define MAX_ENTITIES 4096 -#define MAX_COMPONENTS 32 - -typedef uint32_t Entity; -typedef uint32_t ComponentType; - -// 组件接口 -typedef struct { - void (*destroy)(void* component); -} ComponentVTable; - -// 世界 -typedef struct { - Entity entities[MAX_ENTITIES]; - uint32_t entity_count; - uint32_t next_entity; - - void* components[MAX_COMPONENTS][MAX_ENTITIES]; - ComponentVTable component_tables[MAX_COMPONENTS]; - uint32_t component_sizes[MAX_COMPONENTS]; - uint32_t component_count; - - uint64_t entity_masks[MAX_ENTITIES]; -} World; - -// 创建/销毁 -World* world_create(void); -void world_destroy(World* world); - -// 实体 -Entity world_create_entity(World* world); -void world_destroy_entity(World* world, Entity entity); -int world_entity_alive(World* world, Entity entity); - -// 组件 -ComponentType world_register_component(World* world, uint32_t size, ComponentVTable vtable); -void* world_add_component(World* world, Entity entity, ComponentType type); -void* world_get_component(World* world, Entity entity, ComponentType type); -void world_remove_component(World* world, Entity entity, ComponentType type); -int world_has_component(World* world, Entity entity, ComponentType type); - -// 系统遍历 -typedef void (*SystemFunc)(World* world, Entity entity, void* data); -void world_each(World* world, uint64_t mask, SystemFunc func, void* data); diff --git a/Engine/Engine/Editor/bitmap_font.c b/Engine/Engine/Editor/bitmap_font.c deleted file mode 100644 index c75c2ce..0000000 --- a/Engine/Engine/Editor/bitmap_font.c +++ /dev/null @@ -1,303 +0,0 @@ -#include "bitmap_font.h" -#include -#include -#include "../Core/logger.h" - -static const uint8_t FONT_DATA[FONT_NUM_CHARS][FONT_CHAR_H] = { - {0},{0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, - {0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, - {0x18,0x18,0x7C,0xC6,0xC2,0xC0,0x7C,0x06,0x06,0x86,0xC6,0x7C,0x18,0x18,0x00,0x00}, - {0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00}, - {0x00,0x30,0x30,0x30,0x70,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0xCE,0xDE,0xF6,0xE6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00}, - {0},{0},{0}, - {0x00,0x00,0x00,0x0C,0x18,0x30,0x60,0xC0,0x60,0x30,0x18,0x0C,0x00,0x00,0x00,0x00}, - {0},{0}, - {0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, - {0},{0},{0},{0},{0},{0},{0},{0},{0}, - {0x00,0x00,0x7C,0xC6,0xC6,0xCE,0xDE,0xF6,0xE6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x0C,0x18,0x30,0x60,0xC0,0x60,0x30,0x18,0x0C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x7C,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xE6,0x66,0x66,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00}, - {0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFF,0xDB,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xC6,0x6C,0x7C,0x38,0x38,0x7C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xC6,0xC6,0xC6,0x6C,0x38,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0xFE,0xC6,0x86,0x0C,0x18,0x30,0x60,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x06,0x02,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00}, - {0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00}, -}; - -static Shader* g_font_shader = NULL; -static ID3D11Buffer* g_font_vb = NULL; -static ID3D11Buffer* g_font_ib = NULL; -static FontVert g_font_verts[FONT_MAX_QUADS * 4]; -static uint32_t g_font_indices[FONT_MAX_QUADS * 6]; -static int g_font_vi = 0; -static int g_font_ii = 0; - -static void make_ortho(float* m, float sw, float sh) { - memset(m, 0, 64); - m[0] = 2.0f / sw; - m[5] = -2.0f / sh; - m[10] = 1.0f; - m[12] = -1.0f; - m[13] = 1.0f; - m[15] = 1.0f; -} - -static void make_atlas(uint8_t* pixels, int w, int h) { - memset(pixels, 0, (size_t)w * h * 4); - int cols = w / FONT_CHAR_W; - for (int i = 0; i < FONT_NUM_CHARS; i++) { - int cx = (i % cols) * FONT_CHAR_W; - int cy = (i / cols) * FONT_CHAR_H; - for (int row = 0; row < FONT_CHAR_H; row++) { - uint8_t bits = FONT_DATA[i][row]; - for (int col = 0; col < 8; col++) { - if (bits & (0x80 >> col)) { - int px = cx + col, py = cy + row; - int idx = (py * w + px) * 4; - pixels[idx] = 255; pixels[idx+1] = 255; pixels[idx+2] = 255; pixels[idx+3] = 255; - } - } - } - } -} - -int bitmap_font_init(BitmapFont* f, ID3D11Device* dev) { - memset(f, 0, sizeof(*f)); - int cols = 16; - f->atlas_w = cols * FONT_CHAR_W; - f->atlas_h = ((FONT_NUM_CHARS + cols - 1) / cols) * FONT_CHAR_H; - - uint8_t* pixels = (uint8_t*)malloc((size_t)f->atlas_w * f->atlas_h * 4); - make_atlas(pixels, f->atlas_w, f->atlas_h); - - D3D11_TEXTURE2D_DESC td = {0}; - td.Width = (UINT)f->atlas_w; td.Height = (UINT)f->atlas_h; - td.MipLevels = 1; td.ArraySize = 1; - td.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - td.SampleDesc.Count = 1; - td.Usage = D3D11_USAGE_DEFAULT; - td.BindFlags = D3D11_BIND_SHADER_RESOURCE; - D3D11_SUBRESOURCE_DATA sd = {0}; - sd.pSysMem = pixels; sd.SysMemPitch = (UINT)(f->atlas_w * 4); - HRESULT hr = dev->lpVtbl->CreateTexture2D(dev, &td, &sd, &f->texture); - free(pixels); - if (FAILED(hr)) return 0; - dev->lpVtbl->CreateShaderResourceView(dev, (ID3D11Resource*)f->texture, NULL, &f->srv); - - f->shader = shader_create(); - if (!shader_compile(f->shader, dev, NULL, NULL, 0, 0)) return 0; - g_font_shader = f->shader; - - D3D11_BUFFER_DESC bd = {0}; - bd.ByteWidth = FONT_MAX_QUADS * 4 * sizeof(FontVert); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - memset(g_font_verts, 0, sizeof(g_font_verts)); - sd.pSysMem = g_font_verts; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &g_font_vb); - - bd.ByteWidth = FONT_MAX_QUADS * 6 * sizeof(uint32_t); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - memset(g_font_indices, 0, sizeof(g_font_indices)); - sd.pSysMem = g_font_indices; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &g_font_ib); - - bd.ByteWidth = 256; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - dev->lpVtbl->CreateBuffer(dev, &bd, NULL, &f->cb); - - D3D11_BLEND_DESC bdesc = {0}; - bdesc.RenderTarget[0].BlendEnable = TRUE; - bdesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - bdesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - bdesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - bdesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - bdesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - bdesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - dev->lpVtbl->CreateBlendState(dev, &bdesc, &f->blend); - - D3D11_SAMPLER_DESC sdesc = {0}; - sdesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - sdesc.AddressU = sdesc.AddressV = sdesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - dev->lpVtbl->CreateSamplerState(dev, &sdesc, &f->sampler); - - D3D11_DEPTH_STENCIL_DESC dsdesc = {0}; - dsdesc.DepthEnable = FALSE; - dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - dev->lpVtbl->CreateDepthStencilState(dev, &dsdesc, &f->ds_no_depth); - - LOG_INFO("bitmap_font: initialized (%dx%d atlas)", f->atlas_w, f->atlas_h); - return 1; -} - -void bitmap_font_destroy(BitmapFont* f) { - if (!f) return; - if (f->ds_no_depth) f->ds_no_depth->lpVtbl->Release(f->ds_no_depth); - if (f->sampler) f->sampler->lpVtbl->Release(f->sampler); - if (f->blend) f->blend->lpVtbl->Release(f->blend); - if (f->cb) f->cb->lpVtbl->Release(f->cb); - if (g_font_ib) { g_font_ib->lpVtbl->Release(g_font_ib); g_font_ib = NULL; } - if (g_font_vb) { g_font_vb->lpVtbl->Release(g_font_vb); g_font_vb = NULL; } - if (f->shader) { shader_destroy(f->shader); g_font_shader = NULL; } - if (f->srv) f->srv->lpVtbl->Release(f->srv); - if (f->texture) f->texture->lpVtbl->Release(f->texture); - memset(f, 0, sizeof(*f)); -} - -static void font_flush(ID3D11DeviceContext* ctx, - float screen_w, float screen_h, int num_idx) { - if (num_idx == 0) return; - - float wvp[64]; - make_ortho(wvp, screen_w, screen_h); - - ID3D11Device* dev = NULL; - ctx->lpVtbl->GetDevice(ctx, &dev); - - D3D11_RASTERIZER_DESC rdesc = {0}; - rdesc.FillMode = D3D11_FILL_SOLID; - rdesc.CullMode = D3D11_CULL_NONE; - rdesc.ScissorEnable = FALSE; - ID3D11RasterizerState* rstate = NULL; - HRESULT hr = dev->lpVtbl->CreateRasterizerState(dev, &rdesc, &rstate); - if (rstate) { - ctx->lpVtbl->RSSetState(ctx, rstate); - rstate->lpVtbl->Release(rstate); - } - dev->lpVtbl->Release(dev); - - shader_bind(g_font_shader, ctx); - shader_set_matrix(g_font_shader, ctx, wvp); - - UINT stride = sizeof(FontVert), offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &g_font_vb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, g_font_ib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - ctx->lpVtbl->DrawIndexed(ctx, (UINT)num_idx, 0, 0); -} - -static void font_begin(void) { g_font_vi = 0; g_font_ii = 0; } - -static void font_add_quad(BitmapFont* f, float x, float y, float w, float h, - float r, float g, float b, float a) { - if (g_font_vi + 4 > FONT_MAX_QUADS * 4) return; - float u0 = 0.19f, v0 = 0.01f, u1 = 0.24f, v1 = 0.15f; - int vi = g_font_vi; - g_font_verts[vi] = (FontVert){{x, y, 0},{0,0,-1},{u0,v0},{r,g,b,a}}; - g_font_verts[vi+1] = (FontVert){{x+w, y, 0},{0,0,-1},{u1,v0},{r,g,b,a}}; - g_font_verts[vi+2] = (FontVert){{x+w, y+h, 0},{0,0,-1},{u1,v1},{r,g,b,a}}; - g_font_verts[vi+3] = (FontVert){{x, y+h, 0},{0,0,-1},{u0,v1},{r,g,b,a}}; - uint32_t base = (uint32_t)vi; - g_font_indices[g_font_ii++] = base; g_font_indices[g_font_ii++] = base+1; g_font_indices[g_font_ii++] = base+2; - g_font_indices[g_font_ii++] = base; g_font_indices[g_font_ii++] = base+2; g_font_indices[g_font_ii++] = base+3; - g_font_vi += 4; -} - -void bitmap_font_draw(BitmapFont* f, ID3D11DeviceContext* ctx, - const char* text, int x, int y, - float r, float g, float b, float a, - float screen_w, float screen_h) { - if (!text || !*text || !f->shader) return; - int len = (int)strlen(text); - if (len > FONT_MAX_QUADS) len = FONT_MAX_QUADS; - int cols = f->atlas_w / FONT_CHAR_W; - - font_begin(); - int cx = x; - for (int i = 0; i < len; i++) { - int ch = (unsigned char)text[i] - FONT_FIRST_CHAR; - if (ch < 0 || ch >= FONT_NUM_CHARS) ch = 0; - int col_idx = ch % cols; - int row_idx = ch / cols; - float u0 = (float)(col_idx * FONT_CHAR_W) / (float)f->atlas_w; - float v0 = (float)(row_idx * FONT_CHAR_H) / (float)f->atlas_h; - float u1 = (float)((col_idx + 1) * FONT_CHAR_W) / (float)f->atlas_w; - float v1 = (float)((row_idx + 1) * FONT_CHAR_H) / (float)f->atlas_h; - int vi = g_font_vi; - g_font_verts[vi] = (FontVert){{(float)cx,(float)y,0},{0,0,-1},{u0,v0},{r,g,b,a}}; - g_font_verts[vi+1] = (FontVert){{(float)cx+FONT_CHAR_W,(float)y,0},{0,0,-1},{u1,v0},{r,g,b,a}}; - g_font_verts[vi+2] = (FontVert){{(float)cx+FONT_CHAR_W,(float)y+FONT_CHAR_H,0},{0,0,-1},{u1,v1},{r,g,b,a}}; - g_font_verts[vi+3] = (FontVert){{(float)cx,(float)y+FONT_CHAR_H,0},{0,0,-1},{u0,v1},{r,g,b,a}}; - uint32_t base = (uint32_t)vi; - g_font_indices[g_font_ii++] = base; g_font_indices[g_font_ii++] = base+1; g_font_indices[g_font_ii++] = base+2; - g_font_indices[g_font_ii++] = base; g_font_indices[g_font_ii++] = base+2; g_font_indices[g_font_ii++] = base+3; - g_font_vi += 4; - cx += FONT_CHAR_W; - } - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)g_font_vb, 0, NULL, g_font_verts, 0, 0); - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)g_font_ib, 0, NULL, g_font_indices, 0, 0); - font_flush(ctx, screen_w, screen_h, g_font_ii); -} - -void bitmap_font_rect(BitmapFont* f, ID3D11DeviceContext* ctx, - float x, float y, float w, float h, - float r, float g, float b, float a, - float screen_w, float screen_h) { - if (!f->shader) return; - font_begin(); - font_add_quad(f, x, y, w, h, r, g, b, a); - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)g_font_vb, 0, NULL, g_font_verts, 0, 0); - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)g_font_ib, 0, NULL, g_font_indices, 0, 0); - font_flush(ctx, screen_w, screen_h, g_font_ii); -} diff --git a/Engine/Engine/Editor/bitmap_font.h b/Engine/Engine/Editor/bitmap_font.h deleted file mode 100644 index 93f7b32..0000000 --- a/Engine/Engine/Editor/bitmap_font.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once -#include -#include -#include "../Rendering/shader.h" - -#define FONT_CHAR_W 8 -#define FONT_CHAR_H 16 -#define FONT_FIRST_CHAR 32 -#define FONT_NUM_CHARS 96 -#define FONT_MAX_QUADS 4096 - -typedef struct { - float pos[3]; - float norm[3]; - float uv[2]; - float color[4]; -} FontVert; - -typedef struct { - ID3D11Texture2D* texture; - ID3D11ShaderResourceView* srv; - ID3D11Buffer* cb; - Shader* shader; - ID3D11BlendState* blend; - ID3D11SamplerState* sampler; - ID3D11DepthStencilState* ds_no_depth; - int atlas_w; - int atlas_h; -} BitmapFont; - -int bitmap_font_init(BitmapFont* f, ID3D11Device* dev); -void bitmap_font_destroy(BitmapFont* f); -void bitmap_font_draw(BitmapFont* f, ID3D11DeviceContext* ctx, - const char* text, int x, int y, - float r, float g, float b, float a, - float screen_w, float screen_h); -void bitmap_font_rect(BitmapFont* f, ID3D11DeviceContext* ctx, - float x, float y, float w, float h, - float r, float g, float b, float a, - float screen_w, float screen_h); diff --git a/Engine/Engine/Editor/editor.c b/Engine/Engine/Editor/editor.c deleted file mode 100644 index 3811221..0000000 --- a/Engine/Engine/Editor/editor.c +++ /dev/null @@ -1,122 +0,0 @@ -#include "editor.h" -#include "../Core/logger.h" -#include -#include -#include - -static const float BG_DARK[] = {0.12f, 0.12f, 0.14f}; -static const float BG_PANEL[] = {0.16f, 0.16f, 0.18f}; -static const float BG_TITLE[] = {0.20f, 0.20f, 0.24f}; -static const float BG_INPUT[] = {0.10f, 0.10f, 0.12f}; - -int editor_init(Editor* ed, GraphicsDevice* dev) { - memset(ed, 0, sizeof(*ed)); - ed->device = dev; - - if (!uilayer_init(&ed->ui, dev->device, (float)dev->width, (float)dev->height)) return 0; - - int sw = dev->width, sh = dev->height; - int menu_h = 28; - ed->panels[0] = (EditorPanel){PANEL_VIEWPORT, "Viewport", 220, menu_h, sw-440, sh-menu_h-200, 1, 0, 0}; - ed->panels[1] = (EditorPanel){PANEL_SCENE, "Scene", 0, menu_h, 220, sh-menu_h-200, 1, 0, 0}; - ed->panels[2] = (EditorPanel){PANEL_INSPECTOR, "Inspector", sw-220, menu_h, 220, sh-menu_h-200, 1, 0, 0}; - ed->panels[3] = (EditorPanel){PANEL_CONSOLE, "Console", 0, sh-200, sw, 200, 1, 0, 0}; - ed->panel_count = 4; - - ed->scene_entities_count = 8; - strcpy(ed->selected_entity, "Cube"); - - LOG_INFO("Editor initialized"); - return 1; -} - -void editor_shutdown(Editor* ed) { - uilayer_destroy(&ed->ui); -} - -void editor_update(Editor* ed, float dt) { - ed->time += dt; - ed->viewport_rotation += dt * 0.5f; -} - -void editor_render(Editor* ed) { - ID3D11DeviceContext* ctx = ed->device->context; - float sw = (float)ed->device->width; - float sh = (float)ed->device->height; - - graphics_device_clear(ed->device, BG_DARK[0], BG_DARK[1], BG_DARK[2], 1.0f); - - uilayer_begin(&ed->ui); - - uilayer_rect(&ed->ui, 0, 0, sw, 28, 1.0f, 0.0f, 0.0f, 1.0f); - uilayer_rect(&ed->ui, 0, 28, sw, 28, 0.0f, 1.0f, 0.0f, 1.0f); - uilayer_rect(&ed->ui, 0, 56, sw/3, sh-256, 0.0f, 0.0f, 1.0f, 1.0f); - uilayer_rect(&ed->ui, sw/3, 56, sw/3, sh-256, 1.0f, 1.0f, 0.0f, 1.0f); - uilayer_rect(&ed->ui, 2*sw/3, 56, sw/3, sh-256, 1.0f, 0.0f, 1.0f, 1.0f); - uilayer_rect(&ed->ui, 0, sh-200, sw, 200, 0.0f, 1.0f, 1.0f, 1.0f); - uilayer_rect(&ed->ui, 0, sh-22, sw, 22, 1.0f, 0.5f, 0.0f, 1.0f); - - uilayer_flush(&ed->ui, ctx); - - float sw2 = sw, sh2 = sh; - bitmap_font_draw(&ed->font, ctx, "Lity3D Engine Editor", 10, 6, - 0.4f, 0.75f, 1.0f, 1.0f, sw2, sh2); - - const char* menu[] = {"File", "Edit", "View", "Build", "Help"}; - int mx = 180; - for (int i = 0; i < 5; i++) { - bitmap_font_draw(&ed->font, ctx, menu[i], mx + 8, 6, - 0.9f, 0.9f, 0.92f, 1.0f, sw2, sh2); - mx += (int)strlen(menu[i]) * 8 + 16; - } - - const char* tools[] = {"Select", "Move", "Rotate", "Scale"}; - int tx = 6; - for (int i = 0; i < 4; i++) { - bitmap_font_draw(&ed->font, ctx, tools[i], tx + 4, 34, - 0.9f, 0.9f, 0.92f, 1.0f, sw2, sh2); - tx += (int)strlen(tools[i]) * 8 + 16; - } - - for (int i = 0; i < ed->panel_count; i++) { - EditorPanel* p = &ed->panels[i]; - if (!p->visible) continue; - bitmap_font_draw(&ed->font, ctx, p->title, p->x + 6, p->y + 6, - 0.9f, 0.9f, 0.92f, 1.0f, sw2, sh2); - } - - bitmap_font_draw(&ed->font, ctx, ed->selected_entity, 226, 56, - 0.4f, 0.75f, 1.0f, 1.0f, sw2, sh2); - - const char* entities[] = {"Light", "Camera", "Cube", "Plane", "Sphere", "Particles", "Audio", "Skybox"}; - for (int i = 0; i < 8; i++) { - bitmap_font_draw(&ed->font, ctx, entities[i], 226, 78 + i * 22, - 0.9f, 0.9f, 0.92f, 1.0f, sw2, sh2); - } - - const char* sections[] = {"Transform", "Mesh Filter", "Material", "Collider"}; - int sy = 56; - for (int s = 0; s < 4; s++) { - bitmap_font_draw(&ed->font, ctx, sections[s], (int)sw - 214, sy, - 0.9f, 0.9f, 0.92f, 1.0f, sw2, sh2); - sy += 26; - } - - char status[128]; - snprintf(status, sizeof(status), "Entities: %d | Time: %.1fs", ed->scene_entities_count, ed->time); - bitmap_font_draw(&ed->font, ctx, status, 10, (int)sh - 18, - 0.55f, 0.55f, 0.6f, 1.0f, sw2, sh2); -} - -void editor_handle_input(Editor* ed, int msg, int wp, int lp) { - (void)lp; - switch (msg) { - case 0x0200: ed->input.mouse_x = wp & 0xFFFF; ed->input.mouse_y = (wp >> 16) & 0x7FFF; break; - case 0x0201: ed->input.mouse_lbtn = 1; break; - case 0x0202: ed->input.mouse_lbtn = 0; break; - case 0x0204: ed->input.mouse_rbtn = 1; break; - case 0x0205: ed->input.mouse_rbtn = 0; break; - case 0x0100: if (wp < 256) ed->input.key_down[wp] = 1; break; - case 0x0101: if (wp < 256) ed->input.key_down[wp] = 0; break; - } -} diff --git a/Engine/Engine/Editor/editor.h b/Engine/Engine/Editor/editor.h deleted file mode 100644 index bb51368..0000000 --- a/Engine/Engine/Editor/editor.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once -#include "uilayer.h" -#include "bitmap_font.h" -#include "../Rendering/graphics_device.h" -#include - -#define EDITOR_MAX_PANELS 16 - -typedef enum { - PANEL_SCENE, - PANEL_INSPECTOR, - PANEL_CONSOLE, - PANEL_ASSETS, - PANEL_VIEWPORT, -} PanelType; - -typedef struct { - PanelType type; - const char* title; - int x, y, w, h; - int visible; - int collapsed; - int active_tab; -} EditorPanel; - -typedef struct { - int mouse_x, mouse_y; - int mouse_lbtn; - int mouse_rbtn; - int key_down[256]; - char text_input[256]; - int text_len; -} EditorInput; - -typedef struct { - GraphicsDevice* device; - UILayer ui; - BitmapFont font; - EditorPanel panels[EDITOR_MAX_PANELS]; - int panel_count; - EditorInput input; - float time; - char console_lines[32][256]; - int console_count; - int console_scroll; - char selected_entity[128]; - int scene_entities_count; - float viewport_rotation; -} Editor; - -int editor_init(Editor* ed, GraphicsDevice* dev); -void editor_shutdown(Editor* ed); -void editor_update(Editor* ed, float dt); -void editor_render(Editor* ed); -void editor_handle_input(Editor* ed, int msg, int wp, int lp); diff --git a/Engine/Engine/Editor/editor_2d.c b/Engine/Engine/Editor/editor_2d.c deleted file mode 100644 index 2017ac9..0000000 --- a/Engine/Engine/Editor/editor_2d.c +++ /dev/null @@ -1,124 +0,0 @@ -#include "editor_2d.h" -#include -#include - -int editor2d_init(Editor2D* e, ID3D11Device* dev) { - memset(e, 0, sizeof(*e)); - - e->shader = shader_create(); - if (!shader_compile(e->shader, dev, NULL, NULL, 0, 0)) return 0; - - D3D11_BUFFER_DESC bd = {0}; - bd.ByteWidth = ED2D_MAX_QUADS * 4 * sizeof(Ed2DVert); - bd.Usage = D3D11_USAGE_DYNAMIC; - bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - if (FAILED(dev->lpVtbl->CreateBuffer(dev, &bd, NULL, &e->vb))) return 0; - - bd.ByteWidth = ED2D_MAX_QUADS * 6 * sizeof(uint32_t); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - bd.CPUAccessFlags = 0; - uint32_t* idx = (uint32_t*)malloc(ED2D_MAX_QUADS * 6 * sizeof(uint32_t)); - for (int i = 0; i < ED2D_MAX_QUADS; i++) { - uint32_t b2 = i * 4; - idx[i*6]=b2; idx[i*6+1]=b2+1; idx[i*6+2]=b2+2; - idx[i*6+3]=b2; idx[i*6+4]=b2+2; idx[i*6+5]=b2+3; - } - D3D11_SUBRESOURCE_DATA sd = {0}; sd.pSysMem = idx; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &e->ib); - free(idx); - - e->verts = (Ed2DVert*)malloc(ED2D_MAX_QUADS * 4 * sizeof(Ed2DVert)); - - D3D11_BLEND_DESC bdesc = {0}; - bdesc.RenderTarget[0].BlendEnable = TRUE; - bdesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - bdesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - bdesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - bdesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - bdesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - bdesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - dev->lpVtbl->CreateBlendState(dev, &bdesc, &e->blend); - - D3D11_DEPTH_STENCIL_DESC dsdesc = {0}; - dsdesc.DepthEnable = FALSE; - dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - dev->lpVtbl->CreateDepthStencilState(dev, &dsdesc, &e->ds_no_depth); - - return 1; -} - -void editor2d_destroy(Editor2D* e) { - if (!e) return; - if (e->ds_no_depth) e->ds_no_depth->lpVtbl->Release(e->ds_no_depth); - if (e->blend) e->blend->lpVtbl->Release(e->blend); - if (e->ib) e->ib->lpVtbl->Release(e->ib); - if (e->vb) e->vb->lpVtbl->Release(e->vb); - shader_destroy(e->shader); - free(e->verts); - memset(e, 0, sizeof(*e)); -} - -void editor2d_begin(Editor2D* e, float sw, float sh) { - e->quad_count = 0; - e->screen_w = sw; - e->screen_h = sh; - - memset(e->wvp, 0, sizeof(e->wvp)); - e->wvp[0] = 2.0f / sw; - e->wvp[5] = -2.0f / sh; - e->wvp[12] = -1.0f; - e->wvp[13] = 1.0f; - e->wvp[15] = 1.0f; -} - -void editor2d_rect(Editor2D* e, float x, float y, float w, float h, float r, float g, float b, float a) { - if (e->quad_count >= ED2D_MAX_QUADS) return; - int vi = e->quad_count * 4; - e->verts[vi+0] = (Ed2DVert){x, y, 0, 0,0,-1, 0,1, r,g,b,a}; - e->verts[vi+1] = (Ed2DVert){x+w, y, 0, 0,0,-1, 1,1, r,g,b,a}; - e->verts[vi+2] = (Ed2DVert){x+w, y+h, 0, 0,0,-1, 1,0, r,g,b,a}; - e->verts[vi+3] = (Ed2DVert){x, y+h, 0, 0,0,-1, 0,0, r,g,b,a}; - e->quad_count++; -} - -void editor2d_rect_border(Editor2D* e, float x, float y, float w, float h, float r, float g, float b, float a, float t) { - editor2d_rect(e, x, y, w, t, r, g, b, a); - editor2d_rect(e, x, y+h-t, w, t, r, g, b, a); - editor2d_rect(e, x, y, t, h, r, g, b, a); - editor2d_rect(e, x+w-t, y, t, h, r, g, b, a); -} - -void editor2d_end(Editor2D* e, ID3D11DeviceContext* ctx) { - if (e->quad_count == 0) return; - - D3D11_MAPPED_SUBRESOURCE mapped; - if (FAILED(ctx->lpVtbl->Map(ctx, (ID3D11Resource*)e->vb, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped))) return; - memcpy(mapped.pData, e->verts, (size_t)e->quad_count * 4 * sizeof(Ed2DVert)); - ctx->lpVtbl->Unmap(ctx, (ID3D11Resource*)e->vb, 0); - - if (e->rtv) { - ctx->lpVtbl->OMSetRenderTargets(ctx, 1, &e->rtv, NULL); - } - - D3D11_VIEWPORT vp = {0}; - vp.Width = e->screen_w; - vp.Height = e->screen_h; - vp.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vp); - - shader_bind(e->shader, ctx); - shader_set_matrix(e->shader, ctx, e->wvp); - - UINT stride = sizeof(Ed2DVert), offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &e->vb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, e->ib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - float bf[4] = {0}; - ctx->lpVtbl->OMSetBlendState(ctx, e->blend, bf, 0xFFFFFFFF); - ctx->lpVtbl->OMSetDepthStencilState(ctx, e->ds_no_depth, 0); - - ctx->lpVtbl->DrawIndexed(ctx, (UINT)(e->quad_count * 6), 0, 0); -} diff --git a/Engine/Engine/Editor/editor_2d.h b/Engine/Engine/Editor/editor_2d.h deleted file mode 100644 index 13bd05f..0000000 --- a/Engine/Engine/Editor/editor_2d.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include -#include -#include "../Rendering/shader.h" -#include "../Rendering/mesh.h" - -#define ED2D_MAX_QUADS 8192 - -typedef struct { - float x, y, z; - float nx, ny, nz; - float u, v; - float r, g, b, a; -} Ed2DVert; - -typedef struct { - Shader* shader; - ID3D11Buffer* vb; - ID3D11Buffer* ib; - ID3D11BlendState* blend; - ID3D11DepthStencilState* ds_no_depth; - ID3D11RenderTargetView* rtv; - Ed2DVert* verts; - int quad_count; - float screen_w; - float screen_h; - float wvp[16]; -} Editor2D; - -int editor2d_init(Editor2D* e, ID3D11Device* dev); -void editor2d_destroy(Editor2D* e); -void editor2d_begin(Editor2D* e, float sw, float sh); -void editor2d_rect(Editor2D* e, float x, float y, float w, float h, float r, float g, float b, float a); -void editor2d_rect_border(Editor2D* e, float x, float y, float w, float h, float r, float g, float b, float a, float thickness); -void editor2d_end(Editor2D* e, ID3D11DeviceContext* ctx); diff --git a/Engine/Engine/Editor/glyph_atlas.c b/Engine/Engine/Editor/glyph_atlas.c deleted file mode 100644 index fe9af28..0000000 --- a/Engine/Engine/Editor/glyph_atlas.c +++ /dev/null @@ -1,171 +0,0 @@ -#include "glyph_atlas.h" -#include -#include -#include -#include -#include "../Core/logger.h" - -typedef struct { - wchar_t ch; - int x, y; - int w, h; - float u0, v0, u1, v1; - float advance_x; -} GlyphEntry; - -#define MAX_GLYPHS 1024 -static GlyphEntry g_entries[MAX_GLYPHS]; -static int g_entry_count = 0; - -int glyph_atlas_init(GlyphAtlas* ga, ID3D11Device* dev) { - memset(ga, 0, sizeof(*ga)); - ga->cell_w = GLYPH_CELL_W; - ga->cell_h = GLYPH_CELL_H; - ga->atlas_w = GLYPH_ATLAS_SIZE; - ga->atlas_h = GLYPH_ATLAS_SIZE; - ga->next_x = 0; - ga->next_y = 0; - ga->u_scale = 1.0f / (float)ga->atlas_w; - ga->v_scale = 1.0f / (float)ga->atlas_h; - - uint8_t* pixels = (uint8_t*)calloc(ga->atlas_w * ga->atlas_h * 4, 1); - - D3D11_TEXTURE2D_DESC td = {0}; - td.Width = ga->atlas_w; - td.Height = ga->atlas_h; - td.MipLevels = 1; - td.ArraySize = 1; - td.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - td.SampleDesc.Count = 1; - td.Usage = D3D11_USAGE_DEFAULT; - td.BindFlags = D3D11_BIND_SHADER_RESOURCE; - D3D11_SUBRESOURCE_DATA sd = {0}; - sd.pSysMem = pixels; - sd.SysMemPitch = ga->atlas_w * 4; - HRESULT hr = dev->lpVtbl->CreateTexture2D(dev, &td, &sd, &ga->texture); - free(pixels); - if (FAILED(hr)) return 0; - - dev->lpVtbl->CreateShaderResourceView(dev, (ID3D11Resource*)ga->texture, NULL, &ga->srv); - - LOG_INFO("GlyphAtlas: initialized (%dx%d, max %d glyphs)", ga->atlas_w, ga->atlas_h, MAX_GLYPHS); - return 1; -} - -void glyph_atlas_destroy(GlyphAtlas* ga) { - if (!ga) return; - if (ga->srv) ga->srv->lpVtbl->Release(ga->srv); - if (ga->texture) ga->texture->lpVtbl->Release(ga->texture); - memset(ga, 0, sizeof(*ga)); - g_entry_count = 0; -} - -static int find_glyph(wchar_t ch) { - for (int i = 0; i < g_entry_count; i++) { - if (g_entries[i].ch == ch) return i; - } - return -1; -} - -int glyph_atlas_get_or_create(GlyphAtlas* ga, ID3D11Device* dev, ID3D11DeviceContext* ctx, wchar_t ch, - float* u0, float* v0, float* u1, float* v1, - float* advance_x, float* advance_y) { - int idx = find_glyph(ch); - if (idx >= 0) { - *u0 = g_entries[idx].u0; - *v0 = g_entries[idx].v0; - *u1 = g_entries[idx].u1; - *v1 = g_entries[idx].v1; - *advance_x = g_entries[idx].advance_x; - *advance_y = (float)g_entries[idx].h; - return 1; - } - - if (g_entry_count >= MAX_GLYPHS) return 0; - - if (ga->next_x + ga->cell_w > ga->atlas_w) { - ga->next_x = 0; - ga->next_y += ga->cell_h; - } - if (ga->next_y + ga->cell_h > ga->atlas_h) return 0; - - HDC hdc = GetDC(NULL); - HFONT hfont = CreateFontW( - ga->cell_h - 4, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, - DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, - CLEARTYPE_QUALITY, FIXED_PITCH | FF_DONTCARE, L"Microsoft YaHei" - ); - HFONT old = (HFONT)SelectObject(hdc, hfont); - - GLYPHMETRICS gm = {0}; - MAT2 mat = {{0,0},{0,0},{0,0},{0,0}}; - mat.eM11.value = 1; mat.eM22.value = 1; - - DWORD size = GetGlyphOutlineW(hdc, ch, GGO_GRAY8_BITMAP, &gm, 0, NULL, &mat); - - int gw = gm.gmBlackBoxX; - int gh = gm.gmBlackBoxY; - int gx = ga->next_x; - int gy = ga->next_y; - - if (size > 0 && gw > 0 && gh > 0) { - uint8_t* buf = (uint8_t*)malloc(size); - GetGlyphOutlineW(hdc, ch, GGO_GRAY8_BITMAP, &gm, size, buf, &mat); - - uint8_t* pixels = (uint8_t*)calloc(gw * gh * 4, 1); - - int row_bytes = ((gw + 3) / 4) * 4; - - for (int row = 0; row < gh; row++) { - for (int col = 0; col < gw; col++) { - int src_idx = row * row_bytes + col; - if (src_idx < (int)size) { - uint8_t gray = buf[src_idx]; - uint8_t alpha = (gray > 200) ? 255 : (gray > 100) ? 200 : (gray > 30) ? 128 : 0; - int idx = (row * gw + col) * 4; - pixels[idx] = 255; - pixels[idx + 1] = 255; - pixels[idx + 2] = 255; - pixels[idx + 3] = alpha; - } - } - } - - D3D11_BOX box = {0}; - box.left = gx; - box.top = gy; - box.front = 0; - box.right = gx + gw; - box.bottom = gy + gh; - box.back = 1; - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)ga->texture, 0, &box, pixels, gw * 4, 0); - free(buf); - free(pixels); - } - - SelectObject(hdc, old); - DeleteObject(hfont); - ReleaseDC(NULL, hdc); - - GlyphEntry* e = &g_entries[g_entry_count++]; - e->ch = ch; - e->x = gx; - e->y = gy; - e->w = gw > 0 ? gw : ga->cell_w / 2; - e->h = gh > 0 ? gh : ga->cell_h; - e->u0 = (float)gx * ga->u_scale; - e->v0 = (float)gy * ga->v_scale; - e->u1 = (float)(gx + e->w) * ga->u_scale; - e->v1 = (float)(gy + e->h) * ga->v_scale; - e->advance_x = (float)(gm.gmCellIncX > 0 ? gm.gmCellIncX : ga->cell_w / 2); - - ga->next_x += ga->cell_w; - - *u0 = e->u0; - *v0 = e->v0; - *u1 = e->u1; - *v1 = e->v1; - *advance_x = e->advance_x; - *advance_y = (float)e->h; - return 1; -} diff --git a/Engine/Engine/Editor/glyph_atlas.h b/Engine/Engine/Editor/glyph_atlas.h deleted file mode 100644 index bb47559..0000000 --- a/Engine/Engine/Editor/glyph_atlas.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -#include -#include - -#define GLYPH_CELL_W 32 -#define GLYPH_CELL_H 32 -#define GLYPH_ATLAS_COLS 16 -#define GLYPH_ATLAS_ROWS 16 -#define GLYPH_ATLAS_SIZE (GLYPH_ATLAS_COLS * GLYPH_CELL_W) - -typedef struct { - ID3D11Texture2D* texture; - ID3D11ShaderResourceView* srv; - int atlas_w; - int atlas_h; - int next_x; - int next_y; - int cell_w; - int cell_h; - float u_scale; - float v_scale; -} GlyphAtlas; - -int glyph_atlas_init(GlyphAtlas* ga, ID3D11Device* dev); -void glyph_atlas_destroy(GlyphAtlas* ga); -int glyph_atlas_get_or_create(GlyphAtlas* ga, ID3D11Device* dev, ID3D11DeviceContext* ctx, wchar_t ch, - float* u0, float* v0, float* u1, float* v1, - float* advance_x, float* advance_y); diff --git a/Engine/Engine/Editor/textlayer.h b/Engine/Engine/Editor/textlayer.h deleted file mode 100644 index 680e6cb..0000000 --- a/Engine/Engine/Editor/textlayer.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "uilayer.h" -#include "bitmap_font.h" - -int textlayer_init(TextLayer* t, ID3D11Device* dev, BitmapFont* font, UILayer* ui); -void textlayer_destroy(TextLayer* t); -void textlayer_draw(TextLayer* t, ID3D11DeviceContext* ctx, - const char* text, int x, int y, - float r, float g, float b, float a, - float screen_w, float screen_h); diff --git a/Engine/Engine/Editor/uilayer.c b/Engine/Engine/Editor/uilayer.c deleted file mode 100644 index a3b898e..0000000 --- a/Engine/Engine/Editor/uilayer.c +++ /dev/null @@ -1,252 +0,0 @@ -#include "uilayer.h" -#include -#include -#include "../Core/logger.h" - -#define UI_MAX_VERTS (UI_MAX_QUADS * 4) -#define UI_MAX_IDXS (UI_MAX_QUADS * 6) - -typedef struct { float p[3], n[3], uv[2], c[4]; } UIVert; - -static UIVert g_verts[UI_MAX_VERTS]; -static uint32_t g_indices[UI_MAX_IDXS]; -static int g_vi = 0; -static int g_ii = 0; - -static UIVert g_text_verts[UI_MAX_VERTS]; -static uint32_t g_text_indices[UI_MAX_IDXS]; -static int g_tvi = 0; -static int g_tii = 0; -static ID3D11ShaderResourceView* g_text_srv = NULL; - -static void screen_to_world(float sx, float sy, float sw, float sh, float z, float* wx, float* wy) { - *wx = sx - sw * 0.5f; - *wy = -(sy - sh * 0.5f); -} - -int uilayer_init(UILayer* u, ID3D11Device* dev, float screen_w, float screen_h) { - memset(u, 0, sizeof(*u)); - u->screen_w = screen_w; - u->screen_h = screen_h; - u->z_plane = 0.0f; - - u->camera = camera_orthographic(screen_w, screen_h, 0.1f, 200.0f); - u->camera.position = (Vec3){0, 0, 100}; - u->camera.target = (Vec3){0, 0, 0}; - u->camera.dirty = 1; - camera_update(&u->camera); - - u->shader = shader_create(); - if (!shader_compile(u->shader, dev, NULL, NULL, 0, 0)) { - LOG_ERROR("UILayer: shader compile failed"); - return 0; - } - - D3D11_BUFFER_DESC bd = {0}; - D3D11_SUBRESOURCE_DATA sd = {0}; - - UIVert* empty = (UIVert*)calloc(UI_MAX_VERTS, sizeof(UIVert)); - bd.ByteWidth = UI_MAX_VERTS * sizeof(UIVert); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = empty; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &u->vb); - free(empty); - - uint32_t* eidx = (uint32_t*)calloc(UI_MAX_IDXS, sizeof(uint32_t)); - bd.ByteWidth = UI_MAX_IDXS * sizeof(uint32_t); - bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = eidx; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &u->ib); - free(eidx); - - UIVert* empty2 = (UIVert*)calloc(UI_MAX_VERTS, sizeof(UIVert)); - bd.ByteWidth = UI_MAX_VERTS * sizeof(UIVert); - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = empty2; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &u->text_vb); - free(empty2); - - uint32_t* eidx2 = (uint32_t*)calloc(UI_MAX_IDXS, sizeof(uint32_t)); - bd.ByteWidth = UI_MAX_IDXS * sizeof(uint32_t); - bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = eidx2; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &u->text_ib); - free(eidx2); - - D3D11_RASTERIZER_DESC rdesc = {0}; - rdesc.FillMode = D3D11_FILL_SOLID; - rdesc.CullMode = D3D11_CULL_NONE; - dev->lpVtbl->CreateRasterizerState(dev, &rdesc, &u->rstate); - - D3D11_DEPTH_STENCIL_DESC dsdesc = {0}; - dsdesc.DepthEnable = FALSE; - dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - dev->lpVtbl->CreateDepthStencilState(dev, &dsdesc, &u->ds_state); - - D3D11_BLEND_DESC bdesc = {0}; - bdesc.RenderTarget[0].BlendEnable = TRUE; - bdesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - bdesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - bdesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - bdesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - bdesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - bdesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - dev->lpVtbl->CreateBlendState(dev, &bdesc, &u->text_blend); - - D3D11_SAMPLER_DESC sdesc = {0}; - sdesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - sdesc.AddressU = sdesc.AddressV = sdesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - dev->lpVtbl->CreateSamplerState(dev, &sdesc, &u->text_sampler); - - const char* text_vs_src = - "cbuffer CB:register(b0){float4x4 WVP;};" - "struct VS_IN{float4 pos:POSITION;float3 n:NORMAL;float2 uv:TEXCOORD;float4 col:COLOR;};" - "struct PS_IN{float4 pos:SV_POSITION;float2 uv:TEXCOORD;float4 col:COLOR;};" - "PS_IN main(VS_IN i){PS_IN o;o.pos=mul(i.pos,WVP);o.uv=i.uv;o.col=i.col;return o;}"; - const char* text_ps_src = - "Texture2D tex:register(t0);SamplerState smp:register(s0);" - "struct PS_IN{float4 pos:SV_POSITION;float2 uv:TEXCOORD;float4 col:COLOR;};" - "float4 main(PS_IN i):SV_TARGET{float a=tex.Sample(smp,i.uv).a;return float4(i.col.rgb,i.col.a*a);}"; - - ID3DBlob *vsb = NULL, *psb = NULL; - D3DCompile(text_vs_src, (UINT)strlen(text_vs_src), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &vsb, NULL); - D3DCompile(text_ps_src, (UINT)strlen(text_ps_src), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &psb, NULL); - if (vsb && psb) { - dev->lpVtbl->CreateVertexShader(dev, vsb->lpVtbl->GetBufferPointer(vsb), vsb->lpVtbl->GetBufferSize(vsb), NULL, &u->text_vs); - dev->lpVtbl->CreatePixelShader(dev, psb->lpVtbl->GetBufferPointer(psb), psb->lpVtbl->GetBufferSize(psb), NULL, &u->text_ps); - D3D11_INPUT_ELEMENT_DESC layout[] = { - {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}, - }; - dev->lpVtbl->CreateInputLayout(dev, layout, 4, vsb->lpVtbl->GetBufferPointer(vsb), vsb->lpVtbl->GetBufferSize(vsb), &u->text_layout); - vsb->lpVtbl->Release(vsb); - psb->lpVtbl->Release(psb); - } - - LOG_INFO("UILayer: initialized (%.0fx%.0f)", screen_w, screen_h); - return 1; -} - -void uilayer_destroy(UILayer* u) { - if (!u) return; - if (u->text_sampler) u->text_sampler->lpVtbl->Release(u->text_sampler); - if (u->text_blend) u->text_blend->lpVtbl->Release(u->text_blend); - if (u->text_layout) u->text_layout->lpVtbl->Release(u->text_layout); - if (u->text_ps) u->text_ps->lpVtbl->Release(u->text_ps); - if (u->text_vs) u->text_vs->lpVtbl->Release(u->text_vs); - if (u->text_ib) u->text_ib->lpVtbl->Release(u->text_ib); - if (u->text_vb) u->text_vb->lpVtbl->Release(u->text_vb); - if (u->ds_state) u->ds_state->lpVtbl->Release(u->ds_state); - if (u->rstate) u->rstate->lpVtbl->Release(u->rstate); - if (u->ib) u->ib->lpVtbl->Release(u->ib); - if (u->vb) u->vb->lpVtbl->Release(u->vb); - if (u->shader) shader_destroy(u->shader); - memset(u, 0, sizeof(*u)); -} - -void uilayer_begin(UILayer* u) { - (void)u; - g_vi = 0; g_ii = 0; - g_tvi = 0; g_tii = 0; - g_text_srv = NULL; -} - -void uilayer_rect(UILayer* u, float x, float y, float w, float h, - float r, float g, float b, float a) { - if (g_vi + 4 > UI_MAX_VERTS) return; - float x0, y0, x1, y1; - screen_to_world(x, y, u->screen_w, u->screen_h, u->z_plane, &x0, &y0); - screen_to_world(x + w, y + h, u->screen_w, u->screen_h, u->z_plane, &x1, &y1); - float z = u->z_plane; - uint32_t base = (uint32_t)g_vi; - g_verts[g_vi] = (UIVert){{x0,y0,z},{0,0,1},{0,0},{r,g,b,a}}; g_vi++; - g_verts[g_vi] = (UIVert){{x1,y0,z},{0,0,1},{1,0},{r,g,b,a}}; g_vi++; - g_verts[g_vi] = (UIVert){{x1,y1,z},{0,0,1},{1,1},{r,g,b,a}}; g_vi++; - g_verts[g_vi] = (UIVert){{x0,y1,z},{0,0,1},{0,1},{r,g,b,a}}; g_vi++; - g_indices[g_ii++] = base; g_indices[g_ii++] = base+1; g_indices[g_ii++] = base+2; - g_indices[g_ii++] = base; g_indices[g_ii++] = base+2; g_indices[g_ii++] = base+3; -} - -void uilayer_textured_rect(UILayer* u, ID3D11DeviceContext* ctx, - ID3D11ShaderResourceView* srv, - float x, float y, float w, float h, - float u0, float v0, float u1, float v1, - float r, float g, float b, float a) { - (void)ctx; - if (!srv || g_tvi + 4 > UI_MAX_VERTS) return; - float x0, y0, x1, y1; - screen_to_world(x, y, u->screen_w, u->screen_h, u->z_plane, &x0, &y0); - screen_to_world(x + w, y + h, u->screen_w, u->screen_h, u->z_plane, &x1, &y1); - float z = u->z_plane; - uint32_t base = (uint32_t)g_tvi; - g_text_verts[g_tvi] = (UIVert){{x0,y0,z},{0,0,1},{u0,v0},{r,g,b,a}}; g_tvi++; - g_text_verts[g_tvi] = (UIVert){{x1,y0,z},{0,0,1},{u1,v0},{r,g,b,a}}; g_tvi++; - g_text_verts[g_tvi] = (UIVert){{x1,y1,z},{0,0,1},{u1,v1},{r,g,b,a}}; g_tvi++; - g_text_verts[g_tvi] = (UIVert){{x0,y1,z},{0,0,1},{u0,v1},{r,g,b,a}}; g_tvi++; - g_text_indices[g_tii++] = base; g_text_indices[g_tii++] = base+1; g_text_indices[g_tii++] = base+2; - g_text_indices[g_tii++] = base; g_text_indices[g_tii++] = base+2; g_text_indices[g_tii++] = base+3; - g_text_srv = srv; -} - -static void flush_batch(ID3D11DeviceContext* ctx, UIVert* verts, uint32_t* indices, - int num_idx, ID3D11Buffer* vb, ID3D11Buffer* ib) { - if (num_idx == 0) return; - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)vb, 0, NULL, verts, 0, 0); - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)ib, 0, NULL, indices, 0, 0); - UINT stride = sizeof(UIVert), offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &vb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, ib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->DrawIndexed(ctx, (UINT)num_idx, 0, 0); -} - -void uilayer_flush(UILayer* u, ID3D11DeviceContext* ctx) { - if (g_ii == 0) return; - Mat4 view = u->camera.view; - Mat4 proj = u->camera.projection; - Mat4 vp, vp_t; - mat4_multiply(&view, &proj, &vp); - mat4_transpose(&vp, &vp_t); - - D3D11_VIEWPORT vport = {0}; - vport.Width = u->screen_w; vport.Height = u->screen_h; vport.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vport); - ctx->lpVtbl->RSSetState(ctx, u->rstate); - ctx->lpVtbl->OMSetDepthStencilState(ctx, u->ds_state, 0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - shader_bind(u->shader, ctx); - shader_set_matrix(u->shader, ctx, (float*)&vp_t); - flush_batch(ctx, g_verts, g_indices, g_ii, u->vb, u->ib); -} - -void uilayer_flush_text(UILayer* u, ID3D11DeviceContext* ctx) { - if (g_tii == 0 || !g_text_srv || !u->text_vs || !u->text_ps) return; - Mat4 view = u->camera.view; - Mat4 proj = u->camera.projection; - Mat4 vp, vp_t; - mat4_multiply(&view, &proj, &vp); - mat4_transpose(&vp, &vp_t); - - D3D11_VIEWPORT vport = {0}; - vport.Width = u->screen_w; vport.Height = u->screen_h; vport.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vport); - ctx->lpVtbl->RSSetState(ctx, u->rstate); - ctx->lpVtbl->OMSetDepthStencilState(ctx, u->ds_state, 0); - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - ctx->lpVtbl->VSSetShader(ctx, u->text_vs, NULL, 0); - ctx->lpVtbl->PSSetShader(ctx, u->text_ps, NULL, 0); - ctx->lpVtbl->IASetInputLayout(ctx, u->text_layout); - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)u->shader->cb, 0, NULL, &vp_t, 0, 0); - ctx->lpVtbl->VSSetConstantBuffers(ctx, 0, 1, &u->shader->cb); - - float bf[4] = {0}; - ctx->lpVtbl->OMSetBlendState(ctx, u->text_blend, bf, 0xFFFFFFFF); - ctx->lpVtbl->PSSetShaderResources(ctx, 0, 1, &g_text_srv); - ctx->lpVtbl->PSSetSamplers(ctx, 0, 1, &u->text_sampler); - - flush_batch(ctx, g_text_verts, g_text_indices, g_tii, u->text_vb, u->text_ib); -} diff --git a/Engine/Engine/Editor/uilayer.h b/Engine/Engine/Editor/uilayer.h deleted file mode 100644 index 241cf12..0000000 --- a/Engine/Engine/Editor/uilayer.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once -#include "../Rendering/camera.h" -#include "../Rendering/shader.h" -#include "../Rendering/mesh.h" -#include "../Rendering/graphics_device.h" -#include "../ASM/math_c_fallback.h" - -#define UI_MAX_QUADS 8192 - -typedef struct { - Camera camera; - Shader* shader; - ID3D11Buffer* vb; - ID3D11Buffer* ib; - ID3D11Buffer* text_vb; - ID3D11Buffer* text_ib; - ID3D11RasterizerState* rstate; - ID3D11DepthStencilState* ds_state; - ID3D11VertexShader* text_vs; - ID3D11PixelShader* text_ps; - ID3D11InputLayout* text_layout; - ID3D11BlendState* text_blend; - ID3D11SamplerState* text_sampler; - float screen_w; - float screen_h; - float z_plane; -} UILayer; - -int uilayer_init(UILayer* u, ID3D11Device* dev, float screen_w, float screen_h); -void uilayer_destroy(UILayer* u); -void uilayer_begin(UILayer* u); -void uilayer_rect(UILayer* u, - float x, float y, float w, float h, - float r, float g, float b, float a); -void uilayer_textured_rect(UILayer* u, ID3D11DeviceContext* ctx, - ID3D11ShaderResourceView* srv, - float x, float y, float w, float h, - float u0, float v0, float u1, float v1, - float r, float g, float b, float a); -void uilayer_flush(UILayer* u, ID3D11DeviceContext* ctx); -void uilayer_flush_text(UILayer* u, ID3D11DeviceContext* ctx); diff --git a/Engine/Engine/Engine.vcxproj b/Engine/Engine/Engine.vcxproj deleted file mode 100644 index d47cc3f..0000000 --- a/Engine/Engine/Engine.vcxproj +++ /dev/null @@ -1,124 +0,0 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - {B5C5B5B5-5B5B-5B5B-5B5B-5B5B5B5B5B5B} - Engine - 10.0 - - - - StaticLibrary - true - v143 - Unicode - - - StaticLibrary - false - v143 - true - Unicode - - - - - - - - - - - - - - - NotUsing - Level4 - true - _DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) - true - stdc17 - $(ProjectDir);$(ProjectDir)include;%(AdditionalIncludeDirectories) - AdvancedVectorExtensions2 - - - %(AdditionalLibraryDirectories) - - - - - NotUsing - Level4 - true - true - true - NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions) - true - stdc17 - $(ProjectDir);$(ProjectDir)include;%(AdditionalIncludeDirectories) - AdvancedVectorExtensions2 - - - %(AdditionalLibraryDirectories) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Engine/Engine/Input/input.c b/Engine/Engine/Input/input.c deleted file mode 100644 index 215d0f3..0000000 --- a/Engine/Engine/Input/input.c +++ /dev/null @@ -1,138 +0,0 @@ -#include "input.h" - -#include -#include -#include - -static float normalize_trigger(BYTE value) { - return value / 255.0f; -} - -static float normalize_axis(SHORT value) { - if (value > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { - return (value - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) / (32767.0f - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE); - } else if (value < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { - return (value + XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) / (32767.0f - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE); - } - return 0.0f; -} - -Input* input_create(void) { - Input* input = (Input*)calloc(1, sizeof(Input)); - input->deadzone = 0.2f; - return input; -} - -void input_destroy(Input* input) { - free(input); -} - -void input_update(Input* input) { - memcpy(input->key_prev, input->key_states, sizeof(int) * MAX_KEYS); - memcpy(input->mouse_prev, input->mouse_buttons, sizeof(int) * 3); - - input->mouse_dx = 0; - input->mouse_dy = 0; - input->mouse_scroll = 0; - - memcpy(&input->gamepad_prev, &input->gamepad_state, sizeof(XINPUT_STATE)); - input->gamepad_connected = (XInputGetState(0, &input->gamepad_state) == ERROR_SUCCESS); -} - -void input_process_key(Input* input, int key, int down) { - if (key >= 0 && key < MAX_KEYS) { - input->key_states[key] = down; - } -} - -void input_process_mouse_move(Input* input, int x, int y) { - input->mouse_dx = x - input->mouse_x; - input->mouse_dy = y - input->mouse_y; - input->mouse_x = x; - input->mouse_y = y; -} - -void input_process_mouse_button(Input* input, int button, int down) { - if (button >= 0 && button < 3) { - input->mouse_buttons[button] = down; - } -} - -void input_process_mouse_wheel(Input* input, int delta) { - input->mouse_scroll += delta; -} - -int input_key_down(Input* input, int key) { - return (key >= 0 && key < MAX_KEYS) ? input->key_states[key] : 0; -} - -int input_key_pressed(Input* input, int key) { - return (key >= 0 && key < MAX_KEYS) ? (input->key_states[key] && !input->key_prev[key]) : 0; -} - -int input_key_released(Input* input, int key) { - return (key >= 0 && key < MAX_KEYS) ? (!input->key_states[key] && input->key_prev[key]) : 0; -} - -int input_mouse_button(Input* input, int button) { - return (button >= 0 && button < 3) ? input->mouse_buttons[button] : 0; -} - -int input_mouse_button_pressed(Input* input, int button) { - return (button >= 0 && button < 3) ? (input->mouse_buttons[button] && !input->mouse_prev[button]) : 0; -} - -void input_get_mouse_pos(Input* input, int* x, int* y) { - if (x) *x = input->mouse_x; - if (y) *y = input->mouse_y; -} - -void input_get_mouse_delta(Input* input, int* dx, int* dy) { - if (dx) *dx = input->mouse_dx; - if (dy) *dy = input->mouse_dy; -} - -int input_get_mouse_scroll(Input* input) { - return input->mouse_scroll; -} - -int input_gamepad_connected(Input* input) { - return input->gamepad_connected; -} - -float input_gamepad_axis_lx(Input* input) { - float v = normalize_axis(input->gamepad_state.Gamepad.sThumbLX); - return fabsf(v) < input->deadzone ? 0.0f : v; -} - -float input_gamepad_axis_ly(Input* input) { - float v = normalize_axis(input->gamepad_state.Gamepad.sThumbLY); - return fabsf(v) < input->deadzone ? 0.0f : v; -} - -float input_gamepad_axis_rx(Input* input) { - float v = normalize_axis(input->gamepad_state.Gamepad.sThumbRX); - return fabsf(v) < input->deadzone ? 0.0f : v; -} - -float input_gamepad_axis_ry(Input* input) { - float v = normalize_axis(input->gamepad_state.Gamepad.sThumbRY); - return fabsf(v) < input->deadzone ? 0.0f : v; -} - -float input_gamepad_trigger_l(Input* input) { - return normalize_trigger(input->gamepad_state.Gamepad.bLeftTrigger); -} - -float input_gamepad_trigger_r(Input* input) { - return normalize_trigger(input->gamepad_state.Gamepad.bRightTrigger); -} - -int input_gamepad_button(Input* input, uint16_t button) { - return (input->gamepad_state.Gamepad.wButtons & button) != 0; -} - -int input_gamepad_button_pressed(Input* input, uint16_t button) { - return (input->gamepad_state.Gamepad.wButtons & button) != 0 && - (input->gamepad_prev.Gamepad.wButtons & button) == 0; -} diff --git a/Engine/Engine/Input/input.h b/Engine/Engine/Input/input.h deleted file mode 100644 index 4e6c045..0000000 --- a/Engine/Engine/Input/input.h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once - -// ============================================================================ -// input.h - 输入管理 (键盘/鼠标/手柄) -// ============================================================================ - -#include -#include -#include - -#pragma comment(lib, "xinput.lib") - -// 键盘状态 -#define MAX_KEYS 256 - -// 鼠标按钮 -#define MOUSE_LEFT 0 -#define MOUSE_RIGHT 1 -#define MOUSE_MIDDLE 2 - -// 手柄按钮 -#define GAMEPAD_A XINPUT_GAMEPAD_A -#define GAMEPAD_B XINPUT_GAMEPAD_B -#define GAMEPAD_X XINPUT_GAMEPAD_X -#define GAMEPAD_Y XINPUT_GAMEPAD_Y -#define GAMEPAD_START XINPUT_GAMEPAD_START -#define GAMEPAD_BACK XINPUT_GAMEPAD_BACK -#define GAMEPAD_LB XINPUT_GAMEPAD_LEFT_SHOULDER -#define GAMEPAD_RB XINPUT_GAMEPAD_RIGHT_SHOULDER -#define GAMEPAD_LTHUMB XINPUT_GAMEPAD_LEFT_THUMB -#define GAMEPAD_RTHUMB XINPUT_GAMEPAD_RIGHT_THUMB -#define GAMEPAD_UP XINPUT_GAMEPAD_DPAD_UP -#define GAMEPAD_DOWN XINPUT_GAMEPAD_DPAD_DOWN -#define GAMEPAD_LEFT XINPUT_GAMEPAD_DPAD_LEFT -#define GAMEPAD_RIGHT XINPUT_GAMEPAD_DPAD_RIGHT - -typedef struct { - int key_states[MAX_KEYS]; - int key_prev[MAX_KEYS]; - - int mouse_x, mouse_y; - int mouse_dx, mouse_dy; - int mouse_scroll; - int mouse_buttons[3]; - int mouse_prev[3]; - - XINPUT_STATE gamepad_state; - XINPUT_STATE gamepad_prev; - int gamepad_connected; - - float deadzone; -} Input; - -// 创建/销毁 -Input* input_create(void); -void input_destroy(Input* input); - -// 更新 (每帧调用) -void input_update(Input* input); - -// Win32 消息处理 -void input_process_key(Input* input, int key, int down); -void input_process_mouse_move(Input* input, int x, int y); -void input_process_mouse_button(Input* input, int button, int down); -void input_process_mouse_wheel(Input* input, int delta); - -// 键盘查询 -int input_key_down(Input* input, int key); -int input_key_pressed(Input* input, int key); -int input_key_released(Input* input, int key); - -// 鼠标查询 -int input_mouse_button(Input* input, int button); -int input_mouse_button_pressed(Input* input, int button); -void input_get_mouse_pos(Input* input, int* x, int* y); -void input_get_mouse_delta(Input* input, int* dx, int* dy); -int input_get_mouse_scroll(Input* input); - -// 手柄查询 -int input_gamepad_connected(Input* input); -float input_gamepad_axis_lx(Input* input); -float input_gamepad_axis_ly(Input* input); -float input_gamepad_axis_rx(Input* input); -float input_gamepad_axis_ry(Input* input); -float input_gamepad_trigger_l(Input* input); -float input_gamepad_trigger_r(Input* input); -int input_gamepad_button(Input* input, uint16_t button); -int input_gamepad_button_pressed(Input* input, uint16_t button); diff --git a/Engine/Engine/Math/math_impl.c b/Engine/Engine/Math/math_impl.c deleted file mode 100644 index 35a2e85..0000000 --- a/Engine/Engine/Math/math_impl.c +++ /dev/null @@ -1,8 +0,0 @@ -// math_impl.c - 数学函数实现 (C fallback) -// 当 MASM 不可用时使用 - -#include "math_c_fallback.h" - -// 由于函数是 static inline,它们应该被内联 -// 但如果编译器没有内联,这些函数将提供实现 -// 这个文件确保链接器能找到符号 diff --git a/Engine/Engine/Physics/physics.c b/Engine/Engine/Physics/physics.c deleted file mode 100644 index deec9d5..0000000 --- a/Engine/Engine/Physics/physics.c +++ /dev/null @@ -1,373 +0,0 @@ -#include "physics.h" -#include "../include/engine_api.h" - -#include -#include -#include - -static void move_collider(Collider* c, Vec3 delta); - -PhysicsWorld* physics_create(void) { - PhysicsWorld* w = (PhysicsWorld*)calloc(1, sizeof(PhysicsWorld)); - w->gravity_enabled = 1; - w->gravity = (Vec3){0, -9.81f, 0}; - return w; -} - -void physics_destroy(PhysicsWorld* world) { - free(world); -} - -static void init_body(RigidBody* b) { - b->velocity = (Vec3){0, 0, 0}; - b->acceleration = (Vec3){0, 0, 0}; - b->mass = 1.0f; - b->restitution = 0.5f; - b->friction = 0.3f; - b->is_kinematic = 0; -} - -uint32_t physics_add_aabb(PhysicsWorld* world, uint32_t entity, Vec3 min, Vec3 max) { - uint32_t idx = world->collider_count++; - Collider* c = &world->colliders[idx]; - c->entity_id = entity; - c->type = COLLIDER_AABB; - c->aabb.min = min; - c->aabb.max = max; - c->is_trigger = 0; - c->is_static = 0; - init_body(&c->body); - return idx; -} - -uint32_t physics_add_sphere(PhysicsWorld* world, uint32_t entity, Vec3 center, float radius) { - uint32_t idx = world->collider_count++; - Collider* c = &world->colliders[idx]; - c->entity_id = entity; - c->type = COLLIDER_SPHERE; - c->sphere.center = center; - c->sphere.radius = radius; - c->is_trigger = 0; - c->is_static = 0; - init_body(&c->body); - return idx; -} - -uint32_t physics_add_plane(PhysicsWorld* world, uint32_t entity, Vec3 normal, float distance) { - uint32_t idx = world->collider_count++; - Collider* c = &world->colliders[idx]; - c->entity_id = entity; - c->type = COLLIDER_PLANE; - vec3_normalize(&normal, &c->plane.normal); - c->plane.distance = distance; - c->is_trigger = 0; - c->is_static = 1; - init_body(&c->body); - c->body.mass = 0.0f; - c->body.is_kinematic = 1; - return idx; -} - -void physics_remove_collider(PhysicsWorld* world, uint32_t index) { - if (index < world->collider_count) { - world->colliders[index] = world->colliders[--world->collider_count]; - } -} - -void physics_update_collider(PhysicsWorld* world, uint32_t index, Vec3 position) { - if (!world || index >= world->collider_count) return; - Collider* c = &world->colliders[index]; - if (c->type == COLLIDER_SPHERE) { - c->sphere.center = position; - } else if (c->type == COLLIDER_AABB) { - Vec3 center = { - (c->aabb.min.x + c->aabb.max.x) * 0.5f, - (c->aabb.min.y + c->aabb.max.y) * 0.5f, - (c->aabb.min.z + c->aabb.max.z) * 0.5f - }; - Vec3 delta; - vec3_sub(&position, ¢er, &delta); - move_collider(c, delta); - } -} - -static int aabb_vs_aabb(const Collider* a, const Collider* b, Vec3* normal, float* depth) { - Vec3 diff; - Vec3 centerA = {(a->aabb.min.x + a->aabb.max.x) * 0.5f, (a->aabb.min.y + a->aabb.max.y) * 0.5f, (a->aabb.min.z + a->aabb.max.z) * 0.5f}; - Vec3 centerB = {(b->aabb.min.x + b->aabb.max.x) * 0.5f, (b->aabb.min.y + b->aabb.max.y) * 0.5f, (b->aabb.min.z + b->aabb.max.z) * 0.5f}; - vec3_sub(¢erA, ¢erB, &diff); - Vec3 half_a, half_b; - vec3_sub(&a->aabb.max, &a->aabb.min, &half_a); - vec3_scale(&half_a, 0.5f, &half_a); - vec3_sub(&b->aabb.max, &b->aabb.min, &half_b); - vec3_scale(&half_b, 0.5f, &half_b); - - float dx = fabsf(diff.x) - (half_a.x + half_b.x); - float dy = fabsf(diff.y) - (half_a.y + half_b.y); - float dz = fabsf(diff.z) - (half_a.z + half_b.z); - - if (dx < 0 && dy < 0 && dz < 0) { - *depth = -fmaxf(fmaxf(dx, dy), dz); - if (dx > dy && dx > dz) { *normal = (Vec3){copysignf(1.0f, diff.x), 0, 0}; } - else if (dy > dz) { normal->x = 0; normal->y = copysignf(1.0f, diff.y); normal->z = 0; } - else { normal->x = 0; normal->y = 0; normal->z = copysignf(1.0f, diff.z); } - return 1; - } - return 0; -} - -static int sphere_vs_sphere(const Collider* a, const Collider* b, Vec3* normal, float* depth) { - Vec3 diff; - vec3_sub(&a->sphere.center, &b->sphere.center, &diff); - float dist = vec3_length(&diff); - float radii = a->sphere.radius + b->sphere.radius; - - if (dist < radii) { - *depth = radii - dist; - if (dist > 0.0001f) { - vec3_normalize(&diff, normal); - } else { - *normal = (Vec3){0, 1, 0}; - } - return 1; - } - return 0; -} - -static int sphere_vs_aabb(const Collider* sphere, const Collider* aabb, Vec3* normal, float* depth) { - Vec3 closest; - closest.x = fmaxf(aabb->aabb.min.x, fminf(sphere->sphere.center.x, aabb->aabb.max.x)); - closest.y = fmaxf(aabb->aabb.min.y, fminf(sphere->sphere.center.y, aabb->aabb.max.y)); - closest.z = fmaxf(aabb->aabb.min.z, fminf(sphere->sphere.center.z, aabb->aabb.max.z)); - - Vec3 diff; - vec3_sub(&sphere->sphere.center, &closest, &diff); - float dist_sq = vec3_dot(&diff, &diff); - - if (dist_sq < sphere->sphere.radius * sphere->sphere.radius) { - float dist = sqrtf(dist_sq); - *depth = sphere->sphere.radius - dist; - if (dist > 0.0001f) { - vec3_normalize(&diff, normal); - } else { - *normal = (Vec3){0, 1, 0}; - } - return 1; - } - return 0; -} - -static int sphere_vs_plane(const Collider* sphere, const Collider* plane, Vec3* normal, float* depth) { - float dist = vec3_dot(&sphere->sphere.center, &plane->plane.normal) - plane->plane.distance; - if (dist < sphere->sphere.radius) { - *depth = sphere->sphere.radius - dist; - *normal = plane->plane.normal; - return 1; - } - return 0; -} - -int physics_check_collision(const Collider* a, const Collider* b, Vec3* normal, float* depth) { - if (a->type == COLLIDER_AABB && b->type == COLLIDER_AABB) - return aabb_vs_aabb(a, b, normal, depth); - if (a->type == COLLIDER_SPHERE && b->type == COLLIDER_SPHERE) - return sphere_vs_sphere(a, b, normal, depth); - if (a->type == COLLIDER_SPHERE && b->type == COLLIDER_AABB) - return sphere_vs_aabb(a, b, normal, depth); - if (a->type == COLLIDER_AABB && b->type == COLLIDER_SPHERE) { - int hit = sphere_vs_aabb(b, a, normal, depth); - if (hit) { normal->x = -normal->x; normal->y = -normal->y; normal->z = -normal->z; } - return hit; - } - if (a->type == COLLIDER_SPHERE && b->type == COLLIDER_PLANE) - return sphere_vs_plane(a, b, normal, depth); - if (a->type == COLLIDER_PLANE && b->type == COLLIDER_SPHERE) { - int hit = sphere_vs_plane(b, a, normal, depth); - if (hit) { normal->x = -normal->x; normal->y = -normal->y; normal->z = -normal->z; } - return hit; - } - return 0; -} - -int physics_raycast(PhysicsWorld* world, Vec3 origin, Vec3 direction, float max_dist, - uint32_t* hit_entity, Vec3* hit_point, Vec3* hit_normal) { - vec3_normalize(&direction, &direction); - float closest_t = max_dist; - int hit = 0; - - for (uint32_t i = 0; i < world->collider_count; i++) { - Collider* c = &world->colliders[i]; - if (c->type == COLLIDER_SPHERE) { - Vec3 oc; - vec3_sub(&origin, &c->sphere.center, &oc); - float a = vec3_dot(&direction, &direction); - float b = 2.0f * vec3_dot(&oc, &direction); - float cc = vec3_dot(&oc, &oc) - c->sphere.radius * c->sphere.radius; - float disc = b * b - 4 * a * cc; - if (disc >= 0) { - float t = (-b - sqrtf(disc)) / (2 * a); - if (t > 0 && t < closest_t) { - closest_t = t; - *hit_entity = c->entity_id; - Vec3 scaled; - vec3_scale(&direction, t, &scaled); - vec3_add(&origin, &scaled, hit_point); - vec3_sub(hit_point, &c->sphere.center, hit_normal); - vec3_normalize(hit_normal, hit_normal); - hit = 1; - } - } - } - } - return hit; -} - -static int body_is_movable(Collider* c) { - return !c->is_static && !c->body.is_kinematic && c->body.mass > 0.0f; -} - -static float body_inv_mass(Collider* c) { - if (c->is_static || c->body.is_kinematic || c->body.mass <= 0.0f) return 0.0f; - return 1.0f / c->body.mass; -} - -static void move_collider(Collider* c, Vec3 delta) { - if (c->type == COLLIDER_SPHERE) { - vec3_add(&c->sphere.center, &delta, &c->sphere.center); - } else if (c->type == COLLIDER_AABB) { - vec3_add(&c->aabb.min, &delta, &c->aabb.min); - vec3_add(&c->aabb.max, &delta, &c->aabb.max); - } -} - -RigidBody* physics_get_body(PhysicsWorld* world, uint32_t index) { - if (!world || index >= world->collider_count) return NULL; - return &world->colliders[index].body; -} - -void physics_apply_force(PhysicsWorld* world, uint32_t index, Vec3 force) { - RigidBody* b = physics_get_body(world, index); - if (!b || b->mass <= 0.0f) return; - Vec3 scaled; - vec3_scale(&force, 1.0f / b->mass, &scaled); - vec3_add(&b->acceleration, &scaled, &b->acceleration); -} - -void physics_apply_impulse(PhysicsWorld* world, uint32_t index, Vec3 impulse) { - RigidBody* b = physics_get_body(world, index); - if (!b || b->mass <= 0.0f) return; - Vec3 scaled; - vec3_scale(&impulse, 1.0f / b->mass, &scaled); - vec3_add(&b->velocity, &scaled, &b->velocity); -} - -void physics_step(PhysicsWorld* world, float dt) { - if (!world || world->collider_count == 0 || dt <= 0.0f) return; - - const float linear_damping = 0.995f; - - // 1. 积分动态刚体 - for (uint32_t i = 0; i < world->collider_count; i++) { - Collider* c = &world->colliders[i]; - if (!body_is_movable(c)) continue; - - RigidBody* b = &c->body; - if (world->gravity_enabled) { - vec3_add(&b->acceleration, &world->gravity, &b->acceleration); - } - - Vec3 dv; - vec3_scale(&b->acceleration, dt, &dv); - vec3_add(&b->velocity, &dv, &b->velocity); - b->acceleration = (Vec3){0, 0, 0}; - - vec3_scale(&b->velocity, linear_damping, &b->velocity); - - Vec3 dp; - vec3_scale(&b->velocity, dt, &dp); - move_collider(c, dp); - } - - // 2. 碰撞检测与响应 - for (uint32_t i = 0; i < world->collider_count; i++) { - Collider* a = &world->colliders[i]; - for (uint32_t j = i + 1; j < world->collider_count; j++) { - Collider* b = &world->colliders[j]; - if (a->is_static && b->is_static) continue; - - Vec3 normal; - float depth = 0.0f; - if (!physics_check_collision(a, b, &normal, &depth)) continue; - - // 触发器只报告,不解决 - if (a->is_trigger || b->is_trigger) continue; - - float inv_a = body_inv_mass(a); - float inv_b = body_inv_mass(b); - float total_inv = inv_a + inv_b; - if (total_inv <= 0.0f) continue; - - // 位置修正(防止沉入) - float percent = 0.5f; // 修正比例 - Vec3 correction; - vec3_scale(&normal, depth * percent / total_inv, &correction); - if (inv_a > 0.0f) { - Vec3 da; vec3_scale(&correction, inv_a, &da); - da.x = -da.x; da.y = -da.y; da.z = -da.z; - move_collider(a, da); - } - if (inv_b > 0.0f) { - Vec3 db; vec3_scale(&correction, inv_b, &db); - move_collider(b, db); - } - - // 冲量响应 - Vec3 rel_v; - vec3_sub(&a->body.velocity, &b->body.velocity, &rel_v); - float vel_along_normal = vec3_dot(&rel_v, &normal); - if (vel_along_normal > 0.0f) continue; // 正在分离 - - float e = fminf(a->body.restitution, b->body.restitution); - float j = -(1.0f + e) * vel_along_normal / total_inv; - - Vec3 impulse; - vec3_scale(&normal, j, &impulse); - if (inv_a > 0.0f) { - Vec3 va; vec3_scale(&impulse, inv_a, &va); - vec3_add(&a->body.velocity, &va, &a->body.velocity); - } - if (inv_b > 0.0f) { - Vec3 vb; vec3_scale(&impulse, inv_b, &vb); - vec3_sub(&b->body.velocity, &vb, &b->body.velocity); - } - - // 摩擦力 - vec3_sub(&a->body.velocity, &b->body.velocity, &rel_v); - Vec3 tangent; - Vec3 vn; vec3_scale(&normal, vec3_dot(&rel_v, &normal), &vn); - vec3_sub(&rel_v, &vn, &tangent); - float tan_len = vec3_length(&tangent); - if (tan_len > 0.0001f) { - vec3_scale(&tangent, 1.0f / tan_len, &tangent); - float jt = -vec3_dot(&rel_v, &tangent) / total_inv; - float mu = sqrtf(a->body.friction * a->body.friction + b->body.friction * b->body.friction); - if (jt > j * mu) jt = j * mu; - if (jt < -j * mu) jt = -j * mu; - Vec3 friction_impulse; - vec3_scale(&tangent, jt, &friction_impulse); - if (inv_a > 0.0f) { - Vec3 va; vec3_scale(&friction_impulse, inv_a, &va); - vec3_add(&a->body.velocity, &va, &a->body.velocity); - } - if (inv_b > 0.0f) { - Vec3 vb; vec3_scale(&friction_impulse, inv_b, &vb); - vec3_sub(&b->body.velocity, &vb, &b->body.velocity); - } - } - } - } -} - -void physics_set_gravity(PhysicsWorld* world, Vec3 gravity) { - world->gravity = gravity; -} diff --git a/Engine/Engine/Physics/physics.h b/Engine/Engine/Physics/physics.h deleted file mode 100644 index 7f7a2b5..0000000 --- a/Engine/Engine/Physics/physics.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -// ============================================================================ -// physics.h - 物理引擎 (碰撞检测, 调用ASM数学) -// ============================================================================ - -#include "../include/engine_api.h" -#include "../ASM/math_c_fallback.h" -#include - -#define MAX_COLLIDERS 1024 - -typedef enum { - COLLIDER_AABB, - COLLIDER_SPHERE, - COLLIDER_PLANE, -} ColliderType; - -typedef struct { - Vec3 velocity; - Vec3 acceleration; - float mass; - float restitution; - float friction; - int is_kinematic; -} RigidBody; - -typedef struct { - uint32_t entity_id; - ColliderType type; - union { - struct { Vec3 min; Vec3 max; } aabb; - struct { Vec3 center; float radius; } sphere; - struct { Vec3 normal; float distance; } plane; - }; - int is_trigger; - int is_static; - RigidBody body; -} Collider; - -typedef struct { - Collider colliders[MAX_COLLIDERS]; - uint32_t collider_count; - int gravity_enabled; - Vec3 gravity; -} PhysicsWorld; - -// 碰撞回调 -typedef void (*CollisionCallback)(uint32_t entity_a, uint32_t entity_b, Vec3 normal, float depth); - -// 创建/销毁 -PhysicsWorld* physics_create(void); -void physics_destroy(PhysicsWorld* world); - -// 碰撞体 -uint32_t physics_add_aabb(PhysicsWorld* world, uint32_t entity, Vec3 min, Vec3 max); -uint32_t physics_add_sphere(PhysicsWorld* world, uint32_t entity, Vec3 center, float radius); -uint32_t physics_add_plane(PhysicsWorld* world, uint32_t entity, Vec3 normal, float distance); -void physics_remove_collider(PhysicsWorld* world, uint32_t index); -void physics_update_collider(PhysicsWorld* world, uint32_t index, Vec3 position); - -// 碰撞检测 -int physics_check_collision(const Collider* a, const Collider* b, Vec3* normal, float* depth); -int physics_raycast(PhysicsWorld* world, Vec3 origin, Vec3 direction, float max_dist, - uint32_t* hit_entity, Vec3* hit_point, Vec3* hit_normal); - -// 刚体 -RigidBody* physics_get_body(PhysicsWorld* world, uint32_t index); -void physics_apply_force(PhysicsWorld* world, uint32_t index, Vec3 force); -void physics_apply_impulse(PhysicsWorld* world, uint32_t index, Vec3 impulse); - -// 模拟 -void physics_step(PhysicsWorld* world, float dt); -void physics_set_gravity(PhysicsWorld* world, Vec3 gravity); diff --git a/Engine/Engine/Rendering/camera.c b/Engine/Engine/Rendering/camera.c deleted file mode 100644 index 285cfcd..0000000 --- a/Engine/Engine/Rendering/camera.c +++ /dev/null @@ -1,135 +0,0 @@ -#include "camera.h" - -#include -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -Camera camera_perspective(float fov_y, float aspect, float near_z, float far_z) { - Camera cam = {0}; - cam.type = CAMERA_PERSPECTIVE; - cam.position = (Vec3){0, 0, -5}; - cam.target = (Vec3){0, 0, 0}; - cam.up = (Vec3){0, 1, 0}; - cam.fov_y = fov_y; - cam.aspect = aspect; - cam.near_z = near_z; - cam.far_z = far_z; - cam.dirty = 1; - return cam; -} - -Camera camera_orthographic(float width, float height, float near_z, float far_z) { - Camera cam = {0}; - cam.type = CAMERA_ORTHOGRAPHIC; - cam.position = (Vec3){0, 0, -5}; - cam.target = (Vec3){0, 0, 0}; - cam.up = (Vec3){0, 1, 0}; - cam.ortho_width = width; - cam.ortho_height = height; - cam.near_z = near_z; - cam.far_z = far_z; - cam.dirty = 1; - return cam; -} - -void camera_update(Camera* camera) { - if (!camera->dirty) return; - mat4_lookat(&camera->position, &camera->target, &camera->up, &camera->view); - - if (camera->type == CAMERA_PERSPECTIVE) { - mat4_perspective(camera->fov_y, camera->aspect, camera->near_z, camera->far_z, &camera->projection); - } else { - mat4_orthographic(camera->ortho_width, camera->ortho_height, camera->near_z, camera->far_z, &camera->projection); - } - camera->dirty = 0; -} - -const Mat4* camera_get_view(Camera* camera) { - camera_update(camera); - return &camera->view; -} - -const Mat4* camera_get_projection(Camera* camera) { - camera_update(camera); - return &camera->projection; -} - -void camera_move_forward(Camera* camera, float distance) { - Vec3 dir; - vec3_sub(&camera->target, &camera->position, &dir); - vec3_normalize(&dir, &dir); - Vec3 move; - vec3_scale(&dir, distance, &move); - vec3_add(&camera->position, &move, &camera->position); - vec3_add(&camera->target, &move, &camera->target); - camera->dirty = 1; -} - -void camera_move_right(Camera* camera, float distance) { - Vec3 forward, right; - vec3_sub(&camera->target, &camera->position, &forward); - vec3_normalize(&forward, &forward); - vec3_cross(&camera->up, &forward, &right); - vec3_normalize(&right, &right); - Vec3 move; - vec3_scale(&right, distance, &move); - vec3_add(&camera->position, &move, &camera->position); - vec3_add(&camera->target, &move, &camera->target); - camera->dirty = 1; -} - -void camera_move_up(Camera* camera, float distance) { - Vec3 move; - vec3_scale(&camera->up, distance, &move); - vec3_add(&camera->position, &move, &camera->position); - vec3_add(&camera->target, &move, &camera->target); - camera->dirty = 1; -} - -void camera_rotate_yaw(Camera* camera, float angle) { - Vec3 forward; - vec3_sub(&camera->target, &camera->position, &forward); - - float cs = cosf(angle), sn = sinf(angle); - Vec3 right; - vec3_cross(&forward, &camera->up, &right); - vec3_normalize(&right, &right); - - Vec3 new_forward = { - forward.x * cs + right.x * sn, - forward.y * cs + right.y * sn, - forward.z * cs + right.z * sn, - }; - vec3_add(&camera->position, &new_forward, &camera->target); - camera->dirty = 1; -} - -void camera_rotate_pitch(Camera* camera, float angle) { - Vec3 forward; - vec3_sub(&camera->target, &camera->position, &forward); - - Vec3 right; - vec3_cross(&forward, &camera->up, &right); - vec3_normalize(&right, &right); - - float cs = cosf(angle), sn = sinf(angle); - Vec3 new_forward = { - forward.x * cs + camera->up.x * sn, - forward.y * cs + camera->up.y * sn, - forward.z * cs + camera->up.z * sn, - }; - - Vec3 new_up; - vec3_cross(&right, &new_forward, &new_up); - camera->up = new_up; - vec3_add(&camera->position, &new_forward, &camera->target); - camera->dirty = 1; -} - -void camera_look_at(Camera* camera, Vec3 target) { - camera->target = target; - camera->dirty = 1; -} diff --git a/Engine/Engine/Rendering/camera.h b/Engine/Engine/Rendering/camera.h deleted file mode 100644 index 9a28863..0000000 --- a/Engine/Engine/Rendering/camera.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -// ============================================================================ -// camera.h - 摄像机 -// ============================================================================ - -#include "../include/engine_api.h" -#include "../ASM/math_c_fallback.h" - -typedef enum { - CAMERA_PERSPECTIVE, - CAMERA_ORTHOGRAPHIC, -} CameraType; - -typedef struct { - CameraType type; - Vec3 position; - Vec3 target; - Vec3 up; - float fov_y; - float aspect; - float near_z; - float far_z; - float ortho_width; - float ortho_height; - Mat4 view; - Mat4 projection; - int dirty; -} Camera; - -// 创建默认透视摄像机 -Camera camera_perspective(float fov_y, float aspect, float near_z, float far_z); - -// 创建正交摄像机 -Camera camera_orthographic(float width, float height, float near_z, float far_z); - -// 更新矩阵 -void camera_update(Camera* camera); - -// 获取矩阵 -const Mat4* camera_get_view(Camera* camera); -const Mat4* camera_get_projection(Camera* camera); - -// 移动 -void camera_move_forward(Camera* camera, float distance); -void camera_move_right(Camera* camera, float distance); -void camera_move_up(Camera* camera, float distance); - -// 旋转 -void camera_rotate_yaw(Camera* camera, float angle); -void camera_rotate_pitch(Camera* camera, float angle); - -// 设置目标 -void camera_look_at(Camera* camera, Vec3 target); diff --git a/Engine/Engine/Rendering/camera_controller.c b/Engine/Engine/Rendering/camera_controller.c deleted file mode 100644 index a022ad8..0000000 --- a/Engine/Engine/Rendering/camera_controller.c +++ /dev/null @@ -1,98 +0,0 @@ -#include "camera_controller.h" -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846f -#endif - -CameraController camera_controller_create(Camera* camera) { - CameraController ctrl = {0}; - ctrl.camera = camera; - ctrl.mode = CAMERA_MODE_FLY; - ctrl.move_speed = 10.0f; - ctrl.mouse_sensitivity = 0.003f; - ctrl.height_offset = 1.75f; - ctrl.pitch_min = -1.45f; - ctrl.pitch_max = 1.45f; - ctrl.yaw = 0.0f; - ctrl.pitch = 0.0f; - ctrl.ground_height_fn = NULL; - ctrl.ground_user = NULL; - return ctrl; -} - -void camera_controller_set_ground_callback(CameraController* ctrl, - float (*get_height)(float x, float z, void* user), - void* user) { - ctrl->ground_height_fn = get_height; - ctrl->ground_user = user; -} - -void camera_controller_set_mode(CameraController* ctrl, CameraMode mode) { - ctrl->mode = mode; -} - -void camera_controller_look(CameraController* ctrl, float delta_x, float delta_y) { - ctrl->yaw -= delta_x * ctrl->mouse_sensitivity; - ctrl->pitch -= delta_y * ctrl->mouse_sensitivity; - if (ctrl->pitch < ctrl->pitch_min) ctrl->pitch = ctrl->pitch_min; - if (ctrl->pitch > ctrl->pitch_max) ctrl->pitch = ctrl->pitch_max; - - // 重建 target - Vec3 forward; - forward.x = cosf(ctrl->pitch) * sinf(ctrl->yaw); - forward.y = sinf(ctrl->pitch); - forward.z = cosf(ctrl->pitch) * cosf(ctrl->yaw); - vec3_normalize(&forward, &forward); - - vec3_add(&ctrl->camera->position, &forward, &ctrl->camera->target); - ctrl->camera->dirty = 1; -} - -void camera_controller_move(CameraController* ctrl, Vec3 dir, float dt) { - Camera* cam = ctrl->camera; - - Vec3 forward, right, up; - vec3_sub(&cam->target, &cam->position, &forward); - forward.y = 0.0f; - vec3_normalize(&forward, &forward); - - vec3_cross(&cam->up, &forward, &right); - vec3_normalize(&right, &right); - - up = cam->up; - - Vec3 move = {0}; - Vec3 tmp; - vec3_scale(&right, dir.x, &tmp); - vec3_add(&move, &tmp, &move); - vec3_scale(&up, dir.y, &tmp); - vec3_add(&move, &tmp, &move); - vec3_scale(&forward, dir.z, &tmp); - vec3_add(&move, &tmp, &move); - - float len = vec3_length(&move); - if (len > 0.0001f) { - vec3_scale(&move, ctrl->move_speed * dt / len, &move); - vec3_add(&cam->position, &move, &cam->position); - vec3_add(&cam->target, &move, &cam->target); - cam->dirty = 1; - } -} - -void camera_controller_update(CameraController* ctrl, float dt) { - (void)dt; - if (ctrl->mode != CAMERA_MODE_WALK) return; - if (!ctrl->ground_height_fn) return; - - float ground = ctrl->ground_height_fn(ctrl->camera->position.x, ctrl->camera->position.z, ctrl->ground_user); - float desired_y = ground + ctrl->height_offset; - float delta = desired_y - ctrl->camera->position.y; - - if (fabsf(delta) > 0.01f) { - Vec3 move = {0, delta, 0}; - vec3_add(&ctrl->camera->position, &move, &ctrl->camera->position); - vec3_add(&ctrl->camera->target, &move, &ctrl->camera->target); - ctrl->camera->dirty = 1; - } -} diff --git a/Engine/Engine/Rendering/camera_controller.h b/Engine/Engine/Rendering/camera_controller.h deleted file mode 100644 index 8708eee..0000000 --- a/Engine/Engine/Rendering/camera_controller.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -// ============================================================================ -// camera_controller.h - 增强相机控制器(飞行 / 步行模式) -// ============================================================================ - -#include "camera.h" -#include "../ASM/math_c_fallback.h" - -typedef enum { - CAMERA_MODE_FLY, - CAMERA_MODE_WALK, -} CameraMode; - -typedef struct { - Camera* camera; - CameraMode mode; - float move_speed; - float mouse_sensitivity; - float height_offset; // 步行模式眼睛离地面高度 - float pitch_min; - float pitch_max; - float yaw; - float pitch; - float (*ground_height_fn)(float x, float z, void* user); - void* ground_user; -} CameraController; - -CameraController camera_controller_create(Camera* camera); - -// 更新 yaw/pitch,鼠标输入以 delta 像素为单位 -void camera_controller_look(CameraController* ctrl, float delta_x, float delta_y); - -// 移动:dir 为本地空间方向 (x=右, y=上, z=前) -void camera_controller_move(CameraController* ctrl, Vec3 dir, float dt); - -// 设置地形高度采样回调 -void camera_controller_set_ground_callback(CameraController* ctrl, float (*get_height)(float x, float z, void* user), void* user); - -// 切换模式 -void camera_controller_set_mode(CameraController* ctrl, CameraMode mode); - -// 每帧应用约束(如步行贴地) -void camera_controller_update(CameraController* ctrl, float dt); diff --git a/Engine/Engine/Rendering/frustum.c b/Engine/Engine/Rendering/frustum.c deleted file mode 100644 index 74f38a2..0000000 --- a/Engine/Engine/Rendering/frustum.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "frustum.h" -#include - -void frustum_from_matrix(const Mat4* vp, Vec4 planes[6]) { - // 行主序存储:clip = vec4(pos,1) * vp - // 因此 clip 分量 = dot(pos, vp 的列) - // left = col3 + col0 - // right = col3 - col0 - // bottom = col3 + col1 - // top = col3 - col1 - // near = col3 + col2 - // far = col3 - col2 - planes[0] = (Vec4){ vp->m[0][3] + vp->m[0][0], - vp->m[1][3] + vp->m[1][0], - vp->m[2][3] + vp->m[2][0], - vp->m[3][3] + vp->m[3][0] }; - planes[1] = (Vec4){ vp->m[0][3] - vp->m[0][0], - vp->m[1][3] - vp->m[1][0], - vp->m[2][3] - vp->m[2][0], - vp->m[3][3] - vp->m[3][0] }; - planes[2] = (Vec4){ vp->m[0][3] + vp->m[0][1], - vp->m[1][3] + vp->m[1][1], - vp->m[2][3] + vp->m[2][1], - vp->m[3][3] + vp->m[3][1] }; - planes[3] = (Vec4){ vp->m[0][3] - vp->m[0][1], - vp->m[1][3] - vp->m[1][1], - vp->m[2][3] - vp->m[2][1], - vp->m[3][3] - vp->m[3][1] }; - planes[4] = (Vec4){ vp->m[0][3] + vp->m[0][2], - vp->m[1][3] + vp->m[1][2], - vp->m[2][3] + vp->m[2][2], - vp->m[3][3] + vp->m[3][2] }; - planes[5] = (Vec4){ vp->m[0][3] - vp->m[0][2], - vp->m[1][3] - vp->m[1][2], - vp->m[2][3] - vp->m[2][2], - vp->m[3][3] - vp->m[3][2] }; - - for (int i = 0; i < 6; i++) { - float len = sqrtf(planes[i].x * planes[i].x + - planes[i].y * planes[i].y + - planes[i].z * planes[i].z); - if (len > 0.0001f) { - planes[i].x /= len; - planes[i].y /= len; - planes[i].z /= len; - planes[i].w /= len; - } - } -} - -int frustum_intersects_sphere(const Vec4 planes[6], Vec3 center, float radius) { - for (int i = 0; i < 6; i++) { - float dist = planes[i].x * center.x + - planes[i].y * center.y + - planes[i].z * center.z + - planes[i].w; - if (dist < -radius) return 0; - } - return 1; -} diff --git a/Engine/Engine/Rendering/frustum.h b/Engine/Engine/Rendering/frustum.h deleted file mode 100644 index 5c7e51c..0000000 --- a/Engine/Engine/Rendering/frustum.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include "../ASM/math_c_fallback.h" - -// 从视图*投影矩阵提取 6 个视锥平面(行主序,planes[0..5] = left, right, bottom, top, near, far) -void frustum_from_matrix(const Mat4* vp, Vec4 planes[6]); - -// 判断球体是否与视锥相交(1=可见/相交,0=完全在外) -int frustum_intersects_sphere(const Vec4 planes[6], Vec3 center, float radius); diff --git a/Engine/Engine/Rendering/graphics_device.c b/Engine/Engine/Rendering/graphics_device.c deleted file mode 100644 index 4166cd9..0000000 --- a/Engine/Engine/Rendering/graphics_device.c +++ /dev/null @@ -1,189 +0,0 @@ -#include "graphics_device.h" -#include -#include -#include - -GraphicsDevice* graphics_device_create(void) { - return (GraphicsDevice*)calloc(1, sizeof(GraphicsDevice)); -} - -void graphics_device_destroy(GraphicsDevice* d) { - if (!d) return; - if (d->depth_stencil) d->depth_stencil->lpVtbl->Release(d->depth_stencil); - if (d->depth_texture) d->depth_texture->lpVtbl->Release(d->depth_texture); - if (d->render_target) d->render_target->lpVtbl->Release(d->render_target); - if (d->swap_chain) d->swap_chain->lpVtbl->Release(d->swap_chain); - if (d->context) d->context->lpVtbl->Release(d->context); - if (d->device) d->device->lpVtbl->Release(d->device); - free(d); -} - -static int create_depth_stencil(GraphicsDevice* d, uint32_t w, uint32_t h) { - D3D11_TEXTURE2D_DESC desc = {0}; - desc.Width = w; desc.Height = h; - desc.MipLevels = 1; desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - HRESULT hr = d->device->lpVtbl->CreateTexture2D(d->device, &desc, NULL, &d->depth_texture); - if (FAILED(hr)) return 0; - D3D11_DEPTH_STENCIL_VIEW_DESC dsv = {0}; - dsv.Format = desc.Format; - dsv.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - hr = d->device->lpVtbl->CreateDepthStencilView(d->device, (ID3D11Resource*)d->depth_texture, &dsv, &d->depth_stencil); - return SUCCEEDED(hr); -} - -int graphics_device_init(GraphicsDevice* d, void* hwnd, uint32_t w, uint32_t h, int vsync) { - d->width = w; d->height = h; d->vsync = vsync; - DXGI_SWAP_CHAIN_DESC scd = {0}; - scd.BufferCount = 1; - scd.BufferDesc.Width = w; - scd.BufferDesc.Height = h; - scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - scd.BufferDesc.RefreshRate.Numerator = 60; - scd.BufferDesc.RefreshRate.Denominator = 1; - scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - scd.OutputWindow = (HWND)hwnd; - scd.SampleDesc.Count = 1; - scd.Windowed = TRUE; - scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - D3D_FEATURE_LEVEL levels[] = {D3D_FEATURE_LEVEL_11_0}; - UINT flags = 0; -#ifdef _DEBUG - flags |= D3D11_CREATE_DEVICE_DEBUG; -#endif - HRESULT hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, levels, 1, D3D11_SDK_VERSION, &scd, &d->swap_chain, &d->device, NULL, &d->context); - if (FAILED(hr)) return 0; - ID3D11Texture2D* back_buffer = NULL; - d->swap_chain->lpVtbl->GetBuffer(d->swap_chain, 0, &IID_ID3D11Texture2D, (void**)&back_buffer); - d->device->lpVtbl->CreateRenderTargetView(d->device, (ID3D11Resource*)back_buffer, NULL, &d->render_target); - if (back_buffer) back_buffer->lpVtbl->Release(back_buffer); - create_depth_stencil(d, w, h); - d->context->lpVtbl->OMSetRenderTargets(d->context, 1, &d->render_target, d->depth_stencil); - D3D11_VIEWPORT vp = {0}; - vp.Width = (float)w; vp.Height = (float)h; - vp.MaxDepth = 1.0f; - d->context->lpVtbl->RSSetViewports(d->context, 1, &vp); - - // 设置默认深度状态 (避免 UILayer init 破坏) - D3D11_DEPTH_STENCIL_DESC dsd = {0}; - dsd.DepthEnable = TRUE; - dsd.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - dsd.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; - ID3D11DepthStencilState* default_dss = NULL; - d->device->lpVtbl->CreateDepthStencilState(d->device, &dsd, &default_dss); - if (default_dss) { - d->context->lpVtbl->OMSetDepthStencilState(d->context, default_dss, 0); - default_dss->lpVtbl->Release(default_dss); - } - - // 设置默认光栅化状态:背面剔除 + 实体填充 - D3D11_RASTERIZER_DESC rd = {0}; - rd.FillMode = D3D11_FILL_SOLID; - rd.CullMode = D3D11_CULL_BACK; - rd.FrontCounterClockwise = FALSE; - rd.DepthClipEnable = TRUE; - ID3D11RasterizerState* default_rs = NULL; - d->device->lpVtbl->CreateRasterizerState(d->device, &rd, &default_rs); - if (default_rs) { - d->context->lpVtbl->RSSetState(d->context, default_rs); - default_rs->lpVtbl->Release(default_rs); - } - return 1; -} - -void graphics_device_resize(GraphicsDevice* d, uint32_t w, uint32_t h) { - if (w == 0 || h == 0) return; - d->context->lpVtbl->OMSetRenderTargets(d->context, 0, NULL, NULL); - if (d->render_target) { d->render_target->lpVtbl->Release(d->render_target); d->render_target = NULL; } - if (d->depth_stencil) { d->depth_stencil->lpVtbl->Release(d->depth_stencil); d->depth_stencil = NULL; } - if (d->depth_texture) { d->depth_texture->lpVtbl->Release(d->depth_texture); d->depth_texture = NULL; } - d->swap_chain->lpVtbl->ResizeBuffers(d->swap_chain, 0, w, h, DXGI_FORMAT_UNKNOWN, 0); - ID3D11Texture2D* back_buffer = NULL; - d->swap_chain->lpVtbl->GetBuffer(d->swap_chain, 0, &IID_ID3D11Texture2D, (void**)&back_buffer); - d->device->lpVtbl->CreateRenderTargetView(d->device, (ID3D11Resource*)back_buffer, NULL, &d->render_target); - if (back_buffer) back_buffer->lpVtbl->Release(back_buffer); - create_depth_stencil(d, w, h); - d->context->lpVtbl->OMSetRenderTargets(d->context, 1, &d->render_target, d->depth_stencil); - D3D11_VIEWPORT vp = {0}; - vp.Width = (float)w; vp.Height = (float)h; vp.MaxDepth = 1.0f; - d->context->lpVtbl->RSSetViewports(d->context, 1, &vp); - d->width = w; d->height = h; -} - -void graphics_device_clear(GraphicsDevice* d, float r, float g, float b, float a) { - float color[4] = {r, g, b, a}; - d->context->lpVtbl->ClearRenderTargetView(d->context, d->render_target, color); - d->context->lpVtbl->ClearDepthStencilView(d->context, d->depth_stencil, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); -} - -void graphics_device_present(GraphicsDevice* d) { - d->swap_chain->lpVtbl->Present(d->swap_chain, d->vsync ? 1 : 0, 0); -} - -int graphics_device_save_screenshot(GraphicsDevice* d, const char* path) { - if (!d || !d->swap_chain || !d->device || !d->context) return 0; - - ID3D11Texture2D* back = NULL; - HRESULT hr = d->swap_chain->lpVtbl->GetBuffer(d->swap_chain, 0, &IID_ID3D11Texture2D, (void**)&back); - if (FAILED(hr) || !back) return 0; - - D3D11_TEXTURE2D_DESC desc = {0}; - back->lpVtbl->GetDesc(back, &desc); - - D3D11_TEXTURE2D_DESC sd = desc; - sd.BindFlags = 0; - sd.Usage = D3D11_USAGE_STAGING; - sd.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - sd.MiscFlags = 0; - - ID3D11Texture2D* staging = NULL; - hr = d->device->lpVtbl->CreateTexture2D(d->device, &sd, NULL, &staging); - if (FAILED(hr) || !staging) { back->lpVtbl->Release(back); return 0; } - - d->context->lpVtbl->CopyResource(d->context, (ID3D11Resource*)staging, (ID3D11Resource*)back); - - D3D11_MAPPED_SUBRESOURCE map = {0}; - hr = d->context->lpVtbl->Map(d->context, (ID3D11Resource*)staging, 0, D3D11_MAP_READ, 0, &map); - if (FAILED(hr)) { staging->lpVtbl->Release(staging); back->lpVtbl->Release(back); return 0; } - - FILE* f = fopen(path, "wb"); - if (!f) { d->context->lpVtbl->Unmap(d->context, (ID3D11Resource*)staging, 0); staging->lpVtbl->Release(staging); back->lpVtbl->Release(back); return 0; } - - int w = (int)desc.Width; - int h = (int)desc.Height; - int row_size = ((w * 3 + 3) / 4) * 4; - int file_size = 54 + row_size * h; - - unsigned char header[54] = {0}; - header[0] = 'B'; header[1] = 'M'; - memcpy(header + 2, &file_size, 4); - header[10] = 54; - header[14] = 40; - memcpy(header + 18, &w, 4); - memcpy(header + 22, &h, 4); - header[26] = 1; - header[28] = 24; - fwrite(header, 1, 54, f); - - unsigned char* row = (unsigned char*)malloc(row_size); - for (int y = 0; y < h; y++) { - uint8_t* src = (uint8_t*)map.pData + (h - 1 - y) * map.RowPitch; - for (int x = 0; x < w; x++) { - // 后台缓冲区为 RGBA,BMP 24-bit 需要 BGR - row[x * 3 + 0] = src[x * 4 + 2]; - row[x * 3 + 1] = src[x * 4 + 1]; - row[x * 3 + 2] = src[x * 4 + 0]; - } - fwrite(row, 1, row_size, f); - } - free(row); - fclose(f); - - d->context->lpVtbl->Unmap(d->context, (ID3D11Resource*)staging, 0); - staging->lpVtbl->Release(staging); - back->lpVtbl->Release(back); - return 1; -} diff --git a/Engine/Engine/Rendering/graphics_device.h b/Engine/Engine/Rendering/graphics_device.h deleted file mode 100644 index 3bc05c3..0000000 --- a/Engine/Engine/Rendering/graphics_device.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include -#include -#include - -typedef struct GraphicsDevice GraphicsDevice; -struct GraphicsDevice { - ID3D11Device* device; - ID3D11DeviceContext* context; - IDXGISwapChain* swap_chain; - ID3D11RenderTargetView* render_target; - ID3D11DepthStencilView* depth_stencil; - ID3D11Texture2D* depth_texture; - uint32_t width; - uint32_t height; - int vsync; -}; - -GraphicsDevice* graphics_device_create(void); -void graphics_device_destroy(GraphicsDevice* d); -int graphics_device_init(GraphicsDevice* d, void* hwnd, uint32_t w, uint32_t h, int vsync); -void graphics_device_resize(GraphicsDevice* d, uint32_t w, uint32_t h); -void graphics_device_clear(GraphicsDevice* d, float r, float g, float b, float a); -void graphics_device_present(GraphicsDevice* d); -int graphics_device_save_screenshot(GraphicsDevice* d, const char* path); diff --git a/Engine/Engine/Rendering/lighting.c b/Engine/Engine/Rendering/lighting.c deleted file mode 100644 index 0c52240..0000000 --- a/Engine/Engine/Rendering/lighting.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "lighting.h" -#include -#include - -Light* light_create_dir(float r, float g, float b, float intensity, float dx, float dy, float dz) { - Light* l = (Light*)calloc(1, sizeof(Light)); - l->type = LIGHT_DIR; - l->color[0] = r; l->color[1] = g; l->color[2] = b; - l->intensity = intensity; - l->direction[0] = dx; l->direction[1] = dy; l->direction[2] = dz; - float len = sqrtf(dx*dx + dy*dy + dz*dz); - if (len > 0.0001f) { l->direction[0] /= len; l->direction[1] /= len; l->direction[2] /= len; } - return l; -} - -Light* light_create_point(float r, float g, float b, float intensity, float x, float y, float z, float range) { - Light* l = (Light*)calloc(1, sizeof(Light)); - l->type = LIGHT_POINT; - l->color[0] = r; l->color[1] = g; l->color[2] = b; - l->intensity = intensity; - l->position[0] = x; l->position[1] = y; l->position[2] = z; - l->range = range; - return l; -} - -void light_destroy(Light* light) { free(light); } diff --git a/Engine/Engine/Rendering/lighting.h b/Engine/Engine/Rendering/lighting.h deleted file mode 100644 index 08aaef0..0000000 --- a/Engine/Engine/Rendering/lighting.h +++ /dev/null @@ -1,17 +0,0 @@ -// lighting.h -#pragma once - -typedef enum { LIGHT_DIR=0, LIGHT_POINT } LightType; - -typedef struct { - LightType type; - float color[3]; - float intensity; - float direction[3]; - float position[3]; - float range; -} Light; - -Light* light_create_dir(float r, float g, float b, float intensity, float dx, float dy, float dz); -Light* light_create_point(float r, float g, float b, float intensity, float x, float y, float z, float range); -void light_destroy(Light* light); diff --git a/Engine/Engine/Rendering/material.c b/Engine/Engine/Rendering/material.c deleted file mode 100644 index b7d8fa9..0000000 --- a/Engine/Engine/Rendering/material.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "material.h" -#include - -Material* material_create(Shader* shader, Texture* texture) { - Material* m = (Material*)calloc(1, sizeof(Material)); - m->shader = shader; - m->texture = texture; - m->color = (Vec4){1.0f, 1.0f, 1.0f, 1.0f}; - m->use_texture = (texture != NULL) ? 1 : 0; - return m; -} - -void material_destroy(Material* m) { - free(m); -} diff --git a/Engine/Engine/Rendering/material.h b/Engine/Engine/Rendering/material.h deleted file mode 100644 index 1e0f87f..0000000 --- a/Engine/Engine/Rendering/material.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "shader.h" -#include "texture.h" -#include "../ASM/math_c_fallback.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - Shader* shader; - Texture* texture; - Vec4 color; - int use_texture; -} Material; - -Material* material_create(Shader* shader, Texture* texture); -void material_destroy(Material* m); - -#ifdef __cplusplus -} -#endif diff --git a/Engine/Engine/Rendering/mesh.c b/Engine/Engine/Rendering/mesh.c deleted file mode 100644 index 59c5a5f..0000000 --- a/Engine/Engine/Rendering/mesh.c +++ /dev/null @@ -1,204 +0,0 @@ -#include "mesh.h" -#include -#include -#include -#include -#ifndef MATH_ASM_AVAILABLE -#include "../ASM/math_c_fallback.h" -#endif - -#define POS(n,x,y,z,nx,ny,nz,u,v,r,g,b,a) {x,y,z, nx,ny,nz, u,v, r,g,b,a} - -static Mesh* create_mesh(ID3D11Device* dev, const void* verts, uint32_t vc, const uint32_t* idx, uint32_t ic, uint32_t stride) { - Mesh* m = (Mesh*)calloc(1, sizeof(Mesh)); - m->stride = stride; m->vcount = vc; m->icount = ic; - D3D11_BUFFER_DESC bd = {0}; - D3D11_SUBRESOURCE_DATA sd = {0}; - bd.ByteWidth = stride * vc; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = verts; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &m->vb); - if (idx && ic > 0) { - bd.ByteWidth = sizeof(uint32_t) * ic; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = idx; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &m->ib); - } - return m; -} - -void mesh_destroy(Mesh* m) { - if (!m) return; - if (m->ib) m->ib->lpVtbl->Release(m->ib); - if (m->vb) m->vb->lpVtbl->Release(m->vb); - free(m); -} - -void mesh_draw(Mesh* m, ID3D11DeviceContext* ctx) { - UINT stride = m->stride, offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &m->vb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, m->ib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->DrawIndexed(ctx, m->icount, 0, 0); -} - -Mesh* mesh_create_cube(ID3D11Device* dev) { - typedef struct { float p[3], n[3], uv[2], c[4]; } V; - V v[24] = { - POS(0,-.5f,-.5f,-.5f, 0,0,-1, 0,1, 1,1,1,1), POS(1, .5f,-.5f,-.5f, 0,0,-1, 1,1, 1,1,1,1), - POS(2, .5f, .5f,-.5f, 0,0,-1, 1,0, 1,1,1,1), POS(3,-.5f, .5f,-.5f, 0,0,-1, 0,0, 1,1,1,1), - POS(4, .5f,-.5f, .5f, 0,0, 1, 0,1, 1,1,1,1), POS(5,-.5f,-.5f, .5f, 0,0, 1, 1,1, 1,1,1,1), - POS(6,-.5f, .5f, .5f, 0,0, 1, 1,0, 1,1,1,1), POS(7, .5f, .5f, .5f, 0,0, 1, 0,0, 1,1,1,1), - POS(8,-.5f, .5f,-.5f, 0,1, 0, 0,1, 1,1,1,1), POS(9, .5f, .5f,-.5f, 0,1, 0, 1,1, 1,1,1,1), - POS(10,.5f, .5f, .5f, 0,1, 0, 1,0, 1,1,1,1), POS(11,-.5f, .5f, .5f, 0,1, 0, 0,0, 1,1,1,1), - POS(12,-.5f,-.5f, .5f, 0,-1,0, 0,1, 1,1,1,1), POS(13,.5f,-.5f, .5f, 0,-1,0, 1,1, 1,1,1,1), - POS(14,.5f,-.5f,-.5f, 0,-1,0, 1,0, 1,1,1,1), POS(15,-.5f,-.5f,-.5f, 0,-1,0, 0,0, 1,1,1,1), - POS(16,.5f,-.5f,-.5f, 1,0, 0, 0,1, 1,1,1,1), POS(17,.5f,-.5f, .5f, 1,0, 0, 1,1, 1,1,1,1), - POS(18,.5f, .5f, .5f, 1,0, 0, 1,0, 1,1,1,1), POS(19,.5f, .5f,-.5f, 1,0, 0, 0,0, 1,1,1,1), - POS(20,-.5f,-.5f, .5f, -1,0,0, 0,1, 1,1,1,1), POS(21,-.5f,-.5f,-.5f, -1,0,0, 1,1, 1,1,1,1), - POS(22,-.5f, .5f,-.5f, -1,0,0, 1,0, 1,1,1,1), POS(23,-.5f, .5f, .5f, -1,0,0, 0,0, 1,1,1,1), - }; - uint32_t idx[36]; - for (int i = 0; i < 6; i++) { int b = i*4; idx[i*6]=b; idx[i*6+1]=b+1; idx[i*6+2]=b+2; idx[i*6+3]=b; idx[i*6+4]=b+2; idx[i*6+5]=b+3; } - return create_mesh(dev, v, 24, idx, 36, sizeof(V)); -} - -Mesh* mesh_create_plane(ID3D11Device* dev, float size) { - typedef struct { float p[3], n[3], uv[2], c[4]; } V; - float h = size * 0.5f; - V v[4] = { - {{-h,0,h},{0,1,0},{0,1},{1,1,1,1}}, - {{ h,0,h},{0,1,0},{1,1},{1,1,1,1}}, - {{ h,0,-h},{0,1,0},{1,0},{1,1,1,1}}, - {{-h,0,-h},{0,1,0},{0,0},{1,1,1,1}}, - }; - uint32_t idx[6] = {0,1,2,0,2,3}; - return create_mesh(dev, v, 4, idx, 6, sizeof(V)); -} - -Mesh* mesh_create_sphere(ID3D11Device* dev, float r, int seg) { - typedef struct { float p[3], n[3], uv[2], c[4]; } V; - int vc = (seg+1)*(seg+1); - V* v = (V*)malloc(vc * sizeof(V)); - int vi = 0; - for (int lat = 0; lat <= seg; lat++) { - float theta = 3.14159265f * lat / seg; - float st = sinf(theta), ct = cosf(theta); - for (int lon = 0; lon <= seg; lon++) { - float phi = 2.0f * 3.14159265f * lon / seg; - float sp = sinf(phi), cp = cosf(phi); - float nx = cp*st, ny = ct, nz = sp*st; - v[vi].p[0] = nx*r; v[vi].p[1] = ny*r; v[vi].p[2] = nz*r; - v[vi].n[0] = nx; v[vi].n[1] = ny; v[vi].n[2] = nz; - v[vi].uv[0] = (float)lon/seg; v[vi].uv[1] = (float)lat/seg; - v[vi].c[0]=1; v[vi].c[1]=1; v[vi].c[2]=1; v[vi].c[3]=1; - vi++; - } - } - int ic = seg*seg*6; - uint32_t* idx = (uint32_t*)malloc(ic * sizeof(uint32_t)); - int ii = 0; - for (int lat = 0; lat < seg; lat++) { - for (int lon = 0; lon < seg; lon++) { - uint32_t f = lat*(seg+1)+lon, s = f+seg+1; - idx[ii++]=f; idx[ii++]=s; idx[ii++]=f+1; - idx[ii++]=s; idx[ii++]=s+1; idx[ii++]=f+1; - } - } - Mesh* m = create_mesh(dev, v, vc, idx, ic, sizeof(V)); - free(v); free(idx); - return m; -} - -// OBJ 加载器 -Mesh* mesh_load_obj(ID3D11Device* dev, const char* path) { - FILE* f = fopen(path, "r"); - if (!f) return NULL; - - // 先统计顶点和面数 - int max_v = 4096, max_f = 8192; - float* verts = (float*)malloc(max_v * 3 * sizeof(float)); - float* uvs = (float*)malloc(max_v * 2 * sizeof(float)); - int vert_count = 0, uv_count = 0; - int* face_idx = (int*)malloc(max_f * 3 * sizeof(int)); - int face_count = 0; - - char line[256]; - while (fgets(line, sizeof(line), f)) { - if (line[0] == 'v' && line[1] == ' ') { - float x, y, z; - if (sscanf(line + 2, "%f %f %f", &x, &y, &z) == 3 && vert_count < max_v) { - verts[vert_count * 3] = x; - verts[vert_count * 3 + 1] = y; - verts[vert_count * 3 + 2] = z; - vert_count++; - } - } else if (line[0] == 'v' && line[1] == 't') { - float u, v; - if (sscanf(line + 3, "%f %f", &u, &v) == 2 && uv_count < max_v) { - uvs[uv_count * 2] = u; - uvs[uv_count * 2 + 1] = v; - uv_count++; - } - } else if (line[0] == 'f' && line[1] == ' ') { - // 解析面: f v/vt v/vt v/vt 或 f v v v - int v0, v1, v2; - char* p = line + 2; - v0 = atoi(p) - 1; while (*p && *p != ' ') p++; p++; - v1 = atoi(p) - 1; while (*p && *p != ' ') p++; p++; - v2 = atoi(p) - 1; - if (v0 >= 0 && v1 >= 0 && v2 >= 0 && face_count < max_f) { - face_idx[face_count * 3] = v0; - face_idx[face_count * 3 + 1] = v1; - face_idx[face_count * 3 + 2] = v2; - face_count++; - } - } - } - fclose(f); - - if (vert_count == 0 || face_count == 0) { - free(verts); free(uvs); free(face_idx); - return NULL; - } - - // 构建去重顶点 (简单方案: 每个面一个顶点) - int out_vcount = face_count * 3; - Vertex* out_verts = (Vertex*)calloc(out_vcount, sizeof(Vertex)); - uint32_t* out_idx = (uint32_t*)malloc(face_count * 3 * sizeof(uint32_t)); - - for (int i = 0; i < face_count; i++) { - for (int j = 0; j < 3; j++) { - int vi = face_idx[i * 3 + j]; - int oi = i * 3 + j; - if (vi < vert_count) { - out_verts[oi].pos[0] = verts[vi * 3]; - out_verts[oi].pos[1] = verts[vi * 3 + 1]; - out_verts[oi].pos[2] = verts[vi * 3 + 2]; - } - out_verts[oi].color[0] = out_verts[oi].color[1] = out_verts[oi].color[2] = 1.0f; - out_verts[oi].color[3] = 1.0f; - out_idx[oi] = oi; - } - } - - // 简单法线计算 (面法线) - for (int i = 0; i < face_count; i++) { - float* p0 = out_verts[i * 3].pos; - float* p1 = out_verts[i * 3 + 1].pos; - float* p2 = out_verts[i * 3 + 2].pos; - float e1[3] = {p1[0] - p0[0], p1[1] - p0[1], p1[2] - p0[2]}; - float e2[3] = {p2[0] - p0[0], p2[1] - p0[1], p2[2] - p0[2]}; - float nx = e1[1]*e2[2] - e1[2]*e2[1]; - float ny = e1[2]*e2[0] - e1[0]*e2[2]; - float nz = e1[0]*e2[1] - e1[1]*e2[0]; - float nl = sqrtf(nx*nx + ny*ny + nz*nz); - if (nl > 0.0001f) { nx /= nl; ny /= nl; nz /= nl; } - for (int j = 0; j < 3; j++) { - out_verts[i * 3 + j].norm[0] = nx; - out_verts[i * 3 + j].norm[1] = ny; - out_verts[i * 3 + j].norm[2] = nz; - } - } - - Mesh* m = create_mesh(dev, out_verts, out_vcount, out_idx, face_count * 3, sizeof(Vertex)); - free(out_verts); free(out_idx); free(verts); free(uvs); free(face_idx); - return m; -} diff --git a/Engine/Engine/Rendering/mesh.h b/Engine/Engine/Rendering/mesh.h deleted file mode 100644 index 1dfc41a..0000000 --- a/Engine/Engine/Rendering/mesh.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include -#include - -typedef struct { - float pos[3]; - float norm[3]; - float uv[2]; - float color[4]; -} Vertex; - -typedef struct { - ID3D11Buffer* vb; - ID3D11Buffer* ib; - uint32_t vcount; - uint32_t icount; - uint32_t stride; -} Mesh; - -Mesh* mesh_create_cube(ID3D11Device* dev); -Mesh* mesh_create_plane(ID3D11Device* dev, float size); -Mesh* mesh_create_sphere(ID3D11Device* dev, float r, int seg); -Mesh* mesh_load_obj(ID3D11Device* dev, const char* path); -void mesh_destroy(Mesh* m); -void mesh_draw(Mesh* m, ID3D11DeviceContext* ctx); diff --git a/Engine/Engine/Rendering/renderer.c b/Engine/Engine/Rendering/renderer.c deleted file mode 100644 index 9504ab2..0000000 --- a/Engine/Engine/Rendering/renderer.c +++ /dev/null @@ -1,118 +0,0 @@ -#include "renderer.h" -#include "../Core/logger.h" -#include -#include - -static void fill_constant_buffer(float* cb, const Mat4* world, const Mat4* wvp, - Vec3 light_dir, Vec4 light_color, Vec4 ambient_color, - int use_texture, Vec4 diffuse_color) { - memcpy(cb + 0, world->m, sizeof(float) * 16); - memcpy(cb + 16, wvp->m, sizeof(float) * 16); - cb[32] = light_dir.x; cb[33] = light_dir.y; cb[34] = light_dir.z; cb[35] = 0.0f; - cb[36] = light_color.x; cb[37] = light_color.y; cb[38] = light_color.z; cb[39] = light_color.w; - cb[40] = ambient_color.x; cb[41] = ambient_color.y; cb[42] = ambient_color.z; cb[43] = ambient_color.w; - cb[44] = use_texture ? 1.0f : 0.0f; cb[45] = 0.0f; cb[46] = 0.0f; cb[47] = 0.0f; - cb[48] = diffuse_color.x; cb[49] = diffuse_color.y; cb[50] = diffuse_color.z; cb[51] = diffuse_color.w; -} - -Renderer* renderer_create(GraphicsDevice* device) { - Renderer* r = (Renderer*)calloc(1, sizeof(Renderer)); - r->device = device; - mat4_identity(&r->view); - mat4_identity(&r->projection); - r->light_dir = (Vec3){0.5f, -1.0f, 0.3f}; - r->light_color = (Vec4){1,1,1,1}; - r->ambient_color = (Vec4){0.2f,0.2f,0.3f,1}; - r->clear_color[0] = 0.1f; r->clear_color[1] = 0.1f; - r->clear_color[2] = 0.15f; r->clear_color[3] = 1.0f; - return r; -} - -void renderer_destroy(Renderer* r) { free(r); } - -void renderer_begin_frame(Renderer* r) { - ID3D11DeviceContext* ctx = r->device->context; - graphics_device_clear(r->device, r->clear_color[0], r->clear_color[1], r->clear_color[2], r->clear_color[3]); - D3D11_VIEWPORT vp = {0}; - vp.Width = (float)r->device->width; - vp.Height = (float)r->device->height; - vp.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vp); - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); -} - -void renderer_end_frame(Renderer* r) { - graphics_device_present(r->device); -} - -void renderer_draw_mesh(Renderer* r, Mesh* m) { - if (!r || !m || m->icount == 0) return; - if (!m->vb) { LOG_ERROR("renderer_draw_mesh: null vertex buffer"); return; } - if (!m->ib) { LOG_ERROR("renderer_draw_mesh: null index buffer"); return; } - ID3D11DeviceContext* ctx = r->device->context; - UINT stride = sizeof(Vertex); - UINT offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &m->vb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, m->ib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->DrawIndexed(ctx, m->icount, 0, 0); -} - -void renderer_draw_mesh_with_shader(Renderer* r, Mesh* m, Shader* s, const Mat4* world, Texture* t) { - if (!m || !s || !r) return; - ID3D11DeviceContext* ctx = r->device->context; - shader_bind(s, ctx); - - Mat4 wvp; - mat4_multiply(world, &r->view, &wvp); - mat4_multiply(&wvp, &r->projection, &wvp); - - float cb[64]; - memset(cb, 0, sizeof(cb)); - fill_constant_buffer(cb, world, &wvp, r->light_dir, r->light_color, r->ambient_color, t ? 1 : 0, (Vec4){1,1,1,1}); - - shader_set_matrix(s, ctx, cb); - if (t) texture_bind(t, ctx, 0); - - renderer_draw_mesh(r, m); -} - -void renderer_draw_mesh_with_material(Renderer* r, Mesh* m, Material* mat, const Mat4* world) { - if (!m || !mat || !mat->shader || !r) return; - ID3D11DeviceContext* ctx = r->device->context; - shader_bind(mat->shader, ctx); - - Mat4 wvp; - mat4_multiply(world, &r->view, &wvp); - mat4_multiply(&wvp, &r->projection, &wvp); - - float cb[64]; - memset(cb, 0, sizeof(cb)); - fill_constant_buffer(cb, world, &wvp, r->light_dir, r->light_color, r->ambient_color, - mat->use_texture, mat->color); - - shader_set_matrix(mat->shader, ctx, cb); - if (mat->use_texture && mat->texture) texture_bind(mat->texture, ctx, 0); - - renderer_draw_mesh(r, m); -} - -void renderer_set_view(Renderer* r, const Mat4* v) { r->view = *v; } -void renderer_set_projection(Renderer* r, const Mat4* p) { r->projection = *p; } -void renderer_set_light(Renderer* r, Vec3 d, Vec4 c, Vec4 a) { r->light_dir=d; r->light_color=c; r->ambient_color=a; } -void renderer_set_clear_color(Renderer* r, float rc, float g, float b, float a) { - if (!r) return; - r->clear_color[0] = rc; r->clear_color[1] = g; - r->clear_color[2] = b; r->clear_color[3] = a; -} -GraphicsDevice* renderer_get_device(Renderer* r) { return r ? r->device : NULL; } - -void renderer_get_view_projection(const Renderer* r, Mat4* out) { - if (!r || !out) return; - mat4_multiply(&r->view, &r->projection, out); -} - -void renderer_resize(Renderer* r, int width, int height) { - if (r && r->device && width > 0 && height > 0) { - graphics_device_resize(r->device, width, height); - } -} diff --git a/Engine/Engine/Rendering/renderer.h b/Engine/Engine/Rendering/renderer.h deleted file mode 100644 index 37fad16..0000000 --- a/Engine/Engine/Rendering/renderer.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include "graphics_device.h" -#include "shader.h" -#include "mesh.h" -#include "texture.h" -#include "camera.h" -#include "material.h" -#include "../include/engine_api.h" -#include "../ASM/math_c_fallback.h" - -typedef struct Renderer Renderer; -struct Renderer { - GraphicsDevice* device; - Shader* current_shader; - Mat4 view; - Mat4 projection; - Vec3 light_dir; - Vec4 light_color; - Vec4 ambient_color; - float clear_color[4]; -}; - -Renderer* renderer_create(GraphicsDevice* device); -void renderer_destroy(Renderer* renderer); -void renderer_begin_frame(Renderer* renderer); -void renderer_end_frame(Renderer* renderer); -void renderer_draw_mesh(Renderer* renderer, Mesh* mesh); -void renderer_draw_mesh_with_shader(Renderer* renderer, Mesh* mesh, Shader* shader, const Mat4* world, Texture* tex); -void renderer_draw_mesh_with_material(Renderer* renderer, Mesh* mesh, Material* material, const Mat4* world); -void renderer_set_view(Renderer* renderer, const Mat4* view); -void renderer_set_projection(Renderer* renderer, const Mat4* projection); -void renderer_set_light(Renderer* renderer, Vec3 dir, Vec4 color, Vec4 ambient); -void renderer_set_clear_color(Renderer* renderer, float r, float g, float b, float a); -GraphicsDevice* renderer_get_device(Renderer* renderer); -void renderer_resize(Renderer* renderer, int width, int height); -void renderer_get_view_projection(const Renderer* renderer, Mat4* out); diff --git a/Engine/Engine/Rendering/shader.c b/Engine/Engine/Rendering/shader.c deleted file mode 100644 index e1c1e60..0000000 --- a/Engine/Engine/Rendering/shader.c +++ /dev/null @@ -1,84 +0,0 @@ -#include "shader.h" -#include "../Core/logger.h" -#include -#include -#include - -static const char* default_vs = - "struct VS_IN{float3 pos:POSITION;float3 n:NORMAL;float2 uv:TEXCOORD;float4 col:COLOR;};" - "struct PS_IN{float4 pos:SV_POSITION;float3 world_n:NORMAL;float2 uv:TEXCOORD;float4 col:COLOR;};" - "cbuffer CB:register(b0){float4x4 World;float4x4 WVP;float4 LightDir;float4 LightColor;float4 AmbientColor;float4 UseTexture;float4 DiffuseColor;};" - "PS_IN main(VS_IN i){PS_IN o;o.pos=mul(float4(i.pos,1),WVP);o.world_n=normalize(mul(float4(i.n,0),World).xyz);o.uv=i.uv;o.col=i.col*DiffuseColor;return o;}"; - -static const char* default_ps = - "struct PS_IN{float4 pos:SV_POSITION;float3 world_n:NORMAL;float2 uv:TEXCOORD;float4 col:COLOR;};" - "cbuffer CB:register(b0){float4x4 World;float4x4 WVP;float4 LightDir;float4 LightColor;float4 AmbientColor;float4 UseTexture;float4 DiffuseColor;};" - "Texture2D tex:register(t0);SamplerState samp:register(s0);" - "float4 main(PS_IN i):SV_TARGET{float3 ld=normalize(LightDir.xyz);float diff=saturate(dot(i.world_n,ld));float4 light=AmbientColor+LightColor*diff;float4 albedo=i.col;if(UseTexture.x>0.5)albedo=albedo*tex.Sample(samp,i.uv);return albedo*light;}"; - -static ID3DBlob* compile_shader(const char* code, uint32_t len, const char* target) { - ID3DBlob *blob = NULL, *err = NULL; - UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL3 | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR; - D3DCompile(code, len, NULL, NULL, NULL, "main", target, flags, 0, &blob, &err); - if (err) { - const char* msg = (const char*)err->lpVtbl->GetBufferPointer(err); - LOG_ERROR("Shader compile error (%s): %s", target, msg); - err->lpVtbl->Release(err); - } - return blob; -} - -Shader* shader_create(void) { - return (Shader*)calloc(1, sizeof(Shader)); -} - -void shader_destroy(Shader* s) { - if (!s) return; - if (s->cb) s->cb->lpVtbl->Release(s->cb); - if (s->layout) s->layout->lpVtbl->Release(s->layout); - if (s->ps) s->ps->lpVtbl->Release(s->ps); - if (s->vs) s->vs->lpVtbl->Release(s->vs); - free(s); -} - -int shader_compile(Shader* s, ID3D11Device* dev, const char* vs_code, const char* ps_code, uint32_t vs_len, uint32_t ps_len) { - if (!vs_code || !ps_code) { - vs_code = default_vs; ps_code = default_ps; - vs_len = (uint32_t)strlen(default_vs); ps_len = (uint32_t)strlen(default_ps); - } - ID3DBlob* vs_blob = compile_shader(vs_code, vs_len, "vs_5_0"); - ID3DBlob* ps_blob = compile_shader(ps_code, ps_len, "ps_5_0"); - if (!vs_blob || !ps_blob) { - LOG_ERROR("Failed to compile default shader (vs=%p ps=%p)", (void*)vs_blob, (void*)ps_blob); - if (vs_blob) vs_blob->lpVtbl->Release(vs_blob); - if (ps_blob) ps_blob->lpVtbl->Release(ps_blob); - return 0; - } - dev->lpVtbl->CreateVertexShader(dev, vs_blob->lpVtbl->GetBufferPointer(vs_blob), vs_blob->lpVtbl->GetBufferSize(vs_blob), NULL, &s->vs); - dev->lpVtbl->CreatePixelShader(dev, ps_blob->lpVtbl->GetBufferPointer(ps_blob), ps_blob->lpVtbl->GetBufferSize(ps_blob), NULL, &s->ps); - D3D11_INPUT_ELEMENT_DESC layout[] = { - {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}, - }; - dev->lpVtbl->CreateInputLayout(dev, layout, 4, vs_blob->lpVtbl->GetBufferPointer(vs_blob), vs_blob->lpVtbl->GetBufferSize(vs_blob), &s->layout); - D3D11_BUFFER_DESC bd = {0}; - bd.ByteWidth = 256; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - dev->lpVtbl->CreateBuffer(dev, &bd, NULL, &s->cb); - vs_blob->lpVtbl->Release(vs_blob); - ps_blob->lpVtbl->Release(ps_blob); - return 1; -} - -void shader_bind(Shader* s, ID3D11DeviceContext* ctx) { - ctx->lpVtbl->VSSetShader(ctx, s->vs, NULL, 0); - ctx->lpVtbl->PSSetShader(ctx, s->ps, NULL, 0); - ctx->lpVtbl->IASetInputLayout(ctx, s->layout); - ctx->lpVtbl->VSSetConstantBuffers(ctx, 0, 1, &s->cb); - ctx->lpVtbl->PSSetConstantBuffers(ctx, 0, 1, &s->cb); -} - -void shader_set_matrix(Shader* s, ID3D11DeviceContext* ctx, const float* data) { - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)s->cb, 0, NULL, data, 0, 0); -} diff --git a/Engine/Engine/Rendering/shader.h b/Engine/Engine/Rendering/shader.h deleted file mode 100644 index 00924f3..0000000 --- a/Engine/Engine/Rendering/shader.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once -#include -#include - -typedef struct { - ID3D11VertexShader* vs; - ID3D11PixelShader* ps; - ID3D11InputLayout* layout; - ID3D11Buffer* cb; -} Shader; - -Shader* shader_create(void); -void shader_destroy(Shader* s); -int shader_compile(Shader* s, ID3D11Device* dev, const char* vs_code, const char* ps_code, uint32_t vs_len, uint32_t ps_len); -void shader_bind(Shader* s, ID3D11DeviceContext* ctx); -void shader_set_matrix(Shader* s, ID3D11DeviceContext* ctx, const float* data); diff --git a/Engine/Engine/Rendering/texture.c b/Engine/Engine/Rendering/texture.c deleted file mode 100644 index 3cb964f..0000000 --- a/Engine/Engine/Rendering/texture.c +++ /dev/null @@ -1,231 +0,0 @@ -#include "texture.h" - -#include -#include -#include - -#pragma comment(lib, "windowscodecs.lib") - -// 为 MinGW 提供 COM 助手宏(MSVC 已内联提供) -#ifndef _MSC_VER -#define ID3D11ShaderResourceView_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11Texture2D_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11Device_CreateTexture2D(p,a,b,c) (p)->lpVtbl->CreateTexture2D(p,a,b,c) -#define ID3D11Device_CreateShaderResourceView(p,a,b,c) (p)->lpVtbl->CreateShaderResourceView(p,a,b,c) -#define ID3D11DeviceContext_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) -#define ID3D11DeviceContext_PSSetShaderResources(p,a,b,c) (p)->lpVtbl->PSSetShaderResources(p,a,b,c) -#define ID3D11DeviceContext_PSSetSamplers(p,a,b,c) (p)->lpVtbl->PSSetSamplers(p,a,b,c) -#define ID3D11Device_CreateSamplerState(p,a,b) (p)->lpVtbl->CreateSamplerState(p,a,b) - -#define IWICBitmapDecoder_GetFrame(p,a,b) (p)->lpVtbl->GetFrame(p,a,b) -#define IWICBitmapFrameDecode_GetSize(p,a,b) (p)->lpVtbl->GetSize(p,a,b) -#define IWICImagingFactory_CreateFormatConverter(p,a) (p)->lpVtbl->CreateFormatConverter(p,a) -#define IWICFormatConverter_Initialize(p,a,b,c,d,e,f) (p)->lpVtbl->Initialize(p,a,b,c,d,e,f) -#define IWICFormatConverter_CopyPixels(p,a,b,c,d) (p)->lpVtbl->CopyPixels(p,a,b,c,d) -#define IWICFormatConverter_Release(p) (p)->lpVtbl->Release(p) -#define IWICBitmapFrameDecode_Release(p) (p)->lpVtbl->Release(p) -#define IWICImagingFactory_CreateDecoderFromFilename(p,a,b,c,d,e) (p)->lpVtbl->CreateDecoderFromFilename(p,a,b,c,d,e) -#define IWICBitmapDecoder_Release(p) (p)->lpVtbl->Release(p) -#define IWICImagingFactory_CreateStream(p,a) (p)->lpVtbl->CreateStream(p,a) -#define IWICStream_InitializeFromMemory(p,a,b) (p)->lpVtbl->InitializeFromMemory(p,a,b) -#define IWICImagingFactory_CreateDecoderFromStream(p,a,b,c,d) (p)->lpVtbl->CreateDecoderFromStream(p,a,b,c,d) -#define IWICStream_Release(p) (p)->lpVtbl->Release(p) -#endif - -static IWICImagingFactory* wic_factory = NULL; - -static HRESULT ensure_wic(void) { - if (wic_factory) return S_OK; - return CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICImagingFactory, (void**)&wic_factory); -} - -Texture* texture_create(void) { - return (Texture*)calloc(1, sizeof(Texture)); -} - -void texture_destroy(Texture* texture) { - if (!texture) return; - if (texture->srv) ID3D11ShaderResourceView_Release(texture->srv); - if (texture->texture) ID3D11Texture2D_Release(texture->texture); - free(texture); -} - -static Texture* create_from_wic(ID3D11Device* device, IWICBitmapDecoder* decoder) { - IWICBitmapFrameDecode* frame = NULL; - IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - - uint32_t w, h; - IWICBitmapFrameDecode_GetSize(frame, &w, &h); - - IWICFormatConverter* converter = NULL; - IWICImagingFactory_CreateFormatConverter(wic_factory, &converter); - IWICFormatConverter_Initialize(converter, (IWICBitmapSource*)frame, - &GUID_WICPixelFormat32bppRGBA, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom); - - uint8_t* pixels = (uint8_t*)malloc(w * h * 4); - IWICFormatConverter_CopyPixels(converter, NULL, w * 4, w * h * 4, pixels); - IWICFormatConverter_Release(converter); - IWICBitmapFrameDecode_Release(frame); - - D3D11_TEXTURE2D_DESC desc = {0}; - desc.Width = w; - desc.Height = h; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - - D3D11_SUBRESOURCE_DATA init = {pixels, w * 4, 0}; - - Texture* tex = texture_create(); - ID3D11Device_CreateTexture2D(device, &desc, &init, &tex->texture); - - D3D11_SHADER_RESOURCE_VIEW_DESC srvd = {0}; - srvd.Format = desc.Format; - srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvd.Texture2D.MipLevels = 1; - ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource*)tex->texture, &srvd, &tex->srv); - - tex->width = w; - tex->height = h; - tex->mip_levels = 1; - - free(pixels); - return tex; -} - -Texture* texture_load_from_file(ID3D11Device* device, const char* path) { - if (FAILED(ensure_wic())) return NULL; - - IWICBitmapDecoder* decoder = NULL; - wchar_t wpath[512]; - MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, 512); - - HRESULT hr = IWICImagingFactory_CreateDecoderFromFilename(wic_factory, wpath, NULL, - GENERIC_READ, WICDecodeMetadataCacheOnLoad, &decoder); - if (FAILED(hr)) return NULL; - - Texture* tex = create_from_wic(device, decoder); - IWICBitmapDecoder_Release(decoder); - return tex; -} - -Texture* texture_load_from_memory(ID3D11Device* device, const uint8_t* data, uint32_t size) { - if (FAILED(ensure_wic())) return NULL; - - IWICStream* stream = NULL; - IWICImagingFactory_CreateStream(wic_factory, &stream); - IWICStream_InitializeFromMemory(stream, (BYTE*)data, size); - - IWICBitmapDecoder* decoder = NULL; - IWICImagingFactory_CreateDecoderFromStream(wic_factory, (IStream*)stream, NULL, - WICDecodeMetadataCacheOnLoad, &decoder); - IWICStream_Release(stream); - - if (!decoder) return NULL; - Texture* tex = create_from_wic(device, decoder); - IWICBitmapDecoder_Release(decoder); - return tex; -} - -Texture* texture_create_solid(ID3D11Device* device, uint32_t w, uint32_t h, - uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - uint8_t* pixels = (uint8_t*)malloc(w * h * 4); - for (uint32_t i = 0; i < w * h; i++) { - pixels[i * 4 + 0] = r; - pixels[i * 4 + 1] = g; - pixels[i * 4 + 2] = b; - pixels[i * 4 + 3] = a; - } - - D3D11_TEXTURE2D_DESC desc = {0}; - desc.Width = w; - desc.Height = h; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - - D3D11_SUBRESOURCE_DATA init = {pixels, w * 4, 0}; - - Texture* tex = texture_create(); - ID3D11Device_CreateTexture2D(device, &desc, &init, &tex->texture); - - D3D11_SHADER_RESOURCE_VIEW_DESC srvd = {0}; - srvd.Format = desc.Format; - srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvd.Texture2D.MipLevels = 1; - ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource*)tex->texture, &srvd, &tex->srv); - - tex->width = w; - tex->height = h; - free(pixels); - return tex; -} - -Texture* texture_create_checkerboard(ID3D11Device* device, uint32_t size, uint32_t checks) { - uint8_t* pixels = (uint8_t*)malloc(size * size * 4); - uint32_t cell = size / checks; - for (uint32_t y = 0; y < size; y++) { - for (uint32_t x = 0; x < size; x++) { - uint8_t c = ((x / cell) + (y / cell)) % 2 ? 200 : 55; - uint32_t i = (y * size + x) * 4; - pixels[i] = pixels[i + 1] = pixels[i + 2] = c; - pixels[i + 3] = 255; - } - } - - D3D11_TEXTURE2D_DESC desc = {0}; - desc.Width = size; - desc.Height = size; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - - D3D11_SUBRESOURCE_DATA init = {pixels, size * 4, 0}; - - Texture* tex = texture_create(); - ID3D11Device_CreateTexture2D(device, &desc, &init, &tex->texture); - - D3D11_SHADER_RESOURCE_VIEW_DESC srvd = {0}; - srvd.Format = desc.Format; - srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvd.Texture2D.MipLevels = 1; - ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource*)tex->texture, &srvd, &tex->srv); - - tex->width = size; - tex->height = size; - free(pixels); - return tex; -} - -void texture_bind(Texture* texture, ID3D11DeviceContext* ctx, uint32_t slot) { - if (!texture || !texture->srv) return; - static ID3D11SamplerState* default_sampler = NULL; - if (!default_sampler) { - ID3D11Device* device = NULL; - ctx->lpVtbl->GetDevice(ctx, &device); - if (device) { - D3D11_SAMPLER_DESC sd = {0}; - sd.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; - sd.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; - sd.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; - sd.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; - sd.ComparisonFunc = D3D11_COMPARISON_NEVER; - sd.MinLOD = 0; - sd.MaxLOD = D3D11_FLOAT32_MAX; - device->lpVtbl->CreateSamplerState(device, &sd, &default_sampler); - device->lpVtbl->Release(device); - } - } - ctx->lpVtbl->PSSetShaderResources(ctx, slot, 1, &texture->srv); - ctx->lpVtbl->PSSetSamplers(ctx, slot, 1, &default_sampler); -} diff --git a/Engine/Engine/Rendering/texture.h b/Engine/Engine/Rendering/texture.h deleted file mode 100644 index a1e5648..0000000 --- a/Engine/Engine/Rendering/texture.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -// ============================================================================ -// texture.h - 纹理加载 (WIC) -// ============================================================================ - -#include -#include - -typedef struct { - ID3D11Texture2D* texture; - ID3D11ShaderResourceView* srv; - uint32_t width; - uint32_t height; - uint32_t mip_levels; -} Texture; - -// 创建/销毁 -Texture* texture_create(void); -void texture_destroy(Texture* texture); - -// 从文件加载 -Texture* texture_load_from_file(ID3D11Device* device, const char* path); - -// 从内存加载 -Texture* texture_load_from_memory(ID3D11Device* device, - const uint8_t* data, uint32_t size); - -// 创建纯色纹理 -Texture* texture_create_solid(ID3D11Device* device, uint32_t w, uint32_t h, - uint8_t r, uint8_t g, uint8_t b, uint8_t a); - -// 创建棋盘格 -Texture* texture_create_checkerboard(ID3D11Device* device, uint32_t size, uint32_t checks); - -// 绑定 -void texture_bind(Texture* texture, ID3D11DeviceContext* ctx, uint32_t slot); diff --git a/Engine/Engine/Scene/scene_graph.c b/Engine/Engine/Scene/scene_graph.c deleted file mode 100644 index b5f55d5..0000000 --- a/Engine/Engine/Scene/scene_graph.c +++ /dev/null @@ -1,226 +0,0 @@ -// ============================================================================ -// scene_graph.c - 场景图实现 -// ============================================================================ - -#include "scene_graph.h" -#include -#include -#include - -void scene_init(Scene* scene) { - memset(scene, 0, sizeof(Scene)); - scene->next_id = 1; - // 创建根节点 - scene->root = &scene->nodes[0]; - memset(scene->root, 0, sizeof(SceneNode)); - scene->root->id = scene->next_id++; - strcpy(scene->root->name, "Root"); - scene->root->scale = (Vec3){1, 1, 1}; - scene->root->visible = 1; - scene->root->dirty = 1; - scene->node_count = 1; -} - -void scene_destroy(Scene* scene) { - // 清空子节点引用 (不释放静态数组) - for (int i = 0; i < scene->node_count; i++) { - scene->nodes[i].parent = NULL; - scene->nodes[i].child_count = 0; - } - scene->node_count = 0; -} - -SceneNode* scene_create_node(Scene* scene, const char* name) { - if (scene->node_count >= MAX_NODES) return NULL; - SceneNode* node = &scene->nodes[scene->node_count++]; - memset(node, 0, sizeof(SceneNode)); - node->id = scene->next_id++; - strncpy(node->name, name, 63); - node->scale = (Vec3){1, 1, 1}; - node->visible = 1; - node->dirty = 1; - return node; -} - -void scene_destroy_node(Scene* scene, SceneNode* node) { - if (!node || node == scene->root) return; - // 移除子引用 - if (node->parent) { - scene_remove_child(node->parent, node); - } - // 递归销毁子节点 - while (node->child_count > 0) { - scene_destroy_node(scene, node->children[0]); - } - node->id = 0; // 标记为空 -} - -SceneNode* scene_find_node(Scene* scene, int id) { - for (int i = 0; i < scene->node_count; i++) { - if (scene->nodes[i].id == id) return &scene->nodes[i]; - } - return NULL; -} - -SceneNode* scene_find_by_name(Scene* scene, const char* name) { - for (int i = 0; i < scene->node_count; i++) { - if (strcmp(scene->nodes[i].name, name) == 0) return &scene->nodes[i]; - } - return NULL; -} - -void scene_set_parent(SceneNode* child, SceneNode* parent) { - if (!child || !parent || child == parent) return; - if (child->parent) scene_remove_child(child->parent, child); - child->parent = parent; - if (parent->child_count < MAX_CHILDREN) { - parent->children[parent->child_count++] = child; - } - child->dirty = 1; -} - -void scene_add_child(SceneNode* parent, SceneNode* child) { - scene_set_parent(child, parent); -} - -void scene_remove_child(SceneNode* parent, SceneNode* child) { - if (!parent || !child) return; - for (int i = 0; i < parent->child_count; i++) { - if (parent->children[i] == child) { - parent->children[i] = parent->children[parent->child_count - 1]; - parent->child_count--; - child->parent = NULL; - child->dirty = 1; - return; - } - } -} - -void scene_set_position(SceneNode* node, float x, float y, float z) { - node->position = (Vec3){x, y, z}; - node->dirty = 1; -} - -void scene_set_rotation_euler(SceneNode* node, float rx, float ry, float rz) { - // 欧拉角转四元数 (YXZ 顺序) - float cr = cosf(rx * 0.5f), sr = sinf(rx * 0.5f); - float cp = cosf(ry * 0.5f), sp = sinf(ry * 0.5f); - float cy = cosf(rz * 0.5f), sy = sinf(rz * 0.5f); - node->rotation = (Quat){ - sr * cp * cy - cr * sp * sy, - cr * sp * cy + sr * cp * sy, - cr * cp * sy - sr * sp * cy, - cr * cp * cy + sr * sp * sy - }; - node->dirty = 1; -} - -void scene_set_scale(SceneNode* node, float sx, float sy, float sz) { - node->scale = (Vec3){sx, sy, sz}; - node->dirty = 1; -} - -void scene_set_rotation_quat(SceneNode* node, const Quat* q) { - node->rotation = *q; - node->dirty = 1; -} - -void scene_mark_dirty(SceneNode* node) { - node->dirty = 1; - for (int i = 0; i < node->child_count; i++) { - scene_mark_dirty(node->children[i]); - } -} - -static void update_local_matrix(SceneNode* node) { - // 旋转矩阵 - Mat4 rot; - quat_to_matrix(&node->rotation, &rot); - - // 缩放矩阵 - Mat4 scl; - mat4_identity(&scl); - scl.m[0][0] = node->scale.x; - scl.m[1][1] = node->scale.y; - scl.m[2][2] = node->scale.z; - - // 平移矩阵 - Mat4 trl; - mat4_translate(node->position.x, node->position.y, node->position.z, &trl); - - // local = trl * rot * scl - Mat4 tmp; - mat4_multiply(&rot, &scl, &tmp); - mat4_multiply(&trl, &tmp, &node->local_matrix); -} - -static void update_world_matrices(SceneNode* node) { - if (node->dirty) { - update_local_matrix(node); - if (node->parent) { - mat4_multiply(&node->parent->world_matrix, &node->local_matrix, &node->world_matrix); - } else { - node->world_matrix = node->local_matrix; - } - node->dirty = 0; - } - for (int i = 0; i < node->child_count; i++) { - update_world_matrices(node->children[i]); - } -} - -void scene_update(Scene* scene) { - if (scene->root) { - update_world_matrices(scene->root); - } -} - -void scene_get_world_position(SceneNode* node, Vec3* out) { - out->x = node->world_matrix.m[3][0]; - out->y = node->world_matrix.m[3][1]; - out->z = node->world_matrix.m[3][2]; -} - -void scene_get_world_rotation(SceneNode* node, Quat* out) { - // 从世界矩阵提取四元数 - Mat4 m = node->world_matrix; - float tr = m.m[0][0] + m.m[1][1] + m.m[2][2]; - if (tr > 0) { - float s = 0.5f / sqrtf(tr + 1.0f); - out->w = 0.25f / s; - out->x = (m.m[2][1] - m.m[1][2]) * s; - out->y = (m.m[0][2] - m.m[2][0]) * s; - out->z = (m.m[1][0] - m.m[0][1]) * s; - } else if (m.m[0][0] > m.m[1][1] && m.m[0][0] > m.m[2][2]) { - float s = 2.0f * sqrtf(1.0f + m.m[0][0] - m.m[1][1] - m.m[2][2]); - out->w = (m.m[2][1] - m.m[1][2]) / s; - out->x = 0.25f * s; - out->y = (m.m[0][1] + m.m[1][0]) / s; - out->z = (m.m[0][2] + m.m[2][0]) / s; - } else if (m.m[1][1] > m.m[2][2]) { - float s = 2.0f * sqrtf(1.0f + m.m[1][1] - m.m[0][0] - m.m[2][2]); - out->w = (m.m[0][2] - m.m[2][0]) / s; - out->x = (m.m[0][1] + m.m[1][0]) / s; - out->y = 0.25f * s; - out->z = (m.m[1][2] + m.m[2][1]) / s; - } else { - float s = 2.0f * sqrtf(1.0f + m.m[2][2] - m.m[0][0] - m.m[1][1]); - out->w = (m.m[1][0] - m.m[0][1]) / s; - out->x = (m.m[0][2] + m.m[2][0]) / s; - out->y = (m.m[1][2] + m.m[2][1]) / s; - out->z = 0.25f * s; - } -} - -void scene_get_world_scale(SceneNode* node, Vec3* out) { - // 从世界矩阵提取缩放 (各列向量的长度) - out->x = sqrtf(node->world_matrix.m[0][0] * node->world_matrix.m[0][0] + - node->world_matrix.m[0][1] * node->world_matrix.m[0][1] + - node->world_matrix.m[0][2] * node->world_matrix.m[0][2]); - out->y = sqrtf(node->world_matrix.m[1][0] * node->world_matrix.m[1][0] + - node->world_matrix.m[1][1] * node->world_matrix.m[1][1] + - node->world_matrix.m[1][2] * node->world_matrix.m[1][2]); - out->z = sqrtf(node->world_matrix.m[2][0] * node->world_matrix.m[2][0] + - node->world_matrix.m[2][1] * node->world_matrix.m[2][1] + - node->world_matrix.m[2][2] * node->world_matrix.m[2][2]); -} diff --git a/Engine/Engine/Scene/scene_graph.h b/Engine/Engine/Scene/scene_graph.h deleted file mode 100644 index 2d06eeb..0000000 --- a/Engine/Engine/Scene/scene_graph.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -// ============================================================================ -// scene_graph.h - 场景图: 节点树 + 变换继承 -// ============================================================================ - -#include "../ASM/math_c_fallback.h" -#include - -#define MAX_CHILDREN 64 -#define MAX_NODES 1024 - -// 场景节点 -typedef struct SceneNode { - int id; - char name[64]; - - // 本地变换 - Vec3 position; - Quat rotation; - Vec3 scale; - - // 世界矩阵 (每帧由 scene_update 计算) - Mat4 world_matrix; - Mat4 local_matrix; - - // 层级 - struct SceneNode* parent; - struct SceneNode* children[MAX_CHILDREN]; - int child_count; - - // 标志 - int visible; - int dirty; // 需要重新计算矩阵 - - // 用户数据 - void* user_data; - int user_type; -} SceneNode; - -// 场景 -typedef struct Scene { - SceneNode nodes[MAX_NODES]; - int node_count; - SceneNode* root; - int next_id; -} Scene; - -// 初始化/销毁 -void scene_init(Scene* scene); -void scene_destroy(Scene* scene); - -// 节点管理 -SceneNode* scene_create_node(Scene* scene, const char* name); -void scene_destroy_node(Scene* scene, SceneNode* node); -SceneNode* scene_find_node(Scene* scene, int id); -SceneNode* scene_find_by_name(Scene* scene, const char* name); - -// 层级 -void scene_set_parent(SceneNode* child, SceneNode* parent); -void scene_add_child(SceneNode* parent, SceneNode* child); -void scene_remove_child(SceneNode* parent, SceneNode* child); - -// 变换 -void scene_set_position(SceneNode* node, float x, float y, float z); -void scene_set_rotation_euler(SceneNode* node, float rx, float ry, float rz); -void scene_set_scale(SceneNode* node, float sx, float sy, float sz); -void scene_set_rotation_quat(SceneNode* node, const Quat* q); -void scene_mark_dirty(SceneNode* node); - -// 每帧更新 -void scene_update(Scene* scene); - -// 获取世界变换 -void scene_get_world_position(SceneNode* node, Vec3* out); -void scene_get_world_rotation(SceneNode* node, Quat* out); -void scene_get_world_scale(SceneNode* node, Vec3* out); diff --git a/Engine/Engine/Scene/scene_render.c b/Engine/Engine/Scene/scene_render.c deleted file mode 100644 index 5d41dba..0000000 --- a/Engine/Engine/Scene/scene_render.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "scene_render.h" -#include -#include - -void scene_node_set_mesh_renderer(SceneNode* node, MeshRenderer* renderer) { - if (!node) return; - node->user_type = 1; - node->user_data = renderer; -} - -MeshRenderer* scene_node_get_mesh_renderer(SceneNode* node) { - if (!node || node->user_type != 1) return NULL; - return (MeshRenderer*)node->user_data; -} - -static void scene_render_node_recursive(SceneNode* node, Renderer* r) { - if (!node || !node->visible) return; - - MeshRenderer* mr = scene_node_get_mesh_renderer(node); - if (mr && mr->mesh && mr->material) { - renderer_draw_mesh_with_material(r, mr->mesh, mr->material, &node->world_matrix); - } - - for (int i = 0; i < node->child_count; i++) { - scene_render_node_recursive(node->children[i], r); - } -} - -void scene_render(Scene* scene, Renderer* r) { - if (!scene || !r) return; - scene_render_node_recursive(scene->root, r); -} - -MeshRenderer* mesh_renderer_create(MeshType type, Mesh* mesh, Material* material) { - MeshRenderer* mr = (MeshRenderer*)calloc(1, sizeof(MeshRenderer)); - mr->type = type; - mr->mesh = mesh; - mr->material = material; - mr->path[0] = '\0'; - return mr; -} - -void mesh_renderer_destroy(MeshRenderer* mr) { - if (!mr) return; - if (mr->material) material_destroy(mr->material); - free(mr); -} - -static void destroy_renderers_recursive(SceneNode* node) { - if (!node) return; - MeshRenderer* mr = scene_node_get_mesh_renderer(node); - if (mr) { - mesh_renderer_destroy(mr); - node->user_data = NULL; - node->user_type = 0; - } - for (int i = 0; i < node->child_count; i++) { - destroy_renderers_recursive(node->children[i]); - } -} - -void scene_destroy_renderers(Scene* scene) { - if (!scene) return; - destroy_renderers_recursive(scene->root); -} diff --git a/Engine/Engine/Scene/scene_render.h b/Engine/Engine/Scene/scene_render.h deleted file mode 100644 index e0c0926..0000000 --- a/Engine/Engine/Scene/scene_render.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "scene_graph.h" -#include "../Rendering/renderer.h" -#include "../Rendering/mesh.h" -#include "../Rendering/material.h" -#include "../Rendering/shader.h" -#include "../Rendering/texture.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - MESH_NONE = 0, - MESH_CUBE = 1, - MESH_SPHERE = 2, - MESH_PLANE = 3, - MESH_OBJ = 4 -} MeshType; - -typedef struct { - MeshType type; - Mesh* mesh; - Material* material; - char path[256]; -} MeshRenderer; - -void scene_node_set_mesh_renderer(SceneNode* node, MeshRenderer* renderer); -MeshRenderer* scene_node_get_mesh_renderer(SceneNode* node); - -void scene_render_node(SceneNode* node, Renderer* r); -void scene_render(Scene* scene, Renderer* r); - -MeshRenderer* mesh_renderer_create(MeshType type, Mesh* mesh, Material* material); -void mesh_renderer_destroy(MeshRenderer* mr); -void scene_destroy_renderers(Scene* scene); - -#ifdef __cplusplus -} -#endif diff --git a/Engine/Engine/Scene/scene_serialize.c b/Engine/Engine/Scene/scene_serialize.c deleted file mode 100644 index d98b913..0000000 --- a/Engine/Engine/Scene/scene_serialize.c +++ /dev/null @@ -1,141 +0,0 @@ -#include "scene_serialize.h" -#include "scene_render.h" -#include "../ASM/math_c_fallback.h" -#include -#include -#include -#include - -#ifndef PI -#define PI 3.14159265f -#endif - -static int node_index(Scene* scene, SceneNode* node) { - if (!scene || !node) return -1; - return (int)(node - scene->nodes); -} - -static const char* mesh_type_name(MeshType t) { - switch (t) { - case MESH_CUBE: return "CUBE"; - case MESH_SPHERE: return "SPHERE"; - case MESH_PLANE: return "PLANE"; - case MESH_OBJ: return "OBJ"; - default: return "NONE"; - } -} - -static MeshType parse_mesh_type(const char* s) { - if (!s) return MESH_NONE; - if (strcmp(s, "CUBE") == 0) return MESH_CUBE; - if (strcmp(s, "SPHERE") == 0) return MESH_SPHERE; - if (strcmp(s, "PLANE") == 0) return MESH_PLANE; - if (strcmp(s, "OBJ") == 0) return MESH_OBJ; - return MESH_NONE; -} - -static void write_node(FILE* f, Scene* scene, SceneNode* node) { - if (!node) return; - int parent = (node == scene->root) ? -1 : node_index(scene, node->parent); - MeshRenderer* mr = scene_node_get_mesh_renderer(node); - MeshType type = mr ? mr->type : MESH_NONE; - const char* path = (mr && mr->path[0]) ? mr->path : "-"; - - float ex = 0.0f, ey = 0.0f, ez = 0.0f; - quat_to_euler(&node->rotation, &ex, &ey, &ez); - - fprintf(f, "%s %d %s %s %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\n", - node->name, parent, mesh_type_name(type), path, - node->position.x, node->position.y, node->position.z, - ex * 180.0f / PI, ey * 180.0f / PI, ez * 180.0f / PI, - node->scale.x, node->scale.y, node->scale.z); - - for (int i = 0; i < node->child_count; i++) { - write_node(f, scene, node->children[i]); - } -} - -int scene_save(Scene* scene, const char* path) { - if (!scene || !path) return 0; - FILE* f = fopen(path, "w"); - if (!f) return 0; - fprintf(f, "LITY3D_SCENE 1\n"); - write_node(f, scene, scene->root); - fclose(f); - return 1; -} - -static Mesh* create_mesh_for_type(MeshType type, ID3D11Device* dev, const char* path) { - switch (type) { - case MESH_CUBE: return mesh_create_cube(dev); - case MESH_SPHERE: return mesh_create_sphere(dev, 1.0f, 16); - case MESH_PLANE: return mesh_create_plane(dev, 10.0f); - case MESH_OBJ: return path ? mesh_load_obj(dev, path) : NULL; - default: return NULL; - } -} - -Scene* scene_load(const char* path, ID3D11Device* dev, Shader* default_shader) { - FILE* f = fopen(path, "r"); - if (!f) return NULL; - - char line[512]; - if (!fgets(line, sizeof(line), f)) { fclose(f); return NULL; } - if (strncmp(line, "LITY3D_SCENE", 10) != 0) { fclose(f); return NULL; } - - Scene* scene = (Scene*)malloc(sizeof(Scene)); - if (!scene) { fclose(f); return NULL; } - scene_init(scene); - - int capacity = 64; - SceneNode** nodes = (SceneNode**)malloc(sizeof(SceneNode*) * capacity); - int count = 0; - - while (fgets(line, sizeof(line), f)) { - char name[64]; - char type_str[16]; - char path_str[256]; - int parent_id; - float px, py, pz, degx, degy, degz, sx, sy, sz; - if (sscanf(line, "%63s %d %15s %255s %f %f %f %f %f %f %f %f %f", - name, &parent_id, type_str, path_str, - &px, &py, &pz, °x, °y, °z, &sx, &sy, &sz) != 13) { - continue; - } - - if (count >= capacity) { - capacity *= 2; - nodes = (SceneNode**)realloc(nodes, sizeof(SceneNode*) * capacity); - } - - SceneNode* parent = (parent_id < 0) ? scene->root : nodes[parent_id]; - SceneNode* node = scene_create_node(scene, name); - if (!node) continue; - if (parent) scene_set_parent(node, parent); - - node->position = (Vec3){px, py, pz}; - node->scale = (Vec3){sx, sy, sz}; - quat_from_euler(degx * PI / 180.0f, degy * PI / 180.0f, degz * PI / 180.0f, &node->rotation); - - MeshType type = parse_mesh_type(type_str); - if (type != MESH_NONE) { - const char* mesh_path = (strcmp(path_str, "-") == 0) ? NULL : path_str; - Mesh* mesh = create_mesh_for_type(type, dev, mesh_path); - if (mesh) { - Material* mat = material_create(default_shader, NULL); - MeshRenderer* mr = mesh_renderer_create(type, mesh, mat); - if (mesh_path) strncpy(mr->path, mesh_path, sizeof(mr->path) - 1); - scene_node_set_mesh_renderer(node, mr); - } - } - - nodes[count] = node; - count++; - } - - free(nodes); - fclose(f); - - scene_update(scene); - return scene; -} diff --git a/Engine/Engine/Scene/scene_serialize.h b/Engine/Engine/Scene/scene_serialize.h deleted file mode 100644 index 5fbac28..0000000 --- a/Engine/Engine/Scene/scene_serialize.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "scene_graph.h" -#include "../Rendering/shader.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int scene_save(Scene* scene, const char* path); -Scene* scene_load(const char* path, ID3D11Device* dev, Shader* default_shader); - -#ifdef __cplusplus -} -#endif diff --git a/Engine/Engine/Scripting/lua_engine.c b/Engine/Engine/Scripting/lua_engine.c deleted file mode 100644 index b04eb13..0000000 --- a/Engine/Engine/Scripting/lua_engine.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "lua_engine.h" - -#include -#include - -// Lua头文件 (需要单独下载或集成) -// #include -// #include -// #include - -// 由于Lua需要单独集成,这里提供占位实现 -// 实际使用时取消注释并链接Lua库 - -typedef struct lua_State lua_State; - -static lua_State* luaL_newstate(void) { return NULL; } -static void luaL_openlibs(lua_State* L) { (void)L; } -static int luaL_dofile(lua_State* L, const char* fn) { (void)L; (void)fn; return -1; } -static int luaL_dostring(lua_State* L, const char* s) { (void)L; (void)s; return -1; } -static void lua_close(lua_State* L) { (void)L; } - -LuaEngine* lua_engine_create(void) { - return (LuaEngine*)calloc(1, sizeof(LuaEngine)); -} - -void lua_engine_destroy(LuaEngine* engine) { - if (!engine) return; - if (engine->L) lua_close(engine->L); - free(engine); -} - -int lua_engine_init(LuaEngine* engine) { - engine->L = luaL_newstate(); - if (!engine->L) return -1; - luaL_openlibs(engine->L); - engine->initialized = 1; - return 0; -} - -int lua_engine_do_file(LuaEngine* engine, const char* path) { - if (!engine->L) return -1; - return luaL_dofile(engine->L, path); -} - -int lua_engine_do_string(LuaEngine* engine, const char* code) { - if (!engine->L) return -1; - return luaL_dostring(engine->L, code); -} - -void lua_engine_register_function(LuaEngine* engine, const char* name, void* func) { - (void)engine; - (void)name; - (void)func; - // lua_pushcfunction(engine->L, func); - // lua_setglobal(engine->L, name); -} - -lua_State* lua_engine_get_state(LuaEngine* engine) { - return engine->L; -} diff --git a/Engine/Engine/Scripting/lua_engine.h b/Engine/Engine/Scripting/lua_engine.h deleted file mode 100644 index 2e70d19..0000000 --- a/Engine/Engine/Scripting/lua_engine.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -// ============================================================================ -// lua_engine.h - Lua脚本引擎 -// ============================================================================ - -#include - -// 前向声明 -struct lua_State; - -typedef struct { - struct lua_State* L; - int initialized; -} LuaEngine; - -// 创建/销毁 -LuaEngine* lua_engine_create(void); -void lua_engine_destroy(LuaEngine* engine); - -// 初始化 -int lua_engine_init(LuaEngine* engine); - -// 执行 -int lua_engine_do_file(LuaEngine* engine, const char* path); -int lua_engine_do_string(LuaEngine* engine, const char* code); - -// 注册C函数 -void lua_engine_register_function(LuaEngine* engine, const char* name, void* func); - -// 获取状态 -struct lua_State* lua_engine_get_state(LuaEngine* engine); diff --git a/Engine/Engine/Terrain/terrain.c b/Engine/Engine/Terrain/terrain.c deleted file mode 100644 index 5729bb6..0000000 --- a/Engine/Engine/Terrain/terrain.c +++ /dev/null @@ -1,289 +0,0 @@ -#include "terrain.h" -#include -#include -#include - -// ============================================================================ -// 简单的 Value Noise + 叠加 -// ============================================================================ - -float hash_noise(int x, int z, int seed) { - unsigned int n = (unsigned int)x * 374761393u - + (unsigned int)z * 668265263u - + (unsigned int)seed * 1013904223u; - n = (n ^ (n >> 13)) * 1274126177u; - n = n ^ (n >> 16); - return (float)(n & 0x7fffffffu) / (float)0x7fffffffu; -} - -static float smooth_noise(float x, float z, int seed) { - int ix = (int)floorf(x); - int iz = (int)floorf(z); - float fx = x - ix; - float fz = z - iz; - - float v00 = hash_noise(ix, iz, seed); - float v10 = hash_noise(ix + 1, iz, seed); - float v01 = hash_noise(ix, iz + 1, seed); - float v11 = hash_noise(ix + 1, iz + 1, seed); - - float u = fx * fx * (3.0f - 2.0f * fx); - float v = fz * fz * (3.0f - 2.0f * fz); - - float a = v00 + (v10 - v00) * u; - float b = v01 + (v11 - v01) * u; - return a + (b - a) * v; -} - -float fbm_noise(float x, float z, int seed, int octaves, float persistence) { - float total = 0.0f; - float amplitude = 1.0f; - float frequency = 1.0f; - float max_value = 0.0f; - for (int i = 0; i < octaves; i++) { - total += smooth_noise(x * frequency, z * frequency, seed + i * 57) * amplitude; - max_value += amplitude; - amplitude *= persistence; - frequency *= 2.0f; - } - return total / max_value; -} - -// ============================================================================ -// 高度图 -// ============================================================================ - -TerrainConfig terrain_default_config(void) { - TerrainConfig cfg = {0}; - cfg.chunks_x = 4; - cfg.chunks_z = 4; - cfg.vertices_per_chunk = 32; - cfg.chunk_size = 64.0f; - cfg.height_scale = 20.0f; - cfg.uv_scale = 0.1f; - return cfg; -} - -TerrainHeightmap terrain_heightmap_create(int size) { - TerrainHeightmap hm = {0}; - if (size < 2) size = 2; - if (size > TERRAIN_MAX_HEIGHTMAP_SIZE) size = TERRAIN_MAX_HEIGHTMAP_SIZE; - hm.size = size; - hm.data = (float*)calloc(size * size, sizeof(float)); - return hm; -} - -void terrain_heightmap_destroy(TerrainHeightmap* hm) { - if (hm && hm->data) { - free(hm->data); - hm->data = NULL; - hm->size = 0; - } -} - -void terrain_heightmap_fill_noise(TerrainHeightmap* hm, int seed, float scale, float amplitude) { - if (!hm || !hm->data) return; - int s = hm->size; - for (int z = 0; z < s; z++) { - for (int x = 0; x < s; x++) { - float nx = (float)x / (float)(s - 1) * scale; - float nz = (float)z / (float)(s - 1) * scale; - float h = fbm_noise(nx, nz, seed, 6, 0.5f); - hm->data[z * s + x] = h * amplitude; - } - } -} - -float terrain_heightmap_sample(const TerrainHeightmap* hm, float x, float z) { - if (!hm || !hm->data || hm->size < 2) return 0.0f; - int s = hm->size; - float fx = x * (float)(s - 1); - float fz = z * (float)(s - 1); - int ix = (int)floorf(fx); - int iz = (int)floorf(fz); - if (ix < 0) ix = 0; - if (iz < 0) iz = 0; - if (ix >= s - 1) ix = s - 2; - if (iz >= s - 1) iz = s - 2; - float tx = fx - ix; - float tz = fz - iz; - - float h00 = hm->data[iz * s + ix]; - float h10 = hm->data[iz * s + ix + 1]; - float h01 = hm->data[(iz + 1) * s + ix]; - float h11 = hm->data[(iz + 1) * s + ix + 1]; - - float a = h00 + (h10 - h00) * tx; - float b = h01 + (h11 - h01) * tx; - return a + (b - a) * tz; -} - -// ============================================================================ -// 地形网格 -// ============================================================================ - -static Mesh* create_mesh_from_terrain(ID3D11Device* dev, const TerrainHeightmap* hm, - float size, float height_scale, float uv_scale) { - if (!hm || !hm->data || hm->size < 2) return NULL; - int s = hm->size; - int vc = s * s; - int ic = (s - 1) * (s - 1) * 6; - - Vertex* verts = (Vertex*)calloc(vc, sizeof(Vertex)); - uint32_t* idx = (uint32_t*)malloc(ic * sizeof(uint32_t)); - - float half = size * 0.5f; - float step = size / (float)(s - 1); - - for (int z = 0; z < s; z++) { - for (int x = 0; x < s; x++) { - int i = z * s + x; - float px = (float)x * step - half; - float pz = (float)z * step - half; - float py = hm->data[i] * height_scale; - verts[i].pos[0] = px; - verts[i].pos[1] = py; - verts[i].pos[2] = pz; - verts[i].uv[0] = (float)x * uv_scale; - verts[i].uv[1] = (float)z * uv_scale; - verts[i].color[0] = 1.0f; - verts[i].color[1] = 1.0f; - verts[i].color[2] = 1.0f; - verts[i].color[3] = 1.0f; - } - } - - // 计算法线 - memset(verts, 0, vc * sizeof(Vertex)); // 重新初始化法线 - for (int z = 0; z < s; z++) { - for (int x = 0; x < s; x++) { - int i = z * s + x; - float px = (float)x * step - half; - float pz = (float)z * step - half; - float py = hm->data[i] * height_scale; - verts[i].pos[0] = px; - verts[i].pos[1] = py; - verts[i].pos[2] = pz; - verts[i].uv[0] = (float)x * uv_scale; - verts[i].uv[1] = (float)z * uv_scale; - - // 估算法线 - float hl = (x > 0) ? hm->data[z * s + x - 1] * height_scale : py; - float hr = (x < s - 1) ? hm->data[z * s + x + 1] * height_scale : py; - float hd = (z > 0) ? hm->data[(z - 1) * s + x] * height_scale : py; - float hu = (z < s - 1) ? hm->data[(z + 1) * s + x] * height_scale : py; - verts[i].norm[0] = (hl - hr); - verts[i].norm[1] = 2.0f * step; - verts[i].norm[2] = (hd - hu); - - float nx = verts[i].norm[0]; - float ny = verts[i].norm[1]; - float nz = verts[i].norm[2]; - float len = sqrtf(nx * nx + ny * ny + nz * nz); - if (len > 0.0001f) { - verts[i].norm[0] = nx / len; - verts[i].norm[1] = ny / len; - verts[i].norm[2] = nz / len; - } else { - verts[i].norm[0] = 0; - verts[i].norm[1] = 1; - verts[i].norm[2] = 0; - } - - // 根据高度和坡度着色 - float h = hm->data[i]; - float slope = (ny > 0.0001f) ? sqrtf(nx * nx + nz * nz) / ny : 0.0f; - if (h > 0.72f) { - verts[i].color[0] = 0.92f; - verts[i].color[1] = 0.92f; - verts[i].color[2] = 0.95f; - } else if (h > 0.55f || slope > 0.42f) { - verts[i].color[0] = 0.62f; - verts[i].color[1] = 0.60f; - verts[i].color[2] = 0.56f; - } else if (h < 0.18f) { - verts[i].color[0] = 0.82f; - verts[i].color[1] = 0.76f; - verts[i].color[2] = 0.50f; - } else { - verts[i].color[0] = 0.40f; - verts[i].color[1] = 0.68f; - verts[i].color[2] = 0.36f; - } - verts[i].color[3] = 1.0f; - } - } - - int ii = 0; - for (int z = 0; z < s - 1; z++) { - for (int x = 0; x < s - 1; x++) { - uint32_t a = z * s + x; - uint32_t b = z * s + x + 1; - uint32_t c = (z + 1) * s + x; - uint32_t d = (z + 1) * s + x + 1; - idx[ii++] = a; - idx[ii++] = c; - idx[ii++] = b; - idx[ii++] = b; - idx[ii++] = c; - idx[ii++] = d; - } - } - - Mesh* m = (Mesh*)calloc(1, sizeof(Mesh)); - m->vcount = vc; - m->icount = ic; - m->stride = sizeof(Vertex); - - D3D11_BUFFER_DESC bd = {0}; - D3D11_SUBRESOURCE_DATA sd = {0}; - bd.ByteWidth = sizeof(Vertex) * vc; - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = verts; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &m->vb); - - bd.ByteWidth = sizeof(uint32_t) * ic; - bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = idx; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &m->ib); - - free(verts); - free(idx); - return m; -} - -Mesh* terrain_mesh_create(ID3D11Device* dev, const TerrainHeightmap* hm, float size, float height_scale, float uv_scale) { - return create_mesh_from_terrain(dev, hm, size, height_scale, uv_scale); -} - -// ============================================================================ -// 地形对象 -// ============================================================================ - -Terrain* terrain_create(ID3D11Device* dev, const TerrainConfig* config) { - if (!dev || !config) return NULL; - Terrain* t = (Terrain*)calloc(1, sizeof(Terrain)); - t->config = *config; - t->device = dev; - t->heightmap = terrain_heightmap_create(config->vertices_per_chunk); - terrain_heightmap_fill_noise(&t->heightmap, 12345, 4.0f, 1.0f); - t->mesh = terrain_mesh_create(dev, &t->heightmap, config->chunk_size, config->height_scale, config->uv_scale); - return t; -} - -void terrain_destroy(Terrain* terrain) { - if (!terrain) return; - terrain_heightmap_destroy(&terrain->heightmap); - if (terrain->mesh) mesh_destroy(terrain->mesh); - free(terrain); -} - -float terrain_get_height(const Terrain* terrain, float world_x, float world_z) { - if (!terrain) return 0.0f; - float half = terrain->config.chunk_size * 0.5f; - float local_x = (world_x + half) / terrain->config.chunk_size; - float local_z = (world_z + half) / terrain->config.chunk_size; - float h = terrain_heightmap_sample(&terrain->heightmap, local_x, local_z); - return h * terrain->config.height_scale; -} diff --git a/Engine/Engine/Terrain/terrain.h b/Engine/Engine/Terrain/terrain.h deleted file mode 100644 index a0a59b4..0000000 --- a/Engine/Engine/Terrain/terrain.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -// ============================================================================ -// terrain.h - 程序化地形 -// ============================================================================ - -#include -#include "../Rendering/mesh.h" - -#define TERRAIN_MAX_HEIGHTMAP_SIZE 256 - -typedef struct { - float* data; - int size; -} TerrainHeightmap; - -typedef struct { - int chunks_x; - int chunks_z; - int vertices_per_chunk; - float chunk_size; - float height_scale; - float uv_scale; -} TerrainConfig; - -typedef struct { - TerrainConfig config; - TerrainHeightmap heightmap; - Mesh* mesh; - ID3D11Device* device; -} Terrain; - -// 默认配置 -TerrainConfig terrain_default_config(void); - -// 高度图 -TerrainHeightmap terrain_heightmap_create(int size); -void terrain_heightmap_destroy(TerrainHeightmap* hm); -void terrain_heightmap_fill_noise(TerrainHeightmap* hm, int seed, float scale, float amplitude); -float terrain_heightmap_sample(const TerrainHeightmap* hm, float x, float z); - -// 地形对象 -Terrain* terrain_create(ID3D11Device* dev, const TerrainConfig* config); -void terrain_destroy(Terrain* terrain); - -// 从世界坐标采样高度 (用于相机/角色贴地) -float terrain_get_height(const Terrain* terrain, float world_x, float world_z); - -// 网格生成 -Mesh* terrain_mesh_create(ID3D11Device* dev, const TerrainHeightmap* hm, float size, float height_scale, float uv_scale); - -// 噪声工具(供分块管理器复用) -float hash_noise(int x, int z, int seed); -float fbm_noise(float x, float z, int seed, int octaves, float persistence); diff --git a/Engine/Engine/Terrain/terrain_manager.c b/Engine/Engine/Terrain/terrain_manager.c deleted file mode 100644 index c40637b..0000000 --- a/Engine/Engine/Terrain/terrain_manager.c +++ /dev/null @@ -1,199 +0,0 @@ -#include "terrain_manager.h" -#include "../Rendering/renderer.h" -#include "../Rendering/frustum.h" -#include "../Core/logger.h" -#include -#include - -// ============================================================================ -// 噪声:分块需要世界一致的高度,这里复用 terrain.c 的 hash_noise/fbm_noise -// ============================================================================ - -static float sample_world_height(int seed, float world_x, float world_z, float scale) { - return fbm_noise(world_x * scale, world_z * scale, seed, 6, 0.5f); -} - -static void fill_heightmap_for_chunk(TerrainHeightmap* hm, int seed, int cx, int cz, - float chunk_size, float scale) { - if (!hm || !hm->data) return; - int s = hm->size; - float half = chunk_size * 0.5f; - float step = chunk_size / (float)(s - 1); - float origin_x = (float)cx * chunk_size - half; - float origin_z = (float)cz * chunk_size - half; - - for (int z = 0; z < s; z++) { - for (int x = 0; x < s; x++) { - float wx = origin_x + (float)x * step; - float wz = origin_z + (float)z * step; - hm->data[z * s + x] = sample_world_height(seed, wx, wz, scale); - } - } -} - -static void make_chunk_world_matrix(TerrainChunk* chunk, Mat4* out) { - mat4_identity(out); - out->m[3][0] = (float)chunk->cx * chunk->terrain->config.chunk_size; - out->m[3][1] = 0.0f; - out->m[3][2] = (float)chunk->cz * chunk->terrain->config.chunk_size; -} - -TerrainManager* terrain_manager_create(ID3D11Device* dev, const TerrainConfig* config, Material* base_material) { - if (!dev || !config) return NULL; - TerrainManager* tm = (TerrainManager*)calloc(1, sizeof(TerrainManager)); - tm->config = *config; - tm->device = dev; - tm->base_material = base_material; - tm->load_radius = 3; - tm->seed = 12345; - tm->chunk_count = 0; - return tm; -} - -void terrain_manager_destroy(TerrainManager* tm) { - if (!tm) return; - for (int i = 0; i < tm->chunk_count; i++) { - if (tm->chunks[i].terrain) terrain_destroy(tm->chunks[i].terrain); - } - free(tm); -} - -static int find_chunk_index(TerrainManager* tm, int cx, int cz) { - for (int i = 0; i < tm->chunk_count; i++) { - if (tm->chunks[i].loaded && tm->chunks[i].cx == cx && tm->chunks[i].cz == cz) - return i; - } - return -1; -} - -static TerrainChunk* alloc_chunk_slot(TerrainManager* tm) { - if (tm->chunk_count >= TERRAIN_MAX_CHUNKS) return NULL; - return &tm->chunks[tm->chunk_count++]; -} - -static TerrainChunk* create_chunk(TerrainManager* tm, int cx, int cz) { - TerrainChunk* chunk = alloc_chunk_slot(tm); - if (!chunk) { - LOG_ERROR("Terrain: failed to alloc chunk slot"); - return NULL; - } - - chunk->cx = cx; - chunk->cz = cz; - chunk->terrain = (Terrain*)calloc(1, sizeof(Terrain)); - chunk->terrain->config = tm->config; - chunk->terrain->device = tm->device; - chunk->terrain->heightmap = terrain_heightmap_create(tm->config.vertices_per_chunk); - fill_heightmap_for_chunk(&chunk->terrain->heightmap, tm->seed, cx, cz, - tm->config.chunk_size, 0.015f); - chunk->terrain->mesh = terrain_mesh_create(tm->device, &chunk->terrain->heightmap, - tm->config.chunk_size, - tm->config.height_scale, - tm->config.uv_scale); - chunk->material = tm->base_material; - chunk->loaded = 1; - if (!chunk->terrain->mesh) { - LOG_ERROR("Terrain: chunk mesh create failed at (%d, %d)", cx, cz); - } else { - LOG_INFO("Terrain: created chunk (%d, %d) mesh v=%u i=%u", cx, cz, - chunk->terrain->mesh->vcount, chunk->terrain->mesh->icount); - } - return chunk; -} - -void terrain_manager_update(TerrainManager* tm, Vec3 observer_pos) { - if (!tm) return; - float inv_size = 1.0f / tm->config.chunk_size; - int ox = (int)floorf(observer_pos.x * inv_size + 0.5f); - int oz = (int)floorf(observer_pos.z * inv_size + 0.5f); - static int logged = 0; - if (!logged) { - LOG_INFO("Terrain update: observer=(%.1f,%.1f,%.1f) center_chunk=(%d,%d)", - observer_pos.x, observer_pos.y, observer_pos.z, ox, oz); - logged = 1; - } - - // 标记需要保留 - int keep[TERRAIN_MAX_CHUNKS] = {0}; - - // 加载需要的分块 - int r = tm->load_radius; - for (int z = oz - r; z <= oz + r; z++) { - for (int x = ox - r; x <= ox + r; x++) { - int idx = find_chunk_index(tm, x, z); - if (idx < 0) { - if (create_chunk(tm, x, z)) { - keep[tm->chunk_count - 1] = 1; - } - } else { - keep[idx] = 1; - } - } - } - - // 卸载不需要的分块 - int write = 0; - for (int i = 0; i < tm->chunk_count; i++) { - if (keep[i]) { - tm->chunks[write] = tm->chunks[i]; - write++; - } else { - terrain_destroy(tm->chunks[i].terrain); - } - } - tm->chunk_count = write; -} - -void terrain_manager_render(TerrainManager* tm, Renderer* renderer) { - if (!tm || !renderer) return; - static int logged = 0; - if (!logged) { - LOG_INFO("Terrain render: chunk_count=%d", tm->chunk_count); - logged = 1; - } - - Mat4 vp; - renderer_get_view_projection(renderer, &vp); - Vec4 planes[6]; - frustum_from_matrix(&vp, planes); - - float half = tm->config.chunk_size * 0.5f; - float radius = sqrtf(half * half * 2.0f + - (tm->config.height_scale * 0.5f) * - (tm->config.height_scale * 0.5f)); - float cy = tm->config.height_scale * 0.5f; - - int rendered = 0; - for (int i = 0; i < tm->chunk_count; i++) { - TerrainChunk* c = &tm->chunks[i]; - if (!c->loaded || !c->terrain || !c->terrain->mesh) continue; - - Vec3 center = { (float)c->cx * tm->config.chunk_size, cy, (float)c->cz * tm->config.chunk_size }; - if (!frustum_intersects_sphere(planes, center, radius)) continue; - - Mat4 world; - make_chunk_world_matrix(c, &world); - renderer_draw_mesh_with_material(renderer, c->terrain->mesh, c->material, &world); - rendered++; - } - LOG_INFO("Terrain render: visible_chunks=%d/%d", rendered, tm->chunk_count); -} - -float terrain_manager_get_height(TerrainManager* tm, float world_x, float world_z) { - if (!tm) return 0.0f; - float inv_size = 1.0f / tm->config.chunk_size; - int cx = (int)floorf(world_x * inv_size + 0.5f); - int cz = (int)floorf(world_z * inv_size + 0.5f); - - // 先在已加载分块中查找 - int idx = find_chunk_index(tm, cx, cz); - if (idx >= 0 && tm->chunks[idx].terrain) { - Terrain* t = tm->chunks[idx].terrain; - float local_x = world_x - (float)cx * tm->config.chunk_size; - float local_z = world_z - (float)cz * tm->config.chunk_size; - return terrain_get_height(t, local_x, local_z); - } - - // 回退到直接采样噪声 - return sample_world_height(tm->seed, world_x, world_z, 0.015f) * tm->config.height_scale; -} diff --git a/Engine/Engine/Terrain/terrain_manager.h b/Engine/Engine/Terrain/terrain_manager.h deleted file mode 100644 index 7a91039..0000000 --- a/Engine/Engine/Terrain/terrain_manager.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -// ============================================================================ -// terrain_manager.h - 地形分块流式加载 -// ============================================================================ - -#include "terrain.h" -#include "../Rendering/material.h" -#include "../Rendering/renderer.h" -#include "../ASM/math_c_fallback.h" - -#define TERRAIN_MAX_CHUNKS 64 - -typedef struct { - int cx; - int cz; - Terrain* terrain; - Material* material; - int loaded; -} TerrainChunk; - -typedef struct { - TerrainConfig config; - TerrainChunk chunks[TERRAIN_MAX_CHUNKS]; - int chunk_count; - int load_radius; - int seed; - ID3D11Device* device; - Material* base_material; -} TerrainManager; - -TerrainManager* terrain_manager_create(ID3D11Device* dev, const TerrainConfig* config, Material* base_material); -void terrain_manager_destroy(TerrainManager* tm); - -// 根据观察者位置更新分块 -void terrain_manager_update(TerrainManager* tm, Vec3 observer_pos); - -// 渲染所有已加载分块 -void terrain_manager_render(TerrainManager* tm, Renderer* renderer); - -// 从世界坐标获取地形高度(在所有已加载分块中采样) -float terrain_manager_get_height(TerrainManager* tm, float world_x, float world_z); diff --git a/Engine/Engine/UI/ui.c b/Engine/Engine/UI/ui.c deleted file mode 100644 index 390519c..0000000 --- a/Engine/Engine/UI/ui.c +++ /dev/null @@ -1,401 +0,0 @@ -#include "ui.h" - -#include -#include -#include -#include - -// 为 MinGW 提供 COM 助手宏(MSVC 已内联提供) -#ifndef _MSC_VER -#define ID3D11Device_CreateBuffer(p,a,b,c) (p)->lpVtbl->CreateBuffer(p,a,b,c) -#define ID3D11Device_CreateVertexShader(p,a,b,c,d) (p)->lpVtbl->CreateVertexShader(p,a,b,c,d) -#define ID3D11Device_CreatePixelShader(p,a,b,c,d) (p)->lpVtbl->CreatePixelShader(p,a,b,c,d) -#define ID3D11Device_CreateInputLayout(p,a,b,c,d,e) (p)->lpVtbl->CreateInputLayout(p,a,b,c,d,e) -#define ID3D11Device_CreateBlendState(p,a,b) (p)->lpVtbl->CreateBlendState(p,a,b) -#define ID3D11Device_CreateRasterizerState(p,a,b) (p)->lpVtbl->CreateRasterizerState(p,a,b) -#define ID3D11Device_CreateTexture2D(p,a,b,c) (p)->lpVtbl->CreateTexture2D(p,a,b,c) -#define ID3D11Device_CreateShaderResourceView(p,a,b,c) (p)->lpVtbl->CreateShaderResourceView(p,a,b,c) -#define ID3D11Device_CreateSamplerState(p,a,b) (p)->lpVtbl->CreateSamplerState(p,a,b) - -#define ID3D11RasterizerState_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11BlendState_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11InputLayout_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11PixelShader_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11VertexShader_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11Buffer_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11Texture2D_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11ShaderResourceView_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11SamplerState_Release(p) (p)->lpVtbl->Release(p) -#define ID3D10Blob_Release(p) (p)->lpVtbl->Release(p) -#define ID3D10Blob_GetBufferPointer(p) (p)->lpVtbl->GetBufferPointer(p) -#define ID3D10Blob_GetBufferSize(p) (p)->lpVtbl->GetBufferSize(p) - -#define ID3D11DeviceContext_Map(p,a,b,c,d,e) (p)->lpVtbl->Map(p,a,b,c,d,e) -#define ID3D11DeviceContext_Unmap(p,a,b) (p)->lpVtbl->Unmap(p,a,b) -#define ID3D11DeviceContext_IASetVertexBuffers(p,a,b,c,d,e) (p)->lpVtbl->IASetVertexBuffers(p,a,b,c,d,e) -#define ID3D11DeviceContext_IASetIndexBuffer(p,a,b,c) (p)->lpVtbl->IASetIndexBuffer(p,a,b,c) -#define ID3D11DeviceContext_IASetPrimitiveTopology(p,a) (p)->lpVtbl->IASetPrimitiveTopology(p,a) -#define ID3D11DeviceContext_IASetInputLayout(p,a) (p)->lpVtbl->IASetInputLayout(p,a) -#define ID3D11DeviceContext_VSSetShader(p,a,b,c) (p)->lpVtbl->VSSetShader(p,a,b,c) -#define ID3D11DeviceContext_PSSetShader(p,a,b,c) (p)->lpVtbl->PSSetShader(p,a,b,c) -#define ID3D11DeviceContext_PSSetShaderResources(p,a,b,c) (p)->lpVtbl->PSSetShaderResources(p,a,b,c) -#define ID3D11DeviceContext_PSSetSamplers(p,a,b,c) (p)->lpVtbl->PSSetSamplers(p,a,b,c) -#define ID3D11DeviceContext_OMSetBlendState(p,a,b,c) (p)->lpVtbl->OMSetBlendState(p,a,b,c) -#define ID3D11DeviceContext_RSSetState(p,a) (p)->lpVtbl->RSSetState(p,a) -#define ID3D11DeviceContext_DrawIndexed(p,a,b,c) (p)->lpVtbl->DrawIndexed(p,a,b,c) -#endif - -static const char* ui_vs = R"( -struct VS_INPUT { float2 Pos : POSITION; float2 UV : TEXCOORD0; uint Color : COLOR0; }; -struct VS_OUTPUT { float4 Pos : SV_POSITION; float2 UV : TEXCOORD0; float4 Color : COLOR0; }; -VS_OUTPUT main(VS_INPUT input) { - VS_OUTPUT output; - output.Pos = float4(input.Pos.x, input.Pos.y, 0, 1); - output.UV = input.UV; - output.Color = float4((input.Color & 0xFF) / 255.0, ((input.Color >> 8) & 0xFF) / 255.0, - ((input.Color >> 16) & 0xFF) / 255.0, ((input.Color >> 24) & 0xFF) / 255.0); - return output; -} -)"; - -static const char* ui_ps = R"( -struct PS_INPUT { float4 Pos : SV_POSITION; float2 UV : TEXCOORD0; float4 Color : COLOR0; }; -Texture2D tex : register(t0); -SamplerState samp : register(s0); -float4 main(PS_INPUT input) : SV_TARGET { return input.Color * tex.Sample(samp, input.UV); } -)"; - -#define UI_FONT_COLS 16 -#define UI_FONT_ROWS 8 -#define UI_FONT_CELL_W 16 -#define UI_FONT_CELL_H 16 -#define UI_FONT_ATLAS_W (UI_FONT_COLS * UI_FONT_CELL_W) -#define UI_FONT_ATLAS_H (UI_FONT_ROWS * UI_FONT_CELL_H) - -static int ui_create_font_texture(UI* ui, ID3D11Device* device) { - BITMAPINFO bmi = {0}; - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = UI_FONT_ATLAS_W; - bmi.bmiHeader.biHeight = -UI_FONT_ATLAS_H; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - - HDC hdc = GetDC(NULL); - HDC memdc = CreateCompatibleDC(hdc); - void* bits = NULL; - HBITMAP bmp = CreateDIBSection(memdc, &bmi, DIB_RGB_COLORS, &bits, NULL, 0); - if (!bmp) { - DeleteDC(memdc); - ReleaseDC(NULL, hdc); - return 0; - } - SelectObject(memdc, bmp); - PatBlt(memdc, 0, 0, UI_FONT_ATLAS_W, UI_FONT_ATLAS_H, BLACKNESS); - SetBkColor(memdc, RGB(0, 0, 0)); - SetTextColor(memdc, RGB(255, 255, 255)); - - HFONT font = CreateFont(UI_FONT_CELL_H - 2, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, - DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, - CLEARTYPE_QUALITY, FIXED_PITCH | FF_MODERN, "Consolas"); - if (font) SelectObject(memdc, font); - - for (int i = 32; i < 128; i++) { - int col = i % UI_FONT_COLS; - int row = i / UI_FONT_COLS; - char c = (char)i; - TextOutA(memdc, col * UI_FONT_CELL_W + 1, row * UI_FONT_CELL_H + 1, &c, 1); - - ui->char_uvs[i][0] = (float)(col * UI_FONT_CELL_W) / UI_FONT_ATLAS_W; - ui->char_uvs[i][1] = (float)(row * UI_FONT_CELL_H) / UI_FONT_ATLAS_H; - ui->char_uvs[i][2] = (float)((col + 1) * UI_FONT_CELL_W) / UI_FONT_ATLAS_W; - ui->char_uvs[i][3] = (float)((row + 1) * UI_FONT_CELL_H) / UI_FONT_ATLAS_H; - } - - // 将亮度转为 alpha,文字存储为白色 - uint32_t* pixels = (uint32_t*)bits; - for (int i = 0; i < UI_FONT_ATLAS_W * UI_FONT_ATLAS_H; i++) { - uint32_t p = pixels[i]; - uint8_t b = (uint8_t)(p & 0xFF); - uint8_t g = (uint8_t)((p >> 8) & 0xFF); - uint8_t r = (uint8_t)((p >> 16) & 0xFF); - uint8_t lum = (uint8_t)((r * 77 + g * 150 + b * 29) >> 8); - pixels[i] = 0x00FFFFFF | ((uint32_t)lum << 24); - } - // 左上角像素保留为纯白,供纯色矩形采样 - pixels[0] = 0xFFFFFFFF; - - D3D11_TEXTURE2D_DESC desc = {0}; - desc.Width = UI_FONT_ATLAS_W; - desc.Height = UI_FONT_ATLAS_H; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_IMMUTABLE; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - - D3D11_SUBRESOURCE_DATA init = {0}; - init.pSysMem = bits; - init.SysMemPitch = UI_FONT_ATLAS_W * 4; - - ID3D11Texture2D* tex = NULL; - HRESULT hr = ID3D11Device_CreateTexture2D(device, &desc, &init, &tex); - if (SUCCEEDED(hr) && tex) { - ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource*)tex, NULL, &ui->font_srv); - ID3D11Texture2D_Release(tex); - } - - D3D11_SAMPLER_DESC sd = {0}; - sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - sd.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; - sd.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; - sd.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; - ID3D11Device_CreateSamplerState(device, &sd, &ui->font_sampler); - - if (font) DeleteObject(font); - DeleteObject(bmp); - DeleteDC(memdc); - ReleaseDC(NULL, hdc); - - return ui->font_srv != NULL && ui->font_sampler != NULL; -} - -UI* ui_create(ID3D11Device* device) { - UI* ui = (UI*)calloc(1, sizeof(UI)); - ui->font_size = 14.0f; - ui->text_color = 0xFFFFFFFF; - ui->bg_color = 0xFF333333; - ui->border_color = 0xFF666666; - ui->padding = 4.0f; - - D3D11_BUFFER_DESC vbd = {0}; - vbd.ByteWidth = sizeof(UIVertex) * UI_MAX_VERTICES; - vbd.Usage = D3D11_USAGE_DYNAMIC; - vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - vbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - ID3D11Device_CreateBuffer(device, &vbd, NULL, &ui->vertex_buffer); - - D3D11_BUFFER_DESC ibd = {0}; - ibd.ByteWidth = sizeof(uint32_t) * UI_MAX_INDICES; - ibd.Usage = D3D11_USAGE_DYNAMIC; - ibd.BindFlags = D3D11_BIND_INDEX_BUFFER; - ibd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - ID3D11Device_CreateBuffer(device, &ibd, NULL, &ui->index_buffer); - - // 编译着色器 - ID3DBlob* vs_blob = NULL, *ps_blob = NULL, *err = NULL; - D3DCompile(ui_vs, strlen(ui_vs), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &vs_blob, &err); - D3DCompile(ui_ps, strlen(ui_ps), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &ps_blob, &err); - - if (vs_blob && ps_blob) { - ID3D11Device_CreateVertexShader(device, ID3D10Blob_GetBufferPointer(vs_blob), - ID3D10Blob_GetBufferSize(vs_blob), NULL, &ui->vertex_shader); - ID3D11Device_CreatePixelShader(device, ID3D10Blob_GetBufferPointer(ps_blob), - ID3D10Blob_GetBufferSize(ps_blob), NULL, &ui->pixel_shader); - - D3D11_INPUT_ELEMENT_DESC layout[] = { - {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0}, - }; - ID3D11Device_CreateInputLayout(device, layout, 3, - ID3D10Blob_GetBufferPointer(vs_blob), ID3D10Blob_GetBufferSize(vs_blob), &ui->input_layout); - ID3D10Blob_Release(vs_blob); - ID3D10Blob_Release(ps_blob); - } - - D3D11_BLEND_DESC bd = {0}; - bd.RenderTarget[0].BlendEnable = TRUE; - bd.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - bd.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - bd.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - bd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - bd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - bd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - ID3D11Device_CreateBlendState(device, &bd, &ui->blend_state); - - D3D11_RASTERIZER_DESC rd = {0}; - rd.FillMode = D3D11_FILL_SOLID; - rd.CullMode = D3D11_CULL_NONE; - rd.ScissorEnable = TRUE; - ID3D11Device_CreateRasterizerState(device, &rd, &ui->rasterizer); - - ui_create_font_texture(ui, device); - - return ui; -} - -void ui_destroy(UI* ui) { - if (!ui) return; - if (ui->font_sampler) ID3D11SamplerState_Release(ui->font_sampler); - if (ui->font_srv) ID3D11ShaderResourceView_Release(ui->font_srv); - if (ui->rasterizer) ID3D11RasterizerState_Release(ui->rasterizer); - if (ui->blend_state) ID3D11BlendState_Release(ui->blend_state); - if (ui->input_layout) ID3D11InputLayout_Release(ui->input_layout); - if (ui->pixel_shader) ID3D11PixelShader_Release(ui->pixel_shader); - if (ui->vertex_shader) ID3D11VertexShader_Release(ui->vertex_shader); - if (ui->index_buffer) ID3D11Buffer_Release(ui->index_buffer); - if (ui->vertex_buffer) ID3D11Buffer_Release(ui->vertex_buffer); - free(ui); -} - -void ui_begin(UI* ui, float mx, float my, int md, int mp, int mr) { - ui->mouse_x = mx; - ui->mouse_y = my; - ui->mouse_down = md; - ui->mouse_pressed = mp; - ui->mouse_released = mr; - ui->vertex_count = 0; - ui->index_count = 0; -} - -void ui_end(UI* ui) { - (void)ui; -} - -void ui_draw_rect(UI* ui, float x, float y, float w, float h, uint32_t color) { - uint32_t base = ui->vertex_count; - // UV 指向字体图集左上角纯白像素,使纯色矩形不受纹理内容影响 - ui->vertices[ui->vertex_count++] = (UIVertex){x, y, 0.0f, 0.0f, color}; - ui->vertices[ui->vertex_count++] = (UIVertex){x + w, y, 0.0f, 0.0f, color}; - ui->vertices[ui->vertex_count++] = (UIVertex){x + w, y + h, 0.0f, 0.0f, color}; - ui->vertices[ui->vertex_count++] = (UIVertex){x, y + h, 0.0f, 0.0f, color}; - ui->indices[ui->index_count++] = base; - ui->indices[ui->index_count++] = base + 1; - ui->indices[ui->index_count++] = base + 2; - ui->indices[ui->index_count++] = base; - ui->indices[ui->index_count++] = base + 2; - ui->indices[ui->index_count++] = base + 3; -} - -void ui_draw_text(UI* ui, float x, float y, const char* text, uint32_t color) { - if (!text) return; - float px = x; - float py = y; - const float cw = (float)UI_FONT_CELL_W; - const float ch = (float)UI_FONT_CELL_H; - while (*text) { - unsigned char c = (unsigned char)*text++; - if (c < 32 || c >= 128) c = '?'; - float u1 = ui->char_uvs[c][0]; - float v1 = ui->char_uvs[c][1]; - float u2 = ui->char_uvs[c][2]; - float v2 = ui->char_uvs[c][3]; - - uint32_t base = ui->vertex_count; - ui->vertices[ui->vertex_count++] = (UIVertex){px, py, u1, v1, color}; - ui->vertices[ui->vertex_count++] = (UIVertex){px + cw, py, u2, v1, color}; - ui->vertices[ui->vertex_count++] = (UIVertex){px + cw, py + ch, u2, v2, color}; - ui->vertices[ui->vertex_count++] = (UIVertex){px, py + ch, u1, v2, color}; - ui->indices[ui->index_count++] = base; - ui->indices[ui->index_count++] = base + 1; - ui->indices[ui->index_count++] = base + 2; - ui->indices[ui->index_count++] = base; - ui->indices[ui->index_count++] = base + 2; - ui->indices[ui->index_count++] = base + 3; - px += cw; - } -} - -void ui_draw_rect_border(UI* ui, float x, float y, float w, float h, - uint32_t fill, uint32_t border, float thickness) { - ui_draw_rect(ui, x, y, w, h, fill); - ui_draw_rect(ui, x, y, w, thickness, border); - ui_draw_rect(ui, x, y + h - thickness, w, thickness, border); - ui_draw_rect(ui, x, y, thickness, h, border); - ui_draw_rect(ui, x + w - thickness, y, thickness, h, border); -} - -int ui_button(UI* ui, float x, float y, float w, float h, const char* text) { - int hover = ui->mouse_x >= x && ui->mouse_x <= x + w && - ui->mouse_y >= y && ui->mouse_y <= y + h; - uint32_t color = hover ? 0xFF555555 : 0xFF444444; - if (hover && ui->mouse_pressed) color = 0xFF666666; - ui_draw_rect_border(ui, x, y, w, h, color, 0xFF888888, 1); - if (text) { - float tx = x + ui->padding; - float ty = y + (h - UI_FONT_CELL_H) * 0.5f; - ui_draw_text(ui, tx, ty, text, ui->text_color); - } - return hover && ui->mouse_pressed; -} - -float ui_slider(UI* ui, float x, float y, float w, float h, float value, float min_val, float max_val) { - ui_draw_rect_border(ui, x, y, w, h, 0xFF333333, 0xFF666666, 1); - - int hover = ui->mouse_x >= x && ui->mouse_x <= x + w && - ui->mouse_y >= y && ui->mouse_y <= y + h; - if (hover && ui->mouse_down) { - float t = (ui->mouse_x - x) / w; - value = min_val + t * (max_val - min_val); - if (value < min_val) value = min_val; - if (value > max_val) value = max_val; - } - - float knob_x = x + ((value - min_val) / (max_val - min_val)) * (w - h); - ui_draw_rect(ui, knob_x, y, h, h, 0xFF0078D4); - return value; -} - -int ui_checkbox(UI* ui, float x, float y, const char* text, int checked) { - float s = 16.0f; - ui_draw_rect_border(ui, x, y, s, s, checked ? 0xFF0078D4 : 0xFF333333, 0xFF666666, 1); - if (checked) { - // 绘制对勾 - ui_draw_rect(ui, x + 4, y + 7, 2, 2, 0xFFFFFFFF); - ui_draw_rect(ui, x + 6, y + 9, 2, 2, 0xFFFFFFFF); - ui_draw_rect(ui, x + 8, y + 5, 5, 2, 0xFFFFFFFF); - } - if (text) { - ui_draw_text(ui, x + s + ui->padding, y + (s - UI_FONT_CELL_H) * 0.5f, text, ui->text_color); - } - if (ui->mouse_x >= x && ui->mouse_x <= x + s && - ui->mouse_y >= y && ui->mouse_y <= y + s && ui->mouse_pressed) { - return !checked; - } - return checked; -} - -void ui_label(UI* ui, float x, float y, const char* text) { - if (text) { - ui_draw_text(ui, x, y, text, ui->text_color); - } -} - -void ui_render(UI* ui, ID3D11DeviceContext* ctx) { - if (ui->vertex_count == 0) return; - - D3D11_MAPPED_SUBRESOURCE mapped; - if (SUCCEEDED(ID3D11DeviceContext_Map(ctx, (ID3D11Resource*)ui->vertex_buffer, 0, - D3D11_MAP_WRITE_DISCARD, 0, &mapped))) { - memcpy(mapped.pData, ui->vertices, sizeof(UIVertex) * ui->vertex_count); - ID3D11DeviceContext_Unmap(ctx, (ID3D11Resource*)ui->vertex_buffer, 0); - } - if (SUCCEEDED(ID3D11DeviceContext_Map(ctx, (ID3D11Resource*)ui->index_buffer, 0, - D3D11_MAP_WRITE_DISCARD, 0, &mapped))) { - memcpy(mapped.pData, ui->indices, sizeof(uint32_t) * ui->index_count); - ID3D11DeviceContext_Unmap(ctx, (ID3D11Resource*)ui->index_buffer, 0); - } - - UINT stride = sizeof(UIVertex); - UINT offset = 0; - ID3D11DeviceContext_IASetVertexBuffers(ctx, 0, 1, &ui->vertex_buffer, &stride, &offset); - ID3D11DeviceContext_IASetIndexBuffer(ctx, ui->index_buffer, DXGI_FORMAT_R32_UINT, 0); - ID3D11DeviceContext_IASetPrimitiveTopology(ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D11DeviceContext_IASetInputLayout(ctx, ui->input_layout); - - ID3D11DeviceContext_VSSetShader(ctx, ui->vertex_shader, NULL, 0); - ID3D11DeviceContext_PSSetShader(ctx, ui->pixel_shader, NULL, 0); - ID3D11DeviceContext_PSSetShaderResources(ctx, 0, 1, &ui->font_srv); - ID3D11DeviceContext_PSSetSamplers(ctx, 0, 1, &ui->font_sampler); - - float blend[4] = {1, 1, 1, 1}; - ID3D11DeviceContext_OMSetBlendState(ctx, ui->blend_state, blend, 0xFFFFFFFF); - ID3D11DeviceContext_RSSetState(ctx, ui->rasterizer); - - ID3D11DeviceContext_DrawIndexed(ctx, ui->index_count, 0, 0); - - ID3D11DeviceContext_OMSetBlendState(ctx, NULL, blend, 0xFFFFFFFF); - ID3D11DeviceContext_RSSetState(ctx, NULL); -} diff --git a/Engine/Engine/UI/ui.h b/Engine/Engine/UI/ui.h deleted file mode 100644 index 091a173..0000000 --- a/Engine/Engine/UI/ui.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -// ============================================================================ -// ui.h - 立即模式UI -// ============================================================================ - -#include -#include - -#define UI_MAX_VERTICES 16384 -#define UI_MAX_INDICES 32768 -#define UI_MAX_WIDGETS 256 - -typedef struct { - float x, y; - float u, v; - uint32_t color; -} UIVertex; - -typedef struct { - float x, y, w, h; - uint32_t color; - int visible; -} UIRect; - -typedef struct { - ID3D11Buffer* vertex_buffer; - ID3D11Buffer* index_buffer; - ID3D11VertexShader* vertex_shader; - ID3D11PixelShader* pixel_shader; - ID3D11InputLayout* input_layout; - ID3D11BlendState* blend_state; - ID3D11RasterizerState* rasterizer; - ID3D11ShaderResourceView* font_srv; - ID3D11SamplerState* font_sampler; - - UIVertex vertices[UI_MAX_VERTICES]; - uint32_t indices[UI_MAX_INDICES]; - uint32_t vertex_count; - uint32_t index_count; - - float mouse_x, mouse_y; - int mouse_down; - int mouse_pressed; - int mouse_released; - - float font_size; - uint32_t text_color; - uint32_t bg_color; - uint32_t border_color; - float padding; - - float char_uvs[128][4]; -} UI; - -// 创建/销毁 -UI* ui_create(ID3D11Device* device); -void ui_destroy(UI* ui); - -// 帧操作 -void ui_begin(UI* ui, float mouse_x, float mouse_y, int mouse_down, int mouse_pressed, int mouse_released); -void ui_end(UI* ui); -void ui_render(UI* ui, ID3D11DeviceContext* ctx); - -// 基础绘制 -void ui_draw_rect(UI* ui, float x, float y, float w, float h, uint32_t color); -void ui_draw_rect_border(UI* ui, float x, float y, float w, float h, uint32_t fill, uint32_t border, float thickness); -void ui_draw_text(UI* ui, float x, float y, const char* text, uint32_t color); - -// 控件 -int ui_button(UI* ui, float x, float y, float w, float h, const char* text); -float ui_slider(UI* ui, float x, float y, float w, float h, float value, float min_val, float max_val); -int ui_checkbox(UI* ui, float x, float y, const char* text, int checked); -void ui_label(UI* ui, float x, float y, const char* text); diff --git a/Engine/Engine/VisualScript/block_core.c b/Engine/Engine/VisualScript/block_core.c deleted file mode 100644 index acfd2ec..0000000 --- a/Engine/Engine/VisualScript/block_core.c +++ /dev/null @@ -1,159 +0,0 @@ -// ============================================================================ -// block_core.c - 积木核心操作 -// ============================================================================ - -#include "block_core.h" -#include -#include - -// 创建积木 -Block* block_create(BlockType type, float x, float y) { - Block* block = (Block*)calloc(1, sizeof(Block)); - if (!block) return NULL; - - block->type = type; - block->x = x; - block->y = y; - block->width = 200; - block->height = 60; - - // 初始化槽位 - block->input_count = 0; - block->output_count = 0; - - for (int i = 0; i < MAX_BLOCK_INPUTS; i++) { - block->inputs[i].owner = block; - block->inputs[i].id = i; - } - for (int i = 0; i < MAX_BLOCK_OUTPUTS; i++) { - block->outputs[i].owner = block; - block->outputs[i].id = i; - } - - return block; -} - -// 复制积木 (深拷贝,不复制连接关系) -Block* block_copy(const Block* src) { - if (!src) return NULL; - Block* block = (Block*)malloc(sizeof(Block)); - if (!block) return NULL; - memcpy(block, src, sizeof(Block)); - - // 重新设置拥有者,断开所有连接 - for (int i = 0; i < MAX_BLOCK_INPUTS; i++) { - block->inputs[i].owner = block; - block->inputs[i].connected = NULL; - } - for (int i = 0; i < MAX_BLOCK_OUTPUTS; i++) { - block->outputs[i].owner = block; - block->outputs[i].connected = NULL; - } - block->next = NULL; - block->parent_if = NULL; - block->workspace = NULL; - block->user_data = NULL; - - return block; -} - -// 销毁积木 -void block_destroy(Block* block) { - if (!block) return; - free(block); -} - -// 添加输入槽位 -BlockSlot* block_add_input(Block* block, SlotKind kind, SlotValueType value_type, const char* label) { - if (block->input_count >= MAX_BLOCK_INPUTS) return NULL; - - BlockSlot* slot = &block->inputs[block->input_count]; - slot->kind = kind; - slot->value_type = value_type; - if (label) strncpy(slot->label, label, MAX_BLOCK_LABEL - 1); - slot->value.type = value_type; - - block->input_count++; - return slot; -} - -// 添加输出槽位 -BlockSlot* block_add_output(Block* block, SlotKind kind, SlotValueType value_type, const char* label) { - if (block->output_count >= MAX_BLOCK_OUTPUTS) return NULL; - - BlockSlot* slot = &block->outputs[block->output_count]; - slot->kind = kind; - slot->value_type = value_type; - if (label) strncpy(slot->label, label, MAX_BLOCK_LABEL - 1); - - block->output_count++; - return slot; -} - -// 连接两个槽位 -bool block_connect(BlockSlot* from, BlockSlot* to) { - if (!from || !to) return false; - if (from->owner == to->owner) return false; // 不能自连 - - // 断开旧连接 - if (from->connected) from->connected->connected = NULL; - if (to->connected) to->connected->connected = NULL; - - from->connected = to; - to->connected = from; - return true; -} - -// 断开槽位 -void block_disconnect(BlockSlot* slot) { - if (!slot || !slot->connected) return; - slot->connected->connected = NULL; - slot->connected = NULL; -} - -// 检查槽位是否已连接 -bool block_slot_connected(BlockSlot* slot) { - return slot && slot->connected != NULL; -} - -// 获取槽位的值 -SlotValue block_slot_get_value(BlockSlot* slot) { - if (!slot) { - SlotValue empty = {0}; - return empty; - } - - // 如果有连接,从连接的积木获取值 - if (slot->connected && slot->connected->owner) { - Block* source = slot->connected->owner; - // 从源积木的输出槽位获取值 - for (int i = 0; i < source->output_count; i++) { - if (&source->outputs[i] == slot->connected) { - return source->outputs[i].value; - } - } - } - - return slot->value; -} - -// 设置槽位的值 -void block_slot_set_value(BlockSlot* slot, SlotValue value) { - if (slot) slot->value = value; -} - -// 积木是否包含点 -bool block_contains_point(Block* block, float px, float py) { - return px >= block->x && px <= block->x + block->width - && py >= block->y && py <= block->y + block->height; -} - -// 获取槽位的世界位置 -void block_slot_world_pos(BlockSlot* slot, float* wx, float* wy) { - if (!slot || !slot->owner) { - *wx = 0; *wy = 0; - return; - } - *wx = slot->owner->x + slot->x; - *wy = slot->owner->y + slot->y; -} diff --git a/Engine/Engine/VisualScript/block_core.h b/Engine/Engine/VisualScript/block_core.h deleted file mode 100644 index 1f1a530..0000000 --- a/Engine/Engine/VisualScript/block_core.h +++ /dev/null @@ -1,183 +0,0 @@ -#pragma once - -// ============================================================================ -// block_core.h - 积木核心数据结构 -// ============================================================================ - -#include -#include - -#define MAX_BLOCK_INPUTS 8 -#define MAX_BLOCK_OUTPUTS 8 -#define MAX_BLOCK_LABEL 64 - -// 颜色 -typedef struct { - float r, g, b, a; -} Color; - -typedef Color BlockColor; - -// 预定义颜色 -#define BLOCK_COLOR_EVENT {0.9f, 0.2f, 0.2f, 1.0f} // 红 -#define BLOCK_COLOR_ACTION {0.2f, 0.5f, 0.9f, 1.0f} // 蓝 -#define BLOCK_COLOR_CONTROL {0.2f, 0.7f, 0.3f, 1.0f} // 绿 -#define BLOCK_COLOR_OPERATOR {0.9f, 0.6f, 0.1f, 1.0f} // 橙 -#define BLOCK_COLOR_VARIABLE {0.7f, 0.3f, 0.8f, 1.0f} // 紫 -#define BLOCK_COLOR_FUNCTION {0.9f, 0.8f, 0.2f, 1.0f} // 黄 -#define BLOCK_COLOR_DATA {0.4f, 0.7f, 0.9f, 1.0f} // 浅蓝 - -// 槽位值类型 -typedef enum { - SLOT_VALUE_NUMBER = 0, - SLOT_VALUE_STRING, - SLOT_VALUE_BOOLEAN, - SLOT_VALUE_VECTOR3, - SLOT_VALUE_ANY -} SlotValueType; - -// 槽位值 -typedef struct { - SlotValueType type; - union { - double number; - char string[256]; - int boolean; - struct { float x, y, z; } vector3; - } as; -} SlotValue; - -// 槽位类型 -typedef enum { - SLOT_STATEMENT = 0, // 语句槽位 (执行流) - SLOT_VALUE // 值槽位 (数据流) -} SlotKind; - -// 槽位 -typedef struct BlockSlot { - int id; - SlotKind kind; - SlotValueType value_type; - char label[MAX_BLOCK_LABEL]; - - struct Block* owner; // 所属积木 - struct BlockSlot* connected; // 连接的槽位 - - SlotValue value; // 当前值 (仅值槽位) - - float x, y; // 相对于积木的位置 - float width, height; // 槽位尺寸 -} BlockSlot; - -// 积木类型 -typedef enum { - // 事件 - BLOCK_EVENT_START = 0, - BLOCK_EVENT_UPDATE, - BLOCK_EVENT_COLLISION, - BLOCK_EVENT_KEY_PRESSED, - BLOCK_EVENT_MOUSE_CLICK, - BLOCK_EVENT_TIMER, - - // 动作 - BLOCK_ACTION_MOVE, - BLOCK_ACTION_ROTATE, - BLOCK_ACTION_SCALE, - BLOCK_ACTION_SET_POSITION, - BLOCK_ACTION_SET_ROTATION, - BLOCK_ACTION_PLAY_SOUND, - BLOCK_ACTION_DESTROY, - BLOCK_ACTION_INSTANTIATE, - - // 控制 - BLOCK_CONTROL_IF, - BLOCK_CONTROL_IF_ELSE, - BLOCK_CONTROL_REPEAT, - BLOCK_CONTROL_REPEAT_TIMES, - BLOCK_CONTROL_WHILE, - BLOCK_CONTROL_WAIT, - BLOCK_CONTROL_FUNCTION_DEF, - - // 运算 - BLOCK_OP_ADD, - BLOCK_OP_SUB, - BLOCK_OP_MUL, - BLOCK_OP_DIV, - BLOCK_OP_MOD, - BLOCK_OP_EQUALS, - BLOCK_OP_NOT_EQUALS, - BLOCK_OP_GREATER, - BLOCK_OP_LESS, - BLOCK_OP_AND, - BLOCK_OP_OR, - BLOCK_OP_NOT, - - // 变量 - BLOCK_VAR_GET, - BLOCK_VAR_SET, - BLOCK_VAR_CREATE, - - // 函数 - BLOCK_FUNC_CALL, - BLOCK_FUNC_RETURN, - - BLOCK_TYPE_COUNT -} BlockType; - -// 积木类型信息 -typedef struct { - BlockType type; - const char* name; - const char* label; - const char* category; - BlockColor color; - int input_count; - int output_count; - SlotValueType input_types[MAX_BLOCK_INPUTS]; - SlotValueType output_types[MAX_BLOCK_OUTPUTS]; - const char* input_labels[MAX_BLOCK_INPUTS]; - const char* output_labels[MAX_BLOCK_OUTPUTS]; -} BlockTypeInfo; - -// 积木 -typedef struct Block { - int id; - BlockType type; - char label[MAX_BLOCK_LABEL]; - - float x, y; // 画布位置 - float width, height; // 尺寸 - Color color; // 颜色 - - BlockSlot inputs[MAX_BLOCK_INPUTS]; - int input_count; - - BlockSlot outputs[MAX_BLOCK_OUTPUTS]; - int output_count; - - struct Block* next; // 下一个积木 (堆叠) - struct Block* parent_if; // 所属 if 块 (用于子语句) - - struct BlockWorkspace* workspace; - void* user_data; -} Block; - -// 连接 -typedef struct BlockConnection { - BlockSlot* from; - BlockSlot* to; - float points[8]; // 贝塞尔曲线控制点 -} BlockConnection; - -// 函数声明 -Block* block_create(BlockType type, float x, float y); -Block* block_copy(const Block* src); -void block_destroy(Block* block); -BlockSlot* block_add_input(Block* block, SlotKind kind, SlotValueType value_type, const char* label); -BlockSlot* block_add_output(Block* block, SlotKind kind, SlotValueType value_type, const char* label); -bool block_connect(BlockSlot* from, BlockSlot* to); -void block_disconnect(BlockSlot* slot); -SlotValue block_slot_get_value(BlockSlot* slot); -void block_slot_set_value(BlockSlot* slot, SlotValue value); -bool block_contains_point(Block* block, float px, float py); -void block_slot_world_pos(BlockSlot* slot, float* wx, float* wy); diff --git a/Engine/Engine/VisualScript/block_editor.c b/Engine/Engine/VisualScript/block_editor.c deleted file mode 100644 index 744cf8f..0000000 --- a/Engine/Engine/VisualScript/block_editor.c +++ /dev/null @@ -1,225 +0,0 @@ -// ============================================================================ -// block_editor.c - 编辑器主界面实现 -// ============================================================================ - -#include "block_editor.h" -#include "block_types.h" -#include -#include - -int block_editor_init(BlockEditor* editor, void* device, void* context, int width, int height) { - memset(editor, 0, sizeof(BlockEditor)); - - editor->width = width; - editor->height = height; - editor->toolbar_height = 30; - editor->properties_width = 200; - editor->visible = 0; - - // 创建工作区 - editor->workspace = workspace_create(); - if (!editor->workspace) return 0; - - // 初始化渲染器 - if (!block_renderer_init(&editor->renderer, device, context)) { - workspace_destroy(editor->workspace); - return 0; - } - - // 初始化交互 - interaction_init(&editor->interaction); - - // 初始化面板 - palette_init(&editor->palette); - editor->palette.x = 0; - editor->palette.y = editor->toolbar_height; - - // 创建执行器 - editor->executor = executor_create(editor->workspace); - - return 1; -} - -void block_editor_shutdown(BlockEditor* editor) { - if (editor->executor) executor_destroy(editor->executor); - block_renderer_shutdown(&editor->renderer); - if (editor->workspace) workspace_destroy(editor->workspace); -} - -void block_editor_show(BlockEditor* editor) { - editor->visible = 1; -} - -void block_editor_hide(BlockEditor* editor) { - editor->visible = 0; -} - -int block_editor_is_visible(BlockEditor* editor) { - return editor->visible; -} - -void block_editor_update(BlockEditor* editor, double delta_time) { - if (!editor->visible) return; - - // 更新交互 - interaction_update(&editor->interaction, editor->workspace); - - // 更新执行器 - if (editor->executor->state == EXEC_RUNNING) { - executor_update(editor->executor, delta_time); - } -} - -void block_editor_render(BlockEditor* editor) { - if (!editor->visible) return; - - block_renderer_begin(&editor->renderer); - - // 绘制工具栏 - block_renderer_add_quad(&editor->renderer, 0, 0, (float)editor->width, (float)editor->toolbar_height, - 0.2f, 0.2f, 0.25f, 1.0f); - block_renderer_draw_text(&editor->renderer, "积木编辑器", 5, 5, 1.0f, 1.0f, 1.0f); - - // 绘制面板 - palette_render(&editor->palette, &editor->renderer); - - // 绘制工作区积木 - float ws_x = editor->palette.width; - float ws_y = editor->toolbar_height; - float ws_w = (float)editor->width - editor->palette.width - editor->properties_width; - float ws_h = (float)editor->height - editor->toolbar_height; - - // 工作区背景 - block_renderer_add_quad(&editor->renderer, ws_x, ws_y, ws_w, ws_h, - 0.12f, 0.12f, 0.15f, 1.0f); - - // 绘制连接线 - for (int i = 0; i < editor->workspace->connection_count; i++) { - BlockConnection* conn = &editor->workspace->connections[i]; - if (conn->from && conn->to) { - block_renderer_draw_connection(&editor->renderer, conn->from, conn->to, - editor->workspace->view_x, editor->workspace->view_y, editor->workspace->zoom); - } - } - - // 绘制积木 - for (int i = 0; i < editor->workspace->block_count; i++) { - Block* block = editor->workspace->blocks[i]; - block_renderer_draw_block(&editor->renderer, block, - editor->workspace->view_x, editor->workspace->view_y, editor->workspace->zoom); - - // 高亮选中的积木 - if (block == editor->workspace->selected_block) { - float x = (block->x - editor->workspace->view_x) * editor->workspace->zoom; - float y = (block->y - editor->workspace->view_y) * editor->workspace->zoom; - float w = block->width * editor->workspace->zoom; - float h = block->height * editor->workspace->zoom; - block_renderer_add_quad(&editor->renderer, x - 2, y - 2, w + 4, h + 4, - 1.0f, 1.0f, 0.0f, 0.3f); - } - } - - // 绘制正在拖拽的连接线 - if (editor->interaction.connecting_from) { - float x1, y1; - block_slot_world_pos(editor->interaction.connecting_from, &x1, &y1); - x1 = (x1 - editor->workspace->view_x) * editor->workspace->zoom; - y1 = (y1 - editor->workspace->view_y) * editor->workspace->zoom; - float x2 = (float)editor->interaction.mouse_x; - float y2 = (float)editor->interaction.mouse_y; - block_renderer_add_line(&editor->renderer, x1, y1, x2, y2, 1.0f, 1.0f, 0.0f, 0.8f); - } - - block_renderer_end(&editor->renderer); -} - -void block_editor_on_mouse_move(BlockEditor* editor, int x, int y) { - if (!editor->visible) return; - interaction_mouse_move(&editor->interaction, editor->workspace, x, y); -} - -void block_editor_on_mouse_down(BlockEditor* editor, int button) { - if (!editor->visible) return; - - int x = editor->interaction.mouse_x; - int y = editor->interaction.mouse_y; - - // 检查面板点击 - if (x < editor->palette.width && y >= editor->toolbar_height) { - BlockType type = palette_handle_click(&editor->palette, (float)x, (float)y); - if (type >= 0) { - block_editor_create_block_from_palette(editor, type, 300, 100); - } - return; - } - - interaction_mouse_down(&editor->interaction, editor->workspace, button); -} - -void block_editor_on_mouse_up(BlockEditor* editor, int button) { - if (!editor->visible) return; - interaction_mouse_up(&editor->interaction, editor->workspace, button); -} - -void block_editor_on_mouse_wheel(BlockEditor* editor, int delta) { - if (!editor->visible) return; - interaction_mouse_wheel(&editor->interaction, editor->workspace, delta); -} - -void block_editor_on_key(BlockEditor* editor, int key) { - if (!editor->visible) return; - interaction_key_down(&editor->interaction, editor->workspace, key); -} - -void block_editor_on_resize(BlockEditor* editor, int width, int height) { - editor->width = width; - editor->height = height; -} - -void block_editor_create_block_from_palette(BlockEditor* editor, BlockType type, float x, float y) { - Block* block = block_create(type, x, y); - if (!block) return; - - const BlockTypeInfo* info = block_type_get_info(type); - if (info) { - strncpy(block->label, info->label, MAX_BLOCK_LABEL - 1); - - // 创建输入槽位 - for (int i = 0; i < info->input_count; i++) { - block_add_input(block, - i == 0 ? SLOT_STATEMENT : SLOT_VALUE, - info->input_types[i], - info->input_labels[i]); - } - - // 创建输出槽位 - for (int i = 0; i < info->output_count; i++) { - block_add_output(block, - info->output_types[i] == SLOT_VALUE_ANY ? SLOT_STATEMENT : SLOT_VALUE, - info->output_types[i], - info->output_labels[i]); - } - } - - workspace_add_block(editor->workspace, block); -} - -int block_editor_save(BlockEditor* editor, const char* filepath) { - return serializer_save(editor->workspace, filepath); -} - -int block_editor_load(BlockEditor* editor, const char* filepath) { - return serializer_load(editor->workspace, filepath); -} - -void block_editor_run(BlockEditor* editor) { - executor_start(editor->executor); -} - -void block_editor_stop(BlockEditor* editor) { - executor_stop(editor->executor); -} - -void block_editor_pause(BlockEditor* editor) { - executor_pause(editor->executor); -} diff --git a/Engine/Engine/VisualScript/block_editor.h b/Engine/Engine/VisualScript/block_editor.h deleted file mode 100644 index f149ae2..0000000 --- a/Engine/Engine/VisualScript/block_editor.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -// ============================================================================ -// block_editor.h - 编辑器主界面 -// ============================================================================ - -#include "block_workspace.h" -#include "block_renderer.h" -#include "block_interaction.h" -#include "block_palette.h" -#include "block_executor.h" -#include "block_serializer.h" - -typedef struct BlockEditor { - BlockWorkspace* workspace; - BlockRenderer renderer; - BlockInteraction interaction; - BlockPalette palette; - BlockExecutor* executor; - - int width, height; - int visible; - - // 工具栏 - int toolbar_height; - - // 属性面板 - int properties_width; - Block* selected_block; -} BlockEditor; - -// 初始化/销毁 -int block_editor_init(BlockEditor* editor, void* device, void* context, int width, int height); -void block_editor_shutdown(BlockEditor* editor); - -// 显示/隐藏 -void block_editor_show(BlockEditor* editor); -void block_editor_hide(BlockEditor* editor); -int block_editor_is_visible(BlockEditor* editor); - -// 更新/渲染 -void block_editor_update(BlockEditor* editor, double delta_time); -void block_editor_render(BlockEditor* editor); - -// 输入处理 -void block_editor_on_mouse_move(BlockEditor* editor, int x, int y); -void block_editor_on_mouse_down(BlockEditor* editor, int button); -void block_editor_on_mouse_up(BlockEditor* editor, int button); -void block_editor_on_mouse_wheel(BlockEditor* editor, int delta); -void block_editor_on_key(BlockEditor* editor, int key); -void block_editor_on_resize(BlockEditor* editor, int width, int height); - -// 从面板拖拽创建积木 -void block_editor_create_block_from_palette(BlockEditor* editor, BlockType type, float x, float y); - -// 保存/加载 -int block_editor_save(BlockEditor* editor, const char* filepath); -int block_editor_load(BlockEditor* editor, const char* filepath); - -// 运行控制 -void block_editor_run(BlockEditor* editor); -void block_editor_stop(BlockEditor* editor); -void block_editor_pause(BlockEditor* editor); diff --git a/Engine/Engine/VisualScript/block_executor.c b/Engine/Engine/VisualScript/block_executor.c deleted file mode 100644 index 3d0e2dd..0000000 --- a/Engine/Engine/VisualScript/block_executor.c +++ /dev/null @@ -1,465 +0,0 @@ -// ============================================================================ -// block_executor.c - 积木执行引擎 (完整实现) -// ============================================================================ - -#include "block_executor.h" -#include "block_types.h" -#include -#include -#include -#include -#include - -// 日志回调 -typedef void (*LogCallback)(const char* msg, int level); -static LogCallback g_log_cb = NULL; - -static void log_info(const char* fmt, ...) { - char buf[512]; va_list args; va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); - if (g_log_cb) g_log_cb(buf, 0); else printf("[INFO] %s\n", buf); -} -static void log_error(const char* fmt, ...) { - char buf[512]; va_list args; va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); - if (g_log_cb) g_log_cb(buf, 2); else printf("[ERROR] %s\n", buf); -} - -void executor_set_log_callback(LogCallback cb) { g_log_cb = cb; } - -// 值辅助 -static SlotValue make_number(double v) { SlotValue v2; v2.type = SLOT_VALUE_NUMBER; v2.as.number = v; return v2; } -static SlotValue make_string(const char* s) { SlotValue v; v.type = SLOT_VALUE_STRING; strncpy(v.as.string, s, 255); return v; } -static SlotValue make_bool(int b) { SlotValue v; v.type = SLOT_VALUE_BOOLEAN; v.as.boolean = b; return v; } -static SlotValue make_vec3(float x, float y, float z) { SlotValue v; v.type = SLOT_VALUE_VECTOR3; v.as.vector3.x = x; v.as.vector3.y = y; v.as.vector3.z = z; return v; } - -// 连接追踪:获取槽位的输入值(通过连线回溯) -static SlotValue get_connected_value(BlockSlot* slot) { - if (slot->connected) return slot->connected->value; - return slot->value; -} - -BlockExecutor* executor_create(BlockWorkspace* ws) { - BlockExecutor* exec = (BlockExecutor*)calloc(1, sizeof(BlockExecutor)); - if (!exec) return NULL; - exec->workspace = ws; - return exec; -} - -void executor_destroy(BlockExecutor* exec) { free(exec); } - -void executor_start(BlockExecutor* exec) { - exec->state = EXEC_RUNNING; - exec->call_stack_top = 0; - exec->loop_stack_top = 0; - exec->current_block = NULL; - for (int i = 0; i < exec->workspace->block_count; i++) { - Block* block = exec->workspace->blocks[i]; - if (block->type == BLOCK_EVENT_START) { - exec->current_block = block; - log_info("执行器启动: 找到 on_start 事件"); - return; - } - } - log_error("未找到 on_start 事件积木"); - exec->state = EXEC_IDLE; -} - -void executor_stop(BlockExecutor* exec) { exec->state = EXEC_IDLE; exec->current_block = NULL; } -void executor_pause(BlockExecutor* exec) { if (exec->state == EXEC_RUNNING) exec->state = EXEC_PAUSED; } -void executor_resume(BlockExecutor* exec) { if (exec->state == EXEC_PAUSED) exec->state = EXEC_RUNNING; } - -// 获取下一个执行的积木(通过输出端口连接) -static Block* next_from_output(Block* block, int output_index) { - if (output_index >= block->output_count) return NULL; - BlockSlot* out = &block->outputs[output_index]; - if (out->connected && out->connected->owner) return out->connected->owner; - return NULL; -} - -// 查找循环体链的最后一个积木(用于确定循环结束后应跳转到的积木) -static Block* find_loop_body_end(Block* loop_block) { - if (!loop_block || loop_block->output_count == 0 || !loop_block->outputs[0].connected) return NULL; - Block* cur = loop_block->outputs[0].connected->owner; - Block* prev = loop_block; - int guard = 0; - while (cur && guard < 1000) { - guard++; - if (cur == loop_block) return prev; // 回到循环头,则前一个为体尾 - Block* next = NULL; - if (cur->output_count > 0 && cur->outputs[0].connected) { - next = cur->outputs[0].connected->owner; - } - if (!next) return cur; - prev = cur; - cur = next; - } - return cur; -} - -// 获取值输入 -static SlotValue get_input(Block* block, int idx) { - if (idx >= block->input_count) return make_number(0); - return get_connected_value(&block->inputs[idx]); -} - -void executor_step(BlockExecutor* exec) { - if (!exec->current_block) { exec->state = EXEC_IDLE; return; } - Block* cur = exec->current_block; - Block* next = NULL; - - switch (cur->type) { - // === 事件 === - case BLOCK_EVENT_START: - case BLOCK_EVENT_UPDATE: - case BLOCK_EVENT_COLLISION: - case BLOCK_EVENT_MOUSE_CLICK: - next = next_from_output(cur, 0); - break; - case BLOCK_EVENT_KEY_PRESSED: { - const char* key = get_input(cur, 0).as.string; - log_info("事件: 按键 '%s' (需要引擎集成)", key); - next = next_from_output(cur, 0); - break; - } - case BLOCK_EVENT_TIMER: { - double interval = get_input(cur, 0).as.number; - log_info("事件: 定时器 %.1fs (需要引擎集成)", interval); - next = next_from_output(cur, 0); - break; - } - - // === 动作 === - case BLOCK_ACTION_MOVE: { - double x = get_input(cur, 1).as.number; - double y = get_input(cur, 2).as.number; - double z = get_input(cur, 3).as.number; - log_info("移动物体: (%.2f, %.2f, %.2f)", x, y, z); - next = next_from_output(cur, 0); - break; - } - case BLOCK_ACTION_ROTATE: { - double x = get_input(cur, 1).as.number; - double y = get_input(cur, 2).as.number; - double z = get_input(cur, 3).as.number; - log_info("旋转物体: (%.2f, %.2f, %.2f)", x, y, z); - next = next_from_output(cur, 0); - break; - } - case BLOCK_ACTION_SCALE: { - double x = get_input(cur, 1).as.number; - double y = get_input(cur, 2).as.number; - double z = get_input(cur, 3).as.number; - log_info("缩放物体: (%.2f, %.2f, %.2f)", x, y, z); - next = next_from_output(cur, 0); - break; - } - case BLOCK_ACTION_SET_POSITION: { - double x = get_input(cur, 1).as.number; - double y = get_input(cur, 2).as.number; - double z = get_input(cur, 3).as.number; - log_info("设置位置: (%.2f, %.2f, %.2f)", x, y, z); - next = next_from_output(cur, 0); - break; - } - case BLOCK_ACTION_SET_ROTATION: { - double x = get_input(cur, 1).as.number; - double y = get_input(cur, 2).as.number; - double z = get_input(cur, 3).as.number; - log_info("设置旋转: (%.2f, %.2f, %.2f)", x, y, z); - next = next_from_output(cur, 0); - break; - } - case BLOCK_ACTION_PLAY_SOUND: { - const char* name = get_input(cur, 1).as.string; - log_info("播放音效: '%s'", name); - next = next_from_output(cur, 0); - break; - } - case BLOCK_ACTION_DESTROY: - log_info("销毁物体"); - next = next_from_output(cur, 0); - break; - case BLOCK_ACTION_INSTANTIATE: { - const char* prefab = get_input(cur, 1).as.string; - log_info("实例化预制体: '%s'", prefab); - next = next_from_output(cur, 0); - break; - } - - // === 控制流 === - case BLOCK_CONTROL_IF: - case BLOCK_CONTROL_IF_ELSE: { - int cond = get_input(cur, 1).as.boolean; - log_info("如果 %s", cond ? "真 -> Then" : "假 -> Else"); - next = next_from_output(cur, cond ? 0 : 1); - break; - } - case BLOCK_CONTROL_REPEAT: - case BLOCK_CONTROL_WHILE: { - int cond = get_input(cur, 1).as.boolean; - LoopFrame* frame = NULL; - if (exec->loop_stack_top > 0 && exec->loop_stack[exec->loop_stack_top - 1].loop_block == cur) { - frame = &exec->loop_stack[exec->loop_stack_top - 1]; - } else { - if (exec->loop_stack_top < MAX_LOOP_STACK) { - frame = &exec->loop_stack[exec->loop_stack_top++]; - frame->loop_block = cur; - frame->counter = 0; - frame->target = 0; - Block* body_end = find_loop_body_end(cur); - frame->after_block = body_end ? next_from_output(body_end, 0) : NULL; - } - } - if (frame && cond) { - frame->counter++; - next = next_from_output(cur, 0); - } else { - if (frame) exec->loop_stack_top--; - next = frame ? frame->after_block : next_from_output(cur, 0); - } - break; - } - case BLOCK_CONTROL_REPEAT_TIMES: { - double times = get_input(cur, 1).as.number; - LoopFrame* frame = NULL; - if (exec->loop_stack_top > 0 && exec->loop_stack[exec->loop_stack_top - 1].loop_block == cur) { - frame = &exec->loop_stack[exec->loop_stack_top - 1]; - frame->counter++; - } else { - if (exec->loop_stack_top < MAX_LOOP_STACK) { - frame = &exec->loop_stack[exec->loop_stack_top++]; - frame->loop_block = cur; - frame->counter = 0; - frame->target = (int)times; - Block* body_end = find_loop_body_end(cur); - frame->after_block = body_end ? next_from_output(body_end, 0) : NULL; - } - } - if (frame && frame->counter < frame->target) { - log_info("循环 %d / %d", frame->counter + 1, frame->target); - next = next_from_output(cur, 0); - } else { - if (frame) exec->loop_stack_top--; - next = frame ? frame->after_block : next_from_output(cur, 0); - } - break; - } - case BLOCK_CONTROL_WAIT: { - double secs = get_input(cur, 1).as.number; - log_info("等待 %.1f 秒", secs); - exec->wait_timer = secs; - exec->state = EXEC_WAITING; - exec->current_block = next_from_output(cur, 0); - return; - } - case BLOCK_CONTROL_FUNCTION_DEF: - log_info("函数定义 (跳过)"); - next = next_from_output(cur, 0); - break; - - // === 运算 === - case BLOCK_OP_ADD: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_number(a + b); - log_info("%.1f + %.1f = %.1f", a, b, a + b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_SUB: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_number(a - b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_MUL: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_number(a * b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_DIV: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_number(b != 0 ? a / b : 0); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_MOD: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_number(b != 0 ? fmod(a, b) : 0); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_EQUALS: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_bool(a == b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_NOT_EQUALS: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_bool(a != b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_GREATER: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_bool(a > b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_LESS: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_bool(a < b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_AND: { - int a = get_input(cur, 0).as.boolean; - int b = get_input(cur, 1).as.boolean; - cur->outputs[0].value = make_bool(a && b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_OR: { - int a = get_input(cur, 0).as.boolean; - int b = get_input(cur, 1).as.boolean; - cur->outputs[0].value = make_bool(a || b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_NOT: { - int a = get_input(cur, 0).as.boolean; - cur->outputs[0].value = make_bool(!a); - next = next_from_output(cur, 0); - break; - } - - // === 变量 === - case BLOCK_VAR_GET: { - const char* name = cur->label; - SlotValue val = executor_get_variable(exec, name); - cur->outputs[0].value = val; - log_info("读取变量 '%s' = %.2f", name, val.as.number); - next = next_from_output(cur, 0); - break; - } - case BLOCK_VAR_SET: { - const char* name = cur->label; - SlotValue val = get_input(cur, 1); - executor_set_variable(exec, name, val); - log_info("设置变量 '%s' = %.2f", name, val.as.number); - next = next_from_output(cur, 0); - break; - } - case BLOCK_VAR_CREATE: { - const char* name = cur->label; - executor_create_variable(exec, name); - log_info("创建变量 '%s' = 0", name); - next = next_from_output(cur, 0); - break; - } - - // === 函数 === - case BLOCK_FUNC_CALL: { - const char* fname = get_input(cur, 1).as.string; - log_info("调用函数 '%s'", fname); - - // 在工作区中查找同名函数定义积木 - Block* def = NULL; - for (int i = 0; i < exec->workspace->block_count; i++) { - Block* b = exec->workspace->blocks[i]; - if (b->type == BLOCK_CONTROL_FUNCTION_DEF && strcmp(b->label, fname) == 0) { - def = b; - break; - } - } - - if (def && exec->call_stack_top < MAX_CALL_STACK) { - exec->call_stack[exec->call_stack_top].block = cur; - exec->call_stack[exec->call_stack_top].return_block = next_from_output(cur, 0); - exec->call_stack_top++; - next = next_from_output(def, 0); - } else { - if (!def) log_error("未找到函数定义: '%s'", fname); - next = next_from_output(cur, 0); - } - break; - } - case BLOCK_FUNC_RETURN: { - if (exec->call_stack_top > 0) { - exec->call_stack_top--; - next = exec->call_stack[exec->call_stack_top].return_block; - } - break; - } - - default: - log_error("未知积木类型: %d", cur->type); - next = next_from_output(cur, 0); - break; - } - - // 若当前 next 是某个活跃循环的 after_block,则跳转回循环头继续判断 - if (next && exec->loop_stack_top > 0) { - LoopFrame* frame = &exec->loop_stack[exec->loop_stack_top - 1]; - if (next == frame->after_block) { - next = frame->loop_block; - } - } - - exec->current_block = next; - if (!exec->current_block) { - log_info("执行完成"); - exec->state = EXEC_IDLE; - } -} - -void executor_update(BlockExecutor* exec, double delta_time) { - if (exec->state == EXEC_WAITING) { - exec->wait_timer -= delta_time; - if (exec->wait_timer <= 0) exec->state = EXEC_RUNNING; - return; - } - if (exec->state != EXEC_RUNNING) return; - int steps = 0; - while (exec->current_block && exec->state == EXEC_RUNNING && steps < 1000) { - executor_step(exec); - steps++; - } -} - -void executor_set_variable(BlockExecutor* exec, const char* name, SlotValue value) { - for (int i = 0; i < exec->variable_count; i++) { - if (strcmp(exec->variables[i].name, name) == 0) { - exec->variables[i].value = value; - return; - } - } - if (exec->variable_count < MAX_VARIABLES) { - Variable* var = &exec->variables[exec->variable_count++]; - strncpy(var->name, name, 63); - var->value = value; - var->used = 1; - } -} - -SlotValue executor_get_variable(BlockExecutor* exec, const char* name) { - for (int i = 0; i < exec->variable_count; i++) { - if (strcmp(exec->variables[i].name, name) == 0) return exec->variables[i].value; - } - return make_number(0); -} - -void executor_create_variable(BlockExecutor* exec, const char* name) { - executor_set_variable(exec, name, make_number(0)); -} diff --git a/Engine/Engine/VisualScript/block_executor.h b/Engine/Engine/VisualScript/block_executor.h deleted file mode 100644 index 09603b2..0000000 --- a/Engine/Engine/VisualScript/block_executor.h +++ /dev/null @@ -1,86 +0,0 @@ -#pragma once - -// ============================================================================ -// block_executor.h - 积木执行引擎 -// ============================================================================ - -#include "block_workspace.h" - -#define MAX_VARIABLES 256 -#define MAX_CALL_STACK 32 -#define MAX_EXEC_STACK 1024 -#define MAX_LOOP_STACK 32 - -// 变量 -typedef struct { - char name[64]; - SlotValue value; - int used; -} Variable; - -// 调用帧 -typedef struct { - Block* block; - Block* return_block; -} CallFrame; - -// 循环帧 -typedef struct { - Block* loop_block; - int counter; - int target; - Block* after_block; -} LoopFrame; - -// 执行状态 -typedef enum { - EXEC_IDLE = 0, - EXEC_RUNNING, - EXEC_WAITING, - EXEC_PAUSED, - EXEC_ERROR -} ExecState; - -// 执行器 -typedef struct BlockExecutor { - BlockWorkspace* workspace; - ExecState state; - - Variable variables[MAX_VARIABLES]; - int variable_count; - - CallFrame call_stack[MAX_CALL_STACK]; - int call_stack_top; - - LoopFrame loop_stack[MAX_LOOP_STACK]; - int loop_stack_top; - - Block* current_block; - double wait_timer; - - int breakpoint_enabled; - Block* breakpoint_block; -} BlockExecutor; - -// 初始化/销毁 -BlockExecutor* executor_create(BlockWorkspace* ws); -void executor_destroy(BlockExecutor* exec); - -// 控制 -void executor_start(BlockExecutor* exec); -void executor_stop(BlockExecutor* exec); -void executor_pause(BlockExecutor* exec); -void executor_resume(BlockExecutor* exec); -void executor_step(BlockExecutor* exec); - -// 更新 (每帧调用) -void executor_update(BlockExecutor* exec, double delta_time); - -// 变量操作 -void executor_set_variable(BlockExecutor* exec, const char* name, SlotValue value); -SlotValue executor_get_variable(BlockExecutor* exec, const char* name); -void executor_create_variable(BlockExecutor* exec, const char* name); - -// 日志回调 -typedef void (*LogCallback)(const char* msg, int level); -void executor_set_log_callback(LogCallback cb); diff --git a/Engine/Engine/VisualScript/block_font.inc b/Engine/Engine/VisualScript/block_font.inc deleted file mode 100644 index 3ba92dd..0000000 --- a/Engine/Engine/VisualScript/block_font.inc +++ /dev/null @@ -1,99 +0,0 @@ -// 5x7 位图字体 (列优先, LSB 在上) -static const uint8_t BLOCK_FONT[96][5] = { - /* */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* ! */ {0x00, 0x00, 0xBE, 0x00, 0x00}, - /* " */ {0x00, 0x36, 0x36, 0x00, 0x00}, - /* # */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* $ */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* % */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* & */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* ' */ {0x00, 0x06, 0x06, 0x00, 0x00}, - /* ( */ {0x3C, 0x42, 0x81, 0x81, 0x00}, - /* ) */ {0x00, 0x81, 0x81, 0x42, 0x3C}, - /* * */ {0x22, 0x14, 0x08, 0x14, 0x22}, - /* + */ {0x08, 0x08, 0x7F, 0x08, 0x08}, - /* , */ {0x00, 0xA0, 0x60, 0x00, 0x00}, - /* - */ {0x08, 0x08, 0x08, 0x08, 0x08}, - /* . */ {0x00, 0x60, 0x60, 0x00, 0x00}, - /* / */ {0x80, 0x40, 0x20, 0x10, 0x08}, - /* 0 */ {0x7E, 0x81, 0x81, 0x81, 0x7E}, - /* 1 */ {0x00, 0x82, 0xFF, 0x80, 0x00}, - /* 2 */ {0xC2, 0xA1, 0x91, 0x89, 0x86}, - /* 3 */ {0x42, 0x81, 0x89, 0x89, 0x76}, - /* 4 */ {0x18, 0x28, 0x48, 0xFF, 0x08}, - /* 5 */ {0x4F, 0x89, 0x89, 0x89, 0x71}, - /* 6 */ {0x7E, 0x89, 0x89, 0x89, 0x72}, - /* 7 */ {0x01, 0xC1, 0x31, 0x0D, 0x03}, - /* 8 */ {0x76, 0x89, 0x89, 0x89, 0x76}, - /* 9 */ {0x46, 0x89, 0x89, 0x89, 0x7E}, - /* : */ {0x00, 0x66, 0x66, 0x00, 0x00}, - /* ; */ {0x00, 0xB6, 0x66, 0x00, 0x00}, - /* < */ {0x10, 0x28, 0x44, 0x82, 0x00}, - /* = */ {0x28, 0x28, 0x28, 0x28, 0x28}, - /* > */ {0x00, 0x82, 0x44, 0x28, 0x10}, - /* ? */ {0x02, 0x01, 0x51, 0x09, 0x06}, - /* @ */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* A */ {0x7E, 0x09, 0x09, 0x09, 0x7E}, - /* B */ {0xFF, 0x89, 0x89, 0x89, 0x76}, - /* C */ {0x7E, 0x81, 0x81, 0x81, 0x42}, - /* D */ {0xFF, 0x81, 0x81, 0x42, 0x3C}, - /* E */ {0xFF, 0x89, 0x89, 0x89, 0x81}, - /* F */ {0xFF, 0x09, 0x09, 0x09, 0x01}, - /* G */ {0x7E, 0x81, 0x89, 0x89, 0x72}, - /* H */ {0xFF, 0x08, 0x08, 0x08, 0xFF}, - /* I */ {0x00, 0x81, 0xFF, 0x81, 0x00}, - /* J */ {0x40, 0x80, 0x80, 0x80, 0x7F}, - /* K */ {0xFF, 0x08, 0x14, 0x22, 0x41}, - /* L */ {0xFF, 0x80, 0x80, 0x80, 0x80}, - /* M */ {0xFF, 0x02, 0x0C, 0x02, 0xFF}, - /* N */ {0xFF, 0x04, 0x08, 0x10, 0xFF}, - /* O */ {0x7E, 0x81, 0x81, 0x81, 0x7E}, - /* P */ {0xFF, 0x09, 0x09, 0x09, 0x06}, - /* Q */ {0x7E, 0x81, 0xA1, 0x41, 0xBE}, - /* R */ {0xFF, 0x09, 0x19, 0x29, 0x46}, - /* S */ {0x46, 0x89, 0x89, 0x89, 0x72}, - /* T */ {0x01, 0x01, 0xFF, 0x01, 0x01}, - /* U */ {0x7F, 0x80, 0x80, 0x80, 0x7F}, - /* V */ {0x3F, 0x40, 0x80, 0x40, 0x3F}, - /* W */ {0x7F, 0x80, 0x70, 0x80, 0x7F}, - /* X */ {0xC3, 0x24, 0x18, 0x24, 0xC3}, - /* Y */ {0x03, 0x04, 0xF8, 0x04, 0x03}, - /* Z */ {0xC1, 0xA1, 0x91, 0x89, 0x87}, - /* [ */ {0x7E, 0x82, 0x82, 0x82, 0x00}, - /* \ */ {0x08, 0x10, 0x20, 0x40, 0x80}, - /* ] */ {0x00, 0x82, 0x82, 0x82, 0x7E}, - /* ^ */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* _ */ {0x80, 0x80, 0x80, 0x80, 0x80}, - /* ` */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* a */ {0x20, 0x54, 0x54, 0x54, 0x78}, - /* b */ {0xFF, 0x48, 0x48, 0x48, 0x30}, - /* c */ {0x38, 0x44, 0x44, 0x44, 0x44}, - /* d */ {0x30, 0x48, 0x48, 0x48, 0xFF}, - /* e */ {0x38, 0x54, 0x54, 0x54, 0x58}, - /* f */ {0x08, 0x7E, 0x09, 0x01, 0x02}, - /* g */ {0x08, 0x54, 0x54, 0x54, 0x3C}, - /* h */ {0xFF, 0x08, 0x08, 0x08, 0xF0}, - /* i */ {0x00, 0x48, 0x7A, 0x40, 0x00}, - /* j */ {0x20, 0x40, 0x40, 0x3A, 0x00}, - /* k */ {0xFF, 0x10, 0x28, 0x44, 0x82}, - /* l */ {0x00, 0x41, 0xFF, 0x40, 0x00}, - /* m */ {0x7C, 0x04, 0x78, 0x04, 0x78}, - /* n */ {0x7C, 0x04, 0x04, 0x04, 0xF8}, - /* o */ {0x38, 0x44, 0x44, 0x44, 0x38}, - /* p */ {0xFC, 0x24, 0x24, 0x24, 0x18}, - /* q */ {0x18, 0x24, 0x24, 0x24, 0xFC}, - /* r */ {0x7C, 0x08, 0x04, 0x04, 0x08}, - /* s */ {0x48, 0x54, 0x54, 0x54, 0x24}, - /* t */ {0x04, 0x3F, 0x44, 0x40, 0x20}, - /* u */ {0x3C, 0x40, 0x40, 0x40, 0x3C}, - /* v */ {0x1C, 0x20, 0x40, 0x20, 0x1C}, - /* w */ {0x3C, 0x40, 0x30, 0x40, 0x3C}, - /* x */ {0x44, 0x28, 0x10, 0x28, 0x44}, - /* y */ {0x0C, 0x50, 0x50, 0x50, 0x3C}, - /* z */ {0x44, 0x64, 0x54, 0x4C, 0x44}, - /* { */ {0x18, 0x24, 0x42, 0x24, 0x18}, - /* | */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* } */ {0x18, 0x24, 0x42, 0x24, 0x18}, - /* ~ */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* \x7f */ {0x00, 0x00, 0x00, 0x00, 0x00}, -}; diff --git a/Engine/Engine/VisualScript/block_interaction.c b/Engine/Engine/VisualScript/block_interaction.c deleted file mode 100644 index 99dc3fb..0000000 --- a/Engine/Engine/VisualScript/block_interaction.c +++ /dev/null @@ -1,151 +0,0 @@ -// ============================================================================ -// block_interaction.c - 交互系统实现 -// ============================================================================ - -#include "block_interaction.h" -#include -#include -#include -#include - -void interaction_init(BlockInteraction* inter) { - memset(inter, 0, sizeof(BlockInteraction)); -} - -void interaction_mouse_move(BlockInteraction* inter, BlockWorkspace* ws, int x, int y) { - inter->mouse_x = x; - inter->mouse_y = y; - - // 拖拽积木 - if (inter->dragging_block) { - float wx, wy; - workspace_screen_to_world(ws, (float)x, (float)y, &wx, &wy); - inter->dragging_block->x = wx - inter->drag_offset_x; - inter->dragging_block->y = wy - inter->drag_offset_y; - } - - // 平移画布 - if (inter->panning) { - float dx = (x - inter->pan_start_x) / ws->zoom; - float dy = (y - inter->pan_start_y) / ws->zoom; - ws->view_x = inter->view_start_x - dx; - ws->view_y = inter->view_start_y - dy; - } -} - -void interaction_mouse_down(BlockInteraction* inter, BlockWorkspace* ws, int button) { - inter->mouse_down = 1; - inter->mouse_button = button; - - float wx, wy; - workspace_screen_to_world(ws, (float)inter->mouse_x, (float)inter->mouse_y, &wx, &wy); - - if (button == 0) { // 左键 - // 检查是否点击槽位 - BlockSlot* slot = workspace_find_slot_at(ws, wx, wy); - if (slot) { - // 开始连接 - inter->connecting_from = slot; - inter->connect_start_x = wx; - inter->connect_start_y = wy; - return; - } - - // 检查是否点击积木 - Block* block = workspace_find_block_at(ws, wx, wy); - if (block) { - inter->dragging_block = block; - inter->drag_offset_x = wx - block->x; - inter->drag_offset_y = wy - block->y; - inter->selected_block = block; - ws->selected_block = block; - return; - } - - // 点击空白区域: 取消选择 - inter->selected_block = NULL; - ws->selected_block = NULL; - } - - if (button == 1 || button == 2) { // 右键/中键: 平移 - inter->panning = 1; - inter->pan_start_x = (float)inter->mouse_x; - inter->pan_start_y = (float)inter->mouse_y; - inter->view_start_x = ws->view_x; - inter->view_start_y = ws->view_y; - } -} - -void interaction_mouse_up(BlockInteraction* inter, BlockWorkspace* ws, int button) { - inter->mouse_down = 0; - - if (button == 0) { - // 结束拖拽积木 - inter->dragging_block = NULL; - - // 结束连接 - if (inter->connecting_from) { - float wx, wy; - workspace_screen_to_world(ws, (float)inter->mouse_x, (float)inter->mouse_y, &wx, &wy); - - BlockSlot* target = workspace_find_slot_at(ws, wx, wy); - if (target && target != inter->connecting_from) { - // 尝试建立连接 - workspace_add_connection(ws, inter->connecting_from, target); - } - inter->connecting_from = NULL; - } - } - - if (button == 1 || button == 2) { - inter->panning = 0; - } -} - -void interaction_key_down(BlockInteraction* inter, BlockWorkspace* ws, int key) { - inter->key = key; - inter->key_pressed = 1; - - // 删除选中的积木 - if (key == 46 || key == 8) { // DELETE 或 BACKSPACE - if (inter->selected_block) { - workspace_remove_block(ws, inter->selected_block->id); - inter->selected_block = NULL; - ws->selected_block = NULL; - } - } - - // 复制/粘贴 (Ctrl+C / Ctrl+V) - static Block* clipboard = NULL; - if (key == 'C' && (GetAsyncKeyState(VK_CONTROL) & 0x8000)) { - if (inter->selected_block) { - if (clipboard) block_destroy(clipboard); - clipboard = block_copy(inter->selected_block); - } - } - if (key == 'V' && (GetAsyncKeyState(VK_CONTROL) & 0x8000)) { - if (clipboard) { - Block* copy = block_copy(clipboard); - if (copy) { - copy->x += 20.0f; - copy->y += 20.0f; - copy->id = ws->next_block_id++; - workspace_add_block(ws, copy); - inter->selected_block = copy; - ws->selected_block = copy; - } - } - } -} - -void interaction_mouse_wheel(BlockInteraction* inter, BlockWorkspace* ws, int delta) { - float zoom_factor = delta > 0 ? 1.1f : 0.9f; - ws->zoom *= zoom_factor; - if (ws->zoom < 0.25f) ws->zoom = 0.25f; - if (ws->zoom > 4.0f) ws->zoom = 4.0f; -} - -void interaction_update(BlockInteraction* inter, BlockWorkspace* ws) { - inter->key_pressed = 0; - (void)ws; -} diff --git a/Engine/Engine/VisualScript/block_interaction.h b/Engine/Engine/VisualScript/block_interaction.h deleted file mode 100644 index cb90b68..0000000 --- a/Engine/Engine/VisualScript/block_interaction.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -// ============================================================================ -// block_interaction.h - 交互系统 -// ============================================================================ - -#include "block_workspace.h" - -typedef struct { - int mouse_x, mouse_y; - int mouse_down; - int mouse_button; // 0=left, 1=right, 2=middle - int key; - int key_pressed; - - // 拖拽状态 - Block* dragging_block; - float drag_offset_x, drag_offset_y; - - // 连接状态 - BlockSlot* connecting_from; - float connect_start_x, connect_start_y; - - // 选择状态 - Block* selected_block; - - // 平移状态 - int panning; - float pan_start_x, pan_start_y; - float view_start_x, view_start_y; -} BlockInteraction; - -// 初始化 -void interaction_init(BlockInteraction* inter); - -// 处理输入事件 -void interaction_mouse_move(BlockInteraction* inter, BlockWorkspace* ws, int x, int y); -void interaction_mouse_down(BlockInteraction* inter, BlockWorkspace* ws, int button); -void interaction_mouse_up(BlockInteraction* inter, BlockWorkspace* ws, int button); -void interaction_key_down(BlockInteraction* inter, BlockWorkspace* ws, int key); -void interaction_mouse_wheel(BlockInteraction* inter, BlockWorkspace* ws, int delta); - -// 更新 (每帧调用) -void interaction_update(BlockInteraction* inter, BlockWorkspace* ws); diff --git a/Engine/Engine/VisualScript/block_palette.c b/Engine/Engine/VisualScript/block_palette.c deleted file mode 100644 index 672dad4..0000000 --- a/Engine/Engine/VisualScript/block_palette.c +++ /dev/null @@ -1,140 +0,0 @@ -// ============================================================================ -// block_palette.c - 积木面板实现 -// ============================================================================ - -#include "block_palette.h" -#include "block_renderer.h" -#include -#include -#include - -void palette_init(BlockPalette* palette) { - memset(palette, 0, sizeof(BlockPalette)); - palette->width = 200; - palette->height = 600; - - // 添加所有积木类型 - int count; - const BlockTypeInfo* all = block_type_get_all(&count); - for (int i = 0; i < count; i++) { - palette_add_block(palette, all[i].type); - } -} - -void palette_add_block(BlockPalette* palette, BlockType type) { - const BlockTypeInfo* info = block_type_get_info(type); - if (!info) return; - - // 查找或创建分类 - for (int i = 0; i < palette->category_count; i++) { - if (strcmp(palette->categories[i].name, info->category) == 0) { - palette->categories[i].blocks[palette->categories[i].block_count++] = type; - return; - } - } - - // 创建新分类 - if (palette->category_count < MAX_PALETTE_CATEGORIES) { - PaletteCategory* cat = &palette->categories[palette->category_count++]; - strncpy(cat->name, info->category, 63); - cat->blocks[cat->block_count++] = type; - cat->expanded = 1; - } -} - -void palette_render(BlockPalette* palette, BlockRenderer* renderer) { - // 绘制背景 - block_renderer_add_quad(renderer, palette->x, palette->y, palette->width, palette->height, - 0.15f, 0.15f, 0.18f, 1.0f); - - // 绘制标题 - block_renderer_draw_text(renderer, "积木面板", palette->x + 5, palette->y + 5, - 1.0f, 1.0f, 1.0f); - - float y = palette->y + 25 - palette->scroll_y; - - for (int c = 0; c < palette->category_count; c++) { - PaletteCategory* cat = &palette->categories[c]; - - // 绘制分类标题 - block_renderer_add_quad(renderer, palette->x + 2, y, palette->width - 4, 20, - 0.25f, 0.25f, 0.3f, 1.0f); - - const char* arrow = cat->expanded ? "[-]" : "[+]"; - char title[128]; - snprintf(title, 128, "%s %s (%d)", arrow, cat->name, cat->block_count); - block_renderer_draw_text(renderer, title, palette->x + 5, y + 3, - 0.9f, 0.9f, 0.9f); - - y += 22; - - if (!cat->expanded) continue; - - // 绘制积木列表 - for (int b = 0; b < cat->block_count; b++) { - const BlockTypeInfo* info = block_type_get_info(cat->blocks[b]); - if (!info) continue; - - // 搜索过滤 - if (palette->search_active && palette->search_text[0]) { - if (strstr(info->name, palette->search_text) == NULL && - strstr(info->label, palette->search_text) == NULL) { - continue; - } - } - - // 绘制积木预览 - block_renderer_add_quad(renderer, palette->x + 5, y, palette->width - 10, 18, - info->color.r, info->color.g, info->color.b, info->color.a); - - block_renderer_draw_text(renderer, info->label, palette->x + 10, y + 3, - 1.0f, 1.0f, 1.0f); - - y += 20; - } - - y += 5; - } -} - -BlockType palette_handle_click(BlockPalette* palette, float mx, float my) { - float y = palette->y + 25 - palette->scroll_y; - - for (int c = 0; c < palette->category_count; c++) { - PaletteCategory* cat = &palette->categories[c]; - - // 检查分类标题点击 - if (mx >= palette->x && mx <= palette->x + palette->width && - my >= y && my <= y + 20) { - cat->expanded = !cat->expanded; - return -1; - } - - y += 22; - - if (!cat->expanded) continue; - - // 检查积木点击 - for (int b = 0; b < cat->block_count; b++) { - if (mx >= palette->x + 5 && mx <= palette->x + palette->width - 5 && - my >= y && my <= y + 18) { - return cat->blocks[b]; - } - y += 20; - } - - y += 5; - } - - return -1; -} - -void palette_search(BlockPalette* palette, const char* text) { - if (text) { - strncpy(palette->search_text, text, 127); - palette->search_active = 1; - } else { - palette->search_text[0] = '\0'; - palette->search_active = 0; - } -} diff --git a/Engine/Engine/VisualScript/block_palette.h b/Engine/Engine/VisualScript/block_palette.h deleted file mode 100644 index 868b0dc..0000000 --- a/Engine/Engine/VisualScript/block_palette.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -// ============================================================================ -// block_palette.h - 积木面板 -// ============================================================================ - -#include "block_types.h" -#include "block_workspace.h" - -#define MAX_PALETTE_CATEGORIES 16 - -typedef struct { - char name[64]; - BlockType blocks[64]; - int block_count; - int expanded; -} PaletteCategory; - -typedef struct BlockPalette { - PaletteCategory categories[MAX_PALETTE_CATEGORIES]; - int category_count; - - float x, y, width, height; - float scroll_y; - - char search_text[128]; - int search_active; -} BlockPalette; - -// 初始化 -void palette_init(BlockPalette* palette); - -// 添加积木到面板 (按分类) -void palette_add_block(BlockPalette* palette, BlockType type); - -struct BlockRenderer; -void palette_render(BlockPalette* palette, struct BlockRenderer* renderer); - -// 处理点击 -BlockType palette_handle_click(BlockPalette* palette, float mx, float my); - -// 搜索 -void palette_search(BlockPalette* palette, const char* text); diff --git a/Engine/Engine/VisualScript/block_renderer.c b/Engine/Engine/VisualScript/block_renderer.c deleted file mode 100644 index 8d42ee4..0000000 --- a/Engine/Engine/VisualScript/block_renderer.c +++ /dev/null @@ -1,190 +0,0 @@ -#include "block_renderer.h" -#include "block_core.h" -#include -#include -#include - -// 5x7 位图字体 (列优先, LSB 在上) -#include "block_font.inc" - -int block_renderer_init(BlockRenderer* renderer, void* device, void* context) { - memset(renderer, 0, sizeof(BlockRenderer)); - renderer->device = (ID3D11Device*)device; - renderer->context = (ID3D11DeviceContext*)context; - renderer->vertex_capacity = 65536; - renderer->vertex_data = (float*)malloc(renderer->vertex_capacity * 7 * sizeof(float)); - renderer->index_capacity = 65536; - renderer->index_data = (uint32_t*)malloc(renderer->index_capacity * sizeof(uint32_t)); - return 1; -} - -void block_renderer_shutdown(BlockRenderer* renderer) { - if (renderer->vertex_data) free(renderer->vertex_data); - if (renderer->index_data) free(renderer->index_data); - if (renderer->vertex_buffer) renderer->vertex_buffer->lpVtbl->Release(renderer->vertex_buffer); - if (renderer->index_buffer) renderer->index_buffer->lpVtbl->Release(renderer->index_buffer); - if (renderer->vertex_shader) renderer->vertex_shader->lpVtbl->Release(renderer->vertex_shader); - if (renderer->pixel_shader) renderer->pixel_shader->lpVtbl->Release(renderer->pixel_shader); - if (renderer->input_layout) renderer->input_layout->lpVtbl->Release(renderer->input_layout); - memset(renderer, 0, sizeof(BlockRenderer)); -} - -void block_renderer_begin(BlockRenderer* renderer) { - renderer->vertex_count = 0; - renderer->index_count = 0; -} - -void block_renderer_end(BlockRenderer* renderer) { - if (renderer->vertex_count == 0) return; - ID3D11DeviceContext* ctx = renderer->context; - - D3D11_MAPPED_SUBRESOURCE mapped; - if (SUCCEEDED(ctx->lpVtbl->Map(ctx, (ID3D11Resource*)renderer->vertex_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped))) { - memcpy(mapped.pData, renderer->vertex_data, renderer->vertex_count * 7 * sizeof(float)); - ctx->lpVtbl->Unmap(ctx, (ID3D11Resource*)renderer->vertex_buffer, 0); - } - - if (renderer->index_count > 0) { - if (SUCCEEDED(ctx->lpVtbl->Map(ctx, (ID3D11Resource*)renderer->index_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped))) { - memcpy(mapped.pData, renderer->index_data, renderer->index_count * sizeof(uint32_t)); - ctx->lpVtbl->Unmap(ctx, (ID3D11Resource*)renderer->index_buffer, 0); - } - } - - UINT stride = 7 * sizeof(float); - UINT offset = 0; - ID3D11Buffer* vb = renderer->vertex_buffer; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &vb, &stride, &offset); - - if (renderer->index_buffer) { - ctx->lpVtbl->IASetIndexBuffer(ctx, renderer->index_buffer, DXGI_FORMAT_R32_UINT, 0); - } - ctx->lpVtbl->IASetInputLayout(ctx, renderer->input_layout); - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ctx->lpVtbl->VSSetShader(ctx, renderer->vertex_shader, NULL, 0); - ctx->lpVtbl->PSSetShader(ctx, renderer->pixel_shader, NULL, 0); - - if (renderer->index_count > 0) { - ctx->lpVtbl->DrawIndexed(ctx, renderer->index_count, 0, 0); - } else { - ctx->lpVtbl->Draw(ctx, renderer->vertex_count, 0); - } -} - -void block_renderer_add_quad(BlockRenderer* renderer, float x, float y, float w, float h, float r, float g, float b, float a) { - if (renderer->vertex_count + 4 > renderer->vertex_capacity) return; - if (renderer->index_count + 6 > renderer->index_capacity) return; - - uint32_t base = renderer->vertex_count; - float* v = renderer->vertex_data + base * 7; - - v[0*7+0] = x; v[0*7+1] = y; v[0*7+2] = 0; v[0*7+3] = r; v[0*7+4] = g; v[0*7+5] = b; v[0*7+6] = a; - v[1*7+0] = x + w; v[1*7+1] = y; v[1*7+2] = 0; v[1*7+3] = r; v[1*7+4] = g; v[1*7+5] = b; v[1*7+6] = a; - v[2*7+0] = x + w; v[2*7+1] = y + h; v[2*7+2] = 0; v[2*7+3] = r; v[2*7+4] = g; v[2*7+5] = b; v[2*7+6] = a; - v[3*7+0] = x; v[3*7+1] = y + h; v[3*7+2] = 0; v[3*7+3] = r; v[3*7+4] = g; v[3*7+5] = b; v[3*7+6] = a; - - renderer->vertex_count += 4; - - renderer->index_data[renderer->index_count++] = base + 0; - renderer->index_data[renderer->index_count++] = base + 1; - renderer->index_data[renderer->index_count++] = base + 2; - renderer->index_data[renderer->index_count++] = base + 0; - renderer->index_data[renderer->index_count++] = base + 2; - renderer->index_data[renderer->index_count++] = base + 3; -} - -void block_renderer_add_line(BlockRenderer* renderer, float x1, float y1, float x2, float y2, float r, float g, float b, float a) { - float dx = x2 - x1; - float dy = y2 - y1; - float len = sqrtf(dx * dx + dy * dy); - if (len < 0.001f) return; - - const float thickness = 1.0f; - float nx = -dy / len * thickness * 0.5f; - float ny = dx / len * thickness * 0.5f; - - if (renderer->vertex_count + 4 > renderer->vertex_capacity) return; - if (renderer->index_count + 6 > renderer->index_capacity) return; - - uint32_t base = renderer->vertex_count; - float* v = renderer->vertex_data + base * 7; - - v[0*7+0] = x1 + nx; v[0*7+1] = y1 + ny; v[0*7+2] = 0; v[0*7+3] = r; v[0*7+4] = g; v[0*7+5] = b; v[0*7+6] = a; - v[1*7+0] = x2 + nx; v[1*7+1] = y2 + ny; v[1*7+2] = 0; v[1*7+3] = r; v[1*7+4] = g; v[1*7+5] = b; v[1*7+6] = a; - v[2*7+0] = x2 - nx; v[2*7+1] = y2 - ny; v[2*7+2] = 0; v[2*7+3] = r; v[2*7+4] = g; v[2*7+5] = b; v[2*7+6] = a; - v[3*7+0] = x1 - nx; v[3*7+1] = y1 - ny; v[3*7+2] = 0; v[3*7+3] = r; v[3*7+4] = g; v[3*7+5] = b; v[3*7+6] = a; - - renderer->vertex_count += 4; - - renderer->index_data[renderer->index_count++] = base + 0; - renderer->index_data[renderer->index_count++] = base + 1; - renderer->index_data[renderer->index_count++] = base + 2; - renderer->index_data[renderer->index_count++] = base + 0; - renderer->index_data[renderer->index_count++] = base + 2; - renderer->index_data[renderer->index_count++] = base + 3; -} - -static void block_renderer_add_bezier(BlockRenderer* renderer, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2, float r, float g, float b, float a) { - int segments = 16; - float prev_x = x1, prev_y = y1; - for (int i = 1; i <= segments; i++) { - float t = (float)i / segments; - float mt = 1.0f - t; - float px = mt*mt*mt*x1 + 3*mt*mt*t*cx1 + 3*mt*t*t*cx2 + t*t*t*x2; - float py = mt*mt*mt*y1 + 3*mt*mt*t*cy1 + 3*mt*t*t*cy2 + t*t*t*y2; - block_renderer_add_line(renderer, prev_x, prev_y, px, py, r, g, b, a); - prev_x = px; - prev_y = py; - } -} - -void block_renderer_draw_block(BlockRenderer* renderer, Block* block, float view_x, float view_y, float zoom) { - float x = (block->x - view_x) * zoom; - float y = (block->y - view_y) * zoom; - float w = block->width * zoom; - float h = block->height * zoom; - - block_renderer_add_quad(renderer, x, y, w, h, 0.3f, 0.3f, 0.35f, 1.0f); - block_renderer_add_quad(renderer, x, y, w, 20 * zoom, 0.2f, 0.2f, 0.25f, 1.0f); - - if (block->label[0]) { - block_renderer_draw_text(renderer, block->label, x + 4.0f * zoom, y + 4.0f * zoom, 0.9f, 0.9f, 0.9f); - } -} - -void block_renderer_draw_connection(BlockRenderer* renderer, BlockSlot* from, BlockSlot* to, float view_x, float view_y, float zoom) { - float x1 = (from->owner->x + from->x - view_x) * zoom; - float y1 = (from->owner->y + from->y - view_y) * zoom; - float x2 = (to->owner->x + to->x - view_x) * zoom; - float y2 = (to->owner->y + to->y - view_y) * zoom; - - float dx = fabsf(x2 - x1) * 0.5f; - if (dx < 50.0f) dx = 50.0f; - - block_renderer_add_bezier(renderer, x1, y1, x1 + dx, y1, x2 - dx, y2, x2, y2, 0.8f, 0.8f, 0.2f, 1.0f); -} - -void block_renderer_draw_text(BlockRenderer* renderer, const char* text, float x, float y, float r, float g, float b) { - if (!text) return; - const float scale = 2.0f; - const float advance = 5.0f * scale + 1.0f; - float cx = x; - for (const char* p = text; *p; ++p) { - unsigned char ch = (unsigned char)*p; - if (ch < 32 || ch > 127) ch = '?'; - int idx = ch - 32; - for (int col = 0; col < 5; ++col) { - uint8_t column = BLOCK_FONT[idx][col]; - for (int row = 0; row < 7; ++row) { - if (column & (1u << row)) { - block_renderer_add_quad(renderer, - cx + col * scale, - y + row * scale, - scale, scale, - r, g, b, 1.0f); - } - } - } - cx += advance; - } -} diff --git a/Engine/Engine/VisualScript/block_renderer.h b/Engine/Engine/VisualScript/block_renderer.h deleted file mode 100644 index d3f5075..0000000 --- a/Engine/Engine/VisualScript/block_renderer.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "block_workspace.h" -#include -#include - -typedef struct BlockRenderer { - ID3D11Device* device; - ID3D11DeviceContext* context; - ID3D11Buffer* vertex_buffer; - ID3D11Buffer* index_buffer; - ID3D11VertexShader* vertex_shader; - ID3D11PixelShader* pixel_shader; - ID3D11InputLayout* input_layout; - - float* vertex_data; - int vertex_count; - int vertex_capacity; - uint32_t* index_data; - int index_count; - int index_capacity; -} BlockRenderer; - -int block_renderer_init(BlockRenderer* renderer, void* device, void* context); -void block_renderer_shutdown(BlockRenderer* renderer); -void block_renderer_begin(BlockRenderer* renderer); -void block_renderer_end(BlockRenderer* renderer); -void block_renderer_draw_block(BlockRenderer* renderer, Block* block, float view_x, float view_y, float zoom); -void block_renderer_draw_connection(BlockRenderer* renderer, BlockSlot* from, BlockSlot* to, float view_x, float view_y, float zoom); -void block_renderer_draw_text(BlockRenderer* renderer, const char* text, float x, float y, float r, float g, float b); -void block_renderer_add_quad(BlockRenderer* renderer, float x, float y, float w, float h, float r, float g, float b, float a); -void block_renderer_add_line(BlockRenderer* renderer, float x1, float y1, float x2, float y2, float r, float g, float b, float a); diff --git a/Engine/Engine/VisualScript/block_serializer.c b/Engine/Engine/VisualScript/block_serializer.c deleted file mode 100644 index 7ad6bed..0000000 --- a/Engine/Engine/VisualScript/block_serializer.c +++ /dev/null @@ -1,415 +0,0 @@ -// ============================================================================ -// block_serializer.c - JSON 序列化实现 -// ============================================================================ - -#include "block_serializer.h" -#include "block_types.h" -#include -#include -#include - -// 简单的 JSON 生成器 -typedef struct { - char* buffer; - size_t size; - size_t capacity; -} JsonBuffer; - -static void json_init(JsonBuffer* buf) { - buf->capacity = 4096; - buf->buffer = (char*)malloc(buf->capacity); - buf->size = 0; - buf->buffer[0] = '\0'; -} - -static void json_append(JsonBuffer* buf, const char* str) { - size_t len = strlen(str); - if (buf->size + len + 1 > buf->capacity) { - buf->capacity = (buf->size + len + 1) * 2; - buf->buffer = (char*)realloc(buf->buffer, buf->capacity); - } - memcpy(buf->buffer + buf->size, str, len + 1); - buf->size += len; -} - -int serializer_save(BlockWorkspace* ws, const char* filepath) { - char* json = serializer_save_to_string(ws); - if (!json) return 0; - - FILE* f = fopen(filepath, "w"); - if (!f) { - free(json); - return 0; - } - - fprintf(f, "%s", json); - fclose(f); - free(json); - return 1; -} - -int serializer_load(BlockWorkspace* ws, const char* filepath) { - FILE* f = fopen(filepath, "r"); - if (!f) return 0; - - fseek(f, 0, SEEK_END); - long size = ftell(f); - fseek(f, 0, SEEK_SET); - - char* json = (char*)malloc(size + 1); - fread(json, 1, size, f); - json[size] = '\0'; - fclose(f); - - int result = serializer_load_from_string(ws, json); - free(json); - return result; -} - -char* serializer_save_to_string(BlockWorkspace* ws) { - JsonBuffer buf; - json_init(&buf); - - json_append(&buf, "{\n"); - json_append(&buf, " \"version\": \"1.0\",\n"); - - // 保存积木 - json_append(&buf, " \"blocks\": [\n"); - for (int i = 0; i < ws->block_count; i++) { - Block* block = ws->blocks[i]; - const BlockTypeInfo* info = block_type_get_info(block->type); - - char tmp[256]; - snprintf(tmp, 256, " {\n"); - json_append(&buf, tmp); - - snprintf(tmp, 256, " \"id\": %d,\n", block->id); - json_append(&buf, tmp); - - snprintf(tmp, 256, " \"type\": \"%s\",\n", info ? info->name : "unknown"); - json_append(&buf, tmp); - - snprintf(tmp, 256, " \"x\": %.1f,\n", block->x); - json_append(&buf, tmp); - - snprintf(tmp, 256, " \"y\": %.1f,\n", block->y); - json_append(&buf, tmp); - - snprintf(tmp, 256, " \"label\": \"%s\"", block->label); - json_append(&buf, tmp); - - // 保存输入槽默认值 - if (block->input_count > 0) { - json_append(&buf, ",\n \"inputs\": [\n"); - for (int j = 0; j < block->input_count; j++) { - BlockSlot* slot = &block->inputs[j]; - SlotValue* val = &slot->value; - switch (val->type) { - case SLOT_VALUE_NUMBER: - snprintf(tmp, 256, " {\"type\": \"number\", \"value\": %.6g}%s\n", val->as.number, j < block->input_count - 1 ? "," : ""); - break; - case SLOT_VALUE_STRING: - snprintf(tmp, 256, " {\"type\": \"string\", \"value\": \"%s\"}%s\n", val->as.string, j < block->input_count - 1 ? "," : ""); - break; - case SLOT_VALUE_BOOLEAN: - snprintf(tmp, 256, " {\"type\": \"boolean\", \"value\": %s}%s\n", val->as.boolean ? "true" : "false", j < block->input_count - 1 ? "," : ""); - break; - default: - snprintf(tmp, 256, " {\"type\": \"number\", \"value\": 0}%s\n", j < block->input_count - 1 ? "," : ""); - break; - } - json_append(&buf, tmp); - } - json_append(&buf, " ]"); - } - - json_append(&buf, "\n"); - json_append(&buf, i < ws->block_count - 1 ? " },\n" : " }\n"); - } - json_append(&buf, " ],\n"); - - // 保存连接 - json_append(&buf, " \"connections\": [\n"); - for (int i = 0; i < ws->connection_count; i++) { - BlockConnection* conn = &ws->connections[i]; - char tmp[128]; - snprintf(tmp, 128, " {\"from\": %d, \"to\": %d}%s\n", - conn->from ? conn->from->owner->id : 0, - conn->to ? conn->to->owner->id : 0, - i < ws->connection_count - 1 ? "," : ""); - json_append(&buf, tmp); - } - json_append(&buf, " ]\n"); - - json_append(&buf, "}\n"); - - return buf.buffer; -} - -// 跳过空白字符 -static const char* skip_ws(const char* p) { - while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') p++; - return p; -} - -// 查找字符串值,返回指向引号内内容的指针,并在 *len 中设置长度 -static const char* parse_json_string(const char* p, int* len) { - p = skip_ws(p); - if (*p != '"') return NULL; - p++; - const char* start = p; - while (*p && *p != '"') p++; - if (*p != '"') return NULL; - *len = (int)(p - start); - return start; -} - -// 查找数字值,返回指向数字开头的指针 -static const char* parse_json_number(const char* p, float* out) { - p = skip_ws(p); - const char* start = p; - if (*p == '-') p++; - while (*p >= '0' && *p <= '9') p++; - if (*p == '.') { - p++; - while (*p >= '0' && *p <= '9') p++; - } - if (p == start) return NULL; - *out = (float)strtod(start, NULL); - return p; -} - -int serializer_load_from_string(BlockWorkspace* ws, const char* json_str) { - workspace_clear(ws); - block_types_init(); - - // 解析 blocks 数组 - const char* blocks_key = strstr(json_str, "\"blocks\""); - if (!blocks_key) return 0; - const char* p = blocks_key + 8; - p = skip_ws(p); - if (*p != ':') return 0; - p++; - p = skip_ws(p); - if (*p != '[') return 0; - p++; - - while (1) { - p = skip_ws(p); - if (*p == ']') { p++; break; } - if (*p != '{') return 0; - p++; - - int id = 0; - char type_name[64] = {0}; - char label[64] = {0}; - float x = 0, y = 0; - SlotValue input_values[MAX_BLOCK_INPUTS]; - int input_count = 0; - - while (1) { - p = skip_ws(p); - if (*p == '}') { p++; break; } - - int key_len = 0; - const char* key = parse_json_string(p, &key_len); - if (!key) return 0; - p = key + key_len + 1; - p = skip_ws(p); - if (*p != ':') return 0; - p++; - - if (key_len == 2 && strncmp(key, "id", 2) == 0) { - float fv; p = parse_json_number(p, &fv); id = (int)fv; - } else if (key_len == 4 && strncmp(key, "type", 4) == 0) { - int val_len = 0; - const char* val = parse_json_string(p, &val_len); - if (val) { - if (val_len >= (int)sizeof(type_name)) val_len = (int)sizeof(type_name) - 1; - strncpy(type_name, val, val_len); - type_name[val_len] = '\0'; - p = val + val_len + 1; - } - } else if (key_len == 1 && *key == 'x') { - p = parse_json_number(p, &x); - } else if (key_len == 1 && *key == 'y') { - p = parse_json_number(p, &y); - } else if (key_len == 5 && strncmp(key, "label", 5) == 0) { - int val_len = 0; - const char* val = parse_json_string(p, &val_len); - if (val) { - if (val_len >= (int)sizeof(label)) val_len = (int)sizeof(label) - 1; - strncpy(label, val, val_len); - label[val_len] = '\0'; - p = val + val_len + 1; - } - } else if (key_len == 6 && strncmp(key, "inputs", 6) == 0) { - p = skip_ws(p); - if (*p == '[') { - p++; - input_count = 0; - while (1) { - p = skip_ws(p); - if (*p == ']') { p++; break; } - if (*p != '{') break; - p++; - - char iv_type[16] = {0}; - float fv = 0; - int bv = 0; - char sval_str[256] = {0}; - while (1) { - p = skip_ws(p); - if (*p == '}') { p++; break; } - int ik_len = 0; - const char* ik = parse_json_string(p, &ik_len); - if (!ik) break; - p = ik + ik_len + 1; - p = skip_ws(p); - if (*p != ':') break; - p++; - - if (ik_len == 4 && strncmp(ik, "type", 4) == 0) { - int iv_len = 0; - const char* iv = parse_json_string(p, &iv_len); - if (iv) { - if (iv_len >= (int)sizeof(iv_type)) iv_len = (int)sizeof(iv_type) - 1; - strncpy(iv_type, iv, iv_len); - iv_type[iv_len] = '\0'; - p = iv + iv_len + 1; - } - } else if (ik_len == 5 && strncmp(ik, "value", 5) == 0) { - p = skip_ws(p); - if (*p == '"') { - int sv_len = 0; - const char* sval = parse_json_string(p, &sv_len); - if (sval) { - if (sv_len >= (int)sizeof(sval_str)) sv_len = (int)sizeof(sval_str) - 1; - strncpy(sval_str, sval, sv_len); - sval_str[sv_len] = '\0'; - p = sval + sv_len + 1; - } - } else if (strncmp(p, "true", 4) == 0) { - bv = 1; p += 4; - } else if (strncmp(p, "false", 5) == 0) { - bv = 0; p += 5; - } else { - p = parse_json_number(p, &fv); - } - } else { - while (*p && *p != ',' && *p != '}') p++; - } - p = skip_ws(p); - if (*p == ',') p++; - } - // 暂存输入值 - if (input_count < MAX_BLOCK_INPUTS) { - SlotValue* sv = &input_values[input_count++]; - memset(sv, 0, sizeof(SlotValue)); - if (strcmp(iv_type, "number") == 0) { - sv->type = SLOT_VALUE_NUMBER; - sv->as.number = (double)fv; - } else if (strcmp(iv_type, "string") == 0) { - sv->type = SLOT_VALUE_STRING; - strncpy(sv->as.string, sval_str, sizeof(sv->as.string) - 1); - } else if (strcmp(iv_type, "boolean") == 0) { - sv->type = SLOT_VALUE_BOOLEAN; - sv->as.boolean = bv; - } else { - sv->type = SLOT_VALUE_NUMBER; - sv->as.number = 0; - } - } - p = skip_ws(p); - if (*p == ',') p++; - } - } - } else { - // 跳过未知值 (简单跳过直到逗号或右花括号) - while (*p && *p != ',' && *p != '}') p++; - } - - p = skip_ws(p); - if (*p == ',') p++; - } - - BlockType type = block_type_find_by_name(type_name); - if (type == BLOCK_TYPE_COUNT || type_name[0] == '\0') { - type = BLOCK_EVENT_START; // fallback - } - - Block* block = block_create(type, x, y); - if (block) { - block->id = id; - strncpy(block->label, label, sizeof(block->label) - 1); - block->label[sizeof(block->label) - 1] = '\0'; - for (int j = 0; j < input_count && j < block->input_count; j++) { - block->inputs[j].value = input_values[j]; - } - workspace_add_block(ws, block); - if (id >= ws->next_block_id) ws->next_block_id = id + 1; - } - - p = skip_ws(p); - if (*p == ',') p++; - } - - // 解析 connections 数组 - const char* conn_key = strstr(json_str, "\"connections\""); - if (conn_key) { - p = conn_key + 13; - p = skip_ws(p); - if (*p == ':') { - p++; - p = skip_ws(p); - if (*p == '[') { - p++; - while (1) { - p = skip_ws(p); - if (*p == ']') { p++; break; } - if (*p != '{') break; - p++; - - int from_id = -1, to_id = -1; - while (1) { - p = skip_ws(p); - if (*p == '}') { p++; break; } - - int key_len = 0; - const char* key = parse_json_string(p, &key_len); - if (!key) break; - p = key + key_len + 1; - p = skip_ws(p); - if (*p != ':') break; - p++; - - float fv = 0; - if (key_len == 4 && strncmp(key, "from", 4) == 0) { - p = parse_json_number(p, &fv); from_id = (int)fv; - } else if (key_len == 2 && strncmp(key, "to", 2) == 0) { - p = parse_json_number(p, &fv); to_id = (int)fv; - } else { - while (*p && *p != ',' && *p != '}') p++; - } - - p = skip_ws(p); - if (*p == ',') p++; - } - - if (from_id >= 0 && to_id >= 0) { - Block* from_block = workspace_find_block(ws, from_id); - Block* to_block = workspace_find_block(ws, to_id); - if (from_block && to_block && from_block->output_count > 0 && to_block->input_count > 0) { - workspace_add_connection(ws, &from_block->outputs[0], &to_block->inputs[0]); - } - } - - p = skip_ws(p); - if (*p == ',') p++; - } - } - } - } - - return 1; -} diff --git a/Engine/Engine/VisualScript/block_serializer.h b/Engine/Engine/VisualScript/block_serializer.h deleted file mode 100644 index 0914ca8..0000000 --- a/Engine/Engine/VisualScript/block_serializer.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -// ============================================================================ -// block_serializer.h - JSON 序列化 -// ============================================================================ - -#include "block_workspace.h" - -// 保存工作区到文件 -int serializer_save(BlockWorkspace* ws, const char* filepath); - -// 从文件加载工作区 -int serializer_load(BlockWorkspace* ws, const char* filepath); - -// 保存到字符串 -char* serializer_save_to_string(BlockWorkspace* ws); - -// 从字符串加载 -int serializer_load_from_string(BlockWorkspace* ws, const char* json_str); diff --git a/Engine/Engine/VisualScript/block_types.c b/Engine/Engine/VisualScript/block_types.c deleted file mode 100644 index 9ebaff2..0000000 --- a/Engine/Engine/VisualScript/block_types.c +++ /dev/null @@ -1,326 +0,0 @@ -// ============================================================================ -// block_types.c - 积木类型注册 -// ============================================================================ - -#include "block_types.h" -#include - -static BlockTypeInfo g_type_info[BLOCK_TYPE_COUNT]; -static int g_types_initialized = 0; - -void block_types_init(void) { - if (g_types_initialized) return; - - int i = 0; - - // === 事件积木 (红色) === - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_EVENT_START, "event_start", "on_start", "Events", - BLOCK_COLOR_EVENT, 0, 1, - {}, {SLOT_STATEMENT}, - {}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_EVENT_UPDATE, "event_update", "on_update", "Events", - BLOCK_COLOR_EVENT, 0, 1, - {}, {SLOT_STATEMENT}, - {}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_EVENT_COLLISION, "event_collision", "on_collision", "Events", - BLOCK_COLOR_EVENT, 1, 1, - {SLOT_VALUE_STRING}, {SLOT_STATEMENT}, - {"碰撞对象"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_EVENT_KEY_PRESSED, "event_key", "on_key_pressed", "Events", - BLOCK_COLOR_EVENT, 1, 1, - {SLOT_VALUE_STRING}, {SLOT_STATEMENT}, - {"按键"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_EVENT_MOUSE_CLICK, "event_mouse", "on_mouse_click", "Events", - BLOCK_COLOR_EVENT, 0, 1, - {}, {SLOT_STATEMENT}, - {}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_EVENT_TIMER, "event_timer", "on_timer", "Events", - BLOCK_COLOR_EVENT, 1, 1, - {SLOT_VALUE_NUMBER}, {SLOT_STATEMENT}, - {"间隔(秒)"}, {"执行"} - }; - - // === 动作积木 (蓝色) === - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_MOVE, "action_move", "move", "Actions", - BLOCK_COLOR_ACTION, 4, 1, - {SLOT_STATEMENT, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_STATEMENT}, - {"执行", "X", "Y", "Z"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_ROTATE, "action_rotate", "rotate", "Actions", - BLOCK_COLOR_ACTION, 4, 1, - {SLOT_STATEMENT, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_STATEMENT}, - {"执行", "X", "Y", "Z"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_SCALE, "action_scale", "scale", "Actions", - BLOCK_COLOR_ACTION, 4, 1, - {SLOT_STATEMENT, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_STATEMENT}, - {"执行", "X", "Y", "Z"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_SET_POSITION, "action_setpos", "set_position", "Actions", - BLOCK_COLOR_ACTION, 4, 1, - {SLOT_STATEMENT, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_STATEMENT}, - {"执行", "X", "Y", "Z"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_SET_ROTATION, "action_setrot", "set_rotation", "Actions", - BLOCK_COLOR_ACTION, 4, 1, - {SLOT_STATEMENT, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_STATEMENT}, - {"执行", "X", "Y", "Z"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_PLAY_SOUND, "action_sound", "play_sound", "Actions", - BLOCK_COLOR_ACTION, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_STRING}, - {SLOT_STATEMENT}, - {"执行", "音效名"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_DESTROY, "action_destroy", "destroy", "Actions", - BLOCK_COLOR_ACTION, 1, 1, - {SLOT_STATEMENT}, - {SLOT_STATEMENT}, - {"执行"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_INSTANTIATE, "action_instantiate", "instantiate", "Actions", - BLOCK_COLOR_ACTION, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_STRING}, - {SLOT_STATEMENT}, - {"执行", "预制体"}, {"执行"} - }; - - // === 控制积木 (绿色) === - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_CONTROL_IF, "control_if", "if", "Control", - BLOCK_COLOR_CONTROL, 2, 2, - {SLOT_STATEMENT, SLOT_VALUE_BOOLEAN}, - {SLOT_STATEMENT, SLOT_STATEMENT}, - {"执行", "条件"}, {"Then", "Else"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_CONTROL_IF_ELSE, "control_ifelse", "if_else", "Control", - BLOCK_COLOR_CONTROL, 2, 2, - {SLOT_STATEMENT, SLOT_VALUE_BOOLEAN}, - {SLOT_STATEMENT, SLOT_STATEMENT}, - {"执行", "条件"}, {"Then", "Else"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_CONTROL_REPEAT, "control_repeat", "repeat", "Control", - BLOCK_COLOR_CONTROL, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_BOOLEAN}, - {SLOT_STATEMENT}, - {"执行", "条件"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_CONTROL_REPEAT_TIMES, "control_count", "repeat_times", "Control", - BLOCK_COLOR_CONTROL, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_NUMBER}, - {SLOT_STATEMENT}, - {"执行", "次数"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_CONTROL_WHILE, "control_while", "while", "Control", - BLOCK_COLOR_CONTROL, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_BOOLEAN}, - {SLOT_STATEMENT}, - {"执行", "条件"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_CONTROL_WAIT, "control_wait", "wait", "Control", - BLOCK_COLOR_CONTROL, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_NUMBER}, - {SLOT_STATEMENT}, - {"执行", "秒数"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_CONTROL_FUNCTION_DEF, "control_funcdef", "function_def", "Control", - BLOCK_COLOR_CONTROL, 1, 1, - {SLOT_STATEMENT}, - {SLOT_STATEMENT}, - {"执行"}, {"执行"} - }; - - // === 运算积木 (橙色) === - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_ADD, "op_add", "+", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_VALUE_NUMBER}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_SUB, "op_sub", "-", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_VALUE_NUMBER}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_MUL, "op_mul", "*", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_VALUE_NUMBER}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_DIV, "op_div", "/", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_VALUE_NUMBER}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_MOD, "op_mod", "%", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_VALUE_NUMBER}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_EQUALS, "op_eq", "==", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_ANY, SLOT_VALUE_ANY}, - {SLOT_VALUE_BOOLEAN}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_NOT_EQUALS, "op_neq", "!=", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_ANY, SLOT_VALUE_ANY}, - {SLOT_VALUE_BOOLEAN}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_GREATER, "op_gt", ">", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_VALUE_BOOLEAN}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_LESS, "op_lt", "<", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_VALUE_BOOLEAN}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_AND, "op_and", "AND", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_BOOLEAN, SLOT_VALUE_BOOLEAN}, - {SLOT_VALUE_BOOLEAN}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_OR, "op_or", "OR", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_BOOLEAN, SLOT_VALUE_BOOLEAN}, - {SLOT_VALUE_BOOLEAN}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_NOT, "op_not", "NOT", "Operators", - BLOCK_COLOR_OPERATOR, 1, 1, - {SLOT_VALUE_BOOLEAN}, - {SLOT_VALUE_BOOLEAN}, - {"A"}, {"结果"} - }; - - // === 变量积木 (紫色) === - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_VAR_GET, "var_get", "get_variable", "Variables", - BLOCK_COLOR_VARIABLE, 0, 1, - {}, {SLOT_VALUE_ANY}, - {}, {"值"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_VAR_SET, "var_set", "set_variable", "Variables", - BLOCK_COLOR_VARIABLE, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_ANY}, - {SLOT_STATEMENT}, - {"执行", "值"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_VAR_CREATE, "var_create", "create_variable", "Variables", - BLOCK_COLOR_VARIABLE, 1, 1, - {SLOT_STATEMENT}, - {SLOT_STATEMENT}, - {"执行"}, {"执行"} - }; - - // === 函数积木 (黄色) === - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_FUNC_CALL, "func_call", "call_function", "Functions", - BLOCK_COLOR_FUNCTION, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_STRING}, - {SLOT_STATEMENT}, - {"执行", "函数名"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_FUNC_RETURN, "func_return", "return", "Functions", - BLOCK_COLOR_FUNCTION, 2, 0, - {SLOT_STATEMENT, SLOT_VALUE_ANY}, - {}, - {"执行", "返回值"} - }; - - g_types_initialized = 1; -} - -const BlockTypeInfo* block_type_get_info(BlockType type) { - if (type < 0 || type >= BLOCK_TYPE_COUNT) return NULL; - return &g_type_info[type]; -} - -const BlockTypeInfo* block_type_get_all(int* count) { - *count = BLOCK_TYPE_COUNT; - return g_type_info; -} - -BlockType block_type_find_by_name(const char* name) { - for (int i = 0; i < BLOCK_TYPE_COUNT; i++) { - if (strcmp(g_type_info[i].name, name) == 0) { - return g_type_info[i].type; - } - } - return -1; -} - -const char** block_type_get_categories(int* count) { - static const char* categories[] = { - "Events", "Actions", "Control", "Operators", "Variables", "Functions" - }; - *count = 6; - return categories; -} - -const BlockType* block_type_get_by_category(const char* category, int* count) { - static BlockType buffer[BLOCK_TYPE_COUNT]; - *count = 0; - for (int i = 0; i < BLOCK_TYPE_COUNT; i++) { - if (strcmp(g_type_info[i].category, category) == 0) { - buffer[(*count)++] = g_type_info[i].type; - } - } - return buffer; -} diff --git a/Engine/Engine/VisualScript/block_types.h b/Engine/Engine/VisualScript/block_types.h deleted file mode 100644 index 2577576..0000000 --- a/Engine/Engine/VisualScript/block_types.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -// ============================================================================ -// block_types.h - 积木类型定义 -// ============================================================================ - -#include "block_core.h" - -// 获取积木类型信息 -const BlockTypeInfo* block_type_get_info(BlockType type); - -// 获取所有类型信息 -const BlockTypeInfo* block_type_get_all(int* count); - -// 按名称查找类型 -BlockType block_type_find_by_name(const char* name); - -// 按分类获取类型列表 -const BlockType* block_type_get_by_category(const char* category, int* count); - -// 获取所有分类 -const char** block_type_get_categories(int* count); - -// 初始化所有积木类型 -void block_types_init(void); diff --git a/Engine/Engine/VisualScript/block_workspace.c b/Engine/Engine/VisualScript/block_workspace.c deleted file mode 100644 index 84939bd..0000000 --- a/Engine/Engine/VisualScript/block_workspace.c +++ /dev/null @@ -1,171 +0,0 @@ -// ============================================================================ -// block_workspace.c - 工作区管理实现 -// ============================================================================ - -#include "block_workspace.h" -#include -#include -#include - -BlockWorkspace* workspace_create(void) { - BlockWorkspace* ws = (BlockWorkspace*)calloc(1, sizeof(BlockWorkspace)); - if (!ws) return NULL; - - ws->zoom = 1.0f; - ws->next_block_id = 1; - - return ws; -} - -void workspace_destroy(BlockWorkspace* ws) { - if (!ws) return; - workspace_clear(ws); - free(ws); -} - -int workspace_add_block(BlockWorkspace* ws, Block* block) { - if (ws->block_count >= MAX_WORKSPACE_BLOCKS) return -1; - if (!block) return -1; - if (block->id <= 0) block->id = ws->next_block_id++; - else if (block->id >= ws->next_block_id) ws->next_block_id = block->id + 1; - block->workspace = ws; - ws->blocks[ws->block_count++] = block; - return block->id; -} - -void workspace_remove_block(BlockWorkspace* ws, int block_id) { - // 先移除所有相关连接 - for (int i = ws->connection_count - 1; i >= 0; i--) { - BlockSlot* from = ws->connections[i].from; - BlockSlot* to = ws->connections[i].to; - if (from && from->owner && from->owner->id == block_id) { - workspace_remove_connection(ws, from); - } else if (to && to->owner && to->owner->id == block_id) { - workspace_remove_connection(ws, to); - } - } - - // 移除积木 - for (int i = 0; i < ws->block_count; i++) { - if (ws->blocks[i]->id == block_id) { - block_destroy(ws->blocks[i]); - ws->blocks[i] = ws->blocks[ws->block_count - 1]; - ws->block_count--; - return; - } - } -} - -bool workspace_add_connection(BlockWorkspace* ws, BlockSlot* from, BlockSlot* to) { - if (ws->connection_count >= MAX_WORKSPACE_CONNECTIONS) return false; - if (!from || !to) return false; - - // 检查是否已连接 - for (int i = 0; i < ws->connection_count; i++) { - if (ws->connections[i].from == from || ws->connections[i].to == to) { - return false; // 已有连接 - } - } - - // 建立连接 - block_connect(from, to); - - BlockConnection* conn = &ws->connections[ws->connection_count++]; - conn->from = from; - conn->to = to; - - return true; -} - -void workspace_remove_connection(BlockWorkspace* ws, BlockSlot* slot) { - for (int i = ws->connection_count - 1; i >= 0; i--) { - if (ws->connections[i].from == slot || ws->connections[i].to == slot) { - block_disconnect(ws->connections[i].from); - ws->connections[i] = ws->connections[ws->connection_count - 1]; - ws->connection_count--; - } - } -} - -void workspace_remove_all_connections(BlockWorkspace* ws, Block* block) { - if (!block) return; - - for (int i = ws->connection_count - 1; i >= 0; i--) { - BlockSlot* from = ws->connections[i].from; - BlockSlot* to = ws->connections[i].to; - if ((from && from->owner == block) || (to && to->owner == block)) { - block_disconnect(from); - ws->connections[i] = ws->connections[ws->connection_count - 1]; - ws->connection_count--; - } - } -} - -Block* workspace_find_block(BlockWorkspace* ws, int block_id) { - for (int i = 0; i < ws->block_count; i++) { - if (ws->blocks[i]->id == block_id) return ws->blocks[i]; - } - return NULL; -} - -Block* workspace_find_block_at(BlockWorkspace* ws, float x, float y) { - // 从后往前找 (最后添加的在最上面) - for (int i = ws->block_count - 1; i >= 0; i--) { - if (block_contains_point(ws->blocks[i], x, y)) { - return ws->blocks[i]; - } - } - return NULL; -} - -BlockSlot* workspace_find_slot_at(BlockWorkspace* ws, float x, float y) { - float threshold = 10.0f; - - for (int i = ws->block_count - 1; i >= 0; i--) { - Block* block = ws->blocks[i]; - - // 检查输出槽位 - for (int j = 0; j < block->output_count; j++) { - BlockSlot* slot = &block->outputs[j]; - float sx, sy; - block_slot_world_pos(slot, &sx, &sy); - float dx = x - sx; - float dy = y - sy; - if (dx * dx + dy * dy < threshold * threshold) { - return slot; - } - } - - // 检查输入槽位 - for (int j = 0; j < block->input_count; j++) { - BlockSlot* slot = &block->inputs[j]; - float sx, sy; - block_slot_world_pos(slot, &sx, &sy); - float dx = x - sx; - float dy = y - sy; - if (dx * dx + dy * dy < threshold * threshold) { - return slot; - } - } - } - return NULL; -} - -void workspace_screen_to_world(BlockWorkspace* ws, float sx, float sy, float* wx, float* wy) { - *wx = (sx / ws->zoom) + ws->view_x; - *wy = (sy / ws->zoom) + ws->view_y; -} - -void workspace_world_to_screen(BlockWorkspace* ws, float wx, float wy, float* sx, float* sy) { - *sx = (wx - ws->view_x) * ws->zoom; - *sy = (wy - ws->view_y) * ws->zoom; -} - -void workspace_clear(BlockWorkspace* ws) { - for (int i = 0; i < ws->block_count; i++) { - block_destroy(ws->blocks[i]); - } - ws->block_count = 0; - ws->connection_count = 0; - ws->selected_block = NULL; -} diff --git a/Engine/Engine/VisualScript/block_workspace.h b/Engine/Engine/VisualScript/block_workspace.h deleted file mode 100644 index e5ba5c6..0000000 --- a/Engine/Engine/VisualScript/block_workspace.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -// ============================================================================ -// block_workspace.h - 工作区管理 -// ============================================================================ - -#include "block_core.h" - -#define MAX_WORKSPACE_BLOCKS 1024 -#define MAX_WORKSPACE_CONNECTIONS 2048 - -typedef struct BlockWorkspace { - Block* blocks[MAX_WORKSPACE_BLOCKS]; - int block_count; - - BlockConnection connections[MAX_WORKSPACE_CONNECTIONS]; - int connection_count; - - float view_x, view_y; - float zoom; - - Block* selected_block; - BlockSlot* dragging_from; - float drag_start_x, drag_start_y; - - int next_block_id; - - struct BlockPalette* palette; -} BlockWorkspace; - -// 创建/销毁 -BlockWorkspace* workspace_create(void); -void workspace_destroy(BlockWorkspace* ws); - -// 添加/移除积木 -int workspace_add_block(BlockWorkspace* ws, Block* block); -void workspace_remove_block(BlockWorkspace* ws, int block_id); - -// 添加/移除连接 -bool workspace_add_connection(BlockWorkspace* ws, BlockSlot* from, BlockSlot* to); -void workspace_remove_connection(BlockWorkspace* ws, BlockSlot* from); -void workspace_remove_all_connections(BlockWorkspace* ws, Block* block); - -// 查找 -Block* workspace_find_block(BlockWorkspace* ws, int block_id); -Block* workspace_find_block_at(BlockWorkspace* ws, float x, float y); -BlockSlot* workspace_find_slot_at(BlockWorkspace* ws, float x, float y); - -// 视口变换 -void workspace_screen_to_world(BlockWorkspace* ws, float sx, float sy, float* wx, float* wy); -void workspace_world_to_screen(BlockWorkspace* ws, float wx, float wy, float* sx, float* sy); - -// 清空 -void workspace_clear(BlockWorkspace* ws); diff --git a/Engine/Engine/Window/window.c b/Engine/Engine/Window/window.c deleted file mode 100644 index 4cdfc94..0000000 --- a/Engine/Engine/Window/window.c +++ /dev/null @@ -1,198 +0,0 @@ -// ============================================================================ -// window.c - Win32 窗口实现 -// ============================================================================ - -#include "window.h" -#include "../Core/logger.h" -#include -#include - -// 窗口类名 -static const wchar_t* WINDOW_CLASS = L"Lity3DEngineWindow"; - -// 全局回调 -static WindowKeyCallback g_key_callback = NULL; -static WindowResizeCallback g_resize_callback = NULL; -static WindowMouseMoveCallback g_mouse_move_callback = NULL; -static WindowMouseButtonCallback g_mouse_button_callback = NULL; - -// 窗口过程 -static LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - Window* window = NULL; - - if (msg == WM_NCCREATE) { - CREATESTRUCT* cs = (CREATESTRUCT*)lParam; - window = (Window*)cs->lpCreateParams; - SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR)window); - } else { - window = (Window*)GetWindowLongPtrW(hwnd, GWLP_USERDATA); - } - - if (window) { - switch (msg) { - case WM_SIZE: - window->width = LOWORD(lParam); - window->height = HIWORD(lParam); - window->minimized = (wParam == SIZE_MINIMIZED); - if (g_resize_callback && !window->minimized) { - g_resize_callback(window->width, window->height); - } - return 0; - - case WM_PAINT: - ValidateRect(hwnd, NULL); - return 0; - - case WM_ERASEBKGND: - return 1; - - case WM_KEYDOWN: - if (g_key_callback) g_key_callback((int)wParam); - return 0; - - case WM_KEYUP: - return 0; - - case WM_MOUSEMOVE: - if (g_mouse_move_callback) g_mouse_move_callback(LOWORD(lParam), HIWORD(lParam)); - return 0; - - case WM_LBUTTONDOWN: - SetCapture(hwnd); - if (g_mouse_button_callback) g_mouse_button_callback(0, 1); - return 0; - case WM_RBUTTONDOWN: - SetCapture(hwnd); - if (g_mouse_button_callback) g_mouse_button_callback(1, 1); - return 0; - case WM_MBUTTONDOWN: - SetCapture(hwnd); - if (g_mouse_button_callback) g_mouse_button_callback(2, 1); - return 0; - - case WM_LBUTTONUP: - if (GetCapture() == hwnd) ReleaseCapture(); - if (g_mouse_button_callback) g_mouse_button_callback(0, 0); - return 0; - case WM_RBUTTONUP: - if (GetCapture() == hwnd) ReleaseCapture(); - if (g_mouse_button_callback) g_mouse_button_callback(1, 0); - return 0; - case WM_MBUTTONUP: - if (GetCapture() == hwnd) ReleaseCapture(); - if (g_mouse_button_callback) g_mouse_button_callback(2, 0); - return 0; - - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - } - - return DefWindowProcW(hwnd, msg, wParam, lParam); -} - -// 注册窗口类 -static void register_window_class(void) { - WNDCLASSEXW wc = {0}; - wc.cbSize = sizeof(WNDCLASSEXW); - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = window_proc; - wc.hInstance = GetModuleHandleW(NULL); - wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = NULL; - wc.lpszClassName = WINDOW_CLASS; - wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); - - if (!RegisterClassExW(&wc)) { - LOG_ERROR("Failed to register window class!"); - } -} - -Window* window_create(const char* title, int width, int height, int fullscreen) { - Window* window = (Window*)calloc(1, sizeof(Window)); - if (!window) return NULL; - - window->title = title; - window->width = width; - window->height = height; - window->fullscreen = fullscreen; - - register_window_class(); - - DWORD style = WS_OVERLAPPEDWINDOW; - DWORD ex_style = WS_EX_APPWINDOW; - - RECT rect = {0, 0, width, height}; - AdjustWindowRectEx(&rect, style, FALSE, ex_style); - - int adjusted_width = rect.right - rect.left; - int adjusted_height = rect.bottom - rect.top; - - int screen_w = GetSystemMetrics(SM_CXSCREEN); - int screen_h = GetSystemMetrics(SM_CYSCREEN); - int pos_x = (screen_w - adjusted_width) / 2; - int pos_y = (screen_h - adjusted_height) / 2; - - // 转换标题为宽字符 - wchar_t w_title[256]; - MultiByteToWideChar(CP_UTF8, 0, title, -1, w_title, 256); - - window->hwnd = CreateWindowExW( - ex_style, WINDOW_CLASS, w_title, style, - pos_x, pos_y, adjusted_width, adjusted_height, - NULL, NULL, GetModuleHandleW(NULL), window - ); - - if (!window->hwnd) { - LOG_ERROR("Failed to create window! Error: %lu", GetLastError()); - free(window); - return NULL; - } - - ShowWindow(window->hwnd, SW_SHOW); - UpdateWindow(window->hwnd); - - LOG_INFO("Window created: %dx%d", width, height); - return window; -} - -void window_destroy(Window* window) { - if (window) { - if (window->hwnd) { - DestroyWindow(window->hwnd); - window->hwnd = NULL; - } - free(window); - } -} - -void window_show(Window* window) { - if (window && window->hwnd) ShowWindow(window->hwnd, SW_SHOW); -} - -void window_hide(Window* window) { - if (window && window->hwnd) ShowWindow(window->hwnd, SW_HIDE); -} - -int window_process_messages(Window* window) { - MSG msg = {0}; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - if (msg.message == WM_QUIT) return 0; - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return 1; -} - -int window_get_width(Window* window) { return window ? window->width : 0; } -int window_get_height(Window* window) { return window ? window->height : 0; } -HWND window_get_handle(Window* window) { return window ? window->hwnd : NULL; } -int window_is_fullscreen(Window* window) { return window ? window->fullscreen : 0; } -int window_is_minimized(Window* window) { return window ? window->minimized : 0; } - -void window_set_key_callback(Window* window, WindowKeyCallback callback) { g_key_callback = callback; } -void window_set_resize_callback(Window* window, WindowResizeCallback callback) { g_resize_callback = callback; } -void window_set_mouse_move_callback(Window* window, WindowMouseMoveCallback callback) { g_mouse_move_callback = callback; } -void window_set_mouse_button_callback(Window* window, WindowMouseButtonCallback callback) { g_mouse_button_callback = callback; } diff --git a/Engine/Engine/Window/window.h b/Engine/Engine/Window/window.h deleted file mode 100644 index 2a3c447..0000000 --- a/Engine/Engine/Window/window.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -// ============================================================================ -// window.h - Win32 窗口管理 -// ============================================================================ - -#include - -// 窗口结构 -typedef struct Window { - HWND hwnd; - int width; - int height; - int fullscreen; - int minimized; - const char* title; -} Window; - -// 回调类型 -typedef void (*WindowKeyCallback)(int key); -typedef void (*WindowResizeCallback)(int width, int height); -typedef void (*WindowMouseMoveCallback)(int x, int y); -typedef void (*WindowMouseButtonCallback)(int button, int pressed); - -// 创建/销毁 -Window* window_create(const char* title, int width, int height, int fullscreen); -void window_destroy(Window* window); - -// 显示/隐藏 -void window_show(Window* window); -void window_hide(Window* window); - -// 消息处理 -int window_process_messages(Window* window); - -// 获取属性 -int window_get_width(Window* window); -int window_get_height(Window* window); -HWND window_get_handle(Window* window); -int window_is_fullscreen(Window* window); -int window_is_minimized(Window* window); - -// 设置回调 -void window_set_key_callback(Window* window, WindowKeyCallback callback); -void window_set_resize_callback(Window* window, WindowResizeCallback callback); -void window_set_mouse_move_callback(Window* window, WindowMouseMoveCallback callback); -void window_set_mouse_button_callback(Window* window, WindowMouseButtonCallback callback); diff --git a/Engine/Engine/include/engine_api.h b/Engine/Engine/include/engine_api.h deleted file mode 100644 index cf51193..0000000 --- a/Engine/Engine/include/engine_api.h +++ /dev/null @@ -1,145 +0,0 @@ -#pragma once - -// ============================================================================ -// engine_api.h - C-ASM 接口头文件 -// 暴露所有汇编函数给 C 代码使用 -// ============================================================================ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// 当 MASM 不可用时,使用 C fallback -// math_c_fallback.h 已经定义了所有数学类型和函数 -// 不需要重复声明 - -// ============================================================================ -// memory.asm - 对齐内存分配 -// ============================================================================ - -#if !defined(MATH_ASM_AVAILABLE) || MATH_ASM_AVAILABLE == 0 -// 在 C fallback 模式下,这些函数已在 math_c_fallback.h 中定义 -// 不需要重复声明 -#else -void* mem_aligned_alloc(uint64_t size, uint64_t alignment); -void mem_aligned_free(void* ptr); -void* mem_aligned_realloc(void* ptr, uint64_t size, uint64_t alignment); - -// ============================================================================ -// string_ops.asm - 快速字符串操作 -// ============================================================================ - -void fast_memcpy(void* dst, const void* src, uint64_t count); -void fast_memset(void* dst, int value, uint64_t count); -uint64_t fast_strlen(const char* str); -int fast_strcmp(const char* a, const char* b); - -// ============================================================================ -// profiling.asm - 性能分析 -// ============================================================================ - -uint64_t prof_rdtsc(void); -double prof_cycles_to_ms(uint64_t cycles); -uint64_t prof_get_freq(void); - -// 性能计时器结构 -typedef struct { - uint64_t start; - uint64_t end; - double elapsed_ms; -} ProfTimer; - -void prof_timer_start(ProfTimer* timer); -void prof_timer_stop(ProfTimer* timer); -#endif - -#ifdef __cplusplus -} -#endif - -// ============================================================================ -// C++ 便利封装 -// ============================================================================ - -#ifdef __cplusplus - -// Vec3 运算符重载 -inline Vec3 operator+(const Vec3& a, const Vec3& b) { - Vec3 result; - vec3_add(&a, &b, &result); - return result; -} - -inline Vec3 operator-(const Vec3& a, const Vec3& b) { - Vec3 result; - vec3_sub(&a, &b, &result); - return result; -} - -inline Vec3 operator*(const Vec3& a, float s) { - Vec3 result; - vec3_scale(&a, s, &result); - return result; -} - -inline float dot(const Vec3& a, const Vec3& b) { - return vec3_dot(&a, &b); -} - -inline Vec3 cross(const Vec3& a, const Vec3& b) { - Vec3 result; - vec3_cross(&a, &b, &result); - return result; -} - -inline float length(const Vec3& a) { - return vec3_length(&a); -} - -inline Vec3 normalize(const Vec3& a) { - Vec3 result; - vec3_normalize(&a, &result); - return result; -} - -inline Vec3 lerp(const Vec3& a, const Vec3& b, float t) { - Vec3 result; - vec3_lerp(&a, &b, t, &result); - return result; -} - -// Mat4 运算符重载 -inline Mat4 operator*(const Mat4& a, const Mat4& b) { - Mat4 result; - mat4_multiply(&a, &b, &result); - return result; -} - -inline Vec3 transformPoint(const Mat4& m, const Vec3& v) { - Vec3 result; - // 使用 vec4 乘法, w=1 - Vec4 v4 = {v.x, v.y, v.z, 1.0f}; - Vec4 r4; - // 简化: 逐行计算 - result.x = m.m[0][0]*v.x + m.m[0][1]*v.y + m.m[0][2]*v.z + m.m[0][3]; - result.y = m.m[1][0]*v.x + m.m[1][1]*v.y + m.m[1][2]*v.z + m.m[1][3]; - result.z = m.m[2][0]*v.x + m.m[2][1]*v.y + m.m[2][2]*v.z + m.m[2][3]; - return result; -} - -// Quat 运算符重载 -inline Quat operator*(const Quat& a, const Quat& b) { - Quat result; - quat_multiply(&a, &b, &result); - return result; -} - -inline Vec3 rotate(const Quat& q, const Vec3& v) { - Vec3 result; - quat_rotate_vec3(&q, &v, &result); - return result; -} - -#endif // __cplusplus diff --git a/Engine/Input/input.c b/Engine/Input/input.c deleted file mode 100644 index 215d0f3..0000000 --- a/Engine/Input/input.c +++ /dev/null @@ -1,138 +0,0 @@ -#include "input.h" - -#include -#include -#include - -static float normalize_trigger(BYTE value) { - return value / 255.0f; -} - -static float normalize_axis(SHORT value) { - if (value > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { - return (value - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) / (32767.0f - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE); - } else if (value < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { - return (value + XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) / (32767.0f - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE); - } - return 0.0f; -} - -Input* input_create(void) { - Input* input = (Input*)calloc(1, sizeof(Input)); - input->deadzone = 0.2f; - return input; -} - -void input_destroy(Input* input) { - free(input); -} - -void input_update(Input* input) { - memcpy(input->key_prev, input->key_states, sizeof(int) * MAX_KEYS); - memcpy(input->mouse_prev, input->mouse_buttons, sizeof(int) * 3); - - input->mouse_dx = 0; - input->mouse_dy = 0; - input->mouse_scroll = 0; - - memcpy(&input->gamepad_prev, &input->gamepad_state, sizeof(XINPUT_STATE)); - input->gamepad_connected = (XInputGetState(0, &input->gamepad_state) == ERROR_SUCCESS); -} - -void input_process_key(Input* input, int key, int down) { - if (key >= 0 && key < MAX_KEYS) { - input->key_states[key] = down; - } -} - -void input_process_mouse_move(Input* input, int x, int y) { - input->mouse_dx = x - input->mouse_x; - input->mouse_dy = y - input->mouse_y; - input->mouse_x = x; - input->mouse_y = y; -} - -void input_process_mouse_button(Input* input, int button, int down) { - if (button >= 0 && button < 3) { - input->mouse_buttons[button] = down; - } -} - -void input_process_mouse_wheel(Input* input, int delta) { - input->mouse_scroll += delta; -} - -int input_key_down(Input* input, int key) { - return (key >= 0 && key < MAX_KEYS) ? input->key_states[key] : 0; -} - -int input_key_pressed(Input* input, int key) { - return (key >= 0 && key < MAX_KEYS) ? (input->key_states[key] && !input->key_prev[key]) : 0; -} - -int input_key_released(Input* input, int key) { - return (key >= 0 && key < MAX_KEYS) ? (!input->key_states[key] && input->key_prev[key]) : 0; -} - -int input_mouse_button(Input* input, int button) { - return (button >= 0 && button < 3) ? input->mouse_buttons[button] : 0; -} - -int input_mouse_button_pressed(Input* input, int button) { - return (button >= 0 && button < 3) ? (input->mouse_buttons[button] && !input->mouse_prev[button]) : 0; -} - -void input_get_mouse_pos(Input* input, int* x, int* y) { - if (x) *x = input->mouse_x; - if (y) *y = input->mouse_y; -} - -void input_get_mouse_delta(Input* input, int* dx, int* dy) { - if (dx) *dx = input->mouse_dx; - if (dy) *dy = input->mouse_dy; -} - -int input_get_mouse_scroll(Input* input) { - return input->mouse_scroll; -} - -int input_gamepad_connected(Input* input) { - return input->gamepad_connected; -} - -float input_gamepad_axis_lx(Input* input) { - float v = normalize_axis(input->gamepad_state.Gamepad.sThumbLX); - return fabsf(v) < input->deadzone ? 0.0f : v; -} - -float input_gamepad_axis_ly(Input* input) { - float v = normalize_axis(input->gamepad_state.Gamepad.sThumbLY); - return fabsf(v) < input->deadzone ? 0.0f : v; -} - -float input_gamepad_axis_rx(Input* input) { - float v = normalize_axis(input->gamepad_state.Gamepad.sThumbRX); - return fabsf(v) < input->deadzone ? 0.0f : v; -} - -float input_gamepad_axis_ry(Input* input) { - float v = normalize_axis(input->gamepad_state.Gamepad.sThumbRY); - return fabsf(v) < input->deadzone ? 0.0f : v; -} - -float input_gamepad_trigger_l(Input* input) { - return normalize_trigger(input->gamepad_state.Gamepad.bLeftTrigger); -} - -float input_gamepad_trigger_r(Input* input) { - return normalize_trigger(input->gamepad_state.Gamepad.bRightTrigger); -} - -int input_gamepad_button(Input* input, uint16_t button) { - return (input->gamepad_state.Gamepad.wButtons & button) != 0; -} - -int input_gamepad_button_pressed(Input* input, uint16_t button) { - return (input->gamepad_state.Gamepad.wButtons & button) != 0 && - (input->gamepad_prev.Gamepad.wButtons & button) == 0; -} diff --git a/Engine/Input/input.h b/Engine/Input/input.h deleted file mode 100644 index 4e6c045..0000000 --- a/Engine/Input/input.h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once - -// ============================================================================ -// input.h - 输入管理 (键盘/鼠标/手柄) -// ============================================================================ - -#include -#include -#include - -#pragma comment(lib, "xinput.lib") - -// 键盘状态 -#define MAX_KEYS 256 - -// 鼠标按钮 -#define MOUSE_LEFT 0 -#define MOUSE_RIGHT 1 -#define MOUSE_MIDDLE 2 - -// 手柄按钮 -#define GAMEPAD_A XINPUT_GAMEPAD_A -#define GAMEPAD_B XINPUT_GAMEPAD_B -#define GAMEPAD_X XINPUT_GAMEPAD_X -#define GAMEPAD_Y XINPUT_GAMEPAD_Y -#define GAMEPAD_START XINPUT_GAMEPAD_START -#define GAMEPAD_BACK XINPUT_GAMEPAD_BACK -#define GAMEPAD_LB XINPUT_GAMEPAD_LEFT_SHOULDER -#define GAMEPAD_RB XINPUT_GAMEPAD_RIGHT_SHOULDER -#define GAMEPAD_LTHUMB XINPUT_GAMEPAD_LEFT_THUMB -#define GAMEPAD_RTHUMB XINPUT_GAMEPAD_RIGHT_THUMB -#define GAMEPAD_UP XINPUT_GAMEPAD_DPAD_UP -#define GAMEPAD_DOWN XINPUT_GAMEPAD_DPAD_DOWN -#define GAMEPAD_LEFT XINPUT_GAMEPAD_DPAD_LEFT -#define GAMEPAD_RIGHT XINPUT_GAMEPAD_DPAD_RIGHT - -typedef struct { - int key_states[MAX_KEYS]; - int key_prev[MAX_KEYS]; - - int mouse_x, mouse_y; - int mouse_dx, mouse_dy; - int mouse_scroll; - int mouse_buttons[3]; - int mouse_prev[3]; - - XINPUT_STATE gamepad_state; - XINPUT_STATE gamepad_prev; - int gamepad_connected; - - float deadzone; -} Input; - -// 创建/销毁 -Input* input_create(void); -void input_destroy(Input* input); - -// 更新 (每帧调用) -void input_update(Input* input); - -// Win32 消息处理 -void input_process_key(Input* input, int key, int down); -void input_process_mouse_move(Input* input, int x, int y); -void input_process_mouse_button(Input* input, int button, int down); -void input_process_mouse_wheel(Input* input, int delta); - -// 键盘查询 -int input_key_down(Input* input, int key); -int input_key_pressed(Input* input, int key); -int input_key_released(Input* input, int key); - -// 鼠标查询 -int input_mouse_button(Input* input, int button); -int input_mouse_button_pressed(Input* input, int button); -void input_get_mouse_pos(Input* input, int* x, int* y); -void input_get_mouse_delta(Input* input, int* dx, int* dy); -int input_get_mouse_scroll(Input* input); - -// 手柄查询 -int input_gamepad_connected(Input* input); -float input_gamepad_axis_lx(Input* input); -float input_gamepad_axis_ly(Input* input); -float input_gamepad_axis_rx(Input* input); -float input_gamepad_axis_ry(Input* input); -float input_gamepad_trigger_l(Input* input); -float input_gamepad_trigger_r(Input* input); -int input_gamepad_button(Input* input, uint16_t button); -int input_gamepad_button_pressed(Input* input, uint16_t button); diff --git a/Engine/Math/math_impl.c b/Engine/Math/math_impl.c deleted file mode 100644 index 35a2e85..0000000 --- a/Engine/Math/math_impl.c +++ /dev/null @@ -1,8 +0,0 @@ -// math_impl.c - 数学函数实现 (C fallback) -// 当 MASM 不可用时使用 - -#include "math_c_fallback.h" - -// 由于函数是 static inline,它们应该被内联 -// 但如果编译器没有内联,这些函数将提供实现 -// 这个文件确保链接器能找到符号 diff --git a/Engine/Physics/physics.c b/Engine/Physics/physics.c deleted file mode 100644 index deec9d5..0000000 --- a/Engine/Physics/physics.c +++ /dev/null @@ -1,373 +0,0 @@ -#include "physics.h" -#include "../include/engine_api.h" - -#include -#include -#include - -static void move_collider(Collider* c, Vec3 delta); - -PhysicsWorld* physics_create(void) { - PhysicsWorld* w = (PhysicsWorld*)calloc(1, sizeof(PhysicsWorld)); - w->gravity_enabled = 1; - w->gravity = (Vec3){0, -9.81f, 0}; - return w; -} - -void physics_destroy(PhysicsWorld* world) { - free(world); -} - -static void init_body(RigidBody* b) { - b->velocity = (Vec3){0, 0, 0}; - b->acceleration = (Vec3){0, 0, 0}; - b->mass = 1.0f; - b->restitution = 0.5f; - b->friction = 0.3f; - b->is_kinematic = 0; -} - -uint32_t physics_add_aabb(PhysicsWorld* world, uint32_t entity, Vec3 min, Vec3 max) { - uint32_t idx = world->collider_count++; - Collider* c = &world->colliders[idx]; - c->entity_id = entity; - c->type = COLLIDER_AABB; - c->aabb.min = min; - c->aabb.max = max; - c->is_trigger = 0; - c->is_static = 0; - init_body(&c->body); - return idx; -} - -uint32_t physics_add_sphere(PhysicsWorld* world, uint32_t entity, Vec3 center, float radius) { - uint32_t idx = world->collider_count++; - Collider* c = &world->colliders[idx]; - c->entity_id = entity; - c->type = COLLIDER_SPHERE; - c->sphere.center = center; - c->sphere.radius = radius; - c->is_trigger = 0; - c->is_static = 0; - init_body(&c->body); - return idx; -} - -uint32_t physics_add_plane(PhysicsWorld* world, uint32_t entity, Vec3 normal, float distance) { - uint32_t idx = world->collider_count++; - Collider* c = &world->colliders[idx]; - c->entity_id = entity; - c->type = COLLIDER_PLANE; - vec3_normalize(&normal, &c->plane.normal); - c->plane.distance = distance; - c->is_trigger = 0; - c->is_static = 1; - init_body(&c->body); - c->body.mass = 0.0f; - c->body.is_kinematic = 1; - return idx; -} - -void physics_remove_collider(PhysicsWorld* world, uint32_t index) { - if (index < world->collider_count) { - world->colliders[index] = world->colliders[--world->collider_count]; - } -} - -void physics_update_collider(PhysicsWorld* world, uint32_t index, Vec3 position) { - if (!world || index >= world->collider_count) return; - Collider* c = &world->colliders[index]; - if (c->type == COLLIDER_SPHERE) { - c->sphere.center = position; - } else if (c->type == COLLIDER_AABB) { - Vec3 center = { - (c->aabb.min.x + c->aabb.max.x) * 0.5f, - (c->aabb.min.y + c->aabb.max.y) * 0.5f, - (c->aabb.min.z + c->aabb.max.z) * 0.5f - }; - Vec3 delta; - vec3_sub(&position, ¢er, &delta); - move_collider(c, delta); - } -} - -static int aabb_vs_aabb(const Collider* a, const Collider* b, Vec3* normal, float* depth) { - Vec3 diff; - Vec3 centerA = {(a->aabb.min.x + a->aabb.max.x) * 0.5f, (a->aabb.min.y + a->aabb.max.y) * 0.5f, (a->aabb.min.z + a->aabb.max.z) * 0.5f}; - Vec3 centerB = {(b->aabb.min.x + b->aabb.max.x) * 0.5f, (b->aabb.min.y + b->aabb.max.y) * 0.5f, (b->aabb.min.z + b->aabb.max.z) * 0.5f}; - vec3_sub(¢erA, ¢erB, &diff); - Vec3 half_a, half_b; - vec3_sub(&a->aabb.max, &a->aabb.min, &half_a); - vec3_scale(&half_a, 0.5f, &half_a); - vec3_sub(&b->aabb.max, &b->aabb.min, &half_b); - vec3_scale(&half_b, 0.5f, &half_b); - - float dx = fabsf(diff.x) - (half_a.x + half_b.x); - float dy = fabsf(diff.y) - (half_a.y + half_b.y); - float dz = fabsf(diff.z) - (half_a.z + half_b.z); - - if (dx < 0 && dy < 0 && dz < 0) { - *depth = -fmaxf(fmaxf(dx, dy), dz); - if (dx > dy && dx > dz) { *normal = (Vec3){copysignf(1.0f, diff.x), 0, 0}; } - else if (dy > dz) { normal->x = 0; normal->y = copysignf(1.0f, diff.y); normal->z = 0; } - else { normal->x = 0; normal->y = 0; normal->z = copysignf(1.0f, diff.z); } - return 1; - } - return 0; -} - -static int sphere_vs_sphere(const Collider* a, const Collider* b, Vec3* normal, float* depth) { - Vec3 diff; - vec3_sub(&a->sphere.center, &b->sphere.center, &diff); - float dist = vec3_length(&diff); - float radii = a->sphere.radius + b->sphere.radius; - - if (dist < radii) { - *depth = radii - dist; - if (dist > 0.0001f) { - vec3_normalize(&diff, normal); - } else { - *normal = (Vec3){0, 1, 0}; - } - return 1; - } - return 0; -} - -static int sphere_vs_aabb(const Collider* sphere, const Collider* aabb, Vec3* normal, float* depth) { - Vec3 closest; - closest.x = fmaxf(aabb->aabb.min.x, fminf(sphere->sphere.center.x, aabb->aabb.max.x)); - closest.y = fmaxf(aabb->aabb.min.y, fminf(sphere->sphere.center.y, aabb->aabb.max.y)); - closest.z = fmaxf(aabb->aabb.min.z, fminf(sphere->sphere.center.z, aabb->aabb.max.z)); - - Vec3 diff; - vec3_sub(&sphere->sphere.center, &closest, &diff); - float dist_sq = vec3_dot(&diff, &diff); - - if (dist_sq < sphere->sphere.radius * sphere->sphere.radius) { - float dist = sqrtf(dist_sq); - *depth = sphere->sphere.radius - dist; - if (dist > 0.0001f) { - vec3_normalize(&diff, normal); - } else { - *normal = (Vec3){0, 1, 0}; - } - return 1; - } - return 0; -} - -static int sphere_vs_plane(const Collider* sphere, const Collider* plane, Vec3* normal, float* depth) { - float dist = vec3_dot(&sphere->sphere.center, &plane->plane.normal) - plane->plane.distance; - if (dist < sphere->sphere.radius) { - *depth = sphere->sphere.radius - dist; - *normal = plane->plane.normal; - return 1; - } - return 0; -} - -int physics_check_collision(const Collider* a, const Collider* b, Vec3* normal, float* depth) { - if (a->type == COLLIDER_AABB && b->type == COLLIDER_AABB) - return aabb_vs_aabb(a, b, normal, depth); - if (a->type == COLLIDER_SPHERE && b->type == COLLIDER_SPHERE) - return sphere_vs_sphere(a, b, normal, depth); - if (a->type == COLLIDER_SPHERE && b->type == COLLIDER_AABB) - return sphere_vs_aabb(a, b, normal, depth); - if (a->type == COLLIDER_AABB && b->type == COLLIDER_SPHERE) { - int hit = sphere_vs_aabb(b, a, normal, depth); - if (hit) { normal->x = -normal->x; normal->y = -normal->y; normal->z = -normal->z; } - return hit; - } - if (a->type == COLLIDER_SPHERE && b->type == COLLIDER_PLANE) - return sphere_vs_plane(a, b, normal, depth); - if (a->type == COLLIDER_PLANE && b->type == COLLIDER_SPHERE) { - int hit = sphere_vs_plane(b, a, normal, depth); - if (hit) { normal->x = -normal->x; normal->y = -normal->y; normal->z = -normal->z; } - return hit; - } - return 0; -} - -int physics_raycast(PhysicsWorld* world, Vec3 origin, Vec3 direction, float max_dist, - uint32_t* hit_entity, Vec3* hit_point, Vec3* hit_normal) { - vec3_normalize(&direction, &direction); - float closest_t = max_dist; - int hit = 0; - - for (uint32_t i = 0; i < world->collider_count; i++) { - Collider* c = &world->colliders[i]; - if (c->type == COLLIDER_SPHERE) { - Vec3 oc; - vec3_sub(&origin, &c->sphere.center, &oc); - float a = vec3_dot(&direction, &direction); - float b = 2.0f * vec3_dot(&oc, &direction); - float cc = vec3_dot(&oc, &oc) - c->sphere.radius * c->sphere.radius; - float disc = b * b - 4 * a * cc; - if (disc >= 0) { - float t = (-b - sqrtf(disc)) / (2 * a); - if (t > 0 && t < closest_t) { - closest_t = t; - *hit_entity = c->entity_id; - Vec3 scaled; - vec3_scale(&direction, t, &scaled); - vec3_add(&origin, &scaled, hit_point); - vec3_sub(hit_point, &c->sphere.center, hit_normal); - vec3_normalize(hit_normal, hit_normal); - hit = 1; - } - } - } - } - return hit; -} - -static int body_is_movable(Collider* c) { - return !c->is_static && !c->body.is_kinematic && c->body.mass > 0.0f; -} - -static float body_inv_mass(Collider* c) { - if (c->is_static || c->body.is_kinematic || c->body.mass <= 0.0f) return 0.0f; - return 1.0f / c->body.mass; -} - -static void move_collider(Collider* c, Vec3 delta) { - if (c->type == COLLIDER_SPHERE) { - vec3_add(&c->sphere.center, &delta, &c->sphere.center); - } else if (c->type == COLLIDER_AABB) { - vec3_add(&c->aabb.min, &delta, &c->aabb.min); - vec3_add(&c->aabb.max, &delta, &c->aabb.max); - } -} - -RigidBody* physics_get_body(PhysicsWorld* world, uint32_t index) { - if (!world || index >= world->collider_count) return NULL; - return &world->colliders[index].body; -} - -void physics_apply_force(PhysicsWorld* world, uint32_t index, Vec3 force) { - RigidBody* b = physics_get_body(world, index); - if (!b || b->mass <= 0.0f) return; - Vec3 scaled; - vec3_scale(&force, 1.0f / b->mass, &scaled); - vec3_add(&b->acceleration, &scaled, &b->acceleration); -} - -void physics_apply_impulse(PhysicsWorld* world, uint32_t index, Vec3 impulse) { - RigidBody* b = physics_get_body(world, index); - if (!b || b->mass <= 0.0f) return; - Vec3 scaled; - vec3_scale(&impulse, 1.0f / b->mass, &scaled); - vec3_add(&b->velocity, &scaled, &b->velocity); -} - -void physics_step(PhysicsWorld* world, float dt) { - if (!world || world->collider_count == 0 || dt <= 0.0f) return; - - const float linear_damping = 0.995f; - - // 1. 积分动态刚体 - for (uint32_t i = 0; i < world->collider_count; i++) { - Collider* c = &world->colliders[i]; - if (!body_is_movable(c)) continue; - - RigidBody* b = &c->body; - if (world->gravity_enabled) { - vec3_add(&b->acceleration, &world->gravity, &b->acceleration); - } - - Vec3 dv; - vec3_scale(&b->acceleration, dt, &dv); - vec3_add(&b->velocity, &dv, &b->velocity); - b->acceleration = (Vec3){0, 0, 0}; - - vec3_scale(&b->velocity, linear_damping, &b->velocity); - - Vec3 dp; - vec3_scale(&b->velocity, dt, &dp); - move_collider(c, dp); - } - - // 2. 碰撞检测与响应 - for (uint32_t i = 0; i < world->collider_count; i++) { - Collider* a = &world->colliders[i]; - for (uint32_t j = i + 1; j < world->collider_count; j++) { - Collider* b = &world->colliders[j]; - if (a->is_static && b->is_static) continue; - - Vec3 normal; - float depth = 0.0f; - if (!physics_check_collision(a, b, &normal, &depth)) continue; - - // 触发器只报告,不解决 - if (a->is_trigger || b->is_trigger) continue; - - float inv_a = body_inv_mass(a); - float inv_b = body_inv_mass(b); - float total_inv = inv_a + inv_b; - if (total_inv <= 0.0f) continue; - - // 位置修正(防止沉入) - float percent = 0.5f; // 修正比例 - Vec3 correction; - vec3_scale(&normal, depth * percent / total_inv, &correction); - if (inv_a > 0.0f) { - Vec3 da; vec3_scale(&correction, inv_a, &da); - da.x = -da.x; da.y = -da.y; da.z = -da.z; - move_collider(a, da); - } - if (inv_b > 0.0f) { - Vec3 db; vec3_scale(&correction, inv_b, &db); - move_collider(b, db); - } - - // 冲量响应 - Vec3 rel_v; - vec3_sub(&a->body.velocity, &b->body.velocity, &rel_v); - float vel_along_normal = vec3_dot(&rel_v, &normal); - if (vel_along_normal > 0.0f) continue; // 正在分离 - - float e = fminf(a->body.restitution, b->body.restitution); - float j = -(1.0f + e) * vel_along_normal / total_inv; - - Vec3 impulse; - vec3_scale(&normal, j, &impulse); - if (inv_a > 0.0f) { - Vec3 va; vec3_scale(&impulse, inv_a, &va); - vec3_add(&a->body.velocity, &va, &a->body.velocity); - } - if (inv_b > 0.0f) { - Vec3 vb; vec3_scale(&impulse, inv_b, &vb); - vec3_sub(&b->body.velocity, &vb, &b->body.velocity); - } - - // 摩擦力 - vec3_sub(&a->body.velocity, &b->body.velocity, &rel_v); - Vec3 tangent; - Vec3 vn; vec3_scale(&normal, vec3_dot(&rel_v, &normal), &vn); - vec3_sub(&rel_v, &vn, &tangent); - float tan_len = vec3_length(&tangent); - if (tan_len > 0.0001f) { - vec3_scale(&tangent, 1.0f / tan_len, &tangent); - float jt = -vec3_dot(&rel_v, &tangent) / total_inv; - float mu = sqrtf(a->body.friction * a->body.friction + b->body.friction * b->body.friction); - if (jt > j * mu) jt = j * mu; - if (jt < -j * mu) jt = -j * mu; - Vec3 friction_impulse; - vec3_scale(&tangent, jt, &friction_impulse); - if (inv_a > 0.0f) { - Vec3 va; vec3_scale(&friction_impulse, inv_a, &va); - vec3_add(&a->body.velocity, &va, &a->body.velocity); - } - if (inv_b > 0.0f) { - Vec3 vb; vec3_scale(&friction_impulse, inv_b, &vb); - vec3_sub(&b->body.velocity, &vb, &b->body.velocity); - } - } - } - } -} - -void physics_set_gravity(PhysicsWorld* world, Vec3 gravity) { - world->gravity = gravity; -} diff --git a/Engine/Physics/physics.h b/Engine/Physics/physics.h deleted file mode 100644 index 7f7a2b5..0000000 --- a/Engine/Physics/physics.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -// ============================================================================ -// physics.h - 物理引擎 (碰撞检测, 调用ASM数学) -// ============================================================================ - -#include "../include/engine_api.h" -#include "../ASM/math_c_fallback.h" -#include - -#define MAX_COLLIDERS 1024 - -typedef enum { - COLLIDER_AABB, - COLLIDER_SPHERE, - COLLIDER_PLANE, -} ColliderType; - -typedef struct { - Vec3 velocity; - Vec3 acceleration; - float mass; - float restitution; - float friction; - int is_kinematic; -} RigidBody; - -typedef struct { - uint32_t entity_id; - ColliderType type; - union { - struct { Vec3 min; Vec3 max; } aabb; - struct { Vec3 center; float radius; } sphere; - struct { Vec3 normal; float distance; } plane; - }; - int is_trigger; - int is_static; - RigidBody body; -} Collider; - -typedef struct { - Collider colliders[MAX_COLLIDERS]; - uint32_t collider_count; - int gravity_enabled; - Vec3 gravity; -} PhysicsWorld; - -// 碰撞回调 -typedef void (*CollisionCallback)(uint32_t entity_a, uint32_t entity_b, Vec3 normal, float depth); - -// 创建/销毁 -PhysicsWorld* physics_create(void); -void physics_destroy(PhysicsWorld* world); - -// 碰撞体 -uint32_t physics_add_aabb(PhysicsWorld* world, uint32_t entity, Vec3 min, Vec3 max); -uint32_t physics_add_sphere(PhysicsWorld* world, uint32_t entity, Vec3 center, float radius); -uint32_t physics_add_plane(PhysicsWorld* world, uint32_t entity, Vec3 normal, float distance); -void physics_remove_collider(PhysicsWorld* world, uint32_t index); -void physics_update_collider(PhysicsWorld* world, uint32_t index, Vec3 position); - -// 碰撞检测 -int physics_check_collision(const Collider* a, const Collider* b, Vec3* normal, float* depth); -int physics_raycast(PhysicsWorld* world, Vec3 origin, Vec3 direction, float max_dist, - uint32_t* hit_entity, Vec3* hit_point, Vec3* hit_normal); - -// 刚体 -RigidBody* physics_get_body(PhysicsWorld* world, uint32_t index); -void physics_apply_force(PhysicsWorld* world, uint32_t index, Vec3 force); -void physics_apply_impulse(PhysicsWorld* world, uint32_t index, Vec3 impulse); - -// 模拟 -void physics_step(PhysicsWorld* world, float dt); -void physics_set_gravity(PhysicsWorld* world, Vec3 gravity); diff --git a/Engine/Rendering/camera.c b/Engine/Rendering/camera.c deleted file mode 100644 index 285cfcd..0000000 --- a/Engine/Rendering/camera.c +++ /dev/null @@ -1,135 +0,0 @@ -#include "camera.h" - -#include -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -Camera camera_perspective(float fov_y, float aspect, float near_z, float far_z) { - Camera cam = {0}; - cam.type = CAMERA_PERSPECTIVE; - cam.position = (Vec3){0, 0, -5}; - cam.target = (Vec3){0, 0, 0}; - cam.up = (Vec3){0, 1, 0}; - cam.fov_y = fov_y; - cam.aspect = aspect; - cam.near_z = near_z; - cam.far_z = far_z; - cam.dirty = 1; - return cam; -} - -Camera camera_orthographic(float width, float height, float near_z, float far_z) { - Camera cam = {0}; - cam.type = CAMERA_ORTHOGRAPHIC; - cam.position = (Vec3){0, 0, -5}; - cam.target = (Vec3){0, 0, 0}; - cam.up = (Vec3){0, 1, 0}; - cam.ortho_width = width; - cam.ortho_height = height; - cam.near_z = near_z; - cam.far_z = far_z; - cam.dirty = 1; - return cam; -} - -void camera_update(Camera* camera) { - if (!camera->dirty) return; - mat4_lookat(&camera->position, &camera->target, &camera->up, &camera->view); - - if (camera->type == CAMERA_PERSPECTIVE) { - mat4_perspective(camera->fov_y, camera->aspect, camera->near_z, camera->far_z, &camera->projection); - } else { - mat4_orthographic(camera->ortho_width, camera->ortho_height, camera->near_z, camera->far_z, &camera->projection); - } - camera->dirty = 0; -} - -const Mat4* camera_get_view(Camera* camera) { - camera_update(camera); - return &camera->view; -} - -const Mat4* camera_get_projection(Camera* camera) { - camera_update(camera); - return &camera->projection; -} - -void camera_move_forward(Camera* camera, float distance) { - Vec3 dir; - vec3_sub(&camera->target, &camera->position, &dir); - vec3_normalize(&dir, &dir); - Vec3 move; - vec3_scale(&dir, distance, &move); - vec3_add(&camera->position, &move, &camera->position); - vec3_add(&camera->target, &move, &camera->target); - camera->dirty = 1; -} - -void camera_move_right(Camera* camera, float distance) { - Vec3 forward, right; - vec3_sub(&camera->target, &camera->position, &forward); - vec3_normalize(&forward, &forward); - vec3_cross(&camera->up, &forward, &right); - vec3_normalize(&right, &right); - Vec3 move; - vec3_scale(&right, distance, &move); - vec3_add(&camera->position, &move, &camera->position); - vec3_add(&camera->target, &move, &camera->target); - camera->dirty = 1; -} - -void camera_move_up(Camera* camera, float distance) { - Vec3 move; - vec3_scale(&camera->up, distance, &move); - vec3_add(&camera->position, &move, &camera->position); - vec3_add(&camera->target, &move, &camera->target); - camera->dirty = 1; -} - -void camera_rotate_yaw(Camera* camera, float angle) { - Vec3 forward; - vec3_sub(&camera->target, &camera->position, &forward); - - float cs = cosf(angle), sn = sinf(angle); - Vec3 right; - vec3_cross(&forward, &camera->up, &right); - vec3_normalize(&right, &right); - - Vec3 new_forward = { - forward.x * cs + right.x * sn, - forward.y * cs + right.y * sn, - forward.z * cs + right.z * sn, - }; - vec3_add(&camera->position, &new_forward, &camera->target); - camera->dirty = 1; -} - -void camera_rotate_pitch(Camera* camera, float angle) { - Vec3 forward; - vec3_sub(&camera->target, &camera->position, &forward); - - Vec3 right; - vec3_cross(&forward, &camera->up, &right); - vec3_normalize(&right, &right); - - float cs = cosf(angle), sn = sinf(angle); - Vec3 new_forward = { - forward.x * cs + camera->up.x * sn, - forward.y * cs + camera->up.y * sn, - forward.z * cs + camera->up.z * sn, - }; - - Vec3 new_up; - vec3_cross(&right, &new_forward, &new_up); - camera->up = new_up; - vec3_add(&camera->position, &new_forward, &camera->target); - camera->dirty = 1; -} - -void camera_look_at(Camera* camera, Vec3 target) { - camera->target = target; - camera->dirty = 1; -} diff --git a/Engine/Rendering/camera.h b/Engine/Rendering/camera.h deleted file mode 100644 index 9a28863..0000000 --- a/Engine/Rendering/camera.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -// ============================================================================ -// camera.h - 摄像机 -// ============================================================================ - -#include "../include/engine_api.h" -#include "../ASM/math_c_fallback.h" - -typedef enum { - CAMERA_PERSPECTIVE, - CAMERA_ORTHOGRAPHIC, -} CameraType; - -typedef struct { - CameraType type; - Vec3 position; - Vec3 target; - Vec3 up; - float fov_y; - float aspect; - float near_z; - float far_z; - float ortho_width; - float ortho_height; - Mat4 view; - Mat4 projection; - int dirty; -} Camera; - -// 创建默认透视摄像机 -Camera camera_perspective(float fov_y, float aspect, float near_z, float far_z); - -// 创建正交摄像机 -Camera camera_orthographic(float width, float height, float near_z, float far_z); - -// 更新矩阵 -void camera_update(Camera* camera); - -// 获取矩阵 -const Mat4* camera_get_view(Camera* camera); -const Mat4* camera_get_projection(Camera* camera); - -// 移动 -void camera_move_forward(Camera* camera, float distance); -void camera_move_right(Camera* camera, float distance); -void camera_move_up(Camera* camera, float distance); - -// 旋转 -void camera_rotate_yaw(Camera* camera, float angle); -void camera_rotate_pitch(Camera* camera, float angle); - -// 设置目标 -void camera_look_at(Camera* camera, Vec3 target); diff --git a/Engine/Rendering/camera_controller.c b/Engine/Rendering/camera_controller.c deleted file mode 100644 index a022ad8..0000000 --- a/Engine/Rendering/camera_controller.c +++ /dev/null @@ -1,98 +0,0 @@ -#include "camera_controller.h" -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846f -#endif - -CameraController camera_controller_create(Camera* camera) { - CameraController ctrl = {0}; - ctrl.camera = camera; - ctrl.mode = CAMERA_MODE_FLY; - ctrl.move_speed = 10.0f; - ctrl.mouse_sensitivity = 0.003f; - ctrl.height_offset = 1.75f; - ctrl.pitch_min = -1.45f; - ctrl.pitch_max = 1.45f; - ctrl.yaw = 0.0f; - ctrl.pitch = 0.0f; - ctrl.ground_height_fn = NULL; - ctrl.ground_user = NULL; - return ctrl; -} - -void camera_controller_set_ground_callback(CameraController* ctrl, - float (*get_height)(float x, float z, void* user), - void* user) { - ctrl->ground_height_fn = get_height; - ctrl->ground_user = user; -} - -void camera_controller_set_mode(CameraController* ctrl, CameraMode mode) { - ctrl->mode = mode; -} - -void camera_controller_look(CameraController* ctrl, float delta_x, float delta_y) { - ctrl->yaw -= delta_x * ctrl->mouse_sensitivity; - ctrl->pitch -= delta_y * ctrl->mouse_sensitivity; - if (ctrl->pitch < ctrl->pitch_min) ctrl->pitch = ctrl->pitch_min; - if (ctrl->pitch > ctrl->pitch_max) ctrl->pitch = ctrl->pitch_max; - - // 重建 target - Vec3 forward; - forward.x = cosf(ctrl->pitch) * sinf(ctrl->yaw); - forward.y = sinf(ctrl->pitch); - forward.z = cosf(ctrl->pitch) * cosf(ctrl->yaw); - vec3_normalize(&forward, &forward); - - vec3_add(&ctrl->camera->position, &forward, &ctrl->camera->target); - ctrl->camera->dirty = 1; -} - -void camera_controller_move(CameraController* ctrl, Vec3 dir, float dt) { - Camera* cam = ctrl->camera; - - Vec3 forward, right, up; - vec3_sub(&cam->target, &cam->position, &forward); - forward.y = 0.0f; - vec3_normalize(&forward, &forward); - - vec3_cross(&cam->up, &forward, &right); - vec3_normalize(&right, &right); - - up = cam->up; - - Vec3 move = {0}; - Vec3 tmp; - vec3_scale(&right, dir.x, &tmp); - vec3_add(&move, &tmp, &move); - vec3_scale(&up, dir.y, &tmp); - vec3_add(&move, &tmp, &move); - vec3_scale(&forward, dir.z, &tmp); - vec3_add(&move, &tmp, &move); - - float len = vec3_length(&move); - if (len > 0.0001f) { - vec3_scale(&move, ctrl->move_speed * dt / len, &move); - vec3_add(&cam->position, &move, &cam->position); - vec3_add(&cam->target, &move, &cam->target); - cam->dirty = 1; - } -} - -void camera_controller_update(CameraController* ctrl, float dt) { - (void)dt; - if (ctrl->mode != CAMERA_MODE_WALK) return; - if (!ctrl->ground_height_fn) return; - - float ground = ctrl->ground_height_fn(ctrl->camera->position.x, ctrl->camera->position.z, ctrl->ground_user); - float desired_y = ground + ctrl->height_offset; - float delta = desired_y - ctrl->camera->position.y; - - if (fabsf(delta) > 0.01f) { - Vec3 move = {0, delta, 0}; - vec3_add(&ctrl->camera->position, &move, &ctrl->camera->position); - vec3_add(&ctrl->camera->target, &move, &ctrl->camera->target); - ctrl->camera->dirty = 1; - } -} diff --git a/Engine/Rendering/camera_controller.h b/Engine/Rendering/camera_controller.h deleted file mode 100644 index 8708eee..0000000 --- a/Engine/Rendering/camera_controller.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -// ============================================================================ -// camera_controller.h - 增强相机控制器(飞行 / 步行模式) -// ============================================================================ - -#include "camera.h" -#include "../ASM/math_c_fallback.h" - -typedef enum { - CAMERA_MODE_FLY, - CAMERA_MODE_WALK, -} CameraMode; - -typedef struct { - Camera* camera; - CameraMode mode; - float move_speed; - float mouse_sensitivity; - float height_offset; // 步行模式眼睛离地面高度 - float pitch_min; - float pitch_max; - float yaw; - float pitch; - float (*ground_height_fn)(float x, float z, void* user); - void* ground_user; -} CameraController; - -CameraController camera_controller_create(Camera* camera); - -// 更新 yaw/pitch,鼠标输入以 delta 像素为单位 -void camera_controller_look(CameraController* ctrl, float delta_x, float delta_y); - -// 移动:dir 为本地空间方向 (x=右, y=上, z=前) -void camera_controller_move(CameraController* ctrl, Vec3 dir, float dt); - -// 设置地形高度采样回调 -void camera_controller_set_ground_callback(CameraController* ctrl, float (*get_height)(float x, float z, void* user), void* user); - -// 切换模式 -void camera_controller_set_mode(CameraController* ctrl, CameraMode mode); - -// 每帧应用约束(如步行贴地) -void camera_controller_update(CameraController* ctrl, float dt); diff --git a/Engine/Rendering/frustum.c b/Engine/Rendering/frustum.c deleted file mode 100644 index 74f38a2..0000000 --- a/Engine/Rendering/frustum.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "frustum.h" -#include - -void frustum_from_matrix(const Mat4* vp, Vec4 planes[6]) { - // 行主序存储:clip = vec4(pos,1) * vp - // 因此 clip 分量 = dot(pos, vp 的列) - // left = col3 + col0 - // right = col3 - col0 - // bottom = col3 + col1 - // top = col3 - col1 - // near = col3 + col2 - // far = col3 - col2 - planes[0] = (Vec4){ vp->m[0][3] + vp->m[0][0], - vp->m[1][3] + vp->m[1][0], - vp->m[2][3] + vp->m[2][0], - vp->m[3][3] + vp->m[3][0] }; - planes[1] = (Vec4){ vp->m[0][3] - vp->m[0][0], - vp->m[1][3] - vp->m[1][0], - vp->m[2][3] - vp->m[2][0], - vp->m[3][3] - vp->m[3][0] }; - planes[2] = (Vec4){ vp->m[0][3] + vp->m[0][1], - vp->m[1][3] + vp->m[1][1], - vp->m[2][3] + vp->m[2][1], - vp->m[3][3] + vp->m[3][1] }; - planes[3] = (Vec4){ vp->m[0][3] - vp->m[0][1], - vp->m[1][3] - vp->m[1][1], - vp->m[2][3] - vp->m[2][1], - vp->m[3][3] - vp->m[3][1] }; - planes[4] = (Vec4){ vp->m[0][3] + vp->m[0][2], - vp->m[1][3] + vp->m[1][2], - vp->m[2][3] + vp->m[2][2], - vp->m[3][3] + vp->m[3][2] }; - planes[5] = (Vec4){ vp->m[0][3] - vp->m[0][2], - vp->m[1][3] - vp->m[1][2], - vp->m[2][3] - vp->m[2][2], - vp->m[3][3] - vp->m[3][2] }; - - for (int i = 0; i < 6; i++) { - float len = sqrtf(planes[i].x * planes[i].x + - planes[i].y * planes[i].y + - planes[i].z * planes[i].z); - if (len > 0.0001f) { - planes[i].x /= len; - planes[i].y /= len; - planes[i].z /= len; - planes[i].w /= len; - } - } -} - -int frustum_intersects_sphere(const Vec4 planes[6], Vec3 center, float radius) { - for (int i = 0; i < 6; i++) { - float dist = planes[i].x * center.x + - planes[i].y * center.y + - planes[i].z * center.z + - planes[i].w; - if (dist < -radius) return 0; - } - return 1; -} diff --git a/Engine/Rendering/frustum.h b/Engine/Rendering/frustum.h deleted file mode 100644 index 5c7e51c..0000000 --- a/Engine/Rendering/frustum.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include "../ASM/math_c_fallback.h" - -// 从视图*投影矩阵提取 6 个视锥平面(行主序,planes[0..5] = left, right, bottom, top, near, far) -void frustum_from_matrix(const Mat4* vp, Vec4 planes[6]); - -// 判断球体是否与视锥相交(1=可见/相交,0=完全在外) -int frustum_intersects_sphere(const Vec4 planes[6], Vec3 center, float radius); diff --git a/Engine/Rendering/graphics_device.c b/Engine/Rendering/graphics_device.c deleted file mode 100644 index 4166cd9..0000000 --- a/Engine/Rendering/graphics_device.c +++ /dev/null @@ -1,189 +0,0 @@ -#include "graphics_device.h" -#include -#include -#include - -GraphicsDevice* graphics_device_create(void) { - return (GraphicsDevice*)calloc(1, sizeof(GraphicsDevice)); -} - -void graphics_device_destroy(GraphicsDevice* d) { - if (!d) return; - if (d->depth_stencil) d->depth_stencil->lpVtbl->Release(d->depth_stencil); - if (d->depth_texture) d->depth_texture->lpVtbl->Release(d->depth_texture); - if (d->render_target) d->render_target->lpVtbl->Release(d->render_target); - if (d->swap_chain) d->swap_chain->lpVtbl->Release(d->swap_chain); - if (d->context) d->context->lpVtbl->Release(d->context); - if (d->device) d->device->lpVtbl->Release(d->device); - free(d); -} - -static int create_depth_stencil(GraphicsDevice* d, uint32_t w, uint32_t h) { - D3D11_TEXTURE2D_DESC desc = {0}; - desc.Width = w; desc.Height = h; - desc.MipLevels = 1; desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - HRESULT hr = d->device->lpVtbl->CreateTexture2D(d->device, &desc, NULL, &d->depth_texture); - if (FAILED(hr)) return 0; - D3D11_DEPTH_STENCIL_VIEW_DESC dsv = {0}; - dsv.Format = desc.Format; - dsv.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - hr = d->device->lpVtbl->CreateDepthStencilView(d->device, (ID3D11Resource*)d->depth_texture, &dsv, &d->depth_stencil); - return SUCCEEDED(hr); -} - -int graphics_device_init(GraphicsDevice* d, void* hwnd, uint32_t w, uint32_t h, int vsync) { - d->width = w; d->height = h; d->vsync = vsync; - DXGI_SWAP_CHAIN_DESC scd = {0}; - scd.BufferCount = 1; - scd.BufferDesc.Width = w; - scd.BufferDesc.Height = h; - scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - scd.BufferDesc.RefreshRate.Numerator = 60; - scd.BufferDesc.RefreshRate.Denominator = 1; - scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - scd.OutputWindow = (HWND)hwnd; - scd.SampleDesc.Count = 1; - scd.Windowed = TRUE; - scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - D3D_FEATURE_LEVEL levels[] = {D3D_FEATURE_LEVEL_11_0}; - UINT flags = 0; -#ifdef _DEBUG - flags |= D3D11_CREATE_DEVICE_DEBUG; -#endif - HRESULT hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, levels, 1, D3D11_SDK_VERSION, &scd, &d->swap_chain, &d->device, NULL, &d->context); - if (FAILED(hr)) return 0; - ID3D11Texture2D* back_buffer = NULL; - d->swap_chain->lpVtbl->GetBuffer(d->swap_chain, 0, &IID_ID3D11Texture2D, (void**)&back_buffer); - d->device->lpVtbl->CreateRenderTargetView(d->device, (ID3D11Resource*)back_buffer, NULL, &d->render_target); - if (back_buffer) back_buffer->lpVtbl->Release(back_buffer); - create_depth_stencil(d, w, h); - d->context->lpVtbl->OMSetRenderTargets(d->context, 1, &d->render_target, d->depth_stencil); - D3D11_VIEWPORT vp = {0}; - vp.Width = (float)w; vp.Height = (float)h; - vp.MaxDepth = 1.0f; - d->context->lpVtbl->RSSetViewports(d->context, 1, &vp); - - // 设置默认深度状态 (避免 UILayer init 破坏) - D3D11_DEPTH_STENCIL_DESC dsd = {0}; - dsd.DepthEnable = TRUE; - dsd.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - dsd.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; - ID3D11DepthStencilState* default_dss = NULL; - d->device->lpVtbl->CreateDepthStencilState(d->device, &dsd, &default_dss); - if (default_dss) { - d->context->lpVtbl->OMSetDepthStencilState(d->context, default_dss, 0); - default_dss->lpVtbl->Release(default_dss); - } - - // 设置默认光栅化状态:背面剔除 + 实体填充 - D3D11_RASTERIZER_DESC rd = {0}; - rd.FillMode = D3D11_FILL_SOLID; - rd.CullMode = D3D11_CULL_BACK; - rd.FrontCounterClockwise = FALSE; - rd.DepthClipEnable = TRUE; - ID3D11RasterizerState* default_rs = NULL; - d->device->lpVtbl->CreateRasterizerState(d->device, &rd, &default_rs); - if (default_rs) { - d->context->lpVtbl->RSSetState(d->context, default_rs); - default_rs->lpVtbl->Release(default_rs); - } - return 1; -} - -void graphics_device_resize(GraphicsDevice* d, uint32_t w, uint32_t h) { - if (w == 0 || h == 0) return; - d->context->lpVtbl->OMSetRenderTargets(d->context, 0, NULL, NULL); - if (d->render_target) { d->render_target->lpVtbl->Release(d->render_target); d->render_target = NULL; } - if (d->depth_stencil) { d->depth_stencil->lpVtbl->Release(d->depth_stencil); d->depth_stencil = NULL; } - if (d->depth_texture) { d->depth_texture->lpVtbl->Release(d->depth_texture); d->depth_texture = NULL; } - d->swap_chain->lpVtbl->ResizeBuffers(d->swap_chain, 0, w, h, DXGI_FORMAT_UNKNOWN, 0); - ID3D11Texture2D* back_buffer = NULL; - d->swap_chain->lpVtbl->GetBuffer(d->swap_chain, 0, &IID_ID3D11Texture2D, (void**)&back_buffer); - d->device->lpVtbl->CreateRenderTargetView(d->device, (ID3D11Resource*)back_buffer, NULL, &d->render_target); - if (back_buffer) back_buffer->lpVtbl->Release(back_buffer); - create_depth_stencil(d, w, h); - d->context->lpVtbl->OMSetRenderTargets(d->context, 1, &d->render_target, d->depth_stencil); - D3D11_VIEWPORT vp = {0}; - vp.Width = (float)w; vp.Height = (float)h; vp.MaxDepth = 1.0f; - d->context->lpVtbl->RSSetViewports(d->context, 1, &vp); - d->width = w; d->height = h; -} - -void graphics_device_clear(GraphicsDevice* d, float r, float g, float b, float a) { - float color[4] = {r, g, b, a}; - d->context->lpVtbl->ClearRenderTargetView(d->context, d->render_target, color); - d->context->lpVtbl->ClearDepthStencilView(d->context, d->depth_stencil, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); -} - -void graphics_device_present(GraphicsDevice* d) { - d->swap_chain->lpVtbl->Present(d->swap_chain, d->vsync ? 1 : 0, 0); -} - -int graphics_device_save_screenshot(GraphicsDevice* d, const char* path) { - if (!d || !d->swap_chain || !d->device || !d->context) return 0; - - ID3D11Texture2D* back = NULL; - HRESULT hr = d->swap_chain->lpVtbl->GetBuffer(d->swap_chain, 0, &IID_ID3D11Texture2D, (void**)&back); - if (FAILED(hr) || !back) return 0; - - D3D11_TEXTURE2D_DESC desc = {0}; - back->lpVtbl->GetDesc(back, &desc); - - D3D11_TEXTURE2D_DESC sd = desc; - sd.BindFlags = 0; - sd.Usage = D3D11_USAGE_STAGING; - sd.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - sd.MiscFlags = 0; - - ID3D11Texture2D* staging = NULL; - hr = d->device->lpVtbl->CreateTexture2D(d->device, &sd, NULL, &staging); - if (FAILED(hr) || !staging) { back->lpVtbl->Release(back); return 0; } - - d->context->lpVtbl->CopyResource(d->context, (ID3D11Resource*)staging, (ID3D11Resource*)back); - - D3D11_MAPPED_SUBRESOURCE map = {0}; - hr = d->context->lpVtbl->Map(d->context, (ID3D11Resource*)staging, 0, D3D11_MAP_READ, 0, &map); - if (FAILED(hr)) { staging->lpVtbl->Release(staging); back->lpVtbl->Release(back); return 0; } - - FILE* f = fopen(path, "wb"); - if (!f) { d->context->lpVtbl->Unmap(d->context, (ID3D11Resource*)staging, 0); staging->lpVtbl->Release(staging); back->lpVtbl->Release(back); return 0; } - - int w = (int)desc.Width; - int h = (int)desc.Height; - int row_size = ((w * 3 + 3) / 4) * 4; - int file_size = 54 + row_size * h; - - unsigned char header[54] = {0}; - header[0] = 'B'; header[1] = 'M'; - memcpy(header + 2, &file_size, 4); - header[10] = 54; - header[14] = 40; - memcpy(header + 18, &w, 4); - memcpy(header + 22, &h, 4); - header[26] = 1; - header[28] = 24; - fwrite(header, 1, 54, f); - - unsigned char* row = (unsigned char*)malloc(row_size); - for (int y = 0; y < h; y++) { - uint8_t* src = (uint8_t*)map.pData + (h - 1 - y) * map.RowPitch; - for (int x = 0; x < w; x++) { - // 后台缓冲区为 RGBA,BMP 24-bit 需要 BGR - row[x * 3 + 0] = src[x * 4 + 2]; - row[x * 3 + 1] = src[x * 4 + 1]; - row[x * 3 + 2] = src[x * 4 + 0]; - } - fwrite(row, 1, row_size, f); - } - free(row); - fclose(f); - - d->context->lpVtbl->Unmap(d->context, (ID3D11Resource*)staging, 0); - staging->lpVtbl->Release(staging); - back->lpVtbl->Release(back); - return 1; -} diff --git a/Engine/Rendering/graphics_device.h b/Engine/Rendering/graphics_device.h deleted file mode 100644 index 3bc05c3..0000000 --- a/Engine/Rendering/graphics_device.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include -#include -#include - -typedef struct GraphicsDevice GraphicsDevice; -struct GraphicsDevice { - ID3D11Device* device; - ID3D11DeviceContext* context; - IDXGISwapChain* swap_chain; - ID3D11RenderTargetView* render_target; - ID3D11DepthStencilView* depth_stencil; - ID3D11Texture2D* depth_texture; - uint32_t width; - uint32_t height; - int vsync; -}; - -GraphicsDevice* graphics_device_create(void); -void graphics_device_destroy(GraphicsDevice* d); -int graphics_device_init(GraphicsDevice* d, void* hwnd, uint32_t w, uint32_t h, int vsync); -void graphics_device_resize(GraphicsDevice* d, uint32_t w, uint32_t h); -void graphics_device_clear(GraphicsDevice* d, float r, float g, float b, float a); -void graphics_device_present(GraphicsDevice* d); -int graphics_device_save_screenshot(GraphicsDevice* d, const char* path); diff --git a/Engine/Rendering/lighting.c b/Engine/Rendering/lighting.c deleted file mode 100644 index 0c52240..0000000 --- a/Engine/Rendering/lighting.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "lighting.h" -#include -#include - -Light* light_create_dir(float r, float g, float b, float intensity, float dx, float dy, float dz) { - Light* l = (Light*)calloc(1, sizeof(Light)); - l->type = LIGHT_DIR; - l->color[0] = r; l->color[1] = g; l->color[2] = b; - l->intensity = intensity; - l->direction[0] = dx; l->direction[1] = dy; l->direction[2] = dz; - float len = sqrtf(dx*dx + dy*dy + dz*dz); - if (len > 0.0001f) { l->direction[0] /= len; l->direction[1] /= len; l->direction[2] /= len; } - return l; -} - -Light* light_create_point(float r, float g, float b, float intensity, float x, float y, float z, float range) { - Light* l = (Light*)calloc(1, sizeof(Light)); - l->type = LIGHT_POINT; - l->color[0] = r; l->color[1] = g; l->color[2] = b; - l->intensity = intensity; - l->position[0] = x; l->position[1] = y; l->position[2] = z; - l->range = range; - return l; -} - -void light_destroy(Light* light) { free(light); } diff --git a/Engine/Rendering/lighting.h b/Engine/Rendering/lighting.h deleted file mode 100644 index 08aaef0..0000000 --- a/Engine/Rendering/lighting.h +++ /dev/null @@ -1,17 +0,0 @@ -// lighting.h -#pragma once - -typedef enum { LIGHT_DIR=0, LIGHT_POINT } LightType; - -typedef struct { - LightType type; - float color[3]; - float intensity; - float direction[3]; - float position[3]; - float range; -} Light; - -Light* light_create_dir(float r, float g, float b, float intensity, float dx, float dy, float dz); -Light* light_create_point(float r, float g, float b, float intensity, float x, float y, float z, float range); -void light_destroy(Light* light); diff --git a/Engine/Rendering/material.c b/Engine/Rendering/material.c deleted file mode 100644 index b7d8fa9..0000000 --- a/Engine/Rendering/material.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "material.h" -#include - -Material* material_create(Shader* shader, Texture* texture) { - Material* m = (Material*)calloc(1, sizeof(Material)); - m->shader = shader; - m->texture = texture; - m->color = (Vec4){1.0f, 1.0f, 1.0f, 1.0f}; - m->use_texture = (texture != NULL) ? 1 : 0; - return m; -} - -void material_destroy(Material* m) { - free(m); -} diff --git a/Engine/Rendering/material.h b/Engine/Rendering/material.h deleted file mode 100644 index 1e0f87f..0000000 --- a/Engine/Rendering/material.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "shader.h" -#include "texture.h" -#include "../ASM/math_c_fallback.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - Shader* shader; - Texture* texture; - Vec4 color; - int use_texture; -} Material; - -Material* material_create(Shader* shader, Texture* texture); -void material_destroy(Material* m); - -#ifdef __cplusplus -} -#endif diff --git a/Engine/Rendering/mesh.c b/Engine/Rendering/mesh.c deleted file mode 100644 index 59c5a5f..0000000 --- a/Engine/Rendering/mesh.c +++ /dev/null @@ -1,204 +0,0 @@ -#include "mesh.h" -#include -#include -#include -#include -#ifndef MATH_ASM_AVAILABLE -#include "../ASM/math_c_fallback.h" -#endif - -#define POS(n,x,y,z,nx,ny,nz,u,v,r,g,b,a) {x,y,z, nx,ny,nz, u,v, r,g,b,a} - -static Mesh* create_mesh(ID3D11Device* dev, const void* verts, uint32_t vc, const uint32_t* idx, uint32_t ic, uint32_t stride) { - Mesh* m = (Mesh*)calloc(1, sizeof(Mesh)); - m->stride = stride; m->vcount = vc; m->icount = ic; - D3D11_BUFFER_DESC bd = {0}; - D3D11_SUBRESOURCE_DATA sd = {0}; - bd.ByteWidth = stride * vc; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = verts; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &m->vb); - if (idx && ic > 0) { - bd.ByteWidth = sizeof(uint32_t) * ic; bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = idx; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &m->ib); - } - return m; -} - -void mesh_destroy(Mesh* m) { - if (!m) return; - if (m->ib) m->ib->lpVtbl->Release(m->ib); - if (m->vb) m->vb->lpVtbl->Release(m->vb); - free(m); -} - -void mesh_draw(Mesh* m, ID3D11DeviceContext* ctx) { - UINT stride = m->stride, offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &m->vb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, m->ib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->DrawIndexed(ctx, m->icount, 0, 0); -} - -Mesh* mesh_create_cube(ID3D11Device* dev) { - typedef struct { float p[3], n[3], uv[2], c[4]; } V; - V v[24] = { - POS(0,-.5f,-.5f,-.5f, 0,0,-1, 0,1, 1,1,1,1), POS(1, .5f,-.5f,-.5f, 0,0,-1, 1,1, 1,1,1,1), - POS(2, .5f, .5f,-.5f, 0,0,-1, 1,0, 1,1,1,1), POS(3,-.5f, .5f,-.5f, 0,0,-1, 0,0, 1,1,1,1), - POS(4, .5f,-.5f, .5f, 0,0, 1, 0,1, 1,1,1,1), POS(5,-.5f,-.5f, .5f, 0,0, 1, 1,1, 1,1,1,1), - POS(6,-.5f, .5f, .5f, 0,0, 1, 1,0, 1,1,1,1), POS(7, .5f, .5f, .5f, 0,0, 1, 0,0, 1,1,1,1), - POS(8,-.5f, .5f,-.5f, 0,1, 0, 0,1, 1,1,1,1), POS(9, .5f, .5f,-.5f, 0,1, 0, 1,1, 1,1,1,1), - POS(10,.5f, .5f, .5f, 0,1, 0, 1,0, 1,1,1,1), POS(11,-.5f, .5f, .5f, 0,1, 0, 0,0, 1,1,1,1), - POS(12,-.5f,-.5f, .5f, 0,-1,0, 0,1, 1,1,1,1), POS(13,.5f,-.5f, .5f, 0,-1,0, 1,1, 1,1,1,1), - POS(14,.5f,-.5f,-.5f, 0,-1,0, 1,0, 1,1,1,1), POS(15,-.5f,-.5f,-.5f, 0,-1,0, 0,0, 1,1,1,1), - POS(16,.5f,-.5f,-.5f, 1,0, 0, 0,1, 1,1,1,1), POS(17,.5f,-.5f, .5f, 1,0, 0, 1,1, 1,1,1,1), - POS(18,.5f, .5f, .5f, 1,0, 0, 1,0, 1,1,1,1), POS(19,.5f, .5f,-.5f, 1,0, 0, 0,0, 1,1,1,1), - POS(20,-.5f,-.5f, .5f, -1,0,0, 0,1, 1,1,1,1), POS(21,-.5f,-.5f,-.5f, -1,0,0, 1,1, 1,1,1,1), - POS(22,-.5f, .5f,-.5f, -1,0,0, 1,0, 1,1,1,1), POS(23,-.5f, .5f, .5f, -1,0,0, 0,0, 1,1,1,1), - }; - uint32_t idx[36]; - for (int i = 0; i < 6; i++) { int b = i*4; idx[i*6]=b; idx[i*6+1]=b+1; idx[i*6+2]=b+2; idx[i*6+3]=b; idx[i*6+4]=b+2; idx[i*6+5]=b+3; } - return create_mesh(dev, v, 24, idx, 36, sizeof(V)); -} - -Mesh* mesh_create_plane(ID3D11Device* dev, float size) { - typedef struct { float p[3], n[3], uv[2], c[4]; } V; - float h = size * 0.5f; - V v[4] = { - {{-h,0,h},{0,1,0},{0,1},{1,1,1,1}}, - {{ h,0,h},{0,1,0},{1,1},{1,1,1,1}}, - {{ h,0,-h},{0,1,0},{1,0},{1,1,1,1}}, - {{-h,0,-h},{0,1,0},{0,0},{1,1,1,1}}, - }; - uint32_t idx[6] = {0,1,2,0,2,3}; - return create_mesh(dev, v, 4, idx, 6, sizeof(V)); -} - -Mesh* mesh_create_sphere(ID3D11Device* dev, float r, int seg) { - typedef struct { float p[3], n[3], uv[2], c[4]; } V; - int vc = (seg+1)*(seg+1); - V* v = (V*)malloc(vc * sizeof(V)); - int vi = 0; - for (int lat = 0; lat <= seg; lat++) { - float theta = 3.14159265f * lat / seg; - float st = sinf(theta), ct = cosf(theta); - for (int lon = 0; lon <= seg; lon++) { - float phi = 2.0f * 3.14159265f * lon / seg; - float sp = sinf(phi), cp = cosf(phi); - float nx = cp*st, ny = ct, nz = sp*st; - v[vi].p[0] = nx*r; v[vi].p[1] = ny*r; v[vi].p[2] = nz*r; - v[vi].n[0] = nx; v[vi].n[1] = ny; v[vi].n[2] = nz; - v[vi].uv[0] = (float)lon/seg; v[vi].uv[1] = (float)lat/seg; - v[vi].c[0]=1; v[vi].c[1]=1; v[vi].c[2]=1; v[vi].c[3]=1; - vi++; - } - } - int ic = seg*seg*6; - uint32_t* idx = (uint32_t*)malloc(ic * sizeof(uint32_t)); - int ii = 0; - for (int lat = 0; lat < seg; lat++) { - for (int lon = 0; lon < seg; lon++) { - uint32_t f = lat*(seg+1)+lon, s = f+seg+1; - idx[ii++]=f; idx[ii++]=s; idx[ii++]=f+1; - idx[ii++]=s; idx[ii++]=s+1; idx[ii++]=f+1; - } - } - Mesh* m = create_mesh(dev, v, vc, idx, ic, sizeof(V)); - free(v); free(idx); - return m; -} - -// OBJ 加载器 -Mesh* mesh_load_obj(ID3D11Device* dev, const char* path) { - FILE* f = fopen(path, "r"); - if (!f) return NULL; - - // 先统计顶点和面数 - int max_v = 4096, max_f = 8192; - float* verts = (float*)malloc(max_v * 3 * sizeof(float)); - float* uvs = (float*)malloc(max_v * 2 * sizeof(float)); - int vert_count = 0, uv_count = 0; - int* face_idx = (int*)malloc(max_f * 3 * sizeof(int)); - int face_count = 0; - - char line[256]; - while (fgets(line, sizeof(line), f)) { - if (line[0] == 'v' && line[1] == ' ') { - float x, y, z; - if (sscanf(line + 2, "%f %f %f", &x, &y, &z) == 3 && vert_count < max_v) { - verts[vert_count * 3] = x; - verts[vert_count * 3 + 1] = y; - verts[vert_count * 3 + 2] = z; - vert_count++; - } - } else if (line[0] == 'v' && line[1] == 't') { - float u, v; - if (sscanf(line + 3, "%f %f", &u, &v) == 2 && uv_count < max_v) { - uvs[uv_count * 2] = u; - uvs[uv_count * 2 + 1] = v; - uv_count++; - } - } else if (line[0] == 'f' && line[1] == ' ') { - // 解析面: f v/vt v/vt v/vt 或 f v v v - int v0, v1, v2; - char* p = line + 2; - v0 = atoi(p) - 1; while (*p && *p != ' ') p++; p++; - v1 = atoi(p) - 1; while (*p && *p != ' ') p++; p++; - v2 = atoi(p) - 1; - if (v0 >= 0 && v1 >= 0 && v2 >= 0 && face_count < max_f) { - face_idx[face_count * 3] = v0; - face_idx[face_count * 3 + 1] = v1; - face_idx[face_count * 3 + 2] = v2; - face_count++; - } - } - } - fclose(f); - - if (vert_count == 0 || face_count == 0) { - free(verts); free(uvs); free(face_idx); - return NULL; - } - - // 构建去重顶点 (简单方案: 每个面一个顶点) - int out_vcount = face_count * 3; - Vertex* out_verts = (Vertex*)calloc(out_vcount, sizeof(Vertex)); - uint32_t* out_idx = (uint32_t*)malloc(face_count * 3 * sizeof(uint32_t)); - - for (int i = 0; i < face_count; i++) { - for (int j = 0; j < 3; j++) { - int vi = face_idx[i * 3 + j]; - int oi = i * 3 + j; - if (vi < vert_count) { - out_verts[oi].pos[0] = verts[vi * 3]; - out_verts[oi].pos[1] = verts[vi * 3 + 1]; - out_verts[oi].pos[2] = verts[vi * 3 + 2]; - } - out_verts[oi].color[0] = out_verts[oi].color[1] = out_verts[oi].color[2] = 1.0f; - out_verts[oi].color[3] = 1.0f; - out_idx[oi] = oi; - } - } - - // 简单法线计算 (面法线) - for (int i = 0; i < face_count; i++) { - float* p0 = out_verts[i * 3].pos; - float* p1 = out_verts[i * 3 + 1].pos; - float* p2 = out_verts[i * 3 + 2].pos; - float e1[3] = {p1[0] - p0[0], p1[1] - p0[1], p1[2] - p0[2]}; - float e2[3] = {p2[0] - p0[0], p2[1] - p0[1], p2[2] - p0[2]}; - float nx = e1[1]*e2[2] - e1[2]*e2[1]; - float ny = e1[2]*e2[0] - e1[0]*e2[2]; - float nz = e1[0]*e2[1] - e1[1]*e2[0]; - float nl = sqrtf(nx*nx + ny*ny + nz*nz); - if (nl > 0.0001f) { nx /= nl; ny /= nl; nz /= nl; } - for (int j = 0; j < 3; j++) { - out_verts[i * 3 + j].norm[0] = nx; - out_verts[i * 3 + j].norm[1] = ny; - out_verts[i * 3 + j].norm[2] = nz; - } - } - - Mesh* m = create_mesh(dev, out_verts, out_vcount, out_idx, face_count * 3, sizeof(Vertex)); - free(out_verts); free(out_idx); free(verts); free(uvs); free(face_idx); - return m; -} diff --git a/Engine/Rendering/mesh.h b/Engine/Rendering/mesh.h deleted file mode 100644 index 1dfc41a..0000000 --- a/Engine/Rendering/mesh.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include -#include - -typedef struct { - float pos[3]; - float norm[3]; - float uv[2]; - float color[4]; -} Vertex; - -typedef struct { - ID3D11Buffer* vb; - ID3D11Buffer* ib; - uint32_t vcount; - uint32_t icount; - uint32_t stride; -} Mesh; - -Mesh* mesh_create_cube(ID3D11Device* dev); -Mesh* mesh_create_plane(ID3D11Device* dev, float size); -Mesh* mesh_create_sphere(ID3D11Device* dev, float r, int seg); -Mesh* mesh_load_obj(ID3D11Device* dev, const char* path); -void mesh_destroy(Mesh* m); -void mesh_draw(Mesh* m, ID3D11DeviceContext* ctx); diff --git a/Engine/Rendering/renderer.c b/Engine/Rendering/renderer.c deleted file mode 100644 index 9504ab2..0000000 --- a/Engine/Rendering/renderer.c +++ /dev/null @@ -1,118 +0,0 @@ -#include "renderer.h" -#include "../Core/logger.h" -#include -#include - -static void fill_constant_buffer(float* cb, const Mat4* world, const Mat4* wvp, - Vec3 light_dir, Vec4 light_color, Vec4 ambient_color, - int use_texture, Vec4 diffuse_color) { - memcpy(cb + 0, world->m, sizeof(float) * 16); - memcpy(cb + 16, wvp->m, sizeof(float) * 16); - cb[32] = light_dir.x; cb[33] = light_dir.y; cb[34] = light_dir.z; cb[35] = 0.0f; - cb[36] = light_color.x; cb[37] = light_color.y; cb[38] = light_color.z; cb[39] = light_color.w; - cb[40] = ambient_color.x; cb[41] = ambient_color.y; cb[42] = ambient_color.z; cb[43] = ambient_color.w; - cb[44] = use_texture ? 1.0f : 0.0f; cb[45] = 0.0f; cb[46] = 0.0f; cb[47] = 0.0f; - cb[48] = diffuse_color.x; cb[49] = diffuse_color.y; cb[50] = diffuse_color.z; cb[51] = diffuse_color.w; -} - -Renderer* renderer_create(GraphicsDevice* device) { - Renderer* r = (Renderer*)calloc(1, sizeof(Renderer)); - r->device = device; - mat4_identity(&r->view); - mat4_identity(&r->projection); - r->light_dir = (Vec3){0.5f, -1.0f, 0.3f}; - r->light_color = (Vec4){1,1,1,1}; - r->ambient_color = (Vec4){0.2f,0.2f,0.3f,1}; - r->clear_color[0] = 0.1f; r->clear_color[1] = 0.1f; - r->clear_color[2] = 0.15f; r->clear_color[3] = 1.0f; - return r; -} - -void renderer_destroy(Renderer* r) { free(r); } - -void renderer_begin_frame(Renderer* r) { - ID3D11DeviceContext* ctx = r->device->context; - graphics_device_clear(r->device, r->clear_color[0], r->clear_color[1], r->clear_color[2], r->clear_color[3]); - D3D11_VIEWPORT vp = {0}; - vp.Width = (float)r->device->width; - vp.Height = (float)r->device->height; - vp.MaxDepth = 1.0f; - ctx->lpVtbl->RSSetViewports(ctx, 1, &vp); - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); -} - -void renderer_end_frame(Renderer* r) { - graphics_device_present(r->device); -} - -void renderer_draw_mesh(Renderer* r, Mesh* m) { - if (!r || !m || m->icount == 0) return; - if (!m->vb) { LOG_ERROR("renderer_draw_mesh: null vertex buffer"); return; } - if (!m->ib) { LOG_ERROR("renderer_draw_mesh: null index buffer"); return; } - ID3D11DeviceContext* ctx = r->device->context; - UINT stride = sizeof(Vertex); - UINT offset = 0; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &m->vb, &stride, &offset); - ctx->lpVtbl->IASetIndexBuffer(ctx, m->ib, DXGI_FORMAT_R32_UINT, 0); - ctx->lpVtbl->DrawIndexed(ctx, m->icount, 0, 0); -} - -void renderer_draw_mesh_with_shader(Renderer* r, Mesh* m, Shader* s, const Mat4* world, Texture* t) { - if (!m || !s || !r) return; - ID3D11DeviceContext* ctx = r->device->context; - shader_bind(s, ctx); - - Mat4 wvp; - mat4_multiply(world, &r->view, &wvp); - mat4_multiply(&wvp, &r->projection, &wvp); - - float cb[64]; - memset(cb, 0, sizeof(cb)); - fill_constant_buffer(cb, world, &wvp, r->light_dir, r->light_color, r->ambient_color, t ? 1 : 0, (Vec4){1,1,1,1}); - - shader_set_matrix(s, ctx, cb); - if (t) texture_bind(t, ctx, 0); - - renderer_draw_mesh(r, m); -} - -void renderer_draw_mesh_with_material(Renderer* r, Mesh* m, Material* mat, const Mat4* world) { - if (!m || !mat || !mat->shader || !r) return; - ID3D11DeviceContext* ctx = r->device->context; - shader_bind(mat->shader, ctx); - - Mat4 wvp; - mat4_multiply(world, &r->view, &wvp); - mat4_multiply(&wvp, &r->projection, &wvp); - - float cb[64]; - memset(cb, 0, sizeof(cb)); - fill_constant_buffer(cb, world, &wvp, r->light_dir, r->light_color, r->ambient_color, - mat->use_texture, mat->color); - - shader_set_matrix(mat->shader, ctx, cb); - if (mat->use_texture && mat->texture) texture_bind(mat->texture, ctx, 0); - - renderer_draw_mesh(r, m); -} - -void renderer_set_view(Renderer* r, const Mat4* v) { r->view = *v; } -void renderer_set_projection(Renderer* r, const Mat4* p) { r->projection = *p; } -void renderer_set_light(Renderer* r, Vec3 d, Vec4 c, Vec4 a) { r->light_dir=d; r->light_color=c; r->ambient_color=a; } -void renderer_set_clear_color(Renderer* r, float rc, float g, float b, float a) { - if (!r) return; - r->clear_color[0] = rc; r->clear_color[1] = g; - r->clear_color[2] = b; r->clear_color[3] = a; -} -GraphicsDevice* renderer_get_device(Renderer* r) { return r ? r->device : NULL; } - -void renderer_get_view_projection(const Renderer* r, Mat4* out) { - if (!r || !out) return; - mat4_multiply(&r->view, &r->projection, out); -} - -void renderer_resize(Renderer* r, int width, int height) { - if (r && r->device && width > 0 && height > 0) { - graphics_device_resize(r->device, width, height); - } -} diff --git a/Engine/Rendering/renderer.h b/Engine/Rendering/renderer.h deleted file mode 100644 index 37fad16..0000000 --- a/Engine/Rendering/renderer.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include "graphics_device.h" -#include "shader.h" -#include "mesh.h" -#include "texture.h" -#include "camera.h" -#include "material.h" -#include "../include/engine_api.h" -#include "../ASM/math_c_fallback.h" - -typedef struct Renderer Renderer; -struct Renderer { - GraphicsDevice* device; - Shader* current_shader; - Mat4 view; - Mat4 projection; - Vec3 light_dir; - Vec4 light_color; - Vec4 ambient_color; - float clear_color[4]; -}; - -Renderer* renderer_create(GraphicsDevice* device); -void renderer_destroy(Renderer* renderer); -void renderer_begin_frame(Renderer* renderer); -void renderer_end_frame(Renderer* renderer); -void renderer_draw_mesh(Renderer* renderer, Mesh* mesh); -void renderer_draw_mesh_with_shader(Renderer* renderer, Mesh* mesh, Shader* shader, const Mat4* world, Texture* tex); -void renderer_draw_mesh_with_material(Renderer* renderer, Mesh* mesh, Material* material, const Mat4* world); -void renderer_set_view(Renderer* renderer, const Mat4* view); -void renderer_set_projection(Renderer* renderer, const Mat4* projection); -void renderer_set_light(Renderer* renderer, Vec3 dir, Vec4 color, Vec4 ambient); -void renderer_set_clear_color(Renderer* renderer, float r, float g, float b, float a); -GraphicsDevice* renderer_get_device(Renderer* renderer); -void renderer_resize(Renderer* renderer, int width, int height); -void renderer_get_view_projection(const Renderer* renderer, Mat4* out); diff --git a/Engine/Rendering/shader.c b/Engine/Rendering/shader.c deleted file mode 100644 index e1c1e60..0000000 --- a/Engine/Rendering/shader.c +++ /dev/null @@ -1,84 +0,0 @@ -#include "shader.h" -#include "../Core/logger.h" -#include -#include -#include - -static const char* default_vs = - "struct VS_IN{float3 pos:POSITION;float3 n:NORMAL;float2 uv:TEXCOORD;float4 col:COLOR;};" - "struct PS_IN{float4 pos:SV_POSITION;float3 world_n:NORMAL;float2 uv:TEXCOORD;float4 col:COLOR;};" - "cbuffer CB:register(b0){float4x4 World;float4x4 WVP;float4 LightDir;float4 LightColor;float4 AmbientColor;float4 UseTexture;float4 DiffuseColor;};" - "PS_IN main(VS_IN i){PS_IN o;o.pos=mul(float4(i.pos,1),WVP);o.world_n=normalize(mul(float4(i.n,0),World).xyz);o.uv=i.uv;o.col=i.col*DiffuseColor;return o;}"; - -static const char* default_ps = - "struct PS_IN{float4 pos:SV_POSITION;float3 world_n:NORMAL;float2 uv:TEXCOORD;float4 col:COLOR;};" - "cbuffer CB:register(b0){float4x4 World;float4x4 WVP;float4 LightDir;float4 LightColor;float4 AmbientColor;float4 UseTexture;float4 DiffuseColor;};" - "Texture2D tex:register(t0);SamplerState samp:register(s0);" - "float4 main(PS_IN i):SV_TARGET{float3 ld=normalize(LightDir.xyz);float diff=saturate(dot(i.world_n,ld));float4 light=AmbientColor+LightColor*diff;float4 albedo=i.col;if(UseTexture.x>0.5)albedo=albedo*tex.Sample(samp,i.uv);return albedo*light;}"; - -static ID3DBlob* compile_shader(const char* code, uint32_t len, const char* target) { - ID3DBlob *blob = NULL, *err = NULL; - UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL3 | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR; - D3DCompile(code, len, NULL, NULL, NULL, "main", target, flags, 0, &blob, &err); - if (err) { - const char* msg = (const char*)err->lpVtbl->GetBufferPointer(err); - LOG_ERROR("Shader compile error (%s): %s", target, msg); - err->lpVtbl->Release(err); - } - return blob; -} - -Shader* shader_create(void) { - return (Shader*)calloc(1, sizeof(Shader)); -} - -void shader_destroy(Shader* s) { - if (!s) return; - if (s->cb) s->cb->lpVtbl->Release(s->cb); - if (s->layout) s->layout->lpVtbl->Release(s->layout); - if (s->ps) s->ps->lpVtbl->Release(s->ps); - if (s->vs) s->vs->lpVtbl->Release(s->vs); - free(s); -} - -int shader_compile(Shader* s, ID3D11Device* dev, const char* vs_code, const char* ps_code, uint32_t vs_len, uint32_t ps_len) { - if (!vs_code || !ps_code) { - vs_code = default_vs; ps_code = default_ps; - vs_len = (uint32_t)strlen(default_vs); ps_len = (uint32_t)strlen(default_ps); - } - ID3DBlob* vs_blob = compile_shader(vs_code, vs_len, "vs_5_0"); - ID3DBlob* ps_blob = compile_shader(ps_code, ps_len, "ps_5_0"); - if (!vs_blob || !ps_blob) { - LOG_ERROR("Failed to compile default shader (vs=%p ps=%p)", (void*)vs_blob, (void*)ps_blob); - if (vs_blob) vs_blob->lpVtbl->Release(vs_blob); - if (ps_blob) ps_blob->lpVtbl->Release(ps_blob); - return 0; - } - dev->lpVtbl->CreateVertexShader(dev, vs_blob->lpVtbl->GetBufferPointer(vs_blob), vs_blob->lpVtbl->GetBufferSize(vs_blob), NULL, &s->vs); - dev->lpVtbl->CreatePixelShader(dev, ps_blob->lpVtbl->GetBufferPointer(ps_blob), ps_blob->lpVtbl->GetBufferSize(ps_blob), NULL, &s->ps); - D3D11_INPUT_ELEMENT_DESC layout[] = { - {"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"NORMAL",0,DXGI_FORMAT_R32G32B32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,24,D3D11_INPUT_PER_VERTEX_DATA,0}, - {"COLOR",0,DXGI_FORMAT_R32G32B32A32_FLOAT,0,32,D3D11_INPUT_PER_VERTEX_DATA,0}, - }; - dev->lpVtbl->CreateInputLayout(dev, layout, 4, vs_blob->lpVtbl->GetBufferPointer(vs_blob), vs_blob->lpVtbl->GetBufferSize(vs_blob), &s->layout); - D3D11_BUFFER_DESC bd = {0}; - bd.ByteWidth = 256; bd.Usage = D3D11_USAGE_DEFAULT; bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - dev->lpVtbl->CreateBuffer(dev, &bd, NULL, &s->cb); - vs_blob->lpVtbl->Release(vs_blob); - ps_blob->lpVtbl->Release(ps_blob); - return 1; -} - -void shader_bind(Shader* s, ID3D11DeviceContext* ctx) { - ctx->lpVtbl->VSSetShader(ctx, s->vs, NULL, 0); - ctx->lpVtbl->PSSetShader(ctx, s->ps, NULL, 0); - ctx->lpVtbl->IASetInputLayout(ctx, s->layout); - ctx->lpVtbl->VSSetConstantBuffers(ctx, 0, 1, &s->cb); - ctx->lpVtbl->PSSetConstantBuffers(ctx, 0, 1, &s->cb); -} - -void shader_set_matrix(Shader* s, ID3D11DeviceContext* ctx, const float* data) { - ctx->lpVtbl->UpdateSubresource(ctx, (ID3D11Resource*)s->cb, 0, NULL, data, 0, 0); -} diff --git a/Engine/Rendering/shader.h b/Engine/Rendering/shader.h deleted file mode 100644 index 00924f3..0000000 --- a/Engine/Rendering/shader.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once -#include -#include - -typedef struct { - ID3D11VertexShader* vs; - ID3D11PixelShader* ps; - ID3D11InputLayout* layout; - ID3D11Buffer* cb; -} Shader; - -Shader* shader_create(void); -void shader_destroy(Shader* s); -int shader_compile(Shader* s, ID3D11Device* dev, const char* vs_code, const char* ps_code, uint32_t vs_len, uint32_t ps_len); -void shader_bind(Shader* s, ID3D11DeviceContext* ctx); -void shader_set_matrix(Shader* s, ID3D11DeviceContext* ctx, const float* data); diff --git a/Engine/Rendering/texture.c b/Engine/Rendering/texture.c deleted file mode 100644 index 3cb964f..0000000 --- a/Engine/Rendering/texture.c +++ /dev/null @@ -1,231 +0,0 @@ -#include "texture.h" - -#include -#include -#include - -#pragma comment(lib, "windowscodecs.lib") - -// 为 MinGW 提供 COM 助手宏(MSVC 已内联提供) -#ifndef _MSC_VER -#define ID3D11ShaderResourceView_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11Texture2D_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11Device_CreateTexture2D(p,a,b,c) (p)->lpVtbl->CreateTexture2D(p,a,b,c) -#define ID3D11Device_CreateShaderResourceView(p,a,b,c) (p)->lpVtbl->CreateShaderResourceView(p,a,b,c) -#define ID3D11DeviceContext_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) -#define ID3D11DeviceContext_PSSetShaderResources(p,a,b,c) (p)->lpVtbl->PSSetShaderResources(p,a,b,c) -#define ID3D11DeviceContext_PSSetSamplers(p,a,b,c) (p)->lpVtbl->PSSetSamplers(p,a,b,c) -#define ID3D11Device_CreateSamplerState(p,a,b) (p)->lpVtbl->CreateSamplerState(p,a,b) - -#define IWICBitmapDecoder_GetFrame(p,a,b) (p)->lpVtbl->GetFrame(p,a,b) -#define IWICBitmapFrameDecode_GetSize(p,a,b) (p)->lpVtbl->GetSize(p,a,b) -#define IWICImagingFactory_CreateFormatConverter(p,a) (p)->lpVtbl->CreateFormatConverter(p,a) -#define IWICFormatConverter_Initialize(p,a,b,c,d,e,f) (p)->lpVtbl->Initialize(p,a,b,c,d,e,f) -#define IWICFormatConverter_CopyPixels(p,a,b,c,d) (p)->lpVtbl->CopyPixels(p,a,b,c,d) -#define IWICFormatConverter_Release(p) (p)->lpVtbl->Release(p) -#define IWICBitmapFrameDecode_Release(p) (p)->lpVtbl->Release(p) -#define IWICImagingFactory_CreateDecoderFromFilename(p,a,b,c,d,e) (p)->lpVtbl->CreateDecoderFromFilename(p,a,b,c,d,e) -#define IWICBitmapDecoder_Release(p) (p)->lpVtbl->Release(p) -#define IWICImagingFactory_CreateStream(p,a) (p)->lpVtbl->CreateStream(p,a) -#define IWICStream_InitializeFromMemory(p,a,b) (p)->lpVtbl->InitializeFromMemory(p,a,b) -#define IWICImagingFactory_CreateDecoderFromStream(p,a,b,c,d) (p)->lpVtbl->CreateDecoderFromStream(p,a,b,c,d) -#define IWICStream_Release(p) (p)->lpVtbl->Release(p) -#endif - -static IWICImagingFactory* wic_factory = NULL; - -static HRESULT ensure_wic(void) { - if (wic_factory) return S_OK; - return CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, - &IID_IWICImagingFactory, (void**)&wic_factory); -} - -Texture* texture_create(void) { - return (Texture*)calloc(1, sizeof(Texture)); -} - -void texture_destroy(Texture* texture) { - if (!texture) return; - if (texture->srv) ID3D11ShaderResourceView_Release(texture->srv); - if (texture->texture) ID3D11Texture2D_Release(texture->texture); - free(texture); -} - -static Texture* create_from_wic(ID3D11Device* device, IWICBitmapDecoder* decoder) { - IWICBitmapFrameDecode* frame = NULL; - IWICBitmapDecoder_GetFrame(decoder, 0, &frame); - - uint32_t w, h; - IWICBitmapFrameDecode_GetSize(frame, &w, &h); - - IWICFormatConverter* converter = NULL; - IWICImagingFactory_CreateFormatConverter(wic_factory, &converter); - IWICFormatConverter_Initialize(converter, (IWICBitmapSource*)frame, - &GUID_WICPixelFormat32bppRGBA, WICBitmapDitherTypeNone, NULL, 0.0, WICBitmapPaletteTypeCustom); - - uint8_t* pixels = (uint8_t*)malloc(w * h * 4); - IWICFormatConverter_CopyPixels(converter, NULL, w * 4, w * h * 4, pixels); - IWICFormatConverter_Release(converter); - IWICBitmapFrameDecode_Release(frame); - - D3D11_TEXTURE2D_DESC desc = {0}; - desc.Width = w; - desc.Height = h; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - - D3D11_SUBRESOURCE_DATA init = {pixels, w * 4, 0}; - - Texture* tex = texture_create(); - ID3D11Device_CreateTexture2D(device, &desc, &init, &tex->texture); - - D3D11_SHADER_RESOURCE_VIEW_DESC srvd = {0}; - srvd.Format = desc.Format; - srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvd.Texture2D.MipLevels = 1; - ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource*)tex->texture, &srvd, &tex->srv); - - tex->width = w; - tex->height = h; - tex->mip_levels = 1; - - free(pixels); - return tex; -} - -Texture* texture_load_from_file(ID3D11Device* device, const char* path) { - if (FAILED(ensure_wic())) return NULL; - - IWICBitmapDecoder* decoder = NULL; - wchar_t wpath[512]; - MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, 512); - - HRESULT hr = IWICImagingFactory_CreateDecoderFromFilename(wic_factory, wpath, NULL, - GENERIC_READ, WICDecodeMetadataCacheOnLoad, &decoder); - if (FAILED(hr)) return NULL; - - Texture* tex = create_from_wic(device, decoder); - IWICBitmapDecoder_Release(decoder); - return tex; -} - -Texture* texture_load_from_memory(ID3D11Device* device, const uint8_t* data, uint32_t size) { - if (FAILED(ensure_wic())) return NULL; - - IWICStream* stream = NULL; - IWICImagingFactory_CreateStream(wic_factory, &stream); - IWICStream_InitializeFromMemory(stream, (BYTE*)data, size); - - IWICBitmapDecoder* decoder = NULL; - IWICImagingFactory_CreateDecoderFromStream(wic_factory, (IStream*)stream, NULL, - WICDecodeMetadataCacheOnLoad, &decoder); - IWICStream_Release(stream); - - if (!decoder) return NULL; - Texture* tex = create_from_wic(device, decoder); - IWICBitmapDecoder_Release(decoder); - return tex; -} - -Texture* texture_create_solid(ID3D11Device* device, uint32_t w, uint32_t h, - uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - uint8_t* pixels = (uint8_t*)malloc(w * h * 4); - for (uint32_t i = 0; i < w * h; i++) { - pixels[i * 4 + 0] = r; - pixels[i * 4 + 1] = g; - pixels[i * 4 + 2] = b; - pixels[i * 4 + 3] = a; - } - - D3D11_TEXTURE2D_DESC desc = {0}; - desc.Width = w; - desc.Height = h; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - - D3D11_SUBRESOURCE_DATA init = {pixels, w * 4, 0}; - - Texture* tex = texture_create(); - ID3D11Device_CreateTexture2D(device, &desc, &init, &tex->texture); - - D3D11_SHADER_RESOURCE_VIEW_DESC srvd = {0}; - srvd.Format = desc.Format; - srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvd.Texture2D.MipLevels = 1; - ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource*)tex->texture, &srvd, &tex->srv); - - tex->width = w; - tex->height = h; - free(pixels); - return tex; -} - -Texture* texture_create_checkerboard(ID3D11Device* device, uint32_t size, uint32_t checks) { - uint8_t* pixels = (uint8_t*)malloc(size * size * 4); - uint32_t cell = size / checks; - for (uint32_t y = 0; y < size; y++) { - for (uint32_t x = 0; x < size; x++) { - uint8_t c = ((x / cell) + (y / cell)) % 2 ? 200 : 55; - uint32_t i = (y * size + x) * 4; - pixels[i] = pixels[i + 1] = pixels[i + 2] = c; - pixels[i + 3] = 255; - } - } - - D3D11_TEXTURE2D_DESC desc = {0}; - desc.Width = size; - desc.Height = size; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - - D3D11_SUBRESOURCE_DATA init = {pixels, size * 4, 0}; - - Texture* tex = texture_create(); - ID3D11Device_CreateTexture2D(device, &desc, &init, &tex->texture); - - D3D11_SHADER_RESOURCE_VIEW_DESC srvd = {0}; - srvd.Format = desc.Format; - srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvd.Texture2D.MipLevels = 1; - ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource*)tex->texture, &srvd, &tex->srv); - - tex->width = size; - tex->height = size; - free(pixels); - return tex; -} - -void texture_bind(Texture* texture, ID3D11DeviceContext* ctx, uint32_t slot) { - if (!texture || !texture->srv) return; - static ID3D11SamplerState* default_sampler = NULL; - if (!default_sampler) { - ID3D11Device* device = NULL; - ctx->lpVtbl->GetDevice(ctx, &device); - if (device) { - D3D11_SAMPLER_DESC sd = {0}; - sd.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; - sd.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; - sd.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; - sd.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; - sd.ComparisonFunc = D3D11_COMPARISON_NEVER; - sd.MinLOD = 0; - sd.MaxLOD = D3D11_FLOAT32_MAX; - device->lpVtbl->CreateSamplerState(device, &sd, &default_sampler); - device->lpVtbl->Release(device); - } - } - ctx->lpVtbl->PSSetShaderResources(ctx, slot, 1, &texture->srv); - ctx->lpVtbl->PSSetSamplers(ctx, slot, 1, &default_sampler); -} diff --git a/Engine/Rendering/texture.h b/Engine/Rendering/texture.h deleted file mode 100644 index a1e5648..0000000 --- a/Engine/Rendering/texture.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -// ============================================================================ -// texture.h - 纹理加载 (WIC) -// ============================================================================ - -#include -#include - -typedef struct { - ID3D11Texture2D* texture; - ID3D11ShaderResourceView* srv; - uint32_t width; - uint32_t height; - uint32_t mip_levels; -} Texture; - -// 创建/销毁 -Texture* texture_create(void); -void texture_destroy(Texture* texture); - -// 从文件加载 -Texture* texture_load_from_file(ID3D11Device* device, const char* path); - -// 从内存加载 -Texture* texture_load_from_memory(ID3D11Device* device, - const uint8_t* data, uint32_t size); - -// 创建纯色纹理 -Texture* texture_create_solid(ID3D11Device* device, uint32_t w, uint32_t h, - uint8_t r, uint8_t g, uint8_t b, uint8_t a); - -// 创建棋盘格 -Texture* texture_create_checkerboard(ID3D11Device* device, uint32_t size, uint32_t checks); - -// 绑定 -void texture_bind(Texture* texture, ID3D11DeviceContext* ctx, uint32_t slot); diff --git a/Engine/Scene/scene_graph.c b/Engine/Scene/scene_graph.c deleted file mode 100644 index b5f55d5..0000000 --- a/Engine/Scene/scene_graph.c +++ /dev/null @@ -1,226 +0,0 @@ -// ============================================================================ -// scene_graph.c - 场景图实现 -// ============================================================================ - -#include "scene_graph.h" -#include -#include -#include - -void scene_init(Scene* scene) { - memset(scene, 0, sizeof(Scene)); - scene->next_id = 1; - // 创建根节点 - scene->root = &scene->nodes[0]; - memset(scene->root, 0, sizeof(SceneNode)); - scene->root->id = scene->next_id++; - strcpy(scene->root->name, "Root"); - scene->root->scale = (Vec3){1, 1, 1}; - scene->root->visible = 1; - scene->root->dirty = 1; - scene->node_count = 1; -} - -void scene_destroy(Scene* scene) { - // 清空子节点引用 (不释放静态数组) - for (int i = 0; i < scene->node_count; i++) { - scene->nodes[i].parent = NULL; - scene->nodes[i].child_count = 0; - } - scene->node_count = 0; -} - -SceneNode* scene_create_node(Scene* scene, const char* name) { - if (scene->node_count >= MAX_NODES) return NULL; - SceneNode* node = &scene->nodes[scene->node_count++]; - memset(node, 0, sizeof(SceneNode)); - node->id = scene->next_id++; - strncpy(node->name, name, 63); - node->scale = (Vec3){1, 1, 1}; - node->visible = 1; - node->dirty = 1; - return node; -} - -void scene_destroy_node(Scene* scene, SceneNode* node) { - if (!node || node == scene->root) return; - // 移除子引用 - if (node->parent) { - scene_remove_child(node->parent, node); - } - // 递归销毁子节点 - while (node->child_count > 0) { - scene_destroy_node(scene, node->children[0]); - } - node->id = 0; // 标记为空 -} - -SceneNode* scene_find_node(Scene* scene, int id) { - for (int i = 0; i < scene->node_count; i++) { - if (scene->nodes[i].id == id) return &scene->nodes[i]; - } - return NULL; -} - -SceneNode* scene_find_by_name(Scene* scene, const char* name) { - for (int i = 0; i < scene->node_count; i++) { - if (strcmp(scene->nodes[i].name, name) == 0) return &scene->nodes[i]; - } - return NULL; -} - -void scene_set_parent(SceneNode* child, SceneNode* parent) { - if (!child || !parent || child == parent) return; - if (child->parent) scene_remove_child(child->parent, child); - child->parent = parent; - if (parent->child_count < MAX_CHILDREN) { - parent->children[parent->child_count++] = child; - } - child->dirty = 1; -} - -void scene_add_child(SceneNode* parent, SceneNode* child) { - scene_set_parent(child, parent); -} - -void scene_remove_child(SceneNode* parent, SceneNode* child) { - if (!parent || !child) return; - for (int i = 0; i < parent->child_count; i++) { - if (parent->children[i] == child) { - parent->children[i] = parent->children[parent->child_count - 1]; - parent->child_count--; - child->parent = NULL; - child->dirty = 1; - return; - } - } -} - -void scene_set_position(SceneNode* node, float x, float y, float z) { - node->position = (Vec3){x, y, z}; - node->dirty = 1; -} - -void scene_set_rotation_euler(SceneNode* node, float rx, float ry, float rz) { - // 欧拉角转四元数 (YXZ 顺序) - float cr = cosf(rx * 0.5f), sr = sinf(rx * 0.5f); - float cp = cosf(ry * 0.5f), sp = sinf(ry * 0.5f); - float cy = cosf(rz * 0.5f), sy = sinf(rz * 0.5f); - node->rotation = (Quat){ - sr * cp * cy - cr * sp * sy, - cr * sp * cy + sr * cp * sy, - cr * cp * sy - sr * sp * cy, - cr * cp * cy + sr * sp * sy - }; - node->dirty = 1; -} - -void scene_set_scale(SceneNode* node, float sx, float sy, float sz) { - node->scale = (Vec3){sx, sy, sz}; - node->dirty = 1; -} - -void scene_set_rotation_quat(SceneNode* node, const Quat* q) { - node->rotation = *q; - node->dirty = 1; -} - -void scene_mark_dirty(SceneNode* node) { - node->dirty = 1; - for (int i = 0; i < node->child_count; i++) { - scene_mark_dirty(node->children[i]); - } -} - -static void update_local_matrix(SceneNode* node) { - // 旋转矩阵 - Mat4 rot; - quat_to_matrix(&node->rotation, &rot); - - // 缩放矩阵 - Mat4 scl; - mat4_identity(&scl); - scl.m[0][0] = node->scale.x; - scl.m[1][1] = node->scale.y; - scl.m[2][2] = node->scale.z; - - // 平移矩阵 - Mat4 trl; - mat4_translate(node->position.x, node->position.y, node->position.z, &trl); - - // local = trl * rot * scl - Mat4 tmp; - mat4_multiply(&rot, &scl, &tmp); - mat4_multiply(&trl, &tmp, &node->local_matrix); -} - -static void update_world_matrices(SceneNode* node) { - if (node->dirty) { - update_local_matrix(node); - if (node->parent) { - mat4_multiply(&node->parent->world_matrix, &node->local_matrix, &node->world_matrix); - } else { - node->world_matrix = node->local_matrix; - } - node->dirty = 0; - } - for (int i = 0; i < node->child_count; i++) { - update_world_matrices(node->children[i]); - } -} - -void scene_update(Scene* scene) { - if (scene->root) { - update_world_matrices(scene->root); - } -} - -void scene_get_world_position(SceneNode* node, Vec3* out) { - out->x = node->world_matrix.m[3][0]; - out->y = node->world_matrix.m[3][1]; - out->z = node->world_matrix.m[3][2]; -} - -void scene_get_world_rotation(SceneNode* node, Quat* out) { - // 从世界矩阵提取四元数 - Mat4 m = node->world_matrix; - float tr = m.m[0][0] + m.m[1][1] + m.m[2][2]; - if (tr > 0) { - float s = 0.5f / sqrtf(tr + 1.0f); - out->w = 0.25f / s; - out->x = (m.m[2][1] - m.m[1][2]) * s; - out->y = (m.m[0][2] - m.m[2][0]) * s; - out->z = (m.m[1][0] - m.m[0][1]) * s; - } else if (m.m[0][0] > m.m[1][1] && m.m[0][0] > m.m[2][2]) { - float s = 2.0f * sqrtf(1.0f + m.m[0][0] - m.m[1][1] - m.m[2][2]); - out->w = (m.m[2][1] - m.m[1][2]) / s; - out->x = 0.25f * s; - out->y = (m.m[0][1] + m.m[1][0]) / s; - out->z = (m.m[0][2] + m.m[2][0]) / s; - } else if (m.m[1][1] > m.m[2][2]) { - float s = 2.0f * sqrtf(1.0f + m.m[1][1] - m.m[0][0] - m.m[2][2]); - out->w = (m.m[0][2] - m.m[2][0]) / s; - out->x = (m.m[0][1] + m.m[1][0]) / s; - out->y = 0.25f * s; - out->z = (m.m[1][2] + m.m[2][1]) / s; - } else { - float s = 2.0f * sqrtf(1.0f + m.m[2][2] - m.m[0][0] - m.m[1][1]); - out->w = (m.m[1][0] - m.m[0][1]) / s; - out->x = (m.m[0][2] + m.m[2][0]) / s; - out->y = (m.m[1][2] + m.m[2][1]) / s; - out->z = 0.25f * s; - } -} - -void scene_get_world_scale(SceneNode* node, Vec3* out) { - // 从世界矩阵提取缩放 (各列向量的长度) - out->x = sqrtf(node->world_matrix.m[0][0] * node->world_matrix.m[0][0] + - node->world_matrix.m[0][1] * node->world_matrix.m[0][1] + - node->world_matrix.m[0][2] * node->world_matrix.m[0][2]); - out->y = sqrtf(node->world_matrix.m[1][0] * node->world_matrix.m[1][0] + - node->world_matrix.m[1][1] * node->world_matrix.m[1][1] + - node->world_matrix.m[1][2] * node->world_matrix.m[1][2]); - out->z = sqrtf(node->world_matrix.m[2][0] * node->world_matrix.m[2][0] + - node->world_matrix.m[2][1] * node->world_matrix.m[2][1] + - node->world_matrix.m[2][2] * node->world_matrix.m[2][2]); -} diff --git a/Engine/Scene/scene_graph.h b/Engine/Scene/scene_graph.h deleted file mode 100644 index 2d06eeb..0000000 --- a/Engine/Scene/scene_graph.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -// ============================================================================ -// scene_graph.h - 场景图: 节点树 + 变换继承 -// ============================================================================ - -#include "../ASM/math_c_fallback.h" -#include - -#define MAX_CHILDREN 64 -#define MAX_NODES 1024 - -// 场景节点 -typedef struct SceneNode { - int id; - char name[64]; - - // 本地变换 - Vec3 position; - Quat rotation; - Vec3 scale; - - // 世界矩阵 (每帧由 scene_update 计算) - Mat4 world_matrix; - Mat4 local_matrix; - - // 层级 - struct SceneNode* parent; - struct SceneNode* children[MAX_CHILDREN]; - int child_count; - - // 标志 - int visible; - int dirty; // 需要重新计算矩阵 - - // 用户数据 - void* user_data; - int user_type; -} SceneNode; - -// 场景 -typedef struct Scene { - SceneNode nodes[MAX_NODES]; - int node_count; - SceneNode* root; - int next_id; -} Scene; - -// 初始化/销毁 -void scene_init(Scene* scene); -void scene_destroy(Scene* scene); - -// 节点管理 -SceneNode* scene_create_node(Scene* scene, const char* name); -void scene_destroy_node(Scene* scene, SceneNode* node); -SceneNode* scene_find_node(Scene* scene, int id); -SceneNode* scene_find_by_name(Scene* scene, const char* name); - -// 层级 -void scene_set_parent(SceneNode* child, SceneNode* parent); -void scene_add_child(SceneNode* parent, SceneNode* child); -void scene_remove_child(SceneNode* parent, SceneNode* child); - -// 变换 -void scene_set_position(SceneNode* node, float x, float y, float z); -void scene_set_rotation_euler(SceneNode* node, float rx, float ry, float rz); -void scene_set_scale(SceneNode* node, float sx, float sy, float sz); -void scene_set_rotation_quat(SceneNode* node, const Quat* q); -void scene_mark_dirty(SceneNode* node); - -// 每帧更新 -void scene_update(Scene* scene); - -// 获取世界变换 -void scene_get_world_position(SceneNode* node, Vec3* out); -void scene_get_world_rotation(SceneNode* node, Quat* out); -void scene_get_world_scale(SceneNode* node, Vec3* out); diff --git a/Engine/Scene/scene_render.c b/Engine/Scene/scene_render.c deleted file mode 100644 index 5d41dba..0000000 --- a/Engine/Scene/scene_render.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "scene_render.h" -#include -#include - -void scene_node_set_mesh_renderer(SceneNode* node, MeshRenderer* renderer) { - if (!node) return; - node->user_type = 1; - node->user_data = renderer; -} - -MeshRenderer* scene_node_get_mesh_renderer(SceneNode* node) { - if (!node || node->user_type != 1) return NULL; - return (MeshRenderer*)node->user_data; -} - -static void scene_render_node_recursive(SceneNode* node, Renderer* r) { - if (!node || !node->visible) return; - - MeshRenderer* mr = scene_node_get_mesh_renderer(node); - if (mr && mr->mesh && mr->material) { - renderer_draw_mesh_with_material(r, mr->mesh, mr->material, &node->world_matrix); - } - - for (int i = 0; i < node->child_count; i++) { - scene_render_node_recursive(node->children[i], r); - } -} - -void scene_render(Scene* scene, Renderer* r) { - if (!scene || !r) return; - scene_render_node_recursive(scene->root, r); -} - -MeshRenderer* mesh_renderer_create(MeshType type, Mesh* mesh, Material* material) { - MeshRenderer* mr = (MeshRenderer*)calloc(1, sizeof(MeshRenderer)); - mr->type = type; - mr->mesh = mesh; - mr->material = material; - mr->path[0] = '\0'; - return mr; -} - -void mesh_renderer_destroy(MeshRenderer* mr) { - if (!mr) return; - if (mr->material) material_destroy(mr->material); - free(mr); -} - -static void destroy_renderers_recursive(SceneNode* node) { - if (!node) return; - MeshRenderer* mr = scene_node_get_mesh_renderer(node); - if (mr) { - mesh_renderer_destroy(mr); - node->user_data = NULL; - node->user_type = 0; - } - for (int i = 0; i < node->child_count; i++) { - destroy_renderers_recursive(node->children[i]); - } -} - -void scene_destroy_renderers(Scene* scene) { - if (!scene) return; - destroy_renderers_recursive(scene->root); -} diff --git a/Engine/Scene/scene_render.h b/Engine/Scene/scene_render.h deleted file mode 100644 index e0c0926..0000000 --- a/Engine/Scene/scene_render.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "scene_graph.h" -#include "../Rendering/renderer.h" -#include "../Rendering/mesh.h" -#include "../Rendering/material.h" -#include "../Rendering/shader.h" -#include "../Rendering/texture.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - MESH_NONE = 0, - MESH_CUBE = 1, - MESH_SPHERE = 2, - MESH_PLANE = 3, - MESH_OBJ = 4 -} MeshType; - -typedef struct { - MeshType type; - Mesh* mesh; - Material* material; - char path[256]; -} MeshRenderer; - -void scene_node_set_mesh_renderer(SceneNode* node, MeshRenderer* renderer); -MeshRenderer* scene_node_get_mesh_renderer(SceneNode* node); - -void scene_render_node(SceneNode* node, Renderer* r); -void scene_render(Scene* scene, Renderer* r); - -MeshRenderer* mesh_renderer_create(MeshType type, Mesh* mesh, Material* material); -void mesh_renderer_destroy(MeshRenderer* mr); -void scene_destroy_renderers(Scene* scene); - -#ifdef __cplusplus -} -#endif diff --git a/Engine/Scene/scene_serialize.c b/Engine/Scene/scene_serialize.c deleted file mode 100644 index d98b913..0000000 --- a/Engine/Scene/scene_serialize.c +++ /dev/null @@ -1,141 +0,0 @@ -#include "scene_serialize.h" -#include "scene_render.h" -#include "../ASM/math_c_fallback.h" -#include -#include -#include -#include - -#ifndef PI -#define PI 3.14159265f -#endif - -static int node_index(Scene* scene, SceneNode* node) { - if (!scene || !node) return -1; - return (int)(node - scene->nodes); -} - -static const char* mesh_type_name(MeshType t) { - switch (t) { - case MESH_CUBE: return "CUBE"; - case MESH_SPHERE: return "SPHERE"; - case MESH_PLANE: return "PLANE"; - case MESH_OBJ: return "OBJ"; - default: return "NONE"; - } -} - -static MeshType parse_mesh_type(const char* s) { - if (!s) return MESH_NONE; - if (strcmp(s, "CUBE") == 0) return MESH_CUBE; - if (strcmp(s, "SPHERE") == 0) return MESH_SPHERE; - if (strcmp(s, "PLANE") == 0) return MESH_PLANE; - if (strcmp(s, "OBJ") == 0) return MESH_OBJ; - return MESH_NONE; -} - -static void write_node(FILE* f, Scene* scene, SceneNode* node) { - if (!node) return; - int parent = (node == scene->root) ? -1 : node_index(scene, node->parent); - MeshRenderer* mr = scene_node_get_mesh_renderer(node); - MeshType type = mr ? mr->type : MESH_NONE; - const char* path = (mr && mr->path[0]) ? mr->path : "-"; - - float ex = 0.0f, ey = 0.0f, ez = 0.0f; - quat_to_euler(&node->rotation, &ex, &ey, &ez); - - fprintf(f, "%s %d %s %s %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\n", - node->name, parent, mesh_type_name(type), path, - node->position.x, node->position.y, node->position.z, - ex * 180.0f / PI, ey * 180.0f / PI, ez * 180.0f / PI, - node->scale.x, node->scale.y, node->scale.z); - - for (int i = 0; i < node->child_count; i++) { - write_node(f, scene, node->children[i]); - } -} - -int scene_save(Scene* scene, const char* path) { - if (!scene || !path) return 0; - FILE* f = fopen(path, "w"); - if (!f) return 0; - fprintf(f, "LITY3D_SCENE 1\n"); - write_node(f, scene, scene->root); - fclose(f); - return 1; -} - -static Mesh* create_mesh_for_type(MeshType type, ID3D11Device* dev, const char* path) { - switch (type) { - case MESH_CUBE: return mesh_create_cube(dev); - case MESH_SPHERE: return mesh_create_sphere(dev, 1.0f, 16); - case MESH_PLANE: return mesh_create_plane(dev, 10.0f); - case MESH_OBJ: return path ? mesh_load_obj(dev, path) : NULL; - default: return NULL; - } -} - -Scene* scene_load(const char* path, ID3D11Device* dev, Shader* default_shader) { - FILE* f = fopen(path, "r"); - if (!f) return NULL; - - char line[512]; - if (!fgets(line, sizeof(line), f)) { fclose(f); return NULL; } - if (strncmp(line, "LITY3D_SCENE", 10) != 0) { fclose(f); return NULL; } - - Scene* scene = (Scene*)malloc(sizeof(Scene)); - if (!scene) { fclose(f); return NULL; } - scene_init(scene); - - int capacity = 64; - SceneNode** nodes = (SceneNode**)malloc(sizeof(SceneNode*) * capacity); - int count = 0; - - while (fgets(line, sizeof(line), f)) { - char name[64]; - char type_str[16]; - char path_str[256]; - int parent_id; - float px, py, pz, degx, degy, degz, sx, sy, sz; - if (sscanf(line, "%63s %d %15s %255s %f %f %f %f %f %f %f %f %f", - name, &parent_id, type_str, path_str, - &px, &py, &pz, °x, °y, °z, &sx, &sy, &sz) != 13) { - continue; - } - - if (count >= capacity) { - capacity *= 2; - nodes = (SceneNode**)realloc(nodes, sizeof(SceneNode*) * capacity); - } - - SceneNode* parent = (parent_id < 0) ? scene->root : nodes[parent_id]; - SceneNode* node = scene_create_node(scene, name); - if (!node) continue; - if (parent) scene_set_parent(node, parent); - - node->position = (Vec3){px, py, pz}; - node->scale = (Vec3){sx, sy, sz}; - quat_from_euler(degx * PI / 180.0f, degy * PI / 180.0f, degz * PI / 180.0f, &node->rotation); - - MeshType type = parse_mesh_type(type_str); - if (type != MESH_NONE) { - const char* mesh_path = (strcmp(path_str, "-") == 0) ? NULL : path_str; - Mesh* mesh = create_mesh_for_type(type, dev, mesh_path); - if (mesh) { - Material* mat = material_create(default_shader, NULL); - MeshRenderer* mr = mesh_renderer_create(type, mesh, mat); - if (mesh_path) strncpy(mr->path, mesh_path, sizeof(mr->path) - 1); - scene_node_set_mesh_renderer(node, mr); - } - } - - nodes[count] = node; - count++; - } - - free(nodes); - fclose(f); - - scene_update(scene); - return scene; -} diff --git a/Engine/Scene/scene_serialize.h b/Engine/Scene/scene_serialize.h deleted file mode 100644 index 5fbac28..0000000 --- a/Engine/Scene/scene_serialize.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "scene_graph.h" -#include "../Rendering/shader.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int scene_save(Scene* scene, const char* path); -Scene* scene_load(const char* path, ID3D11Device* dev, Shader* default_shader); - -#ifdef __cplusplus -} -#endif diff --git a/Engine/Scripting/lity.py b/Engine/Scripting/lity.py deleted file mode 100644 index 59c8f24..0000000 --- a/Engine/Scripting/lity.py +++ /dev/null @@ -1,598 +0,0 @@ -""" -LityPy - lity3d 引擎 Python 脚本库 - -用法: - from lity import * - - scene = Scene("My Game") - player = scene.create("hero", "cube", pos=(0, 1, 0), color=Color.GREEN) - ground = create_ground(scene) - - @scene.on_key("W") - def move_forward(dt): - player.z += 5 * dt - - scene.run() -""" - -import math -import time -import sys -import os -import struct -import json -from dataclasses import dataclass, field -from typing import List, Dict, Tuple, Optional, Callable, Any -from functools import wraps - -# ============================================================================ -# 数学 -# ============================================================================ - -@dataclass -class Vec3: - x: float = 0.0 - y: float = 0.0 - z: float = 0.0 - - def __add__(self, o): return Vec3(self.x+o.x, self.y+o.y, self.z+o.z) - def __sub__(self, o): return Vec3(self.x-o.x, self.y-o.y, self.z-o.z) - def __mul__(self, s): return Vec3(self.x*s, self.y*s, self.z*s) - def __rmul__(self, s): return self * s - def __neg__(self): return Vec3(-self.x, -self.y, -self.z) - def length(self): return math.sqrt(self.x**2 + self.y**2 + self.z**2) - def normalize(self): - l = self.length() - return Vec3(self.x/l, self.y/l, self.z/l) if l > 0.0001 else Vec3() - def dot(self, o): return self.x*o.x + self.y*o.y + self.z*o.z - def cross(self, o): return Vec3(self.y*o.z-self.z*o.y, self.z*o.x-self.x*o.z, self.x*o.y-self.y*o.x) - def lerp(self, o, t): return Vec3(self.x+(o.x-self.x)*t, self.y+(o.y-self.y)*t, self.z+(o.z-self.z)*t) - def distance(self, o): return (self - o).length() - def tuple(self): return (self.x, self.y, self.z) - def __repr__(self): return f"Vec3({self.x:.2f}, {self.y:.2f}, {self.z:.2f})" - -@dataclass -class Color: - r: float = 1.0 - g: float = 1.0 - b: float = 1.0 - a: float = 1.0 - - @classmethod - def from_hex(cls, hex_str): - h = hex_str.lstrip('#') - if len(h) == 6: return cls(int(h[0:2],16)/255, int(h[2:4],16)/255, int(h[4:6],16)/255) - if len(h) == 8: return cls(int(h[0:2],16)/255, int(h[2:4],16)/255, int(h[4:6],16)/255, int(h[6:8],16)/255) - return cls() - - RED = None; GREEN = None; BLUE = None; WHITE = None; BLACK = None - YELLOW = None; CYAN = None; MAGENTA = None; ORANGE = None; GRAY = None - -Color.RED = Color(1, 0.2, 0.15) -Color.GREEN = Color(0.2, 0.8, 0.3) -Color.BLUE = Color(0.2, 0.4, 0.9) -Color.WHITE = Color(1, 1, 1) -Color.BLACK = Color(0.1, 0.1, 0.1) -Color.YELLOW = Color(1, 0.9, 0.2) -Color.CYAN = Color(0.2, 0.8, 0.8) -Color.MAGENTA = Color(0.8, 0.2, 0.8) -Color.ORANGE = Color(1, 0.5, 0.1) -Color.GRAY = Color(0.5, 0.5, 0.5) - -def lerp(a, b, t): return a + (b - a) * t -def clamp(v, lo, hi): return max(lo, min(hi, v)) -def sin_val(v): return math.sin(v) -def cos_val(v): return math.cos(v) -def sqrt_val(v): return math.sqrt(v) -def abs_val(v): return abs(v) -def rand(lo=0, hi=1): import random; return random.uniform(lo, hi) -def rand_int(lo, hi): import random; return random.randint(lo, hi) -def distance(a, b): return (a - b).length() if isinstance(a, Vec3) else abs(a - b) -def time_s(): return time.time() - -# ============================================================================ -# 组件系统 -# ============================================================================ - -@dataclass -class Transform: - position: Vec3 = field(default_factory=Vec3) - rotation: Vec3 = field(default_factory=Vec3) # euler angles in radians - scale: Vec3 = field(default_factory=lambda: Vec3(1, 1, 1)) - - @property - def x(self): return self.position.x - @x.setter - def x(self, v): self.position.x = v - @property - def y(self): return self.position.y - @y.setter - def y(self, v): self.position.y = v - @property - def z(self): return self.position.z - @z.setter - def z(self, v): self.position.z = v - -@dataclass -class MeshRenderer: - mesh_type: str = "cube" - color: Color = field(default_factory=Color) - visible: bool = True - -@dataclass -class RigidBody: - velocity: Vec3 = field(default_factory=Vec3) - mass: float = 1.0 - use_gravity: bool = False - drag: float = 0.98 - -@dataclass -class Collider: - shape: str = "box" # box, sphere - size: Vec3 = field(default_factory=lambda: Vec3(1, 1, 1)) - -@dataclass -class Script: - update: Optional[Callable] = None - on_start: Optional[Callable] = None - on_collision: Optional[Callable] = None - -# ============================================================================ -# Entity -# ============================================================================ - -_next_id = 0 - -class Entity: - def __init__(self, name="entity", mesh="cube", pos=None, color=None, **kwargs): - global _next_id - _next_id += 1 - self.id = _next_id - self.name = name - self.tags: List[str] = kwargs.get("tags", []) - self.active = True - if pos and not isinstance(pos, Vec3): - pos = Vec3(*pos) if isinstance(pos, (list, tuple)) else Vec3(pos, 0, 0) - self.transform = Transform(position=pos or Vec3()) - self.renderer = MeshRenderer(mesh_type=mesh, color=color or Color.WHITE) - self.rigid_body = None - self.collider = None - self.script = None - self.children: List['Entity'] = [] - self.parent: Optional['Entity'] = None - self._props: Dict[str, Any] = {} - - @property - def pos(self): return self.transform.position - @pos.setter - def pos(self, v): - if isinstance(v, (list, tuple)): v = Vec3(*v) - self.transform.position = v - @property - def x(self): return self.transform.position.x - @x.setter - def x(self, v): self.transform.position.x = v - @property - def y(self): return self.transform.position.y - @y.setter - def y(self, v): self.transform.position.y = v - @property - def z(self): return self.transform.position.z - @z.setter - def z(self, v): self.transform.position.z = v - @property - def rot(self): return self.transform.rotation - @rot.setter - def rot(self, v): self.transform.rotation = v if isinstance(v, Vec3) else Vec3(*v) - @property - def scl(self): return self.transform.scale - @scl.setter - def scl(self, v): self.transform.scale = v if isinstance(v, Vec3) else Vec3(*v) - @property - def color(self): return self.renderer.color - @color.setter - def color(self, v): self.renderer.color = v if isinstance(v, Color) else Color(*v) - - def move(self, dx=0, dy=0, dz=0): - self.transform.position = self.transform.position + Vec3(dx, dy, dz) - - def look_at(self, target): - if isinstance(target, Entity): target = target.pos - d = (target - self.pos).normalize() - self.transform.rotation = Vec3(math.atan2(d.z, d.x), 0, 0) - - def add_rigidbody(self, mass=1.0, gravity=False): - self.rigid_body = RigidBody(mass=mass, use_gravity=gravity) - return self - - def add_collider(self, shape="box", size=None): - self.collider = Collider(shape=shape, size=size or Vec3(1, 1, 1)) - return self - - def set_script(self, update=None, on_start=None, on_collision=None): - self.script = Script(update=update, on_start=on_start, on_collision=on_collision) - if on_start: on_start(self) - return self - - def child(self, name, mesh="cube", **kwargs): - e = Entity(name, mesh, **kwargs) - e.parent = self - self.children.append(e) - return e - - def __getitem__(self, key): return self._props.get(key) - def __setitem__(self, key, val): self._props[key] = val - def __contains__(self, tag): return tag in self.tags - -# ============================================================================ -# 场景 -# ============================================================================ - -class Scene: - def __init__(self, title="Lity3D", width=1280, height=720): - self.title = title - self.width = width - self.height = height - self.entities: List[Entity] = [] - self._key_handlers: Dict[int, List[Callable]] = {} - self._key_down_handlers: Dict[int, List[Callable]] = {} - self._frame_handlers: List[Callable] = [] - self._update_handlers: List[Callable] = [] - self._collision_handlers: List[Callable] = [] - self._mouse_handlers: List[Callable] = [] - self._dt = 0.016 - self._time = 0.0 - self._running = False - self._last_time = 0.0 - self._camera_pos = Vec3(0, 5, -10) - self._camera_target = Vec3(0, 0, 0) - self._sky_color = Color(0.15, 0.18, 0.25) - self._gravity = Vec3(0, -9.8, 0) - self._paused = False - self._custom_data: Dict[str, Any] = {} - self._log_file = None - - def create(self, name="entity", mesh="cube", pos=None, color=None, scale=None, **kwargs) -> Entity: - e = Entity(name, mesh, pos=pos, color=color, **kwargs) - if scale: - e.transform.scale = Vec3(*scale) if not isinstance(scale, Vec3) else scale - self.entities.append(e) - return e - - def find(self, name) -> Optional[Entity]: - for e in self.entities: - if e.name == name: return e - return None - - def find_by_tag(self, tag) -> List[Entity]: - return [e for e in self.entities if tag in e.tags] - - def destroy(self, entity): - if entity in self.entities: self.entities.remove(entity) - for c in entity.children: self.destroy(c) - - def destroy_all(self, tag=None): - if tag: self.entities = [e for e in self.entities if tag not in e.tags] - else: self.entities.clear() - - def on_frame(self, func): - self._frame_handlers.append(func) - return func - - def on_update(self, func): - self._update_handlers.append(func) - return func - - def on_key(self, key): - def decorator(func): - if isinstance(key, str): k = ord(key.upper()) - else: k = key - self._key_handlers.setdefault(k, []).append(func) - return func - return decorator - - def on_key_down(self, key): - def decorator(func): - if isinstance(key, str): k = ord(key.upper()) - else: k = key - self._key_down_handlers.setdefault(k, []).append(func) - return func - return decorator - - def on_collision(self, func): - self._collision_handlers.append(func) - return func - - def on_mouse(self, func): - self._mouse_handlers.append(func) - return func - - def log(self, *args): - msg = " ".join(str(a) for a in args) - print(f"[{self._time:.2f}] {msg}") - if self._log_file: - self._log_file.write(f"[{self._time:.2f}] {msg}\n") - self._log_file.flush() - - def save(self, path="scene.json"): - data = [] - for e in self.entities: - d = { - "name": e.name, "mesh": e.renderer.mesh_type, - "pos": e.pos.tuple(), "rot": e.rot.tuple(), "scl": e.scl.tuple(), - "color": (e.color.r, e.color.g, e.color.b, e.color.a), - "visible": e.renderer.visible, "tags": e.tags, - "props": e._props, - } - data.append(d) - with open(path, 'w') as f: json.dump(data, f, indent=2) - self.log(f"Scene saved to {path} ({len(data)} entities)") - - def load(self, path="scene.json"): - if not os.path.exists(path): self.log(f"No {path} found"); return - with open(path, 'r') as f: data = json.load(f) - for d in data: - e = self.create( - d["name"], d.get("mesh", "cube"), - pos=Vec3(*d.get("pos", (0,0,0))), - color=Color(*d.get("color", (1,1,1))), - tags=d.get("tags", []) - ) - e.rot = Vec3(*d.get("rot", (0,0,0))) - e.scl = Vec3(*d.get("scl", (1,1,1))) - e.renderer.visible = d.get("visible", True) - e._props = d.get("props", {}) - self.log(f"Scene loaded from {path} ({len(data)} entities)") - - def run(self, headless=True, duration=None): - self._running = True - self._last_time = time.time() - start = self._last_time - self.log(f"Scene '{self.title}' starting ({len(self.entities)} entities)") - - if headless: - self.log("Running in headless/script mode") - else: - self.log("Running with engine rendering") - - for e in self.entities: - if e.script and e.script.on_start: e.script.on_start(e) - - try: - while self._running: - now = time.time() - self._dt = now - (start if self._time == 0 else self._last_time) - self._last_time = now - self._time += self._dt - - if self._paused: continue - - self._update(self._dt) - - if duration and self._time >= duration: - self.log(f"Duration {duration}s reached") - break - except KeyboardInterrupt: - self.log("Stopped by user") - finally: - self.log(f"Scene ended (ran for {self._time:.2f}s)") - - def stop(self): self._running = False - def pause(self): self._paused = True; self.log("Paused") - def resume(self): self._paused = False; self.log("Resumed") - - def _update(self, dt): - for e in self.entities: - if not e.active: continue - if e.rigid_body and e.rigid_body.use_gravity: - e.rigid_body.velocity = e.rigid_body.velocity + self._gravity * dt - if e.rigid_body: - e.rigid_body.velocity = e.rigid_body.velocity * e.rigid_body.drag - e.pos = e.pos + e.rigid_body.velocity * dt - if e.script and e.script.update: - e.script.update(e, dt) - for c in e.children: - if c.script and c.script.update: - c.script.update(c, dt) - for h in self._update_handlers: h(self, dt) - for h in self._frame_handlers: h(dt) - -# ============================================================================ -# 摄像机 -# ============================================================================ - -class Camera: - def __init__(self, pos=None, target=None, fov=60, near=0.1, far=200): - self.pos = pos or Vec3(0, 5, -10) - self.target = target or Vec3(0, 0, 0) - self.fov = fov - self.near = near - self.far = far - - def follow(self, entity, offset=None, smooth=0.1): - off = offset or Vec3(0, 3, -6) - target = entity.pos + off - self.pos = self.pos.lerp(target, smooth) - self.target = entity.pos - - def orbit(self, center, distance=10, yaw=0, pitch=0.3): - self.pos = Vec3( - center.x + math.sin(yaw) * distance * math.cos(pitch), - center.y + math.sin(pitch) * distance, - center.z + math.cos(yaw) * distance * math.cos(pitch) - ) - self.target = center - -# ============================================================================ -# 物理辅助 -# ============================================================================ - -def physics_raycast(origin, direction, max_dist=100): - return None # placeholder for engine integration - -def physics_overlap(box_a, box_b): - if not box_a.collider or not box_b.collider: return False - ax, ay, az = box_a.pos.x, box_a.pos.y, box_a.pos.z - bx, by, bz = box_b.pos.x, box_b.pos.y, box_b.pos.z - dx = abs(ax - bx) - dy = abs(ay - by) - dz = abs(az - bz) - sx = (box_a.collider.size.x + box_b.collider.size.x) * 0.5 - sy = (box_a.collider.size.y + box_b.collider.size.y) * 0.5 - sz = (box_a.collider.size.z + box_b.collider.size.z) * 0.5 - return dx < sx and dy < sy and dz < sz - -# ============================================================================ -# 预设 -# ============================================================================ - -def create_ground(scene, size=40, color=None): - return scene.create("ground", "plane", pos=Vec3(0, -0.01, 0), - scale=Vec3(size, 1, size), color=color or Color(0.3, 0.5, 0.25)) - -def create_skybox(scene, color=None): - scene._sky_color = color or Color(0.15, 0.18, 0.25) - -def create_tree(scene, x, z, trunk_color=None, leaves_color=None): - trunk = scene.create("trunk", "cube", pos=Vec3(x, 0.5, z), - scale=Vec3(0.2, 1, 0.2), color=trunk_color or Color(0.45, 0.28, 0.15)) - leaves = scene.create("leaves", "sphere", pos=Vec3(x, 1.8, z), - scale=Vec3(0.8, 0.7, 0.8), color=leaves_color or Color(0.15, 0.45, 0.12)) - return trunk, leaves - -def create_building(scene, x, z, w=2, h=2, d=2, wall_color=None, roof_color=None): - wall = scene.create("wall", "cube", pos=Vec3(x, h*0.5, z), - scale=Vec3(w, h, d), color=wall_color or Color(0.8, 0.3, 0.2)) - roof = scene.create("roof", "cube", pos=Vec3(x, h+0.15, z), - scale=Vec3(w+0.3, 0.3, d+0.3), color=roof_color or Color(0.35, 0.35, 0.38)) - return wall, roof - -# ============================================================================ -# 动画/tween -# ============================================================================ - -class Tween: - def __init__(self, entity, prop, target, duration, ease="linear"): - self.entity = entity - self.prop = prop - self.start = getattr(entity, prop) if hasattr(entity, prop) else 0 - self.target = target - self.duration = duration - self.elapsed = 0 - self.done = False - self.ease = ease - - def update(self, dt): - if self.done: return - self.elapsed += dt - t = min(self.elapsed / self.duration, 1.0) - if self.ease == "ease_in": t = t * t - elif self.ease == "ease_out": t = 1 - (1-t)**2 - elif self.ease == "ease_in_out": t = 3*t**2 - 2*t**3 - val = lerp(self.start, self.target, t) - if hasattr(self.entity, self.prop): setattr(self.entity, self.prop, val) - if t >= 1.0: self.done = True - -def tween_to(entity, prop, target, duration=1.0, ease="linear"): - return Tween(entity, prop, target, duration, ease) - -# ============================================================================ -# 序列化/导出 -# ============================================================================ - -def export_scene_ly(scene, path="scene.ly"): - lines = [f"# LityPy exported scene: {scene.title}"] - for e in scene.entities: - p = e.pos - r = e.rot - s = e.scl - c = e.color - lines.append(f'world.create("{e.name}", "{e.renderer.mesh_type}", ' - f'pos=({p.x:.2f},{p.y:.2f},{p.z:.2f}), ' - f'color=({c.r:.2f},{c.g:.2f},{c.b:.2f}))') - with open(path, 'w') as f: - f.write('\n'.join(lines)) - print(f"Exported {len(scene.entities)} entities to {path}") - -# ============================================================================ -# 游戏模板 -# ============================================================================ - -def game_2d_platformer(): - """创建2D平台跳跃游戏模板""" - scene = Scene("2D Platformer", 1280, 720) - player = scene.create("player", "cube", pos=Vec3(0, 1, 0), color=Color.GREEN) - player.add_rigidbody(mass=1.0, gravity=True) - player.add_collider(size=Vec3(0.8, 1.0, 0.8)) - player.speed = 5.0 - player.jump_force = 8.0 - player.grounded = False - - ground = create_ground(scene, 100) - - for i in range(-5, 6): - scene.create(f"platform_{i}", "cube", pos=Vec3(i*3, 0.5, 0), - scale=Vec3(2, 0.3, 2), color=Color.GRAY) - - @scene.on_frame - def update(dt): - scene.log(f"Player at ({player.x:.1f}, {player.y:.1f})") - - return scene - -def game_topdown_rpg(): - """创建俯视角RPG模板""" - scene = Scene("Top-Down RPG") - player = scene.create("player", "cube", pos=Vec3(0, 0, 0), color=Color.GREEN) - player.speed = 5.0 - - create_ground(scene, 60) - for i in range(20): - x, z = rand(-25, 25), rand(-25, 25) - create_tree(scene, x, z) - for i in range(5): - x, z = rand(-15, 15), rand(-15, 15) - create_building(scene, x, z, rand(1.5, 3), rand(1.5, 3), rand(1.5, 3), - wall_color=Color(rand(0.6,1), rand(0.2,0.8), rand(0.1,0.5))) - - return scene - -def game_fps_shooter(): - """创建FPS射击模板""" - scene = Scene("FPS Shooter") - player = scene.create("player", "cube", pos=Vec3(0, 1.7, 0), color=Color.GREEN) - cam = Camera(pos=Vec3(0, 1.7, 0)) - player.speed = 8.0 - - create_ground(scene, 80) - for i in range(30): - x, z = rand(-30, 30), rand(-30, 30) - scene.create(f"target_{i}", "sphere", pos=Vec3(x, 1, z), - color=Color.RED, tags=["enemy"]) - - return scene, cam - -# ============================================================================ -# CLI 入口 -# ============================================================================ - -def run_script(path): - """运行 .py 脚本文件""" - with open(path) as f: - code = f.read() - namespace = {"__name__": "__litypy__", "__file__": path} - exec(compile(code, path, "exec"), namespace) - -if __name__ == "__main__": - if len(sys.argv) > 1: - run_script(sys.argv[1]) - else: - print("LityPy - lity3d 引擎 Python 脚本库") - print("用法: python lity.py ") - print() - print("示例:") - print(" from lity import *") - print(" scene = Scene()") - print(" player = scene.create('hero', 'cube', pos=(0,1,0), color=Color.GREEN)") - print(" create_ground(scene)") - print(" scene.run()") diff --git a/Engine/Scripting/lua_engine.c b/Engine/Scripting/lua_engine.c deleted file mode 100644 index b04eb13..0000000 --- a/Engine/Scripting/lua_engine.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "lua_engine.h" - -#include -#include - -// Lua头文件 (需要单独下载或集成) -// #include -// #include -// #include - -// 由于Lua需要单独集成,这里提供占位实现 -// 实际使用时取消注释并链接Lua库 - -typedef struct lua_State lua_State; - -static lua_State* luaL_newstate(void) { return NULL; } -static void luaL_openlibs(lua_State* L) { (void)L; } -static int luaL_dofile(lua_State* L, const char* fn) { (void)L; (void)fn; return -1; } -static int luaL_dostring(lua_State* L, const char* s) { (void)L; (void)s; return -1; } -static void lua_close(lua_State* L) { (void)L; } - -LuaEngine* lua_engine_create(void) { - return (LuaEngine*)calloc(1, sizeof(LuaEngine)); -} - -void lua_engine_destroy(LuaEngine* engine) { - if (!engine) return; - if (engine->L) lua_close(engine->L); - free(engine); -} - -int lua_engine_init(LuaEngine* engine) { - engine->L = luaL_newstate(); - if (!engine->L) return -1; - luaL_openlibs(engine->L); - engine->initialized = 1; - return 0; -} - -int lua_engine_do_file(LuaEngine* engine, const char* path) { - if (!engine->L) return -1; - return luaL_dofile(engine->L, path); -} - -int lua_engine_do_string(LuaEngine* engine, const char* code) { - if (!engine->L) return -1; - return luaL_dostring(engine->L, code); -} - -void lua_engine_register_function(LuaEngine* engine, const char* name, void* func) { - (void)engine; - (void)name; - (void)func; - // lua_pushcfunction(engine->L, func); - // lua_setglobal(engine->L, name); -} - -lua_State* lua_engine_get_state(LuaEngine* engine) { - return engine->L; -} diff --git a/Engine/Scripting/lua_engine.h b/Engine/Scripting/lua_engine.h deleted file mode 100644 index 2e70d19..0000000 --- a/Engine/Scripting/lua_engine.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -// ============================================================================ -// lua_engine.h - Lua脚本引擎 -// ============================================================================ - -#include - -// 前向声明 -struct lua_State; - -typedef struct { - struct lua_State* L; - int initialized; -} LuaEngine; - -// 创建/销毁 -LuaEngine* lua_engine_create(void); -void lua_engine_destroy(LuaEngine* engine); - -// 初始化 -int lua_engine_init(LuaEngine* engine); - -// 执行 -int lua_engine_do_file(LuaEngine* engine, const char* path); -int lua_engine_do_string(LuaEngine* engine, const char* code); - -// 注册C函数 -void lua_engine_register_function(LuaEngine* engine, const char* name, void* func); - -// 获取状态 -struct lua_State* lua_engine_get_state(LuaEngine* engine); diff --git a/Engine/Terrain/terrain.c b/Engine/Terrain/terrain.c deleted file mode 100644 index 5729bb6..0000000 --- a/Engine/Terrain/terrain.c +++ /dev/null @@ -1,289 +0,0 @@ -#include "terrain.h" -#include -#include -#include - -// ============================================================================ -// 简单的 Value Noise + 叠加 -// ============================================================================ - -float hash_noise(int x, int z, int seed) { - unsigned int n = (unsigned int)x * 374761393u - + (unsigned int)z * 668265263u - + (unsigned int)seed * 1013904223u; - n = (n ^ (n >> 13)) * 1274126177u; - n = n ^ (n >> 16); - return (float)(n & 0x7fffffffu) / (float)0x7fffffffu; -} - -static float smooth_noise(float x, float z, int seed) { - int ix = (int)floorf(x); - int iz = (int)floorf(z); - float fx = x - ix; - float fz = z - iz; - - float v00 = hash_noise(ix, iz, seed); - float v10 = hash_noise(ix + 1, iz, seed); - float v01 = hash_noise(ix, iz + 1, seed); - float v11 = hash_noise(ix + 1, iz + 1, seed); - - float u = fx * fx * (3.0f - 2.0f * fx); - float v = fz * fz * (3.0f - 2.0f * fz); - - float a = v00 + (v10 - v00) * u; - float b = v01 + (v11 - v01) * u; - return a + (b - a) * v; -} - -float fbm_noise(float x, float z, int seed, int octaves, float persistence) { - float total = 0.0f; - float amplitude = 1.0f; - float frequency = 1.0f; - float max_value = 0.0f; - for (int i = 0; i < octaves; i++) { - total += smooth_noise(x * frequency, z * frequency, seed + i * 57) * amplitude; - max_value += amplitude; - amplitude *= persistence; - frequency *= 2.0f; - } - return total / max_value; -} - -// ============================================================================ -// 高度图 -// ============================================================================ - -TerrainConfig terrain_default_config(void) { - TerrainConfig cfg = {0}; - cfg.chunks_x = 4; - cfg.chunks_z = 4; - cfg.vertices_per_chunk = 32; - cfg.chunk_size = 64.0f; - cfg.height_scale = 20.0f; - cfg.uv_scale = 0.1f; - return cfg; -} - -TerrainHeightmap terrain_heightmap_create(int size) { - TerrainHeightmap hm = {0}; - if (size < 2) size = 2; - if (size > TERRAIN_MAX_HEIGHTMAP_SIZE) size = TERRAIN_MAX_HEIGHTMAP_SIZE; - hm.size = size; - hm.data = (float*)calloc(size * size, sizeof(float)); - return hm; -} - -void terrain_heightmap_destroy(TerrainHeightmap* hm) { - if (hm && hm->data) { - free(hm->data); - hm->data = NULL; - hm->size = 0; - } -} - -void terrain_heightmap_fill_noise(TerrainHeightmap* hm, int seed, float scale, float amplitude) { - if (!hm || !hm->data) return; - int s = hm->size; - for (int z = 0; z < s; z++) { - for (int x = 0; x < s; x++) { - float nx = (float)x / (float)(s - 1) * scale; - float nz = (float)z / (float)(s - 1) * scale; - float h = fbm_noise(nx, nz, seed, 6, 0.5f); - hm->data[z * s + x] = h * amplitude; - } - } -} - -float terrain_heightmap_sample(const TerrainHeightmap* hm, float x, float z) { - if (!hm || !hm->data || hm->size < 2) return 0.0f; - int s = hm->size; - float fx = x * (float)(s - 1); - float fz = z * (float)(s - 1); - int ix = (int)floorf(fx); - int iz = (int)floorf(fz); - if (ix < 0) ix = 0; - if (iz < 0) iz = 0; - if (ix >= s - 1) ix = s - 2; - if (iz >= s - 1) iz = s - 2; - float tx = fx - ix; - float tz = fz - iz; - - float h00 = hm->data[iz * s + ix]; - float h10 = hm->data[iz * s + ix + 1]; - float h01 = hm->data[(iz + 1) * s + ix]; - float h11 = hm->data[(iz + 1) * s + ix + 1]; - - float a = h00 + (h10 - h00) * tx; - float b = h01 + (h11 - h01) * tx; - return a + (b - a) * tz; -} - -// ============================================================================ -// 地形网格 -// ============================================================================ - -static Mesh* create_mesh_from_terrain(ID3D11Device* dev, const TerrainHeightmap* hm, - float size, float height_scale, float uv_scale) { - if (!hm || !hm->data || hm->size < 2) return NULL; - int s = hm->size; - int vc = s * s; - int ic = (s - 1) * (s - 1) * 6; - - Vertex* verts = (Vertex*)calloc(vc, sizeof(Vertex)); - uint32_t* idx = (uint32_t*)malloc(ic * sizeof(uint32_t)); - - float half = size * 0.5f; - float step = size / (float)(s - 1); - - for (int z = 0; z < s; z++) { - for (int x = 0; x < s; x++) { - int i = z * s + x; - float px = (float)x * step - half; - float pz = (float)z * step - half; - float py = hm->data[i] * height_scale; - verts[i].pos[0] = px; - verts[i].pos[1] = py; - verts[i].pos[2] = pz; - verts[i].uv[0] = (float)x * uv_scale; - verts[i].uv[1] = (float)z * uv_scale; - verts[i].color[0] = 1.0f; - verts[i].color[1] = 1.0f; - verts[i].color[2] = 1.0f; - verts[i].color[3] = 1.0f; - } - } - - // 计算法线 - memset(verts, 0, vc * sizeof(Vertex)); // 重新初始化法线 - for (int z = 0; z < s; z++) { - for (int x = 0; x < s; x++) { - int i = z * s + x; - float px = (float)x * step - half; - float pz = (float)z * step - half; - float py = hm->data[i] * height_scale; - verts[i].pos[0] = px; - verts[i].pos[1] = py; - verts[i].pos[2] = pz; - verts[i].uv[0] = (float)x * uv_scale; - verts[i].uv[1] = (float)z * uv_scale; - - // 估算法线 - float hl = (x > 0) ? hm->data[z * s + x - 1] * height_scale : py; - float hr = (x < s - 1) ? hm->data[z * s + x + 1] * height_scale : py; - float hd = (z > 0) ? hm->data[(z - 1) * s + x] * height_scale : py; - float hu = (z < s - 1) ? hm->data[(z + 1) * s + x] * height_scale : py; - verts[i].norm[0] = (hl - hr); - verts[i].norm[1] = 2.0f * step; - verts[i].norm[2] = (hd - hu); - - float nx = verts[i].norm[0]; - float ny = verts[i].norm[1]; - float nz = verts[i].norm[2]; - float len = sqrtf(nx * nx + ny * ny + nz * nz); - if (len > 0.0001f) { - verts[i].norm[0] = nx / len; - verts[i].norm[1] = ny / len; - verts[i].norm[2] = nz / len; - } else { - verts[i].norm[0] = 0; - verts[i].norm[1] = 1; - verts[i].norm[2] = 0; - } - - // 根据高度和坡度着色 - float h = hm->data[i]; - float slope = (ny > 0.0001f) ? sqrtf(nx * nx + nz * nz) / ny : 0.0f; - if (h > 0.72f) { - verts[i].color[0] = 0.92f; - verts[i].color[1] = 0.92f; - verts[i].color[2] = 0.95f; - } else if (h > 0.55f || slope > 0.42f) { - verts[i].color[0] = 0.62f; - verts[i].color[1] = 0.60f; - verts[i].color[2] = 0.56f; - } else if (h < 0.18f) { - verts[i].color[0] = 0.82f; - verts[i].color[1] = 0.76f; - verts[i].color[2] = 0.50f; - } else { - verts[i].color[0] = 0.40f; - verts[i].color[1] = 0.68f; - verts[i].color[2] = 0.36f; - } - verts[i].color[3] = 1.0f; - } - } - - int ii = 0; - for (int z = 0; z < s - 1; z++) { - for (int x = 0; x < s - 1; x++) { - uint32_t a = z * s + x; - uint32_t b = z * s + x + 1; - uint32_t c = (z + 1) * s + x; - uint32_t d = (z + 1) * s + x + 1; - idx[ii++] = a; - idx[ii++] = c; - idx[ii++] = b; - idx[ii++] = b; - idx[ii++] = c; - idx[ii++] = d; - } - } - - Mesh* m = (Mesh*)calloc(1, sizeof(Mesh)); - m->vcount = vc; - m->icount = ic; - m->stride = sizeof(Vertex); - - D3D11_BUFFER_DESC bd = {0}; - D3D11_SUBRESOURCE_DATA sd = {0}; - bd.ByteWidth = sizeof(Vertex) * vc; - bd.Usage = D3D11_USAGE_DEFAULT; - bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - sd.pSysMem = verts; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &m->vb); - - bd.ByteWidth = sizeof(uint32_t) * ic; - bd.BindFlags = D3D11_BIND_INDEX_BUFFER; - sd.pSysMem = idx; - dev->lpVtbl->CreateBuffer(dev, &bd, &sd, &m->ib); - - free(verts); - free(idx); - return m; -} - -Mesh* terrain_mesh_create(ID3D11Device* dev, const TerrainHeightmap* hm, float size, float height_scale, float uv_scale) { - return create_mesh_from_terrain(dev, hm, size, height_scale, uv_scale); -} - -// ============================================================================ -// 地形对象 -// ============================================================================ - -Terrain* terrain_create(ID3D11Device* dev, const TerrainConfig* config) { - if (!dev || !config) return NULL; - Terrain* t = (Terrain*)calloc(1, sizeof(Terrain)); - t->config = *config; - t->device = dev; - t->heightmap = terrain_heightmap_create(config->vertices_per_chunk); - terrain_heightmap_fill_noise(&t->heightmap, 12345, 4.0f, 1.0f); - t->mesh = terrain_mesh_create(dev, &t->heightmap, config->chunk_size, config->height_scale, config->uv_scale); - return t; -} - -void terrain_destroy(Terrain* terrain) { - if (!terrain) return; - terrain_heightmap_destroy(&terrain->heightmap); - if (terrain->mesh) mesh_destroy(terrain->mesh); - free(terrain); -} - -float terrain_get_height(const Terrain* terrain, float world_x, float world_z) { - if (!terrain) return 0.0f; - float half = terrain->config.chunk_size * 0.5f; - float local_x = (world_x + half) / terrain->config.chunk_size; - float local_z = (world_z + half) / terrain->config.chunk_size; - float h = terrain_heightmap_sample(&terrain->heightmap, local_x, local_z); - return h * terrain->config.height_scale; -} diff --git a/Engine/Terrain/terrain.h b/Engine/Terrain/terrain.h deleted file mode 100644 index a0a59b4..0000000 --- a/Engine/Terrain/terrain.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -// ============================================================================ -// terrain.h - 程序化地形 -// ============================================================================ - -#include -#include "../Rendering/mesh.h" - -#define TERRAIN_MAX_HEIGHTMAP_SIZE 256 - -typedef struct { - float* data; - int size; -} TerrainHeightmap; - -typedef struct { - int chunks_x; - int chunks_z; - int vertices_per_chunk; - float chunk_size; - float height_scale; - float uv_scale; -} TerrainConfig; - -typedef struct { - TerrainConfig config; - TerrainHeightmap heightmap; - Mesh* mesh; - ID3D11Device* device; -} Terrain; - -// 默认配置 -TerrainConfig terrain_default_config(void); - -// 高度图 -TerrainHeightmap terrain_heightmap_create(int size); -void terrain_heightmap_destroy(TerrainHeightmap* hm); -void terrain_heightmap_fill_noise(TerrainHeightmap* hm, int seed, float scale, float amplitude); -float terrain_heightmap_sample(const TerrainHeightmap* hm, float x, float z); - -// 地形对象 -Terrain* terrain_create(ID3D11Device* dev, const TerrainConfig* config); -void terrain_destroy(Terrain* terrain); - -// 从世界坐标采样高度 (用于相机/角色贴地) -float terrain_get_height(const Terrain* terrain, float world_x, float world_z); - -// 网格生成 -Mesh* terrain_mesh_create(ID3D11Device* dev, const TerrainHeightmap* hm, float size, float height_scale, float uv_scale); - -// 噪声工具(供分块管理器复用) -float hash_noise(int x, int z, int seed); -float fbm_noise(float x, float z, int seed, int octaves, float persistence); diff --git a/Engine/Terrain/terrain_manager.c b/Engine/Terrain/terrain_manager.c deleted file mode 100644 index c40637b..0000000 --- a/Engine/Terrain/terrain_manager.c +++ /dev/null @@ -1,199 +0,0 @@ -#include "terrain_manager.h" -#include "../Rendering/renderer.h" -#include "../Rendering/frustum.h" -#include "../Core/logger.h" -#include -#include - -// ============================================================================ -// 噪声:分块需要世界一致的高度,这里复用 terrain.c 的 hash_noise/fbm_noise -// ============================================================================ - -static float sample_world_height(int seed, float world_x, float world_z, float scale) { - return fbm_noise(world_x * scale, world_z * scale, seed, 6, 0.5f); -} - -static void fill_heightmap_for_chunk(TerrainHeightmap* hm, int seed, int cx, int cz, - float chunk_size, float scale) { - if (!hm || !hm->data) return; - int s = hm->size; - float half = chunk_size * 0.5f; - float step = chunk_size / (float)(s - 1); - float origin_x = (float)cx * chunk_size - half; - float origin_z = (float)cz * chunk_size - half; - - for (int z = 0; z < s; z++) { - for (int x = 0; x < s; x++) { - float wx = origin_x + (float)x * step; - float wz = origin_z + (float)z * step; - hm->data[z * s + x] = sample_world_height(seed, wx, wz, scale); - } - } -} - -static void make_chunk_world_matrix(TerrainChunk* chunk, Mat4* out) { - mat4_identity(out); - out->m[3][0] = (float)chunk->cx * chunk->terrain->config.chunk_size; - out->m[3][1] = 0.0f; - out->m[3][2] = (float)chunk->cz * chunk->terrain->config.chunk_size; -} - -TerrainManager* terrain_manager_create(ID3D11Device* dev, const TerrainConfig* config, Material* base_material) { - if (!dev || !config) return NULL; - TerrainManager* tm = (TerrainManager*)calloc(1, sizeof(TerrainManager)); - tm->config = *config; - tm->device = dev; - tm->base_material = base_material; - tm->load_radius = 3; - tm->seed = 12345; - tm->chunk_count = 0; - return tm; -} - -void terrain_manager_destroy(TerrainManager* tm) { - if (!tm) return; - for (int i = 0; i < tm->chunk_count; i++) { - if (tm->chunks[i].terrain) terrain_destroy(tm->chunks[i].terrain); - } - free(tm); -} - -static int find_chunk_index(TerrainManager* tm, int cx, int cz) { - for (int i = 0; i < tm->chunk_count; i++) { - if (tm->chunks[i].loaded && tm->chunks[i].cx == cx && tm->chunks[i].cz == cz) - return i; - } - return -1; -} - -static TerrainChunk* alloc_chunk_slot(TerrainManager* tm) { - if (tm->chunk_count >= TERRAIN_MAX_CHUNKS) return NULL; - return &tm->chunks[tm->chunk_count++]; -} - -static TerrainChunk* create_chunk(TerrainManager* tm, int cx, int cz) { - TerrainChunk* chunk = alloc_chunk_slot(tm); - if (!chunk) { - LOG_ERROR("Terrain: failed to alloc chunk slot"); - return NULL; - } - - chunk->cx = cx; - chunk->cz = cz; - chunk->terrain = (Terrain*)calloc(1, sizeof(Terrain)); - chunk->terrain->config = tm->config; - chunk->terrain->device = tm->device; - chunk->terrain->heightmap = terrain_heightmap_create(tm->config.vertices_per_chunk); - fill_heightmap_for_chunk(&chunk->terrain->heightmap, tm->seed, cx, cz, - tm->config.chunk_size, 0.015f); - chunk->terrain->mesh = terrain_mesh_create(tm->device, &chunk->terrain->heightmap, - tm->config.chunk_size, - tm->config.height_scale, - tm->config.uv_scale); - chunk->material = tm->base_material; - chunk->loaded = 1; - if (!chunk->terrain->mesh) { - LOG_ERROR("Terrain: chunk mesh create failed at (%d, %d)", cx, cz); - } else { - LOG_INFO("Terrain: created chunk (%d, %d) mesh v=%u i=%u", cx, cz, - chunk->terrain->mesh->vcount, chunk->terrain->mesh->icount); - } - return chunk; -} - -void terrain_manager_update(TerrainManager* tm, Vec3 observer_pos) { - if (!tm) return; - float inv_size = 1.0f / tm->config.chunk_size; - int ox = (int)floorf(observer_pos.x * inv_size + 0.5f); - int oz = (int)floorf(observer_pos.z * inv_size + 0.5f); - static int logged = 0; - if (!logged) { - LOG_INFO("Terrain update: observer=(%.1f,%.1f,%.1f) center_chunk=(%d,%d)", - observer_pos.x, observer_pos.y, observer_pos.z, ox, oz); - logged = 1; - } - - // 标记需要保留 - int keep[TERRAIN_MAX_CHUNKS] = {0}; - - // 加载需要的分块 - int r = tm->load_radius; - for (int z = oz - r; z <= oz + r; z++) { - for (int x = ox - r; x <= ox + r; x++) { - int idx = find_chunk_index(tm, x, z); - if (idx < 0) { - if (create_chunk(tm, x, z)) { - keep[tm->chunk_count - 1] = 1; - } - } else { - keep[idx] = 1; - } - } - } - - // 卸载不需要的分块 - int write = 0; - for (int i = 0; i < tm->chunk_count; i++) { - if (keep[i]) { - tm->chunks[write] = tm->chunks[i]; - write++; - } else { - terrain_destroy(tm->chunks[i].terrain); - } - } - tm->chunk_count = write; -} - -void terrain_manager_render(TerrainManager* tm, Renderer* renderer) { - if (!tm || !renderer) return; - static int logged = 0; - if (!logged) { - LOG_INFO("Terrain render: chunk_count=%d", tm->chunk_count); - logged = 1; - } - - Mat4 vp; - renderer_get_view_projection(renderer, &vp); - Vec4 planes[6]; - frustum_from_matrix(&vp, planes); - - float half = tm->config.chunk_size * 0.5f; - float radius = sqrtf(half * half * 2.0f + - (tm->config.height_scale * 0.5f) * - (tm->config.height_scale * 0.5f)); - float cy = tm->config.height_scale * 0.5f; - - int rendered = 0; - for (int i = 0; i < tm->chunk_count; i++) { - TerrainChunk* c = &tm->chunks[i]; - if (!c->loaded || !c->terrain || !c->terrain->mesh) continue; - - Vec3 center = { (float)c->cx * tm->config.chunk_size, cy, (float)c->cz * tm->config.chunk_size }; - if (!frustum_intersects_sphere(planes, center, radius)) continue; - - Mat4 world; - make_chunk_world_matrix(c, &world); - renderer_draw_mesh_with_material(renderer, c->terrain->mesh, c->material, &world); - rendered++; - } - LOG_INFO("Terrain render: visible_chunks=%d/%d", rendered, tm->chunk_count); -} - -float terrain_manager_get_height(TerrainManager* tm, float world_x, float world_z) { - if (!tm) return 0.0f; - float inv_size = 1.0f / tm->config.chunk_size; - int cx = (int)floorf(world_x * inv_size + 0.5f); - int cz = (int)floorf(world_z * inv_size + 0.5f); - - // 先在已加载分块中查找 - int idx = find_chunk_index(tm, cx, cz); - if (idx >= 0 && tm->chunks[idx].terrain) { - Terrain* t = tm->chunks[idx].terrain; - float local_x = world_x - (float)cx * tm->config.chunk_size; - float local_z = world_z - (float)cz * tm->config.chunk_size; - return terrain_get_height(t, local_x, local_z); - } - - // 回退到直接采样噪声 - return sample_world_height(tm->seed, world_x, world_z, 0.015f) * tm->config.height_scale; -} diff --git a/Engine/Terrain/terrain_manager.h b/Engine/Terrain/terrain_manager.h deleted file mode 100644 index 7a91039..0000000 --- a/Engine/Terrain/terrain_manager.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -// ============================================================================ -// terrain_manager.h - 地形分块流式加载 -// ============================================================================ - -#include "terrain.h" -#include "../Rendering/material.h" -#include "../Rendering/renderer.h" -#include "../ASM/math_c_fallback.h" - -#define TERRAIN_MAX_CHUNKS 64 - -typedef struct { - int cx; - int cz; - Terrain* terrain; - Material* material; - int loaded; -} TerrainChunk; - -typedef struct { - TerrainConfig config; - TerrainChunk chunks[TERRAIN_MAX_CHUNKS]; - int chunk_count; - int load_radius; - int seed; - ID3D11Device* device; - Material* base_material; -} TerrainManager; - -TerrainManager* terrain_manager_create(ID3D11Device* dev, const TerrainConfig* config, Material* base_material); -void terrain_manager_destroy(TerrainManager* tm); - -// 根据观察者位置更新分块 -void terrain_manager_update(TerrainManager* tm, Vec3 observer_pos); - -// 渲染所有已加载分块 -void terrain_manager_render(TerrainManager* tm, Renderer* renderer); - -// 从世界坐标获取地形高度(在所有已加载分块中采样) -float terrain_manager_get_height(TerrainManager* tm, float world_x, float world_z); diff --git a/Engine/UI/ui.c b/Engine/UI/ui.c deleted file mode 100644 index 390519c..0000000 --- a/Engine/UI/ui.c +++ /dev/null @@ -1,401 +0,0 @@ -#include "ui.h" - -#include -#include -#include -#include - -// 为 MinGW 提供 COM 助手宏(MSVC 已内联提供) -#ifndef _MSC_VER -#define ID3D11Device_CreateBuffer(p,a,b,c) (p)->lpVtbl->CreateBuffer(p,a,b,c) -#define ID3D11Device_CreateVertexShader(p,a,b,c,d) (p)->lpVtbl->CreateVertexShader(p,a,b,c,d) -#define ID3D11Device_CreatePixelShader(p,a,b,c,d) (p)->lpVtbl->CreatePixelShader(p,a,b,c,d) -#define ID3D11Device_CreateInputLayout(p,a,b,c,d,e) (p)->lpVtbl->CreateInputLayout(p,a,b,c,d,e) -#define ID3D11Device_CreateBlendState(p,a,b) (p)->lpVtbl->CreateBlendState(p,a,b) -#define ID3D11Device_CreateRasterizerState(p,a,b) (p)->lpVtbl->CreateRasterizerState(p,a,b) -#define ID3D11Device_CreateTexture2D(p,a,b,c) (p)->lpVtbl->CreateTexture2D(p,a,b,c) -#define ID3D11Device_CreateShaderResourceView(p,a,b,c) (p)->lpVtbl->CreateShaderResourceView(p,a,b,c) -#define ID3D11Device_CreateSamplerState(p,a,b) (p)->lpVtbl->CreateSamplerState(p,a,b) - -#define ID3D11RasterizerState_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11BlendState_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11InputLayout_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11PixelShader_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11VertexShader_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11Buffer_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11Texture2D_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11ShaderResourceView_Release(p) (p)->lpVtbl->Release(p) -#define ID3D11SamplerState_Release(p) (p)->lpVtbl->Release(p) -#define ID3D10Blob_Release(p) (p)->lpVtbl->Release(p) -#define ID3D10Blob_GetBufferPointer(p) (p)->lpVtbl->GetBufferPointer(p) -#define ID3D10Blob_GetBufferSize(p) (p)->lpVtbl->GetBufferSize(p) - -#define ID3D11DeviceContext_Map(p,a,b,c,d,e) (p)->lpVtbl->Map(p,a,b,c,d,e) -#define ID3D11DeviceContext_Unmap(p,a,b) (p)->lpVtbl->Unmap(p,a,b) -#define ID3D11DeviceContext_IASetVertexBuffers(p,a,b,c,d,e) (p)->lpVtbl->IASetVertexBuffers(p,a,b,c,d,e) -#define ID3D11DeviceContext_IASetIndexBuffer(p,a,b,c) (p)->lpVtbl->IASetIndexBuffer(p,a,b,c) -#define ID3D11DeviceContext_IASetPrimitiveTopology(p,a) (p)->lpVtbl->IASetPrimitiveTopology(p,a) -#define ID3D11DeviceContext_IASetInputLayout(p,a) (p)->lpVtbl->IASetInputLayout(p,a) -#define ID3D11DeviceContext_VSSetShader(p,a,b,c) (p)->lpVtbl->VSSetShader(p,a,b,c) -#define ID3D11DeviceContext_PSSetShader(p,a,b,c) (p)->lpVtbl->PSSetShader(p,a,b,c) -#define ID3D11DeviceContext_PSSetShaderResources(p,a,b,c) (p)->lpVtbl->PSSetShaderResources(p,a,b,c) -#define ID3D11DeviceContext_PSSetSamplers(p,a,b,c) (p)->lpVtbl->PSSetSamplers(p,a,b,c) -#define ID3D11DeviceContext_OMSetBlendState(p,a,b,c) (p)->lpVtbl->OMSetBlendState(p,a,b,c) -#define ID3D11DeviceContext_RSSetState(p,a) (p)->lpVtbl->RSSetState(p,a) -#define ID3D11DeviceContext_DrawIndexed(p,a,b,c) (p)->lpVtbl->DrawIndexed(p,a,b,c) -#endif - -static const char* ui_vs = R"( -struct VS_INPUT { float2 Pos : POSITION; float2 UV : TEXCOORD0; uint Color : COLOR0; }; -struct VS_OUTPUT { float4 Pos : SV_POSITION; float2 UV : TEXCOORD0; float4 Color : COLOR0; }; -VS_OUTPUT main(VS_INPUT input) { - VS_OUTPUT output; - output.Pos = float4(input.Pos.x, input.Pos.y, 0, 1); - output.UV = input.UV; - output.Color = float4((input.Color & 0xFF) / 255.0, ((input.Color >> 8) & 0xFF) / 255.0, - ((input.Color >> 16) & 0xFF) / 255.0, ((input.Color >> 24) & 0xFF) / 255.0); - return output; -} -)"; - -static const char* ui_ps = R"( -struct PS_INPUT { float4 Pos : SV_POSITION; float2 UV : TEXCOORD0; float4 Color : COLOR0; }; -Texture2D tex : register(t0); -SamplerState samp : register(s0); -float4 main(PS_INPUT input) : SV_TARGET { return input.Color * tex.Sample(samp, input.UV); } -)"; - -#define UI_FONT_COLS 16 -#define UI_FONT_ROWS 8 -#define UI_FONT_CELL_W 16 -#define UI_FONT_CELL_H 16 -#define UI_FONT_ATLAS_W (UI_FONT_COLS * UI_FONT_CELL_W) -#define UI_FONT_ATLAS_H (UI_FONT_ROWS * UI_FONT_CELL_H) - -static int ui_create_font_texture(UI* ui, ID3D11Device* device) { - BITMAPINFO bmi = {0}; - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = UI_FONT_ATLAS_W; - bmi.bmiHeader.biHeight = -UI_FONT_ATLAS_H; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - - HDC hdc = GetDC(NULL); - HDC memdc = CreateCompatibleDC(hdc); - void* bits = NULL; - HBITMAP bmp = CreateDIBSection(memdc, &bmi, DIB_RGB_COLORS, &bits, NULL, 0); - if (!bmp) { - DeleteDC(memdc); - ReleaseDC(NULL, hdc); - return 0; - } - SelectObject(memdc, bmp); - PatBlt(memdc, 0, 0, UI_FONT_ATLAS_W, UI_FONT_ATLAS_H, BLACKNESS); - SetBkColor(memdc, RGB(0, 0, 0)); - SetTextColor(memdc, RGB(255, 255, 255)); - - HFONT font = CreateFont(UI_FONT_CELL_H - 2, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, - DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, - CLEARTYPE_QUALITY, FIXED_PITCH | FF_MODERN, "Consolas"); - if (font) SelectObject(memdc, font); - - for (int i = 32; i < 128; i++) { - int col = i % UI_FONT_COLS; - int row = i / UI_FONT_COLS; - char c = (char)i; - TextOutA(memdc, col * UI_FONT_CELL_W + 1, row * UI_FONT_CELL_H + 1, &c, 1); - - ui->char_uvs[i][0] = (float)(col * UI_FONT_CELL_W) / UI_FONT_ATLAS_W; - ui->char_uvs[i][1] = (float)(row * UI_FONT_CELL_H) / UI_FONT_ATLAS_H; - ui->char_uvs[i][2] = (float)((col + 1) * UI_FONT_CELL_W) / UI_FONT_ATLAS_W; - ui->char_uvs[i][3] = (float)((row + 1) * UI_FONT_CELL_H) / UI_FONT_ATLAS_H; - } - - // 将亮度转为 alpha,文字存储为白色 - uint32_t* pixels = (uint32_t*)bits; - for (int i = 0; i < UI_FONT_ATLAS_W * UI_FONT_ATLAS_H; i++) { - uint32_t p = pixels[i]; - uint8_t b = (uint8_t)(p & 0xFF); - uint8_t g = (uint8_t)((p >> 8) & 0xFF); - uint8_t r = (uint8_t)((p >> 16) & 0xFF); - uint8_t lum = (uint8_t)((r * 77 + g * 150 + b * 29) >> 8); - pixels[i] = 0x00FFFFFF | ((uint32_t)lum << 24); - } - // 左上角像素保留为纯白,供纯色矩形采样 - pixels[0] = 0xFFFFFFFF; - - D3D11_TEXTURE2D_DESC desc = {0}; - desc.Width = UI_FONT_ATLAS_W; - desc.Height = UI_FONT_ATLAS_H; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_IMMUTABLE; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - - D3D11_SUBRESOURCE_DATA init = {0}; - init.pSysMem = bits; - init.SysMemPitch = UI_FONT_ATLAS_W * 4; - - ID3D11Texture2D* tex = NULL; - HRESULT hr = ID3D11Device_CreateTexture2D(device, &desc, &init, &tex); - if (SUCCEEDED(hr) && tex) { - ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource*)tex, NULL, &ui->font_srv); - ID3D11Texture2D_Release(tex); - } - - D3D11_SAMPLER_DESC sd = {0}; - sd.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - sd.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; - sd.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; - sd.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; - ID3D11Device_CreateSamplerState(device, &sd, &ui->font_sampler); - - if (font) DeleteObject(font); - DeleteObject(bmp); - DeleteDC(memdc); - ReleaseDC(NULL, hdc); - - return ui->font_srv != NULL && ui->font_sampler != NULL; -} - -UI* ui_create(ID3D11Device* device) { - UI* ui = (UI*)calloc(1, sizeof(UI)); - ui->font_size = 14.0f; - ui->text_color = 0xFFFFFFFF; - ui->bg_color = 0xFF333333; - ui->border_color = 0xFF666666; - ui->padding = 4.0f; - - D3D11_BUFFER_DESC vbd = {0}; - vbd.ByteWidth = sizeof(UIVertex) * UI_MAX_VERTICES; - vbd.Usage = D3D11_USAGE_DYNAMIC; - vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER; - vbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - ID3D11Device_CreateBuffer(device, &vbd, NULL, &ui->vertex_buffer); - - D3D11_BUFFER_DESC ibd = {0}; - ibd.ByteWidth = sizeof(uint32_t) * UI_MAX_INDICES; - ibd.Usage = D3D11_USAGE_DYNAMIC; - ibd.BindFlags = D3D11_BIND_INDEX_BUFFER; - ibd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - ID3D11Device_CreateBuffer(device, &ibd, NULL, &ui->index_buffer); - - // 编译着色器 - ID3DBlob* vs_blob = NULL, *ps_blob = NULL, *err = NULL; - D3DCompile(ui_vs, strlen(ui_vs), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &vs_blob, &err); - D3DCompile(ui_ps, strlen(ui_ps), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &ps_blob, &err); - - if (vs_blob && ps_blob) { - ID3D11Device_CreateVertexShader(device, ID3D10Blob_GetBufferPointer(vs_blob), - ID3D10Blob_GetBufferSize(vs_blob), NULL, &ui->vertex_shader); - ID3D11Device_CreatePixelShader(device, ID3D10Blob_GetBufferPointer(ps_blob), - ID3D10Blob_GetBufferSize(ps_blob), NULL, &ui->pixel_shader); - - D3D11_INPUT_ELEMENT_DESC layout[] = { - {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0}, - }; - ID3D11Device_CreateInputLayout(device, layout, 3, - ID3D10Blob_GetBufferPointer(vs_blob), ID3D10Blob_GetBufferSize(vs_blob), &ui->input_layout); - ID3D10Blob_Release(vs_blob); - ID3D10Blob_Release(ps_blob); - } - - D3D11_BLEND_DESC bd = {0}; - bd.RenderTarget[0].BlendEnable = TRUE; - bd.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - bd.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - bd.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - bd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - bd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - bd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - ID3D11Device_CreateBlendState(device, &bd, &ui->blend_state); - - D3D11_RASTERIZER_DESC rd = {0}; - rd.FillMode = D3D11_FILL_SOLID; - rd.CullMode = D3D11_CULL_NONE; - rd.ScissorEnable = TRUE; - ID3D11Device_CreateRasterizerState(device, &rd, &ui->rasterizer); - - ui_create_font_texture(ui, device); - - return ui; -} - -void ui_destroy(UI* ui) { - if (!ui) return; - if (ui->font_sampler) ID3D11SamplerState_Release(ui->font_sampler); - if (ui->font_srv) ID3D11ShaderResourceView_Release(ui->font_srv); - if (ui->rasterizer) ID3D11RasterizerState_Release(ui->rasterizer); - if (ui->blend_state) ID3D11BlendState_Release(ui->blend_state); - if (ui->input_layout) ID3D11InputLayout_Release(ui->input_layout); - if (ui->pixel_shader) ID3D11PixelShader_Release(ui->pixel_shader); - if (ui->vertex_shader) ID3D11VertexShader_Release(ui->vertex_shader); - if (ui->index_buffer) ID3D11Buffer_Release(ui->index_buffer); - if (ui->vertex_buffer) ID3D11Buffer_Release(ui->vertex_buffer); - free(ui); -} - -void ui_begin(UI* ui, float mx, float my, int md, int mp, int mr) { - ui->mouse_x = mx; - ui->mouse_y = my; - ui->mouse_down = md; - ui->mouse_pressed = mp; - ui->mouse_released = mr; - ui->vertex_count = 0; - ui->index_count = 0; -} - -void ui_end(UI* ui) { - (void)ui; -} - -void ui_draw_rect(UI* ui, float x, float y, float w, float h, uint32_t color) { - uint32_t base = ui->vertex_count; - // UV 指向字体图集左上角纯白像素,使纯色矩形不受纹理内容影响 - ui->vertices[ui->vertex_count++] = (UIVertex){x, y, 0.0f, 0.0f, color}; - ui->vertices[ui->vertex_count++] = (UIVertex){x + w, y, 0.0f, 0.0f, color}; - ui->vertices[ui->vertex_count++] = (UIVertex){x + w, y + h, 0.0f, 0.0f, color}; - ui->vertices[ui->vertex_count++] = (UIVertex){x, y + h, 0.0f, 0.0f, color}; - ui->indices[ui->index_count++] = base; - ui->indices[ui->index_count++] = base + 1; - ui->indices[ui->index_count++] = base + 2; - ui->indices[ui->index_count++] = base; - ui->indices[ui->index_count++] = base + 2; - ui->indices[ui->index_count++] = base + 3; -} - -void ui_draw_text(UI* ui, float x, float y, const char* text, uint32_t color) { - if (!text) return; - float px = x; - float py = y; - const float cw = (float)UI_FONT_CELL_W; - const float ch = (float)UI_FONT_CELL_H; - while (*text) { - unsigned char c = (unsigned char)*text++; - if (c < 32 || c >= 128) c = '?'; - float u1 = ui->char_uvs[c][0]; - float v1 = ui->char_uvs[c][1]; - float u2 = ui->char_uvs[c][2]; - float v2 = ui->char_uvs[c][3]; - - uint32_t base = ui->vertex_count; - ui->vertices[ui->vertex_count++] = (UIVertex){px, py, u1, v1, color}; - ui->vertices[ui->vertex_count++] = (UIVertex){px + cw, py, u2, v1, color}; - ui->vertices[ui->vertex_count++] = (UIVertex){px + cw, py + ch, u2, v2, color}; - ui->vertices[ui->vertex_count++] = (UIVertex){px, py + ch, u1, v2, color}; - ui->indices[ui->index_count++] = base; - ui->indices[ui->index_count++] = base + 1; - ui->indices[ui->index_count++] = base + 2; - ui->indices[ui->index_count++] = base; - ui->indices[ui->index_count++] = base + 2; - ui->indices[ui->index_count++] = base + 3; - px += cw; - } -} - -void ui_draw_rect_border(UI* ui, float x, float y, float w, float h, - uint32_t fill, uint32_t border, float thickness) { - ui_draw_rect(ui, x, y, w, h, fill); - ui_draw_rect(ui, x, y, w, thickness, border); - ui_draw_rect(ui, x, y + h - thickness, w, thickness, border); - ui_draw_rect(ui, x, y, thickness, h, border); - ui_draw_rect(ui, x + w - thickness, y, thickness, h, border); -} - -int ui_button(UI* ui, float x, float y, float w, float h, const char* text) { - int hover = ui->mouse_x >= x && ui->mouse_x <= x + w && - ui->mouse_y >= y && ui->mouse_y <= y + h; - uint32_t color = hover ? 0xFF555555 : 0xFF444444; - if (hover && ui->mouse_pressed) color = 0xFF666666; - ui_draw_rect_border(ui, x, y, w, h, color, 0xFF888888, 1); - if (text) { - float tx = x + ui->padding; - float ty = y + (h - UI_FONT_CELL_H) * 0.5f; - ui_draw_text(ui, tx, ty, text, ui->text_color); - } - return hover && ui->mouse_pressed; -} - -float ui_slider(UI* ui, float x, float y, float w, float h, float value, float min_val, float max_val) { - ui_draw_rect_border(ui, x, y, w, h, 0xFF333333, 0xFF666666, 1); - - int hover = ui->mouse_x >= x && ui->mouse_x <= x + w && - ui->mouse_y >= y && ui->mouse_y <= y + h; - if (hover && ui->mouse_down) { - float t = (ui->mouse_x - x) / w; - value = min_val + t * (max_val - min_val); - if (value < min_val) value = min_val; - if (value > max_val) value = max_val; - } - - float knob_x = x + ((value - min_val) / (max_val - min_val)) * (w - h); - ui_draw_rect(ui, knob_x, y, h, h, 0xFF0078D4); - return value; -} - -int ui_checkbox(UI* ui, float x, float y, const char* text, int checked) { - float s = 16.0f; - ui_draw_rect_border(ui, x, y, s, s, checked ? 0xFF0078D4 : 0xFF333333, 0xFF666666, 1); - if (checked) { - // 绘制对勾 - ui_draw_rect(ui, x + 4, y + 7, 2, 2, 0xFFFFFFFF); - ui_draw_rect(ui, x + 6, y + 9, 2, 2, 0xFFFFFFFF); - ui_draw_rect(ui, x + 8, y + 5, 5, 2, 0xFFFFFFFF); - } - if (text) { - ui_draw_text(ui, x + s + ui->padding, y + (s - UI_FONT_CELL_H) * 0.5f, text, ui->text_color); - } - if (ui->mouse_x >= x && ui->mouse_x <= x + s && - ui->mouse_y >= y && ui->mouse_y <= y + s && ui->mouse_pressed) { - return !checked; - } - return checked; -} - -void ui_label(UI* ui, float x, float y, const char* text) { - if (text) { - ui_draw_text(ui, x, y, text, ui->text_color); - } -} - -void ui_render(UI* ui, ID3D11DeviceContext* ctx) { - if (ui->vertex_count == 0) return; - - D3D11_MAPPED_SUBRESOURCE mapped; - if (SUCCEEDED(ID3D11DeviceContext_Map(ctx, (ID3D11Resource*)ui->vertex_buffer, 0, - D3D11_MAP_WRITE_DISCARD, 0, &mapped))) { - memcpy(mapped.pData, ui->vertices, sizeof(UIVertex) * ui->vertex_count); - ID3D11DeviceContext_Unmap(ctx, (ID3D11Resource*)ui->vertex_buffer, 0); - } - if (SUCCEEDED(ID3D11DeviceContext_Map(ctx, (ID3D11Resource*)ui->index_buffer, 0, - D3D11_MAP_WRITE_DISCARD, 0, &mapped))) { - memcpy(mapped.pData, ui->indices, sizeof(uint32_t) * ui->index_count); - ID3D11DeviceContext_Unmap(ctx, (ID3D11Resource*)ui->index_buffer, 0); - } - - UINT stride = sizeof(UIVertex); - UINT offset = 0; - ID3D11DeviceContext_IASetVertexBuffers(ctx, 0, 1, &ui->vertex_buffer, &stride, &offset); - ID3D11DeviceContext_IASetIndexBuffer(ctx, ui->index_buffer, DXGI_FORMAT_R32_UINT, 0); - ID3D11DeviceContext_IASetPrimitiveTopology(ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D11DeviceContext_IASetInputLayout(ctx, ui->input_layout); - - ID3D11DeviceContext_VSSetShader(ctx, ui->vertex_shader, NULL, 0); - ID3D11DeviceContext_PSSetShader(ctx, ui->pixel_shader, NULL, 0); - ID3D11DeviceContext_PSSetShaderResources(ctx, 0, 1, &ui->font_srv); - ID3D11DeviceContext_PSSetSamplers(ctx, 0, 1, &ui->font_sampler); - - float blend[4] = {1, 1, 1, 1}; - ID3D11DeviceContext_OMSetBlendState(ctx, ui->blend_state, blend, 0xFFFFFFFF); - ID3D11DeviceContext_RSSetState(ctx, ui->rasterizer); - - ID3D11DeviceContext_DrawIndexed(ctx, ui->index_count, 0, 0); - - ID3D11DeviceContext_OMSetBlendState(ctx, NULL, blend, 0xFFFFFFFF); - ID3D11DeviceContext_RSSetState(ctx, NULL); -} diff --git a/Engine/UI/ui.h b/Engine/UI/ui.h deleted file mode 100644 index 091a173..0000000 --- a/Engine/UI/ui.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -// ============================================================================ -// ui.h - 立即模式UI -// ============================================================================ - -#include -#include - -#define UI_MAX_VERTICES 16384 -#define UI_MAX_INDICES 32768 -#define UI_MAX_WIDGETS 256 - -typedef struct { - float x, y; - float u, v; - uint32_t color; -} UIVertex; - -typedef struct { - float x, y, w, h; - uint32_t color; - int visible; -} UIRect; - -typedef struct { - ID3D11Buffer* vertex_buffer; - ID3D11Buffer* index_buffer; - ID3D11VertexShader* vertex_shader; - ID3D11PixelShader* pixel_shader; - ID3D11InputLayout* input_layout; - ID3D11BlendState* blend_state; - ID3D11RasterizerState* rasterizer; - ID3D11ShaderResourceView* font_srv; - ID3D11SamplerState* font_sampler; - - UIVertex vertices[UI_MAX_VERTICES]; - uint32_t indices[UI_MAX_INDICES]; - uint32_t vertex_count; - uint32_t index_count; - - float mouse_x, mouse_y; - int mouse_down; - int mouse_pressed; - int mouse_released; - - float font_size; - uint32_t text_color; - uint32_t bg_color; - uint32_t border_color; - float padding; - - float char_uvs[128][4]; -} UI; - -// 创建/销毁 -UI* ui_create(ID3D11Device* device); -void ui_destroy(UI* ui); - -// 帧操作 -void ui_begin(UI* ui, float mouse_x, float mouse_y, int mouse_down, int mouse_pressed, int mouse_released); -void ui_end(UI* ui); -void ui_render(UI* ui, ID3D11DeviceContext* ctx); - -// 基础绘制 -void ui_draw_rect(UI* ui, float x, float y, float w, float h, uint32_t color); -void ui_draw_rect_border(UI* ui, float x, float y, float w, float h, uint32_t fill, uint32_t border, float thickness); -void ui_draw_text(UI* ui, float x, float y, const char* text, uint32_t color); - -// 控件 -int ui_button(UI* ui, float x, float y, float w, float h, const char* text); -float ui_slider(UI* ui, float x, float y, float w, float h, float value, float min_val, float max_val); -int ui_checkbox(UI* ui, float x, float y, const char* text, int checked); -void ui_label(UI* ui, float x, float y, const char* text); diff --git a/Engine/VisualScript/block_core.c b/Engine/VisualScript/block_core.c deleted file mode 100644 index acfd2ec..0000000 --- a/Engine/VisualScript/block_core.c +++ /dev/null @@ -1,159 +0,0 @@ -// ============================================================================ -// block_core.c - 积木核心操作 -// ============================================================================ - -#include "block_core.h" -#include -#include - -// 创建积木 -Block* block_create(BlockType type, float x, float y) { - Block* block = (Block*)calloc(1, sizeof(Block)); - if (!block) return NULL; - - block->type = type; - block->x = x; - block->y = y; - block->width = 200; - block->height = 60; - - // 初始化槽位 - block->input_count = 0; - block->output_count = 0; - - for (int i = 0; i < MAX_BLOCK_INPUTS; i++) { - block->inputs[i].owner = block; - block->inputs[i].id = i; - } - for (int i = 0; i < MAX_BLOCK_OUTPUTS; i++) { - block->outputs[i].owner = block; - block->outputs[i].id = i; - } - - return block; -} - -// 复制积木 (深拷贝,不复制连接关系) -Block* block_copy(const Block* src) { - if (!src) return NULL; - Block* block = (Block*)malloc(sizeof(Block)); - if (!block) return NULL; - memcpy(block, src, sizeof(Block)); - - // 重新设置拥有者,断开所有连接 - for (int i = 0; i < MAX_BLOCK_INPUTS; i++) { - block->inputs[i].owner = block; - block->inputs[i].connected = NULL; - } - for (int i = 0; i < MAX_BLOCK_OUTPUTS; i++) { - block->outputs[i].owner = block; - block->outputs[i].connected = NULL; - } - block->next = NULL; - block->parent_if = NULL; - block->workspace = NULL; - block->user_data = NULL; - - return block; -} - -// 销毁积木 -void block_destroy(Block* block) { - if (!block) return; - free(block); -} - -// 添加输入槽位 -BlockSlot* block_add_input(Block* block, SlotKind kind, SlotValueType value_type, const char* label) { - if (block->input_count >= MAX_BLOCK_INPUTS) return NULL; - - BlockSlot* slot = &block->inputs[block->input_count]; - slot->kind = kind; - slot->value_type = value_type; - if (label) strncpy(slot->label, label, MAX_BLOCK_LABEL - 1); - slot->value.type = value_type; - - block->input_count++; - return slot; -} - -// 添加输出槽位 -BlockSlot* block_add_output(Block* block, SlotKind kind, SlotValueType value_type, const char* label) { - if (block->output_count >= MAX_BLOCK_OUTPUTS) return NULL; - - BlockSlot* slot = &block->outputs[block->output_count]; - slot->kind = kind; - slot->value_type = value_type; - if (label) strncpy(slot->label, label, MAX_BLOCK_LABEL - 1); - - block->output_count++; - return slot; -} - -// 连接两个槽位 -bool block_connect(BlockSlot* from, BlockSlot* to) { - if (!from || !to) return false; - if (from->owner == to->owner) return false; // 不能自连 - - // 断开旧连接 - if (from->connected) from->connected->connected = NULL; - if (to->connected) to->connected->connected = NULL; - - from->connected = to; - to->connected = from; - return true; -} - -// 断开槽位 -void block_disconnect(BlockSlot* slot) { - if (!slot || !slot->connected) return; - slot->connected->connected = NULL; - slot->connected = NULL; -} - -// 检查槽位是否已连接 -bool block_slot_connected(BlockSlot* slot) { - return slot && slot->connected != NULL; -} - -// 获取槽位的值 -SlotValue block_slot_get_value(BlockSlot* slot) { - if (!slot) { - SlotValue empty = {0}; - return empty; - } - - // 如果有连接,从连接的积木获取值 - if (slot->connected && slot->connected->owner) { - Block* source = slot->connected->owner; - // 从源积木的输出槽位获取值 - for (int i = 0; i < source->output_count; i++) { - if (&source->outputs[i] == slot->connected) { - return source->outputs[i].value; - } - } - } - - return slot->value; -} - -// 设置槽位的值 -void block_slot_set_value(BlockSlot* slot, SlotValue value) { - if (slot) slot->value = value; -} - -// 积木是否包含点 -bool block_contains_point(Block* block, float px, float py) { - return px >= block->x && px <= block->x + block->width - && py >= block->y && py <= block->y + block->height; -} - -// 获取槽位的世界位置 -void block_slot_world_pos(BlockSlot* slot, float* wx, float* wy) { - if (!slot || !slot->owner) { - *wx = 0; *wy = 0; - return; - } - *wx = slot->owner->x + slot->x; - *wy = slot->owner->y + slot->y; -} diff --git a/Engine/VisualScript/block_core.h b/Engine/VisualScript/block_core.h deleted file mode 100644 index 1f1a530..0000000 --- a/Engine/VisualScript/block_core.h +++ /dev/null @@ -1,183 +0,0 @@ -#pragma once - -// ============================================================================ -// block_core.h - 积木核心数据结构 -// ============================================================================ - -#include -#include - -#define MAX_BLOCK_INPUTS 8 -#define MAX_BLOCK_OUTPUTS 8 -#define MAX_BLOCK_LABEL 64 - -// 颜色 -typedef struct { - float r, g, b, a; -} Color; - -typedef Color BlockColor; - -// 预定义颜色 -#define BLOCK_COLOR_EVENT {0.9f, 0.2f, 0.2f, 1.0f} // 红 -#define BLOCK_COLOR_ACTION {0.2f, 0.5f, 0.9f, 1.0f} // 蓝 -#define BLOCK_COLOR_CONTROL {0.2f, 0.7f, 0.3f, 1.0f} // 绿 -#define BLOCK_COLOR_OPERATOR {0.9f, 0.6f, 0.1f, 1.0f} // 橙 -#define BLOCK_COLOR_VARIABLE {0.7f, 0.3f, 0.8f, 1.0f} // 紫 -#define BLOCK_COLOR_FUNCTION {0.9f, 0.8f, 0.2f, 1.0f} // 黄 -#define BLOCK_COLOR_DATA {0.4f, 0.7f, 0.9f, 1.0f} // 浅蓝 - -// 槽位值类型 -typedef enum { - SLOT_VALUE_NUMBER = 0, - SLOT_VALUE_STRING, - SLOT_VALUE_BOOLEAN, - SLOT_VALUE_VECTOR3, - SLOT_VALUE_ANY -} SlotValueType; - -// 槽位值 -typedef struct { - SlotValueType type; - union { - double number; - char string[256]; - int boolean; - struct { float x, y, z; } vector3; - } as; -} SlotValue; - -// 槽位类型 -typedef enum { - SLOT_STATEMENT = 0, // 语句槽位 (执行流) - SLOT_VALUE // 值槽位 (数据流) -} SlotKind; - -// 槽位 -typedef struct BlockSlot { - int id; - SlotKind kind; - SlotValueType value_type; - char label[MAX_BLOCK_LABEL]; - - struct Block* owner; // 所属积木 - struct BlockSlot* connected; // 连接的槽位 - - SlotValue value; // 当前值 (仅值槽位) - - float x, y; // 相对于积木的位置 - float width, height; // 槽位尺寸 -} BlockSlot; - -// 积木类型 -typedef enum { - // 事件 - BLOCK_EVENT_START = 0, - BLOCK_EVENT_UPDATE, - BLOCK_EVENT_COLLISION, - BLOCK_EVENT_KEY_PRESSED, - BLOCK_EVENT_MOUSE_CLICK, - BLOCK_EVENT_TIMER, - - // 动作 - BLOCK_ACTION_MOVE, - BLOCK_ACTION_ROTATE, - BLOCK_ACTION_SCALE, - BLOCK_ACTION_SET_POSITION, - BLOCK_ACTION_SET_ROTATION, - BLOCK_ACTION_PLAY_SOUND, - BLOCK_ACTION_DESTROY, - BLOCK_ACTION_INSTANTIATE, - - // 控制 - BLOCK_CONTROL_IF, - BLOCK_CONTROL_IF_ELSE, - BLOCK_CONTROL_REPEAT, - BLOCK_CONTROL_REPEAT_TIMES, - BLOCK_CONTROL_WHILE, - BLOCK_CONTROL_WAIT, - BLOCK_CONTROL_FUNCTION_DEF, - - // 运算 - BLOCK_OP_ADD, - BLOCK_OP_SUB, - BLOCK_OP_MUL, - BLOCK_OP_DIV, - BLOCK_OP_MOD, - BLOCK_OP_EQUALS, - BLOCK_OP_NOT_EQUALS, - BLOCK_OP_GREATER, - BLOCK_OP_LESS, - BLOCK_OP_AND, - BLOCK_OP_OR, - BLOCK_OP_NOT, - - // 变量 - BLOCK_VAR_GET, - BLOCK_VAR_SET, - BLOCK_VAR_CREATE, - - // 函数 - BLOCK_FUNC_CALL, - BLOCK_FUNC_RETURN, - - BLOCK_TYPE_COUNT -} BlockType; - -// 积木类型信息 -typedef struct { - BlockType type; - const char* name; - const char* label; - const char* category; - BlockColor color; - int input_count; - int output_count; - SlotValueType input_types[MAX_BLOCK_INPUTS]; - SlotValueType output_types[MAX_BLOCK_OUTPUTS]; - const char* input_labels[MAX_BLOCK_INPUTS]; - const char* output_labels[MAX_BLOCK_OUTPUTS]; -} BlockTypeInfo; - -// 积木 -typedef struct Block { - int id; - BlockType type; - char label[MAX_BLOCK_LABEL]; - - float x, y; // 画布位置 - float width, height; // 尺寸 - Color color; // 颜色 - - BlockSlot inputs[MAX_BLOCK_INPUTS]; - int input_count; - - BlockSlot outputs[MAX_BLOCK_OUTPUTS]; - int output_count; - - struct Block* next; // 下一个积木 (堆叠) - struct Block* parent_if; // 所属 if 块 (用于子语句) - - struct BlockWorkspace* workspace; - void* user_data; -} Block; - -// 连接 -typedef struct BlockConnection { - BlockSlot* from; - BlockSlot* to; - float points[8]; // 贝塞尔曲线控制点 -} BlockConnection; - -// 函数声明 -Block* block_create(BlockType type, float x, float y); -Block* block_copy(const Block* src); -void block_destroy(Block* block); -BlockSlot* block_add_input(Block* block, SlotKind kind, SlotValueType value_type, const char* label); -BlockSlot* block_add_output(Block* block, SlotKind kind, SlotValueType value_type, const char* label); -bool block_connect(BlockSlot* from, BlockSlot* to); -void block_disconnect(BlockSlot* slot); -SlotValue block_slot_get_value(BlockSlot* slot); -void block_slot_set_value(BlockSlot* slot, SlotValue value); -bool block_contains_point(Block* block, float px, float py); -void block_slot_world_pos(BlockSlot* slot, float* wx, float* wy); diff --git a/Engine/VisualScript/block_editor.c b/Engine/VisualScript/block_editor.c deleted file mode 100644 index 744cf8f..0000000 --- a/Engine/VisualScript/block_editor.c +++ /dev/null @@ -1,225 +0,0 @@ -// ============================================================================ -// block_editor.c - 编辑器主界面实现 -// ============================================================================ - -#include "block_editor.h" -#include "block_types.h" -#include -#include - -int block_editor_init(BlockEditor* editor, void* device, void* context, int width, int height) { - memset(editor, 0, sizeof(BlockEditor)); - - editor->width = width; - editor->height = height; - editor->toolbar_height = 30; - editor->properties_width = 200; - editor->visible = 0; - - // 创建工作区 - editor->workspace = workspace_create(); - if (!editor->workspace) return 0; - - // 初始化渲染器 - if (!block_renderer_init(&editor->renderer, device, context)) { - workspace_destroy(editor->workspace); - return 0; - } - - // 初始化交互 - interaction_init(&editor->interaction); - - // 初始化面板 - palette_init(&editor->palette); - editor->palette.x = 0; - editor->palette.y = editor->toolbar_height; - - // 创建执行器 - editor->executor = executor_create(editor->workspace); - - return 1; -} - -void block_editor_shutdown(BlockEditor* editor) { - if (editor->executor) executor_destroy(editor->executor); - block_renderer_shutdown(&editor->renderer); - if (editor->workspace) workspace_destroy(editor->workspace); -} - -void block_editor_show(BlockEditor* editor) { - editor->visible = 1; -} - -void block_editor_hide(BlockEditor* editor) { - editor->visible = 0; -} - -int block_editor_is_visible(BlockEditor* editor) { - return editor->visible; -} - -void block_editor_update(BlockEditor* editor, double delta_time) { - if (!editor->visible) return; - - // 更新交互 - interaction_update(&editor->interaction, editor->workspace); - - // 更新执行器 - if (editor->executor->state == EXEC_RUNNING) { - executor_update(editor->executor, delta_time); - } -} - -void block_editor_render(BlockEditor* editor) { - if (!editor->visible) return; - - block_renderer_begin(&editor->renderer); - - // 绘制工具栏 - block_renderer_add_quad(&editor->renderer, 0, 0, (float)editor->width, (float)editor->toolbar_height, - 0.2f, 0.2f, 0.25f, 1.0f); - block_renderer_draw_text(&editor->renderer, "积木编辑器", 5, 5, 1.0f, 1.0f, 1.0f); - - // 绘制面板 - palette_render(&editor->palette, &editor->renderer); - - // 绘制工作区积木 - float ws_x = editor->palette.width; - float ws_y = editor->toolbar_height; - float ws_w = (float)editor->width - editor->palette.width - editor->properties_width; - float ws_h = (float)editor->height - editor->toolbar_height; - - // 工作区背景 - block_renderer_add_quad(&editor->renderer, ws_x, ws_y, ws_w, ws_h, - 0.12f, 0.12f, 0.15f, 1.0f); - - // 绘制连接线 - for (int i = 0; i < editor->workspace->connection_count; i++) { - BlockConnection* conn = &editor->workspace->connections[i]; - if (conn->from && conn->to) { - block_renderer_draw_connection(&editor->renderer, conn->from, conn->to, - editor->workspace->view_x, editor->workspace->view_y, editor->workspace->zoom); - } - } - - // 绘制积木 - for (int i = 0; i < editor->workspace->block_count; i++) { - Block* block = editor->workspace->blocks[i]; - block_renderer_draw_block(&editor->renderer, block, - editor->workspace->view_x, editor->workspace->view_y, editor->workspace->zoom); - - // 高亮选中的积木 - if (block == editor->workspace->selected_block) { - float x = (block->x - editor->workspace->view_x) * editor->workspace->zoom; - float y = (block->y - editor->workspace->view_y) * editor->workspace->zoom; - float w = block->width * editor->workspace->zoom; - float h = block->height * editor->workspace->zoom; - block_renderer_add_quad(&editor->renderer, x - 2, y - 2, w + 4, h + 4, - 1.0f, 1.0f, 0.0f, 0.3f); - } - } - - // 绘制正在拖拽的连接线 - if (editor->interaction.connecting_from) { - float x1, y1; - block_slot_world_pos(editor->interaction.connecting_from, &x1, &y1); - x1 = (x1 - editor->workspace->view_x) * editor->workspace->zoom; - y1 = (y1 - editor->workspace->view_y) * editor->workspace->zoom; - float x2 = (float)editor->interaction.mouse_x; - float y2 = (float)editor->interaction.mouse_y; - block_renderer_add_line(&editor->renderer, x1, y1, x2, y2, 1.0f, 1.0f, 0.0f, 0.8f); - } - - block_renderer_end(&editor->renderer); -} - -void block_editor_on_mouse_move(BlockEditor* editor, int x, int y) { - if (!editor->visible) return; - interaction_mouse_move(&editor->interaction, editor->workspace, x, y); -} - -void block_editor_on_mouse_down(BlockEditor* editor, int button) { - if (!editor->visible) return; - - int x = editor->interaction.mouse_x; - int y = editor->interaction.mouse_y; - - // 检查面板点击 - if (x < editor->palette.width && y >= editor->toolbar_height) { - BlockType type = palette_handle_click(&editor->palette, (float)x, (float)y); - if (type >= 0) { - block_editor_create_block_from_palette(editor, type, 300, 100); - } - return; - } - - interaction_mouse_down(&editor->interaction, editor->workspace, button); -} - -void block_editor_on_mouse_up(BlockEditor* editor, int button) { - if (!editor->visible) return; - interaction_mouse_up(&editor->interaction, editor->workspace, button); -} - -void block_editor_on_mouse_wheel(BlockEditor* editor, int delta) { - if (!editor->visible) return; - interaction_mouse_wheel(&editor->interaction, editor->workspace, delta); -} - -void block_editor_on_key(BlockEditor* editor, int key) { - if (!editor->visible) return; - interaction_key_down(&editor->interaction, editor->workspace, key); -} - -void block_editor_on_resize(BlockEditor* editor, int width, int height) { - editor->width = width; - editor->height = height; -} - -void block_editor_create_block_from_palette(BlockEditor* editor, BlockType type, float x, float y) { - Block* block = block_create(type, x, y); - if (!block) return; - - const BlockTypeInfo* info = block_type_get_info(type); - if (info) { - strncpy(block->label, info->label, MAX_BLOCK_LABEL - 1); - - // 创建输入槽位 - for (int i = 0; i < info->input_count; i++) { - block_add_input(block, - i == 0 ? SLOT_STATEMENT : SLOT_VALUE, - info->input_types[i], - info->input_labels[i]); - } - - // 创建输出槽位 - for (int i = 0; i < info->output_count; i++) { - block_add_output(block, - info->output_types[i] == SLOT_VALUE_ANY ? SLOT_STATEMENT : SLOT_VALUE, - info->output_types[i], - info->output_labels[i]); - } - } - - workspace_add_block(editor->workspace, block); -} - -int block_editor_save(BlockEditor* editor, const char* filepath) { - return serializer_save(editor->workspace, filepath); -} - -int block_editor_load(BlockEditor* editor, const char* filepath) { - return serializer_load(editor->workspace, filepath); -} - -void block_editor_run(BlockEditor* editor) { - executor_start(editor->executor); -} - -void block_editor_stop(BlockEditor* editor) { - executor_stop(editor->executor); -} - -void block_editor_pause(BlockEditor* editor) { - executor_pause(editor->executor); -} diff --git a/Engine/VisualScript/block_editor.h b/Engine/VisualScript/block_editor.h deleted file mode 100644 index f149ae2..0000000 --- a/Engine/VisualScript/block_editor.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -// ============================================================================ -// block_editor.h - 编辑器主界面 -// ============================================================================ - -#include "block_workspace.h" -#include "block_renderer.h" -#include "block_interaction.h" -#include "block_palette.h" -#include "block_executor.h" -#include "block_serializer.h" - -typedef struct BlockEditor { - BlockWorkspace* workspace; - BlockRenderer renderer; - BlockInteraction interaction; - BlockPalette palette; - BlockExecutor* executor; - - int width, height; - int visible; - - // 工具栏 - int toolbar_height; - - // 属性面板 - int properties_width; - Block* selected_block; -} BlockEditor; - -// 初始化/销毁 -int block_editor_init(BlockEditor* editor, void* device, void* context, int width, int height); -void block_editor_shutdown(BlockEditor* editor); - -// 显示/隐藏 -void block_editor_show(BlockEditor* editor); -void block_editor_hide(BlockEditor* editor); -int block_editor_is_visible(BlockEditor* editor); - -// 更新/渲染 -void block_editor_update(BlockEditor* editor, double delta_time); -void block_editor_render(BlockEditor* editor); - -// 输入处理 -void block_editor_on_mouse_move(BlockEditor* editor, int x, int y); -void block_editor_on_mouse_down(BlockEditor* editor, int button); -void block_editor_on_mouse_up(BlockEditor* editor, int button); -void block_editor_on_mouse_wheel(BlockEditor* editor, int delta); -void block_editor_on_key(BlockEditor* editor, int key); -void block_editor_on_resize(BlockEditor* editor, int width, int height); - -// 从面板拖拽创建积木 -void block_editor_create_block_from_palette(BlockEditor* editor, BlockType type, float x, float y); - -// 保存/加载 -int block_editor_save(BlockEditor* editor, const char* filepath); -int block_editor_load(BlockEditor* editor, const char* filepath); - -// 运行控制 -void block_editor_run(BlockEditor* editor); -void block_editor_stop(BlockEditor* editor); -void block_editor_pause(BlockEditor* editor); diff --git a/Engine/VisualScript/block_executor.c b/Engine/VisualScript/block_executor.c deleted file mode 100644 index 3d0e2dd..0000000 --- a/Engine/VisualScript/block_executor.c +++ /dev/null @@ -1,465 +0,0 @@ -// ============================================================================ -// block_executor.c - 积木执行引擎 (完整实现) -// ============================================================================ - -#include "block_executor.h" -#include "block_types.h" -#include -#include -#include -#include -#include - -// 日志回调 -typedef void (*LogCallback)(const char* msg, int level); -static LogCallback g_log_cb = NULL; - -static void log_info(const char* fmt, ...) { - char buf[512]; va_list args; va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); - if (g_log_cb) g_log_cb(buf, 0); else printf("[INFO] %s\n", buf); -} -static void log_error(const char* fmt, ...) { - char buf[512]; va_list args; va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); - if (g_log_cb) g_log_cb(buf, 2); else printf("[ERROR] %s\n", buf); -} - -void executor_set_log_callback(LogCallback cb) { g_log_cb = cb; } - -// 值辅助 -static SlotValue make_number(double v) { SlotValue v2; v2.type = SLOT_VALUE_NUMBER; v2.as.number = v; return v2; } -static SlotValue make_string(const char* s) { SlotValue v; v.type = SLOT_VALUE_STRING; strncpy(v.as.string, s, 255); return v; } -static SlotValue make_bool(int b) { SlotValue v; v.type = SLOT_VALUE_BOOLEAN; v.as.boolean = b; return v; } -static SlotValue make_vec3(float x, float y, float z) { SlotValue v; v.type = SLOT_VALUE_VECTOR3; v.as.vector3.x = x; v.as.vector3.y = y; v.as.vector3.z = z; return v; } - -// 连接追踪:获取槽位的输入值(通过连线回溯) -static SlotValue get_connected_value(BlockSlot* slot) { - if (slot->connected) return slot->connected->value; - return slot->value; -} - -BlockExecutor* executor_create(BlockWorkspace* ws) { - BlockExecutor* exec = (BlockExecutor*)calloc(1, sizeof(BlockExecutor)); - if (!exec) return NULL; - exec->workspace = ws; - return exec; -} - -void executor_destroy(BlockExecutor* exec) { free(exec); } - -void executor_start(BlockExecutor* exec) { - exec->state = EXEC_RUNNING; - exec->call_stack_top = 0; - exec->loop_stack_top = 0; - exec->current_block = NULL; - for (int i = 0; i < exec->workspace->block_count; i++) { - Block* block = exec->workspace->blocks[i]; - if (block->type == BLOCK_EVENT_START) { - exec->current_block = block; - log_info("执行器启动: 找到 on_start 事件"); - return; - } - } - log_error("未找到 on_start 事件积木"); - exec->state = EXEC_IDLE; -} - -void executor_stop(BlockExecutor* exec) { exec->state = EXEC_IDLE; exec->current_block = NULL; } -void executor_pause(BlockExecutor* exec) { if (exec->state == EXEC_RUNNING) exec->state = EXEC_PAUSED; } -void executor_resume(BlockExecutor* exec) { if (exec->state == EXEC_PAUSED) exec->state = EXEC_RUNNING; } - -// 获取下一个执行的积木(通过输出端口连接) -static Block* next_from_output(Block* block, int output_index) { - if (output_index >= block->output_count) return NULL; - BlockSlot* out = &block->outputs[output_index]; - if (out->connected && out->connected->owner) return out->connected->owner; - return NULL; -} - -// 查找循环体链的最后一个积木(用于确定循环结束后应跳转到的积木) -static Block* find_loop_body_end(Block* loop_block) { - if (!loop_block || loop_block->output_count == 0 || !loop_block->outputs[0].connected) return NULL; - Block* cur = loop_block->outputs[0].connected->owner; - Block* prev = loop_block; - int guard = 0; - while (cur && guard < 1000) { - guard++; - if (cur == loop_block) return prev; // 回到循环头,则前一个为体尾 - Block* next = NULL; - if (cur->output_count > 0 && cur->outputs[0].connected) { - next = cur->outputs[0].connected->owner; - } - if (!next) return cur; - prev = cur; - cur = next; - } - return cur; -} - -// 获取值输入 -static SlotValue get_input(Block* block, int idx) { - if (idx >= block->input_count) return make_number(0); - return get_connected_value(&block->inputs[idx]); -} - -void executor_step(BlockExecutor* exec) { - if (!exec->current_block) { exec->state = EXEC_IDLE; return; } - Block* cur = exec->current_block; - Block* next = NULL; - - switch (cur->type) { - // === 事件 === - case BLOCK_EVENT_START: - case BLOCK_EVENT_UPDATE: - case BLOCK_EVENT_COLLISION: - case BLOCK_EVENT_MOUSE_CLICK: - next = next_from_output(cur, 0); - break; - case BLOCK_EVENT_KEY_PRESSED: { - const char* key = get_input(cur, 0).as.string; - log_info("事件: 按键 '%s' (需要引擎集成)", key); - next = next_from_output(cur, 0); - break; - } - case BLOCK_EVENT_TIMER: { - double interval = get_input(cur, 0).as.number; - log_info("事件: 定时器 %.1fs (需要引擎集成)", interval); - next = next_from_output(cur, 0); - break; - } - - // === 动作 === - case BLOCK_ACTION_MOVE: { - double x = get_input(cur, 1).as.number; - double y = get_input(cur, 2).as.number; - double z = get_input(cur, 3).as.number; - log_info("移动物体: (%.2f, %.2f, %.2f)", x, y, z); - next = next_from_output(cur, 0); - break; - } - case BLOCK_ACTION_ROTATE: { - double x = get_input(cur, 1).as.number; - double y = get_input(cur, 2).as.number; - double z = get_input(cur, 3).as.number; - log_info("旋转物体: (%.2f, %.2f, %.2f)", x, y, z); - next = next_from_output(cur, 0); - break; - } - case BLOCK_ACTION_SCALE: { - double x = get_input(cur, 1).as.number; - double y = get_input(cur, 2).as.number; - double z = get_input(cur, 3).as.number; - log_info("缩放物体: (%.2f, %.2f, %.2f)", x, y, z); - next = next_from_output(cur, 0); - break; - } - case BLOCK_ACTION_SET_POSITION: { - double x = get_input(cur, 1).as.number; - double y = get_input(cur, 2).as.number; - double z = get_input(cur, 3).as.number; - log_info("设置位置: (%.2f, %.2f, %.2f)", x, y, z); - next = next_from_output(cur, 0); - break; - } - case BLOCK_ACTION_SET_ROTATION: { - double x = get_input(cur, 1).as.number; - double y = get_input(cur, 2).as.number; - double z = get_input(cur, 3).as.number; - log_info("设置旋转: (%.2f, %.2f, %.2f)", x, y, z); - next = next_from_output(cur, 0); - break; - } - case BLOCK_ACTION_PLAY_SOUND: { - const char* name = get_input(cur, 1).as.string; - log_info("播放音效: '%s'", name); - next = next_from_output(cur, 0); - break; - } - case BLOCK_ACTION_DESTROY: - log_info("销毁物体"); - next = next_from_output(cur, 0); - break; - case BLOCK_ACTION_INSTANTIATE: { - const char* prefab = get_input(cur, 1).as.string; - log_info("实例化预制体: '%s'", prefab); - next = next_from_output(cur, 0); - break; - } - - // === 控制流 === - case BLOCK_CONTROL_IF: - case BLOCK_CONTROL_IF_ELSE: { - int cond = get_input(cur, 1).as.boolean; - log_info("如果 %s", cond ? "真 -> Then" : "假 -> Else"); - next = next_from_output(cur, cond ? 0 : 1); - break; - } - case BLOCK_CONTROL_REPEAT: - case BLOCK_CONTROL_WHILE: { - int cond = get_input(cur, 1).as.boolean; - LoopFrame* frame = NULL; - if (exec->loop_stack_top > 0 && exec->loop_stack[exec->loop_stack_top - 1].loop_block == cur) { - frame = &exec->loop_stack[exec->loop_stack_top - 1]; - } else { - if (exec->loop_stack_top < MAX_LOOP_STACK) { - frame = &exec->loop_stack[exec->loop_stack_top++]; - frame->loop_block = cur; - frame->counter = 0; - frame->target = 0; - Block* body_end = find_loop_body_end(cur); - frame->after_block = body_end ? next_from_output(body_end, 0) : NULL; - } - } - if (frame && cond) { - frame->counter++; - next = next_from_output(cur, 0); - } else { - if (frame) exec->loop_stack_top--; - next = frame ? frame->after_block : next_from_output(cur, 0); - } - break; - } - case BLOCK_CONTROL_REPEAT_TIMES: { - double times = get_input(cur, 1).as.number; - LoopFrame* frame = NULL; - if (exec->loop_stack_top > 0 && exec->loop_stack[exec->loop_stack_top - 1].loop_block == cur) { - frame = &exec->loop_stack[exec->loop_stack_top - 1]; - frame->counter++; - } else { - if (exec->loop_stack_top < MAX_LOOP_STACK) { - frame = &exec->loop_stack[exec->loop_stack_top++]; - frame->loop_block = cur; - frame->counter = 0; - frame->target = (int)times; - Block* body_end = find_loop_body_end(cur); - frame->after_block = body_end ? next_from_output(body_end, 0) : NULL; - } - } - if (frame && frame->counter < frame->target) { - log_info("循环 %d / %d", frame->counter + 1, frame->target); - next = next_from_output(cur, 0); - } else { - if (frame) exec->loop_stack_top--; - next = frame ? frame->after_block : next_from_output(cur, 0); - } - break; - } - case BLOCK_CONTROL_WAIT: { - double secs = get_input(cur, 1).as.number; - log_info("等待 %.1f 秒", secs); - exec->wait_timer = secs; - exec->state = EXEC_WAITING; - exec->current_block = next_from_output(cur, 0); - return; - } - case BLOCK_CONTROL_FUNCTION_DEF: - log_info("函数定义 (跳过)"); - next = next_from_output(cur, 0); - break; - - // === 运算 === - case BLOCK_OP_ADD: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_number(a + b); - log_info("%.1f + %.1f = %.1f", a, b, a + b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_SUB: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_number(a - b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_MUL: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_number(a * b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_DIV: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_number(b != 0 ? a / b : 0); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_MOD: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_number(b != 0 ? fmod(a, b) : 0); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_EQUALS: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_bool(a == b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_NOT_EQUALS: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_bool(a != b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_GREATER: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_bool(a > b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_LESS: { - double a = get_input(cur, 0).as.number; - double b = get_input(cur, 1).as.number; - cur->outputs[0].value = make_bool(a < b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_AND: { - int a = get_input(cur, 0).as.boolean; - int b = get_input(cur, 1).as.boolean; - cur->outputs[0].value = make_bool(a && b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_OR: { - int a = get_input(cur, 0).as.boolean; - int b = get_input(cur, 1).as.boolean; - cur->outputs[0].value = make_bool(a || b); - next = next_from_output(cur, 0); - break; - } - case BLOCK_OP_NOT: { - int a = get_input(cur, 0).as.boolean; - cur->outputs[0].value = make_bool(!a); - next = next_from_output(cur, 0); - break; - } - - // === 变量 === - case BLOCK_VAR_GET: { - const char* name = cur->label; - SlotValue val = executor_get_variable(exec, name); - cur->outputs[0].value = val; - log_info("读取变量 '%s' = %.2f", name, val.as.number); - next = next_from_output(cur, 0); - break; - } - case BLOCK_VAR_SET: { - const char* name = cur->label; - SlotValue val = get_input(cur, 1); - executor_set_variable(exec, name, val); - log_info("设置变量 '%s' = %.2f", name, val.as.number); - next = next_from_output(cur, 0); - break; - } - case BLOCK_VAR_CREATE: { - const char* name = cur->label; - executor_create_variable(exec, name); - log_info("创建变量 '%s' = 0", name); - next = next_from_output(cur, 0); - break; - } - - // === 函数 === - case BLOCK_FUNC_CALL: { - const char* fname = get_input(cur, 1).as.string; - log_info("调用函数 '%s'", fname); - - // 在工作区中查找同名函数定义积木 - Block* def = NULL; - for (int i = 0; i < exec->workspace->block_count; i++) { - Block* b = exec->workspace->blocks[i]; - if (b->type == BLOCK_CONTROL_FUNCTION_DEF && strcmp(b->label, fname) == 0) { - def = b; - break; - } - } - - if (def && exec->call_stack_top < MAX_CALL_STACK) { - exec->call_stack[exec->call_stack_top].block = cur; - exec->call_stack[exec->call_stack_top].return_block = next_from_output(cur, 0); - exec->call_stack_top++; - next = next_from_output(def, 0); - } else { - if (!def) log_error("未找到函数定义: '%s'", fname); - next = next_from_output(cur, 0); - } - break; - } - case BLOCK_FUNC_RETURN: { - if (exec->call_stack_top > 0) { - exec->call_stack_top--; - next = exec->call_stack[exec->call_stack_top].return_block; - } - break; - } - - default: - log_error("未知积木类型: %d", cur->type); - next = next_from_output(cur, 0); - break; - } - - // 若当前 next 是某个活跃循环的 after_block,则跳转回循环头继续判断 - if (next && exec->loop_stack_top > 0) { - LoopFrame* frame = &exec->loop_stack[exec->loop_stack_top - 1]; - if (next == frame->after_block) { - next = frame->loop_block; - } - } - - exec->current_block = next; - if (!exec->current_block) { - log_info("执行完成"); - exec->state = EXEC_IDLE; - } -} - -void executor_update(BlockExecutor* exec, double delta_time) { - if (exec->state == EXEC_WAITING) { - exec->wait_timer -= delta_time; - if (exec->wait_timer <= 0) exec->state = EXEC_RUNNING; - return; - } - if (exec->state != EXEC_RUNNING) return; - int steps = 0; - while (exec->current_block && exec->state == EXEC_RUNNING && steps < 1000) { - executor_step(exec); - steps++; - } -} - -void executor_set_variable(BlockExecutor* exec, const char* name, SlotValue value) { - for (int i = 0; i < exec->variable_count; i++) { - if (strcmp(exec->variables[i].name, name) == 0) { - exec->variables[i].value = value; - return; - } - } - if (exec->variable_count < MAX_VARIABLES) { - Variable* var = &exec->variables[exec->variable_count++]; - strncpy(var->name, name, 63); - var->value = value; - var->used = 1; - } -} - -SlotValue executor_get_variable(BlockExecutor* exec, const char* name) { - for (int i = 0; i < exec->variable_count; i++) { - if (strcmp(exec->variables[i].name, name) == 0) return exec->variables[i].value; - } - return make_number(0); -} - -void executor_create_variable(BlockExecutor* exec, const char* name) { - executor_set_variable(exec, name, make_number(0)); -} diff --git a/Engine/VisualScript/block_executor.h b/Engine/VisualScript/block_executor.h deleted file mode 100644 index 09603b2..0000000 --- a/Engine/VisualScript/block_executor.h +++ /dev/null @@ -1,86 +0,0 @@ -#pragma once - -// ============================================================================ -// block_executor.h - 积木执行引擎 -// ============================================================================ - -#include "block_workspace.h" - -#define MAX_VARIABLES 256 -#define MAX_CALL_STACK 32 -#define MAX_EXEC_STACK 1024 -#define MAX_LOOP_STACK 32 - -// 变量 -typedef struct { - char name[64]; - SlotValue value; - int used; -} Variable; - -// 调用帧 -typedef struct { - Block* block; - Block* return_block; -} CallFrame; - -// 循环帧 -typedef struct { - Block* loop_block; - int counter; - int target; - Block* after_block; -} LoopFrame; - -// 执行状态 -typedef enum { - EXEC_IDLE = 0, - EXEC_RUNNING, - EXEC_WAITING, - EXEC_PAUSED, - EXEC_ERROR -} ExecState; - -// 执行器 -typedef struct BlockExecutor { - BlockWorkspace* workspace; - ExecState state; - - Variable variables[MAX_VARIABLES]; - int variable_count; - - CallFrame call_stack[MAX_CALL_STACK]; - int call_stack_top; - - LoopFrame loop_stack[MAX_LOOP_STACK]; - int loop_stack_top; - - Block* current_block; - double wait_timer; - - int breakpoint_enabled; - Block* breakpoint_block; -} BlockExecutor; - -// 初始化/销毁 -BlockExecutor* executor_create(BlockWorkspace* ws); -void executor_destroy(BlockExecutor* exec); - -// 控制 -void executor_start(BlockExecutor* exec); -void executor_stop(BlockExecutor* exec); -void executor_pause(BlockExecutor* exec); -void executor_resume(BlockExecutor* exec); -void executor_step(BlockExecutor* exec); - -// 更新 (每帧调用) -void executor_update(BlockExecutor* exec, double delta_time); - -// 变量操作 -void executor_set_variable(BlockExecutor* exec, const char* name, SlotValue value); -SlotValue executor_get_variable(BlockExecutor* exec, const char* name); -void executor_create_variable(BlockExecutor* exec, const char* name); - -// 日志回调 -typedef void (*LogCallback)(const char* msg, int level); -void executor_set_log_callback(LogCallback cb); diff --git a/Engine/VisualScript/block_font.inc b/Engine/VisualScript/block_font.inc deleted file mode 100644 index 3ba92dd..0000000 --- a/Engine/VisualScript/block_font.inc +++ /dev/null @@ -1,99 +0,0 @@ -// 5x7 位图字体 (列优先, LSB 在上) -static const uint8_t BLOCK_FONT[96][5] = { - /* */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* ! */ {0x00, 0x00, 0xBE, 0x00, 0x00}, - /* " */ {0x00, 0x36, 0x36, 0x00, 0x00}, - /* # */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* $ */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* % */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* & */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* ' */ {0x00, 0x06, 0x06, 0x00, 0x00}, - /* ( */ {0x3C, 0x42, 0x81, 0x81, 0x00}, - /* ) */ {0x00, 0x81, 0x81, 0x42, 0x3C}, - /* * */ {0x22, 0x14, 0x08, 0x14, 0x22}, - /* + */ {0x08, 0x08, 0x7F, 0x08, 0x08}, - /* , */ {0x00, 0xA0, 0x60, 0x00, 0x00}, - /* - */ {0x08, 0x08, 0x08, 0x08, 0x08}, - /* . */ {0x00, 0x60, 0x60, 0x00, 0x00}, - /* / */ {0x80, 0x40, 0x20, 0x10, 0x08}, - /* 0 */ {0x7E, 0x81, 0x81, 0x81, 0x7E}, - /* 1 */ {0x00, 0x82, 0xFF, 0x80, 0x00}, - /* 2 */ {0xC2, 0xA1, 0x91, 0x89, 0x86}, - /* 3 */ {0x42, 0x81, 0x89, 0x89, 0x76}, - /* 4 */ {0x18, 0x28, 0x48, 0xFF, 0x08}, - /* 5 */ {0x4F, 0x89, 0x89, 0x89, 0x71}, - /* 6 */ {0x7E, 0x89, 0x89, 0x89, 0x72}, - /* 7 */ {0x01, 0xC1, 0x31, 0x0D, 0x03}, - /* 8 */ {0x76, 0x89, 0x89, 0x89, 0x76}, - /* 9 */ {0x46, 0x89, 0x89, 0x89, 0x7E}, - /* : */ {0x00, 0x66, 0x66, 0x00, 0x00}, - /* ; */ {0x00, 0xB6, 0x66, 0x00, 0x00}, - /* < */ {0x10, 0x28, 0x44, 0x82, 0x00}, - /* = */ {0x28, 0x28, 0x28, 0x28, 0x28}, - /* > */ {0x00, 0x82, 0x44, 0x28, 0x10}, - /* ? */ {0x02, 0x01, 0x51, 0x09, 0x06}, - /* @ */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* A */ {0x7E, 0x09, 0x09, 0x09, 0x7E}, - /* B */ {0xFF, 0x89, 0x89, 0x89, 0x76}, - /* C */ {0x7E, 0x81, 0x81, 0x81, 0x42}, - /* D */ {0xFF, 0x81, 0x81, 0x42, 0x3C}, - /* E */ {0xFF, 0x89, 0x89, 0x89, 0x81}, - /* F */ {0xFF, 0x09, 0x09, 0x09, 0x01}, - /* G */ {0x7E, 0x81, 0x89, 0x89, 0x72}, - /* H */ {0xFF, 0x08, 0x08, 0x08, 0xFF}, - /* I */ {0x00, 0x81, 0xFF, 0x81, 0x00}, - /* J */ {0x40, 0x80, 0x80, 0x80, 0x7F}, - /* K */ {0xFF, 0x08, 0x14, 0x22, 0x41}, - /* L */ {0xFF, 0x80, 0x80, 0x80, 0x80}, - /* M */ {0xFF, 0x02, 0x0C, 0x02, 0xFF}, - /* N */ {0xFF, 0x04, 0x08, 0x10, 0xFF}, - /* O */ {0x7E, 0x81, 0x81, 0x81, 0x7E}, - /* P */ {0xFF, 0x09, 0x09, 0x09, 0x06}, - /* Q */ {0x7E, 0x81, 0xA1, 0x41, 0xBE}, - /* R */ {0xFF, 0x09, 0x19, 0x29, 0x46}, - /* S */ {0x46, 0x89, 0x89, 0x89, 0x72}, - /* T */ {0x01, 0x01, 0xFF, 0x01, 0x01}, - /* U */ {0x7F, 0x80, 0x80, 0x80, 0x7F}, - /* V */ {0x3F, 0x40, 0x80, 0x40, 0x3F}, - /* W */ {0x7F, 0x80, 0x70, 0x80, 0x7F}, - /* X */ {0xC3, 0x24, 0x18, 0x24, 0xC3}, - /* Y */ {0x03, 0x04, 0xF8, 0x04, 0x03}, - /* Z */ {0xC1, 0xA1, 0x91, 0x89, 0x87}, - /* [ */ {0x7E, 0x82, 0x82, 0x82, 0x00}, - /* \ */ {0x08, 0x10, 0x20, 0x40, 0x80}, - /* ] */ {0x00, 0x82, 0x82, 0x82, 0x7E}, - /* ^ */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* _ */ {0x80, 0x80, 0x80, 0x80, 0x80}, - /* ` */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* a */ {0x20, 0x54, 0x54, 0x54, 0x78}, - /* b */ {0xFF, 0x48, 0x48, 0x48, 0x30}, - /* c */ {0x38, 0x44, 0x44, 0x44, 0x44}, - /* d */ {0x30, 0x48, 0x48, 0x48, 0xFF}, - /* e */ {0x38, 0x54, 0x54, 0x54, 0x58}, - /* f */ {0x08, 0x7E, 0x09, 0x01, 0x02}, - /* g */ {0x08, 0x54, 0x54, 0x54, 0x3C}, - /* h */ {0xFF, 0x08, 0x08, 0x08, 0xF0}, - /* i */ {0x00, 0x48, 0x7A, 0x40, 0x00}, - /* j */ {0x20, 0x40, 0x40, 0x3A, 0x00}, - /* k */ {0xFF, 0x10, 0x28, 0x44, 0x82}, - /* l */ {0x00, 0x41, 0xFF, 0x40, 0x00}, - /* m */ {0x7C, 0x04, 0x78, 0x04, 0x78}, - /* n */ {0x7C, 0x04, 0x04, 0x04, 0xF8}, - /* o */ {0x38, 0x44, 0x44, 0x44, 0x38}, - /* p */ {0xFC, 0x24, 0x24, 0x24, 0x18}, - /* q */ {0x18, 0x24, 0x24, 0x24, 0xFC}, - /* r */ {0x7C, 0x08, 0x04, 0x04, 0x08}, - /* s */ {0x48, 0x54, 0x54, 0x54, 0x24}, - /* t */ {0x04, 0x3F, 0x44, 0x40, 0x20}, - /* u */ {0x3C, 0x40, 0x40, 0x40, 0x3C}, - /* v */ {0x1C, 0x20, 0x40, 0x20, 0x1C}, - /* w */ {0x3C, 0x40, 0x30, 0x40, 0x3C}, - /* x */ {0x44, 0x28, 0x10, 0x28, 0x44}, - /* y */ {0x0C, 0x50, 0x50, 0x50, 0x3C}, - /* z */ {0x44, 0x64, 0x54, 0x4C, 0x44}, - /* { */ {0x18, 0x24, 0x42, 0x24, 0x18}, - /* | */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* } */ {0x18, 0x24, 0x42, 0x24, 0x18}, - /* ~ */ {0x00, 0x00, 0x00, 0x00, 0x00}, - /* \x7f */ {0x00, 0x00, 0x00, 0x00, 0x00}, -}; diff --git a/Engine/VisualScript/block_interaction.c b/Engine/VisualScript/block_interaction.c deleted file mode 100644 index 99dc3fb..0000000 --- a/Engine/VisualScript/block_interaction.c +++ /dev/null @@ -1,151 +0,0 @@ -// ============================================================================ -// block_interaction.c - 交互系统实现 -// ============================================================================ - -#include "block_interaction.h" -#include -#include -#include -#include - -void interaction_init(BlockInteraction* inter) { - memset(inter, 0, sizeof(BlockInteraction)); -} - -void interaction_mouse_move(BlockInteraction* inter, BlockWorkspace* ws, int x, int y) { - inter->mouse_x = x; - inter->mouse_y = y; - - // 拖拽积木 - if (inter->dragging_block) { - float wx, wy; - workspace_screen_to_world(ws, (float)x, (float)y, &wx, &wy); - inter->dragging_block->x = wx - inter->drag_offset_x; - inter->dragging_block->y = wy - inter->drag_offset_y; - } - - // 平移画布 - if (inter->panning) { - float dx = (x - inter->pan_start_x) / ws->zoom; - float dy = (y - inter->pan_start_y) / ws->zoom; - ws->view_x = inter->view_start_x - dx; - ws->view_y = inter->view_start_y - dy; - } -} - -void interaction_mouse_down(BlockInteraction* inter, BlockWorkspace* ws, int button) { - inter->mouse_down = 1; - inter->mouse_button = button; - - float wx, wy; - workspace_screen_to_world(ws, (float)inter->mouse_x, (float)inter->mouse_y, &wx, &wy); - - if (button == 0) { // 左键 - // 检查是否点击槽位 - BlockSlot* slot = workspace_find_slot_at(ws, wx, wy); - if (slot) { - // 开始连接 - inter->connecting_from = slot; - inter->connect_start_x = wx; - inter->connect_start_y = wy; - return; - } - - // 检查是否点击积木 - Block* block = workspace_find_block_at(ws, wx, wy); - if (block) { - inter->dragging_block = block; - inter->drag_offset_x = wx - block->x; - inter->drag_offset_y = wy - block->y; - inter->selected_block = block; - ws->selected_block = block; - return; - } - - // 点击空白区域: 取消选择 - inter->selected_block = NULL; - ws->selected_block = NULL; - } - - if (button == 1 || button == 2) { // 右键/中键: 平移 - inter->panning = 1; - inter->pan_start_x = (float)inter->mouse_x; - inter->pan_start_y = (float)inter->mouse_y; - inter->view_start_x = ws->view_x; - inter->view_start_y = ws->view_y; - } -} - -void interaction_mouse_up(BlockInteraction* inter, BlockWorkspace* ws, int button) { - inter->mouse_down = 0; - - if (button == 0) { - // 结束拖拽积木 - inter->dragging_block = NULL; - - // 结束连接 - if (inter->connecting_from) { - float wx, wy; - workspace_screen_to_world(ws, (float)inter->mouse_x, (float)inter->mouse_y, &wx, &wy); - - BlockSlot* target = workspace_find_slot_at(ws, wx, wy); - if (target && target != inter->connecting_from) { - // 尝试建立连接 - workspace_add_connection(ws, inter->connecting_from, target); - } - inter->connecting_from = NULL; - } - } - - if (button == 1 || button == 2) { - inter->panning = 0; - } -} - -void interaction_key_down(BlockInteraction* inter, BlockWorkspace* ws, int key) { - inter->key = key; - inter->key_pressed = 1; - - // 删除选中的积木 - if (key == 46 || key == 8) { // DELETE 或 BACKSPACE - if (inter->selected_block) { - workspace_remove_block(ws, inter->selected_block->id); - inter->selected_block = NULL; - ws->selected_block = NULL; - } - } - - // 复制/粘贴 (Ctrl+C / Ctrl+V) - static Block* clipboard = NULL; - if (key == 'C' && (GetAsyncKeyState(VK_CONTROL) & 0x8000)) { - if (inter->selected_block) { - if (clipboard) block_destroy(clipboard); - clipboard = block_copy(inter->selected_block); - } - } - if (key == 'V' && (GetAsyncKeyState(VK_CONTROL) & 0x8000)) { - if (clipboard) { - Block* copy = block_copy(clipboard); - if (copy) { - copy->x += 20.0f; - copy->y += 20.0f; - copy->id = ws->next_block_id++; - workspace_add_block(ws, copy); - inter->selected_block = copy; - ws->selected_block = copy; - } - } - } -} - -void interaction_mouse_wheel(BlockInteraction* inter, BlockWorkspace* ws, int delta) { - float zoom_factor = delta > 0 ? 1.1f : 0.9f; - ws->zoom *= zoom_factor; - if (ws->zoom < 0.25f) ws->zoom = 0.25f; - if (ws->zoom > 4.0f) ws->zoom = 4.0f; -} - -void interaction_update(BlockInteraction* inter, BlockWorkspace* ws) { - inter->key_pressed = 0; - (void)ws; -} diff --git a/Engine/VisualScript/block_interaction.h b/Engine/VisualScript/block_interaction.h deleted file mode 100644 index cb90b68..0000000 --- a/Engine/VisualScript/block_interaction.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -// ============================================================================ -// block_interaction.h - 交互系统 -// ============================================================================ - -#include "block_workspace.h" - -typedef struct { - int mouse_x, mouse_y; - int mouse_down; - int mouse_button; // 0=left, 1=right, 2=middle - int key; - int key_pressed; - - // 拖拽状态 - Block* dragging_block; - float drag_offset_x, drag_offset_y; - - // 连接状态 - BlockSlot* connecting_from; - float connect_start_x, connect_start_y; - - // 选择状态 - Block* selected_block; - - // 平移状态 - int panning; - float pan_start_x, pan_start_y; - float view_start_x, view_start_y; -} BlockInteraction; - -// 初始化 -void interaction_init(BlockInteraction* inter); - -// 处理输入事件 -void interaction_mouse_move(BlockInteraction* inter, BlockWorkspace* ws, int x, int y); -void interaction_mouse_down(BlockInteraction* inter, BlockWorkspace* ws, int button); -void interaction_mouse_up(BlockInteraction* inter, BlockWorkspace* ws, int button); -void interaction_key_down(BlockInteraction* inter, BlockWorkspace* ws, int key); -void interaction_mouse_wheel(BlockInteraction* inter, BlockWorkspace* ws, int delta); - -// 更新 (每帧调用) -void interaction_update(BlockInteraction* inter, BlockWorkspace* ws); diff --git a/Engine/VisualScript/block_palette.c b/Engine/VisualScript/block_palette.c deleted file mode 100644 index 672dad4..0000000 --- a/Engine/VisualScript/block_palette.c +++ /dev/null @@ -1,140 +0,0 @@ -// ============================================================================ -// block_palette.c - 积木面板实现 -// ============================================================================ - -#include "block_palette.h" -#include "block_renderer.h" -#include -#include -#include - -void palette_init(BlockPalette* palette) { - memset(palette, 0, sizeof(BlockPalette)); - palette->width = 200; - palette->height = 600; - - // 添加所有积木类型 - int count; - const BlockTypeInfo* all = block_type_get_all(&count); - for (int i = 0; i < count; i++) { - palette_add_block(palette, all[i].type); - } -} - -void palette_add_block(BlockPalette* palette, BlockType type) { - const BlockTypeInfo* info = block_type_get_info(type); - if (!info) return; - - // 查找或创建分类 - for (int i = 0; i < palette->category_count; i++) { - if (strcmp(palette->categories[i].name, info->category) == 0) { - palette->categories[i].blocks[palette->categories[i].block_count++] = type; - return; - } - } - - // 创建新分类 - if (palette->category_count < MAX_PALETTE_CATEGORIES) { - PaletteCategory* cat = &palette->categories[palette->category_count++]; - strncpy(cat->name, info->category, 63); - cat->blocks[cat->block_count++] = type; - cat->expanded = 1; - } -} - -void palette_render(BlockPalette* palette, BlockRenderer* renderer) { - // 绘制背景 - block_renderer_add_quad(renderer, palette->x, palette->y, palette->width, palette->height, - 0.15f, 0.15f, 0.18f, 1.0f); - - // 绘制标题 - block_renderer_draw_text(renderer, "积木面板", palette->x + 5, palette->y + 5, - 1.0f, 1.0f, 1.0f); - - float y = palette->y + 25 - palette->scroll_y; - - for (int c = 0; c < palette->category_count; c++) { - PaletteCategory* cat = &palette->categories[c]; - - // 绘制分类标题 - block_renderer_add_quad(renderer, palette->x + 2, y, palette->width - 4, 20, - 0.25f, 0.25f, 0.3f, 1.0f); - - const char* arrow = cat->expanded ? "[-]" : "[+]"; - char title[128]; - snprintf(title, 128, "%s %s (%d)", arrow, cat->name, cat->block_count); - block_renderer_draw_text(renderer, title, palette->x + 5, y + 3, - 0.9f, 0.9f, 0.9f); - - y += 22; - - if (!cat->expanded) continue; - - // 绘制积木列表 - for (int b = 0; b < cat->block_count; b++) { - const BlockTypeInfo* info = block_type_get_info(cat->blocks[b]); - if (!info) continue; - - // 搜索过滤 - if (palette->search_active && palette->search_text[0]) { - if (strstr(info->name, palette->search_text) == NULL && - strstr(info->label, palette->search_text) == NULL) { - continue; - } - } - - // 绘制积木预览 - block_renderer_add_quad(renderer, palette->x + 5, y, palette->width - 10, 18, - info->color.r, info->color.g, info->color.b, info->color.a); - - block_renderer_draw_text(renderer, info->label, palette->x + 10, y + 3, - 1.0f, 1.0f, 1.0f); - - y += 20; - } - - y += 5; - } -} - -BlockType palette_handle_click(BlockPalette* palette, float mx, float my) { - float y = palette->y + 25 - palette->scroll_y; - - for (int c = 0; c < palette->category_count; c++) { - PaletteCategory* cat = &palette->categories[c]; - - // 检查分类标题点击 - if (mx >= palette->x && mx <= palette->x + palette->width && - my >= y && my <= y + 20) { - cat->expanded = !cat->expanded; - return -1; - } - - y += 22; - - if (!cat->expanded) continue; - - // 检查积木点击 - for (int b = 0; b < cat->block_count; b++) { - if (mx >= palette->x + 5 && mx <= palette->x + palette->width - 5 && - my >= y && my <= y + 18) { - return cat->blocks[b]; - } - y += 20; - } - - y += 5; - } - - return -1; -} - -void palette_search(BlockPalette* palette, const char* text) { - if (text) { - strncpy(palette->search_text, text, 127); - palette->search_active = 1; - } else { - palette->search_text[0] = '\0'; - palette->search_active = 0; - } -} diff --git a/Engine/VisualScript/block_palette.h b/Engine/VisualScript/block_palette.h deleted file mode 100644 index 868b0dc..0000000 --- a/Engine/VisualScript/block_palette.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -// ============================================================================ -// block_palette.h - 积木面板 -// ============================================================================ - -#include "block_types.h" -#include "block_workspace.h" - -#define MAX_PALETTE_CATEGORIES 16 - -typedef struct { - char name[64]; - BlockType blocks[64]; - int block_count; - int expanded; -} PaletteCategory; - -typedef struct BlockPalette { - PaletteCategory categories[MAX_PALETTE_CATEGORIES]; - int category_count; - - float x, y, width, height; - float scroll_y; - - char search_text[128]; - int search_active; -} BlockPalette; - -// 初始化 -void palette_init(BlockPalette* palette); - -// 添加积木到面板 (按分类) -void palette_add_block(BlockPalette* palette, BlockType type); - -struct BlockRenderer; -void palette_render(BlockPalette* palette, struct BlockRenderer* renderer); - -// 处理点击 -BlockType palette_handle_click(BlockPalette* palette, float mx, float my); - -// 搜索 -void palette_search(BlockPalette* palette, const char* text); diff --git a/Engine/VisualScript/block_renderer.c b/Engine/VisualScript/block_renderer.c deleted file mode 100644 index 8d42ee4..0000000 --- a/Engine/VisualScript/block_renderer.c +++ /dev/null @@ -1,190 +0,0 @@ -#include "block_renderer.h" -#include "block_core.h" -#include -#include -#include - -// 5x7 位图字体 (列优先, LSB 在上) -#include "block_font.inc" - -int block_renderer_init(BlockRenderer* renderer, void* device, void* context) { - memset(renderer, 0, sizeof(BlockRenderer)); - renderer->device = (ID3D11Device*)device; - renderer->context = (ID3D11DeviceContext*)context; - renderer->vertex_capacity = 65536; - renderer->vertex_data = (float*)malloc(renderer->vertex_capacity * 7 * sizeof(float)); - renderer->index_capacity = 65536; - renderer->index_data = (uint32_t*)malloc(renderer->index_capacity * sizeof(uint32_t)); - return 1; -} - -void block_renderer_shutdown(BlockRenderer* renderer) { - if (renderer->vertex_data) free(renderer->vertex_data); - if (renderer->index_data) free(renderer->index_data); - if (renderer->vertex_buffer) renderer->vertex_buffer->lpVtbl->Release(renderer->vertex_buffer); - if (renderer->index_buffer) renderer->index_buffer->lpVtbl->Release(renderer->index_buffer); - if (renderer->vertex_shader) renderer->vertex_shader->lpVtbl->Release(renderer->vertex_shader); - if (renderer->pixel_shader) renderer->pixel_shader->lpVtbl->Release(renderer->pixel_shader); - if (renderer->input_layout) renderer->input_layout->lpVtbl->Release(renderer->input_layout); - memset(renderer, 0, sizeof(BlockRenderer)); -} - -void block_renderer_begin(BlockRenderer* renderer) { - renderer->vertex_count = 0; - renderer->index_count = 0; -} - -void block_renderer_end(BlockRenderer* renderer) { - if (renderer->vertex_count == 0) return; - ID3D11DeviceContext* ctx = renderer->context; - - D3D11_MAPPED_SUBRESOURCE mapped; - if (SUCCEEDED(ctx->lpVtbl->Map(ctx, (ID3D11Resource*)renderer->vertex_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped))) { - memcpy(mapped.pData, renderer->vertex_data, renderer->vertex_count * 7 * sizeof(float)); - ctx->lpVtbl->Unmap(ctx, (ID3D11Resource*)renderer->vertex_buffer, 0); - } - - if (renderer->index_count > 0) { - if (SUCCEEDED(ctx->lpVtbl->Map(ctx, (ID3D11Resource*)renderer->index_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped))) { - memcpy(mapped.pData, renderer->index_data, renderer->index_count * sizeof(uint32_t)); - ctx->lpVtbl->Unmap(ctx, (ID3D11Resource*)renderer->index_buffer, 0); - } - } - - UINT stride = 7 * sizeof(float); - UINT offset = 0; - ID3D11Buffer* vb = renderer->vertex_buffer; - ctx->lpVtbl->IASetVertexBuffers(ctx, 0, 1, &vb, &stride, &offset); - - if (renderer->index_buffer) { - ctx->lpVtbl->IASetIndexBuffer(ctx, renderer->index_buffer, DXGI_FORMAT_R32_UINT, 0); - } - ctx->lpVtbl->IASetInputLayout(ctx, renderer->input_layout); - ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ctx->lpVtbl->VSSetShader(ctx, renderer->vertex_shader, NULL, 0); - ctx->lpVtbl->PSSetShader(ctx, renderer->pixel_shader, NULL, 0); - - if (renderer->index_count > 0) { - ctx->lpVtbl->DrawIndexed(ctx, renderer->index_count, 0, 0); - } else { - ctx->lpVtbl->Draw(ctx, renderer->vertex_count, 0); - } -} - -void block_renderer_add_quad(BlockRenderer* renderer, float x, float y, float w, float h, float r, float g, float b, float a) { - if (renderer->vertex_count + 4 > renderer->vertex_capacity) return; - if (renderer->index_count + 6 > renderer->index_capacity) return; - - uint32_t base = renderer->vertex_count; - float* v = renderer->vertex_data + base * 7; - - v[0*7+0] = x; v[0*7+1] = y; v[0*7+2] = 0; v[0*7+3] = r; v[0*7+4] = g; v[0*7+5] = b; v[0*7+6] = a; - v[1*7+0] = x + w; v[1*7+1] = y; v[1*7+2] = 0; v[1*7+3] = r; v[1*7+4] = g; v[1*7+5] = b; v[1*7+6] = a; - v[2*7+0] = x + w; v[2*7+1] = y + h; v[2*7+2] = 0; v[2*7+3] = r; v[2*7+4] = g; v[2*7+5] = b; v[2*7+6] = a; - v[3*7+0] = x; v[3*7+1] = y + h; v[3*7+2] = 0; v[3*7+3] = r; v[3*7+4] = g; v[3*7+5] = b; v[3*7+6] = a; - - renderer->vertex_count += 4; - - renderer->index_data[renderer->index_count++] = base + 0; - renderer->index_data[renderer->index_count++] = base + 1; - renderer->index_data[renderer->index_count++] = base + 2; - renderer->index_data[renderer->index_count++] = base + 0; - renderer->index_data[renderer->index_count++] = base + 2; - renderer->index_data[renderer->index_count++] = base + 3; -} - -void block_renderer_add_line(BlockRenderer* renderer, float x1, float y1, float x2, float y2, float r, float g, float b, float a) { - float dx = x2 - x1; - float dy = y2 - y1; - float len = sqrtf(dx * dx + dy * dy); - if (len < 0.001f) return; - - const float thickness = 1.0f; - float nx = -dy / len * thickness * 0.5f; - float ny = dx / len * thickness * 0.5f; - - if (renderer->vertex_count + 4 > renderer->vertex_capacity) return; - if (renderer->index_count + 6 > renderer->index_capacity) return; - - uint32_t base = renderer->vertex_count; - float* v = renderer->vertex_data + base * 7; - - v[0*7+0] = x1 + nx; v[0*7+1] = y1 + ny; v[0*7+2] = 0; v[0*7+3] = r; v[0*7+4] = g; v[0*7+5] = b; v[0*7+6] = a; - v[1*7+0] = x2 + nx; v[1*7+1] = y2 + ny; v[1*7+2] = 0; v[1*7+3] = r; v[1*7+4] = g; v[1*7+5] = b; v[1*7+6] = a; - v[2*7+0] = x2 - nx; v[2*7+1] = y2 - ny; v[2*7+2] = 0; v[2*7+3] = r; v[2*7+4] = g; v[2*7+5] = b; v[2*7+6] = a; - v[3*7+0] = x1 - nx; v[3*7+1] = y1 - ny; v[3*7+2] = 0; v[3*7+3] = r; v[3*7+4] = g; v[3*7+5] = b; v[3*7+6] = a; - - renderer->vertex_count += 4; - - renderer->index_data[renderer->index_count++] = base + 0; - renderer->index_data[renderer->index_count++] = base + 1; - renderer->index_data[renderer->index_count++] = base + 2; - renderer->index_data[renderer->index_count++] = base + 0; - renderer->index_data[renderer->index_count++] = base + 2; - renderer->index_data[renderer->index_count++] = base + 3; -} - -static void block_renderer_add_bezier(BlockRenderer* renderer, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2, float r, float g, float b, float a) { - int segments = 16; - float prev_x = x1, prev_y = y1; - for (int i = 1; i <= segments; i++) { - float t = (float)i / segments; - float mt = 1.0f - t; - float px = mt*mt*mt*x1 + 3*mt*mt*t*cx1 + 3*mt*t*t*cx2 + t*t*t*x2; - float py = mt*mt*mt*y1 + 3*mt*mt*t*cy1 + 3*mt*t*t*cy2 + t*t*t*y2; - block_renderer_add_line(renderer, prev_x, prev_y, px, py, r, g, b, a); - prev_x = px; - prev_y = py; - } -} - -void block_renderer_draw_block(BlockRenderer* renderer, Block* block, float view_x, float view_y, float zoom) { - float x = (block->x - view_x) * zoom; - float y = (block->y - view_y) * zoom; - float w = block->width * zoom; - float h = block->height * zoom; - - block_renderer_add_quad(renderer, x, y, w, h, 0.3f, 0.3f, 0.35f, 1.0f); - block_renderer_add_quad(renderer, x, y, w, 20 * zoom, 0.2f, 0.2f, 0.25f, 1.0f); - - if (block->label[0]) { - block_renderer_draw_text(renderer, block->label, x + 4.0f * zoom, y + 4.0f * zoom, 0.9f, 0.9f, 0.9f); - } -} - -void block_renderer_draw_connection(BlockRenderer* renderer, BlockSlot* from, BlockSlot* to, float view_x, float view_y, float zoom) { - float x1 = (from->owner->x + from->x - view_x) * zoom; - float y1 = (from->owner->y + from->y - view_y) * zoom; - float x2 = (to->owner->x + to->x - view_x) * zoom; - float y2 = (to->owner->y + to->y - view_y) * zoom; - - float dx = fabsf(x2 - x1) * 0.5f; - if (dx < 50.0f) dx = 50.0f; - - block_renderer_add_bezier(renderer, x1, y1, x1 + dx, y1, x2 - dx, y2, x2, y2, 0.8f, 0.8f, 0.2f, 1.0f); -} - -void block_renderer_draw_text(BlockRenderer* renderer, const char* text, float x, float y, float r, float g, float b) { - if (!text) return; - const float scale = 2.0f; - const float advance = 5.0f * scale + 1.0f; - float cx = x; - for (const char* p = text; *p; ++p) { - unsigned char ch = (unsigned char)*p; - if (ch < 32 || ch > 127) ch = '?'; - int idx = ch - 32; - for (int col = 0; col < 5; ++col) { - uint8_t column = BLOCK_FONT[idx][col]; - for (int row = 0; row < 7; ++row) { - if (column & (1u << row)) { - block_renderer_add_quad(renderer, - cx + col * scale, - y + row * scale, - scale, scale, - r, g, b, 1.0f); - } - } - } - cx += advance; - } -} diff --git a/Engine/VisualScript/block_renderer.h b/Engine/VisualScript/block_renderer.h deleted file mode 100644 index d3f5075..0000000 --- a/Engine/VisualScript/block_renderer.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "block_workspace.h" -#include -#include - -typedef struct BlockRenderer { - ID3D11Device* device; - ID3D11DeviceContext* context; - ID3D11Buffer* vertex_buffer; - ID3D11Buffer* index_buffer; - ID3D11VertexShader* vertex_shader; - ID3D11PixelShader* pixel_shader; - ID3D11InputLayout* input_layout; - - float* vertex_data; - int vertex_count; - int vertex_capacity; - uint32_t* index_data; - int index_count; - int index_capacity; -} BlockRenderer; - -int block_renderer_init(BlockRenderer* renderer, void* device, void* context); -void block_renderer_shutdown(BlockRenderer* renderer); -void block_renderer_begin(BlockRenderer* renderer); -void block_renderer_end(BlockRenderer* renderer); -void block_renderer_draw_block(BlockRenderer* renderer, Block* block, float view_x, float view_y, float zoom); -void block_renderer_draw_connection(BlockRenderer* renderer, BlockSlot* from, BlockSlot* to, float view_x, float view_y, float zoom); -void block_renderer_draw_text(BlockRenderer* renderer, const char* text, float x, float y, float r, float g, float b); -void block_renderer_add_quad(BlockRenderer* renderer, float x, float y, float w, float h, float r, float g, float b, float a); -void block_renderer_add_line(BlockRenderer* renderer, float x1, float y1, float x2, float y2, float r, float g, float b, float a); diff --git a/Engine/VisualScript/block_serializer.c b/Engine/VisualScript/block_serializer.c deleted file mode 100644 index 7ad6bed..0000000 --- a/Engine/VisualScript/block_serializer.c +++ /dev/null @@ -1,415 +0,0 @@ -// ============================================================================ -// block_serializer.c - JSON 序列化实现 -// ============================================================================ - -#include "block_serializer.h" -#include "block_types.h" -#include -#include -#include - -// 简单的 JSON 生成器 -typedef struct { - char* buffer; - size_t size; - size_t capacity; -} JsonBuffer; - -static void json_init(JsonBuffer* buf) { - buf->capacity = 4096; - buf->buffer = (char*)malloc(buf->capacity); - buf->size = 0; - buf->buffer[0] = '\0'; -} - -static void json_append(JsonBuffer* buf, const char* str) { - size_t len = strlen(str); - if (buf->size + len + 1 > buf->capacity) { - buf->capacity = (buf->size + len + 1) * 2; - buf->buffer = (char*)realloc(buf->buffer, buf->capacity); - } - memcpy(buf->buffer + buf->size, str, len + 1); - buf->size += len; -} - -int serializer_save(BlockWorkspace* ws, const char* filepath) { - char* json = serializer_save_to_string(ws); - if (!json) return 0; - - FILE* f = fopen(filepath, "w"); - if (!f) { - free(json); - return 0; - } - - fprintf(f, "%s", json); - fclose(f); - free(json); - return 1; -} - -int serializer_load(BlockWorkspace* ws, const char* filepath) { - FILE* f = fopen(filepath, "r"); - if (!f) return 0; - - fseek(f, 0, SEEK_END); - long size = ftell(f); - fseek(f, 0, SEEK_SET); - - char* json = (char*)malloc(size + 1); - fread(json, 1, size, f); - json[size] = '\0'; - fclose(f); - - int result = serializer_load_from_string(ws, json); - free(json); - return result; -} - -char* serializer_save_to_string(BlockWorkspace* ws) { - JsonBuffer buf; - json_init(&buf); - - json_append(&buf, "{\n"); - json_append(&buf, " \"version\": \"1.0\",\n"); - - // 保存积木 - json_append(&buf, " \"blocks\": [\n"); - for (int i = 0; i < ws->block_count; i++) { - Block* block = ws->blocks[i]; - const BlockTypeInfo* info = block_type_get_info(block->type); - - char tmp[256]; - snprintf(tmp, 256, " {\n"); - json_append(&buf, tmp); - - snprintf(tmp, 256, " \"id\": %d,\n", block->id); - json_append(&buf, tmp); - - snprintf(tmp, 256, " \"type\": \"%s\",\n", info ? info->name : "unknown"); - json_append(&buf, tmp); - - snprintf(tmp, 256, " \"x\": %.1f,\n", block->x); - json_append(&buf, tmp); - - snprintf(tmp, 256, " \"y\": %.1f,\n", block->y); - json_append(&buf, tmp); - - snprintf(tmp, 256, " \"label\": \"%s\"", block->label); - json_append(&buf, tmp); - - // 保存输入槽默认值 - if (block->input_count > 0) { - json_append(&buf, ",\n \"inputs\": [\n"); - for (int j = 0; j < block->input_count; j++) { - BlockSlot* slot = &block->inputs[j]; - SlotValue* val = &slot->value; - switch (val->type) { - case SLOT_VALUE_NUMBER: - snprintf(tmp, 256, " {\"type\": \"number\", \"value\": %.6g}%s\n", val->as.number, j < block->input_count - 1 ? "," : ""); - break; - case SLOT_VALUE_STRING: - snprintf(tmp, 256, " {\"type\": \"string\", \"value\": \"%s\"}%s\n", val->as.string, j < block->input_count - 1 ? "," : ""); - break; - case SLOT_VALUE_BOOLEAN: - snprintf(tmp, 256, " {\"type\": \"boolean\", \"value\": %s}%s\n", val->as.boolean ? "true" : "false", j < block->input_count - 1 ? "," : ""); - break; - default: - snprintf(tmp, 256, " {\"type\": \"number\", \"value\": 0}%s\n", j < block->input_count - 1 ? "," : ""); - break; - } - json_append(&buf, tmp); - } - json_append(&buf, " ]"); - } - - json_append(&buf, "\n"); - json_append(&buf, i < ws->block_count - 1 ? " },\n" : " }\n"); - } - json_append(&buf, " ],\n"); - - // 保存连接 - json_append(&buf, " \"connections\": [\n"); - for (int i = 0; i < ws->connection_count; i++) { - BlockConnection* conn = &ws->connections[i]; - char tmp[128]; - snprintf(tmp, 128, " {\"from\": %d, \"to\": %d}%s\n", - conn->from ? conn->from->owner->id : 0, - conn->to ? conn->to->owner->id : 0, - i < ws->connection_count - 1 ? "," : ""); - json_append(&buf, tmp); - } - json_append(&buf, " ]\n"); - - json_append(&buf, "}\n"); - - return buf.buffer; -} - -// 跳过空白字符 -static const char* skip_ws(const char* p) { - while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') p++; - return p; -} - -// 查找字符串值,返回指向引号内内容的指针,并在 *len 中设置长度 -static const char* parse_json_string(const char* p, int* len) { - p = skip_ws(p); - if (*p != '"') return NULL; - p++; - const char* start = p; - while (*p && *p != '"') p++; - if (*p != '"') return NULL; - *len = (int)(p - start); - return start; -} - -// 查找数字值,返回指向数字开头的指针 -static const char* parse_json_number(const char* p, float* out) { - p = skip_ws(p); - const char* start = p; - if (*p == '-') p++; - while (*p >= '0' && *p <= '9') p++; - if (*p == '.') { - p++; - while (*p >= '0' && *p <= '9') p++; - } - if (p == start) return NULL; - *out = (float)strtod(start, NULL); - return p; -} - -int serializer_load_from_string(BlockWorkspace* ws, const char* json_str) { - workspace_clear(ws); - block_types_init(); - - // 解析 blocks 数组 - const char* blocks_key = strstr(json_str, "\"blocks\""); - if (!blocks_key) return 0; - const char* p = blocks_key + 8; - p = skip_ws(p); - if (*p != ':') return 0; - p++; - p = skip_ws(p); - if (*p != '[') return 0; - p++; - - while (1) { - p = skip_ws(p); - if (*p == ']') { p++; break; } - if (*p != '{') return 0; - p++; - - int id = 0; - char type_name[64] = {0}; - char label[64] = {0}; - float x = 0, y = 0; - SlotValue input_values[MAX_BLOCK_INPUTS]; - int input_count = 0; - - while (1) { - p = skip_ws(p); - if (*p == '}') { p++; break; } - - int key_len = 0; - const char* key = parse_json_string(p, &key_len); - if (!key) return 0; - p = key + key_len + 1; - p = skip_ws(p); - if (*p != ':') return 0; - p++; - - if (key_len == 2 && strncmp(key, "id", 2) == 0) { - float fv; p = parse_json_number(p, &fv); id = (int)fv; - } else if (key_len == 4 && strncmp(key, "type", 4) == 0) { - int val_len = 0; - const char* val = parse_json_string(p, &val_len); - if (val) { - if (val_len >= (int)sizeof(type_name)) val_len = (int)sizeof(type_name) - 1; - strncpy(type_name, val, val_len); - type_name[val_len] = '\0'; - p = val + val_len + 1; - } - } else if (key_len == 1 && *key == 'x') { - p = parse_json_number(p, &x); - } else if (key_len == 1 && *key == 'y') { - p = parse_json_number(p, &y); - } else if (key_len == 5 && strncmp(key, "label", 5) == 0) { - int val_len = 0; - const char* val = parse_json_string(p, &val_len); - if (val) { - if (val_len >= (int)sizeof(label)) val_len = (int)sizeof(label) - 1; - strncpy(label, val, val_len); - label[val_len] = '\0'; - p = val + val_len + 1; - } - } else if (key_len == 6 && strncmp(key, "inputs", 6) == 0) { - p = skip_ws(p); - if (*p == '[') { - p++; - input_count = 0; - while (1) { - p = skip_ws(p); - if (*p == ']') { p++; break; } - if (*p != '{') break; - p++; - - char iv_type[16] = {0}; - float fv = 0; - int bv = 0; - char sval_str[256] = {0}; - while (1) { - p = skip_ws(p); - if (*p == '}') { p++; break; } - int ik_len = 0; - const char* ik = parse_json_string(p, &ik_len); - if (!ik) break; - p = ik + ik_len + 1; - p = skip_ws(p); - if (*p != ':') break; - p++; - - if (ik_len == 4 && strncmp(ik, "type", 4) == 0) { - int iv_len = 0; - const char* iv = parse_json_string(p, &iv_len); - if (iv) { - if (iv_len >= (int)sizeof(iv_type)) iv_len = (int)sizeof(iv_type) - 1; - strncpy(iv_type, iv, iv_len); - iv_type[iv_len] = '\0'; - p = iv + iv_len + 1; - } - } else if (ik_len == 5 && strncmp(ik, "value", 5) == 0) { - p = skip_ws(p); - if (*p == '"') { - int sv_len = 0; - const char* sval = parse_json_string(p, &sv_len); - if (sval) { - if (sv_len >= (int)sizeof(sval_str)) sv_len = (int)sizeof(sval_str) - 1; - strncpy(sval_str, sval, sv_len); - sval_str[sv_len] = '\0'; - p = sval + sv_len + 1; - } - } else if (strncmp(p, "true", 4) == 0) { - bv = 1; p += 4; - } else if (strncmp(p, "false", 5) == 0) { - bv = 0; p += 5; - } else { - p = parse_json_number(p, &fv); - } - } else { - while (*p && *p != ',' && *p != '}') p++; - } - p = skip_ws(p); - if (*p == ',') p++; - } - // 暂存输入值 - if (input_count < MAX_BLOCK_INPUTS) { - SlotValue* sv = &input_values[input_count++]; - memset(sv, 0, sizeof(SlotValue)); - if (strcmp(iv_type, "number") == 0) { - sv->type = SLOT_VALUE_NUMBER; - sv->as.number = (double)fv; - } else if (strcmp(iv_type, "string") == 0) { - sv->type = SLOT_VALUE_STRING; - strncpy(sv->as.string, sval_str, sizeof(sv->as.string) - 1); - } else if (strcmp(iv_type, "boolean") == 0) { - sv->type = SLOT_VALUE_BOOLEAN; - sv->as.boolean = bv; - } else { - sv->type = SLOT_VALUE_NUMBER; - sv->as.number = 0; - } - } - p = skip_ws(p); - if (*p == ',') p++; - } - } - } else { - // 跳过未知值 (简单跳过直到逗号或右花括号) - while (*p && *p != ',' && *p != '}') p++; - } - - p = skip_ws(p); - if (*p == ',') p++; - } - - BlockType type = block_type_find_by_name(type_name); - if (type == BLOCK_TYPE_COUNT || type_name[0] == '\0') { - type = BLOCK_EVENT_START; // fallback - } - - Block* block = block_create(type, x, y); - if (block) { - block->id = id; - strncpy(block->label, label, sizeof(block->label) - 1); - block->label[sizeof(block->label) - 1] = '\0'; - for (int j = 0; j < input_count && j < block->input_count; j++) { - block->inputs[j].value = input_values[j]; - } - workspace_add_block(ws, block); - if (id >= ws->next_block_id) ws->next_block_id = id + 1; - } - - p = skip_ws(p); - if (*p == ',') p++; - } - - // 解析 connections 数组 - const char* conn_key = strstr(json_str, "\"connections\""); - if (conn_key) { - p = conn_key + 13; - p = skip_ws(p); - if (*p == ':') { - p++; - p = skip_ws(p); - if (*p == '[') { - p++; - while (1) { - p = skip_ws(p); - if (*p == ']') { p++; break; } - if (*p != '{') break; - p++; - - int from_id = -1, to_id = -1; - while (1) { - p = skip_ws(p); - if (*p == '}') { p++; break; } - - int key_len = 0; - const char* key = parse_json_string(p, &key_len); - if (!key) break; - p = key + key_len + 1; - p = skip_ws(p); - if (*p != ':') break; - p++; - - float fv = 0; - if (key_len == 4 && strncmp(key, "from", 4) == 0) { - p = parse_json_number(p, &fv); from_id = (int)fv; - } else if (key_len == 2 && strncmp(key, "to", 2) == 0) { - p = parse_json_number(p, &fv); to_id = (int)fv; - } else { - while (*p && *p != ',' && *p != '}') p++; - } - - p = skip_ws(p); - if (*p == ',') p++; - } - - if (from_id >= 0 && to_id >= 0) { - Block* from_block = workspace_find_block(ws, from_id); - Block* to_block = workspace_find_block(ws, to_id); - if (from_block && to_block && from_block->output_count > 0 && to_block->input_count > 0) { - workspace_add_connection(ws, &from_block->outputs[0], &to_block->inputs[0]); - } - } - - p = skip_ws(p); - if (*p == ',') p++; - } - } - } - } - - return 1; -} diff --git a/Engine/VisualScript/block_serializer.h b/Engine/VisualScript/block_serializer.h deleted file mode 100644 index 0914ca8..0000000 --- a/Engine/VisualScript/block_serializer.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -// ============================================================================ -// block_serializer.h - JSON 序列化 -// ============================================================================ - -#include "block_workspace.h" - -// 保存工作区到文件 -int serializer_save(BlockWorkspace* ws, const char* filepath); - -// 从文件加载工作区 -int serializer_load(BlockWorkspace* ws, const char* filepath); - -// 保存到字符串 -char* serializer_save_to_string(BlockWorkspace* ws); - -// 从字符串加载 -int serializer_load_from_string(BlockWorkspace* ws, const char* json_str); diff --git a/Engine/VisualScript/block_types.c b/Engine/VisualScript/block_types.c deleted file mode 100644 index 9ebaff2..0000000 --- a/Engine/VisualScript/block_types.c +++ /dev/null @@ -1,326 +0,0 @@ -// ============================================================================ -// block_types.c - 积木类型注册 -// ============================================================================ - -#include "block_types.h" -#include - -static BlockTypeInfo g_type_info[BLOCK_TYPE_COUNT]; -static int g_types_initialized = 0; - -void block_types_init(void) { - if (g_types_initialized) return; - - int i = 0; - - // === 事件积木 (红色) === - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_EVENT_START, "event_start", "on_start", "Events", - BLOCK_COLOR_EVENT, 0, 1, - {}, {SLOT_STATEMENT}, - {}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_EVENT_UPDATE, "event_update", "on_update", "Events", - BLOCK_COLOR_EVENT, 0, 1, - {}, {SLOT_STATEMENT}, - {}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_EVENT_COLLISION, "event_collision", "on_collision", "Events", - BLOCK_COLOR_EVENT, 1, 1, - {SLOT_VALUE_STRING}, {SLOT_STATEMENT}, - {"碰撞对象"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_EVENT_KEY_PRESSED, "event_key", "on_key_pressed", "Events", - BLOCK_COLOR_EVENT, 1, 1, - {SLOT_VALUE_STRING}, {SLOT_STATEMENT}, - {"按键"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_EVENT_MOUSE_CLICK, "event_mouse", "on_mouse_click", "Events", - BLOCK_COLOR_EVENT, 0, 1, - {}, {SLOT_STATEMENT}, - {}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_EVENT_TIMER, "event_timer", "on_timer", "Events", - BLOCK_COLOR_EVENT, 1, 1, - {SLOT_VALUE_NUMBER}, {SLOT_STATEMENT}, - {"间隔(秒)"}, {"执行"} - }; - - // === 动作积木 (蓝色) === - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_MOVE, "action_move", "move", "Actions", - BLOCK_COLOR_ACTION, 4, 1, - {SLOT_STATEMENT, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_STATEMENT}, - {"执行", "X", "Y", "Z"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_ROTATE, "action_rotate", "rotate", "Actions", - BLOCK_COLOR_ACTION, 4, 1, - {SLOT_STATEMENT, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_STATEMENT}, - {"执行", "X", "Y", "Z"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_SCALE, "action_scale", "scale", "Actions", - BLOCK_COLOR_ACTION, 4, 1, - {SLOT_STATEMENT, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_STATEMENT}, - {"执行", "X", "Y", "Z"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_SET_POSITION, "action_setpos", "set_position", "Actions", - BLOCK_COLOR_ACTION, 4, 1, - {SLOT_STATEMENT, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_STATEMENT}, - {"执行", "X", "Y", "Z"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_SET_ROTATION, "action_setrot", "set_rotation", "Actions", - BLOCK_COLOR_ACTION, 4, 1, - {SLOT_STATEMENT, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_STATEMENT}, - {"执行", "X", "Y", "Z"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_PLAY_SOUND, "action_sound", "play_sound", "Actions", - BLOCK_COLOR_ACTION, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_STRING}, - {SLOT_STATEMENT}, - {"执行", "音效名"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_DESTROY, "action_destroy", "destroy", "Actions", - BLOCK_COLOR_ACTION, 1, 1, - {SLOT_STATEMENT}, - {SLOT_STATEMENT}, - {"执行"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_ACTION_INSTANTIATE, "action_instantiate", "instantiate", "Actions", - BLOCK_COLOR_ACTION, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_STRING}, - {SLOT_STATEMENT}, - {"执行", "预制体"}, {"执行"} - }; - - // === 控制积木 (绿色) === - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_CONTROL_IF, "control_if", "if", "Control", - BLOCK_COLOR_CONTROL, 2, 2, - {SLOT_STATEMENT, SLOT_VALUE_BOOLEAN}, - {SLOT_STATEMENT, SLOT_STATEMENT}, - {"执行", "条件"}, {"Then", "Else"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_CONTROL_IF_ELSE, "control_ifelse", "if_else", "Control", - BLOCK_COLOR_CONTROL, 2, 2, - {SLOT_STATEMENT, SLOT_VALUE_BOOLEAN}, - {SLOT_STATEMENT, SLOT_STATEMENT}, - {"执行", "条件"}, {"Then", "Else"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_CONTROL_REPEAT, "control_repeat", "repeat", "Control", - BLOCK_COLOR_CONTROL, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_BOOLEAN}, - {SLOT_STATEMENT}, - {"执行", "条件"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_CONTROL_REPEAT_TIMES, "control_count", "repeat_times", "Control", - BLOCK_COLOR_CONTROL, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_NUMBER}, - {SLOT_STATEMENT}, - {"执行", "次数"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_CONTROL_WHILE, "control_while", "while", "Control", - BLOCK_COLOR_CONTROL, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_BOOLEAN}, - {SLOT_STATEMENT}, - {"执行", "条件"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_CONTROL_WAIT, "control_wait", "wait", "Control", - BLOCK_COLOR_CONTROL, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_NUMBER}, - {SLOT_STATEMENT}, - {"执行", "秒数"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_CONTROL_FUNCTION_DEF, "control_funcdef", "function_def", "Control", - BLOCK_COLOR_CONTROL, 1, 1, - {SLOT_STATEMENT}, - {SLOT_STATEMENT}, - {"执行"}, {"执行"} - }; - - // === 运算积木 (橙色) === - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_ADD, "op_add", "+", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_VALUE_NUMBER}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_SUB, "op_sub", "-", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_VALUE_NUMBER}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_MUL, "op_mul", "*", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_VALUE_NUMBER}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_DIV, "op_div", "/", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_VALUE_NUMBER}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_MOD, "op_mod", "%", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_VALUE_NUMBER}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_EQUALS, "op_eq", "==", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_ANY, SLOT_VALUE_ANY}, - {SLOT_VALUE_BOOLEAN}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_NOT_EQUALS, "op_neq", "!=", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_ANY, SLOT_VALUE_ANY}, - {SLOT_VALUE_BOOLEAN}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_GREATER, "op_gt", ">", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_VALUE_BOOLEAN}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_LESS, "op_lt", "<", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_NUMBER, SLOT_VALUE_NUMBER}, - {SLOT_VALUE_BOOLEAN}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_AND, "op_and", "AND", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_BOOLEAN, SLOT_VALUE_BOOLEAN}, - {SLOT_VALUE_BOOLEAN}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_OR, "op_or", "OR", "Operators", - BLOCK_COLOR_OPERATOR, 2, 1, - {SLOT_VALUE_BOOLEAN, SLOT_VALUE_BOOLEAN}, - {SLOT_VALUE_BOOLEAN}, - {"A", "B"}, {"结果"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_OP_NOT, "op_not", "NOT", "Operators", - BLOCK_COLOR_OPERATOR, 1, 1, - {SLOT_VALUE_BOOLEAN}, - {SLOT_VALUE_BOOLEAN}, - {"A"}, {"结果"} - }; - - // === 变量积木 (紫色) === - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_VAR_GET, "var_get", "get_variable", "Variables", - BLOCK_COLOR_VARIABLE, 0, 1, - {}, {SLOT_VALUE_ANY}, - {}, {"值"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_VAR_SET, "var_set", "set_variable", "Variables", - BLOCK_COLOR_VARIABLE, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_ANY}, - {SLOT_STATEMENT}, - {"执行", "值"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_VAR_CREATE, "var_create", "create_variable", "Variables", - BLOCK_COLOR_VARIABLE, 1, 1, - {SLOT_STATEMENT}, - {SLOT_STATEMENT}, - {"执行"}, {"执行"} - }; - - // === 函数积木 (黄色) === - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_FUNC_CALL, "func_call", "call_function", "Functions", - BLOCK_COLOR_FUNCTION, 2, 1, - {SLOT_STATEMENT, SLOT_VALUE_STRING}, - {SLOT_STATEMENT}, - {"执行", "函数名"}, {"执行"} - }; - g_type_info[i++] = (BlockTypeInfo){ - BLOCK_FUNC_RETURN, "func_return", "return", "Functions", - BLOCK_COLOR_FUNCTION, 2, 0, - {SLOT_STATEMENT, SLOT_VALUE_ANY}, - {}, - {"执行", "返回值"} - }; - - g_types_initialized = 1; -} - -const BlockTypeInfo* block_type_get_info(BlockType type) { - if (type < 0 || type >= BLOCK_TYPE_COUNT) return NULL; - return &g_type_info[type]; -} - -const BlockTypeInfo* block_type_get_all(int* count) { - *count = BLOCK_TYPE_COUNT; - return g_type_info; -} - -BlockType block_type_find_by_name(const char* name) { - for (int i = 0; i < BLOCK_TYPE_COUNT; i++) { - if (strcmp(g_type_info[i].name, name) == 0) { - return g_type_info[i].type; - } - } - return -1; -} - -const char** block_type_get_categories(int* count) { - static const char* categories[] = { - "Events", "Actions", "Control", "Operators", "Variables", "Functions" - }; - *count = 6; - return categories; -} - -const BlockType* block_type_get_by_category(const char* category, int* count) { - static BlockType buffer[BLOCK_TYPE_COUNT]; - *count = 0; - for (int i = 0; i < BLOCK_TYPE_COUNT; i++) { - if (strcmp(g_type_info[i].category, category) == 0) { - buffer[(*count)++] = g_type_info[i].type; - } - } - return buffer; -} diff --git a/Engine/VisualScript/block_types.h b/Engine/VisualScript/block_types.h deleted file mode 100644 index 2577576..0000000 --- a/Engine/VisualScript/block_types.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -// ============================================================================ -// block_types.h - 积木类型定义 -// ============================================================================ - -#include "block_core.h" - -// 获取积木类型信息 -const BlockTypeInfo* block_type_get_info(BlockType type); - -// 获取所有类型信息 -const BlockTypeInfo* block_type_get_all(int* count); - -// 按名称查找类型 -BlockType block_type_find_by_name(const char* name); - -// 按分类获取类型列表 -const BlockType* block_type_get_by_category(const char* category, int* count); - -// 获取所有分类 -const char** block_type_get_categories(int* count); - -// 初始化所有积木类型 -void block_types_init(void); diff --git a/Engine/VisualScript/block_workspace.c b/Engine/VisualScript/block_workspace.c deleted file mode 100644 index 84939bd..0000000 --- a/Engine/VisualScript/block_workspace.c +++ /dev/null @@ -1,171 +0,0 @@ -// ============================================================================ -// block_workspace.c - 工作区管理实现 -// ============================================================================ - -#include "block_workspace.h" -#include -#include -#include - -BlockWorkspace* workspace_create(void) { - BlockWorkspace* ws = (BlockWorkspace*)calloc(1, sizeof(BlockWorkspace)); - if (!ws) return NULL; - - ws->zoom = 1.0f; - ws->next_block_id = 1; - - return ws; -} - -void workspace_destroy(BlockWorkspace* ws) { - if (!ws) return; - workspace_clear(ws); - free(ws); -} - -int workspace_add_block(BlockWorkspace* ws, Block* block) { - if (ws->block_count >= MAX_WORKSPACE_BLOCKS) return -1; - if (!block) return -1; - if (block->id <= 0) block->id = ws->next_block_id++; - else if (block->id >= ws->next_block_id) ws->next_block_id = block->id + 1; - block->workspace = ws; - ws->blocks[ws->block_count++] = block; - return block->id; -} - -void workspace_remove_block(BlockWorkspace* ws, int block_id) { - // 先移除所有相关连接 - for (int i = ws->connection_count - 1; i >= 0; i--) { - BlockSlot* from = ws->connections[i].from; - BlockSlot* to = ws->connections[i].to; - if (from && from->owner && from->owner->id == block_id) { - workspace_remove_connection(ws, from); - } else if (to && to->owner && to->owner->id == block_id) { - workspace_remove_connection(ws, to); - } - } - - // 移除积木 - for (int i = 0; i < ws->block_count; i++) { - if (ws->blocks[i]->id == block_id) { - block_destroy(ws->blocks[i]); - ws->blocks[i] = ws->blocks[ws->block_count - 1]; - ws->block_count--; - return; - } - } -} - -bool workspace_add_connection(BlockWorkspace* ws, BlockSlot* from, BlockSlot* to) { - if (ws->connection_count >= MAX_WORKSPACE_CONNECTIONS) return false; - if (!from || !to) return false; - - // 检查是否已连接 - for (int i = 0; i < ws->connection_count; i++) { - if (ws->connections[i].from == from || ws->connections[i].to == to) { - return false; // 已有连接 - } - } - - // 建立连接 - block_connect(from, to); - - BlockConnection* conn = &ws->connections[ws->connection_count++]; - conn->from = from; - conn->to = to; - - return true; -} - -void workspace_remove_connection(BlockWorkspace* ws, BlockSlot* slot) { - for (int i = ws->connection_count - 1; i >= 0; i--) { - if (ws->connections[i].from == slot || ws->connections[i].to == slot) { - block_disconnect(ws->connections[i].from); - ws->connections[i] = ws->connections[ws->connection_count - 1]; - ws->connection_count--; - } - } -} - -void workspace_remove_all_connections(BlockWorkspace* ws, Block* block) { - if (!block) return; - - for (int i = ws->connection_count - 1; i >= 0; i--) { - BlockSlot* from = ws->connections[i].from; - BlockSlot* to = ws->connections[i].to; - if ((from && from->owner == block) || (to && to->owner == block)) { - block_disconnect(from); - ws->connections[i] = ws->connections[ws->connection_count - 1]; - ws->connection_count--; - } - } -} - -Block* workspace_find_block(BlockWorkspace* ws, int block_id) { - for (int i = 0; i < ws->block_count; i++) { - if (ws->blocks[i]->id == block_id) return ws->blocks[i]; - } - return NULL; -} - -Block* workspace_find_block_at(BlockWorkspace* ws, float x, float y) { - // 从后往前找 (最后添加的在最上面) - for (int i = ws->block_count - 1; i >= 0; i--) { - if (block_contains_point(ws->blocks[i], x, y)) { - return ws->blocks[i]; - } - } - return NULL; -} - -BlockSlot* workspace_find_slot_at(BlockWorkspace* ws, float x, float y) { - float threshold = 10.0f; - - for (int i = ws->block_count - 1; i >= 0; i--) { - Block* block = ws->blocks[i]; - - // 检查输出槽位 - for (int j = 0; j < block->output_count; j++) { - BlockSlot* slot = &block->outputs[j]; - float sx, sy; - block_slot_world_pos(slot, &sx, &sy); - float dx = x - sx; - float dy = y - sy; - if (dx * dx + dy * dy < threshold * threshold) { - return slot; - } - } - - // 检查输入槽位 - for (int j = 0; j < block->input_count; j++) { - BlockSlot* slot = &block->inputs[j]; - float sx, sy; - block_slot_world_pos(slot, &sx, &sy); - float dx = x - sx; - float dy = y - sy; - if (dx * dx + dy * dy < threshold * threshold) { - return slot; - } - } - } - return NULL; -} - -void workspace_screen_to_world(BlockWorkspace* ws, float sx, float sy, float* wx, float* wy) { - *wx = (sx / ws->zoom) + ws->view_x; - *wy = (sy / ws->zoom) + ws->view_y; -} - -void workspace_world_to_screen(BlockWorkspace* ws, float wx, float wy, float* sx, float* sy) { - *sx = (wx - ws->view_x) * ws->zoom; - *sy = (wy - ws->view_y) * ws->zoom; -} - -void workspace_clear(BlockWorkspace* ws) { - for (int i = 0; i < ws->block_count; i++) { - block_destroy(ws->blocks[i]); - } - ws->block_count = 0; - ws->connection_count = 0; - ws->selected_block = NULL; -} diff --git a/Engine/VisualScript/block_workspace.h b/Engine/VisualScript/block_workspace.h deleted file mode 100644 index e5ba5c6..0000000 --- a/Engine/VisualScript/block_workspace.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -// ============================================================================ -// block_workspace.h - 工作区管理 -// ============================================================================ - -#include "block_core.h" - -#define MAX_WORKSPACE_BLOCKS 1024 -#define MAX_WORKSPACE_CONNECTIONS 2048 - -typedef struct BlockWorkspace { - Block* blocks[MAX_WORKSPACE_BLOCKS]; - int block_count; - - BlockConnection connections[MAX_WORKSPACE_CONNECTIONS]; - int connection_count; - - float view_x, view_y; - float zoom; - - Block* selected_block; - BlockSlot* dragging_from; - float drag_start_x, drag_start_y; - - int next_block_id; - - struct BlockPalette* palette; -} BlockWorkspace; - -// 创建/销毁 -BlockWorkspace* workspace_create(void); -void workspace_destroy(BlockWorkspace* ws); - -// 添加/移除积木 -int workspace_add_block(BlockWorkspace* ws, Block* block); -void workspace_remove_block(BlockWorkspace* ws, int block_id); - -// 添加/移除连接 -bool workspace_add_connection(BlockWorkspace* ws, BlockSlot* from, BlockSlot* to); -void workspace_remove_connection(BlockWorkspace* ws, BlockSlot* from); -void workspace_remove_all_connections(BlockWorkspace* ws, Block* block); - -// 查找 -Block* workspace_find_block(BlockWorkspace* ws, int block_id); -Block* workspace_find_block_at(BlockWorkspace* ws, float x, float y); -BlockSlot* workspace_find_slot_at(BlockWorkspace* ws, float x, float y); - -// 视口变换 -void workspace_screen_to_world(BlockWorkspace* ws, float sx, float sy, float* wx, float* wy); -void workspace_world_to_screen(BlockWorkspace* ws, float wx, float wy, float* sx, float* sy); - -// 清空 -void workspace_clear(BlockWorkspace* ws); diff --git a/Engine/Window/window.c b/Engine/Window/window.c deleted file mode 100644 index 4cdfc94..0000000 --- a/Engine/Window/window.c +++ /dev/null @@ -1,198 +0,0 @@ -// ============================================================================ -// window.c - Win32 窗口实现 -// ============================================================================ - -#include "window.h" -#include "../Core/logger.h" -#include -#include - -// 窗口类名 -static const wchar_t* WINDOW_CLASS = L"Lity3DEngineWindow"; - -// 全局回调 -static WindowKeyCallback g_key_callback = NULL; -static WindowResizeCallback g_resize_callback = NULL; -static WindowMouseMoveCallback g_mouse_move_callback = NULL; -static WindowMouseButtonCallback g_mouse_button_callback = NULL; - -// 窗口过程 -static LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - Window* window = NULL; - - if (msg == WM_NCCREATE) { - CREATESTRUCT* cs = (CREATESTRUCT*)lParam; - window = (Window*)cs->lpCreateParams; - SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR)window); - } else { - window = (Window*)GetWindowLongPtrW(hwnd, GWLP_USERDATA); - } - - if (window) { - switch (msg) { - case WM_SIZE: - window->width = LOWORD(lParam); - window->height = HIWORD(lParam); - window->minimized = (wParam == SIZE_MINIMIZED); - if (g_resize_callback && !window->minimized) { - g_resize_callback(window->width, window->height); - } - return 0; - - case WM_PAINT: - ValidateRect(hwnd, NULL); - return 0; - - case WM_ERASEBKGND: - return 1; - - case WM_KEYDOWN: - if (g_key_callback) g_key_callback((int)wParam); - return 0; - - case WM_KEYUP: - return 0; - - case WM_MOUSEMOVE: - if (g_mouse_move_callback) g_mouse_move_callback(LOWORD(lParam), HIWORD(lParam)); - return 0; - - case WM_LBUTTONDOWN: - SetCapture(hwnd); - if (g_mouse_button_callback) g_mouse_button_callback(0, 1); - return 0; - case WM_RBUTTONDOWN: - SetCapture(hwnd); - if (g_mouse_button_callback) g_mouse_button_callback(1, 1); - return 0; - case WM_MBUTTONDOWN: - SetCapture(hwnd); - if (g_mouse_button_callback) g_mouse_button_callback(2, 1); - return 0; - - case WM_LBUTTONUP: - if (GetCapture() == hwnd) ReleaseCapture(); - if (g_mouse_button_callback) g_mouse_button_callback(0, 0); - return 0; - case WM_RBUTTONUP: - if (GetCapture() == hwnd) ReleaseCapture(); - if (g_mouse_button_callback) g_mouse_button_callback(1, 0); - return 0; - case WM_MBUTTONUP: - if (GetCapture() == hwnd) ReleaseCapture(); - if (g_mouse_button_callback) g_mouse_button_callback(2, 0); - return 0; - - case WM_DESTROY: - PostQuitMessage(0); - return 0; - } - } - - return DefWindowProcW(hwnd, msg, wParam, lParam); -} - -// 注册窗口类 -static void register_window_class(void) { - WNDCLASSEXW wc = {0}; - wc.cbSize = sizeof(WNDCLASSEXW); - wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; - wc.lpfnWndProc = window_proc; - wc.hInstance = GetModuleHandleW(NULL); - wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = NULL; - wc.lpszClassName = WINDOW_CLASS; - wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); - - if (!RegisterClassExW(&wc)) { - LOG_ERROR("Failed to register window class!"); - } -} - -Window* window_create(const char* title, int width, int height, int fullscreen) { - Window* window = (Window*)calloc(1, sizeof(Window)); - if (!window) return NULL; - - window->title = title; - window->width = width; - window->height = height; - window->fullscreen = fullscreen; - - register_window_class(); - - DWORD style = WS_OVERLAPPEDWINDOW; - DWORD ex_style = WS_EX_APPWINDOW; - - RECT rect = {0, 0, width, height}; - AdjustWindowRectEx(&rect, style, FALSE, ex_style); - - int adjusted_width = rect.right - rect.left; - int adjusted_height = rect.bottom - rect.top; - - int screen_w = GetSystemMetrics(SM_CXSCREEN); - int screen_h = GetSystemMetrics(SM_CYSCREEN); - int pos_x = (screen_w - adjusted_width) / 2; - int pos_y = (screen_h - adjusted_height) / 2; - - // 转换标题为宽字符 - wchar_t w_title[256]; - MultiByteToWideChar(CP_UTF8, 0, title, -1, w_title, 256); - - window->hwnd = CreateWindowExW( - ex_style, WINDOW_CLASS, w_title, style, - pos_x, pos_y, adjusted_width, adjusted_height, - NULL, NULL, GetModuleHandleW(NULL), window - ); - - if (!window->hwnd) { - LOG_ERROR("Failed to create window! Error: %lu", GetLastError()); - free(window); - return NULL; - } - - ShowWindow(window->hwnd, SW_SHOW); - UpdateWindow(window->hwnd); - - LOG_INFO("Window created: %dx%d", width, height); - return window; -} - -void window_destroy(Window* window) { - if (window) { - if (window->hwnd) { - DestroyWindow(window->hwnd); - window->hwnd = NULL; - } - free(window); - } -} - -void window_show(Window* window) { - if (window && window->hwnd) ShowWindow(window->hwnd, SW_SHOW); -} - -void window_hide(Window* window) { - if (window && window->hwnd) ShowWindow(window->hwnd, SW_HIDE); -} - -int window_process_messages(Window* window) { - MSG msg = {0}; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - if (msg.message == WM_QUIT) return 0; - TranslateMessage(&msg); - DispatchMessage(&msg); - } - return 1; -} - -int window_get_width(Window* window) { return window ? window->width : 0; } -int window_get_height(Window* window) { return window ? window->height : 0; } -HWND window_get_handle(Window* window) { return window ? window->hwnd : NULL; } -int window_is_fullscreen(Window* window) { return window ? window->fullscreen : 0; } -int window_is_minimized(Window* window) { return window ? window->minimized : 0; } - -void window_set_key_callback(Window* window, WindowKeyCallback callback) { g_key_callback = callback; } -void window_set_resize_callback(Window* window, WindowResizeCallback callback) { g_resize_callback = callback; } -void window_set_mouse_move_callback(Window* window, WindowMouseMoveCallback callback) { g_mouse_move_callback = callback; } -void window_set_mouse_button_callback(Window* window, WindowMouseButtonCallback callback) { g_mouse_button_callback = callback; } diff --git a/Engine/Window/window.h b/Engine/Window/window.h deleted file mode 100644 index 2a3c447..0000000 --- a/Engine/Window/window.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -// ============================================================================ -// window.h - Win32 窗口管理 -// ============================================================================ - -#include - -// 窗口结构 -typedef struct Window { - HWND hwnd; - int width; - int height; - int fullscreen; - int minimized; - const char* title; -} Window; - -// 回调类型 -typedef void (*WindowKeyCallback)(int key); -typedef void (*WindowResizeCallback)(int width, int height); -typedef void (*WindowMouseMoveCallback)(int x, int y); -typedef void (*WindowMouseButtonCallback)(int button, int pressed); - -// 创建/销毁 -Window* window_create(const char* title, int width, int height, int fullscreen); -void window_destroy(Window* window); - -// 显示/隐藏 -void window_show(Window* window); -void window_hide(Window* window); - -// 消息处理 -int window_process_messages(Window* window); - -// 获取属性 -int window_get_width(Window* window); -int window_get_height(Window* window); -HWND window_get_handle(Window* window); -int window_is_fullscreen(Window* window); -int window_is_minimized(Window* window); - -// 设置回调 -void window_set_key_callback(Window* window, WindowKeyCallback callback); -void window_set_resize_callback(Window* window, WindowResizeCallback callback); -void window_set_mouse_move_callback(Window* window, WindowMouseMoveCallback callback); -void window_set_mouse_button_callback(Window* window, WindowMouseButtonCallback callback); diff --git a/Engine/include/engine_api.h b/Engine/include/engine_api.h deleted file mode 100644 index cf51193..0000000 --- a/Engine/include/engine_api.h +++ /dev/null @@ -1,145 +0,0 @@ -#pragma once - -// ============================================================================ -// engine_api.h - C-ASM 接口头文件 -// 暴露所有汇编函数给 C 代码使用 -// ============================================================================ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// 当 MASM 不可用时,使用 C fallback -// math_c_fallback.h 已经定义了所有数学类型和函数 -// 不需要重复声明 - -// ============================================================================ -// memory.asm - 对齐内存分配 -// ============================================================================ - -#if !defined(MATH_ASM_AVAILABLE) || MATH_ASM_AVAILABLE == 0 -// 在 C fallback 模式下,这些函数已在 math_c_fallback.h 中定义 -// 不需要重复声明 -#else -void* mem_aligned_alloc(uint64_t size, uint64_t alignment); -void mem_aligned_free(void* ptr); -void* mem_aligned_realloc(void* ptr, uint64_t size, uint64_t alignment); - -// ============================================================================ -// string_ops.asm - 快速字符串操作 -// ============================================================================ - -void fast_memcpy(void* dst, const void* src, uint64_t count); -void fast_memset(void* dst, int value, uint64_t count); -uint64_t fast_strlen(const char* str); -int fast_strcmp(const char* a, const char* b); - -// ============================================================================ -// profiling.asm - 性能分析 -// ============================================================================ - -uint64_t prof_rdtsc(void); -double prof_cycles_to_ms(uint64_t cycles); -uint64_t prof_get_freq(void); - -// 性能计时器结构 -typedef struct { - uint64_t start; - uint64_t end; - double elapsed_ms; -} ProfTimer; - -void prof_timer_start(ProfTimer* timer); -void prof_timer_stop(ProfTimer* timer); -#endif - -#ifdef __cplusplus -} -#endif - -// ============================================================================ -// C++ 便利封装 -// ============================================================================ - -#ifdef __cplusplus - -// Vec3 运算符重载 -inline Vec3 operator+(const Vec3& a, const Vec3& b) { - Vec3 result; - vec3_add(&a, &b, &result); - return result; -} - -inline Vec3 operator-(const Vec3& a, const Vec3& b) { - Vec3 result; - vec3_sub(&a, &b, &result); - return result; -} - -inline Vec3 operator*(const Vec3& a, float s) { - Vec3 result; - vec3_scale(&a, s, &result); - return result; -} - -inline float dot(const Vec3& a, const Vec3& b) { - return vec3_dot(&a, &b); -} - -inline Vec3 cross(const Vec3& a, const Vec3& b) { - Vec3 result; - vec3_cross(&a, &b, &result); - return result; -} - -inline float length(const Vec3& a) { - return vec3_length(&a); -} - -inline Vec3 normalize(const Vec3& a) { - Vec3 result; - vec3_normalize(&a, &result); - return result; -} - -inline Vec3 lerp(const Vec3& a, const Vec3& b, float t) { - Vec3 result; - vec3_lerp(&a, &b, t, &result); - return result; -} - -// Mat4 运算符重载 -inline Mat4 operator*(const Mat4& a, const Mat4& b) { - Mat4 result; - mat4_multiply(&a, &b, &result); - return result; -} - -inline Vec3 transformPoint(const Mat4& m, const Vec3& v) { - Vec3 result; - // 使用 vec4 乘法, w=1 - Vec4 v4 = {v.x, v.y, v.z, 1.0f}; - Vec4 r4; - // 简化: 逐行计算 - result.x = m.m[0][0]*v.x + m.m[0][1]*v.y + m.m[0][2]*v.z + m.m[0][3]; - result.y = m.m[1][0]*v.x + m.m[1][1]*v.y + m.m[1][2]*v.z + m.m[1][3]; - result.z = m.m[2][0]*v.x + m.m[2][1]*v.y + m.m[2][2]*v.z + m.m[2][3]; - return result; -} - -// Quat 运算符重载 -inline Quat operator*(const Quat& a, const Quat& b) { - Quat result; - quat_multiply(&a, &b, &result); - return result; -} - -inline Vec3 rotate(const Quat& q, const Vec3& v) { - Vec3 result; - quat_rotate_vec3(&q, &v, &result); - return result; -} - -#endif // __cplusplus diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 7203af6..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2026 shuiyu - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index 237476f..bbd1a72 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@ 你好呀~这个仓库已经搬到更好用的地方啦。 -为了让代码管理更清爽、多平台同步更省心,我们把原先分散的镜像统一收拢到 -**Gitee** 与 **GitHub** 主仓维护,这里就只保留这张"迁移小纸条"咯。 +为了让代码管理更清爽、多平台同步更省心,我们把原先分散的镜像统一收拢到主仓维护,这里就只保留这张"迁移小纸条"咯。 📦 新家在这里: - Gitee:https://gitee.com/shuiyu1123/lity3d diff --git a/build.bat b/build.bat deleted file mode 100644 index 0085ee1..0000000 --- a/build.bat +++ /dev/null @@ -1,110 +0,0 @@ -@echo off -REM ============================================================================ -REM build.bat - MinGW 编译脚本 -REM ============================================================================ - -set MINGW=C:\mingw64\bin -set GCC=%MINGW%\gcc.exe -set GXX=%MINGW%\g++.exe - -set ENGINE_DIR=Engine -set DEMO_DIR=Demo -set OUTPUT=Lity3D.exe - -set CFLAGS=-O2 -Wall -Wextra -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_WARNINGS -DMATH_ASM_AVAILABLE=0 -I%ENGINE_DIR% -I%ENGINE_DIR%\include -set LDFLAGS=-ld3d11 -ldxgi -ld3dcompiler -lole32 -loleaut32 -luuid -lgdi32 -luser32 -lkernel32 -lwinmm -lxinput1_4 -lwindowscodecs -static - -echo === Lity3DEngine ASM Build === -echo Compiler: %GCC% - -REM 创建输出目录并清理旧对象 -if not exist build mkdir build -if exist build\*.o del /Q build\*.o - -REM 编译引擎 C 源文件 -echo [1/3] Compiling Engine sources... -%GCC% %CFLAGS% -c %ENGINE_DIR%\Core\engine.c -o build\engine.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Core\logger.c -o build\logger.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Core\timer.c -o build\timer.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Core\asset_manager.c -o build\asset_manager.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Window\window.c -o build\window.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Rendering\graphics_device.c -o build\graphics_device.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Rendering\renderer.c -o build\renderer.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Rendering\frustum.c -o build\frustum.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Rendering\shader.c -o build\shader.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Rendering\mesh.c -o build\mesh.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Rendering\texture.c -o build\texture.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Rendering\material.c -o build\material.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Rendering\camera.c -o build\camera.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Rendering\camera_controller.c -o build\camera_controller.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Terrain\terrain.c -o build\terrain.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Terrain\terrain_manager.c -o build\terrain_manager.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\ECS\world.c -o build\world.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Input\input.c -o build\input.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Physics\physics.c -o build\physics.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Audio\audio.c -o build\audio.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\UI\ui.c -o build\ui.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Scripting\lua_engine.c -o build\lua_engine.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Scene\scene_graph.c -o build\scene_graph.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Scene\scene_render.c -o build\scene_render.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\Scene\scene_serialize.c -o build\scene_serialize.o - -REM 编译 VisualScript 模块 -echo [2/4] Compiling VisualScript... -%GCC% %CFLAGS% -c %ENGINE_DIR%\VisualScript\block_core.c -o build\block_core.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\VisualScript\block_types.c -o build\block_types.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\VisualScript\block_workspace.c -o build\block_workspace.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\VisualScript\block_interaction.c -o build\block_interaction.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\VisualScript\block_renderer.c -o build\block_renderer.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\VisualScript\block_palette.c -o build\block_palette.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\VisualScript\block_executor.c -o build\block_executor.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\VisualScript\block_serializer.c -o build\block_serializer.o -%GCC% %CFLAGS% -c %ENGINE_DIR%\VisualScript\block_editor.c -o build\block_editor.o - -REM 编译 Demo -echo [3/3] Compiling Demo... -%GCC% %CFLAGS% -c %DEMO_DIR%\main.c -o build\main.o -%GCC% %CFLAGS% -c %DEMO_DIR%\audio_demo.c -o build\audio_demo.o -%GCC% %CFLAGS% -c %DEMO_DIR%\open_world_demo.c -o build\open_world_demo.o - -REM 链接主程序 -echo Linking main... -%GXX% build\engine.o build\logger.o build\timer.o build\asset_manager.o build\window.o build\graphics_device.o build\renderer.o build\frustum.o build\shader.o build\mesh.o build\texture.o build\material.o build\camera.o build\camera_controller.o build\terrain.o build\terrain_manager.o build\world.o build\input.o build\physics.o build\audio.o build\ui.o build\lua_engine.o build\scene_graph.o build\scene_render.o build\scene_serialize.o build\block_core.o build\block_types.o build\block_workspace.o build\block_interaction.o build\block_renderer.o build\block_palette.o build\block_executor.o build\block_serializer.o build\block_editor.o build\main.o -o build\%OUTPUT% %LDFLAGS% - -REM 链接音频演示 -echo Linking audio_demo... -%GXX% build\engine.o build\logger.o build\timer.o build\asset_manager.o build\window.o build\graphics_device.o build\renderer.o build\frustum.o build\shader.o build\mesh.o build\texture.o build\material.o build\camera.o build\camera_controller.o build\terrain.o build\terrain_manager.o build\world.o build\input.o build\physics.o build\audio.o build\ui.o build\lua_engine.o build\scene_graph.o build\scene_render.o build\scene_serialize.o build\block_core.o build\block_types.o build\block_workspace.o build\block_interaction.o build\block_renderer.o build\block_palette.o build\block_executor.o build\block_serializer.o build\block_editor.o build\audio_demo.o -o build\audio_demo.exe %LDFLAGS% - -REM 链接开放世界演示 -echo Linking open_world_demo... -%GXX% build\engine.o build\logger.o build\timer.o build\asset_manager.o build\window.o build\graphics_device.o build\renderer.o build\frustum.o build\shader.o build\mesh.o build\texture.o build\material.o build\camera.o build\camera_controller.o build\terrain.o build\terrain_manager.o build\world.o build\input.o build\physics.o build\audio.o build\ui.o build\lua_engine.o build\scene_graph.o build\scene_render.o build\scene_serialize.o build\block_core.o build\block_types.o build\block_workspace.o build\block_interaction.o build\block_renderer.o build\block_palette.o build\block_executor.o build\block_serializer.o build\block_editor.o build\open_world_demo.o -o build\open_world_demo.exe %LDFLAGS% - -REM 编译 C# 编辑器 -echo Building C# editor... -dotnet build EditorCS\Lity3DEditor.csproj -c Release -o build - -if %ERRORLEVEL% EQU 0 ( - echo. - echo === Build succeeded! === - echo Output: build\%OUTPUT% - echo Audio Demo: build\audio_demo.exe - echo Open World Demo: build\open_world_demo.exe - echo Editor: build\editor.exe - echo. - echo Run with: build\%OUTPUT%, build\audio_demo.exe, build\open_world_demo.exe, or build\editor.exe - - REM 清理中间文件,保留可分发产物 - del /Q build\*.o 2>nul - del /Q build\libEngine.a 2>nul - del /Q build\engine.log 2>nul - del /Q build\screenshot*.bmp 2>nul - rmdir /S /Q build\CMakeFiles 2>nul - del /Q build\CMakeCache.txt 2>nul - del /Q build\Makefile 2>nul - del /Q build\cmake_install.cmake 2>nul - del /Q build\scene.txt 2>nul - del /Q build\scene_log.txt 2>nul -) else ( - echo. - echo === Build FAILED! === -) diff --git a/editor.py b/editor.py deleted file mode 100644 index 0d43299..0000000 --- a/editor.py +++ /dev/null @@ -1,337 +0,0 @@ -""" -Lity3D Editor - 集成开发环境 -双击打开 → 写代码 → F5 运行 → F7 打包 -支持 11 种语言切换 -""" -import tkinter as tk -from tkinter import ttk, filedialog, scrolledtext, messagebox -import os, subprocess, json, sys, time - -ENGINE_DIR = os.path.dirname(os.path.abspath(__file__)) -sys.path.insert(0, ENGINE_DIR) -import i18n - -class LityEditor: - def __init__(self): - i18n.load_language() - self.root = tk.Tk() - self.root.geometry("1400x900") - self.root.configure(bg="#2b2d30") - self.current_file = None - self.process = None - self._setup_styles() - self._build_ui() - i18n.on_language_change(self._refresh_ui) - self.root.protocol("WM_DELETE_WINDOW", self._on_close) - - def _t(self, key): - return i18n.t(key) - - def _setup_styles(self): - s = ttk.Style() - s.theme_use("clam") - s.configure("Dark.TFrame", background="#2b2d30") - s.configure("Dark.TLabel", background="#2b2d30", foreground="#cccccc") - - def _build_ui(self): - self._build_menu() - self._build_toolbar() - self._build_main() - self._build_statusbar() - self._set_status(self._t("ready")) - - def _refresh_ui(self): - self.root.title(self._t("app_title")) - for w in self.root.winfo_children(): - if isinstance(w, tk.Menu): - w.destroy() - self._build_menu() - self._build_toolbar() - - def _build_menu(self): - mb = tk.Menu(self.root, bg="#2b2d30", fg="#cccccc") - self.root.config(menu=mb) - - fm = tk.Menu(mb, tearoff=0, bg="#3c3f41", fg="#cccccc") - fm.add_command(label=self._t("new_file"), accelerator="Ctrl+N", command=self._new_file) - fm.add_command(label=self._t("open_file"), accelerator="Ctrl+O", command=self._open_file) - fm.add_command(label=self._t("open_folder"), command=self._open_folder) - fm.add_separator() - fm.add_command(label=self._t("save"), accelerator="Ctrl+S", command=self._save_file) - fm.add_command(label=self._t("save_as"), command=self._save_as) - fm.add_separator() - fm.add_command(label=self._t("exit"), command=self._on_close) - mb.add_cascade(label=self._t("menu_file"), menu=fm) - - em = tk.Menu(mb, tearoff=0, bg="#3c3f41", fg="#cccccc") - em.add_command(label=self._t("undo"), accelerator="Ctrl+Z", command=lambda: self.code_text.edit_undo()) - em.add_command(label=self._t("redo"), accelerator="Ctrl+Y", command=lambda: self.code_text.edit_redo()) - em.add_separator() - em.add_command(label=self._t("cut"), accelerator="Ctrl+X", command=lambda: self.root.focus_get().event_generate("<>")) - em.add_command(label=self._t("copy"), accelerator="Ctrl+C", command=lambda: self.root.focus_get().event_generate("<>")) - em.add_command(label=self._t("paste"), accelerator="Ctrl+V", command=lambda: self.root.focus_get().event_generate("<>")) - em.add_command(label=self._t("select_all"), accelerator="Ctrl+A", command=lambda: self.code_text.tag_add("sel", "1.0", "end")) - mb.add_cascade(label=self._t("menu_edit"), menu=em) - - bm = tk.Menu(mb, tearoff=0, bg="#3c3f41", fg="#cccccc") - bm.add_command(label=self._t("run_game"), accelerator="F5", command=self._run_game) - bm.add_command(label=self._t("run_file"), accelerator="Ctrl+F5", command=self._run_current) - bm.add_separator() - bm.add_command(label=self._t("build_engine"), command=self._build_engine) - bm.add_command(label=self._t("build_exe"), accelerator="F7", command=self._build_exe) - bm.add_separator() - bm.add_command(label=self._t("kill_process"), accelerator="Shift+F5", command=self._kill_process) - mb.add_cascade(label=self._t("menu_build"), menu=bm) - - sm = tk.Menu(mb, tearoff=0, bg="#3c3f41", fg="#cccccc") - sm.add_command(label=self._t("new_scene"), command=self._new_scene) - sm.add_command(label=self._t("open_scene"), command=self._open_scene) - sm.add_command(label=self._t("save_scene"), command=self._save_scene) - sm.add_separator() - sm.add_command(label=self._t("run_scene"), command=self._run_scene) - mb.add_cascade(label=self._t("menu_scene"), menu=sm) - - lm = tk.Menu(mb, tearoff=0, bg="#3c3f41", fg="#cccccc") - for code, name in i18n.get_all_languages(): - marker = " ✓" if code == i18n.get_language() else "" - lm.add_command(label=f"{name}{marker}", command=lambda c=code: self._switch_lang(c)) - mb.add_cascade(label=self._t("menu_language"), menu=lm) - - hm = tk.Menu(mb, tearoff=0, bg="#3c3f41", fg="#cccccc") - hm.add_command(label=self._t("docs"), command=self._open_docs) - hm.add_command(label=self._t("about"), command=lambda: messagebox.showinfo( - self._t("about"), "Lity3D Engine v1.0\nC+MASM Game Engine\nPython Scripting + D3D11\n11 Languages")) - mb.add_cascade(label=self._t("menu_help"), menu=hm) - - self.root.bind("", lambda e: self._new_file()) - self.root.bind("", lambda e: self._open_file()) - self.root.bind("", lambda e: self._save_file()) - self.root.bind("", lambda e: self._run_game()) - self.root.bind("", lambda e: self._build_exe()) - self.root.bind("", lambda e: self._kill_process()) - - def _switch_lang(self, code): - i18n.set_language(code) - i18n.save_language(code) - self._refresh_ui() - - def _build_toolbar(self): - if hasattr(self, '_toolbar') and self._toolbar: - self._toolbar.destroy() - self._toolbar = ttk.Frame(self.root, style="Dark.TFrame") - self._toolbar.pack(side=tk.TOP, fill=tk.X, padx=2, pady=2) - - ttk.Button(self._toolbar, text=self._t("new_file"), command=self._new_file).pack(side=tk.LEFT, padx=1) - ttk.Button(self._toolbar, text=self._t("open_file"), command=self._open_file).pack(side=tk.LEFT, padx=1) - ttk.Button(self._toolbar, text=self._t("save"), command=self._save_file).pack(side=tk.LEFT, padx=1) - ttk.Separator(self._toolbar, orient=tk.VERTICAL).pack(side=tk.LEFT, fill=tk.Y, padx=4) - ttk.Button(self._toolbar, text=self._t("run") + " (F5)", command=self._run_game).pack(side=tk.LEFT, padx=2) - ttk.Button(self._toolbar, text=self._t("stop"), command=self._kill_process).pack(side=tk.LEFT, padx=1) - ttk.Button(self._toolbar, text=self._t("build_exe") + " (F7)", command=self._build_exe).pack(side=tk.LEFT, padx=2) - ttk.Separator(self._toolbar, orient=tk.VERTICAL).pack(side=tk.LEFT, fill=tk.Y, padx=4) - ttk.Button(self._toolbar, text=self._t("new_scene"), command=self._new_scene).pack(side=tk.LEFT, padx=1) - ttk.Button(self._toolbar, text=self._t("save_scene"), command=self._save_scene).pack(side=tk.LEFT, padx=1) - - def _build_main(self): - main = ttk.PanedWindow(self.root, orient=tk.HORIZONTAL) - main.pack(fill=tk.BOTH, expand=True, padx=2, pady=2) - - left = ttk.Frame(main, style="Dark.TFrame") - main.add(left, weight=1) - ttk.Label(left, text=self._t("explorer").upper(), style="Dark.TLabel", font=("Segoe UI", 9, "bold")).pack(anchor=tk.W, padx=5, pady=3) - self.file_tree = ttk.Treeview(left, show="tree", height=20) - self.file_tree.pack(fill=tk.BOTH, expand=True, padx=3, pady=3) - self.file_tree.bind("", self._on_tree_double) - self._refresh_tree() - - right = ttk.Frame(main, style="Dark.TFrame") - main.add(right, weight=3) - self.notebook = ttk.Notebook(right) - self.notebook.pack(fill=tk.BOTH, expand=True) - self.editor_frame = ttk.Frame(self.notebook) - self.notebook.add(self.editor_frame, text="editor.py") - self.code_text = scrolledtext.ScrolledText(self.editor_frame, bg="#1e1e1e", fg="#d4d4d4", insertbackground="#d4d4d4", font=("Consolas", 12), wrap=tk.NONE, undo=True) - self.code_text.pack(fill=tk.BOTH, expand=True) - - bottom = ttk.Frame(right, style="Dark.TFrame") - bottom.pack(fill=tk.BOTH, expand=False) - self.console = scrolledtext.ScrolledText(bottom, bg="#1e1e1e", fg="#cccccc", font=("Consolas", 10), height=8, state=tk.DISABLED) - self.console.pack(fill=tk.BOTH, expand=True, padx=3, pady=3) - - def _build_statusbar(self): - self.statusbar = ttk.Frame(self.root, style="Dark.TFrame") - self.statusbar.pack(side=tk.BOTTOM, fill=tk.X) - self.status_label = ttk.Label(self.statusbar, text="", style="Dark.TLabel") - self.status_label.pack(side=tk.LEFT, padx=5) - self.process_label = ttk.Label(self.statusbar, text="", style="Dark.TLabel", foreground="#6a9955") - self.process_label.pack(side=tk.RIGHT, padx=5) - - def _log(self, msg, tag="info"): - self.console.config(state=tk.NORMAL) - ts = time.strftime("%H:%M:%S") - pfx = {"info": " ", "error": "!!", "success": "OK"}[tag] - self.console.insert(tk.END, f"[{ts}] {pfx} {msg}\n") - self.console.see(tk.END) - self.console.config(state=tk.DISABLED) - - def _set_status(self, msg): - self.status_label.config(text=msg) - - def _refresh_tree(self): - if not hasattr(self, 'file_tree'): return - self.file_tree.delete(*self.file_tree.get_children()) - root = self.file_tree.insert("", "end", text="lity3d", open=True) - skip = {".git", ".gitignore", "build", "__pycache__", ".lang", ".vs", ".vscode", "obj"} - for item in sorted(os.listdir(ENGINE_DIR)): - if item.startswith(".") or item in skip: continue - full = os.path.join(ENGINE_DIR, item) - if os.path.isdir(full): - dn = self.file_tree.insert(root, "end", text=item) - try: - for f in sorted(os.listdir(full)): - if f.startswith(".") or f.endswith((".pyc", ".exe", ".o", ".a")): continue - self.file_tree.insert(dn, "end", text=f, values=(os.path.join(item, f),)) - except: pass - else: - self.file_tree.insert(root, "end", text=item, values=(item,)) - - def _on_tree_double(self, event): - sel = self.file_tree.selection() - if not sel: return - item = self.file_tree.item(sel[0]) - vals = item.get("values", ()) - path = vals[0] if vals else item["text"] - full = os.path.join(ENGINE_DIR, path) if not os.path.isabs(path) else path - if os.path.isfile(full): self._open_file_at(full) - - def _new_file(self): - self.code_text.delete("1.0", tk.END) - self.current_file = None - self.notebook.tab(self.editor_frame, text="untitled*") - self._set_status(self._t("new_file_msg")) - - def _open_file(self): - p = filedialog.askopenfilename(initialdir=ENGINE_DIR, filetypes=[("Python", "*.py"), ("C", "*.c *.h"), ("All", "*.*")]) - if p: self._open_file_at(p) - - def _open_file_at(self, path): - try: - with open(path, "r", encoding="utf-8", errors="replace") as f: - self.code_text.delete("1.0", tk.END) - self.code_text.insert("1.0", f.read()) - self.current_file = path - name = os.path.basename(path) - self.notebook.tab(self.editor_frame, text=name) - self._log(f"{self._t('opened')} {name}", "success") - except Exception as e: - self._log(str(e), "error") - - def _open_folder(self): - filedialog.askdirectory(initialdir=ENGINE_DIR) - - def _save_file(self): - if not self.current_file: self._save_as(); return - try: - with open(self.current_file, "w", encoding="utf-8") as f: - f.write(self.code_text.get("1.0", tk.END)) - name = os.path.basename(self.current_file) - self.notebook.tab(self.editor_frame, text=name) - self._log(f"{self._t('saved')} {name}", "success") - except Exception as e: - self._log(str(e), "error") - - def _save_as(self): - p = filedialog.asksaveasfilename(initialdir=ENGINE_DIR, defaultextension=".py", filetypes=[("Python", "*.py"), ("All", "*.*")]) - if p: self.current_file = p; self._save_file() - - def _run_game(self): - exe = os.path.join(ENGINE_DIR, "build", "lity.exe") - if os.path.exists(exe): self._run_process([exe]) - else: self._log(self._t("build_first"), "error") - - def _run_current(self): - if not self.current_file: self._log(self._t("no_file"), "error"); return - ext = os.path.splitext(self.current_file)[1] - if ext == ".py": self._run_process([sys.executable, self.current_file]) - else: self._log(self._t("cant_run"), "error") - - def _run_scene(self): - exe = os.path.join(ENGINE_DIR, "build", "lity.exe") - if os.path.exists(exe): self._run_process([exe]) - else: self._log(self._t("build_first"), "error") - - def _run_process(self, cmd): - self._kill_process() - self._log(f"> {' '.join(os.path.basename(c) for c in cmd)}") - self.process_label.config(text=self._t("running")) - try: - self.process = subprocess.Popen(cmd, cwd=ENGINE_DIR, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, creationflags=subprocess.CREATE_NO_WINDOW) - self._poll() - except Exception as e: - self._log(str(e), "error") - self.process_label.config(text="") - - def _poll(self): - if self.process and self.process.poll() is None: - line = self.process.stdout.readline() - if line: - self._log(line.decode(errors="replace").rstrip()) - self.root.after(50, self._poll) - elif self.process: - self._log(f"{self._t('process_exit')} {self.process.returncode}", "success" if self.process.returncode == 0 else "error") - self.process_label.config(text="") - self.process = None - - def _kill_process(self): - if self.process: - self.process.kill() - self._log(self._t("kill_done"), "error") - self.process_label.config(text="") - self.process = None - - def _build_engine(self): - d = os.path.join(ENGINE_DIR, "build") - os.makedirs(d, exist_ok=True) - self._run_process(["cmake", "--build", d]) - - def _build_exe(self): - self._save_file() - exe = os.path.join(ENGINE_DIR, "build", "lity.exe") - if os.path.exists(exe): - out = filedialog.asksaveasfilename(initialdir=ENGINE_DIR, defaultextension=".exe", filetypes=[("EXE", "*.exe")]) - if out: - import shutil - shutil.copy2(exe, out) - self._log(f"{self._t('packaged')} {out}", "success") - else: - self._log(self._t("build_first"), "error") - - def _new_scene(self): - scene = {"entities": [], "camera": {"pos": [0, 5, -10], "target": [0, 0, 0]}} - path = filedialog.asksaveasfilename(initialdir=ENGINE_DIR, defaultextension=".json", filetypes=[("Scene", "*.json")]) - if path: - with open(path, "w") as f: json.dump(scene, f, indent=2) - self.current_file = path - self._open_file_at(path) - self._log(self._t("new_scene_ok"), "success") - - def _open_scene(self): - p = filedialog.askopenfilename(initialdir=ENGINE_DIR, filetypes=[("Scene", "*.json *.txt")]) - if p: self._open_file_at(p) - - def _save_scene(self): - self._save_file() - - def _open_docs(self): - d = os.path.join(ENGINE_DIR, "Engine", "Scripting", "lity.py") - if os.path.exists(d): self._open_file_at(d) - - def _on_close(self): - if self.process: self.process.kill() - self.root.destroy() - - def run(self): - self.root.mainloop() - -if __name__ == "__main__": - LityEditor().run() diff --git a/generate_languages.py b/generate_languages.py deleted file mode 100644 index f41ce91..0000000 --- a/generate_languages.py +++ /dev/null @@ -1,59 +0,0 @@ -"""Generate all language JSON files for Lity3D Editor""" -import json, os - -BASE = os.path.join(os.path.dirname(__file__), "languages") - -translations = { - "zh": {"app_title":"Lity3D 编辑器","file":"文件","build":"构建","scene":"场景","help":"帮助","lang":"语言","new":"新建","open":"打开","save":"保存","exit":"退出","run":"运行游戏","compile":"编译引擎","package":"打包 EXE","explorer":"资源管理器","output":"输出","ready":"就绪","running":"运行中...","saved":"已保存","opened":"已打开","build_first":"请先编译引擎","kill":"进程已终止","packaged":"已打包","about":"关于 Lity3D"}, - "en": {"app_title":"Lity3D Editor","file":"File","build":"Build","scene":"Scene","help":"Help","lang":"Language","new":"New","open":"Open","save":"Save","exit":"Exit","run":"Run Game","compile":"Build Engine","package":"Package EXE","explorer":"Explorer","output":"Output","ready":"Ready","running":"Running...","saved":"Saved","opened":"Opened","build_first":"Build engine first","kill":"Process killed","packaged":"Packaged","about":"About Lity3D"}, - "ja": {"app_title":"Lity3D エディタ","file":"ファイル","build":"ビルド","scene":"シーン","help":"ヘルプ","lang":"言語","new":"新規","open":"開く","save":"保存","exit":"終了","run":"ゲーム実行","compile":"ビルド","package":"EXE出力","explorer":"エクスプローラ","output":"出力","ready":"準備完了","running":"実行中...","saved":"保存済み","opened":"開いた","build_first":"先にビルド","kill":"停止済み","packaged":"パッケージ済み","about":"Lity3D について"}, - "ko": {"app_title":"Lity3D 편집기","file":"파일","build":"빌드","scene":"씬","help":"도움말","lang":"언어","new":"새로 만들기","open":"열기","save":"저장","exit":"종료","run":"게임 실행","compile":"엔진 빌드","package":"EXE 패키징","explorer":"탐색기","output":"출력","ready":"준비","running":"실행 중...","saved":"저장됨","opened":"열림","build_first":"먼저 빌드","kill":"중지됨","packaged":"패키징됨","about":"Lity3D 정보"}, - "es": {"app_title":"Lity3D Editor","file":"Archivo","build":"Compilar","scene":"Escena","help":"Ayuda","lang":"Idioma","new":"Nuevo","open":"Abrir","save":"Guardar","exit":"Salir","run":"Ejecutar juego","compile":"Compilar motor","package":"Empaquetar","explorer":"Explorador","output":"Salida","ready":"Listo","running":"Ejecutando...","saved":"Guardado","opened":"Abierto","build_first":"Compilar primero","kill":"Detenido","packaged":"Empaquetado","about":"Acerca de Lity3D"}, - "fr": {"app_title":"Lity3D Éditeur","file":"Fichier","build":"Construire","scene":"Scène","help":"Aide","lang":"Langue","new":"Nouveau","open":"Ouvrir","save":"Enregistrer","exit":"Quitter","run":"Exécuter le jeu","compile":"Compiler le moteur","package":"Package","explorer":"Explorateur","output":"Sortie","ready":"Prêt","running":"En cours...","saved":"Enregistré","opened":"Ouvert","build_first":"Compiler d'abord","kill":"Arrêté","packaged":"Packagé","about":"À propos"}, - "de": {"app_title":"Lity3D Editor","file":"Datei","build":"Erstellen","scene":"Szene","help":"Hilfe","lang":"Sprache","new":"Neu","open":"Öffnen","save":"Speichern","exit":"Beenden","run":"Spiel starten","compile":"Engine erstellen","package":"Paketieren","explorer":"Explorer","output":"Ausgabe","ready":"Bereit","running":"Läuft...","saved":"Gespeichert","opened":"Geöffnet","build_first":"Erst bauen","kill":"Gestoppt","packaged":"Paketiert","about":"Über Lity3D"}, - "ru": {"app_title":"Lity3D Редактор","file":"Файл","build":"Сборка","scene":"Сцена","help":"Справка","lang":"Язык","new":"Новый","open":"Открыть","save":"Сохранить","exit":"Выход","run":"Запуск","compile":"Собрать","package":"Упаковать","explorer":"Проводник","output":"Вывод","ready":"Готово","running":"Выполняется...","saved":"Сохранено","opened":"Открыто","build_first":"Сначала собрать","kill":"Остановлено","packaged":"Упаковано","about":"О Lity3D"}, - "pt": {"app_title":"Lity3D Editor","file":"Arquivo","build":"Compilar","scene":"Cena","help":"Ajuda","lang":"Idioma","new":"Novo","open":"Abrir","save":"Salvar","exit":"Sair","run":"Executar jogo","compile":"Compilar engine","package":"Empacotar","explorer":"Explorador","output":"Saída","ready":"Pronto","running":"Executando...","saved":"Salvo","opened":"Aberto","build_first":"Compilar primeiro","kill":"Parado","packaged":"Empacotado","about":"Sobre Lity3D"}, - "it": {"app_title":"Lity3D Editor","file":"File","build":"Compila","scene":"Scena","help":"Aiuto","lang":"Lingua","new":"Nuovo","open":"Apri","save":"Salva","exit":"Esci","run":"Esegui gioco","compile":"Compila engine","package":"Pacchetta","explorer":"Esplora","output":"Output","ready":"Pronto","running":"In esecuzione...","saved":"Salvato","opened":"Aperto","build_first":"Compila prima","kill":"Fermato","packaged":"Impacchettato","about":"Informazioni"}, - "tr": {"app_title":"Lity3D Editör","file":"Dosya","build":"Derle","scene":"Sahne","help":"Yardım","lang":"Dil","new":"Yeni","open":"Aç","save":"Kaydet","exit":"Çıkış","run":"Oyunu çalıştır","compile":"Motoru derle","package":"Paketle","explorer":"Gezgin","output":"Çıktı","ready":"Hazır","running":"Çalışıyor...","saved":"Kaydedildi","opened":"Açıldı","build_first":"Önce derle","kill":"Durduruldu","packaged":"Paketlendi","about":"Hakkında"}, - "ar": {"app_title":"Lity3D محرر","file":"ملف","build":"بناء","scene":"مشهد","help":"مساعدة","lang":"لغة","new":"جديد","open":"فتح","save":"حفظ","exit":"خروج","run":"تشغيل اللعبة","compile":"بناء المحرك","package":"تغليف EXE","explorer":"مستكشف","output":"مخرجات","ready":"جاهز","running":"يعمل...","saved":"تم الحفظ","opened":"تم الفتح","build_first":"ابنِ المحرك أولاً","kill":"تم الإيقاف","packaged":"تم التغليف","about":"عن Lity3D"}, - "hi": {"app_title":"Lity3D संपादक","file":"फ़ाइल","build":"बिल्ड","scene":"दृश्य","help":"सहायता","lang":"भाषा","new":"नया","open":"खोलें","save":"सहेजें","exit":"बाहर","run":"गेम चलाएं","compile":"इंजन बिल्ड","package":"EXE पैकेज","explorer":"एक्सप्लोरर","output":"आउटपुट","ready":"तैयार","running":"चल रहा है...","saved":"सहेजा गया","opened":"खोला गया","build_first":"पहले बिल्ड करें","kill":"बंद","packaged":"पैकेज्ड","about":"Lity3D के बारे में"}, - "th": {"app_title":"Lity3D ตัวแก้ไข","file":"ไฟล์","build":"สร้าง","scene":"ฉาก","help":"ช่วยเหลือ","lang":"ภาษา","new":"ใหม่","open":"เปิด","save":"บันทึก","exit":"ออก","run":"รันเกม","compile":"สร้างเอนจิ้น","package":"打包 EXE","explorer":"ตัวสำรวจ","output":"ผลลัพธ์","ready":"พร้อม","running":"กำลังทำงาน...","saved":"บันทึกแล้ว","opened":"เปิดแล้ว","build_first":"สร้างก่อน","kill":"หยุดแล้ว","packaged":"打包แล้ว","about":"เกี่ยวกับ Lity3D"}, - "vi": {"app_title":"Lity3D Trình soạn thảo","file":"Tệp","build":"Xây dựng","scene":"Cảnh","help":"Trợ giúp","lang":"Ngôn ngữ","new":"Mới","open":"Mở","save":"Lưu","exit":"Thoát","run":"Chạy trò chơi","compile":"Build Engine","package":"Gói EXE","explorer":"Trình duyệt","output":"Đầu ra","ready":"Sẵn sàng","running":"Đang chạy...","saved":"Đã lưu","opened":"Đã mở","build_first":"Build trước","kill":"Đã dừng","packaged":"Đã gói","about":"Về Lity3D"}, - "id": {"app_title":"Lity3D Editor","file":"Berkas","build":"Build","scene":"Sken","help":"Bantuan","lang":"Bahasa","new":"Baru","open":"Buka","save":"Simpan","exit":"Keluar","run":"Jalankan Game","compile":"Build Engine","package":"Paket EXE","explorer":"Penjelajah","output":"Output","ready":"Siap","running":"Berjalan...","saved":"Tersimpan","opened":"Terbuka","build_first":"Build dulu","kill":"Berhenti","packaged":"Terpaket","about":"Tentang Lity3D"}, - "pl": {"app_title":"Lity3D Edytor","file":"Plik","build":"Kompiluj","scene":"Scena","help":"Pomoc","lang":"Język","new":"Nowy","open":"Otwórz","save":"Zapisz","exit":"Wyjście","run":"Uruchom grę","compile":"Kompiluj silnik","package":"Pakietuj EXE","explorer":"Eksplorator","output":"Wyjście","ready":"Gotowy","running":"Działa...","saved":"Zapisano","opened":"Otwarto","build_first":"Najpierw kompiluj","kill":"Zatrzymano","packaged":"Spakowano","about":"O Lity3D"}, - "nl": {"app_title":"Lity3D Editor","file":"Bestand","build":"Bouwen","scene":"Scène","help":"Help","lang":"Taal","new":"Nieuw","open":"Open","save":"Opslaan","exit":"Afsluiten","run":"Spel uitvoeren","compile":"Engine bouwen","package":"Pakket EXE","explorer":"Verkenner","output":"Uitvoer","ready":"Gereed","running":"Actief...","saved":"Opgeslagen","opened":"Geopend","build_first":"Eerst bouwen","kill":"Gestopt","packaged":"Ingepakt","about":"Over Lity3D"}, - "uk": {"app_title":"Lity3D Редактор","file":"Файл","build":"Збірка","scene":"Сцена","help":"Довідка","lang":"Мова","new":"Новий","open":"Відкрити","save":"Зберегти","exit":"Вихід","run":"Запуск","compile":"Зібрати","package":"Упакувати","explorer":"Провідник","output":"Вивід","ready":"Готово","running":"Виконується...","saved":"Збережено","opened":"Відкрито","build_first":"Спочатку зібрати","kill":"Зупинено","packaged":"Упаковано","about":"Про Lity3D"}, - "cs": {"app_title":"Lity3D Editor","file":"Soubor","build":"Sestavit","scene":"Scéna","help":"Nápověda","lang":"Jazyk","new":"Nový","open":"Otevřít","save":"Uložit","exit":"Konec","run":"Spustit hru","compile":"Sestavit engine","package":"Zabalit EXE","explorer":"Průzkumník","output":"Výstup","ready":"Připraveno","running":"Běží...","saved":"Uloženo","opened":"Otevřeno","build_first":"Nejdřív sestavit","kill":"Zastaveno","packaged":"Zabaleno","about":"O Lity3D"}, - "ro": {"app_title":"Lity3D Editor","file":"Fișier","build":"Compilă","scene":"Scenă","help":"Ajutor","lang":"Limbă","new":"Nou","open":"Deschide","save":"Salvează","exit":"Ieșire","run":"Rulează joc","compile":"Compilează engine","package":"Pachet EXE","explorer":"Explorator","output":"Ieșire","ready":"Gata","running":"Rulează...","saved":"Salvat","opened":"Deschis","build_first":"Compilează prima dată","kill":"Oprit","packaged":"Impachetat","about":"Despre Lity3D"}, - "sv": {"app_title":"Lity3D Redigerare","file":"Fil","build":"Bygg","scene":"Scen","help":"Hjälp","lang":"Språk","new":"Ny","open":"Öppna","save":"Spara","exit":"Avsluta","run":"Kör spel","compile":"Bygg engine","package":"Paketera EXE","explorer":"Utforskare","output":"Utdata","ready":"Redo","running":"Körs...","saved":"Sparat","opened":"Öppnat","build_first":"Bygg först","kill":"Stoppad","packaged":"Paketerad","about":"Om Lity3D"}, - "fi": {"app_title":"Lity3D Editor","file":"Tiedosto","build":"Käännä","scene":"Sken","help":"Ohje","lang":"Kieli","new":"Uusi","open":"Avaa","save":"Tallenna","exit":"Lopeta","run":"Käynnistä peli","compile":"Käännä moottori","package":"Paketoi EXE","explorer":"Selain","output":"Tuloste","ready":"Valmis","running":"Käynnissä...","saved":"Tallennettu","opened":"Avattu","build_first":"Käännä ensin","kill":"Pysäytetty","packaged":"Paketoitu","about":"Tietoja Lity3D:stä"}, - "da": {"app_title":"Lity3D Editor","file":"Fil","build":"Byg","scene":"Scene","help":"Hjælp","lang":"Sprog","new":"Ny","open":"Åbn","save":"Gem","exit":"Afslut","run":"Kør spil","compile":"Byg engine","package":"Pakke EXE","explorer":"Stifinder","output":"Output","ready":"Klar","running":"Kører...","saved":"Gemt","opened":"Åbnet","build_first":"Byg først","kill":"Stoppet","packaged":"Pakket","about":"Om Lity3D"}, - "no": {"app_title":"Lity3D Editor","file":"Fil","build":"Bygg","scene":"Scene","help":"Hjelp","lang":"Språk","new":"Ny","open":"Åpne","save":"Lagre","exit":"Avslutt","run":"Kjør spill","compile":"Bygg engine","package":"Pakke EXE","explorer":"Utforsker","output":"Utdata","ready":"Klar","running":"Kjører...","saved":"Lagret","opened":"Åpnet","build_first":"Bygg først","kill":"Stoppet","packaged":"Pakket","about":"Om Lity3D"}, - "el": {"app_title":"Lity3D Επεξεργαστής","file":"Αρχείο","build":"Κατασκευή","scene":"Σκηνή","help":"Βοήθεια","lang":"Γλώσσα","new":"Νέο","open":"Άνοιγμα","save":"Αποθήκευση","exit":"Έξοδος","run":"Εκτέλεση παιχνιδιού","compile":"Κατασκευή engine","package":"Paketo EXE","explorer":"Ανιχνευτής","output":"Έξοδος","ready":"Έτοιμο","running":"Εκτελείται...","saved":"Αποθηκεύτηκε","opened":"Ανοίχθηκε","build_first":"Κατασκευή πρώτα","kill":"Σταμάτησε","packaged":"Πακετάριστηκε","about":"Σχετικά με Lity3D"}, - "he": {"app_title":"Lity3D עורך","file":"קובץ","build":"בנייה","scene":"סצנה","help":"עזרה","lang":"שפה","new":"חדש","open":"פתח","save":"שמור","exit":"יציאה","run":"הרץ משחק","compile":"בנה מנוע","package":"ארוז EXE","explorer":"סייר","output":"פלט","ready":"מוכן","running":"רץ...","saved":"נשמר","opened":"נפתח","build_first":"בנה קודם","kill":"נעצר","packaged":"נארז","about":"אודות Lity3D"}, - "ms": {"app_title":"Lity3D Editor","file":"Fail","build":"Bina","scene":"Adegan","help":"Bantuan","lang":"Bahasa","new":"Baharu","open":"Buka","save":"Simpan","exit":"Keluar","run":"Jalankan permainan","compile":"Bina engine","package":"Pakej EXE","explorer":"Peneroka","output":"Output","ready":"Sedia","running":"Berjalan...","saved":"Disimpan","opened":"Dibuka","build_first":"Bina dahulu","kill":"Dihentikan","packaged":"Dibungkus","about":"Tentang Lity3D"}, - "hu": {"app_title":"Lity3D Szerkesztő","file":"Fájl","build":"Fordítás","scene":"Jelenet","help":"Súgó","lang":"Nyelv","new":"Új","open":"Megnyitás","save":"Mentés","exit":"Kilépés","run":"Játék futtatása","compile":"Engine fordítás","package":"Csomagolás","explorer":"Fájlkezelő","output":"Kimenet","ready":"Kész","running":"Fut...","saved":"Mentve","opened":"Megnyitva","build_first":"Előbb fordíts","kill":"Leállítva","packaged":"Becsomagolva","about":"Névjegy"}, - "sk": {"app_title":"Lity3D Editor","file":"Súbor","build":"Kompilácia","scene":"Scéna","help":"Pomoc","lang":"Jazyk","new":"Nový","open":"Otvoriť","save":"Uložiť","exit":"Ukončiť","run":"Spustiť hru","compile":"Skompilovať engine","package":"Balenie EXE","explorer":"Prieskumník","output":"Výstup","ready":"Pripravené","running":"Prebieha...","saved":"Uložené","opened":"Otvorené","build_first":"Najprv skompilovať","kill":"Zastavené","packaged":"Zabalené","about":"O Lity3D"}, - "bg": {"app_title":"Lity3D Редактор","file":"Файл","build":"Компилация","scene":"Сцена","help":"Помощ","lang":"Език","new":"Нов","open":"Отвори","save":"Запази","exit":"Изход","run":"Стартирай игра","compile":"Компилирай engine","package":"Опаковай EXE","explorer":"Проводник","output":"Изход","ready":"Готово","running":"Работи...","saved":"Запазено","opened":"Отворено","build_first":"Първо компилирай","kill":"Спряно","packaged":"Опаковано","about":"Относно Lity3D"}, - "hr": {"app_title":"Lity3D Urednik","file":"Datoteka","build":"Izgradi","scene":"Scena","help":"Pomoć","lang":"Jezik","new":"Novo","open":"Otvori","save":"Spremi","exit":"Izlaz","run":"Pokreni igru","compile":"Izgradi engine","package":"Pakiraj EXE","explorer":"Istraživač","output":"Izlaz","ready":"Spreman","running":"Radi...","saved":"Spremljeno","opened":"Otvoreno","build_first":"Prvo izgradi","kill":"Zaustavljeno","packaged":"Pakirano","about":"O Lity3D"}, - "sr": {"app_title":"Lity3D Уредник","file":"Датотека","build":"Изградња","scene":"Сцена","help":"Помоћ","lang":"Језик","new":"Ново","open":"Отвори","save":"Сачувај","exit":"Излаз","run":"Покрени игру","compile":"Изгради engine","package":"Пакуј EXE","explorer":"Истраживач","output":"Излаз","ready":"Спреман","running":"Ради...","saved":"Сачувано","opened":"Отворено","build_first":"Прво изгради","kill":"Заустављено","packaged":"Паковано","about":"О Lity3D"}, - "sl": {"app_title":"Lity3D Urejevalnik","file":"Datoteka","build":"Izgradi","scene":"Scena","help":"Pomoč","lang":"Jezik","new":"Novo","open":"Odpri","save":"Shrani","exit":"Izhod","run":"Zaženi igro","compile":"Izgradi engine","package":"Pakiraj EXE","explorer":"Raziskovalec","output":"Izhod","ready":"Pripravljeno","running":"Deluje...","saved":"Shranjeno","opened":"Odprto","build_first":"Najprej izgradi","kill":"Ustavljeno","packaged":"Pakirano","about":"O Lity3D"}, - "lt": {"app_title":"Lity3D Redaktorius","file":"Failas","build":"Kompiliuoti","scene":"Scena","help":"Pagalba","lang":"Kalba","new":"Naujas","open":"Atidaryti","save":"Išsaugoti","exit":"Išeiti","run":"Paleisti žaidimą","compile":"Kompiliuoti variklį","package":"Pakuot EXE","explorer":"Naršyklė","output":"Išvestis","ready":"Pasirengęs","running":"Veikia...","saved":"Išsaugota","opened":"Atidaryta","build_first":"Pirmiau kompiliuoti","kill":"Sustabdyta","packaged":"Supakuota","about":"Apie Lity3D"}, - "lv": {"app_title":"Lity3D Redaktors","file":"Fails","build":"Kompilēt","scene":"Aina","help":"Palīdzība","lang":"Valoda","new":"Jauns","open":"Atvērt","save":"Saglabāt","exit":"Izeja","run":"Palaist spēli","compile":"Kompilēt dzinēju","package":"Paketēt EXE","explorer":"Pārlūks","output":"Izeja","ready":"Gatavs","running":"Darbojas...","saved":"Saglabāts","opened":"Atvērts","build_first":"Vispirums kompilēt","kill":"Aizturēts","packaged":"Pakets","about":"Par Lity3D"}, - "et": {"app_title":"Lity3D Redaktor","file":"Fail","build":"Kompileeri","scene":"Stseen","help":"Abi","lang":"Keel","new":"Uus","open":"Ava","save":"Salvesta","exit":"Välju","run":"Käivita mäng","compile":"Kompileeri mootor","package":"Pakendi EXE","explorer":"Eksploorija","output":"Väljund","ready":"Valmis","running":"Töötab...","saved":"Salvestatud","opened":"Avatud","build_first":"Esmalt kompileeri","kill":"Peatatud","packaged":"Pakitud","about":"Lity3D kohta"}, - "sk2": {"app_title":"Lity3D Editor","file":"Súbor","build":"Build","scene":"Scéna","help":"Pomoc","lang":"Jazyk","new":"Nový","open":"Otvoriť","save":"Uložiť","exit":"Ukončiť","run":"Spustiť","compile":"Build","package":"Balenie","explorer":"Prieskumník","output":"Výstup","ready":"Pripravené","running":"Beží...","saved":"Uložené","opened":"Otvorené","build_first":"Najprv build","kill":"Zastavené","packaged":"Zabalené","about":"O Lity3D"}, - "fa": {"app_title":"Lity3D ویرایشگر","file":"پرونده","build":"ساخت","scene":"صحنه","help":"راهنما","lang":"زبان","new":"جدید","open":"باز کردن","save":"ذخیره","exit":"خروج","run":"اجرای بازی","compile":"ساخت موتور","package":"بسته بندی EXE","explorer":"کاوشگر","output":"خروجی","ready":"آماده","running":"در حال اجرا...","saved":"ذخیره شد","opened":"باز شد","build_first":"اول بساز","kill":"متوقف شد","packaged":"بسته بندی شد","about":"درباره Lity3D"}, - "bn": {"app_title":"Lity3D সম্পাদক","file":"ফাইল","build":"বিল্ড","scene":"দৃশ্য","help":"সাহায্য","lang":"ভাষা","new":"নতুন","open":"খুলুন","save":"সংরক্ষণ","exit":"বের হোন","run":"খেলা চালান","compile":"ইঞ্জিন বিল্ড","package":"EXE প্যাকেজ","explorer":"এক্সপ্লোরার","output":"আউটপুট","ready":"প্রস্তুত","running":"চলছে...","saved":"সংরক্ষিত","opened":"খোলা হয়েছে","build_first":"প্রথমে বিল্ড করুন","kill":"বন্ধ","packaged":"প্যাকেজ করা হয়েছে","about":"Lity3D সম্পর্কে"}, - "sw": {"app_title":"Lity3D Mhariri","file":"Faili","build":"Jenga","scene":"Onyesho","help":"Msaada","lang":"Lugha","new":"Mpya","open":"Fungua","save":"Hifadhi","exit":"Ondoka","run":"Endesha mchezo","compile":"Jenga injini","package":"Pakiti EXE","explorer":"Vinara","output":"Matokeo","ready":"Iko tayari","running":"Inafanya kazi...","saved":"Imehifadhiwa","opened":"Imefunguliwa","build_first":"Jenga kwanza","kill":"Imesimamishwa","packaged":"Imepakiwa","about":"Kuhusu Lity3D"}, - "ta": {"app_title":"Lity3D திருத்தி","file":"கோப்பு","build":"உருவாக்கு","scene":"காட்சி","help":"உதவி","lang":"மொழி","new":"புதிய","open":"திற","save":"சேமி","exit":"வெளியேறு","run":"விளையாட்டை இயக்கு","compile":"இயந்திரத்தை உருவாக்கு","package":"EXE பேக்கேஜ்","explorer":"ஆராய்ச்சியாளர்","output":"வெளியீடு","ready":"தயார்","running":"இயங்குகிறது...","saved":"சேமிக்கப்பட்டது","opened":"திறக்கப்பட்டது","build_first":"முதலில் உருவாக்கு","kill":"நிறுத்தப்பட்டது","packaged":"பேக்கேஜ் செய்யப்பட்டது","about":"Lity3D பற்றி"}, - "ml": {"app_title":"Lity3D എഡിറ്റർ","file":"ഫയൽ","build":"ബിൽഡ്","scene":"രംഗം","help":"സഹായം","lang":"ഭാഷ","new":"പുതിയ","open":"തുറക്കുക","save":"സേവ് ചെയ്യുക","exit":"പുറത്തുപോകുക","run":"ഗെയിം റൺ ചെയ്യുക","compile":"എഞ്ചിൻ ബിൽഡ്","package":"EXE പാക്കേജ്","explorer":"എക്സ്പ്ലോറർ","output":"ഔട്ട്പുട്ട്","ready":"തയ്യാർ","running":"റൺ ചെയ്യുന്നു...","saved":"സേവ് ചെയ്തു","opened":"തുറന്നു","build_first":"ആദ്യം ബിൽഡ് ചെയ്യുക","kill":"നിർത്തി","packaged":"പാക്കേജ് ചെയ്തു","about":"Lity3D യെ കുറിച്ച്"}, - "te": {"app_title":"Lity3D ఎడిటర్","file":"ఫైల్","build":"బిల్డ్","scene":"దృశ్యం","help":"సహాయం","lang":"భాష","new":"కొత్త","open":"తెరవండి","save":"సేవ్ చేయండి","exit":"నిష్క్రమించండి","run":"గేమ్ రన్","compile":"ఇంజిన్ బిల్డ్","package":"EXE ప్యాకేజ్","explorer":"ఎక్స్‌ప్లోరర్","output":"అవుట్‌పుట్","ready":"సిద్ధం","running":"రన్ అవుతోంది...","saved":"సేవ్ చేయబడింది","opened":"తెరవబడింది","build_first":"మొదట బిల్డ్","kill":"ఆపబడింది","packaged":"ప్యాకేజ్ చేయబడింది","about":"Lity3D గురించి"}, -} - -for lang, strings in translations.items(): - path = os.path.join(BASE, f"{lang}.json") - with open(path, 'w', encoding='utf-8') as f: - json.dump(strings, f, ensure_ascii=False, indent=2) - print(f"Created: {lang}.json ({len(strings)} keys)") - -print(f"\nTotal: {len(translations)} languages") diff --git a/i18n.py b/i18n.py deleted file mode 100644 index cb9769f..0000000 --- a/i18n.py +++ /dev/null @@ -1,542 +0,0 @@ -""" -Lity3D Editor 多语言翻译系统 -支持: 中文、English、日本語、한국어、Español、Français、Deutsch、Русский、العربية、Português、Italiano、Türkçe -""" -import json, os - -LANG_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "languages") - -_translations = { - "zh": { - "app_title": "Lity3D 编辑器", - "menu_file": "文件", - "menu_edit": "编辑", - "menu_build": "构建", - "menu_scene": "场景", - "menu_help": "帮助", - "menu_view": "视图", - "menu_language": "语言", - "new_file": "新建文件", - "open_file": "打开文件", - "open_folder": "打开文件夹", - "save": "保存", - "save_as": "另存为", - "exit": "退出", - "run": "运行", - "run_game": "运行游戏", - "run_file": "运行当前文件", - "stop": "停止", - "build_engine": "编译引擎", - "build_exe": "打包为 EXE", - "kill_process": "终止进程", - "new_scene": "新建场景", - "open_scene": "打开场景", - "save_scene": "保存场景", - "run_scene": "运行场景", - "about": "关于 Lity3D", - "docs": "API 文档", - "explorer": "资源管理器", - "output": "输出", - "console": "控制台", - "ready": "就绪", - "running": "运行中...", - "saved": "已保存", - "opened": "已打开", - "new_file_msg": "新文件", - "no_file": "没有打开文件", - "no_scene": "没有找到场景文件", - "build_first": "请先编译引擎", - "kill_done": "进程已终止", - "build_ok": "编译成功", - "build_err": "编译失败", - "packaged": "已打包", - "new_scene_ok": "新场景已创建", - "process_exit": "进程退出,返回码", - "cant_run": "无法运行此类文件", - "interpreter_not_found": "解释器未编译", - "theme": "主题", - "dark_theme": "深色主题", - "light_theme": "浅色主题", - "undo": "撤销", - "redo": "重做", - "cut": "剪切", - "copy": "复制", - "paste": "粘贴", - "select_all": "全选", - "find": "查找", - "replace": "替换", - "goto_line": "跳转到行", - "preferences": "首选项", - "recent_files": "最近文件", - "reload": "重新加载", - "close_tab": "关闭标签", - "close_all": "关闭所有", - "line": "行", - "col": "列", - "chars": "字符", - "encoding": "编码", - "new_scene_dialog_title": "新建场景", - "new_scene_name": "场景名称:", - "new_scene_type": "场景类型:", - "type_empty": "空场景", - "type_rpg": "RPG 模板", - "type_fps": "FPS 模板", - "type_platformer": "平台跳跃模板", - "type_custom": "自定义", - "create": "创建", - "cancel": "取消", - "confirm": "确认", - "delete": "删除", - "rename": "重命名", - "duplicate": "复制", - "properties": "属性", - "hierarchy": "层级", - "inspector": "检查器", - "game_view": "游戏视图", - "scene_view": "场景视图", - "project": "项目", - }, - "en": { - "app_title": "Lity3D Editor", - "menu_file": "File", - "menu_edit": "Edit", - "menu_build": "Build", - "menu_scene": "Scene", - "menu_help": "Help", - "menu_view": "View", - "menu_language": "Language", - "new_file": "New File", - "open_file": "Open File", - "open_folder": "Open Folder", - "save": "Save", - "save_as": "Save As", - "exit": "Exit", - "run": "Run", - "run_game": "Run Game", - "run_file": "Run Current File", - "stop": "Stop", - "build_engine": "Build Engine", - "build_exe": "Package as EXE", - "kill_process": "Kill Process", - "new_scene": "New Scene", - "open_scene": "Open Scene", - "save_scene": "Save Scene", - "run_scene": "Run Scene", - "about": "About Lity3D", - "docs": "API Docs", - "explorer": "Explorer", - "output": "Output", - "console": "Console", - "ready": "Ready", - "running": "Running...", - "saved": "Saved", - "opened": "Opened", - "new_file_msg": "New file", - "no_file": "No file open", - "no_scene": "No scene file found", - "build_first": "Build engine first", - "kill_done": "Process killed", - "build_ok": "Build succeeded", - "build_err": "Build failed", - "packaged": "Packaged to", - "new_scene_ok": "New scene created", - "process_exit": "Process exited with code", - "cant_run": "Cannot run this file type", - "interpreter_not_found": "Interpreter not built", - "theme": "Theme", - "dark_theme": "Dark Theme", - "light_theme": "Light Theme", - "undo": "Undo", - "redo": "Redo", - "cut": "Cut", - "copy": "Copy", - "paste": "Paste", - "select_all": "Select All", - "find": "Find", - "replace": "Replace", - "goto_line": "Go to Line", - "preferences": "Preferences", - "recent_files": "Recent Files", - "reload": "Reload", - "close_tab": "Close Tab", - "close_all": "Close All", - "line": "Line", - "col": "Col", - "chars": "Characters", - "encoding": "Encoding", - "new_scene_dialog_title": "New Scene", - "new_scene_name": "Scene Name:", - "new_scene_type": "Scene Type:", - "type_empty": "Empty Scene", - "type_rpg": "RPG Template", - "type_fps": "FPS Template", - "type_platformer": "Platformer Template", - "type_custom": "Custom", - "create": "Create", - "cancel": "Cancel", - "confirm": "Confirm", - "delete": "Delete", - "rename": "Rename", - "duplicate": "Duplicate", - "properties": "Properties", - "hierarchy": "Hierarchy", - "inspector": "Inspector", - "game_view": "Game View", - "scene_view": "Scene View", - "project": "Project", - }, - "ja": { - "app_title": "Lity3D エディタ", - "menu_file": "ファイル", - "menu_edit": "編集", - "menu_build": "ビルド", - "menu_scene": "シーン", - "menu_help": "ヘルプ", - "menu_view": "表示", - "menu_language": "言語", - "new_file": "新規ファイル", - "open_file": "ファイルを開く", - "open_folder": "フォルダを開く", - "save": "保存", - "save_as": "名前を付けて保存", - "exit": "終了", - "run": "実行", - "run_game": "ゲームを実行", - "run_file": "現在のファイルを実行", - "stop": "停止", - "build_engine": "エンジンをビルド", - "build_exe": "EXEにパッケージ", - "kill_process": "プロセスを終了", - "new_scene": "新規シーン", - "open_scene": "シーンを開く", - "save_scene": "シーンを保存", - "run_scene": "シーンを実行", - "about": "Lity3D について", - "docs": "API ドキュメント", - "explorer": "エクスプローラ", - "output": "出力", - "ready": "準備完了", - "running": "実行中...", - "dark_theme": "ダークテーマ", - "light_theme": "ライトテーマ", - "undo": "元に戻す", - "redo": "やり直す", - "save_as": "名前を付けて保存", - "line": "行", - "col": "列", - "cancel": "キャンセル", - "create": "作成", - }, - "ko": { - "app_title": "Lity3D 편집기", - "menu_file": "파일", - "menu_edit": "편집", - "menu_build": "빌드", - "menu_scene": "씬", - "menu_help": "도움말", - "menu_view": "보기", - "menu_language": "언어", - "new_file": "새 파일", - "open_file": "파일 열기", - "open_folder": "폴더 열기", - "save": "저장", - "save_as": "다른 이름으로 저장", - "exit": "종료", - "run": "실행", - "run_game": "게임 실행", - "run_file": "현재 파일 실행", - "stop": "중지", - "build_engine": "엔진 빌드", - "build_exe": "EXE로 패키징", - "kill_process": "프로세스 종료", - "new_scene": "새 씬", - "about": "Lity3D 정보", - "docs": "API 문서", - "explorer": "탐색기", - "output": "출력", - "ready": "준비", - "running": "실행 중...", - "dark_theme": "다크 테마", - "light_theme": "라이트 테마", - "undo": "실행 취소", - "redo": "다시 실행", - "cancel": "취소", - "create": "생성", - "line": "줄", - "col": "열", - }, - "es": { - "app_title": "Lity3D Editor", - "menu_file": "Archivo", - "menu_edit": "Editar", - "menu_build": "Construir", - "menu_scene": "Escena", - "menu_help": "Ayuda", - "menu_view": "Vista", - "menu_language": "Idioma", - "new_file": "Nuevo archivo", - "open_file": "Abrir archivo", - "save": "Guardar", - "save_as": "Guardar como", - "exit": "Salir", - "run": "Ejecutar", - "run_game": "Ejecutar juego", - "stop": "Detener", - "build_engine": "Compilar motor", - "build_exe": "Empaquetar como EXE", - "about": "Acerca de Lity3D", - "explorer": "Explorador", - "output": "Salida", - "ready": "Listo", - "running": "Ejecutando...", - "dark_theme": "Tema oscuro", - "light_theme": "Tema claro", - "undo": "Deshacer", - "redo": "Rehacer", - "cancel": "Cancelar", - "create": "Crear", - "line": "Línea", - "col": "Col", - }, - "fr": { - "app_title": "Lity3D Éditeur", - "menu_file": "Fichier", - "menu_edit": "Édition", - "menu_build": "Construire", - "menu_scene": "Scène", - "menu_help": "Aide", - "menu_view": "Affichage", - "menu_language": "Langue", - "new_file": "Nouveau fichier", - "open_file": "Ouvrir fichier", - "save": "Enregistrer", - "save_as": "Enregistrer sous", - "exit": "Quitter", - "run": "Exécuter", - "run_game": "Exécuter le jeu", - "stop": "Arrêter", - "build_engine": "Compiler le moteur", - "build_exe": "Package EXE", - "about": "À propos", - "explorer": "Explorateur", - "output": "Sortie", - "ready": "Prêt", - "running": "En exécution...", - "dark_theme": "Thème sombre", - "light_theme": "Thème clair", - "undo": "Annuler", - "redo": "Rétablir", - "cancel": "Annuler", - "create": "Créer", - "line": "Ligne", - "col": "Col", - }, - "de": { - "app_title": "Lity3D Editor", - "menu_file": "Datei", - "menu_edit": "Bearbeiten", - "menu_build": "Erstellen", - "menu_scene": "Szene", - "menu_help": "Hilfe", - "menu_view": "Ansicht", - "menu_language": "Sprache", - "new_file": "Neue Datei", - "open_file": "Datei öffnen", - "save": "Speichern", - "save_as": "Speichern unter", - "exit": "Beenden", - "run": "Ausführen", - "run_game": "Spiel starten", - "stop": "Stopp", - "build_engine": "Engine erstellen", - "build_exe": "Als EXE paketieren", - "about": "Über Lity3D", - "explorer": "Explorer", - "output": "Ausgabe", - "ready": "Bereit", - "running": "Wird ausgeführt...", - "dark_theme": "Dunkles Theme", - "light_theme": "Helles Theme", - "undo": "Rückgängig", - "redo": "Wiederholen", - "cancel": "Abbrechen", - "create": "Erstellen", - "line": "Zeile", - "col": "Spalte", - }, - "ru": { - "app_title": "Lity3D Редактор", - "menu_file": "Файл", - "menu_edit": "Правка", - "menu_build": "Сборка", - "menu_scene": "Сцена", - "menu_help": "Справка", - "menu_view": "Вид", - "menu_language": "Язык", - "new_file": "Новый файл", - "open_file": "Открыть файл", - "save": "Сохранить", - "save_as": "Сохранить как", - "exit": "Выход", - "run": "Запуск", - "run_game": "Запустить игру", - "stop": "Стоп", - "build_engine": "Собрать движок", - "build_exe": "Упаковать в EXE", - "about": "О Lity3D", - "explorer": "Проводник", - "output": "Вывод", - "ready": "Готово", - "running": "Выполняется...", - "dark_theme": "Тёмная тема", - "light_theme": "Светлая тема", - "undo": "Отменить", - "redo": "Повторить", - "cancel": "Отмена", - "create": "Создать", - "line": "Строка", - "col": "Столбец", - }, - "pt": { - "app_title": "Lity3D Editor", - "menu_file": "Arquivo", - "menu_edit": "Editar", - "menu_build": "Compilar", - "menu_scene": "Cena", - "menu_help": "Ajuda", - "menu_view": "Visualizar", - "menu_language": "Idioma", - "new_file": "Novo arquivo", - "open_file": "Abrir arquivo", - "save": "Salvar", - "save_as": "Salvar como", - "exit": "Sair", - "run": "Executar", - "run_game": "Executar jogo", - "stop": "Parar", - "build_engine": "Compilar engine", - "build_exe": "Empacotar EXE", - "about": "Sobre Lity3D", - "explorer": "Explorador", - "output": "Saída", - "ready": "Pronto", - "running": "Executando...", - "dark_theme": "Tema escuro", - "light_theme": "Tema claro", - "undo": "Desfazer", - "redo": "Refazer", - "cancel": "Cancelar", - "create": "Criar", - "line": "Linha", - "col": "Col", - }, - "it": { - "app_title": "Lity3D Editor", - "menu_file": "File", - "menu_edit": "Modifica", - "menu_build": "Compila", - "menu_scene": "Scena", - "menu_help": "Aiuto", - "menu_view": "Vista", - "menu_language": "Lingua", - "new_file": "Nuovo file", - "open_file": "Apri file", - "save": "Salva", - "save_as": "Salva come", - "exit": "Esci", - "run": "Esegui", - "run_game": "Esegui gioco", - "stop": "Ferma", - "build_engine": "Compila engine", - "build_exe": "Pacchetta EXE", - "about": "Informazioni", - "explorer": "Esplora", - "output": "Output", - "ready": "Pronto", - "running": "In esecuzione...", - "dark_theme": "Tema scuro", - "light_theme": "Tema chiaro", - "undo": "Annulla", - "redo": "Ripristina", - "cancel": "Annulla", - "create": "Crea", - "line": "Riga", - "col": "Col", - }, - "tr": { - "app_title": "Lity3D Editör", - "menu_file": "Dosya", - "menu_edit": "Düzenle", - "menu_build": "Derle", - "menu_scene": "Sahne", - "menu_help": "Yardım", - "menu_view": "Görünüm", - "menu_language": "Dil", - "new_file": "Yeni dosya", - "open_file": "Dosya aç", - "save": "Kaydet", - "save_as": "Farklı kaydet", - "exit": "Çıkış", - "run": "Çalıştır", - "run_game": "Oyunu çalıştır", - "stop": "Durdur", - "build_engine": "Motoru derle", - "build_exe": "EXE paketle", - "about": "Hakkında", - "explorer": "Gezgin", - "output": "Çıktı", - "ready": "Hazır", - "running": "Çalışıyor...", - "dark_theme": "Koyu tema", - "light_theme": "Açık tema", - "undo": "Geri al", - "redo": "Yinele", - "cancel": "İptal", - "create": "Oluştur", - "line": "Satır", - "col": "Sütun", - }, -} - -_current_lang = "zh" -_listeners = [] - -LANG_NAMES = { - "zh": "中文", "en": "English", "ja": "日本語", "ko": "한국어", - "es": "Español", "fr": "Français", "de": "Deutsch", "ru": "Русский", - "pt": "Português", "it": "Italiano", "tr": "Türkçe", -} - -def t(key): - lang = _translations.get(_current_lang, _translations["en"]) - return lang.get(key, _translations["en"].get(key, key)) - -def set_language(lang_code): - global _current_lang - if lang_code in _translations: - _current_lang = lang_code - for cb in _listeners: - cb() - -def get_language(): - return _current_lang - -def on_language_change(callback): - _listeners.append(callback) - -def get_all_languages(): - return [(code, LANG_NAMES.get(code, code)) for code in _translations] - -def save_language(code): - path = os.path.join(os.path.dirname(os.path.abspath(__file__)), ".lang") - with open(path, "w") as f: - f.write(code) - -def load_language(): - global _current_lang - path = os.path.join(os.path.dirname(os.path.abspath(__file__)), ".lang") - if os.path.exists(path): - with open(path) as f: - code = f.read().strip() - if code in _translations: - _current_lang = code diff --git a/languages/ar.json b/languages/ar.json deleted file mode 100644 index effe547..0000000 --- a/languages/ar.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D محرر", - "file": "ملف", - "build": "بناء", - "scene": "مشهد", - "help": "مساعدة", - "lang": "لغة", - "new": "جديد", - "open": "فتح", - "save": "حفظ", - "exit": "خروج", - "run": "تشغيل اللعبة", - "compile": "بناء المحرك", - "package": "تغليف EXE", - "explorer": "مستكشف", - "output": "مخرجات", - "ready": "جاهز", - "running": "يعمل...", - "saved": "تم الحفظ", - "opened": "تم الفتح", - "build_first": "ابنِ المحرك أولاً", - "kill": "تم الإيقاف", - "packaged": "تم التغليف", - "about": "عن Lity3D" -} \ No newline at end of file diff --git a/languages/bg.json b/languages/bg.json deleted file mode 100644 index b4d996d..0000000 --- a/languages/bg.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Редактор", - "file": "Файл", - "build": "Компилация", - "scene": "Сцена", - "help": "Помощ", - "lang": "Език", - "new": "Нов", - "open": "Отвори", - "save": "Запази", - "exit": "Изход", - "run": "Стартирай игра", - "compile": "Компилирай engine", - "package": "Опаковай EXE", - "explorer": "Проводник", - "output": "Изход", - "ready": "Готово", - "running": "Работи...", - "saved": "Запазено", - "opened": "Отворено", - "build_first": "Първо компилирай", - "kill": "Спряно", - "packaged": "Опаковано", - "about": "Относно Lity3D" -} \ No newline at end of file diff --git a/languages/bn.json b/languages/bn.json deleted file mode 100644 index dcd2b05..0000000 --- a/languages/bn.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D সম্পাদক", - "file": "ফাইল", - "build": "বিল্ড", - "scene": "দৃশ্য", - "help": "সাহায্য", - "lang": "ভাষা", - "new": "নতুন", - "open": "খুলুন", - "save": "সংরক্ষণ", - "exit": "বের হোন", - "run": "খেলা চালান", - "compile": "ইঞ্জিন বিল্ড", - "package": "EXE প্যাকেজ", - "explorer": "এক্সপ্লোরার", - "output": "আউটপুট", - "ready": "প্রস্তুত", - "running": "চলছে...", - "saved": "সংরক্ষিত", - "opened": "খোলা হয়েছে", - "build_first": "প্রথমে বিল্ড করুন", - "kill": "বন্ধ", - "packaged": "প্যাকেজ করা হয়েছে", - "about": "Lity3D সম্পর্কে" -} \ No newline at end of file diff --git a/languages/cs.json b/languages/cs.json deleted file mode 100644 index 91af350..0000000 --- a/languages/cs.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "Soubor", - "build": "Sestavit", - "scene": "Scéna", - "help": "Nápověda", - "lang": "Jazyk", - "new": "Nový", - "open": "Otevřít", - "save": "Uložit", - "exit": "Konec", - "run": "Spustit hru", - "compile": "Sestavit engine", - "package": "Zabalit EXE", - "explorer": "Průzkumník", - "output": "Výstup", - "ready": "Připraveno", - "running": "Běží...", - "saved": "Uloženo", - "opened": "Otevřeno", - "build_first": "Nejdřív sestavit", - "kill": "Zastaveno", - "packaged": "Zabaleno", - "about": "O Lity3D" -} \ No newline at end of file diff --git a/languages/da.json b/languages/da.json deleted file mode 100644 index 3679de0..0000000 --- a/languages/da.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "Fil", - "build": "Byg", - "scene": "Scene", - "help": "Hjælp", - "lang": "Sprog", - "new": "Ny", - "open": "Åbn", - "save": "Gem", - "exit": "Afslut", - "run": "Kør spil", - "compile": "Byg engine", - "package": "Pakke EXE", - "explorer": "Stifinder", - "output": "Output", - "ready": "Klar", - "running": "Kører...", - "saved": "Gemt", - "opened": "Åbnet", - "build_first": "Byg først", - "kill": "Stoppet", - "packaged": "Pakket", - "about": "Om Lity3D" -} \ No newline at end of file diff --git a/languages/de.json b/languages/de.json deleted file mode 100644 index 055eb32..0000000 --- a/languages/de.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "Datei", - "build": "Erstellen", - "scene": "Szene", - "help": "Hilfe", - "lang": "Sprache", - "new": "Neu", - "open": "Öffnen", - "save": "Speichern", - "exit": "Beenden", - "run": "Spiel starten", - "compile": "Engine erstellen", - "package": "Paketieren", - "explorer": "Explorer", - "output": "Ausgabe", - "ready": "Bereit", - "running": "Läuft...", - "saved": "Gespeichert", - "opened": "Geöffnet", - "build_first": "Erst bauen", - "kill": "Gestoppt", - "packaged": "Paketiert", - "about": "Über Lity3D" -} \ No newline at end of file diff --git a/languages/el.json b/languages/el.json deleted file mode 100644 index 8c8a0f6..0000000 --- a/languages/el.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Επεξεργαστής", - "file": "Αρχείο", - "build": "Κατασκευή", - "scene": "Σκηνή", - "help": "Βοήθεια", - "lang": "Γλώσσα", - "new": "Νέο", - "open": "Άνοιγμα", - "save": "Αποθήκευση", - "exit": "Έξοδος", - "run": "Εκτέλεση παιχνιδιού", - "compile": "Κατασκευή engine", - "package": "Paketo EXE", - "explorer": "Ανιχνευτής", - "output": "Έξοδος", - "ready": "Έτοιμο", - "running": "Εκτελείται...", - "saved": "Αποθηκεύτηκε", - "opened": "Ανοίχθηκε", - "build_first": "Κατασκευή πρώτα", - "kill": "Σταμάτησε", - "packaged": "Πακετάριστηκε", - "about": "Σχετικά με Lity3D" -} \ No newline at end of file diff --git a/languages/en.json b/languages/en.json deleted file mode 100644 index bce2e58..0000000 --- a/languages/en.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "File", - "build": "Build", - "scene": "Scene", - "help": "Help", - "lang": "Language", - "new": "New", - "open": "Open", - "save": "Save", - "exit": "Exit", - "run": "Run Game", - "compile": "Build Engine", - "package": "Package EXE", - "explorer": "Explorer", - "output": "Output", - "ready": "Ready", - "running": "Running...", - "saved": "Saved", - "opened": "Opened", - "build_first": "Build engine first", - "kill": "Process killed", - "packaged": "Packaged", - "about": "About Lity3D" -} \ No newline at end of file diff --git a/languages/es.json b/languages/es.json deleted file mode 100644 index 83ae8a3..0000000 --- a/languages/es.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "Archivo", - "build": "Compilar", - "scene": "Escena", - "help": "Ayuda", - "lang": "Idioma", - "new": "Nuevo", - "open": "Abrir", - "save": "Guardar", - "exit": "Salir", - "run": "Ejecutar juego", - "compile": "Compilar motor", - "package": "Empaquetar", - "explorer": "Explorador", - "output": "Salida", - "ready": "Listo", - "running": "Ejecutando...", - "saved": "Guardado", - "opened": "Abierto", - "build_first": "Compilar primero", - "kill": "Detenido", - "packaged": "Empaquetado", - "about": "Acerca de Lity3D" -} \ No newline at end of file diff --git a/languages/et.json b/languages/et.json deleted file mode 100644 index e7c9a1c..0000000 --- a/languages/et.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Redaktor", - "file": "Fail", - "build": "Kompileeri", - "scene": "Stseen", - "help": "Abi", - "lang": "Keel", - "new": "Uus", - "open": "Ava", - "save": "Salvesta", - "exit": "Välju", - "run": "Käivita mäng", - "compile": "Kompileeri mootor", - "package": "Pakendi EXE", - "explorer": "Eksploorija", - "output": "Väljund", - "ready": "Valmis", - "running": "Töötab...", - "saved": "Salvestatud", - "opened": "Avatud", - "build_first": "Esmalt kompileeri", - "kill": "Peatatud", - "packaged": "Pakitud", - "about": "Lity3D kohta" -} \ No newline at end of file diff --git a/languages/fa.json b/languages/fa.json deleted file mode 100644 index 780d9e8..0000000 --- a/languages/fa.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D ویرایشگر", - "file": "پرونده", - "build": "ساخت", - "scene": "صحنه", - "help": "راهنما", - "lang": "زبان", - "new": "جدید", - "open": "باز کردن", - "save": "ذخیره", - "exit": "خروج", - "run": "اجرای بازی", - "compile": "ساخت موتور", - "package": "بسته بندی EXE", - "explorer": "کاوشگر", - "output": "خروجی", - "ready": "آماده", - "running": "در حال اجرا...", - "saved": "ذخیره شد", - "opened": "باز شد", - "build_first": "اول بساز", - "kill": "متوقف شد", - "packaged": "بسته بندی شد", - "about": "درباره Lity3D" -} \ No newline at end of file diff --git a/languages/fi.json b/languages/fi.json deleted file mode 100644 index cf2001a..0000000 --- a/languages/fi.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "Tiedosto", - "build": "Käännä", - "scene": "Sken", - "help": "Ohje", - "lang": "Kieli", - "new": "Uusi", - "open": "Avaa", - "save": "Tallenna", - "exit": "Lopeta", - "run": "Käynnistä peli", - "compile": "Käännä moottori", - "package": "Paketoi EXE", - "explorer": "Selain", - "output": "Tuloste", - "ready": "Valmis", - "running": "Käynnissä...", - "saved": "Tallennettu", - "opened": "Avattu", - "build_first": "Käännä ensin", - "kill": "Pysäytetty", - "packaged": "Paketoitu", - "about": "Tietoja Lity3D:stä" -} \ No newline at end of file diff --git a/languages/fr.json b/languages/fr.json deleted file mode 100644 index 8ae886c..0000000 --- a/languages/fr.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Éditeur", - "file": "Fichier", - "build": "Construire", - "scene": "Scène", - "help": "Aide", - "lang": "Langue", - "new": "Nouveau", - "open": "Ouvrir", - "save": "Enregistrer", - "exit": "Quitter", - "run": "Exécuter le jeu", - "compile": "Compiler le moteur", - "package": "Package", - "explorer": "Explorateur", - "output": "Sortie", - "ready": "Prêt", - "running": "En cours...", - "saved": "Enregistré", - "opened": "Ouvert", - "build_first": "Compiler d'abord", - "kill": "Arrêté", - "packaged": "Packagé", - "about": "À propos" -} \ No newline at end of file diff --git a/languages/he.json b/languages/he.json deleted file mode 100644 index c3545ec..0000000 --- a/languages/he.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D עורך", - "file": "קובץ", - "build": "בנייה", - "scene": "סצנה", - "help": "עזרה", - "lang": "שפה", - "new": "חדש", - "open": "פתח", - "save": "שמור", - "exit": "יציאה", - "run": "הרץ משחק", - "compile": "בנה מנוע", - "package": "ארוז EXE", - "explorer": "סייר", - "output": "פלט", - "ready": "מוכן", - "running": "רץ...", - "saved": "נשמר", - "opened": "נפתח", - "build_first": "בנה קודם", - "kill": "נעצר", - "packaged": "נארז", - "about": "אודות Lity3D" -} \ No newline at end of file diff --git a/languages/hi.json b/languages/hi.json deleted file mode 100644 index 36a390b..0000000 --- a/languages/hi.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D संपादक", - "file": "फ़ाइल", - "build": "बिल्ड", - "scene": "दृश्य", - "help": "सहायता", - "lang": "भाषा", - "new": "नया", - "open": "खोलें", - "save": "सहेजें", - "exit": "बाहर", - "run": "गेम चलाएं", - "compile": "इंजन बिल्ड", - "package": "EXE पैकेज", - "explorer": "एक्सप्लोरर", - "output": "आउटपुट", - "ready": "तैयार", - "running": "चल रहा है...", - "saved": "सहेजा गया", - "opened": "खोला गया", - "build_first": "पहले बिल्ड करें", - "kill": "बंद", - "packaged": "पैकेज्ड", - "about": "Lity3D के बारे में" -} \ No newline at end of file diff --git a/languages/hr.json b/languages/hr.json deleted file mode 100644 index ce4542e..0000000 --- a/languages/hr.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Urednik", - "file": "Datoteka", - "build": "Izgradi", - "scene": "Scena", - "help": "Pomoć", - "lang": "Jezik", - "new": "Novo", - "open": "Otvori", - "save": "Spremi", - "exit": "Izlaz", - "run": "Pokreni igru", - "compile": "Izgradi engine", - "package": "Pakiraj EXE", - "explorer": "Istraživač", - "output": "Izlaz", - "ready": "Spreman", - "running": "Radi...", - "saved": "Spremljeno", - "opened": "Otvoreno", - "build_first": "Prvo izgradi", - "kill": "Zaustavljeno", - "packaged": "Pakirano", - "about": "O Lity3D" -} \ No newline at end of file diff --git a/languages/hu.json b/languages/hu.json deleted file mode 100644 index f121afe..0000000 --- a/languages/hu.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Szerkesztő", - "file": "Fájl", - "build": "Fordítás", - "scene": "Jelenet", - "help": "Súgó", - "lang": "Nyelv", - "new": "Új", - "open": "Megnyitás", - "save": "Mentés", - "exit": "Kilépés", - "run": "Játék futtatása", - "compile": "Engine fordítás", - "package": "Csomagolás", - "explorer": "Fájlkezelő", - "output": "Kimenet", - "ready": "Kész", - "running": "Fut...", - "saved": "Mentve", - "opened": "Megnyitva", - "build_first": "Előbb fordíts", - "kill": "Leállítva", - "packaged": "Becsomagolva", - "about": "Névjegy" -} \ No newline at end of file diff --git a/languages/id.json b/languages/id.json deleted file mode 100644 index 0f83a92..0000000 --- a/languages/id.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "Berkas", - "build": "Build", - "scene": "Sken", - "help": "Bantuan", - "lang": "Bahasa", - "new": "Baru", - "open": "Buka", - "save": "Simpan", - "exit": "Keluar", - "run": "Jalankan Game", - "compile": "Build Engine", - "package": "Paket EXE", - "explorer": "Penjelajah", - "output": "Output", - "ready": "Siap", - "running": "Berjalan...", - "saved": "Tersimpan", - "opened": "Terbuka", - "build_first": "Build dulu", - "kill": "Berhenti", - "packaged": "Terpaket", - "about": "Tentang Lity3D" -} \ No newline at end of file diff --git a/languages/it.json b/languages/it.json deleted file mode 100644 index e6d0c1c..0000000 --- a/languages/it.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "File", - "build": "Compila", - "scene": "Scena", - "help": "Aiuto", - "lang": "Lingua", - "new": "Nuovo", - "open": "Apri", - "save": "Salva", - "exit": "Esci", - "run": "Esegui gioco", - "compile": "Compila engine", - "package": "Pacchetta", - "explorer": "Esplora", - "output": "Output", - "ready": "Pronto", - "running": "In esecuzione...", - "saved": "Salvato", - "opened": "Aperto", - "build_first": "Compila prima", - "kill": "Fermato", - "packaged": "Impacchettato", - "about": "Informazioni" -} \ No newline at end of file diff --git a/languages/ja.json b/languages/ja.json deleted file mode 100644 index 6c25577..0000000 --- a/languages/ja.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D エディタ", - "file": "ファイル", - "build": "ビルド", - "scene": "シーン", - "help": "ヘルプ", - "lang": "言語", - "new": "新規", - "open": "開く", - "save": "保存", - "exit": "終了", - "run": "ゲーム実行", - "compile": "ビルド", - "package": "EXE出力", - "explorer": "エクスプローラ", - "output": "出力", - "ready": "準備完了", - "running": "実行中...", - "saved": "保存済み", - "opened": "開いた", - "build_first": "先にビルド", - "kill": "停止済み", - "packaged": "パッケージ済み", - "about": "Lity3D について" -} \ No newline at end of file diff --git a/languages/ko.json b/languages/ko.json deleted file mode 100644 index f452bcd..0000000 --- a/languages/ko.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D 편집기", - "file": "파일", - "build": "빌드", - "scene": "씬", - "help": "도움말", - "lang": "언어", - "new": "새로 만들기", - "open": "열기", - "save": "저장", - "exit": "종료", - "run": "게임 실행", - "compile": "엔진 빌드", - "package": "EXE 패키징", - "explorer": "탐색기", - "output": "출력", - "ready": "준비", - "running": "실행 중...", - "saved": "저장됨", - "opened": "열림", - "build_first": "먼저 빌드", - "kill": "중지됨", - "packaged": "패키징됨", - "about": "Lity3D 정보" -} \ No newline at end of file diff --git a/languages/lt.json b/languages/lt.json deleted file mode 100644 index d21e541..0000000 --- a/languages/lt.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Redaktorius", - "file": "Failas", - "build": "Kompiliuoti", - "scene": "Scena", - "help": "Pagalba", - "lang": "Kalba", - "new": "Naujas", - "open": "Atidaryti", - "save": "Išsaugoti", - "exit": "Išeiti", - "run": "Paleisti žaidimą", - "compile": "Kompiliuoti variklį", - "package": "Pakuot EXE", - "explorer": "Naršyklė", - "output": "Išvestis", - "ready": "Pasirengęs", - "running": "Veikia...", - "saved": "Išsaugota", - "opened": "Atidaryta", - "build_first": "Pirmiau kompiliuoti", - "kill": "Sustabdyta", - "packaged": "Supakuota", - "about": "Apie Lity3D" -} \ No newline at end of file diff --git a/languages/lv.json b/languages/lv.json deleted file mode 100644 index 1209d7a..0000000 --- a/languages/lv.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Redaktors", - "file": "Fails", - "build": "Kompilēt", - "scene": "Aina", - "help": "Palīdzība", - "lang": "Valoda", - "new": "Jauns", - "open": "Atvērt", - "save": "Saglabāt", - "exit": "Izeja", - "run": "Palaist spēli", - "compile": "Kompilēt dzinēju", - "package": "Paketēt EXE", - "explorer": "Pārlūks", - "output": "Izeja", - "ready": "Gatavs", - "running": "Darbojas...", - "saved": "Saglabāts", - "opened": "Atvērts", - "build_first": "Vispirums kompilēt", - "kill": "Aizturēts", - "packaged": "Pakets", - "about": "Par Lity3D" -} \ No newline at end of file diff --git a/languages/ml.json b/languages/ml.json deleted file mode 100644 index 83a5d9a..0000000 --- a/languages/ml.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D എഡിറ്റർ", - "file": "ഫയൽ", - "build": "ബിൽഡ്", - "scene": "രംഗം", - "help": "സഹായം", - "lang": "ഭാഷ", - "new": "പുതിയ", - "open": "തുറക്കുക", - "save": "സേവ് ചെയ്യുക", - "exit": "പുറത്തുപോകുക", - "run": "ഗെയിം റൺ ചെയ്യുക", - "compile": "എഞ്ചിൻ ബിൽഡ്", - "package": "EXE പാക്കേജ്", - "explorer": "എക്സ്പ്ലോറർ", - "output": "ഔട്ട്പുട്ട്", - "ready": "തയ്യാർ", - "running": "റൺ ചെയ്യുന്നു...", - "saved": "സേവ് ചെയ്തു", - "opened": "തുറന്നു", - "build_first": "ആദ്യം ബിൽഡ് ചെയ്യുക", - "kill": "നിർത്തി", - "packaged": "പാക്കേജ് ചെയ്തു", - "about": "Lity3D യെ കുറിച്ച്" -} \ No newline at end of file diff --git a/languages/ms.json b/languages/ms.json deleted file mode 100644 index e0b4894..0000000 --- a/languages/ms.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "Fail", - "build": "Bina", - "scene": "Adegan", - "help": "Bantuan", - "lang": "Bahasa", - "new": "Baharu", - "open": "Buka", - "save": "Simpan", - "exit": "Keluar", - "run": "Jalankan permainan", - "compile": "Bina engine", - "package": "Pakej EXE", - "explorer": "Peneroka", - "output": "Output", - "ready": "Sedia", - "running": "Berjalan...", - "saved": "Disimpan", - "opened": "Dibuka", - "build_first": "Bina dahulu", - "kill": "Dihentikan", - "packaged": "Dibungkus", - "about": "Tentang Lity3D" -} \ No newline at end of file diff --git a/languages/nl.json b/languages/nl.json deleted file mode 100644 index 5491dca..0000000 --- a/languages/nl.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "Bestand", - "build": "Bouwen", - "scene": "Scène", - "help": "Help", - "lang": "Taal", - "new": "Nieuw", - "open": "Open", - "save": "Opslaan", - "exit": "Afsluiten", - "run": "Spel uitvoeren", - "compile": "Engine bouwen", - "package": "Pakket EXE", - "explorer": "Verkenner", - "output": "Uitvoer", - "ready": "Gereed", - "running": "Actief...", - "saved": "Opgeslagen", - "opened": "Geopend", - "build_first": "Eerst bouwen", - "kill": "Gestopt", - "packaged": "Ingepakt", - "about": "Over Lity3D" -} \ No newline at end of file diff --git a/languages/no.json b/languages/no.json deleted file mode 100644 index 847b815..0000000 --- a/languages/no.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "Fil", - "build": "Bygg", - "scene": "Scene", - "help": "Hjelp", - "lang": "Språk", - "new": "Ny", - "open": "Åpne", - "save": "Lagre", - "exit": "Avslutt", - "run": "Kjør spill", - "compile": "Bygg engine", - "package": "Pakke EXE", - "explorer": "Utforsker", - "output": "Utdata", - "ready": "Klar", - "running": "Kjører...", - "saved": "Lagret", - "opened": "Åpnet", - "build_first": "Bygg først", - "kill": "Stoppet", - "packaged": "Pakket", - "about": "Om Lity3D" -} \ No newline at end of file diff --git a/languages/pl.json b/languages/pl.json deleted file mode 100644 index 4ef7acf..0000000 --- a/languages/pl.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Edytor", - "file": "Plik", - "build": "Kompiluj", - "scene": "Scena", - "help": "Pomoc", - "lang": "Język", - "new": "Nowy", - "open": "Otwórz", - "save": "Zapisz", - "exit": "Wyjście", - "run": "Uruchom grę", - "compile": "Kompiluj silnik", - "package": "Pakietuj EXE", - "explorer": "Eksplorator", - "output": "Wyjście", - "ready": "Gotowy", - "running": "Działa...", - "saved": "Zapisano", - "opened": "Otwarto", - "build_first": "Najpierw kompiluj", - "kill": "Zatrzymano", - "packaged": "Spakowano", - "about": "O Lity3D" -} \ No newline at end of file diff --git a/languages/pt.json b/languages/pt.json deleted file mode 100644 index 72f6ce9..0000000 --- a/languages/pt.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "Arquivo", - "build": "Compilar", - "scene": "Cena", - "help": "Ajuda", - "lang": "Idioma", - "new": "Novo", - "open": "Abrir", - "save": "Salvar", - "exit": "Sair", - "run": "Executar jogo", - "compile": "Compilar engine", - "package": "Empacotar", - "explorer": "Explorador", - "output": "Saída", - "ready": "Pronto", - "running": "Executando...", - "saved": "Salvo", - "opened": "Aberto", - "build_first": "Compilar primeiro", - "kill": "Parado", - "packaged": "Empacotado", - "about": "Sobre Lity3D" -} \ No newline at end of file diff --git a/languages/ro.json b/languages/ro.json deleted file mode 100644 index 958a839..0000000 --- a/languages/ro.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "Fișier", - "build": "Compilă", - "scene": "Scenă", - "help": "Ajutor", - "lang": "Limbă", - "new": "Nou", - "open": "Deschide", - "save": "Salvează", - "exit": "Ieșire", - "run": "Rulează joc", - "compile": "Compilează engine", - "package": "Pachet EXE", - "explorer": "Explorator", - "output": "Ieșire", - "ready": "Gata", - "running": "Rulează...", - "saved": "Salvat", - "opened": "Deschis", - "build_first": "Compilează prima dată", - "kill": "Oprit", - "packaged": "Impachetat", - "about": "Despre Lity3D" -} \ No newline at end of file diff --git a/languages/ru.json b/languages/ru.json deleted file mode 100644 index d50888f..0000000 --- a/languages/ru.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Редактор", - "file": "Файл", - "build": "Сборка", - "scene": "Сцена", - "help": "Справка", - "lang": "Язык", - "new": "Новый", - "open": "Открыть", - "save": "Сохранить", - "exit": "Выход", - "run": "Запуск", - "compile": "Собрать", - "package": "Упаковать", - "explorer": "Проводник", - "output": "Вывод", - "ready": "Готово", - "running": "Выполняется...", - "saved": "Сохранено", - "opened": "Открыто", - "build_first": "Сначала собрать", - "kill": "Остановлено", - "packaged": "Упаковано", - "about": "О Lity3D" -} \ No newline at end of file diff --git a/languages/sk.json b/languages/sk.json deleted file mode 100644 index 1cb7996..0000000 --- a/languages/sk.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "Súbor", - "build": "Kompilácia", - "scene": "Scéna", - "help": "Pomoc", - "lang": "Jazyk", - "new": "Nový", - "open": "Otvoriť", - "save": "Uložiť", - "exit": "Ukončiť", - "run": "Spustiť hru", - "compile": "Skompilovať engine", - "package": "Balenie EXE", - "explorer": "Prieskumník", - "output": "Výstup", - "ready": "Pripravené", - "running": "Prebieha...", - "saved": "Uložené", - "opened": "Otvorené", - "build_first": "Najprv skompilovať", - "kill": "Zastavené", - "packaged": "Zabalené", - "about": "O Lity3D" -} \ No newline at end of file diff --git a/languages/sk2.json b/languages/sk2.json deleted file mode 100644 index e50931c..0000000 --- a/languages/sk2.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editor", - "file": "Súbor", - "build": "Build", - "scene": "Scéna", - "help": "Pomoc", - "lang": "Jazyk", - "new": "Nový", - "open": "Otvoriť", - "save": "Uložiť", - "exit": "Ukončiť", - "run": "Spustiť", - "compile": "Build", - "package": "Balenie", - "explorer": "Prieskumník", - "output": "Výstup", - "ready": "Pripravené", - "running": "Beží...", - "saved": "Uložené", - "opened": "Otvorené", - "build_first": "Najprv build", - "kill": "Zastavené", - "packaged": "Zabalené", - "about": "O Lity3D" -} \ No newline at end of file diff --git a/languages/sl.json b/languages/sl.json deleted file mode 100644 index 742c525..0000000 --- a/languages/sl.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Urejevalnik", - "file": "Datoteka", - "build": "Izgradi", - "scene": "Scena", - "help": "Pomoč", - "lang": "Jezik", - "new": "Novo", - "open": "Odpri", - "save": "Shrani", - "exit": "Izhod", - "run": "Zaženi igro", - "compile": "Izgradi engine", - "package": "Pakiraj EXE", - "explorer": "Raziskovalec", - "output": "Izhod", - "ready": "Pripravljeno", - "running": "Deluje...", - "saved": "Shranjeno", - "opened": "Odprto", - "build_first": "Najprej izgradi", - "kill": "Ustavljeno", - "packaged": "Pakirano", - "about": "O Lity3D" -} \ No newline at end of file diff --git a/languages/sr.json b/languages/sr.json deleted file mode 100644 index 5a1ac0f..0000000 --- a/languages/sr.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Уредник", - "file": "Датотека", - "build": "Изградња", - "scene": "Сцена", - "help": "Помоћ", - "lang": "Језик", - "new": "Ново", - "open": "Отвори", - "save": "Сачувај", - "exit": "Излаз", - "run": "Покрени игру", - "compile": "Изгради engine", - "package": "Пакуј EXE", - "explorer": "Истраживач", - "output": "Излаз", - "ready": "Спреман", - "running": "Ради...", - "saved": "Сачувано", - "opened": "Отворено", - "build_first": "Прво изгради", - "kill": "Заустављено", - "packaged": "Паковано", - "about": "О Lity3D" -} \ No newline at end of file diff --git a/languages/sv.json b/languages/sv.json deleted file mode 100644 index 0013b80..0000000 --- a/languages/sv.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Redigerare", - "file": "Fil", - "build": "Bygg", - "scene": "Scen", - "help": "Hjälp", - "lang": "Språk", - "new": "Ny", - "open": "Öppna", - "save": "Spara", - "exit": "Avsluta", - "run": "Kör spel", - "compile": "Bygg engine", - "package": "Paketera EXE", - "explorer": "Utforskare", - "output": "Utdata", - "ready": "Redo", - "running": "Körs...", - "saved": "Sparat", - "opened": "Öppnat", - "build_first": "Bygg först", - "kill": "Stoppad", - "packaged": "Paketerad", - "about": "Om Lity3D" -} \ No newline at end of file diff --git a/languages/sw.json b/languages/sw.json deleted file mode 100644 index 163bbff..0000000 --- a/languages/sw.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Mhariri", - "file": "Faili", - "build": "Jenga", - "scene": "Onyesho", - "help": "Msaada", - "lang": "Lugha", - "new": "Mpya", - "open": "Fungua", - "save": "Hifadhi", - "exit": "Ondoka", - "run": "Endesha mchezo", - "compile": "Jenga injini", - "package": "Pakiti EXE", - "explorer": "Vinara", - "output": "Matokeo", - "ready": "Iko tayari", - "running": "Inafanya kazi...", - "saved": "Imehifadhiwa", - "opened": "Imefunguliwa", - "build_first": "Jenga kwanza", - "kill": "Imesimamishwa", - "packaged": "Imepakiwa", - "about": "Kuhusu Lity3D" -} \ No newline at end of file diff --git a/languages/ta.json b/languages/ta.json deleted file mode 100644 index 864e851..0000000 --- a/languages/ta.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D திருத்தி", - "file": "கோப்பு", - "build": "உருவாக்கு", - "scene": "காட்சி", - "help": "உதவி", - "lang": "மொழி", - "new": "புதிய", - "open": "திற", - "save": "சேமி", - "exit": "வெளியேறு", - "run": "விளையாட்டை இயக்கு", - "compile": "இயந்திரத்தை உருவாக்கு", - "package": "EXE பேக்கேஜ்", - "explorer": "ஆராய்ச்சியாளர்", - "output": "வெளியீடு", - "ready": "தயார்", - "running": "இயங்குகிறது...", - "saved": "சேமிக்கப்பட்டது", - "opened": "திறக்கப்பட்டது", - "build_first": "முதலில் உருவாக்கு", - "kill": "நிறுத்தப்பட்டது", - "packaged": "பேக்கேஜ் செய்யப்பட்டது", - "about": "Lity3D பற்றி" -} \ No newline at end of file diff --git a/languages/te.json b/languages/te.json deleted file mode 100644 index 02f480c..0000000 --- a/languages/te.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D ఎడిటర్", - "file": "ఫైల్", - "build": "బిల్డ్", - "scene": "దృశ్యం", - "help": "సహాయం", - "lang": "భాష", - "new": "కొత్త", - "open": "తెరవండి", - "save": "సేవ్ చేయండి", - "exit": "నిష్క్రమించండి", - "run": "గేమ్ రన్", - "compile": "ఇంజిన్ బిల్డ్", - "package": "EXE ప్యాకేజ్", - "explorer": "ఎక్స్‌ప్లోరర్", - "output": "అవుట్‌పుట్", - "ready": "సిద్ధం", - "running": "రన్ అవుతోంది...", - "saved": "సేవ్ చేయబడింది", - "opened": "తెరవబడింది", - "build_first": "మొదట బిల్డ్", - "kill": "ఆపబడింది", - "packaged": "ప్యాకేజ్ చేయబడింది", - "about": "Lity3D గురించి" -} \ No newline at end of file diff --git a/languages/th.json b/languages/th.json deleted file mode 100644 index 19d2641..0000000 --- a/languages/th.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D ตัวแก้ไข", - "file": "ไฟล์", - "build": "สร้าง", - "scene": "ฉาก", - "help": "ช่วยเหลือ", - "lang": "ภาษา", - "new": "ใหม่", - "open": "เปิด", - "save": "บันทึก", - "exit": "ออก", - "run": "รันเกม", - "compile": "สร้างเอนจิ้น", - "package": "打包 EXE", - "explorer": "ตัวสำรวจ", - "output": "ผลลัพธ์", - "ready": "พร้อม", - "running": "กำลังทำงาน...", - "saved": "บันทึกแล้ว", - "opened": "เปิดแล้ว", - "build_first": "สร้างก่อน", - "kill": "หยุดแล้ว", - "packaged": "打包แล้ว", - "about": "เกี่ยวกับ Lity3D" -} \ No newline at end of file diff --git a/languages/tr.json b/languages/tr.json deleted file mode 100644 index 8b931e9..0000000 --- a/languages/tr.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Editör", - "file": "Dosya", - "build": "Derle", - "scene": "Sahne", - "help": "Yardım", - "lang": "Dil", - "new": "Yeni", - "open": "Aç", - "save": "Kaydet", - "exit": "Çıkış", - "run": "Oyunu çalıştır", - "compile": "Motoru derle", - "package": "Paketle", - "explorer": "Gezgin", - "output": "Çıktı", - "ready": "Hazır", - "running": "Çalışıyor...", - "saved": "Kaydedildi", - "opened": "Açıldı", - "build_first": "Önce derle", - "kill": "Durduruldu", - "packaged": "Paketlendi", - "about": "Hakkında" -} \ No newline at end of file diff --git a/languages/uk.json b/languages/uk.json deleted file mode 100644 index 588fa3c..0000000 --- a/languages/uk.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Редактор", - "file": "Файл", - "build": "Збірка", - "scene": "Сцена", - "help": "Довідка", - "lang": "Мова", - "new": "Новий", - "open": "Відкрити", - "save": "Зберегти", - "exit": "Вихід", - "run": "Запуск", - "compile": "Зібрати", - "package": "Упакувати", - "explorer": "Провідник", - "output": "Вивід", - "ready": "Готово", - "running": "Виконується...", - "saved": "Збережено", - "opened": "Відкрито", - "build_first": "Спочатку зібрати", - "kill": "Зупинено", - "packaged": "Упаковано", - "about": "Про Lity3D" -} \ No newline at end of file diff --git a/languages/vi.json b/languages/vi.json deleted file mode 100644 index 48430d7..0000000 --- a/languages/vi.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D Trình soạn thảo", - "file": "Tệp", - "build": "Xây dựng", - "scene": "Cảnh", - "help": "Trợ giúp", - "lang": "Ngôn ngữ", - "new": "Mới", - "open": "Mở", - "save": "Lưu", - "exit": "Thoát", - "run": "Chạy trò chơi", - "compile": "Build Engine", - "package": "Gói EXE", - "explorer": "Trình duyệt", - "output": "Đầu ra", - "ready": "Sẵn sàng", - "running": "Đang chạy...", - "saved": "Đã lưu", - "opened": "Đã mở", - "build_first": "Build trước", - "kill": "Đã dừng", - "packaged": "Đã gói", - "about": "Về Lity3D" -} \ No newline at end of file diff --git a/languages/zh.json b/languages/zh.json deleted file mode 100644 index 6e45253..0000000 --- a/languages/zh.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "app_title": "Lity3D 编辑器", - "file": "文件", - "build": "构建", - "scene": "场景", - "help": "帮助", - "lang": "语言", - "new": "新建", - "open": "打开", - "save": "保存", - "exit": "退出", - "run": "运行游戏", - "compile": "编译引擎", - "package": "打包 EXE", - "explorer": "资源管理器", - "output": "输出", - "ready": "就绪", - "running": "运行中...", - "saved": "已保存", - "opened": "已打开", - "build_first": "请先编译引擎", - "kill": "进程已终止", - "packaged": "已打包", - "about": "关于 Lity3D" -} \ No newline at end of file diff --git a/scene.txt b/scene.txt deleted file mode 100644 index 1ad872b..0000000 --- a/scene.txt +++ /dev/null @@ -1,5 +0,0 @@ -LITY3D_SCENE 1 -root -1 NONE - 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 1.0000 1.0000 1.0000 -cube 0 CUBE - 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 1.0000 1.0000 1.0000 -sphere 0 SPHERE - 2.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.8000 0.8000 0.8000 -ground 0 PLANE - 0.0000 -1.0000 0.0000 0.0000 0.0000 0.0000 1.0000 1.0000 1.0000 diff --git a/引擎文件说明.md b/引擎文件说明.md deleted file mode 100644 index eca5010..0000000 --- a/引擎文件说明.md +++ /dev/null @@ -1,143 +0,0 @@ -# Lity3D 引擎文件说明 - -## 顶层结构 - -``` -lity3d/ -├── Engine/ 核心引擎代码(C + MASM汇编) -├── Demo/ 示例程序 -├── Assets/ 3D模型资源 -├── EditorCS/ 编辑器(C#) -├── build/ 编译输出 -├── CMakeLists.txt CMake构建配置 -├── build.bat Windows一键编译 -├── README.md 项目说明 -├── DESIGN.md 架构设计 -└── scene.txt 场景保存文件 -``` - ---- - -## Engine/ASM/ — 汇编加速层 - -引擎的性能热路径用 MASM x64 汇编实现,通过 SSE/AVX2 指令集加速。当汇编不可用时自动降级到纯C版本。 - -- **math.asm** (1013行) — 向量加减乘除、矩阵乘法、四元数旋转,全部用 SIMD 指令 -- **math_c_fallback.h** (65行) — 数学函数的纯C实现,作为汇编的备选 -- **memory.asm** (146行) — 对齐内存分配,保证 SIMD 操作需要的16/32/64字节对齐 -- **string_ops.asm** (253行) — 用SIMD加速的内存拷贝、字符串长度计算、字符串比较 -- **profiling.asm** (122行) — 用CPU的RDTSC指令做高精度计时,用于性能分析 - -## Engine/Core/ — 引擎核心 - -- **engine.c/h** — 引擎主控。负责初始化所有子系统、运行游戏循环(每帧调update→render)、关闭时清理资源。这是整个引擎的入口 -- **timer.c/h** — 用Windows的QueryPerformanceCounter做毫秒级计时,计算帧间隔(delta time) -- **logger.c/h** — 日志系统。支持INFO/WARN/FATAL三级日志,同时输出到控制台和文件 -- **asset_manager.c/h** — 资源管理器。统一处理shader/mesh/texture的加载和缓存,避免重复加载 - -## Engine/Window/ — 窗口系统 - -- **window.c/h** — 创建Win32窗口,处理Windows消息循环。把键盘、鼠标、窗口大小变化等事件转发给引擎回调函数 - -## Engine/Rendering/ — D3D11渲染管线 - -- **graphics_device.c/h** — D3D11设备初始化。创建Device、SwapChain、RenderTarget、DepthStencil,管理渲染状态 -- **renderer.c/h** — 渲染器。设置视口、清屏、管理渲染目标切换 -- **shader.c/h** — 着色器管理。编译HLSL着色器、设置常量缓冲区、绑定到管线 -- **mesh.c/h** — 网格系统。支持立方体/球体/平面程序化生成,也支持OBJ文件加载。管理顶点缓冲区和索引缓冲区 -- **texture.c/h** — 纹理系统。通过WIC加载BMP/PNG/JPEG,也支持生成纯色和棋盘格纹理 -- **camera.c/h** — 摄像机。透视投影、lookAt矩阵、自由移动和旋转 -- **camera_controller.c/h** — 摄像机控制器。封装常用的WASD+鼠标操作 -- **frustum.c/h** — 视锥体裁剪。判断物体是否在摄像机视野内,跳过不可见物体的渲染 -- **lighting.c/h** — 光照系统。方向光+点光源,Lambert漫反射计算 -- **material.c/h** — 材质。把shader和纹理组合在一起,定义物体的外观属性 - -## Engine/Scene/ — 场景图 - -- **scene_graph.c/h** — 场景树。节点有父子关系,子节点继承父节点的位移/旋转/缩放 -- **scene_render.c/h** — 场景渲染。遍历场景树,把每个节点的MeshRenderer提交给渲染器 -- **scene_serialize.c/h** — 场景序列化。把整个场景树保存成text文件或从文件加载 - -## Engine/Input/ — 输入系统 - -- **input.c/h** — 键盘/鼠标/手柄输入。跟踪按键状态,支持轮询(GetAsyncKeyState)和事件回调两种模式 - -## Engine/Audio/ — 音频系统 - -- **audio.c/h** — XAudio2音频引擎。动态加载DLL(兼容Win7~11),加载WAV文件,播放/暂停/音量控制 - -## Engine/Physics/ — 物理系统 - -- **physics.c/h** — 简易物理。AABB碰撞检测、球体碰撞、重力模拟、速度积分 - -## Engine/ECS/ — 实体组件系统 - -- **world.c/h** — ECS世界。实体=组件的容器,系统批量处理同类组件 - -## Engine/UI/ — 用户界面 - -- **ui.c/h** — 2D UI渲染。按钮、标签、面板等基础控件,用D3D11的2D投影绘制 - -## Engine/Editor/ — 内置编辑器 - -- **editor.c/h** — 编辑器主逻辑 -- **editor_2d.c/h** — 2D编辑模式(俯视图) -- **uilayer.c/h** — 编辑器UI层 -- **bitmap_font.c/h** — 位图字体渲染 -- **glyph_atlas.c/h** — 字体图集生成 - -## Engine/VisualScript/ — 积木式可视化编程 - -这是引擎最复杂的模块之一,实现了类似Scratch的积木编程系统: - -- **block_core.c/h** — 积木核心数据结构(输入/输出端口、连接线) -- **block_types.c/h** — 30+种积木类型定义(移动、旋转、条件、循环等) -- **block_executor.c/h** — 积木执行器。解析积木图,按连接顺序执行逻辑 -- **block_serializer.c/h** — 积木序列化。把积木图保存为.ly文件或从文件加载 -- **block_workspace.c/h** — 积木工作区。管理所有积木的位置和连接关系 -- **block_renderer.c/h** — 积木渲染。在屏幕上绘制积木方块和贝塞尔连线 -- **block_interaction.c/h** — 积木交互。拖拽移动、连线创建、端口连接 -- **block_palette.c/h** — 积木面板。侧边栏显示可用积木列表 -- **block_editor.c/h** — 积木编辑器主控 - -## Engine/Scripting/ — 脚本系统 - -- **lity.py** — LityPy。Python脚本库,用Python语法写游戏逻辑 -- **lua_engine.c/h** — Lua脚本引擎桩(预留接口) - -## Engine/Asset/ — 资源定义 - -- **mesh.h** — Mesh结构体定义(顶点数组、索引数组、顶点缓冲区) -- **texture.h** — Texture结构体定义(宽高、像素数据、SRV) - -## Engine/include/ — 对外接口 - -- **engine_api.h** — C/C++便利封装。暴露汇编函数给C代码,提供运算符重载 - ---- - -## Demo/ — 示例程序 - -| 文件 | 说明 | -|------|------| -| main.c | 场景Demo(方块+球体+地面+光照) | -| lity_explorer.c | 3D开放世界探索(村庄+树木+第三人称) | -| cube_dodge.c | 躲避游戏(障碍物+碰撞+计分) | -| game_test.c | 纯D3D11渲染测试(无Engine依赖) | -| raw3d_test.c | 引擎3D渲染验证(彩色面) | -| scene_test.c | 场景图测试 | -| light_test.c | 光照系统测试 | -| input_test.c | 输入系统测试 | -| obj_viewer.c | OBJ模型查看器(鼠标旋转) | -| ly_interpreter.c | .ly积木文件解释器 | -| editor_main.c | 编辑器入口 | -| open_world_demo.c | 开放世界demo | - -## EditorCS/ — 编辑器 - -C# 编写的可视化积木编辑器,用Dear ImGui + D3D11实现。 - -## Assets/ — 模型资源 - -- cube.obj — 简单立方体OBJ模型 -- pyramid.obj — 金字塔OBJ模型