From ef4ea45edc789eb7d4c4321b7822abbec298b98b Mon Sep 17 00:00:00 2001 From: Atdunbg Date: Wed, 25 Mar 2026 21:36:38 +0800 Subject: [PATCH] add simple runtime; fix the issue of crashing when creating file and folder; some tweaks --- CMakeLists.txt | 3 +- Editor/CMakeLists.txt | 2 +- Editor/Editor/EditorLayer.cpp | 20 +- Editor/assets/scenes/FPS.scene | 336 ++++++++++++++++++ Editor/assets/scenes/FPSDemo.scene | 75 ++-- Editor/assets/scenes/demo.scene | 26 +- ExampleApp/ExampleApp.csproj | 1 + ExampleApp/Src/FPSPlayer.cs | 4 + Prism-ScriptCore/Prism-ScriptCore.csproj | 1 + Prism-ScriptCore/Src/Prism/Engine/Engine.cs | 15 + Prism-ScriptCore/Src/Prism/Math/Transform.cs | 6 +- Prism/src/Prism/Asset/AssetsManager.cpp | 59 +-- Prism/src/Prism/Asset/AssetsManager.h | 1 - Prism/src/Prism/Core/Application.cpp | 3 +- Prism/src/Prism/Core/EntryPoint.h | 13 + .../src/Prism/Core/Events/ApplicationEvent.h | 43 +++ Prism/src/Prism/Core/Log.h | 3 +- Prism/src/Prism/Core/TimeStep.h | 2 +- Prism/src/Prism/Core/Window.h | 5 +- .../src/Prism/Editor/ContentBrowserPanel.cpp | 14 +- Prism/src/Prism/Editor/SceneHierachyPanel.cpp | 33 +- Prism/src/Prism/Physics/Physics3D.cpp | 5 +- .../Platform/OpenGL/OpenGLFrameBuffer.cpp | 8 + .../Prism/Platform/OpenGL/OpenGLFrameBuffer.h | 1 + .../Prism/Platform/OpenGL/OpenGLTexture.cpp | 2 +- .../src/Prism/Platform/OpenGL/OpenGLTexture.h | 2 +- .../Windows/WindowsFileSystemWatcher.cpp | 6 +- .../Prism/Platform/Windows/WindowsWindow.cpp | 29 +- .../Prism/Platform/Windows/WindowsWindow.h | 4 +- Prism/src/Prism/Renderer/FrameBuffer.h | 1 + Prism/src/Prism/Renderer/Renderer.cpp | 3 + Prism/src/Prism/Renderer/Renderer3D.cpp | 227 ++---------- Prism/src/Prism/Renderer/SceneRenderer.cpp | 23 +- Prism/src/Prism/Renderer/SceneRenderer.h | 6 +- Prism/src/Prism/Renderer/Texture.h | 2 +- Prism/src/Prism/Scene/Components.h | 2 +- Prism/src/Prism/Scene/Scene.cpp | 29 +- Prism/src/Prism/Scene/Scene.h | 5 +- Prism/src/Prism/Scene/SceneSerializer.cpp | 123 ++++++- Prism/src/Prism/Script/ScriptEngine.cpp | 55 ++- Prism/src/Prism/Script/ScriptEngine.h | 7 + .../src/Prism/Script/ScriptEngineRegistry.cpp | 2 + Prism/src/Prism/Script/ScriptWrappers.cpp | 19 + Prism/src/Prism/Script/ScriptWrappers.h | 3 + PrismRuntime/CMakeLists.txt | 11 + PrismRuntime/PrismRuntime/PrismRuntime.cpp | 63 ++++ PrismRuntime/PrismRuntime/PrismRuntime.h | 30 ++ PrismRuntime/PrismRuntime/PrismRuntimeApp.cpp | 25 ++ 48 files changed, 996 insertions(+), 362 deletions(-) create mode 100644 Editor/assets/scenes/FPS.scene create mode 100644 Prism-ScriptCore/Src/Prism/Engine/Engine.cs create mode 100644 PrismRuntime/CMakeLists.txt create mode 100644 PrismRuntime/PrismRuntime/PrismRuntime.cpp create mode 100644 PrismRuntime/PrismRuntime/PrismRuntime.h create mode 100644 PrismRuntime/PrismRuntime/PrismRuntimeApp.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e479115..9e7f2e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,4 +23,5 @@ endif () add_subdirectory(Prism) add_subdirectory(Sandbox) -add_subdirectory(Editor) \ No newline at end of file +add_subdirectory(Editor) +add_subdirectory(PrismRuntime) diff --git a/Editor/CMakeLists.txt b/Editor/CMakeLists.txt index 9f3bc68..c4845ce 100644 --- a/Editor/CMakeLists.txt +++ b/Editor/CMakeLists.txt @@ -12,7 +12,7 @@ file(COPY ${IMGUI_INI} DESTINATION ${CMAKE_BINARY_DIR}) file(GLOB DOTNET_LIBRARY library) file(COPY ${DOTNET_LIBRARY} DESTINATION ${CMAKE_BINARY_DIR}) -file(GLOB_RECURSE SRC_SOURCE ./**.cpp) +file(GLOB_RECURSE SRC_SOURCE ./Editor/**.cpp) add_executable(${PROJECT_NAME} ${SRC_SOURCE}) diff --git a/Editor/Editor/EditorLayer.cpp b/Editor/Editor/EditorLayer.cpp index ebe4144..15f548e 100644 --- a/Editor/Editor/EditorLayer.cpp +++ b/Editor/Editor/EditorLayer.cpp @@ -51,8 +51,11 @@ namespace Prism NewScene(); m_CurrentScene = m_EditorScene; + SceneRenderer::GetOptions().ShowGrid = true; + AssetEditorPanel::RegisterDefaultEditors(); FileSystem::StartWatching(); + } void EditorLayer::OnDetach() @@ -105,7 +108,7 @@ namespace Prism Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false); const auto viewProj = m_EditorCamera.GetViewProjection(); Renderer2D::BeginScene(viewProj, false); - Renderer2D::DrawRotatedRect({ transform.Translation.x + collider.Offset.x, transform.Translation.y + collider.Offset.y }, {transform.Scale.x * collider.Size.x, transform.Scale.y * collider.Size.y}, transform.Rotation.z, { 0.0f, 0.0f, 1.0f, 1.0f }); + Renderer2D::DrawRotatedRect({ transform.Translation.x + collider.Offset.x, transform.Translation.y + collider.Offset.y , transform.Translation.z}, {transform.Scale.x * collider.Size.x, transform.Scale.y * collider.Size.y}, transform.Rotation.z, { 0.0f, 0.0f, 1.0f, 1.0f }); Renderer2D::EndScene(); Renderer::EndRenderPass(); } @@ -117,7 +120,7 @@ namespace Prism Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false); const auto viewProj = m_EditorCamera.GetViewProjection(); Renderer2D::BeginScene(viewProj, false); - Renderer2D::DrawCircle({ transform.Translation.x + collider.Offset.x, transform.Translation.y + collider.Offset.y}, collider.Radius, { 0.0f, 1.0f, 1.0f, 1.0f }); + Renderer2D::DrawCircle({ transform.Translation.x + collider.Offset.x, transform.Translation.y + collider.Offset.y, transform.Translation.z}, collider.Radius, { 0.0f, 1.0f, 1.0f, 1.0f }); Renderer2D::EndScene(); Renderer::EndRenderPass(); } @@ -237,7 +240,7 @@ namespace Prism { // temp if (ImGui::MenuItem("Reload C# Assembly")) - ScriptEngine::ReloadAssembly("assets/scripts/ExampleApp.dll"); + ScriptEngine::ReloadAssembly("assets/scripts/Assembly-Script.dll"); ImGui::MenuItem("Reload assembly on play", nullptr, &m_ReloadScriptOnPlay); ImGui::EndMenu(); @@ -1054,17 +1057,6 @@ namespace Prism }); if (!m_SelectionContext.empty()) { - if (auto alreadySelectedEntity = m_SceneHierarchyPanel->GetSelected(); - m_SelectionContext.size() != 1 && alreadySelectedEntity) - { - const auto alreadySelectedEntityID = alreadySelectedEntity.GetUUID(); - - for (const auto& selectedEntity : m_SelectionContext) - { - if (alreadySelectedEntityID == selectedEntity.Entity.GetUUID()) continue; - return false; - } - } OnSelected(m_SelectionContext[0]); } } diff --git a/Editor/assets/scenes/FPS.scene b/Editor/assets/scenes/FPS.scene new file mode 100644 index 0000000..a6e510b --- /dev/null +++ b/Editor/assets/scenes/FPS.scene @@ -0,0 +1,336 @@ +Scene: Scene Name +Environment: + AssetHandle: 5211537204242875091 +Entities: + - Entity: 8293051279669100759 + Parent: 0 + Children: + [] + TagComponent: + Tag: Cube + TransformComponent: + Position: [1.736814, 1.4724115, -4.2181306] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + MeshComponent: + AssetID: 18328012085543462741 + AssetPath: assets/meshes/Default/Cube.fbx + RigidBodyComponent: + BodyType: 1 + Mass: 1 + LinearDrag: 0 + AngularDrag: 0.05 + DisableGravity: false + IsKinematic: false + Layer: 0 + Constraints: + LockPositionX: false + LockPositionY: false + LockPositionZ: false + LockRotationX: false + LockRotationY: false + LockRotationZ: false + BoxColliderComponent: + Offset: [0, 0, 0] + Size: [2, 2, 2] + IsTrigger: false + Material: 0 + MaterialPath: "" + - Entity: 5834225236589765516 + Parent: 0 + Children: + [] + TagComponent: + Tag: Cube + TransformComponent: + Position: [-2.6417403, 1.4724115, -7.9285727] + Rotation: [0.52199936, 0, 0] + Scale: [1, 1.0000001, 1.0000001] + MeshComponent: + AssetID: 18328012085543462741 + AssetPath: assets/meshes/Default/Cube.fbx + RigidBodyComponent: + BodyType: 1 + Mass: 1 + LinearDrag: 0 + AngularDrag: 0.05 + DisableGravity: false + IsKinematic: false + Layer: 0 + Constraints: + LockPositionX: false + LockPositionY: false + LockPositionZ: false + LockRotationX: false + LockRotationY: false + LockRotationZ: false + BoxColliderComponent: + Offset: [0, 0, 0] + Size: [2, 2, 2] + IsTrigger: false + Material: 0 + MaterialPath: "" + - Entity: 8234256119181302872 + Parent: 0 + Children: + [] + TagComponent: + Tag: Cube + TransformComponent: + Position: [1.736814, 1.4724115, -7.9285727] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + MeshComponent: + AssetID: 18328012085543462741 + AssetPath: assets/meshes/Default/Cube.fbx + RigidBodyComponent: + BodyType: 1 + Mass: 1 + LinearDrag: 0 + AngularDrag: 0.05 + DisableGravity: false + IsKinematic: false + Layer: 0 + Constraints: + LockPositionX: false + LockPositionY: false + LockPositionZ: false + LockRotationX: false + LockRotationY: false + LockRotationZ: false + BoxColliderComponent: + Offset: [0, 0, 0] + Size: [2, 2, 2] + IsTrigger: false + Material: 0 + MaterialPath: "" + - Entity: 12935252585493481950 + Parent: 0 + Children: + [] + TagComponent: + Tag: Cube + TransformComponent: + Position: [-1.5106764, 6.237644, -4.2181306] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + MeshComponent: + AssetID: 18328012085543462741 + AssetPath: assets/meshes/Default/Cube.fbx + RigidBodyComponent: + BodyType: 1 + Mass: 1 + LinearDrag: 0 + AngularDrag: 0.05 + DisableGravity: false + IsKinematic: false + Layer: 0 + Constraints: + LockPositionX: false + LockPositionY: false + LockPositionZ: false + LockRotationX: false + LockRotationY: false + LockRotationZ: false + BoxColliderComponent: + Offset: [0, 0, 0] + Size: [2, 2, 2] + IsTrigger: false + Material: 0 + MaterialPath: "" + - Entity: 3328246672296261054 + Parent: 0 + Children: + [] + TagComponent: + Tag: Cube + TransformComponent: + Position: [1.736814, 1.4724115, -0.88378817] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + MeshComponent: + AssetID: 18328012085543462741 + AssetPath: assets/meshes/Default/Cube.fbx + RigidBodyComponent: + BodyType: 1 + Mass: 1 + LinearDrag: 0 + AngularDrag: 0.05 + DisableGravity: false + IsKinematic: false + Layer: 0 + Constraints: + LockPositionX: false + LockPositionY: false + LockPositionZ: false + LockRotationX: false + LockRotationY: false + LockRotationZ: false + BoxColliderComponent: + Offset: [0, 0, 0] + Size: [2, 2, 2] + IsTrigger: false + Material: 0 + MaterialPath: "" + - Entity: 4208267561919679628 + Parent: 0 + Children: + [] + TagComponent: + Tag: Cube + TransformComponent: + Position: [-2.6417403, 1.4724115, -4.8956265] + Rotation: [-0.4034239, 0, 0] + Scale: [1, 0.99999994, 0.99999994] + MeshComponent: + AssetID: 18328012085543462741 + AssetPath: assets/meshes/Default/Cube.fbx + RigidBodyComponent: + BodyType: 1 + Mass: 1 + LinearDrag: 0 + AngularDrag: 0.05 + DisableGravity: true + IsKinematic: false + Layer: 0 + Constraints: + LockPositionX: false + LockPositionY: false + LockPositionZ: false + LockRotationX: false + LockRotationY: false + LockRotationZ: false + BoxColliderComponent: + Offset: [0, 0, 0] + Size: [2, 2, 2] + IsTrigger: false + Material: 0 + MaterialPath: "" + - Entity: 8114736924719261351 + Parent: 0 + Children: + [] + TagComponent: + Tag: Camera + TransformComponent: + Position: [0, 0.8097433, 4.573171] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + CameraComponent: + Camera: + ProjectionType: 0 + PerspectiveFOV: 45 + PerspectiveNear: 0.01 + PerspectiveFar: 10000 + OrthographicSize: 10 + OrthographicNear: -1 + OrthographicFar: 1 + Primary: true + - Entity: 9267298328378270409 + Parent: 0 + Children: + [] + TagComponent: + Tag: Player + TransformComponent: + Position: [0, 0.70693016, 0] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + ScriptComponent: + ModuleName: FPSExample.FPSPlayer + StoredFields: + - Name: WalkingSpeed + Type: 1 + Data: 2 + - Name: RunSpeed + Type: 1 + Data: 5 + - Name: JumpForce + Type: 1 + Data: 1 + - Name: MouseSensitivity + Type: 1 + Data: 10 + - Name: CameraForwardOffset + Type: 1 + Data: -2 + - Name: CameraYOffset + Type: 1 + Data: 2 + MeshComponent: + AssetID: 3043502408333723884 + AssetPath: assets/meshes/Default/Capsule.fbx + RigidBodyComponent: + BodyType: 1 + Mass: 1 + LinearDrag: 0 + AngularDrag: 0.05 + DisableGravity: false + IsKinematic: false + Layer: 0 + Constraints: + LockPositionX: false + LockPositionY: false + LockPositionZ: false + LockRotationX: true + LockRotationY: false + LockRotationZ: true + MeshColliderComponent: + IsConvex: true + IsTrigger: false + OverrideMesh: false + Material: 0 + MaterialPath: "" + - Entity: 10732070446010033158 + Parent: 0 + Children: + [] + TagComponent: + Tag: Cube + TransformComponent: + Position: [0, -2.6466873, 0] + Rotation: [0, 0, 0] + Scale: [100, 1, 100] + MeshComponent: + AssetID: 18328012085543462741 + AssetPath: assets/meshes/Default/Cube.fbx + RigidBodyComponent: + BodyType: 0 + Mass: 1 + LinearDrag: 0 + AngularDrag: 0.05 + DisableGravity: false + IsKinematic: false + Layer: 0 + Constraints: + LockPositionX: false + LockPositionY: false + LockPositionZ: false + LockRotationX: false + LockRotationY: false + LockRotationZ: false + BoxColliderComponent: + Offset: [0, 0, 0] + Size: [2, 2, 2] + IsTrigger: false + Material: 0 + MaterialPath: "" + - Entity: 5099152432245948441 + Parent: 0 + Children: + [] + TagComponent: + Tag: venice_dawn_1_4k + TransformComponent: + Position: [0, 0, 0] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + SkyLightComponent: + EnvironmentMap: 5211537204242875091 + EnvironmentAssetPath: assets/env/venice_dawn_1_4k.hdr + Intensity: 1 + Angle: 0 + DynamicSky: false + TurbidityAzimuthInclination: [2, 0, 0] +PhysicsLayers: + [] \ No newline at end of file diff --git a/Editor/assets/scenes/FPSDemo.scene b/Editor/assets/scenes/FPSDemo.scene index 35231c6..3e3d3e5 100644 --- a/Editor/assets/scenes/FPSDemo.scene +++ b/Editor/assets/scenes/FPSDemo.scene @@ -1,11 +1,50 @@ Scene: Scene Name Environment: - AssetHandle: 10549690553241162923 - Light: - Direction: [-0.314, -0.941, -0.209] - Radiance: [0, 0, 0] - Multiplier: 1 + AssetHandle: 6095149963749185931 Entities: + - Entity: 6421668200759325475 + Parent: 0 + Children: + [] + TagComponent: + Tag: M1911Materials + TransformComponent: + Position: [0, 3.159583, 0] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + MeshComponent: + AssetID: 7219694555758922702 + AssetPath: assets/models/m1911/M1911Materials.fbx + - Entity: 16992665426857995732 + Parent: 0 + Children: + [] + TagComponent: + Tag: Cube + TransformComponent: + Position: [0, 0, 0] + Rotation: [0, 0, 0] + Scale: [50, 1, 50] + MeshComponent: + AssetID: 18328012085543462741 + AssetPath: assets/meshes/Default/Cube.fbx + - Entity: 18182275256052989728 + Parent: 0 + Children: + [] + TagComponent: + Tag: Sky Light + TransformComponent: + Position: [0, 0, 0] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + SkyLightComponent: + EnvironmentMap: 6095149963749185931 + EnvironmentAssetPath: "" + Intensity: 1 + Angle: 0 + DynamicSky: true + TurbidityAzimuthInclination: [2, 0.15, 0.71] - Entity: 17803125207910630398 Parent: 0 Children: @@ -20,30 +59,6 @@ Entities: Radiance: [1, 1, 1] CastShadows: true SoftShadows: true - LightSize: 0.5 - - Entity: 4315886439647742331 - Parent: 0 - Children: - [] - TagComponent: - Tag: Cube - TransformComponent: - Position: [0, 2.048974, 0] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - MeshComponent: - AssetID: 3580169978473467053 - - Entity: 16992665426857995732 - Parent: 0 - Children: - [] - TagComponent: - Tag: Cube - TransformComponent: - Position: [0, 0, 0] - Rotation: [0, 0, 0] - Scale: [50, 1, 50] - MeshComponent: - AssetID: 3580169978473467053 + LightSize: 0.9 PhysicsLayers: [] \ No newline at end of file diff --git a/Editor/assets/scenes/demo.scene b/Editor/assets/scenes/demo.scene index 0adab62..fdb06f9 100644 --- a/Editor/assets/scenes/demo.scene +++ b/Editor/assets/scenes/demo.scene @@ -1,12 +1,21 @@ Scene: Scene Name Environment: - AssetHandle: 17073147362577408906 - Light: - Direction: [-0.314, -0.941, -0.209] - Radiance: [0, 0, 0] - Multiplier: 1 + AssetHandle: 5211537204242875091 Entities: - - Entity: 3696833073589069488 + - Entity: 15706224176559717512 + Parent: 0 + Children: + [] + TagComponent: + Tag: Cube + TransformComponent: + Position: [0, 0, 0] + Rotation: [0, 0, 0] + Scale: [1, 1, 1] + MeshComponent: + AssetID: 18328012085543462741 + AssetPath: assets/meshes/Default/Cube.fbx + - Entity: 8041206185299282567 Parent: 0 Children: [] @@ -17,8 +26,11 @@ Entities: Rotation: [0, 0, 0] Scale: [1, 1, 1] SkyLightComponent: - EnvironmentMap: 17073147362577408906 + EnvironmentMap: 5211537204242875091 + EnvironmentAssetPath: assets/env/venice_dawn_1_4k.hdr Intensity: 1 Angle: 0 + DynamicSky: false + TurbidityAzimuthInclination: [2, 0, 0] PhysicsLayers: [] \ No newline at end of file diff --git a/ExampleApp/ExampleApp.csproj b/ExampleApp/ExampleApp.csproj index 310e341..a25a841 100644 --- a/ExampleApp/ExampleApp.csproj +++ b/ExampleApp/ExampleApp.csproj @@ -4,6 +4,7 @@ net9.0 enable enable + true diff --git a/ExampleApp/Src/FPSPlayer.cs b/ExampleApp/Src/FPSPlayer.cs index 16f0dbf..1aa496c 100644 --- a/ExampleApp/Src/FPSPlayer.cs +++ b/ExampleApp/Src/FPSPlayer.cs @@ -1,3 +1,4 @@ +using System.Runtime.InteropServices; using Prism; namespace FPSExample @@ -46,6 +47,9 @@ namespace FPSExample m_LastMousePosition = Input.GetMousePosition(); Input.SetCursorMode(Input.CursorMode.Locked); + + int size = Marshal.SizeOf(); + Console.WriteLine($"C# size of Transform: {size}"); } void OnUpdate(float ts) diff --git a/Prism-ScriptCore/Prism-ScriptCore.csproj b/Prism-ScriptCore/Prism-ScriptCore.csproj index 4cebc04..a50533e 100644 --- a/Prism-ScriptCore/Prism-ScriptCore.csproj +++ b/Prism-ScriptCore/Prism-ScriptCore.csproj @@ -5,6 +5,7 @@ Prism_ScriptCore enable enable + true diff --git a/Prism-ScriptCore/Src/Prism/Engine/Engine.cs b/Prism-ScriptCore/Src/Prism/Engine/Engine.cs new file mode 100644 index 0000000..90e599a --- /dev/null +++ b/Prism-ScriptCore/Src/Prism/Engine/Engine.cs @@ -0,0 +1,15 @@ +using System.Runtime.CompilerServices; + + namespace Prism + { + public class Debug + { + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern void Log_Native(string message); + + public static void Log(string message) + { + Log_Native(message); + } + } + } diff --git a/Prism-ScriptCore/Src/Prism/Math/Transform.cs b/Prism-ScriptCore/Src/Prism/Math/Transform.cs index 47b9edf..8c8a834 100644 --- a/Prism-ScriptCore/Src/Prism/Math/Transform.cs +++ b/Prism-ScriptCore/Src/Prism/Math/Transform.cs @@ -9,8 +9,8 @@ namespace Prism public Vec3 Rotation; public Vec3 Scale; - public Vec3 Up { get; } - public Vec3 Right { get; } - public Vec3 Forward { get; } + public Vec3 Up; + public Vec3 Right; + public Vec3 Forward; } } \ No newline at end of file diff --git a/Prism/src/Prism/Asset/AssetsManager.cpp b/Prism/src/Prism/Asset/AssetsManager.cpp index 8c29a63..53e7290 100644 --- a/Prism/src/Prism/Asset/AssetsManager.cpp +++ b/Prism/src/Prism/Asset/AssetsManager.cpp @@ -132,25 +132,6 @@ namespace Prism return assetHandle != 0 && s_LoadedAssets.find(assetHandle) != s_LoadedAssets.end(); } - void AssetsManager::Rename(Ref& asset, const std::string& newName) - { - const std::string newFilePath = FileSystem::Rename(asset->FilePath, newName); - const std::string oldFilePath = asset->FilePath; - asset->FilePath = newFilePath; - asset->FileName = newName; - - if (FileSystem::Exists(oldFilePath + ".meta")) - { - std::string metaFileName = oldFilePath; - - if (!asset->Extension.empty()) - metaFileName += "." + asset->Extension; - - FileSystem::PrismDeleteFile(oldFilePath + ".meta"); - AssetSerializer::CreateMetaFile(asset); - } - } - template Ref AssetsManager::GetAsset(AssetHandle assetHandle, bool loadData) { @@ -383,41 +364,29 @@ namespace Prism break; case FileSystemAction::Rename: { - Ref asset; - - for (auto it = s_LoadedAssets.begin(); it != s_LoadedAssets.end(); it++) + Ref asset = nullptr; { - if (it->second->FileName == e.OldName) + const std::string oldMetaPath = std::filesystem::path(e.FilePath).parent_path().string() + "/" + e.OldName; + for (auto& [handle, existingAsset] : s_LoadedAssets) { - asset = it->second; + if (existingAsset->FilePath == oldMetaPath) + { + asset = existingAsset; + break; + } } } if (asset) { - if (asset->Type != AssetTypes::GetAssetTypeFromExtension(Utils::GetExtension(e.FilePath))) - { - RemoveAsset(asset->Handle); - FileSystem::PrismDeleteFile(asset->FilePath + ".meta"); - asset = ImportAsset(e.FilePath, parentHandle); - }else - { - std::string oldMetaPath = asset->FilePath + ".meta"; - std::string newMetaPath = e.FilePath + ".meta"; + std::string oldMetaPath = asset->FilePath + ".meta"; - std::error_code ec; - std::filesystem::rename(oldMetaPath, newMetaPath, ec); - if (ec) - { - PM_CORE_ERROR("Failed to rename meta file: {}", ec.message()); - } - - asset->FilePath = e.FilePath; - asset->FileName = e.NewName; - } - - } + FileSystem::Rename(oldMetaPath, e.NewName); + asset->FilePath = e.FilePath; + asset->FileName = e.NewName; + asset->Extension = Utils::GetExtension(e.FilePath); + } } break; case FileSystemAction::Delete: diff --git a/Prism/src/Prism/Asset/AssetsManager.h b/Prism/src/Prism/Asset/AssetsManager.h index f30a726..57d6e12 100644 --- a/Prism/src/Prism/Asset/AssetsManager.h +++ b/Prism/src/Prism/Asset/AssetsManager.h @@ -45,7 +45,6 @@ namespace Prism static AssetHandle GetAssetHandleFromFilePath(const std::string& filepath); static bool IsAssetHandleValid(const AssetHandle& assetHandle); - static void Rename(Ref& asset, const std::string& newName); static Ref CreateAssetPhysicsMaterial(const std::string& filename, AssetType type, const AssetHandle& directoryHandle, float v1, float v2, float v3); diff --git a/Prism/src/Prism/Core/Application.cpp b/Prism/src/Prism/Core/Application.cpp index 03815e2..a134efc 100644 --- a/Prism/src/Prism/Core/Application.cpp +++ b/Prism/src/Prism/Core/Application.cpp @@ -36,7 +36,6 @@ namespace Prism m_Window = std::unique_ptr(Window::Create(WindowProps{props.Name, props.Width, props.Height})); m_Window->SetEventCallback(BIND_EVENT_FN(OnEvent)); m_Window->SetVSync(true); - m_Window->Maximize(); m_ImGuiLayer = new ImGuiLayer("ImGui Layer"); PushOverlay(m_ImGuiLayer); @@ -107,6 +106,7 @@ namespace Prism for (Layer* layer : m_LayerStack) layer->OnImGuiRender(); + /* ImGui::Begin("Renderer"); const auto& caps = RendererAPI::GetCapabilities(); ImGui::Text("Vendor: %s", caps.Vendor.c_str()); @@ -114,6 +114,7 @@ namespace Prism ImGui::Text("Version: %s", caps.Version.c_str()); ImGui::Text("Frame Time: %.2fms\n", m_TimeStep.GetMilliseconds()); ImGui::End(); + */ m_ImGuiLayer->End(); } diff --git a/Prism/src/Prism/Core/EntryPoint.h b/Prism/src/Prism/Core/EntryPoint.h index 12ec928..62faad1 100644 --- a/Prism/src/Prism/Core/EntryPoint.h +++ b/Prism/src/Prism/Core/EntryPoint.h @@ -12,7 +12,19 @@ extern Prism::Application* Prism::CreateApplication(CommandArgs args); +#ifdef PRISM_GUI +#ifdef _WIN32 +#include +int MainEntry(int argc, char* argv[]); +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) +{ + return MainEntry(__argc, __argv); +} +#endif +int MainEntry(int argc, char** argv) +#else int main(int argc, char** argv) +#endif { //TODO: this will use other method to impl std::cout << std::filesystem::current_path() << std::endl; @@ -33,6 +45,7 @@ int main(int argc, char** argv) Prism::ShutdownCore(); #endif + return 0; } #endif //ENTRYPOINT_H diff --git a/Prism/src/Prism/Core/Events/ApplicationEvent.h b/Prism/src/Prism/Core/Events/ApplicationEvent.h index 72076ae..9aefc37 100644 --- a/Prism/src/Prism/Core/Events/ApplicationEvent.h +++ b/Prism/src/Prism/Core/Events/ApplicationEvent.h @@ -45,6 +45,49 @@ namespace Prism { EVENT_CLASS_CATEGORY(EventCategoryApplication) }; + class PRISM_API WindowFocusEvent : public Event + { + public: + WindowFocusEvent() = default; + + EVENT_CLASS_TYPE(WindowFocus) + EVENT_CLASS_CATEGORY(EventCategoryApplication) + }; + + class PRISM_API WindowLostFocusEvent : public Event + { + public: + WindowLostFocusEvent() = default; + + EVENT_CLASS_TYPE(WindowLostFocus) + EVENT_CLASS_CATEGORY(EventCategoryApplication) + }; + + class PRISM_API WindowMovedEvent : public Event + { + public: + WindowMovedEvent(const int32_t x, const int32_t y) + : m_X(x), m_Y(y) + { + } + + inline int32_t GetX() const { return m_X; } + inline int32_t GetY() const { return m_Y; } + + std::string ToString() const override + { + std::stringstream ss; + ss << "WindowMovedEvent: " << m_X << ", " << m_Y; + return ss.str(); + } + + EVENT_CLASS_TYPE(WindowMoved) + EVENT_CLASS_CATEGORY(EventCategoryApplication) + + private: + int32_t m_X, m_Y; + }; + class PRISM_API AppTickEvent : public Event { public: diff --git a/Prism/src/Prism/Core/Log.h b/Prism/src/Prism/Core/Log.h index 5014805..c323d9d 100644 --- a/Prism/src/Prism/Core/Log.h +++ b/Prism/src/Prism/Core/Log.h @@ -24,7 +24,6 @@ namespace Prism static std::shared_ptr s_CoreLogger; static std::shared_ptr s_ClientLogger; }; -} #ifdef _DEBUG #define PM_CORE_TRACE(...) SPDLOG_LOGGER_TRACE(::Prism::Log::GetCoreLogger(), __VA_ARGS__) @@ -41,6 +40,8 @@ namespace Prism #define PM_CORE_ERROR(...) ::Prism::Log::GetCoreLogger()->error(__VA_ARGS__) #define PM_CORE_FATAL(...) ::Prism::Log::GetCoreLogger()->critical(__VA_ARGS__) #endif +} + #define PM_CLIENT_TRACE(...) ::Prism::Log::GetClientLogger()->trace(__VA_ARGS__) diff --git a/Prism/src/Prism/Core/TimeStep.h b/Prism/src/Prism/Core/TimeStep.h index ccdcd7a..93cbd6e 100644 --- a/Prism/src/Prism/Core/TimeStep.h +++ b/Prism/src/Prism/Core/TimeStep.h @@ -21,7 +21,7 @@ namespace Prism operator float() { return m_Time; } private: - float m_Time; + float m_Time = 0.0f; }; } diff --git a/Prism/src/Prism/Core/Window.h b/Prism/src/Prism/Core/Window.h index 7c18486..d08dd31 100644 --- a/Prism/src/Prism/Core/Window.h +++ b/Prism/src/Prism/Core/Window.h @@ -10,6 +10,7 @@ #include "Ref.h" #include "Events/Event.h" #include "Prism/Core/Core.h" +#include namespace Prism @@ -39,8 +40,8 @@ namespace Prism virtual void SetEventCallback(const EventCallbackFn& callback) = 0; virtual uint32_t GetWidth() const = 0; virtual uint32_t GetHeight() const = 0; - virtual std::pair GetSize() const = 0; - virtual std::pair GetWindowPos() const = 0; + virtual glm::ivec2 GetSize() const = 0; + virtual glm::vec2 GetWindowPos() const = 0; virtual void SetVSync(bool enable) = 0; virtual bool const IsVSync() const = 0; diff --git a/Prism/src/Prism/Editor/ContentBrowserPanel.cpp b/Prism/src/Prism/Editor/ContentBrowserPanel.cpp index 1c088f4..9cf8da0 100644 --- a/Prism/src/Prism/Editor/ContentBrowserPanel.cpp +++ b/Prism/src/Prism/Editor/ContentBrowserPanel.cpp @@ -11,6 +11,7 @@ #include "Prism/Core/Application.h" #include "Prism/Core/Input.h" #include "Prism/Core/Log.h" +#include "Prism/Utilities/StringUtils.h" namespace Prism { @@ -101,16 +102,20 @@ namespace Prism if (ImGui::MenuItem("Folder")) { PM_CORE_INFO("Creating Folder..."); - const bool created = FileSystem::CreateFolder(m_CurrentDirectory->FilePath + "/New Folder"); - if (created) + const std::string filePath = m_CurrentDirectory->FilePath + "/new folder"; + FileSystem::CreateFolder(filePath); + UpdateCurrentDirectory(m_CurrentDirHandle); + // const auto& createdDirectory = AssetsManager::CreateDirectory(filePath, m_CurrentDirHandle); + /* + if (createdDirectory) { UpdateCurrentDirectory(m_CurrentDirHandle); - const auto& createdDirectory = AssetsManager::GetAsset(AssetsManager::GetAssetHandleFromFilePath(m_CurrentDirectory->FilePath + "/New Folder")); m_SelectedAssets.Select(createdDirectory->Handle); memset(m_InputBuffer, 0, MAX_INPUT_BUFFER_LENGTH); memcpy(m_InputBuffer, createdDirectory->FileName.c_str(), createdDirectory->FileName.size()); m_RenamingSelected = true; } + */ } if (ImGui::MenuItem("Scene")) @@ -523,7 +528,8 @@ namespace Prism if (ImGui::InputText("##rename_dummy", m_InputBuffer, MAX_INPUT_BUFFER_LENGTH, ImGuiInputTextFlags_EnterReturnsTrue)) { PM_CORE_INFO("Renaming to {0}", m_InputBuffer); - AssetsManager::Rename(asset, m_InputBuffer); + const std::string filename = m_InputBuffer + Utils::GetExtension(asset->FilePath); + FileSystem::Rename(asset->FilePath, filename); m_RenamingSelected = false; m_SelectedAssets.Clear(); m_UpdateDirectoryNextFrame = true; diff --git a/Prism/src/Prism/Editor/SceneHierachyPanel.cpp b/Prism/src/Prism/Editor/SceneHierachyPanel.cpp index 9394d17..cbd5492 100644 --- a/Prism/src/Prism/Editor/SceneHierachyPanel.cpp +++ b/Prism/src/Prism/Editor/SceneHierachyPanel.cpp @@ -1090,18 +1090,33 @@ namespace Prism }); DrawComponent("Script", entity, [=](ScriptComponent& scriptComponent) mutable { - UI::BeginPropertyGrid(); - const std::string oldName = scriptComponent.ModuleName; - if (UI::Property("Module Name", scriptComponent.ModuleName, !ScriptEngine::ModuleExists(scriptComponent.ModuleName))) // TODO: no live edit - { - // Shutdown old script - if (ScriptEngine::ModuleExists(oldName)) - ScriptEngine::ShutdownScriptEntity(entity, oldName); - if (ScriptEngine::ModuleExists(scriptComponent.ModuleName)) - ScriptEngine::InitScriptEntity(entity); + const std::string oldName = scriptComponent.ModuleName; + + if (ImGui::BeginCombo("Module Name", scriptComponent.ModuleName.c_str())) + { + const auto& availableScripts = ScriptEngine::GetAvailableScripts(); + + for (const auto& script : availableScripts) + { + const bool isSelected = (scriptComponent.ModuleName == script); + if (ImGui::Selectable(script.c_str(), isSelected)) + { + // 切换逻辑 + if (ScriptEngine::ModuleExists(oldName)) + ScriptEngine::ShutdownScriptEntity(entity, oldName); + scriptComponent.ModuleName = script; + if (ScriptEngine::ModuleExists(scriptComponent.ModuleName)) + ScriptEngine::InitScriptEntity(entity); + } + if (isSelected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); } + UI::BeginPropertyGrid(); + // Public Fields if (ScriptEngine::ModuleExists(scriptComponent.ModuleName)) { diff --git a/Prism/src/Prism/Physics/Physics3D.cpp b/Prism/src/Prism/Physics/Physics3D.cpp index 3f5356b..d097330 100644 --- a/Prism/src/Prism/Physics/Physics3D.cpp +++ b/Prism/src/Prism/Physics/Physics3D.cpp @@ -85,7 +85,8 @@ namespace Prism void Physics3D::Simulate(const TimeStep ts) { - + auto& time = s_SimulationTime; + auto& sett = s_Settings; // TODO: Allow projects to control the fixed step amount s_SimulationTime += ts.GetMilliseconds(); @@ -106,7 +107,7 @@ namespace Prism void Physics3D::DestroyScene() { - PM_CORE_ASSERT(s_Scene); + if (!s_Scene) return; s_Actors.clear(); s_Scene->release(); diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.cpp index 4a324da..23ba26a 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.cpp +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.cpp @@ -230,4 +230,12 @@ namespace Prism glBindTextureUnit(slot, instance->m_ColorAttachments[attachmentIndex]); }); } + + void OpenGLFrameBuffer::BindDepthTexture(uint32_t slot) const + { + Ref instance = this; + Renderer::Submit([instance, slot]() { + glBindTextureUnit(slot, instance->m_DepthAttachment); + }); + } } diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.h b/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.h index 127fd14..b548ad9 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.h +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLFrameBuffer.h @@ -21,6 +21,7 @@ namespace Prism void Resize(uint32_t width, uint32_t height, bool forceReCreate) override; void BindTexture(uint32_t attachmentIndex, uint32_t slot) const override; + void BindDepthTexture(uint32_t slot = 0) const override; uint32_t GetWidth() const override { return m_Specification.Width; } uint32_t GetHeight() const override { return m_Specification.Height; } diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.cpp b/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.cpp index 4018522..173e84a 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.cpp +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.cpp @@ -186,7 +186,7 @@ namespace Prism }); } - void OpenGLTexture2D::SetData(const void* data, int count) + void OpenGLTexture2D::SetData(const void* data, uint32_t count) { Lock(); diff --git a/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.h b/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.h index 4d24c3c..ebee207 100644 --- a/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.h +++ b/Prism/src/Prism/Platform/OpenGL/OpenGLTexture.h @@ -30,7 +30,7 @@ namespace Prism virtual void Lock() override; virtual void Unlock() override; - virtual void SetData(const void* data, int count) override; + virtual void SetData(const void* data, uint32_t count) override; virtual void Resize(uint32_t width, uint32_t height) override; virtual Buffer GetWriteableBuffer() override; diff --git a/Prism/src/Prism/Platform/Windows/WindowsFileSystemWatcher.cpp b/Prism/src/Prism/Platform/Windows/WindowsFileSystemWatcher.cpp index 4526f64..98d97a2 100644 --- a/Prism/src/Prism/Platform/Windows/WindowsFileSystemWatcher.cpp +++ b/Prism/src/Prism/Platform/Windows/WindowsFileSystemWatcher.cpp @@ -38,10 +38,12 @@ namespace Prism if (FileSystem::s_IgnoreNextChange.load()) return; - std::filesystem::path fullPath = std::filesystem::path(dir) / filename; + std::string fullPath = (std::filesystem::path(dir) / filename).string(); + + std::replace(fullPath.begin(), fullPath.end(), '\\', '/'); FileSystemChangedEvent e; - e.FilePath = fullPath.string(); + e.FilePath = fullPath; e.NewName = filename; e.OldName = oldFilename; // efsw 在重命名时会提供旧文件名 e.IsDirectory = false; // 稍后根据实际情况判断 diff --git a/Prism/src/Prism/Platform/Windows/WindowsWindow.cpp b/Prism/src/Prism/Platform/Windows/WindowsWindow.cpp index 3b67725..abbb692 100644 --- a/Prism/src/Prism/Platform/Windows/WindowsWindow.cpp +++ b/Prism/src/Prism/Platform/Windows/WindowsWindow.cpp @@ -62,7 +62,7 @@ namespace Prism m_Data.VSync = enable; } - std::pair WindowsWindow::GetWindowPos() const + glm::vec2 WindowsWindow::GetWindowPos() const { int x, y; glfwGetWindowPos(m_Window, &x, &y); @@ -91,6 +91,8 @@ namespace Prism glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_DEPTH_BITS, 24); + s_GLFWInitialized = true; } @@ -119,16 +121,37 @@ namespace Prism glfwSetWindowCloseCallback(m_Window, [](GLFWwindow* window) { - auto& data = *((WindowData*)glfwGetWindowUserPointer(window)); + const auto& data = *((WindowData*)glfwGetWindowUserPointer(window)); WindowCloseEvent event; data.EventCallback(event); }); + glfwSetWindowFocusCallback(m_Window, [](GLFWwindow* window, const int focused) { + const auto& data = *((WindowData*)glfwGetWindowUserPointer(window)); + + if (focused) + { + WindowFocusEvent event; + data.EventCallback(event); + } + else + { + WindowLostFocusEvent event; + data.EventCallback(event); + } + }); + + glfwSetWindowPosCallback(m_Window, [](GLFWwindow* window, int xpos, int ypos) { + const auto& data = *((WindowData*)glfwGetWindowUserPointer(window)); + + WindowMovedEvent event(xpos, ypos); + data.EventCallback(event); + }); glfwSetKeyCallback(m_Window, [](GLFWwindow* window, int key, int scancode, int action, int mods) { - auto& data = *((WindowData*)glfwGetWindowUserPointer(window)); + const auto& data = *((WindowData*)glfwGetWindowUserPointer(window)); switch (action) { diff --git a/Prism/src/Prism/Platform/Windows/WindowsWindow.h b/Prism/src/Prism/Platform/Windows/WindowsWindow.h index 6576267..0911b19 100644 --- a/Prism/src/Prism/Platform/Windows/WindowsWindow.h +++ b/Prism/src/Prism/Platform/Windows/WindowsWindow.h @@ -27,8 +27,8 @@ namespace Prism bool const IsVSync() const override { return m_Data.VSync; } void SetVSync(bool enable) override; - virtual std::pair GetSize() const override { return { m_Data.Width, m_Data.Height }; } - virtual std::pair GetWindowPos() const override; + virtual glm::ivec2 GetSize() const override { return { m_Data.Width, m_Data.Height }; } + virtual glm::vec2 GetWindowPos() const override; virtual const std::string& GetTitle() const override { return m_Data.Title; } virtual void SetTitle(const std::string& title) override; diff --git a/Prism/src/Prism/Renderer/FrameBuffer.h b/Prism/src/Prism/Renderer/FrameBuffer.h index ea03c8c..443377c 100644 --- a/Prism/src/Prism/Renderer/FrameBuffer.h +++ b/Prism/src/Prism/Renderer/FrameBuffer.h @@ -78,6 +78,7 @@ namespace Prism virtual void Resize(uint32_t width, uint32_t height, bool forceReCreate = false) = 0; virtual void BindTexture(uint32_t attachmentIndex = 0, uint32_t slot = 0) const = 0; + virtual void BindDepthTexture(uint32_t slot = 0) const = 0; virtual uint32_t GetWidth() const = 0; virtual uint32_t GetHeight() const = 0; diff --git a/Prism/src/Prism/Renderer/Renderer.cpp b/Prism/src/Prism/Renderer/Renderer.cpp index 1e6e61c..6ce7568 100644 --- a/Prism/src/Prism/Renderer/Renderer.cpp +++ b/Prism/src/Prism/Renderer/Renderer.cpp @@ -203,7 +203,10 @@ namespace Prism Renderer::Submit([submesh, material]() { if (material->GetFlag(MaterialFlag::DepthTest)) + { glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + } else glDisable(GL_DEPTH_TEST); diff --git a/Prism/src/Prism/Renderer/Renderer3D.cpp b/Prism/src/Prism/Renderer/Renderer3D.cpp index eec019c..1b71f89 100644 --- a/Prism/src/Prism/Renderer/Renderer3D.cpp +++ b/Prism/src/Prism/Renderer/Renderer3D.cpp @@ -49,7 +49,7 @@ namespace Prism bool EnableAutoExposure = true; float Key = 0.3f; Timer ExposureTimer; - float MaxExposure = 5.0f; + float MaxExposure = 1.5f; float MinExposure = 0.01f; // 直方图模式参数 @@ -153,7 +153,7 @@ namespace Prism //////////////// GeoPass //////////////// { FramebufferSpecification geoFramebufferSpec; - geoFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA16F, FramebufferTextureFormat::DEPTH24STENCIL8 }; + geoFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA32F, FramebufferTextureFormat::DEPTH24STENCIL8 }; geoFramebufferSpec.Samples = 8; geoFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f }; @@ -943,18 +943,17 @@ namespace Prism return; } - uint32_t srcTex = s_Data.ResolvedHDRTexture->GetRendererID(); const int iterations = 5; // 模糊迭代次数,可调 // 第一次:提取高光 + 水平模糊 { Renderer::BeginRenderPass(s_Data.BloomBlurPass[0]); + s_Data.BloomBlurShader->Bind(); s_Data.BloomBlurShader->SetInt("u_Texture", 0); - // s_Data.BloomBlurShader->SetBool("u_Horizontal", true); s_Data.BloomBlurShader->SetBool("u_FirstPass", true); s_Data.BloomBlurShader->SetFloat("u_Threshold", s_Data.BloomThreshold); - Renderer::Submit([srcTex]() { glBindTextureUnit(0, srcTex); }); + s_Data.ResolvedHDRTexture->Bind(); Renderer::SubmitFullscreenQuad(nullptr); Renderer::EndRenderPass(); } @@ -962,18 +961,17 @@ namespace Prism // 后续迭代 for (int i = 1; i < iterations; ++i) { - bool horizontal = (i % 2 == 1); // 第二次垂直,第三次水平... - uint32_t inputTex = (i % 2 == 1) ? - s_Data.BloomBlurPass[0]->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID() : - s_Data.BloomBlurPass[1]->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID(); auto outputPass = (i % 2 == 1) ? s_Data.BloomBlurPass[1] : s_Data.BloomBlurPass[0]; Renderer::BeginRenderPass(outputPass); s_Data.BloomBlurShader->Bind(); s_Data.BloomBlurShader->SetInt("u_Texture", 0); - // s_Data.BloomBlurShader->SetBool("u_Horizontal", horizontal); s_Data.BloomBlurShader->SetBool("u_FirstPass", false); - Renderer::Submit([inputTex]() { glBindTextureUnit(0, inputTex); }); + if (i%2 == 1) + s_Data.BloomBlurPass[0]->GetSpecification().TargetFramebuffer->BindTexture(); + else + s_Data.BloomBlurPass[1]->GetSpecification().TargetFramebuffer->BindTexture(); + Renderer::SubmitFullscreenQuad(nullptr); Renderer::EndRenderPass(); } @@ -986,9 +984,12 @@ namespace Prism Renderer::BeginRenderPass(s_Data.BloomBlendPass); s_Data.BloomBlurShader->Bind(); s_Data.BloomBlurShader->SetInt("u_Texture", 0); - // s_Data.BloomBlurShader->SetBool("u_Horizontal", false); + if (iterations % 2 == 0) + s_Data.BloomBlurPass[1]->GetSpecification().TargetFramebuffer->BindTexture(); + else + s_Data.BloomBlurPass[0]->GetSpecification().TargetFramebuffer->BindTexture(); + s_Data.BloomBlurShader->SetBool("u_FirstPass", false); - Renderer::Submit([finalBlurTex]() { glBindTextureUnit(0, finalBlurTex); }); Renderer::SubmitFullscreenQuad(nullptr); Renderer::EndRenderPass(); } @@ -1023,6 +1024,23 @@ namespace Prism Renderer::EndRenderPass(); } + void CopyDepthBuffer(Ref src, Ref dst) + { + uint32_t srcID = src->GetRendererID(); // 假设 FrameBuffer 有此方法 + uint32_t dstID = dst->GetRendererID(); + + int srcWidth = src->GetWidth(); + int srcHeight = src->GetHeight(); + int dstWidth = dst->GetWidth(); + int dstHeight = dst->GetHeight(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, srcID); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstID); + glBlitFramebuffer(0, 0, srcWidth, srcHeight, 0, 0, dstWidth, dstHeight, + GL_DEPTH_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_FRAMEBUFFER, 0); // 可选恢复 + } + void Renderer3D::CompositePass(const Ref& outRenderPass) { Renderer::BeginRenderPass(outRenderPass); @@ -1041,13 +1059,9 @@ namespace Prism glBindTextureUnit(1, s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetDepthAttachmentRendererID()); }); - // 新增:绑定 Bloom 纹理(如果启用) if (s_Data.EnableBloom) { - uint32_t bloomTex = s_Data.BloomBlendPass->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID(); - Renderer::Submit([bloomTex]() { - glBindTextureUnit(2, bloomTex); // 绑定到单元2 - }); + s_Data.BloomBlendPass->GetSpecification().TargetFramebuffer->BindTexture(0, 2); s_Data.CompositeShader->SetInt("u_BloomTexture", 2); // 告诉着色器使用单元2 } @@ -1057,182 +1071,6 @@ namespace Prism } - /* - void Renderer3D::CompositePass(const Ref& outRenderPass) - { - Renderer::BeginRenderPass(outRenderPass); - - s_Data.CompositeShader->Bind(); - - s_Data.BloomBlendShader->Bind(); - s_Data.BloomBlendShader->SetBool("u_EnableBloom", s_Data.EnableBloom); - - s_Data.AutoExposureData.ExposureSSBO->BindBase(2); - - Renderer::Submit([]() { - glBindTextureUnit(0, s_Data.ResolvedHDRTexture->GetRendererID()); - }); - s_Data.BloomBlendShader->SetInt("u_SceneTexture", 0); - - s_Data.CompositeShader->SetBool("u_EnableAutoExposure",s_Data.AutoExposureData.EnableAutoExposure); - s_Data.CompositeShader->SetFloat("u_ManualExposure", s_Data.SceneData.SceneCamera.Camera.GetExposure()); - s_Data.CompositeShader->SetInt("u_TextureSamples", s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetSpecification().Samples); - s_Data.CompositeShader->SetFloat("u_EnableBloom", s_Data.EnableBloom); - - if (s_Data.EnableBloom) - { - uint32_t bloomTex = s_Data.BloomBlendPass->GetSpecification().TargetFramebuffer->GetColorAttachmentRendererID(); - Renderer::Submit([bloomTex]() { - glBindTextureUnit(1, bloomTex); - }); - s_Data.BloomBlendShader->SetInt("u_BloomTexture", 1); - } - - s_Data.GeoPass->GetSpecification().TargetFramebuffer->BindTexture(); - Renderer::Submit([]() - { - glBindTextureUnit(1, s_Data.GeoPass->GetSpecification().TargetFramebuffer->GetDepthAttachmentRendererID()); - }); - - Renderer::SubmitFullscreenQuad(nullptr); - - Renderer::EndRenderPass(); - } - */ - - - /* - struct FrustumBounds - { - float r, l, b, t, f, n; - }; - - struct CascadeData - { - glm::mat4 ViewProj; - glm::mat4 View; - float SplitDepth; - }; - - - static void CalculateCascades(CascadeData* cascades, const glm::vec3& lightDirection) - { - // FrustumBounds frustumBounds[3]; - - auto& sceneCamera = s_Data.SceneData.SceneCamera; - auto viewProjection = sceneCamera.Camera.GetProjectionMatrix() * sceneCamera.ViewMatrix; - - constexpr int SHADOW_MAP_CASCADE_COUNT = 4; - float cascadeSplits[SHADOW_MAP_CASCADE_COUNT]; - - // TODO: less hard-coding! - float nearClip = 0.1f; - float farClip = 1000.0f; - float clipRange = farClip - nearClip; - - float minZ = nearClip; - float maxZ = nearClip + clipRange; - - float range = maxZ - minZ; - float ratio = maxZ / minZ; - - // Calculate split depths based on view camera frustum - // Based on method presented in https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch10.html - for (uint32_t i = 0; i < SHADOW_MAP_CASCADE_COUNT; i++) - { - float p = (i + 1) / static_cast(SHADOW_MAP_CASCADE_COUNT); - float log = minZ * std::pow(ratio, p); - float uniform = minZ + range * p; - float d = s_Data.CascadeSplitLambda * (log - uniform) + uniform; - cascadeSplits[i] = (d - nearClip) / clipRange; - } - - // cascadeSplits[3] = 0.3f; - - // Manually set cascades here - // cascadeSplits[0] = 0.05f; - // cascadeSplits[1] = 0.15f; - // cascadeSplits[2] = 0.3f; - // cascadeSplits[3] = 1.0f; - - // Calculate orthographic projection matrix for each cascade - float lastSplitDist = 1.0; - for (uint32_t i = 0; i < SHADOW_MAP_CASCADE_COUNT; i++) - { - float splitDist = cascadeSplits[i]; - - glm::vec3 frustumCorners[8] = - { - glm::vec3(-1.0f, 1.0f, -1.0f), - glm::vec3( 1.0f, 1.0f, -1.0f), - glm::vec3( 1.0f, -1.0f, -1.0f), - glm::vec3(-1.0f, -1.0f, -1.0f), - glm::vec3(-1.0f, 1.0f, 1.0f), - glm::vec3( 1.0f, 1.0f, 1.0f), - glm::vec3( 1.0f, -1.0f, 1.0f), - glm::vec3(-1.0f, -1.0f, 1.0f), - }; - - // Project frustum corners into world space - glm::mat4 invCam = glm::inverse(viewProjection); - for (uint32_t i = 0; i < 8; i++) - { - glm::vec4 invCorner = invCam * glm::vec4(frustumCorners[i], 1.0f); - frustumCorners[i] = invCorner / invCorner.w; - } - - for (uint32_t i = 0; i < 4; i++) - { - glm::vec3 dist = frustumCorners[i + 4] - frustumCorners[i]; - frustumCorners[i + 4] = frustumCorners[i] + (dist * splitDist); - frustumCorners[i] = frustumCorners[i] + (dist * lastSplitDist); - } - - // Get frustum center - glm::vec3 frustumCenter = glm::vec3(0.0f); - for (uint32_t i = 0; i < 8; i++) - frustumCenter += frustumCorners[i]; - - frustumCenter /= 8.0f; - - //frustumCenter *= 0.01f; - - float radius = 0.0f; - for (uint32_t i = 0; i < 8; i++) - { - float distance = glm::length(frustumCorners[i] - frustumCenter); - radius = glm::max(radius, distance); - } - radius = std::ceil(radius * 16.0f) / 16.0f; - - glm::vec3 maxExtents = glm::vec3(radius); - glm::vec3 minExtents = -maxExtents; - - glm::vec3 lightDir = -lightDirection; - glm::mat4 lightViewMatrix = glm::lookAt(frustumCenter - lightDir * -minExtents.z, frustumCenter, glm::vec3(0.0f, 0.0f, 1.0f)); - glm::mat4 lightOrthoMatrix = glm::ortho(minExtents.x, maxExtents.x, minExtents.y, maxExtents.y, 0.0f + s_Data.CascadeNearPlaneOffset, maxExtents.z - minExtents.z + s_Data.CascadeFarPlaneOffset); - - // Offset to texel space to avoid shimmering (from https://stackoverflow.com/questions/33499053/cascaded-shadow-map-shimmering) - glm::mat4 shadowMatrix = lightOrthoMatrix * lightViewMatrix; - constexpr float ShadowMapResolution = 4096.0f; - glm::vec4 shadowOrigin = (shadowMatrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)) * ShadowMapResolution / 2.0f; - glm::vec4 roundedOrigin = glm::round(shadowOrigin); - glm::vec4 roundOffset = roundedOrigin - shadowOrigin; - roundOffset = roundOffset * 2.0f / ShadowMapResolution; - roundOffset.z = 0.0f; - roundOffset.w = 0.0f; - - lightOrthoMatrix[3] += roundOffset; - - // Store split distance and matrix in cascade - cascades[i].SplitDepth = (nearClip + splitDist * clipRange) * -1.0f; - cascades[i].ViewProj = lightOrthoMatrix * lightViewMatrix; - cascades[i].View = lightViewMatrix; - - lastSplitDist = cascadeSplits[i]; - } - } - */ std::vector GetFrustumCornersWorldSpace(const SceneRendererCamera& sceneCamera) { std::vector corners(8); @@ -1424,4 +1262,5 @@ namespace Prism ImGui::End(); } + } diff --git a/Prism/src/Prism/Renderer/SceneRenderer.cpp b/Prism/src/Prism/Renderer/SceneRenderer.cpp index dae0265..5915c17 100644 --- a/Prism/src/Prism/Renderer/SceneRenderer.cpp +++ b/Prism/src/Prism/Renderer/SceneRenderer.cpp @@ -12,6 +12,7 @@ #include "Renderer3D.h" #include "RenderPass.h" +#include "glad/glad.h" namespace Prism @@ -26,7 +27,7 @@ namespace Prism void SceneRenderer::Init() { FramebufferSpecification finalFramebufferSpec; - finalFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA16F, FramebufferTextureFormat::Depth}; + finalFramebufferSpec.Attachments = { FramebufferTextureFormat::RGBA32F, FramebufferTextureFormat::DEPTH24STENCIL8}; finalFramebufferSpec.ClearColor = { 0.1f, 0.1f, 0.1f, 1.0f }; RenderPassSpecification finalRenderPassSpec; @@ -207,4 +208,24 @@ namespace Prism { return Renderer3D::GetOptions(); } + + void SceneRenderer::FlushToScreen() + { + const auto fb = s_Data.FinalPass->GetSpecification().TargetFramebuffer; + const auto fbWidth = fb->GetWidth(); + const auto fbHeight = fb->GetHeight(); + + + + Renderer::Submit([fb, fbWidth, fbHeight]() + { + glBindFramebuffer(GL_READ_FRAMEBUFFER, fb->GetColorAttachmentRendererID()); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + glBlitFramebuffer(0, 0, fbWidth, fbHeight, // 源矩形 + 0, 0, fbWidth, fbHeight, // 目标矩形 + GL_COLOR_BUFFER_BIT, // 只复制颜色缓冲 + GL_NEAREST); // 过滤器 + }); + } } diff --git a/Prism/src/Prism/Renderer/SceneRenderer.h b/Prism/src/Prism/Renderer/SceneRenderer.h index f55f371..4a8fe86 100644 --- a/Prism/src/Prism/Renderer/SceneRenderer.h +++ b/Prism/src/Prism/Renderer/SceneRenderer.h @@ -15,7 +15,7 @@ namespace Prism { struct SceneRendererOptions { - bool ShowGrid = true; + bool ShowGrid = false; bool ShowBoundingBoxes = false; }; @@ -90,7 +90,9 @@ namespace Prism static uint32_t GetFinalColorBufferRendererID(); static SceneRendererOptions& GetOptions(); static void OnImGuiRender(); - private: + + + static void FlushToScreen(); }; } diff --git a/Prism/src/Prism/Renderer/Texture.h b/Prism/src/Prism/Renderer/Texture.h index a7d9e67..6223dfb 100644 --- a/Prism/src/Prism/Renderer/Texture.h +++ b/Prism/src/Prism/Renderer/Texture.h @@ -62,7 +62,7 @@ namespace Prism virtual void Lock() = 0; virtual void Unlock() = 0; - virtual void SetData(const void* data, int count) = 0; + virtual void SetData(const void* data, uint32_t count) = 0; virtual void Resize(uint32_t width, uint32_t height) = 0; virtual Buffer GetWriteableBuffer() = 0; diff --git a/Prism/src/Prism/Scene/Components.h b/Prism/src/Prism/Scene/Components.h index e876184..e41bdb1 100644 --- a/Prism/src/Prism/Scene/Components.h +++ b/Prism/src/Prism/Scene/Components.h @@ -431,7 +431,7 @@ namespace Prism bool ShowIcon = false; bool DynamicSky = false; - glm::vec3 TurbidityAzimuthInclination = { 2.0, 0.0, 0.0 }; + glm::vec3 TurbidityAzimuthInclination = { 2.0, 0.0, 1.0 }; SkyLightComponent(const Ref& environment) : SceneEnvironment(environment) diff --git a/Prism/src/Prism/Scene/Scene.cpp b/Prism/src/Prism/Scene/Scene.cpp index 8cebea5..35a0307 100644 --- a/Prism/src/Prism/Scene/Scene.cpp +++ b/Prism/src/Prism/Scene/Scene.cpp @@ -32,12 +32,7 @@ namespace Prism static uint32_t s_SceneIDCounter = 0; - - - - - - Scene::Scene(const std::string& debugName, const bool isEditorScene) + Scene::Scene(const std::string& debugName, const bool isEditorScene, const bool runtime) : m_SceneID(++s_SceneIDCounter), m_DebugName(debugName) { m_Registry.on_construct().connect<&Physics2D::OnTransformConstruct>(); @@ -56,10 +51,11 @@ namespace Prism Physics3D::CreateScene(); } - Init(); + Init(runtime); } + Scene::~Scene() { m_Registry.on_destroy().disconnect(); @@ -68,20 +64,23 @@ namespace Prism s_ActiveScenes.erase(m_SceneID); } - void Scene::Init() + void Scene::Init(const bool runtime) { const auto skyboxShader = Shader::Create("assets/shaders/Skybox.glsl"); m_SkyboxMaterial = MaterialInstance::Create(Material::Create(skyboxShader)); m_SkyboxMaterial->SetFlag(MaterialFlag::DepthTest, false); - m_CameraIcon = AssetsManager::GetAsset("assets/editor/Camera.png"); - m_LightIcon = AssetsManager::GetAsset("assets/editor/light.png"); - + if (!runtime) + { + m_CameraIcon = AssetsManager::GetAsset("assets/editor/Camera.png"); + m_LightIcon = AssetsManager::GetAsset("assets/editor/light.png"); + } } void Scene::OnShutdown() { b2DestroyWorld(m_Registry.get(m_SceneEntity).World); + Physics3D::DestroyScene(); } void Scene::OnUpdate(TimeStep ts) @@ -224,7 +223,9 @@ namespace Prism ///////////////////////////////////////////////////////////////////// } + SceneRenderer::FlushToScreen(); SceneRenderer::EndScene(); + } void Scene::OnRenderEditor(const TimeStep ts, const EditorCamera& editorCamera) @@ -431,6 +432,12 @@ namespace Prism m_IsPlaying = false; } + void Scene::SetViewportSize(const glm::ivec2& viewportSize) + { + m_ViewportWidth = viewportSize.x; + m_ViewportHeight = viewportSize.y; + } + void Scene::SetViewportSize(const uint32_t width, const uint32_t height) { m_ViewportWidth = width; diff --git a/Prism/src/Prism/Scene/Scene.h b/Prism/src/Prism/Scene/Scene.h index 060b86a..766ba5d 100644 --- a/Prism/src/Prism/Scene/Scene.h +++ b/Prism/src/Prism/Scene/Scene.h @@ -74,10 +74,10 @@ namespace Prism class PRISM_API Scene : public RefCounted { public: - Scene(const std::string& debugName = "Scene", bool isEditorScene = false); + Scene(const std::string& debugName = "Scene", bool isEditorScene = false, bool runtime = false); ~Scene(); - void Init(); + void Init(bool runtime); void OnShutdown(); void OnUpdate(TimeStep ts); @@ -88,6 +88,7 @@ namespace Prism void OnRuntimeStart(); void OnRuntimeStop(); + void SetViewportSize(const glm::ivec2& viewportSize); void SetViewportSize(uint32_t width, uint32_t height); const Ref& GetEnvironment() const { return m_Environment; } diff --git a/Prism/src/Prism/Scene/SceneSerializer.cpp b/Prism/src/Prism/Scene/SceneSerializer.cpp index 3182785..8357e00 100644 --- a/Prism/src/Prism/Scene/SceneSerializer.cpp +++ b/Prism/src/Prism/Scene/SceneSerializer.cpp @@ -260,9 +260,15 @@ namespace Prism const auto mesh = entity.GetComponent().Mesh; if (mesh) + { out << YAML::Key << "AssetID" << YAML::Value << mesh->Handle; + out << YAML::Key << "AssetPath" << YAML::Value << mesh->FilePath; + } else + { out << YAML::Key << "AssetID" << YAML::Value << 0; + out << YAML::Key << "AssetPath" << YAML::Value << ""; + } out << YAML::EndMap; // MeshComponent } @@ -287,7 +293,16 @@ namespace Prism out << YAML::BeginMap; // SkyLightComponent const auto& skyLightComponent = entity.GetComponent(); - out << YAML::Key << "EnvironmentMap" << YAML::Value << skyLightComponent.SceneEnvironment->Handle; + if (skyLightComponent.SceneEnvironment) + { + out << YAML::Key << "EnvironmentMap" << YAML::Value << skyLightComponent.SceneEnvironment->Handle; + out << YAML::Key << "EnvironmentAssetPath" << YAML::Value << skyLightComponent.SceneEnvironment->FilePath; + } + else + { + out << YAML::Key << "EnvironmentMap" << YAML::Value << 0; + out << YAML::Key << "EnvironmentAssetPath" << YAML::Value << ""; + } out << YAML::Key << "Intensity" << YAML::Value << skyLightComponent.Intensity; out << YAML::Key << "Angle" << YAML::Value << skyLightComponent.Angle; @@ -518,9 +533,16 @@ namespace Prism out << YAML::Key << "IsTrigger" << YAML::Value << boxColliderComponent.IsTrigger; if (boxColliderComponent.Material) + { out << YAML::Key << "Material" << YAML::Value << boxColliderComponent.Material->Handle; + out << YAML::Key << "MaterialPath" << YAML::Value << boxColliderComponent.Material->FilePath; + } else + { out << YAML::Key << "Material" << YAML::Value << 0; + out << YAML::Key << "MaterialPath" << YAML::Value << ""; + } + out << YAML::EndMap; // BoxColliderComponent } @@ -535,9 +557,16 @@ namespace Prism out << YAML::Key << "IsTrigger" << YAML::Value << sphereColliderComponent.IsTrigger; if (sphereColliderComponent.Material) + { out << YAML::Key << "Material" << YAML::Value << sphereColliderComponent.Material->Handle; + out << YAML::Key << "MaterialPath" << YAML::Value << sphereColliderComponent.Material->FilePath; + } else + { out << YAML::Key << "Material" << YAML::Value << 0; + out << YAML::Key << "MaterialPath" << YAML::Value << ""; + } + out << YAML::EndMap; // SphereColliderComponent } @@ -552,10 +581,18 @@ namespace Prism out << YAML::Key << "Height" << YAML::Value << capsuleColliderComponent.Height; out << YAML::Key << "IsTrigger" << YAML::Value << capsuleColliderComponent.IsTrigger; + if (capsuleColliderComponent.Material) + { out << YAML::Key << "Material" << YAML::Value << capsuleColliderComponent.Material->Handle; + out << YAML::Key << "MaterialPath" << YAML::Value << capsuleColliderComponent.Material->FilePath; + } else + { out << YAML::Key << "Material" << YAML::Value << 0; + out << YAML::Key << "MaterialPath" << YAML::Value << ""; + } + out << YAML::EndMap; // CapsuleColliderComponent } @@ -566,18 +603,26 @@ namespace Prism out << YAML::BeginMap; // MeshColliderComponent auto meshColliderComponent = entity.GetComponent(); - - if (meshColliderComponent.OverrideMesh) + if (meshColliderComponent.OverrideMesh && meshColliderComponent.CollisionMesh) + { out << YAML::Key << "AssetID" << YAML::Value << meshColliderComponent.CollisionMesh->Handle; + out << YAML::Key << "AssetPath" << YAML::Value << meshColliderComponent.CollisionMesh->FilePath; + } out << YAML::Key << "IsConvex" << YAML::Value << meshColliderComponent.IsConvex; out << YAML::Key << "IsTrigger" << YAML::Value << meshColliderComponent.IsTrigger; out << YAML::Key << "OverrideMesh" << YAML::Value << meshColliderComponent.OverrideMesh; if (meshColliderComponent.Material) + { out << YAML::Key << "Material" << YAML::Value << meshColliderComponent.Material->Handle; + out << YAML::Key << "MaterialPath" << YAML::Value << meshColliderComponent.Material->FilePath; + } else + { out << YAML::Key << "Material" << YAML::Value << 0; + out << YAML::Key << "MaterialPath" << YAML::Value << ""; + } out << YAML::EndMap; // MeshColliderComponent } @@ -829,7 +874,7 @@ namespace Prism if (meshComponent["AssetPath"]) { const std::string assetFilePath = meshComponent["AssetPath"].as(); - assetID = AssetsManager::GetAssetHandleFromFilePath(filepath); + assetID = AssetsManager::GetAssetHandleFromFilePath(assetFilePath); } else { @@ -858,8 +903,8 @@ namespace Prism AssetHandle assetHandle; if (skyLightComponent["EnvironmentAssetPath"]) { - const auto filePath = skyLightComponent["EnvironmentAssetPath"].as(); - assetHandle = AssetsManager::GetAssetHandleFromFilePath(filepath); + const auto assetFilePath = skyLightComponent["EnvironmentAssetPath"].as(); + assetHandle = AssetsManager::GetAssetHandleFromFilePath(assetFilePath); } else { @@ -1055,8 +1100,16 @@ namespace Prism if (material && AssetsManager::IsAssetHandleValid(material.as())) { component.Material = AssetsManager::GetAsset(material.as()); + }else + { + const auto materialPath = boxColliderComponent["MaterialPath"].as(); + if (const auto assetId = AssetsManager::GetAssetHandleFromFilePath(materialPath); assetId != 0) + { + component.Material = AssetsManager::GetAsset(assetId); + } } + component.DebugMesh = MeshFactory::CreateBox(component.Size); } @@ -1068,7 +1121,17 @@ namespace Prism auto material = sphereColliderComponent["Material"]; if (material && AssetsManager::IsAssetHandleValid(material.as())) + { component.Material = AssetsManager::GetAsset(material.as()); + }else + { + const auto materialPath = sphereColliderComponent["MaterialPath"].as(); + if (const auto assetId = AssetsManager::GetAssetHandleFromFilePath(materialPath); assetId != 0) + { + component.Material = AssetsManager::GetAsset(assetId); + } + } + component.DebugMesh = MeshFactory::CreateSphere(component.Radius); } @@ -1082,7 +1145,16 @@ namespace Prism auto material = capsuleColliderComponent["Material"]; if (material && AssetsManager::IsAssetHandleValid(material.as())) + { component.Material = AssetsManager::GetAsset(material.as()); + }else + { + const auto materialPath = capsuleColliderComponent["MaterialPath"].as(); + if (const auto assetId = AssetsManager::GetAssetHandleFromFilePath(materialPath); assetId != 0) + { + component.Material = AssetsManager::GetAsset(assetId); + } + } component.DebugMesh = MeshFactory::CreateCapsule(component.Radius, component.Height); } @@ -1095,14 +1167,14 @@ namespace Prism if (overrideMesh) { UUID assetID; - if (meshComponent["AssetPath"]) + if (meshColliderComponent["AssetPath"]) { - const auto assetFilePath = meshComponent["AssetPath"].as(); - assetID = AssetsManager::GetAssetHandleFromFilePath(filepath); + const auto assetFilePath = meshColliderComponent["AssetPath"].as(); + assetID = AssetsManager::GetAssetHandleFromFilePath(assetFilePath); } else { - assetID = meshComponent["AssetID"].as(); + assetID = meshColliderComponent["AssetID"].as(); } if (AssetsManager::IsAssetHandleValid(assetID)) @@ -1116,16 +1188,33 @@ namespace Prism component.IsTrigger = meshColliderComponent["IsTrigger"] ? meshColliderComponent["IsTrigger"].as() : false; component.OverrideMesh = overrideMesh; - auto material = meshColliderComponent["Material"]; - if (material && AssetsManager::IsAssetHandleValid(material.as())) + if (meshColliderComponent["Material"]) { - component.Material = AssetsManager::GetAsset(material.as()); + auto material = meshColliderComponent["Material"]; + if (material && AssetsManager::IsAssetHandleValid(material.as())) + { + component.Material = AssetsManager::GetAsset(material.as()); - if (component.IsConvex) - PhysicsWrappers::CreateConvexMesh(component, deserializedEntity.Transform().Scale); - else - PhysicsWrappers::CreateTriangleMesh(component, deserializedEntity.Transform().Scale); + if (component.IsConvex) + PhysicsWrappers::CreateConvexMesh(component, deserializedEntity.Transform().Scale); + else + PhysicsWrappers::CreateTriangleMesh(component, deserializedEntity.Transform().Scale); + }else + { + const auto materialPath = meshColliderComponent["MaterialPath"].as(); + if (const auto assetId = AssetsManager::GetAssetHandleFromFilePath(materialPath); assetId != 0) + { + component.Material = AssetsManager::GetAsset(assetId); + + if (component.IsConvex) + PhysicsWrappers::CreateConvexMesh(component, deserializedEntity.Transform().Scale); + else + PhysicsWrappers::CreateTriangleMesh(component, deserializedEntity.Transform().Scale); + } + + } } + } else { diff --git a/Prism/src/Prism/Script/ScriptEngine.cpp b/Prism/src/Prism/Script/ScriptEngine.cpp index 0e8f0ba..8bc3695 100644 --- a/Prism/src/Prism/Script/ScriptEngine.cpp +++ b/Prism/src/Prism/Script/ScriptEngine.cpp @@ -3,6 +3,7 @@ // #include "ScriptEngine.h" +#include #include @@ -35,6 +36,10 @@ namespace Prism MonoImage* s_AppAssemblyImage = nullptr; MonoImage* s_CoreAssemblyImage = nullptr; + + + std::vector ScriptEngine::s_AvailableScripts; + #ifdef ENABLE_MONO_DEBUG static bool s_EnableMonoPDBDebug = true; #else @@ -87,6 +92,7 @@ namespace Prism static std::unordered_map s_EntityClassMap; + MonoAssembly* LoadAssemblyFromFile(const char* filepath) { if (!filepath) { @@ -390,6 +396,12 @@ namespace Prism void ScriptEngine::Init(const std::string& assemblyPath) { +#ifdef _WIN32 + _putenv("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1"); +#else + setenv("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT", "1", 1); +#endif + s_AssemblyPath = assemblyPath; InitMono(); @@ -429,8 +441,8 @@ namespace Prism s_CoreAssembly = LoadAssembly("assets/scripts/Prism-ScriptCore.dll"); s_CoreAssemblyImage = GetAssemblyImage(s_CoreAssembly); - auto appAssembly = LoadAssembly(path); - auto appAssemblyImage = GetAssemblyImage(appAssembly); + const auto appAssembly = LoadAssembly(path); + const auto appAssemblyImage = GetAssemblyImage(appAssembly); ScriptEngineRegistry::RegisterAll(); if (cleanup) @@ -441,6 +453,8 @@ namespace Prism s_AppAssembly = appAssembly; s_AppAssemblyImage = appAssemblyImage; + + RefreshAvailableScripts(); } void ScriptEngine::ReloadAssembly(const std::string& path) @@ -845,6 +859,43 @@ namespace Prism return entityIDMap.at(entityID); } + void ScriptEngine::RefreshAvailableScripts() + { + if (!s_AppAssemblyImage) return; + s_AvailableScripts.clear(); + + // 获取类型定义表 + const MonoTableInfo *tableInfo = mono_image_get_table_info(s_AppAssemblyImage, MONO_TABLE_TYPEDEF); + int rows = mono_image_get_table_rows(s_AppAssemblyImage, MONO_TABLE_TYPEDEF); + + for (int i = 0; i < rows; i++) + { + uint32_t cols[MONO_TYPEDEF_SIZE]; + mono_metadata_decode_row(tableInfo, i, cols, MONO_TYPEDEF_SIZE); + + // 获取类名和命名空间 + const char* name = mono_metadata_string_heap(s_AppAssemblyImage, cols[MONO_TYPEDEF_NAME]); + const char* nameSpace = mono_metadata_string_heap(s_AppAssemblyImage, cols[MONO_TYPEDEF_NAMESPACE]); + + if (!name || strlen(name) == 0) continue; + + // 构建全名 + std::string fullName; + if (nameSpace && strlen(nameSpace) > 0) + fullName = std::string(nameSpace) + "." + name; + else + fullName = name; + + s_AvailableScripts.push_back(fullName); + PM_CORE_DEBUG("Script Class: {}", fullName); + } + } + + const std::vector& ScriptEngine::GetAvailableScripts() + { + return s_AvailableScripts; + } + void ScriptEngine::OnImGuiRender() { ImGui::Begin("Script Engine Debug"); diff --git a/Prism/src/Prism/Script/ScriptEngine.h b/Prism/src/Prism/Script/ScriptEngine.h index 1ba7232..d2e4fd4 100644 --- a/Prism/src/Prism/Script/ScriptEngine.h +++ b/Prism/src/Prism/Script/ScriptEngine.h @@ -150,8 +150,15 @@ namespace Prism static EntityInstanceMap& GetEntityInstanceMap(); static EntityInstanceData& GetEntityInstanceData(UUID sceneID, UUID entityID); + // GetAll Script Clas s + static const std::vector& GetAvailableScripts(); + static void RefreshAvailableScripts(); + // Debug static void OnImGuiRender(); + + private: + static std::vector s_AvailableScripts; }; } diff --git a/Prism/src/Prism/Script/ScriptEngineRegistry.cpp b/Prism/src/Prism/Script/ScriptEngineRegistry.cpp index bfc7d76..2d3b3fb 100644 --- a/Prism/src/Prism/Script/ScriptEngineRegistry.cpp +++ b/Prism/src/Prism/Script/ScriptEngineRegistry.cpp @@ -49,6 +49,8 @@ namespace Prism { InitComponentTypes(); + mono_add_internal_call("Prism.Debug::Log_Native", (const void*)Prism::Script::Prism_Log_Native); + mono_add_internal_call("Prism.Noise::PerlinNoise_Native", (const void*)Prism::Script::Prism_Noise_PerlinNoise); mono_add_internal_call("Prism.Physics::Raycast_Native", (const void*)Prism::Script::Prism_Physics_Raycast); diff --git a/Prism/src/Prism/Script/ScriptWrappers.cpp b/Prism/src/Prism/Script/ScriptWrappers.cpp index fcd6032..0831387 100644 --- a/Prism/src/Prism/Script/ScriptWrappers.cpp +++ b/Prism/src/Prism/Script/ScriptWrappers.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "Prism/Core/Input.h" #include "Prism/Core/Math/Noise.h" @@ -32,6 +33,24 @@ namespace Prism { namespace Script { SpriteRenderer = 4 }; + //////////////////////////////////////////////////////////////// + // Debug //////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////// + + void Prism_Log_Native(MonoString* message) + { + if (message) + { + char* utf8 = mono_string_to_utf8(message); + if (utf8) + { + PM_CLIENT_INFO("[c#]: {}", utf8); + mono_free(utf8); + } + } + } + + //////////////////////////////////////////////////////////////// // Math //////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// diff --git a/Prism/src/Prism/Script/ScriptWrappers.h b/Prism/src/Prism/Script/ScriptWrappers.h index c44e60b..d4b2183 100644 --- a/Prism/src/Prism/Script/ScriptWrappers.h +++ b/Prism/src/Prism/Script/ScriptWrappers.h @@ -26,6 +26,9 @@ namespace Prism { namespace Script { }; */ + // Debug + void Prism_Log_Native(MonoString* message); + // Math float Prism_Noise_PerlinNoise(float x, float y); diff --git a/PrismRuntime/CMakeLists.txt b/PrismRuntime/CMakeLists.txt new file mode 100644 index 0000000..0933b45 --- /dev/null +++ b/PrismRuntime/CMakeLists.txt @@ -0,0 +1,11 @@ +project(PrismRuntime) + +file(GLOB_RECURSE SRC_SOURCE ./PrismRuntime/**.cpp) + +add_executable(${PROJECT_NAME} WIN32 ${SRC_SOURCE}) +target_compile_definitions(${PROJECT_NAME} PRIVATE PRISM_GUI) +target_link_libraries(${PROJECT_NAME} PRIVATE Prism-static) + + +add_executable(${PROJECT_NAME}-Console ${SRC_SOURCE}) +target_link_libraries(${PROJECT_NAME}-Console PRIVATE Prism-static) diff --git a/PrismRuntime/PrismRuntime/PrismRuntime.cpp b/PrismRuntime/PrismRuntime/PrismRuntime.cpp new file mode 100644 index 0000000..a764645 --- /dev/null +++ b/PrismRuntime/PrismRuntime/PrismRuntime.cpp @@ -0,0 +1,63 @@ +// +// Created by Atdunbg on 2026/3/23. +// + +#include "PrismRuntime.h" + +#include "Prism/Renderer/Renderer.h" +#include "Prism/Renderer/SceneRenderer.h" +#include "Prism/Scene/SceneSerializer.h" + + +void PrismRuntime::OnAttach() +{ + PM_CLIENT_INFO("App init"); + + AppInstance = &Prism::Application::Get(); + + PM_CLIENT_INFO("Create Scene"); + const Prism::Ref newScene = Prism::Ref::Create("runtime Scene", false, true); + Prism::SceneSerializer serializer(newScene); + + const char* scenePath = "assets/scenes/FPS.scene"; + PM_CLIENT_INFO("loading Scene: ", scenePath); + serializer.Deserialize(scenePath); + + m_CurrentScene = newScene; + + const glm::ivec2 windowSize = AppInstance->GetWindow().GetSize(); + if (m_CurrentScene && windowSize.x > 0 && windowSize.y > 0) + { + Prism::SceneRenderer::SetViewportSize(windowSize.x, windowSize.y); + m_CurrentScene->SetViewportSize(windowSize); + } + + PM_CLIENT_INFO("Scene Start"); + m_CurrentScene->OnRuntimeStart(); +} + +void PrismRuntime::OnDetach() +{ + PM_CLIENT_INFO("Scene Shutdown"); + m_CurrentScene->OnShutdown(); +} + +void PrismRuntime::OnUpdate(const Prism::TimeStep deltaTime) +{ + m_CurrentScene->OnUpdate(deltaTime); + m_CurrentScene->OnRenderRuntime(deltaTime); + + const glm::vec2 windowSize = AppInstance->GetWindow().GetSize(); + if (m_CurrentScene && windowSize.x > 0 && windowSize.y > 0) + { + m_CurrentScene->SetViewportSize(windowSize); + } +} + +void PrismRuntime::OnEvent(Prism::Event& e) +{ +} + +void PrismRuntime::OnImGuiRender() +{ +} diff --git a/PrismRuntime/PrismRuntime/PrismRuntime.h b/PrismRuntime/PrismRuntime/PrismRuntime.h new file mode 100644 index 0000000..628e67d --- /dev/null +++ b/PrismRuntime/PrismRuntime/PrismRuntime.h @@ -0,0 +1,30 @@ +// +// Created by Atdunbg on 2026/3/23. +// + +#ifndef PRISM_PRISMRUNTIME_H +#define PRISM_PRISMRUNTIME_H +#include "Prism/Core/Application.h" +#include "Prism/Core/Layer.h" +#include "Prism/Scene/Scene.h" + + +class PrismRuntime : public Prism::Layer +{ +public: + void OnAttach() override; + void OnDetach() override; + + void OnUpdate(Prism::TimeStep deltaTime) override; + void OnEvent(Prism::Event& e) override; + void OnImGuiRender() override; + + +private: + Prism::Ref m_CurrentScene; + + Prism::Application* AppInstance = nullptr; +}; + + +#endif //PRISM_PRISMRUNTIME_H \ No newline at end of file diff --git a/PrismRuntime/PrismRuntime/PrismRuntimeApp.cpp b/PrismRuntime/PrismRuntime/PrismRuntimeApp.cpp new file mode 100644 index 0000000..58acbca --- /dev/null +++ b/PrismRuntime/PrismRuntime/PrismRuntimeApp.cpp @@ -0,0 +1,25 @@ +// +// Created by Atdunbg on 2026/3/23. +// +#include "Prism.h" +#include "PrismRuntime.h" +#include "Prism/Core/EntryPoint.h" + +class PrismRuntimeApp : public Prism::Application +{ +public: + explicit PrismRuntimeApp(const Prism::ApplicationProps& props) + : Application(props) + { + } + + virtual void OnInit() override + { + PushLayer(new PrismRuntime()); + } +}; + +Prism::Application* Prism::CreateApplication(const CommandArgs args) +{ + return new PrismRuntimeApp({"Game", 1920, 1080, args}); +}