add simple runtime; fix the issue of crashing when creating file and folder; some tweaks
This commit is contained in:
@ -23,4 +23,5 @@ endif ()
|
||||
|
||||
add_subdirectory(Prism)
|
||||
add_subdirectory(Sandbox)
|
||||
add_subdirectory(Editor)
|
||||
add_subdirectory(Editor)
|
||||
add_subdirectory(PrismRuntime)
|
||||
|
||||
@ -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})
|
||||
|
||||
|
||||
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
336
Editor/assets/scenes/FPS.scene
Normal file
336
Editor/assets/scenes/FPS.scene
Normal file
@ -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:
|
||||
[]
|
||||
@ -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:
|
||||
[]
|
||||
@ -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:
|
||||
[]
|
||||
@ -4,6 +4,7 @@
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<InvariantGlobalization>true</InvariantGlobalization>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@ -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<Transform>();
|
||||
Console.WriteLine($"C# size of Transform: {size}");
|
||||
}
|
||||
|
||||
void OnUpdate(float ts)
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
<RootNamespace>Prism_ScriptCore</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<InvariantGlobalization>true</InvariantGlobalization>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
15
Prism-ScriptCore/Src/Prism/Engine/Engine.cs
Normal file
15
Prism-ScriptCore/Src/Prism/Engine/Engine.cs
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -132,25 +132,6 @@ namespace Prism
|
||||
return assetHandle != 0 && s_LoadedAssets.find(assetHandle) != s_LoadedAssets.end();
|
||||
}
|
||||
|
||||
void AssetsManager::Rename(Ref<Asset>& 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 <typename T>
|
||||
Ref<T> AssetsManager::GetAsset(AssetHandle assetHandle, bool loadData)
|
||||
{
|
||||
@ -383,41 +364,29 @@ namespace Prism
|
||||
break;
|
||||
case FileSystemAction::Rename:
|
||||
{
|
||||
Ref<Asset> asset;
|
||||
|
||||
for (auto it = s_LoadedAssets.begin(); it != s_LoadedAssets.end(); it++)
|
||||
Ref<Asset> 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:
|
||||
|
||||
@ -45,7 +45,6 @@ namespace Prism
|
||||
static AssetHandle GetAssetHandleFromFilePath(const std::string& filepath);
|
||||
static bool IsAssetHandleValid(const AssetHandle& assetHandle);
|
||||
|
||||
static void Rename(Ref<Asset>& asset, const std::string& newName);
|
||||
|
||||
static Ref<PhysicsMaterial> CreateAssetPhysicsMaterial(const std::string& filename, AssetType type, const AssetHandle& directoryHandle, float v1, float v2, float v3);
|
||||
|
||||
|
||||
@ -36,7 +36,6 @@ namespace Prism
|
||||
m_Window = std::unique_ptr<Window>(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();
|
||||
}
|
||||
|
||||
@ -12,7 +12,19 @@
|
||||
|
||||
extern Prism::Application* Prism::CreateApplication(CommandArgs args);
|
||||
|
||||
#ifdef PRISM_GUI
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -24,7 +24,6 @@ namespace Prism
|
||||
static std::shared_ptr<spdlog::logger> s_CoreLogger;
|
||||
static std::shared_ptr<spdlog::logger> 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__)
|
||||
|
||||
@ -21,7 +21,7 @@ namespace Prism
|
||||
operator float() { return m_Time; }
|
||||
|
||||
private:
|
||||
float m_Time;
|
||||
float m_Time = 0.0f;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include "Ref.h"
|
||||
#include "Events/Event.h"
|
||||
#include "Prism/Core/Core.h"
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
|
||||
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<uint32_t, uint32_t> GetSize() const = 0;
|
||||
virtual std::pair<float, float> 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;
|
||||
|
||||
@ -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<Directory>(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;
|
||||
|
||||
@ -1090,18 +1090,33 @@ namespace Prism
|
||||
});
|
||||
|
||||
DrawComponent<ScriptComponent>("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))
|
||||
{
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -230,4 +230,12 @@ namespace Prism
|
||||
glBindTextureUnit(slot, instance->m_ColorAttachments[attachmentIndex]);
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::BindDepthTexture(uint32_t slot) const
|
||||
{
|
||||
Ref<const OpenGLFrameBuffer> instance = this;
|
||||
Renderer::Submit([instance, slot]() {
|
||||
glBindTextureUnit(slot, instance->m_DepthAttachment);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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; }
|
||||
|
||||
@ -186,7 +186,7 @@ namespace Prism
|
||||
});
|
||||
}
|
||||
|
||||
void OpenGLTexture2D::SetData(const void* data, int count)
|
||||
void OpenGLTexture2D::SetData(const void* data, uint32_t count)
|
||||
{
|
||||
Lock();
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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; // 稍后根据实际情况判断
|
||||
|
||||
@ -62,7 +62,7 @@ namespace Prism
|
||||
m_Data.VSync = enable;
|
||||
}
|
||||
|
||||
std::pair<float, float> 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)
|
||||
{
|
||||
|
||||
@ -27,8 +27,8 @@ namespace Prism
|
||||
|
||||
bool const IsVSync() const override { return m_Data.VSync; }
|
||||
void SetVSync(bool enable) override;
|
||||
virtual std::pair<uint32_t, uint32_t> GetSize() const override { return { m_Data.Width, m_Data.Height }; }
|
||||
virtual std::pair<float, float> 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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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<FrameBuffer> src, Ref<FrameBuffer> 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<RenderPass>& 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<RenderPass>& 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<float>(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<glm::vec3> GetFrustumCornersWorldSpace(const SceneRendererCamera& sceneCamera)
|
||||
{
|
||||
std::vector<glm::vec3> corners(8);
|
||||
@ -1424,4 +1262,5 @@ namespace Prism
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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); // 过滤器
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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>& environment)
|
||||
: SceneEnvironment(environment)
|
||||
|
||||
@ -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<TransformComponent>().connect<&Physics2D::OnTransformConstruct>();
|
||||
@ -56,10 +51,11 @@ namespace Prism
|
||||
Physics3D::CreateScene();
|
||||
}
|
||||
|
||||
Init();
|
||||
Init(runtime);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Scene::~Scene()
|
||||
{
|
||||
m_Registry.on_destroy<ScriptComponent>().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<Texture2D>("assets/editor/Camera.png");
|
||||
m_LightIcon = AssetsManager::GetAsset<Texture2D>("assets/editor/light.png");
|
||||
|
||||
if (!runtime)
|
||||
{
|
||||
m_CameraIcon = AssetsManager::GetAsset<Texture2D>("assets/editor/Camera.png");
|
||||
m_LightIcon = AssetsManager::GetAsset<Texture2D>("assets/editor/light.png");
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::OnShutdown()
|
||||
{
|
||||
b2DestroyWorld(m_Registry.get<Box2DWorldComponent>(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;
|
||||
|
||||
@ -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<Environment>& GetEnvironment() const { return m_Environment; }
|
||||
|
||||
@ -260,9 +260,15 @@ namespace Prism
|
||||
|
||||
const auto mesh = entity.GetComponent<MeshComponent>().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<SkyLightComponent>();
|
||||
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<MeshColliderComponent>();
|
||||
|
||||
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<std::string>();
|
||||
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<std::string>();
|
||||
assetHandle = AssetsManager::GetAssetHandleFromFilePath(filepath);
|
||||
const auto assetFilePath = skyLightComponent["EnvironmentAssetPath"].as<std::string>();
|
||||
assetHandle = AssetsManager::GetAssetHandleFromFilePath(assetFilePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1055,8 +1100,16 @@ namespace Prism
|
||||
if (material && AssetsManager::IsAssetHandleValid(material.as<uint64_t>()))
|
||||
{
|
||||
component.Material = AssetsManager::GetAsset<PhysicsMaterial>(material.as<uint64_t>());
|
||||
}else
|
||||
{
|
||||
const auto materialPath = boxColliderComponent["MaterialPath"].as<std::string>();
|
||||
if (const auto assetId = AssetsManager::GetAssetHandleFromFilePath(materialPath); assetId != 0)
|
||||
{
|
||||
component.Material = AssetsManager::GetAsset<PhysicsMaterial>(assetId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
component.DebugMesh = MeshFactory::CreateBox(component.Size);
|
||||
}
|
||||
|
||||
@ -1068,7 +1121,17 @@ namespace Prism
|
||||
|
||||
auto material = sphereColliderComponent["Material"];
|
||||
if (material && AssetsManager::IsAssetHandleValid(material.as<uint64_t>()))
|
||||
{
|
||||
component.Material = AssetsManager::GetAsset<PhysicsMaterial>(material.as<uint64_t>());
|
||||
}else
|
||||
{
|
||||
const auto materialPath = sphereColliderComponent["MaterialPath"].as<std::string>();
|
||||
if (const auto assetId = AssetsManager::GetAssetHandleFromFilePath(materialPath); assetId != 0)
|
||||
{
|
||||
component.Material = AssetsManager::GetAsset<PhysicsMaterial>(assetId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
component.DebugMesh = MeshFactory::CreateSphere(component.Radius);
|
||||
}
|
||||
@ -1082,7 +1145,16 @@ namespace Prism
|
||||
|
||||
auto material = capsuleColliderComponent["Material"];
|
||||
if (material && AssetsManager::IsAssetHandleValid(material.as<uint64_t>()))
|
||||
{
|
||||
component.Material = AssetsManager::GetAsset<PhysicsMaterial>(material.as<uint64_t>());
|
||||
}else
|
||||
{
|
||||
const auto materialPath = capsuleColliderComponent["MaterialPath"].as<std::string>();
|
||||
if (const auto assetId = AssetsManager::GetAssetHandleFromFilePath(materialPath); assetId != 0)
|
||||
{
|
||||
component.Material = AssetsManager::GetAsset<PhysicsMaterial>(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<std::string>();
|
||||
assetID = AssetsManager::GetAssetHandleFromFilePath(filepath);
|
||||
const auto assetFilePath = meshColliderComponent["AssetPath"].as<std::string>();
|
||||
assetID = AssetsManager::GetAssetHandleFromFilePath(assetFilePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
assetID = meshComponent["AssetID"].as<uint64_t>();
|
||||
assetID = meshColliderComponent["AssetID"].as<uint64_t>();
|
||||
}
|
||||
|
||||
if (AssetsManager::IsAssetHandleValid(assetID))
|
||||
@ -1116,16 +1188,33 @@ namespace Prism
|
||||
component.IsTrigger = meshColliderComponent["IsTrigger"] ? meshColliderComponent["IsTrigger"].as<bool>() : false;
|
||||
component.OverrideMesh = overrideMesh;
|
||||
|
||||
auto material = meshColliderComponent["Material"];
|
||||
if (material && AssetsManager::IsAssetHandleValid(material.as<uint64_t>()))
|
||||
if (meshColliderComponent["Material"])
|
||||
{
|
||||
component.Material = AssetsManager::GetAsset<PhysicsMaterial>(material.as<uint64_t>());
|
||||
auto material = meshColliderComponent["Material"];
|
||||
if (material && AssetsManager::IsAssetHandleValid(material.as<uint64_t>()))
|
||||
{
|
||||
component.Material = AssetsManager::GetAsset<PhysicsMaterial>(material.as<uint64_t>());
|
||||
|
||||
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<std::string>();
|
||||
if (const auto assetId = AssetsManager::GetAssetHandleFromFilePath(materialPath); assetId != 0)
|
||||
{
|
||||
component.Material = AssetsManager::GetAsset<PhysicsMaterial>(assetId);
|
||||
|
||||
if (component.IsConvex)
|
||||
PhysicsWrappers::CreateConvexMesh(component, deserializedEntity.Transform().Scale);
|
||||
else
|
||||
PhysicsWrappers::CreateTriangleMesh(component, deserializedEntity.Transform().Scale);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
//
|
||||
|
||||
#include "ScriptEngine.h"
|
||||
#include <cstddef>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
@ -35,6 +36,10 @@ namespace Prism
|
||||
MonoImage* s_AppAssemblyImage = nullptr;
|
||||
MonoImage* s_CoreAssemblyImage = nullptr;
|
||||
|
||||
|
||||
|
||||
std::vector<std::string> ScriptEngine::s_AvailableScripts;
|
||||
|
||||
#ifdef ENABLE_MONO_DEBUG
|
||||
static bool s_EnableMonoPDBDebug = true;
|
||||
#else
|
||||
@ -87,6 +92,7 @@ namespace Prism
|
||||
static std::unordered_map<std::string, EntityScriptClass> 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<std::string>& ScriptEngine::GetAvailableScripts()
|
||||
{
|
||||
return s_AvailableScripts;
|
||||
}
|
||||
|
||||
void ScriptEngine::OnImGuiRender()
|
||||
{
|
||||
ImGui::Begin("Script Engine Debug");
|
||||
|
||||
@ -150,8 +150,15 @@ namespace Prism
|
||||
static EntityInstanceMap& GetEntityInstanceMap();
|
||||
static EntityInstanceData& GetEntityInstanceData(UUID sceneID, UUID entityID);
|
||||
|
||||
// GetAll Script Clas s
|
||||
static const std::vector<std::string>& GetAvailableScripts();
|
||||
static void RefreshAvailableScripts();
|
||||
|
||||
// Debug
|
||||
static void OnImGuiRender();
|
||||
|
||||
private:
|
||||
static std::vector<std::string> s_AvailableScripts;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include <mono/metadata/object.h>
|
||||
#include <mono/metadata/reflection.h>
|
||||
#include <mono/metadata/appdomain.h>
|
||||
#include <mono/utils/mono-publib.h>
|
||||
|
||||
#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 ////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -26,6 +26,9 @@ namespace Prism { namespace Script {
|
||||
};
|
||||
*/
|
||||
|
||||
// Debug
|
||||
void Prism_Log_Native(MonoString* message);
|
||||
|
||||
// Math
|
||||
float Prism_Noise_PerlinNoise(float x, float y);
|
||||
|
||||
|
||||
11
PrismRuntime/CMakeLists.txt
Normal file
11
PrismRuntime/CMakeLists.txt
Normal file
@ -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)
|
||||
63
PrismRuntime/PrismRuntime/PrismRuntime.cpp
Normal file
63
PrismRuntime/PrismRuntime/PrismRuntime.cpp
Normal file
@ -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<Prism::Scene> newScene = Prism::Ref<Prism::Scene>::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()
|
||||
{
|
||||
}
|
||||
30
PrismRuntime/PrismRuntime/PrismRuntime.h
Normal file
30
PrismRuntime/PrismRuntime/PrismRuntime.h
Normal file
@ -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<Prism::Scene> m_CurrentScene;
|
||||
|
||||
Prism::Application* AppInstance = nullptr;
|
||||
};
|
||||
|
||||
|
||||
#endif //PRISM_PRISMRUNTIME_H
|
||||
25
PrismRuntime/PrismRuntime/PrismRuntimeApp.cpp
Normal file
25
PrismRuntime/PrismRuntime/PrismRuntimeApp.cpp
Normal file
@ -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});
|
||||
}
|
||||
Reference in New Issue
Block a user