Merge branch 'main' into SP3-1-Rendering

This commit is contained in:
Brandon Mak 2022-11-14 15:38:33 +08:00
commit ac17721363
190 changed files with 9579 additions and 8863 deletions

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1,55 @@
Name: HouseModular
ID: 75328301
Type: 4
Sub Assets:
Name: FloorLarge
ID: 142812576
Type: 8
Name: FloorSmall
ID: 139921228
Type: 8
Name: FloorLong
ID: 136991843
Type: 8
Name: Pillar
ID: 150352316
Type: 8
Name: WallEnd
ID: 139594893
Type: 8
Name: WallCorner
ID: 134714737
Type: 8
Name: WallDefault
ID: 140834166
Type: 8
Name: WallLarge
ID: 142689599
Type: 8
Name: WallDiagonal
ID: 144002377
Type: 8
Name: WallTBlock
ID: 149359798
Type: 8
Name: WindowLarge
ID: 148351779
Type: 8
Name: WindowSmallOpened
ID: 149786048
Type: 8
Name: WindowSmallClosed
ID: 147863396
Type: 8
Name: WindowLargeOpen
ID: 138781993
Type: 8
Name: WallDoorHole
ID: 150924328
Type: 8
Name: Door
ID: 147152385
Type: 8
Name: DoorFrame
ID: 146862321
Type: 8

View File

@ -1,10 +1,10 @@
- EID: 0 - EID: 0
Name: Default Name: Camera
IsActive: true IsActive: true
NumberOfChildren: 0 NumberOfChildren: 0
Components: Components:
Camera Component: Camera Component:
Position: {x: 0, y: 0, z: 0} Position: {x: 0, y: 0, z: 8}
Pitch: 0 Pitch: 0
Yaw: 0 Yaw: 0
Roll: 0 Roll: 0
@ -22,7 +22,7 @@
Strength: 0 Strength: 0
Scripts: ~ Scripts: ~
- EID: 1 - EID: 1
Name: Default Name: Floor
IsActive: true IsActive: true
NumberOfChildren: 0 NumberOfChildren: 0
Components: Components:
@ -36,8 +36,8 @@
RigidBody Component: RigidBody Component:
Type: Static Type: Static
Mass: 1 Mass: 1
Drag: 0 Drag: 0.00999999978
Angular Drag: 0 Angular Drag: 0.00999999978
Use Gravity: true Use Gravity: true
Interpolate: true Interpolate: true
Freeze Position X: false Freeze Position X: false
@ -50,24 +50,21 @@
Colliders: Colliders:
- Is Trigger: false - Is Trigger: false
Type: Box Type: Box
Half Extents: {x: 24.7399445, y: 0.25, z: 8.75} Half Extents: {x: 1, y: 1, z: 1}
Friction: 0.400000006 Friction: 0.400000006
Bounciness: 0 Bounciness: 0
Density: 1 Density: 1
Position Offset: {x: 0, y: 0, z: 0} Position Offset: {x: 0, y: 0, z: 0}
Scripts: ~ Scripts: ~
- EID: 2 - EID: 10
Name: Player Name: Default
IsActive: true IsActive: true
NumberOfChildren: 3 NumberOfChildren: 0
Components: Components:
Transform Component: Transform Component:
Translate: {x: -3.06177855, y: -2, z: -5} Translate: {x: -4.40482807, y: 2.57871056, z: -5.21213436}
Rotate: {x: -0, y: 0, z: -0} Rotate: {x: -0.361265004, y: 1.11661232, z: -0.626627684}
Scale: {x: 2, y: 2, z: 2} Scale: {x: 0.999982238, y: 0.999987125, z: 0.999981165}
Renderable Component:
Mesh: 149697411
Material: 126974645
RigidBody Component: RigidBody Component:
Type: Dynamic Type: Dynamic
Mass: 1 Mass: 1
@ -89,26 +86,10 @@
Friction: 0.400000006 Friction: 0.400000006
Bounciness: 0 Bounciness: 0
Density: 1 Density: 1
Position Offset: {x: 0, y: 0.5, z: 0} Position Offset: {x: 0, y: 0, z: 0}
Scripts: Scripts: ~
- Type: PlayerController
drag: 2
currentState: 0
maxMoveVel: 2
moveForce: 50
sprintMultiplier: 2
rotationFactorPerFrame: 1
maxJumpHeight: 4
maxJumpTime: 0.75
fallMultipler: 2
lightMultiper: 0.75
mediumMultiper: 0.5
heavyMultiper: 0.25
- Type: PickAndThrow
throwForce: [200, 300, 200]
item: 5
- EID: 3 - EID: 3
Name: Default Name: Empty
IsActive: true IsActive: true
NumberOfChildren: 0 NumberOfChildren: 0
Components: Components:
@ -118,7 +99,7 @@
Scale: {x: 1, y: 1, z: 1} Scale: {x: 1, y: 1, z: 1}
Scripts: ~ Scripts: ~
- EID: 4 - EID: 4
Name: Default Name: Empty2
IsActive: true IsActive: true
NumberOfChildren: 0 NumberOfChildren: 0
Components: Components:
@ -126,14 +107,9 @@
Translate: {x: 0, y: 0, z: 0} Translate: {x: 0, y: 0, z: 0}
Rotate: {x: 0, y: 0, z: 0} Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1} Scale: {x: 1, y: 1, z: 1}
Scripts: Scripts: ~
- Type: SHADE_Scripting.ThirdPersonCamera
armLength: 2
turnSpeedPitch: 0.300000012
turnSpeedYaw: 0.5
pitchClamp: 45
- EID: 9 - EID: 9
Name: Default Name: Bag
IsActive: true IsActive: true
NumberOfChildren: 0 NumberOfChildren: 0
Components: Components:
@ -145,6 +121,67 @@
Mesh: 144838771 Mesh: 144838771
Material: 123745521 Material: 123745521
Scripts: ~ Scripts: ~
- EID: 6
Name: AI
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: -8, y: -2, z: 2.5}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1}
Renderable Component:
Mesh: 149697411
Material: 126974645
RigidBody Component:
Type: Dynamic
Mass: 1
Drag: 0
Angular Drag: 0
Use Gravity: true
Interpolate: false
Freeze Position X: false
Freeze Position Y: false
Freeze Position Z: false
Freeze Rotation X: true
Freeze Rotation Y: true
Freeze Rotation Z: true
Collider Component:
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 0.5, y: 0.5, z: 0.5}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0.5, z: 0}
Scripts: ~
- EID: 7
Name: BigBoi
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: -16.8647861, z: -14.039052}
Rotate: {x: -0, y: 0, z: -0}
Scale: {x: 28.1434975, y: 28.1434975, z: 28.1434975}
Renderable Component:
Mesh: 149697411
Material: 126974645
Scripts: ~
- EID: 8
Name: AmbientLight
IsActive: true
NumberOfChildren: 0
Components:
Light Component:
Position: {x: 0, y: 0, z: 0}
Type: Ambient
Direction: {x: 0, y: 0, z: 1}
Color: {x: 1, y: 1, z: 1, w: 1}
Layer: 4294967295
Strength: 0.25
Scripts: ~
- EID: 5 - EID: 5
Name: item Name: item
IsActive: true IsActive: true
@ -189,71 +226,6 @@
Scripts: Scripts:
- Type: Item - Type: Item
currCategory: 0 currCategory: 0
- EID: 6 - Type: PickAndThrow
Name: AI throwForce: [100, 200, 100]
IsActive: true item: 51000
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: -8, y: -2, z: 2.5}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1}
Renderable Component:
Mesh: 149697411
Material: 126974645
RigidBody Component:
Type: Dynamic
Mass: 1
Drag: 0
Angular Drag: 0
Use Gravity: true
Interpolate: false
Freeze Position X: false
Freeze Position Y: false
Freeze Position Z: false
Freeze Rotation X: true
Freeze Rotation Y: true
Freeze Rotation Z: true
Collider Component:
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 0.5, y: 0.5, z: 0.5}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0.5, z: 0}
Scripts:
- Type: AIPrototype
movementForceMultiplier: 100
patrolSpeed: 0.400000006
chaseSpeed: 0.800000012
distanceToCapture: 1.20000005
distanceToStartChase: 2
distanceToEndChase: 2.5
- EID: 7
Name: Default
IsActive: true
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: 0, y: -16.8647861, z: -14.039052}
Rotate: {x: -0, y: 0, z: -0}
Scale: {x: 28.1434975, y: 28.1434975, z: 28.1434975}
Renderable Component:
Mesh: 149697411
Material: 126974645
Scripts: ~
- EID: 8
Name: Default
IsActive: true
NumberOfChildren: 0
Components:
Light Component:
Position: {x: 0, y: 0, z: 0}
Type: Ambient
Direction: {x: 0, y: 0, z: 1}
Color: {x: 1, y: 1, z: 1, w: 1}
Layer: 4294967295
Strength: 0.25
Scripts: ~

View File

@ -51,7 +51,6 @@ public class AIPrototype : Script
private GameObject? player; private GameObject? player;
public AIPrototype(GameObject gameObj) : base(gameObj) { }
protected override void awake() protected override void awake()
{ {

View File

@ -0,0 +1,3 @@
Name: AIPrototype
ID: 163215061
Type: 9

View File

@ -7,7 +7,6 @@ namespace SHADE_Scripting
{ {
public float turnSpeed = 0.5f; public float turnSpeed = 0.5f;
public CameraControl(GameObject go) : base(go) { }
protected override void update() protected override void update()
{ {
//Camera //Camera

View File

@ -0,0 +1,3 @@
Name: CameraControl
ID: 158782344
Type: 9

View File

@ -3,7 +3,6 @@ using System;
public class CameraFix : Script public class CameraFix : Script
{ {
public CameraFix(GameObject gameObj) : base(gameObj) { }
private Transform tranform; private Transform tranform;
public Vector3 pos = Vector3.Zero; public Vector3 pos = Vector3.Zero;

View File

@ -0,0 +1,3 @@
Name: CameraFix
ID: 162231964
Type: 9

View File

@ -10,7 +10,6 @@ public class Item : Script
} }
public ItemCategory currCategory; public ItemCategory currCategory;
public Item(GameObject gameObj) : base(gameObj) { }
protected override void awake() protected override void awake()
{ {

View File

@ -0,0 +1,3 @@
Name: Item
ID: 163145289
Type: 9

View File

@ -8,7 +8,6 @@ public class PhysicsTest : Script
private Transform Transform; private Transform Transform;
private RigidBody RigidBody; private RigidBody RigidBody;
private Collider Collider; private Collider Collider;
public PhysicsTest(GameObject gameObj) : base(gameObj) { }
protected override void awake() protected override void awake()
{ {

View File

@ -0,0 +1,3 @@
Name: PhysicsTest
ID: 159771801
Type: 9

View File

@ -14,7 +14,6 @@ public class PickAndThrow : Script
private float lastXDir; private float lastXDir;
private float lastZDir; private float lastZDir;
private bool inRange = false; private bool inRange = false;
public PickAndThrow(GameObject gameObj) : base(gameObj) { }
protected override void awake() protected override void awake()
{ {

View File

@ -0,0 +1,3 @@
Name: PickAndThrow
ID: 165331952
Type: 9

View File

@ -73,8 +73,6 @@ public class PlayerController : Script
public float mediumMultiper = 0.5f; public float mediumMultiper = 0.5f;
public float heavyMultiper = 0.25f; public float heavyMultiper = 0.25f;
public PlayerController(GameObject gameObj) : base(gameObj) { }
protected override void awake() protected override void awake()
{ {
//default setup //default setup

View File

@ -0,0 +1,3 @@
Name: PlayerController
ID: 164563088
Type: 9

View File

@ -2,8 +2,6 @@
public class PrintWhenActive : Script public class PrintWhenActive : Script
{ {
public PrintWhenActive(GameObject gameObj) : base(gameObj) { }
protected override void update() protected override void update()
{ {
Debug.Log("Active!"); Debug.Log("Active!");

View File

@ -0,0 +1,3 @@
Name: PrintWhenActive
ID: 162536221
Type: 9

View File

@ -1,5 +1,6 @@
using SHADE; using SHADE;
using System; using System;
using System.Collections.Generic;
public class RaccoonShowcase : Script public class RaccoonShowcase : Script
{ {
@ -17,7 +18,11 @@ public class RaccoonShowcase : Script
private double rotation = 0.0; private double rotation = 0.0;
private Vector3 scale = Vector3.Zero; private Vector3 scale = Vector3.Zero;
private double originalScale = 1.0f; private double originalScale = 1.0f;
public RaccoonShowcase(GameObject gameObj) : base(gameObj) {} [Tooltip("Sample list of Vector3s.")]
public List<Vector3> vecList = new List<Vector3>(new Vector3[] { new Vector3(1, 2, 3), new Vector3(4, 5, 6) });
[Range(-5, 5)]
public List<int> intList = new List<int>(new int[] { 2, 8, 2, 6, 8, 0, 1 });
public List<Light.Type> enumList = new List<Light.Type>(new Light.Type[] { Light.Type.Point, Light.Type.Directional, Light.Type.Ambient });
protected override void awake() protected override void awake()
{ {
@ -27,6 +32,11 @@ public class RaccoonShowcase : Script
Debug.LogError("Transform is NULL!"); Debug.LogError("Transform is NULL!");
} }
foreach (var child in Owner)
{
Debug.Log(child.Name);
}
originalScale = Transform.LocalScale.z; originalScale = Transform.LocalScale.z;
} }
protected override void update() protected override void update()
@ -36,4 +46,10 @@ public class RaccoonShowcase : Script
//Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f); //Transform.LocalRotation = new Vector3(0.0f, rotation, 0.0f);
//Transform.LocalScale = new Vector3(System.Math.Abs(System.Math.Sin(scale.x)) * originalScale, System.Math.Abs(System.Math.Cos(scale.y)) * originalScale, System.Math.Abs(System.Math.Sin(scale.z)) * originalScale); //Transform.LocalScale = new Vector3(System.Math.Abs(System.Math.Sin(scale.x)) * originalScale, System.Math.Abs(System.Math.Cos(scale.y)) * originalScale, System.Math.Abs(System.Math.Sin(scale.z)) * originalScale);
} }
protected override void onDrawGizmos()
{
Gizmos.DrawLine(new Vector3(-1.0f, 0.0f, 0.0f), new Vector3(1.0f, 0.0f, 0.0f));
Gizmos.DrawLine(new Vector3(-1.0f, 1.0f, 0.0f), new Vector3(1.0f, 1.0f, 0.0f), Color.Red);
}
} }

View File

@ -0,0 +1,3 @@
Name: RaccoonShowcase
ID: 159969631
Type: 9

View File

@ -8,14 +8,21 @@ public class RaccoonSpin : Script
private float RotateSpeed = 1.0f; private float RotateSpeed = 1.0f;
private float rotation = 0.0f; private float rotation = 0.0f;
[SerializeField] [SerializeField]
private CallbackEvent emptyEvent;
[SerializeField]
private CallbackEvent<int> testEvent; private CallbackEvent<int> testEvent;
[SerializeField] [SerializeField]
private CallbackEvent<int, double, Vector3> testEvent3 = new CallbackEvent<int, double, Vector3>(); private CallbackEvent<int, double, Vector3> testEvent3 = new CallbackEvent<int, double, Vector3>();
private Transform Transform; private Transform Transform;
public RaccoonSpin(GameObject gameObj) : base(gameObj) { }
protected override void awake() protected override void awake()
{ {
emptyEvent = new CallbackEvent();
emptyEvent.RegisterAction(() => Debug.Log("Empty event action!"));
testEvent = new CallbackEvent<int>();
Action<int> action = (x) => Debug.Log($"{x}");
testEvent.RegisterAction(action);
Transform = GetComponent<Transform>(); Transform = GetComponent<Transform>();
if (Transform == null) if (Transform == null)
{ {

View File

@ -0,0 +1,3 @@
Name: RaccoonSpin
ID: 157367824
Type: 9

View File

@ -15,7 +15,6 @@ namespace SHADE_Scripting
public float turnSpeedPitch = 0.3f; public float turnSpeedPitch = 0.3f;
public float turnSpeedYaw = 0.5f; public float turnSpeedYaw = 0.5f;
public float pitchClamp = 45.0f; public float pitchClamp = 45.0f;
public ThirdPersonCamera(GameObject go) : base(go) { }
protected override void awake() protected override void awake()
{ {

View File

@ -0,0 +1,3 @@
Name: ThirdPersonCamera
ID: 154161201
Type: 9

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -24,14 +24,15 @@
#include "Scene/SHSceneManager.h" #include "Scene/SHSceneManager.h"
// Systems // Systems
#include "Scripting/SHScriptEngine.h"
#include "Physics/SHPhysicsSystem.h"
#include "Math/Transform/SHTransformSystem.h"
#include "Input/SHInputManager.h"
#include "FRC/SHFramerateController.h"
#include "AudioSystem/SHAudioSystem.h" #include "AudioSystem/SHAudioSystem.h"
#include "Camera/SHCameraSystem.h" #include "Camera/SHCameraSystem.h"
#include "FRC/SHFramerateController.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h" #include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
#include "Input/SHInputManager.h"
#include "Math/Transform/SHTransformSystem.h"
#include "Physics/System/SHPhysicsSystem.h"
#include "Physics/System/SHPhysicsDebugDrawSystem.h"
#include "Scripting/SHScriptEngine.h"
// Components // Components
#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h"
@ -39,7 +40,6 @@
#include "Scenes/SBTestScene.h" #include "Scenes/SBTestScene.h"
#include "Assets/SHAssetManager.h" #include "Assets/SHAssetManager.h"
#include "Scenes/SBMainScene.h" #include "Scenes/SBMainScene.h"
#include "Serialization/Configurations/SHConfigurationManager.h" #include "Serialization/Configurations/SHConfigurationManager.h"
@ -67,16 +67,21 @@ namespace Sandbox
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow, wndData); window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow, wndData);
// Create Systems // Create Systems
SHSystemManager::CreateSystem<SHGraphicsSystem>();
SHSystemManager::CreateSystem<SHScriptEngine>(); SHSystemManager::CreateSystem<SHScriptEngine>();
SHSystemManager::CreateSystem<SHPhysicsSystem>();
SHSystemManager::CreateSystem<SHTransformSystem>(); SHSystemManager::CreateSystem<SHTransformSystem>();
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>()); SHSystemManager::CreateSystem<SHPhysicsSystem>();
SHSystemManager::CreateSystem<SHPhysicsDebugDrawSystem>();
SHSystemManager::CreateSystem<SHAudioSystem>(); SHSystemManager::CreateSystem<SHAudioSystem>();
SHSystemManager::CreateSystem<SHCameraSystem>(); SHSystemManager::CreateSystem<SHCameraSystem>();
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
SHSystemManager::CreateSystem<SHGraphicsSystem>();
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
// Link up SHDebugDraw // Link up SHDebugDraw
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>()); SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
#ifdef SHEDITOR #ifdef SHEDITOR
@ -101,11 +106,13 @@ namespace Sandbox
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>(); SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>(); SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>(); SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsDebugDraw>();
SHSystemManager::RegisterRoutine<SHPhysicsDebugDrawSystem, SHPhysicsDebugDrawSystem::PhysicsDebugDrawRoutine>();
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>(); SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>(); SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::GizmosDrawRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>(); SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>(); SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
@ -164,7 +171,7 @@ namespace Sandbox
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10)) if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
{ {
drawColliders = !drawColliders; drawColliders = !drawColliders;
SHSystemManager::GetSystem<SHPhysicsSystem>()->SetDrawColliders(drawColliders); SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::COLLIDER, drawColliders);
} }
} }
// Finish all graphics jobs first // Finish all graphics jobs first

View File

@ -10,8 +10,8 @@
#include "Scripting/SHScriptEngine.h" #include "Scripting/SHScriptEngine.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
#include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Interface/SHRigidBodyComponent.h"
#include "Physics/Components/SHColliderComponent.h" #include "Physics/Interface/SHColliderComponent.h"
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h" #include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
#include "Assets/SHAssetManager.h" #include "Assets/SHAssetManager.h"

View File

@ -10,8 +10,8 @@
#include "Scripting/SHScriptEngine.h" #include "Scripting/SHScriptEngine.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
#include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Interface/SHRigidBodyComponent.h"
#include "Physics/Components/SHColliderComponent.h" #include "Physics/Interface/SHColliderComponent.h"
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h" #include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
#include "Assets/SHAssetManager.h" #include "Assets/SHAssetManager.h"
@ -92,7 +92,7 @@ namespace Sandbox
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC); floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
auto* floorBox = floorCollider.AddBoundingBox(); floorCollider.AddBoundingBox();
// Create blank entity with a script // Create blank entity with a script
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>(); //testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
@ -114,8 +114,8 @@ namespace Sandbox
racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f }); racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f });
racoonCollider.AddBoundingBox(); racoonCollider.AddBoundingBox();
racoonCollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f)); racoonCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f));
racoonCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); racoonCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
auto racoonItemLocation = SHEntityManager::CreateEntity<SHTransformComponent>(); auto racoonItemLocation = SHEntityManager::CreateEntity<SHTransformComponent>();
auto& racoonItemLocationTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(racoonItemLocation); auto& racoonItemLocationTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(racoonItemLocation);
@ -140,13 +140,13 @@ namespace Sandbox
itemCollider.AddBoundingBox(); itemCollider.AddBoundingBox();
itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f)); itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f));
itemCollider.GetCollider(1).SetIsTrigger(true); itemCollider.GetCollisionShape(1).SetIsTrigger(true);
itemCollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); itemCollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
itemCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); itemCollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
itemCollider.GetCollider(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); itemCollider.GetCollisionShape(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
itemCollider.GetCollider(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f)); itemCollider.GetCollisionShape(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f));
itemRigidBody.SetInterpolate(false); itemRigidBody.SetInterpolate(false);
itemRigidBody.SetFreezeRotationX(true); itemRigidBody.SetFreezeRotationX(true);
@ -168,8 +168,8 @@ namespace Sandbox
AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f }); AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f });
AICollider.AddBoundingBox(); AICollider.AddBoundingBox();
AICollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f)); AICollider.GetCollisionShape(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
AICollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f)); AICollider.GetCollisionShape(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
AIRigidBody.SetInterpolate(false); AIRigidBody.SetInterpolate(false);
AIRigidBody.SetFreezeRotationX(true); AIRigidBody.SetFreezeRotationX(true);

View File

@ -34,6 +34,99 @@ namespace SHADE
Object TargetObject { get; } Object TargetObject { get; }
} }
/// <summary>
/// Represents a function call that can be serialised and put togetheer with scripts.
/// This variant accepts functions with 0 parameter.
/// </summary>
public class CallbackAction : ICallbackAction
{
#region Properties ------------------------------------------------------------
/// <inheritdoc/>
public Object TargetObject { get; private set; }
/// <inheritdoc/>
public string TargetMethodName => targetMethod == null ? "" : targetMethod.Name;
/// <inheritdoc/>
public bool IsRuntimeAction => targetAction != null;
#endregion
#region Fields ------------------------------------------------------------------
private MethodInfo targetMethod;
private Action targetAction;
private Object[] parameters;
#endregion
#region Constructors ------------------------------------------------------------
/// <summary>
/// Constructs an empty Callback action.
/// </summary>
public CallbackAction() {}
/// <summary>
/// Constructs a CallbackAction that represents a call to the specified static
/// method.
/// </summary>
/// <param name="method">Method to call.</param>
/// <exception cref="ArgumentException">
/// Thrown if a method that is not compatible with the target is specified. The method's
/// source type must match the target's type.
/// </exception>
public CallbackAction(MethodInfo method)
{
// No errors, assign
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[0];
}
/// <summary>
/// Constructs a CallbackAction that represents a call to a specified member
/// method on the specified target.
/// </summary>
/// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param>
/// <exception cref="ArgumentException">
/// Thrown if a method that is not compatible with the target is specified. The method's
/// source type must match the target's type.
/// </exception>
public CallbackAction(Object target, MethodInfo method)
{
// Error Checks
if (method.DeclaringType != target.GetType())
throw new ArgumentException("[CallbackAction] Attempted register an action using an incompatible target object and method.");
// No errors, assign
TargetObject = target;
targetMethod = method;
// Create storage for parameters for calling
parameters = new Object[0];
}
/// <summary>
/// Constructs a Callback action based on an action.
/// </summary>
/// <param name="action">Action that wraps a function to be called.</param>
public CallbackAction(Action action)
{
targetAction = action;
}
#endregion
#region Usage Functions ---------------------------------------------------------
/// <summary>
/// Invokes the CallbackAction's stored method/action with the specified parameters.
/// </summary>
public void Invoke()
{
if (targetAction != null)
{
targetAction.Invoke();
}
else if (targetMethod != null)
{
_ = targetMethod.Invoke(TargetObject, parameters);
}
}
#endregion
}
/// <summary> /// <summary>
/// Represents a function call that can be serialised and put togetheer with scripts. /// Represents a function call that can be serialised and put togetheer with scripts.
/// This variant accepts functions with 1 parameter. /// This variant accepts functions with 1 parameter.

View File

@ -50,12 +50,12 @@ namespace SHADE
Object TargetObject { get; } Object TargetObject { get; }
} }
<# for (int i = 1; i <= max; ++i) { #> <# for (int i = 0; i <= max; ++i) { #>
/// <summary> /// <summary>
/// Represents a function call that can be serialised and put togetheer with scripts. /// Represents a function call that can be serialised and put togetheer with scripts.
/// This variant accepts functions with <#=i#> parameter<# if (i > 1) {#>s<#} #>. /// This variant accepts functions with <#=i#> parameter<# if (i > 1) {#>s<#} #>.
/// </summary> /// </summary>
public class CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> : ICallbackAction public class CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> : ICallbackAction
{ {
#region Properties ------------------------------------------------------------ #region Properties ------------------------------------------------------------
/// <inheritdoc/> /// <inheritdoc/>
@ -68,7 +68,7 @@ namespace SHADE
#region Fields ------------------------------------------------------------------ #region Fields ------------------------------------------------------------------
private MethodInfo targetMethod; private MethodInfo targetMethod;
private Action<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> targetAction; private Action<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> targetAction;
private Object[] parameters; private Object[] parameters;
#endregion #endregion
@ -121,7 +121,7 @@ namespace SHADE
/// Constructs a Callback action based on an action. /// Constructs a Callback action based on an action.
/// </summary> /// </summary>
/// <param name="action">Action that wraps a function to be called.</param> /// <param name="action">Action that wraps a function to be called.</param>
public CallbackAction(Action<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action) public CallbackAction(Action<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action)
{ {
targetAction = action; targetAction = action;
} }

View File

@ -45,6 +45,92 @@ namespace SHADE
IEnumerable<ICallbackAction> Actions { get; } IEnumerable<ICallbackAction> Actions { get; }
} }
/// <summary>
/// A container of CallbackActions that is correlated to a specific scenario as
/// specified by the user of this class.
/// This variant accepts CallbackEvents with 1 generic parameter.
/// </summary>
public class CallbackEvent : ICallbackEvent
{
#region Properties --------------------------------------------------------------
/// <inheritdoc/>
public IEnumerable<ICallbackAction> Actions => actions;
#endregion
#region Fields ------------------------------------------------------------------
private List<ICallbackAction> actions = new List<ICallbackAction>();
#endregion
#region Usage Functions ---------------------------------------------------------
/// <inheritdoc/>
public void RegisterAction()
{
actions.Add(new CallbackAction());
}
/// <inheritdoc/>
public void RegisterAction(ICallbackAction action)
{
// Check if valid action
if (action.GetType() != typeof(CallbackAction))
{
Debug.LogWarning("Attempted to register an invalid CallbackAction type. Ignoring.", this);
return;
}
actions.Add(action);
}
/// <summary>
/// Adds a CallbackAction into the event.
/// </summary>
/// <param name="action">CallbackAction to add.</param>
public void RegisterAction(CallbackAction action)
{
actions.Add(action);
}
/// <summary>
/// Constructs and adds a CallbackAction into the event.
/// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action action)
{
actions.Add(new CallbackAction(action));
}
/// <summary>
/// Constructs and adds a CallbackAction into the event.
/// </summary>
/// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param>
public void RegisterAction(Object target, MethodInfo method)
{
actions.Add(new CallbackAction(target, method));
}
/// <inheritdoc/>
public void DeregisterAction(ICallbackAction action)
{
if (!actions.Remove(action))
{
Debug.LogWarning("Attempted to deregister invalid action. Ignored.", this);
}
}
/// <summary>
/// Invokes all stored CallbackActions with the specified parameters.
/// </summary>
public void Invoke()
{
foreach (CallbackAction action in actions)
{
try
{
action.Invoke();
}
catch (Exception e)
{
Debug.LogException(e, this);
}
}
}
#endregion
}
/// <summary> /// <summary>
/// A container of CallbackActions that is correlated to a specific scenario as /// A container of CallbackActions that is correlated to a specific scenario as
/// specified by the user of this class. /// specified by the user of this class.
@ -88,7 +174,7 @@ namespace SHADE
actions.Add(action); actions.Add(action);
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param> /// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<T1> action) public void RegisterAction(Action<T1> action)
@ -96,7 +182,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1>(action)); actions.Add(new CallbackAction<T1>(action));
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="target">Object to call the method on.</param> /// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param> /// <param name="method">Method to call.</param>
@ -174,7 +260,7 @@ namespace SHADE
actions.Add(action); actions.Add(action);
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param> /// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<T1, T2> action) public void RegisterAction(Action<T1, T2> action)
@ -182,7 +268,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1, T2>(action)); actions.Add(new CallbackAction<T1, T2>(action));
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="target">Object to call the method on.</param> /// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param> /// <param name="method">Method to call.</param>
@ -260,7 +346,7 @@ namespace SHADE
actions.Add(action); actions.Add(action);
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param> /// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<T1, T2, T3> action) public void RegisterAction(Action<T1, T2, T3> action)
@ -268,7 +354,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1, T2, T3>(action)); actions.Add(new CallbackAction<T1, T2, T3>(action));
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="target">Object to call the method on.</param> /// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param> /// <param name="method">Method to call.</param>
@ -346,7 +432,7 @@ namespace SHADE
actions.Add(action); actions.Add(action);
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param> /// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<T1, T2, T3, T4> action) public void RegisterAction(Action<T1, T2, T3, T4> action)
@ -354,7 +440,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1, T2, T3, T4>(action)); actions.Add(new CallbackAction<T1, T2, T3, T4>(action));
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="target">Object to call the method on.</param> /// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param> /// <param name="method">Method to call.</param>
@ -432,7 +518,7 @@ namespace SHADE
actions.Add(action); actions.Add(action);
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param> /// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<T1, T2, T3, T4, T5> action) public void RegisterAction(Action<T1, T2, T3, T4, T5> action)
@ -440,7 +526,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1, T2, T3, T4, T5>(action)); actions.Add(new CallbackAction<T1, T2, T3, T4, T5>(action));
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="target">Object to call the method on.</param> /// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param> /// <param name="method">Method to call.</param>
@ -518,7 +604,7 @@ namespace SHADE
actions.Add(action); actions.Add(action);
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param> /// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6> action) public void RegisterAction(Action<T1, T2, T3, T4, T5, T6> action)
@ -526,7 +612,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6>(action)); actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6>(action));
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="target">Object to call the method on.</param> /// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param> /// <param name="method">Method to call.</param>
@ -604,7 +690,7 @@ namespace SHADE
actions.Add(action); actions.Add(action);
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param> /// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7> action) public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7> action)
@ -612,7 +698,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7>(action)); actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7>(action));
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="target">Object to call the method on.</param> /// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param> /// <param name="method">Method to call.</param>
@ -690,7 +776,7 @@ namespace SHADE
actions.Add(action); actions.Add(action);
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param> /// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8> action) public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8> action)
@ -698,7 +784,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8>(action)); actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8>(action));
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="target">Object to call the method on.</param> /// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param> /// <param name="method">Method to call.</param>
@ -776,7 +862,7 @@ namespace SHADE
actions.Add(action); actions.Add(action);
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param> /// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> action) public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> action)
@ -784,7 +870,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8, T9>(action)); actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8, T9>(action));
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="target">Object to call the method on.</param> /// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param> /// <param name="method">Method to call.</param>
@ -862,7 +948,7 @@ namespace SHADE
actions.Add(action); actions.Add(action);
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param> /// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> action) public void RegisterAction(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> action)
@ -870,7 +956,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(action)); actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(action));
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="target">Object to call the method on.</param> /// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param> /// <param name="method">Method to call.</param>

View File

@ -61,13 +61,13 @@ namespace SHADE
IEnumerable<ICallbackAction> Actions { get; } IEnumerable<ICallbackAction> Actions { get; }
} }
<# for (int i = 1; i <= max; ++i) { #> <# for (int i = 0; i <= max; ++i) { #>
/// <summary> /// <summary>
/// A container of CallbackActions that is correlated to a specific scenario as /// A container of CallbackActions that is correlated to a specific scenario as
/// specified by the user of this class. /// specified by the user of this class.
/// This variant accepts CallbackEvents with 1 generic parameter. /// This variant accepts CallbackEvents with 1 generic parameter.
/// </summary> /// </summary>
public class CallbackEvent<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> : ICallbackEvent public class CallbackEvent<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> : ICallbackEvent
{ {
#region Properties -------------------------------------------------------------- #region Properties --------------------------------------------------------------
/// <inheritdoc/> /// <inheritdoc/>
@ -82,13 +82,13 @@ namespace SHADE
/// <inheritdoc/> /// <inheritdoc/>
public void RegisterAction() public void RegisterAction()
{ {
actions.Add(new CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>()); actions.Add(new CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>());
} }
/// <inheritdoc/> /// <inheritdoc/>
public void RegisterAction(ICallbackAction action) public void RegisterAction(ICallbackAction action)
{ {
// Check if valid action // Check if valid action
if (action.GetType() != typeof(CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>)) if (action.GetType() != typeof(CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>))
{ {
Debug.LogWarning("Attempted to register an invalid CallbackAction type. Ignoring.", this); Debug.LogWarning("Attempted to register an invalid CallbackAction type. Ignoring.", this);
return; return;
@ -100,26 +100,26 @@ namespace SHADE
/// Adds a CallbackAction into the event. /// Adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="action">CallbackAction to add.</param> /// <param name="action">CallbackAction to add.</param>
public void RegisterAction(CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action) public void RegisterAction(CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action)
{ {
actions.Add(action); actions.Add(action);
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param> /// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action) public void RegisterAction(Action<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action)
{ {
actions.Add(new CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>(action)); actions.Add(new CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>(action));
} }
/// <summary> /// <summary>
/// Constructs and adds a CallbackACtion into the event. /// Constructs and adds a CallbackAction into the event.
/// </summary> /// </summary>
/// <param name="target">Object to call the method on.</param> /// <param name="target">Object to call the method on.</param>
/// <param name="method">Method to call.</param> /// <param name="method">Method to call.</param>
public void RegisterAction(Object target, MethodInfo method) public void RegisterAction(Object target, MethodInfo method)
{ {
actions.Add(new CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>>(target, method)); actions.Add(new CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #>(target, method));
} }
/// <inheritdoc/> /// <inheritdoc/>
public void DeregisterAction(ICallbackAction action) public void DeregisterAction(ICallbackAction action)
@ -132,9 +132,9 @@ namespace SHADE
/// <summary> /// <summary>
/// Invokes all stored CallbackActions with the specified parameters. /// Invokes all stored CallbackActions with the specified parameters.
/// </summary> /// </summary>
public void Invoke(<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#> t<#=t#><# if (t != i) { #>, <# } #><# } #>) public void Invoke(<# if (i != 0) { for (int t = 1; t < i + 1; ++t) { #>T<#=t#> t<#=t#><# if (t != i) { #>, <# } #><# } } #>)
{ {
foreach (CallbackAction<<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>> action in actions) foreach (CallbackAction<# if (i != 0) { #><<# for (int t = 1; t < i + 1; ++t) { #>T<#=t#><# if (t != i) { #>, <# } #><# } #>><# } #> action in actions)
{ {
try try
{ {

View File

@ -52,6 +52,8 @@ enum class AssetType : AssetTypeMeta
PREFAB, PREFAB,
MATERIAL, MATERIAL,
MESH, MESH,
SCRIPT,
FONT,
MAX_COUNT MAX_COUNT
}; };
constexpr size_t TYPE_COUNT{ static_cast<size_t>(AssetType::MAX_COUNT) }; constexpr size_t TYPE_COUNT{ static_cast<size_t>(AssetType::MAX_COUNT) };
@ -92,27 +94,32 @@ constexpr std::string_view EXTENSIONS[] = {
AUDIO_EXTENSION, AUDIO_EXTENSION,
SHADER_EXTENSION, SHADER_EXTENSION,
SHADER_BUILT_IN_EXTENSION, SHADER_BUILT_IN_EXTENSION,
FONT_EXTENSION,
MATERIAL_EXTENSION,
TEXTURE_EXTENSION, TEXTURE_EXTENSION,
MODEL_EXTENSION, MODEL_EXTENSION,
SCRIPT_EXTENSION,
SCENE_EXTENSION, SCENE_EXTENSION,
PREFAB_EXTENSION, PREFAB_EXTENSION,
MATERIAL_EXTENSION,
"dummy",
SCRIPT_EXTENSION,
FONT_EXTENSION,
AUDIO_WAV_EXTENSION, AUDIO_WAV_EXTENSION,
}; };
constexpr size_t EXTENSIONS_COUNT{ 11 };
// EXTERNAL EXTENSIONS // EXTERNAL EXTENSIONS
constexpr std::string_view GLSL_EXTENSION{ ".glsl" }; constexpr std::string_view GLSL_EXTENSION{ ".glsl" };
constexpr std::string_view DDS_EXTENSION{ ".dds" }; constexpr std::string_view DDS_EXTENSION{ ".dds" };
constexpr std::string_view FBX_EXTENSION{ ".fbx" }; constexpr std::string_view FBX_EXTENSION{ ".fbx" };
constexpr std::string_view GLTF_EXTENSION{ ".gltf" }; constexpr std::string_view GLTF_EXTENSION{ ".gltf" };
constexpr std::string_view TTF_EXTENSION{ ".ttf" };
constexpr std::string_view EXTERNALS[] = { constexpr std::string_view EXTERNALS[] = {
GLSL_EXTENSION, GLSL_EXTENSION,
DDS_EXTENSION, DDS_EXTENSION,
FBX_EXTENSION, FBX_EXTENSION,
GLTF_EXTENSION GLTF_EXTENSION,
TTF_EXTENSION
}; };
// SHADER IDENTIFIERS // SHADER IDENTIFIERS
@ -127,11 +134,4 @@ constexpr std::pair<std::string_view, SHADE::SH_SHADER_TYPE> SHADER_IDENTIFIERS[
}; };
constexpr size_t SHADER_TYPE_MAX_COUNT{ 3 }; constexpr size_t SHADER_TYPE_MAX_COUNT{ 3 };
// Error flags
constexpr std::string_view FILE_NOT_FOUND_ERR {"FILE NOT FOUND"};
constexpr std::string_view META_NOT_FOUND_ERR {"META NOT FOUND"};
constexpr std::string_view ASSET_NOT_FOUND_ERR {"ASSET NOT FOUND"};
constexpr std::string_view EXT_DOES_NOT_EXIST {"TYPE DOES NOT HAVE EXTENSION DEFINED"};
#endif // !SH_ASSET_MACROS_H #endif // !SH_ASSET_MACROS_H

View File

@ -83,7 +83,7 @@ namespace SHADE
AssetPath SHAssetManager::GenerateLocalPath(AssetPath path) noexcept AssetPath SHAssetManager::GenerateLocalPath(AssetPath path) noexcept
{ {
if (!IsRecognised(path.extension().string().c_str())) if (!SHFileSystem::IsRecognised(path.extension().string().c_str()))
{ {
//TODO:ASSERT UNRECOGNISED FILE TYPE //TODO:ASSERT UNRECOGNISED FILE TYPE
return std::filesystem::path(); return std::filesystem::path();
@ -338,7 +338,7 @@ namespace SHADE
return result; return result;
} }
void SHAssetManager::CompileAsset(AssetPath const& path) noexcept void SHAssetManager::CompileAsset(AssetPath const& path, bool genMeta) noexcept
{ {
if (!std::filesystem::exists(path)) if (!std::filesystem::exists(path))
{ {
@ -360,10 +360,12 @@ namespace SHADE
std::string modelPath = path.string().substr(0, path.string().find_last_of('.')); std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
modelPath += MODEL_EXTENSION; modelPath += MODEL_EXTENSION;
newPath = modelPath; newPath = modelPath;
GenerateNewMeta(newPath);
} }
if (genMeta)
{
GenerateNewMeta(newPath);
}
} }
FolderPointer SHAssetManager::GetRootFolder() noexcept FolderPointer SHAssetManager::GetRootFolder() noexcept
@ -371,17 +373,11 @@ namespace SHADE
return folderRoot; return folderRoot;
} }
bool SHAssetManager::IsRecognised(char const* ext) noexcept void SHAssetManager::RefreshDirectory() noexcept
{ {
for (auto const& e : EXTENSIONS) SHFileSystem::DestroyDirectory(folderRoot);
{ assetCollection.clear();
if (strcmp(ext, e.data()) == 0) BuildAssetCollection();
{
return true;
}
}
return false;
} }
SHAsset SHAssetManager::CreateAssetFromPath(AssetPath path) noexcept SHAsset SHAssetManager::CreateAssetFromPath(AssetPath path) noexcept
@ -396,51 +392,6 @@ namespace SHADE
return result; return result;
} }
void SHAssetManager::CompileAll() noexcept
{
std::vector<AssetPath> paths;
for (auto const& dir : std::filesystem::recursive_directory_iterator{ ASSET_ROOT })
{
if (dir.is_regular_file())
{
for (auto const& ext : EXTERNALS)
{
if (dir.path().extension().string() == ext.data())
{
paths.push_back(dir.path());
}
}
}
}
for (auto const& path : paths)
{
AssetPath newPath;
auto const ext{ path.extension().string() };
if (ext == GLSL_EXTENSION.data())
{
newPath = SHShaderSourceCompiler::LoadAndCompileShader(path).value();
}
else if (ext == DDS_EXTENSION.data())
{
newPath = SHTextureCompiler::CompileTextureAsset(path).value();
}
else if (ext == GLTF_EXTENSION.data() || ext == FBX_EXTENSION.data())
{
std::string command = MODEL_COMPILER_EXE.data();
command += " " + path.string();
std::system(command.c_str());
std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
modelPath += MODEL_EXTENSION;
newPath = modelPath;
}
GenerateNewMeta(newPath);
}
}
bool SHAssetManager::DeleteLocalFile(AssetPath path) noexcept bool SHAssetManager::DeleteLocalFile(AssetPath path) noexcept
{ {
//TODO Move this to dedicated library //TODO Move this to dedicated library
@ -536,7 +487,7 @@ namespace SHADE
{ {
} }
void SHAssetManager::GenerateNewMeta(AssetPath path) noexcept std::optional<AssetID> SHAssetManager::GenerateNewMeta(AssetPath path) noexcept
{ {
auto const ext = path.extension().string(); auto const ext = path.extension().string();
if (ext == SHADER_BUILT_IN_EXTENSION.data()) if (ext == SHADER_BUILT_IN_EXTENSION.data())
@ -597,11 +548,32 @@ namespace SHADE
SHAssetMetaHandler::WriteMetaData(assetCollection[newAsset.id]); SHAssetMetaHandler::WriteMetaData(assetCollection[newAsset.id]);
} }
else if (ext == SCRIPT_EXTENSION)
{
SHAsset newAsset{
path.stem().string(),
GenerateAssetID(AssetType::SCRIPT),
AssetType::SCRIPT,
path,
false
};
assetCollection.emplace(newAsset.id, newAsset);
SHAssetMetaHandler::WriteMetaData(newAsset);
return newAsset.id;
}
} }
void SHAssetManager::BuildAssetCollection() noexcept void SHAssetManager::BuildAssetCollection() noexcept
{ {
SHFileSystem::BuildDirectory(ASSET_ROOT.data(), folderRoot, assetCollection); std::vector<SHFile*> toGenNew;
SHFileSystem::BuildDirectory(ASSET_ROOT.data(), folderRoot, assetCollection, toGenNew);
for (auto& file : toGenNew)
{
auto newID{ GenerateNewMeta(file->path).value() };
file->assetMeta = &assetCollection[newID];
}
for (auto& asset : std::ranges::views::values(assetCollection)) for (auto& asset : std::ranges::views::values(assetCollection))
{ {

View File

@ -87,9 +87,10 @@ namespace SHADE
static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept; static std::vector<SHAssetData const*> GetAllDataOfType(AssetType type) noexcept;
static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept; static std::vector<SHAsset> GetAllRecordOfType(AssetType type) noexcept;
static void CompileAsset(AssetPath const& path) noexcept; static void CompileAsset(AssetPath const& path, bool genMeta) noexcept;
static FolderPointer GetRootFolder() noexcept; static FolderPointer GetRootFolder() noexcept;
static void RefreshDirectory() noexcept;
private: private:
@ -98,16 +99,12 @@ namespace SHADE
static SHAssetData* LoadData(SHAsset const& asset) noexcept; static SHAssetData* LoadData(SHAsset const& asset) noexcept;
static SHAssetData* LoadSubData(SHAsset const& asset) noexcept; static SHAssetData* LoadSubData(SHAsset const& asset) noexcept;
static void LoadNewData(AssetPath path) noexcept; static void LoadNewData(AssetPath path) noexcept;
static void GenerateNewMeta(AssetPath path) noexcept; static std::optional<AssetID> GenerateNewMeta(AssetPath path) noexcept;
inline static void BuildAssetCollection() noexcept; inline static void BuildAssetCollection() noexcept;
static bool IsRecognised(char const*) noexcept;
static SHAsset CreateAssetFromPath(AssetPath path) noexcept; static SHAsset CreateAssetFromPath(AssetPath path) noexcept;
static void CompileAll() noexcept;
static bool DeleteLocalFile(AssetPath path) noexcept; static bool DeleteLocalFile(AssetPath path) noexcept;
//TODO use this function to create asset data internall at all calls to generate id //TODO use this function to create asset data internall at all calls to generate id

View File

@ -38,7 +38,7 @@ namespace SHADE
****************************************************************************/ ****************************************************************************/
AssetType SHAssetMetaHandler::GetTypeFromExtension(AssetExtension ext) noexcept AssetType SHAssetMetaHandler::GetTypeFromExtension(AssetExtension ext) noexcept
{ {
for (int i{0}; i < EXTENSIONS->size(); ++i) for (auto i{0}; i < EXTENSIONS_COUNT; ++i)
{ {
if (strcmp(ext.c_str(), EXTENSIONS[i].data()) == 0) if (strcmp(ext.c_str(), EXTENSIONS[i].data()) == 0)
{ {
@ -98,6 +98,7 @@ namespace SHADE
meta.type = static_cast<AssetType>(type); meta.type = static_cast<AssetType>(type);
meta.isSubAsset = false; meta.isSubAsset = false;
meta.parent = 0;
// Burn Line // Burn Line
if (std::getline(metaFile, line)) if (std::getline(metaFile, line))

View File

@ -17,6 +17,8 @@
#include <FMOD/fmod_studio.hpp> #include <FMOD/fmod_studio.hpp>
#include <SDL_keyboard.h> #include <SDL_keyboard.h>
const std::string AUDIO_FOLDER_PATH{ std::string(ASSET_ROOT)+ "/Audio/" };
namespace SHADE namespace SHADE
{ {
SHAudioSystem::SHAudioSystem() SHAudioSystem::SHAudioSystem()
@ -79,10 +81,10 @@ namespace SHADE
//SHResourceManager::LoadAllAudio(system, soundList); //SHResourceManager::LoadAllAudio(system, soundList);
LoadBank("../../Assets/Audio/Master.bank"); LoadBank((AUDIO_FOLDER_PATH + "Master.bank").data());
LoadBank("../../Assets/Audio/Master.strings.bank"); LoadBank((AUDIO_FOLDER_PATH + "Master.strings.bank").data());
//LoadBank("../../Assets/Audio/Music.bank"); //LoadBank((AUDIO_FOLDER_PATH + "Music.bank").data());
LoadBank("../../Assets/Audio/footsteps.bank"); LoadBank((AUDIO_FOLDER_PATH + "footsteps.bank").data());
//auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human"); //auto clip = CreateAudioClip("event:/Characters/sfx_footsteps_human");
//clip->Play(); //clip->Play();

View File

@ -7,13 +7,15 @@
#include "ECS_Base/Managers/SHComponentManager.h" #include "ECS_Base/Managers/SHComponentManager.h"
#include "Math/Transform/SHTransformComponent.h" #include "Math/Transform/SHTransformComponent.h"
#include <math.h> #include <math.h>
#include "Scene/SHSceneManager.h"
namespace SHADE namespace SHADE
{ {
void SHCameraSystem::UpdateEditorCamera(double dt) noexcept void SHCameraSystem::UpdateEditorCamera(double dt) noexcept
{ {
auto& camera = editorCamera; auto& camera = editorCamera;
SHVec3 view, right, UP; SHVec3 view, right, UP;
GetCameraAxis(camera, view, right, UP); GetCameraAxis(camera, view, right, UP);
@ -61,63 +63,43 @@ namespace SHADE
} }
UpdateCameraComponent(editorCamera); UpdateCameraComponent(editorCamera);
}
} void SHCameraSystem::UpdateEditorArm(double dt,bool active ,SHVec3 const& targetPos) noexcept
void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept
{ {
SHCameraSystem* system = static_cast<SHCameraSystem*>(GetSystem()); if (active == false)
auto& camera = system->editorCamera; {
SHVec3 view, right, UP; editorCameraArm.offset = SHVec3{0.0f};
system->GetCameraAxis(camera, view, right, UP); return;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::A)) editorCamera.SetPosition(targetPos);
{
//std::cout << "Camera movement: "<<right.x<<", " << right.y << std::endl;
camera.position -= right * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::D))
{
camera.position += right * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::W))
{
camera.position += view * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::S))
{
camera.position -= view * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::Q))
{
camera.position += UP * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::E))
{
camera.position -= UP * dt * camera.movementSpeed;
camera.dirtyView = true;
}
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::RMB))
{
double mouseX, mouseY; double mouseX, mouseY;
SHInputManager::GetMouseVelocity(&mouseX, &mouseY); SHInputManager::GetMouseVelocity(&mouseX, &mouseY);
//std::cout << camera.yaw << std::endl; editorCameraArm.pitch -= mouseY * dt * editorCamera.turnSpeed.x;
editorCameraArm.yaw -= mouseX * dt * editorCamera.turnSpeed.y;
constexpr float pitchClamp = 85.0f;
if (editorCameraArm.pitch > pitchClamp)
editorCameraArm.pitch = pitchClamp;
if (editorCameraArm.pitch < -pitchClamp)
editorCameraArm.pitch = -pitchClamp;
editorCameraArm.armLength -= SHInputManager::GetMouseWheelVerticalDelta() * dt;
if (editorCameraArm.armLength < 1.0f)
editorCameraArm.armLength = 1.0f;
UpdatePivotArmComponent(editorCameraArm);
editorCamera.offset = editorCameraArm.GetOffset();
CameraLookAt(editorCamera, targetPos);
camera.pitch -= mouseY * dt * camera.turnSpeed.x;
camera.yaw -= mouseX * dt * camera.turnSpeed.y;
camera.dirtyView = true;
} }
//std::cout << "Camera position: " << camera.position.x << " " << camera.position.y << std::endl;
system->UpdateCameraComponent(system->editorCamera);
system->DecomposeViewMatrix(camera.viewMatrix, camera.pitch, camera.yaw, camera.roll, camera.position);
}
void SHCameraSystem::Init(void) void SHCameraSystem::Init(void)
{ {
@ -164,6 +146,9 @@ namespace SHADE
void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept
{ {
if (camera.isActive == false)
return;
if (SHComponentManager::HasComponent<SHTransformComponent>(camera.GetEID()) == true && &camera != &editorCamera) if (SHComponentManager::HasComponent<SHTransformComponent>(camera.GetEID()) == true && &camera != &editorCamera)
{ {
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(camera.GetEID()); auto transform = SHComponentManager::GetComponent<SHTransformComponent>(camera.GetEID());
@ -183,11 +168,17 @@ namespace SHADE
if (SHComponentManager::HasComponent<SHCameraArmComponent>(camera.GetEID())) if (SHComponentManager::HasComponent<SHCameraArmComponent>(camera.GetEID()))
{ {
auto arm = SHComponentManager::GetComponent<SHCameraArmComponent>(camera.GetEID()); auto arm = SHComponentManager::GetComponent<SHCameraArmComponent>(camera.GetEID());
if (arm->isActive == true)
{
camera.offset = arm->GetOffset(); camera.offset = arm->GetOffset();
if (arm->lookAtCameraOrigin) if (arm->lookAtCameraOrigin)
CameraLookAt(camera, camera.position); CameraLookAt(camera, camera.position);
} }
}
SHVec3 view, right, UP; SHVec3 view, right, UP;
@ -287,11 +278,13 @@ namespace SHADE
for (auto& pivot : pivotDense) for (auto& pivot : pivotDense)
{ {
if(SHSceneManager::CheckNodeAndComponentsActive<SHCameraArmComponent>(pivot.GetEID()))
system->UpdatePivotArmComponent(pivot); system->UpdatePivotArmComponent(pivot);
} }
for (auto& cam : dense) for (auto& cam : dense)
{ {
if (SHSceneManager::CheckNodeAndComponentsActive<SHCameraComponent>(cam.GetEID()))
system->UpdateCameraComponent(cam); system->UpdateCameraComponent(cam);
} }
for (auto& handle : system->directorHandleList) for (auto& handle : system->directorHandleList)
@ -399,7 +392,7 @@ namespace SHADE
SHVec3 up = { 0.0f,1.0f,0.0f }; SHVec3 up = { 0.0f,1.0f,0.0f };
////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll)); //SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll));
//target = SHVec3::Normalise(target); //target = SHVec3::Normalise(target);

View File

@ -5,6 +5,7 @@
#include "ECS_Base/System/SHSystemRoutine.h" #include "ECS_Base/System/SHSystemRoutine.h"
#include "Resource/SHResourceLibrary.h" #include "Resource/SHResourceLibrary.h"
#include "SHCameraDirector.h" #include "SHCameraDirector.h"
#include "SHCameraArmComponent.h"
#include "SH_API.h" #include "SH_API.h"
namespace SHADE namespace SHADE
@ -18,6 +19,7 @@ namespace SHADE
//A camera component that represents editor camera. //A camera component that represents editor camera.
//This is not tied to any entity. Hence this EID should not be used. //This is not tied to any entity. Hence this EID should not be used.
SHCameraComponent editorCamera; SHCameraComponent editorCamera;
SHCameraArmComponent editorCameraArm;
SHResourceLibrary<SHCameraDirector> directorLibrary; SHResourceLibrary<SHCameraDirector> directorLibrary;
std::vector<DirectorHandle> directorHandleList; std::vector<DirectorHandle> directorHandleList;
@ -34,14 +36,7 @@ namespace SHADE
void Init (void); void Init (void);
void Exit (void); void Exit (void);
class SH_API EditorCameraUpdate final : public SHSystemRoutine
{
public:
EditorCameraUpdate() : SHSystemRoutine("Editor Camera Update", true) { };
virtual void Execute(double dt) noexcept override final;
};
friend class EditorCameraUpdate; friend class EditorCameraUpdate;
class SH_API CameraSystemUpdate final: public SHSystemRoutine class SH_API CameraSystemUpdate final: public SHSystemRoutine
@ -63,6 +58,7 @@ namespace SHADE
void DecomposeViewMatrix(SHMatrix const& matrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept; void DecomposeViewMatrix(SHMatrix const& matrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept;
void SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) noexcept; void SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) noexcept;
void CameraLookAt(SHCameraComponent& camera, SHVec3 target) noexcept; void CameraLookAt(SHCameraComponent& camera, SHVec3 target) noexcept;
void UpdateEditorArm(double dt,bool active ,SHVec3 const& targetPos) noexcept;
}; };

View File

@ -10,63 +10,102 @@
namespace SHADE namespace SHADE
{ {
SHCommandManager::CommandStack SHCommandManager::undoStack{};
SHCommandManager::CommandStack SHCommandManager::redoStack{}; SHCommandManager::CommandStack SHCommandManager::undoStack(defaultStackSize);
SHCommandManager::CommandStack SHCommandManager::redoStack(defaultStackSize);
SHCommandManager::CommandStack SHCommandManager::secondaryUndoStack(defaultStackSize);
SHCommandManager::CommandStack SHCommandManager::secondaryRedoStack(defaultStackSize);
SHCommandManager::CommandStackPtr SHCommandManager::pCurrUndoStack(&undoStack);
SHCommandManager::CommandStackPtr SHCommandManager::pCurrRedoStack(&redoStack);
void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue) void SHCommandManager::PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue)
{ {
redoStack = CommandStack(); *pCurrRedoStack = CommandStack(defaultStackSize);
commandPtr->Execute(); commandPtr->Execute();
if (overrideValue && !undoStack.empty()) if (overrideValue && !pCurrUndoStack->Empty())
{ {
undoStack.top()->Merge(commandPtr); pCurrUndoStack->Top()->Merge(commandPtr);
} }
else else
{ {
undoStack.push(commandPtr); pCurrUndoStack->Push(commandPtr);
} }
} }
void SHCommandManager::RegisterCommand(BaseCommandPtr commandPtr) void SHCommandManager::RegisterCommand(BaseCommandPtr commandPtr)
{ {
undoStack.push(commandPtr); pCurrUndoStack->Push(commandPtr);
} }
void SHCommandManager::UndoCommand() void SHCommandManager::UndoCommand()
{ {
if (undoStack.empty()) if (pCurrUndoStack->Empty())
return; return;
undoStack.top()->Undo(); pCurrUndoStack->Top()->Undo();
redoStack.push(undoStack.top()); pCurrRedoStack->Push(pCurrUndoStack->Top());
undoStack.pop(); pCurrUndoStack->Pop();
} }
void SHCommandManager::RedoCommand() void SHCommandManager::RedoCommand()
{ {
if (redoStack.empty()) if (pCurrRedoStack->Empty())
return; return;
redoStack.top()->Execute(); pCurrRedoStack->Top()->Execute();
undoStack.push(redoStack.top()); pCurrUndoStack->Push(pCurrRedoStack->Top());
redoStack.pop(); pCurrRedoStack->Pop();
} }
std::size_t SHCommandManager::GetUndoStackSize() std::size_t SHCommandManager::GetUndoStackSize()
{ {
return undoStack.size(); return pCurrUndoStack->Size();
} }
std::size_t SHCommandManager::GetRedoStackSize() std::size_t SHCommandManager::GetRedoStackSize()
{ {
return redoStack.size(); return pCurrRedoStack->Size();
} }
void SHCommandManager::PopLatestCommandFromRedoStack() void SHCommandManager::PopLatestCommandFromRedoStack()
{ {
redoStack.pop(); pCurrRedoStack->Pop();
} }
void SHCommandManager::PopLatestCommandFromUndoStack() void SHCommandManager::PopLatestCommandFromUndoStack()
{ {
undoStack.pop(); pCurrUndoStack->Pop();
} }
void SHCommandManager::SwapStacks()
{
if (pCurrUndoStack == &undoStack)
{
pCurrUndoStack = &secondaryUndoStack;
}
else
{
secondaryUndoStack.Clear();
pCurrUndoStack = &undoStack;
}
if (pCurrRedoStack == &redoStack)
{
pCurrRedoStack = &secondaryRedoStack;
}
else
{
secondaryRedoStack.Clear();
pCurrRedoStack = &redoStack;
}
}
void SHCommandManager::ClearAll()
{
undoStack.Clear();
redoStack.Clear();
secondaryUndoStack.Clear();
secondaryRedoStack.Clear();
}
}//namespace SHADE }//namespace SHADE

View File

@ -10,6 +10,7 @@
//#==============================================================# //#==============================================================#
#include "SHCommand.hpp" #include "SHCommand.hpp"
#include "SH_API.h" #include "SH_API.h"
#include "Tools/SHDeque.h"
namespace SHADE namespace SHADE
{ {
@ -22,7 +23,8 @@ namespace SHADE
using BaseCommandPtr = std::shared_ptr<SHBaseCommand>; using BaseCommandPtr = std::shared_ptr<SHBaseCommand>;
template<typename T> template<typename T>
using SHCommandPtr = std::shared_ptr<SHCommand<T>>; using SHCommandPtr = std::shared_ptr<SHCommand<T>>;
using CommandStack = std::stack<BaseCommandPtr>; using CommandStack = SHDeque<BaseCommandPtr>;
using CommandStackPtr = CommandStack*;
static void PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue = false); static void PerformCommand(BaseCommandPtr commandPtr, bool const& overrideValue = false);
static void RegisterCommand(BaseCommandPtr commandPtr); static void RegisterCommand(BaseCommandPtr commandPtr);
@ -34,8 +36,17 @@ namespace SHADE
static void PopLatestCommandFromRedoStack(); static void PopLatestCommandFromRedoStack();
static void PopLatestCommandFromUndoStack(); static void PopLatestCommandFromUndoStack();
static void SwapStacks();
static void ClearAll();
static constexpr CommandStack::SizeType defaultStackSize = 100;
private: private:
static CommandStackPtr pCurrUndoStack;
static CommandStackPtr pCurrRedoStack;
static CommandStack undoStack; static CommandStack undoStack;
static CommandStack secondaryUndoStack;
static CommandStack redoStack; static CommandStack redoStack;
static CommandStack secondaryRedoStack;
}; };
}//namespace SHADE }//namespace SHADE

View File

@ -13,11 +13,12 @@
#include "Editor/SHEditor.h" #include "Editor/SHEditor.h"
#include "Editor/DragDrop/SHDragDrop.hpp" #include "Editor/DragDrop/SHDragDrop.hpp"
#include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h" #include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h"
#include "Editor/EditorWindow/SHEditorWindowManager.h"
namespace SHADE namespace SHADE
{ {
SHAssetBrowser::SHAssetBrowser() SHAssetBrowser::SHAssetBrowser()
:SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder), assetBeingCreated(std::nullopt) :SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder)
{ {
} }
@ -34,23 +35,48 @@ namespace SHADE
RecursivelyDrawTree(rootFolder); RecursivelyDrawTree(rootFolder);
DrawMenuBar(); DrawMenuBar();
DrawCurrentFolder(); DrawCurrentFolder();
DrawAssetBeingCreated();
} }
ImGui::End(); ImGui::End();
if(refreshQueued)
Refresh();
}
void SHAssetBrowser::QueueRefresh() noexcept
{
refreshQueued = true;
}
void SHAssetBrowser::Refresh() noexcept
{
SHAssetManager::RefreshDirectory();
rootFolder = SHAssetManager::GetRootFolder();
refreshQueued = false;
} }
void SHAssetBrowser::DrawMenuBar() void SHAssetBrowser::DrawMenuBar()
{ {
if (ImGui::BeginMenuBar()) if (ImGui::BeginMenuBar())
{ {
if(ImGui::SmallButton(ICON_MD_SYNC))
{
QueueRefresh();
}
if(ImGui::SmallButton(ICON_FA_CIRCLE_PLUS))
{
isAssetBeingCreated = true;
}
ImGui::EndMenuBar(); ImGui::EndMenuBar();
} }
} }
//if !compiled, set genMeta to true
ImRect SHAssetBrowser::RecursivelyDrawTree(FolderPointer folder) ImRect SHAssetBrowser::RecursivelyDrawTree(FolderPointer folder)
{ {
auto const& subFolders = folder->subFolders; auto const& subFolders = folder->subFolders;
auto const& files = folder->files; auto files = folder->files;
const bool isSelected = std::ranges::find(selectedFolders, folder) != selectedFolders.end(); const bool isSelected = std::ranges::find(selectedFolders, folder) != selectedFolders.end();
ImGuiTreeNodeFlags flags = (subFolders.empty() && files.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow; ImGuiTreeNodeFlags flags = (subFolders.empty() && files.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow;
if (isSelected) if (isSelected)
@ -62,21 +88,10 @@ namespace SHADE
ImGuiID folderID = ImGui::GetItemID(); ImGuiID folderID = ImGui::GetItemID();
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
if (ImGui::BeginPopupContextItem()) //if (ImGui::BeginPopupContextItem())
{ //{
if (ImGui::BeginMenu("Create Asset")) // ImGui::EndPopup();
{ //}
//TODO: Change to rttr type enum align
if (ImGui::Selectable("Material"))
{
assetBeingCreated = { folder, AssetType::MATERIAL, "New Material" };
ImGui::TreeNodeSetOpen(folderID, true);
isOpen = true;
}
ImGui::EndMenu();
}
ImGui::EndPopup();
}
if (ImGui::IsItemClicked()) if (ImGui::IsItemClicked())
{ {
@ -100,19 +115,15 @@ namespace SHADE
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
vertLineEnd.y = midPoint; vertLineEnd.y = midPoint;
} }
for (auto const& file : files) for (auto& file : files)
{ {
if(file.assetMeta == nullptr)
continue;
const float horizontalLineSize = 25.0f; const float horizontalLineSize = 25.0f;
const ImRect childRect = DrawFile(file.assetMeta); const ImRect childRect = DrawFile(file);
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
vertLineEnd.y = midPoint; vertLineEnd.y = midPoint;
} }
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1); drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1);
if(assetBeingCreated.has_value() && std::get<0>(assetBeingCreated.value()) == folder)
DrawAssetBeingCreated();
ImGui::TreePop(); ImGui::TreePop();
} }
@ -148,7 +159,33 @@ namespace SHADE
//} //}
} }
ImRect SHAssetBrowser::DrawFile(SHAsset const* const asset) noexcept ImRect SHAssetBrowser::DrawFile(SHFile& file) noexcept
{
if(file.compilable)
{
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf;
static constexpr std::string_view icon = ICON_MD_FILE_PRESENT;
ImGui::PushID(file.name.data());
bool const isOpen = ImGui::TreeNodeEx(file.name.data(), flags, "%s %s%s", icon.data(), file.name.data(), file.ext.data());
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
if(ImGui::BeginPopupContextItem())
{
if(ImGui::Selectable("Compile"))
{
SHAssetManager::CompileAsset(file.path, !file.compiled);
QueueRefresh();
}
ImGui::EndPopup();
}
ImGui::TreePop();
ImGui::PopID();
return nodeRect;
}
if(file.assetMeta)
DrawAsset(file.assetMeta, file.ext);
}
ImRect SHAssetBrowser::DrawAsset(SHAsset const* const asset, FileExt const& ext /*= ""*/) noexcept
{ {
if (asset == nullptr) if (asset == nullptr)
return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
@ -173,7 +210,7 @@ namespace SHADE
default:; default:;
} }
bool const isOpen = ImGui::TreeNodeEx(asset, flags, "%s %s", icon.data(), asset->name.data()); bool const isOpen = ImGui::TreeNodeEx(asset, flags, "%s %s%s", icon.data(), asset->name.data(), ext.data());
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
if (SHDragDrop::BeginSource()) if (SHDragDrop::BeginSource())
{ {
@ -212,7 +249,6 @@ namespace SHADE
case AssetType::MAX_COUNT: break; case AssetType::MAX_COUNT: break;
default:; default:;
} }
} }
//TODO: Combine Draw asset and Draw Folder recursive drawing //TODO: Combine Draw asset and Draw Folder recursive drawing
@ -227,7 +263,7 @@ namespace SHADE
for(auto const& subAsset : asset->subAssets) for(auto const& subAsset : asset->subAssets)
{ {
const float horizontalLineSize = 25.0f; const float horizontalLineSize = 25.0f;
const ImRect childRect = DrawFile(subAsset); const ImRect childRect = DrawAsset(subAsset);
const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f; const float midPoint = (childRect.Min.y + childRect.Max.y) * 0.5f;
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1); drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
vertLineEnd.y = midPoint; vertLineEnd.y = midPoint;
@ -240,19 +276,52 @@ namespace SHADE
void SHAssetBrowser::DrawAssetBeingCreated() noexcept void SHAssetBrowser::DrawAssetBeingCreated() noexcept
{ {
if (!assetBeingCreated.has_value()) if(isAssetBeingCreated)
return; ImGui::OpenPopup(newAssetPopup.data());
auto& path = std::get<0>(assetBeingCreated.value());
auto& type = std::get<1>(assetBeingCreated.value()); if(ImGui::BeginPopupModal(newAssetPopup.data(), &isAssetBeingCreated))
auto& assetName = std::get<2>(assetBeingCreated.value());
if (ImGui::InputText("##newAssetName", &assetName, ImGuiInputTextFlags_EnterReturnsTrue))
{ {
AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName); ImGui::RadioButton("Material", true);
ImGui::SameLine();
if (ImGui::InputText("##newAssetName", &nameOfAssetBeingCreated, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_AutoSelectAll))
{
AssetID assetId = SHAssetManager::CreateNewAsset(AssetType::MATERIAL, nameOfAssetBeingCreated);
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>()) if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
{ {
matInspector->OpenMaterial(assetId, true); matInspector->OpenMaterial(assetId, true);
} }
assetBeingCreated.reset(); nameOfAssetBeingCreated.clear();
} QueueRefresh();
isAssetBeingCreated = false;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
//if (ImGui::BeginMenu("Create Asset"))
//{
// //TODO: Change to rttr type enum align
// if (ImGui::Selectable("Material"))
// {
// assetBeingCreated = { folder, AssetType::MATERIAL, "NewMaterial" };
// ImGui::TreeNodeSetOpen(folderID, true);
// isOpen = true;
// }
// ImGui::EndMenu();
//}
//if (!assetBeingCreated.has_value())
// return;
//auto& path = std::get<0>(assetBeingCreated.value());
//auto& type = std::get<1>(assetBeingCreated.value());
//auto& assetName = std::get<2>(assetBeingCreated.value());
//if (ImGui::InputText("##newAssetName", &assetName, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_AutoSelectAll))
//{
// AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName);
// if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
// {
// matInspector->OpenMaterial(assetId, true);
// }
// assetBeingCreated.reset();
// QueueRefresh();
//}
} }
} }

View File

@ -10,24 +10,29 @@ namespace SHADE
class SHAssetBrowser final : public SHEditorWindow class SHAssetBrowser final : public SHEditorWindow
{ {
public: public:
using AssetEntry = std::tuple<FolderPointer, AssetType, std::string>;
SHAssetBrowser(); SHAssetBrowser();
void Init(); void Init();
void Update(); void Update();
void Refresh(); void QueueRefresh() noexcept;
private: private:
void DrawMenuBar(); void DrawMenuBar();
ImRect RecursivelyDrawTree(FolderPointer folder); ImRect RecursivelyDrawTree(FolderPointer folder);
void DrawCurrentFolder(); void DrawCurrentFolder();
ImRect DrawFile(SHAsset const* const asset) noexcept; ImRect DrawFile(SHFile& file) noexcept;
ImRect DrawAsset(SHAsset const* const asset, FileExt const& ext = "") noexcept;
void DrawAssetBeingCreated() noexcept; void DrawAssetBeingCreated() noexcept;
void Refresh() noexcept;
FolderPointer rootFolder, prevFolder, currentFolder; FolderPointer rootFolder, prevFolder, currentFolder;
std::optional<AssetEntry> assetBeingCreated;
std::vector<FolderPointer> selectedFolders; std::vector<FolderPointer> selectedFolders;
std::vector<AssetID> selectedAssets; std::vector<AssetID> selectedAssets;
static constexpr float tileWidth = 50.0f; static constexpr float tileWidth = 50.0f;
bool refreshQueued = false;
bool isAssetBeingCreated = false;
static constexpr std::string_view newAssetPopup = "Create New Asset";
std::string nameOfAssetBeingCreated;
}; };
} }

View File

@ -15,6 +15,7 @@
#include "Editor/DragDrop/SHDragDrop.hpp" #include "Editor/DragDrop/SHDragDrop.hpp"
#include "Tools/SHException.h" #include "Tools/SHException.h"
#include "Editor/IconsMaterialDesign.h" #include "Editor/IconsMaterialDesign.h"
#include "SHHierarchyPanelCommands.h"
//#==============================================================# //#==============================================================#
//|| Library Includes || //|| Library Includes ||
@ -105,15 +106,22 @@ namespace SHADE
PasteEntities(editor->selectedEntities.back()); PasteEntities(editor->selectedEntities.back());
} }
} }
if(ImGui::IsKeyReleased(ImGuiKey_Delete))
{
DeleteSelectedEntities();
}
} }
} }
if(ImGui::IsWindowHovered() && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) if(ImGui::IsWindowHovered() && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
{
if(ImGui::IsDragDropActive())
{ {
ParentSelectedEntities(MAX_EID, draggingEntities); ParentSelectedEntities(MAX_EID, draggingEntities);
draggingEntities.clear(); draggingEntities.clear();
ImGui::ClearDragDrop(); ImGui::ClearDragDrop();
} }
}
ImGui::End(); ImGui::End();
} }
@ -255,9 +263,10 @@ namespace SHADE
PasteEntities(eid); PasteEntities(eid);
skipFrame = true; skipFrame = true;
} }
if (ImGui::Selectable(std::format("{} Delete", ICON_MD_DELETE).data())) if (ImGui::Selectable(std::format("{} Delete selected", ICON_MD_DELETE).data()))
{ {
SHEntityManager::DestroyEntity(eid); //SHEntityManager::DestroyEntity(eid);
DeleteSelectedEntities();
} }
if ((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data())) if ((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data()))
@ -282,9 +291,12 @@ namespace SHADE
} }
else editor->selectedEntities.clear(); else editor->selectedEntities.clear();
} }
else if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) else
{
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
editor->selectedEntities.clear(); editor->selectedEntities.clear();
editor->selectedEntities.push_back(eid); editor->selectedEntities.push_back(eid);
}
}//if not selected }//if not selected
else else
{ {
@ -365,6 +377,7 @@ namespace SHADE
if (eid == beginEID || eid == endEID) if (eid == beginEID || eid == endEID)
{ {
startSelecting = true; startSelecting = true;
if(std::ranges::find(editor->selectedEntities, eid) == editor->selectedEntities.end())
editor->selectedEntities.push_back(eid); editor->selectedEntities.push_back(eid);
} }
} }
@ -372,6 +385,7 @@ namespace SHADE
{ {
if (!endSelecting) if (!endSelecting)
{ {
if (std::ranges::find(editor->selectedEntities, eid) == editor->selectedEntities.end())
editor->selectedEntities.push_back(eid); editor->selectedEntities.push_back(eid);
if (eid == endEID || eid == beginEID) if (eid == endEID || eid == beginEID)
{ {
@ -397,47 +411,39 @@ namespace SHADE
void SHHierarchyPanel::CopySelectedEntities() void SHHierarchyPanel::CopySelectedEntities()
{ {
const auto editor = SHSystemManager::GetSystem<SHEditor>(); const auto editor = SHSystemManager::GetSystem<SHEditor>();
SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(editor->selectedEntities)); auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
std::vector<EntityID> entitiesToCopy{};
std::ranges::copy_if(editor->selectedEntities, std::back_inserter(entitiesToCopy), [&sceneGraph](EntityID const& eid)
{
if(sceneGraph.GetParent(eid)->GetEntityID() == MAX_EID)
return true;
return false;
});
SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(entitiesToCopy));
} }
void SHHierarchyPanel::PasteEntities(EntityID parentEID) void SHHierarchyPanel::PasteEntities(EntityID parentEID)
{ {
SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), parentEID)); //SetScrollTo(SHSerialization::DeserializeEntitiesFromString(SHClipboardUtilities::GetDataFromClipboard(), parentEID).front());
SHCommandManager::PerformCommand(std::make_shared<SHPasteEntitiesCommand>(SHClipboardUtilities::GetDataFromClipboard(), parentEID));
} }
void SHCreateEntityCommand::Execute() void SHHierarchyPanel::DeleteSelectedEntities()
{
EntityID newEID = SHEntityManager::CreateEntity(eid);
if (eid == MAX_EID)
eid = newEID;
}
void SHCreateEntityCommand::Undo()
{
SHEntityManager::DestroyEntity(eid);
}
void SHEntityParentCommand::Execute()
{ {
const auto editor = SHSystemManager::GetSystem<SHEditor>();
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
for (auto const& eid : entities)
std::vector<EntityID> entitiesToDelete{};
std::ranges::copy_if(editor->selectedEntities, std::back_inserter(entitiesToDelete), [&sceneGraph, &selectedEntities = editor->selectedEntities](EntityID const& eid)
{ {
if (entityParentData[eid].newParentEID == MAX_EID) EntityID parentEID = sceneGraph.GetParent(eid)->GetEntityID();
sceneGraph.SetParent(eid, nullptr); if (parentEID == MAX_EID)
else return true;
sceneGraph.SetParent(eid, entityParentData[eid].newParentEID); else if(std::ranges::find(selectedEntities, parentEID) == selectedEntities.end())
} return true;
return false;
});
SHCommandManager::PerformCommand(std::make_shared<SHDeleteEntitiesCommand>(entitiesToDelete));
} }
void SHEntityParentCommand::Undo()
{
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
for (auto const& eid : entities)
{
if (entityParentData[eid].oldParentEID == MAX_EID)
sceneGraph.SetParent(eid, nullptr);
else
sceneGraph.SetParent(eid, entityParentData[eid].oldParentEID);
}
}
}//namespace SHADE }//namespace SHADE

View File

@ -10,7 +10,6 @@
#include "imgui_internal.h" #include "imgui_internal.h"
#include "ECS_Base/SHECSMacros.h" #include "ECS_Base/SHECSMacros.h"
#include "Editor/EditorWindow/SHEditorWindow.h" #include "Editor/EditorWindow/SHEditorWindow.h"
#include "Editor/Command/SHCommand.hpp"
namespace SHADE namespace SHADE
{ {
class SHSceneNode; class SHSceneNode;
@ -33,6 +32,7 @@ namespace SHADE
void SelectAllEntities(); void SelectAllEntities();
void CopySelectedEntities(); void CopySelectedEntities();
void PasteEntities(EntityID parentEID = MAX_EID); void PasteEntities(EntityID parentEID = MAX_EID);
void DeleteSelectedEntities();
bool skipFrame = false; bool skipFrame = false;
std::string filter; std::string filter;
bool isAnyNodeSelected = false; bool isAnyNodeSelected = false;
@ -41,33 +41,4 @@ namespace SHADE
};//class SHHierarchyPanel };//class SHHierarchyPanel
//Might move to a different file
class SHCreateEntityCommand final : public SHBaseCommand
{
public:
void Execute() override;
void Undo() override;
private:
EntityID eid = MAX_EID;
};
class SHEntityParentCommand final : public SHBaseCommand
{
public:
struct Data
{
EntityID oldParentEID = MAX_EID;
EntityID newParentEID = MAX_EID;
};
using EntityParentData = std::unordered_map<EntityID, Data>;
SHEntityParentCommand(std::vector<EntityID> entityIDs, EntityParentData inEntityParentData):entities(entityIDs),entityParentData(inEntityParentData){}
void Execute() override;
void Undo() override;
private:
std::vector<EntityID> entities;
std::unordered_map<EntityID, Data> entityParentData;
};
}//namespace SHADE }//namespace SHADE

View File

@ -0,0 +1,84 @@
#include "SHpch.h"
#include "SHHierarchyPanelCommands.h"
#include "ECS_Base/Managers/SHEntityManager.h"
#include "Scene/SHSceneManager.h"
#include "Serialization/SHSerialization.h"
#include "SHHierarchyPanel.h"
#include "Editor/EditorWindow/SHEditorWindowManager.h"
namespace SHADE
{
void SHCreateEntityCommand::Execute()
{
EntityID newEID = SHEntityManager::CreateEntity(eid);
if (eid == MAX_EID)
eid = newEID;
}
void SHCreateEntityCommand::Undo()
{
SHEntityManager::DestroyEntity(eid);
}
void SHEntityParentCommand::Execute()
{
auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
for (auto const& eid : entities)
{
if (entityParentData[eid].newParentEID == MAX_EID)
sceneGraph.SetParent(eid, nullptr);
else
sceneGraph.SetParent(eid, entityParentData[eid].newParentEID);
}
}
void SHEntityParentCommand::Undo()
{
auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
for (auto const& eid : entities)
{
if (entityParentData[eid].oldParentEID == MAX_EID)
sceneGraph.SetParent(eid, nullptr);
else
sceneGraph.SetParent(eid, entityParentData[eid].oldParentEID);
}
}
void SHPasteEntitiesCommand::Execute()
{
data.createdEntities.clear();
data.createdEntities = SHSerialization::DeserializeEntitiesFromString(data.entityData, data.parentEID);
data.entityData = SHSerialization::ResolveSerializedEntityIndices(data.entityData, data.createdEntities);
SHEditorWindowManager::GetEditorWindow<SHHierarchyPanel>()->SetScrollTo(data.createdEntities.begin()->second);
}
void SHPasteEntitiesCommand::Undo()
{
for (auto const& [oldEID, newEID] : data.createdEntities)
{
SHEntityManager::DestroyEntity(newEID);
}
}
void SHDeleteEntitiesCommand::Execute()
{
if(!data.createdEntities.empty())
{
for(auto& eid : data.entitiesToDelete)
{
eid = data.createdEntities[eid];
}
}
data.entityData = SHSerialization::SerializeEntitiesToString(data.entitiesToDelete);
for (auto const& eid : data.entitiesToDelete)
{
SHEntityManager::DestroyEntity(eid);
}
}
void SHDeleteEntitiesCommand::Undo()
{
data.createdEntities = SHSerialization::DeserializeEntitiesFromString(data.entityData);
data.entityData = SHSerialization::ResolveSerializedEntityIndices(data.entityData, data.createdEntities);
}
}

View File

@ -0,0 +1,72 @@
#pragma once
#include <unordered_map>
#include "ECS_Base/SHECSMacros.h"
#include "Editor/Command/SHCommand.hpp"
#include "Serialization/SHSerialization.h"
namespace SHADE
{
class SHCreateEntityCommand final : public SHBaseCommand
{
public:
void Execute() override;
void Undo() override;
private:
EntityID eid = MAX_EID;
};
class SHEntityParentCommand final : public SHBaseCommand
{
public:
struct Data
{
EntityID oldParentEID = MAX_EID;
EntityID newParentEID = MAX_EID;
};
using EntityParentData = std::unordered_map<EntityID, Data>;
SHEntityParentCommand(std::vector<EntityID> entityIDs, EntityParentData inEntityParentData) :entities(entityIDs), entityParentData(inEntityParentData) {}
void Execute() override;
void Undo() override;
private:
std::vector<EntityID> entities{};
std::unordered_map<EntityID, Data> entityParentData{};
};
class SHPasteEntitiesCommand final : public SHBaseCommand
{
public:
struct Data
{
EntityID parentEID{MAX_EID};
std::string entityData{};
SHSerialization::CreatedEntitiesList createdEntities{};
};
SHPasteEntitiesCommand() = delete;
SHPasteEntitiesCommand(std::string const& serializedEntityData, EntityID parentEid = MAX_EID):data({parentEid, serializedEntityData, {}}){}
void Execute() override;
void Undo() override;
private:
Data data;
};
class SHDeleteEntitiesCommand final : public SHBaseCommand
{
public:
struct Data
{
std::vector<EntityID> entitiesToDelete{};
SHSerialization::CreatedEntitiesList createdEntities{};
std::string entityData{};
};
SHDeleteEntitiesCommand() = delete;
SHDeleteEntitiesCommand(std::vector<EntityID> entitiesToBeDeleted): data{entitiesToBeDeleted}{}
void Execute() override;
void Undo() override;
private:
Data data;
};
}

View File

@ -15,7 +15,7 @@
#include "Editor/SHEditorWidgets.hpp" #include "Editor/SHEditorWidgets.hpp"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h" #include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
#include "Physics/Components/SHColliderComponent.h" #include "Physics/Interface/SHColliderComponent.h"
#include "Reflection/SHReflectionMetadata.h" #include "Reflection/SHReflectionMetadata.h"
#include "Resource/SHResourceManager.h" #include "Resource/SHResourceManager.h"
@ -224,9 +224,6 @@ namespace SHADE
if (!component) if (!component)
return; return;
// Get transform component for extrapolating relative sizes
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(component->GetEID());
const auto componentType = rttr::type::get(*component); const auto componentType = rttr::type::get(*component);
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
ImGui::SameLine(); ImGui::SameLine();
@ -234,46 +231,39 @@ namespace SHADE
{ {
DrawContextMenu(component); DrawContextMenu(component);
auto& colliders = component->GetColliders(); auto& colliders = component->GetCollisionShapes();
int const size = static_cast<int>(colliders.size()); int const size = static_cast<int>(colliders.size());
ImGui::BeginChild("Colliders", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true); ImGui::BeginChild("Collision Shapes", { 0.0f, colliders.empty() ? 1.0f : 250.0f }, true);
std::optional<int> colliderToDelete{ std::nullopt }; std::optional<int> colliderToDelete{ std::nullopt };
for (int i{}; i < size; ++i) for (int i{}; i < size; ++i)
{ {
ImGui::PushID(i); ImGui::PushID(i);
SHCollider* collider = &component->GetCollider(i); SHCollisionShape* collider = &component->GetCollisionShape(i);
auto cursorPos = ImGui::GetCursorPos(); auto cursorPos = ImGui::GetCursorPos();
//collider->IsTrigger //collider->IsTrigger
if (collider->GetType() == SHCollider::Type::BOX) if (collider->GetType() == SHCollisionShape::Type::BOX)
{ {
SHEditorWidgets::BeginPanel(std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); SHEditorWidgets::BeginPanel(std::format("{} Box #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger"); const auto* BOX = reinterpret_cast<const SHBoundingBox*>(collider->GetShape());
auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
SHEditorWidgets::DragVec3 SHEditorWidgets::DragVec3
( (
"Half Extents", { "X", "Y", "Z" }, "Half Extents", { "X", "Y", "Z" },
[box, transformComponent] { return (box->GetHalfExtents() * 2.0f) / transformComponent->GetWorldScale(); }, [BOX] { return BOX->GetRelativeExtents(); },
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); }); [collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
} }
else if (collider->GetType() == SHCollider::Type::SPHERE) else if (collider->GetType() == SHCollisionShape::Type::SPHERE)
{ {
SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger"); const auto* SPHERE = reinterpret_cast<const SHBoundingSphere*>(collider->GetShape());
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
SHEditorWidgets::DragFloat SHEditorWidgets::DragFloat
( (
"Radius", "Radius",
[sphere, transformComponent] [SPHERE] { return SPHERE->GetRelativeRadius(); },
{
const SHVec3& TF_WORLD_SCALE = transformComponent->GetWorldScale();
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
return (sphere->GetRadius() / MAX_SCALE) * 2.0f;
},
[collider](float const& value) { collider->SetBoundingSphere(value); }); [collider](float const& value) { collider->SetBoundingSphere(value); });
} }
else if (collider->GetType() == SHCollider::Type::CAPSULE) else if (collider->GetType() == SHCollisionShape::Type::CAPSULE)
{ {
} }

View File

@ -14,8 +14,8 @@
#include "Scripting/SHScriptEngine.h" #include "Scripting/SHScriptEngine.h"
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Physics/Components/SHRigidBodyComponent.h" #include "Physics/Interface/SHRigidBodyComponent.h"
#include "Physics/Components/SHColliderComponent.h" #include "Physics/Interface/SHColliderComponent.h"
#include "Camera/SHCameraComponent.h" #include "Camera/SHCameraComponent.h"
#include "Camera/SHCameraArmComponent.h" #include "Camera/SHCameraArmComponent.h"
#include "SHEditorComponentView.h" #include "SHEditorComponentView.h"
@ -93,13 +93,14 @@ namespace SHADE
{ {
EntityID const& eid = editor->selectedEntities[0]; EntityID const& eid = editor->selectedEntities[0];
SHEntity* entity = SHEntityManager::GetEntityByID(eid); SHEntity* entity = SHEntityManager::GetEntityByID(eid);
if(!entity) SHSceneNode* entityNode = SHSceneManager::GetCurrentSceneGraph().GetNode(eid);
if(!entity || !entityNode)
{ {
ImGui::End(); ImGui::End();
return; return;
} }
ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid); ImGui::TextColored(ImGuiColors::green, "EID: %zu", eid);
SHEditorWidgets::CheckBox("##IsActive", [entity]()->bool {return entity->GetActive(); }, [entity](bool const& active) {entity->SetActive(active); }); SHEditorWidgets::CheckBox("##IsActive", [entityNode]()->bool {return entityNode->IsActive(); }, [entityNode](bool const& active) {entityNode->SetActive(active); });
ImGui::SameLine(); ImGui::SameLine();
ImGui::InputText("##EntityName", &entity->name); ImGui::InputText("##EntityName", &entity->name);

View File

@ -23,6 +23,9 @@
#include "Scene/SHSceneManager.h" #include "Scene/SHSceneManager.h"
#include "Serialization/SHSerialization.h" #include "Serialization/SHSerialization.h"
#include "Serialization/Configurations/SHConfigurationManager.h" #include "Serialization/Configurations/SHConfigurationManager.h"
#include "Editor/EditorWindow/SHEditorWindowManager.h"
const std::string LAYOUT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts" };
namespace SHADE namespace SHADE
{ {
@ -43,8 +46,7 @@ namespace SHADE
void SHEditorMenuBar::Init() void SHEditorMenuBar::Init()
{ {
SHEditorWindow::Init(); SHEditorWindow::Init();
constexpr std::string_view path = "../../Assets/Editor/Layouts"; for(auto const& entry : std::filesystem::directory_iterator(LAYOUT_FOLDER_PATH))
for(auto const& entry : std::filesystem::directory_iterator(path))
{ {
layoutPaths.push_back(entry.path()); layoutPaths.push_back(entry.path());
} }
@ -221,39 +223,20 @@ namespace SHADE
{ {
if(editor->SaveScene()) if(editor->SaveScene())
{ {
const SHEditorStateChangeEvent STATE_CHANGE_EVENT editor->Play();
{
.previousState = editor->editorState
};
editor->editorState = SHEditor::State::PLAY;
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
} }
} }
ImGui::EndDisabled(); ImGui::EndDisabled();
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE); ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE);
if(ImGui::SmallButton(ICON_MD_PAUSE)) if(ImGui::SmallButton(ICON_MD_PAUSE))
{ {
const SHEditorStateChangeEvent STATE_CHANGE_EVENT editor->Pause();
{
.previousState = editor->editorState
};
editor->editorState = SHEditor::State::PAUSE;
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT);
} }
ImGui::EndDisabled(); ImGui::EndDisabled();
ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP); ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP);
if(ImGui::SmallButton(ICON_MD_STOP)) if(ImGui::SmallButton(ICON_MD_STOP))
{ {
const SHEditorStateChangeEvent STATE_CHANGE_EVENT editor->Stop();
{
.previousState = editor->editorState
};
editor->editorState = SHEditor::State::STOP;
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
editor->LoadScene(SHSceneManager::GetCurrentSceneAssetID());
} }
ImGui::EndDisabled(); ImGui::EndDisabled();
ImGui::EndMenuBar(); ImGui::EndMenuBar();

View File

@ -0,0 +1,8 @@
#include "SHpch.h"
#include "SHEditorWindowManager.h"
namespace SHADE
{
SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{};
SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{};
}

View File

@ -0,0 +1,77 @@
#pragma once
#include <memory>
#include <unordered_map>
#include "SHEditorWindow.h"
#include "Tools/SHLog.h"
namespace SHADE
{
class SH_API SHEditorWindowManager
{
public:
//#==============================================================#
//|| Type Aliases ||
//#==============================================================#
using EditorWindowID = uint8_t;
using EditorWindowPtr = std::unique_ptr<SHEditorWindow>;
using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>;
/**
* @brief Get ID for the Editor Window Type
*
* @tparam T Type of Editor Window
* @return EditorWindowID ID of Editor Window Type
*/
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
static EditorWindowID GetEditorWindowID()
{
static EditorWindowID id;
static bool idCreated = false;
if (!idCreated)
{
id = windowCount++;
idCreated = true;
}
return id;
}
/**
* @brief Create an Editor Window
*
* @tparam T Type of Editor Window to create
*/
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
static void CreateEditorWindow()
{
static bool isCreated = false;
if (!isCreated)
{
editorWindows[GetEditorWindowID<T>()] = std::make_unique<T>();
isCreated = true;
}
else
{
SHLog::Warning("Attempt to create duplicate of Editor window type");
}
}
/**
* @brief Get pointer to the Editor Window
*
* @tparam T Type of editor window to retrieve
* @return T* Pointer to the editor window
*/
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
static T* GetEditorWindow()
{
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
}
static EditorWindowMap editorWindows;
private:
// Number of windows; used for Editor Window ID Generation
static EditorWindowID windowCount;
// Map of Editor Windows
friend class SHEditor;
};
}

View File

@ -33,12 +33,31 @@ namespace SHADE
void SHEditorViewport::Update() void SHEditorViewport::Update()
{ {
SHEditorWindow::Update(); SHEditorWindow::Update();
if (shouldUpdateCamera)
{
auto camSystem = SHSystemManager::GetSystem<SHCameraSystem>(); auto camSystem = SHSystemManager::GetSystem<SHCameraSystem>();
SHEditor* editor = SHSystemManager::GetSystem<SHEditor>();
if (!editor->selectedEntities.empty())
{
if (SHTransformComponent* transform = SHComponentManager::GetComponent_s<SHTransformComponent>(editor->selectedEntities.front()))
{
targetPos = transform->GetWorldPosition();
}
else
{
targetPos = {};
}
}
else
{
targetPos = {};
}
if (shouldUpdateCamera || shouldUpdateCamArm)
{
camSystem->UpdateEditorCamera(SHFrameRateController::GetRawDeltaTime()); camSystem->UpdateEditorCamera(SHFrameRateController::GetRawDeltaTime());
shouldUpdateCamera = false; shouldUpdateCamera = false;
} }
camSystem->UpdateEditorArm(SHFrameRateController::GetRawDeltaTime(), shouldUpdateCamArm, targetPos);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
if (Begin()) if (Begin())
@ -51,7 +70,6 @@ namespace SHADE
beginCursorPos = ImGui::GetCursorScreenPos(); beginCursorPos = ImGui::GetCursorScreenPos();
viewportMousePos = { mousePos.x - beginCursorPos.x, mousePos.y - beginCursorPos.y }; viewportMousePos = { mousePos.x - beginCursorPos.x, mousePos.y - beginCursorPos.y };
gfxSystem->GetMousePickSystem()->SetViewportMousePos(viewportMousePos); gfxSystem->GetMousePickSystem()->SetViewportMousePos(viewportMousePos);
ImGui::Image((ImTextureID)descriptorSet, { beginContentRegionAvailable.x, beginContentRegionAvailable.y }); ImGui::Image((ImTextureID)descriptorSet, { beginContentRegionAvailable.x, beginContentRegionAvailable.y });
if (ImGui::IsWindowHovered() && ImGui::IsMouseDown(ImGuiMouseButton_Right)) if (ImGui::IsWindowHovered() && ImGui::IsMouseDown(ImGuiMouseButton_Right))
@ -64,23 +82,27 @@ namespace SHADE
shouldUpdateCamera = true; shouldUpdateCamera = true;
} }
if (ImGui::IsWindowFocused() && !ImGui::IsMouseDown(ImGuiMouseButton_Right))
shouldUpdateCamArm = ImGui::IsWindowHovered() && ImGui::IsKeyDown(ImGuiKey_LeftAlt) && ImGui::IsMouseDown(ImGuiMouseButton_Left);
if (editor->editorState != SHEditor::State::PLAY && ImGui::IsWindowFocused() && !ImGui::IsMouseDown(ImGuiMouseButton_Right))
{ {
if (ImGui::IsKeyReleased(ImGuiKey_Q)) if (ImGui::IsKeyReleased(ImGuiKey_W))
{ {
transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE; transformGizmo.operation = SHTransformGizmo::Operation::TRANSLATE;
} }
if (ImGui::IsKeyReleased(ImGuiKey_W)) if (ImGui::IsKeyReleased(ImGuiKey_E))
{ {
transformGizmo.operation = SHTransformGizmo::Operation::ROTATE; transformGizmo.operation = SHTransformGizmo::Operation::ROTATE;
} }
if (ImGui::IsKeyReleased(ImGuiKey_E)) if (ImGui::IsKeyReleased(ImGuiKey_R))
{ {
transformGizmo.operation = SHTransformGizmo::Operation::SCALE; transformGizmo.operation = SHTransformGizmo::Operation::SCALE;
} }
} }
} }
ImGuizmo::SetRect(beginCursorPos.x, beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y); ImGuizmo::SetRect(beginCursorPos.x, beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
if(editor->editorState != SHEditor::State::PLAY)
transformGizmo.Draw(); transformGizmo.Draw();
ImGui::End(); ImGui::End();
ImGui::PopStyleVar(); ImGui::PopStyleVar();

View File

@ -29,5 +29,7 @@ namespace SHADE
void DrawMenuBar() noexcept; void DrawMenuBar() noexcept;
SHVec2 beginCursorPos; SHVec2 beginCursorPos;
bool shouldUpdateCamera = false; bool shouldUpdateCamera = false;
bool shouldUpdateCamArm = false;
SHVec3 targetPos;
};//class SHEditorViewport };//class SHEditorViewport
}//namespace SHADE }//namespace SHADE

View File

@ -11,6 +11,8 @@
#include "Camera/SHCameraSystem.h" #include "Camera/SHCameraSystem.h"
#include "Editor/Command/SHCommandManager.h" #include "Editor/Command/SHCommandManager.h"
#include "Editor/EditorWindow/ViewportWindow/SHEditorViewport.h" #include "Editor/EditorWindow/ViewportWindow/SHEditorViewport.h"
#include "Editor/EditorWindow/SHEditorWindowManager.h"
namespace SHADE namespace SHADE
{ {
void SHTransformGizmo::Init() void SHTransformGizmo::Init()

View File

@ -29,6 +29,7 @@
//#==============================================================# //#==============================================================#
//|| Editor Window Includes || //|| Editor Window Includes ||
//#==============================================================# //#==============================================================#
#include "EditorWindow/SHEditorWindowManager.h"
#include "EditorWindow/SHEditorWindowIncludes.h" #include "EditorWindow/SHEditorWindowIncludes.h"
//#==============================================================# //#==============================================================#
@ -65,6 +66,10 @@ RTTR_REGISTRATION
); );
} }
const std::string USER_LAYOUT_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts/UserLayout.ini" };
const std::string DEFAULT_LAYOUT_PATH{ std::string(ASSET_ROOT) + "/Editor/Layouts/Default.ini" };
const std::string FONT_FOLDER_PATH{ std::string(ASSET_ROOT) + "/Editor/Fonts/"};
namespace SHADE namespace SHADE
{ {
@ -73,8 +78,6 @@ namespace SHADE
//#==============================================================# //#==============================================================#
//Handle<SHVkCommandPool> SHEditor::imguiCommandPool; //Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
//Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer; //Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer;
SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{};
SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{};
//std::vector<EntityID> SHEditor::selectedEntities; //std::vector<EntityID> SHEditor::selectedEntities;
//#==============================================================# //#==============================================================#
@ -106,7 +109,7 @@ namespace SHADE
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini"; io->IniFilename = USER_LAYOUT_PATH.data();
io->ConfigWindowsMoveFromTitleBarOnly = true; io->ConfigWindowsMoveFromTitleBarOnly = true;
InitLayout(); InitLayout();
@ -164,6 +167,18 @@ namespace SHADE
{ {
SHCommandManager::UndoCommand(); SHCommandManager::UndoCommand();
} }
if(ImGui::IsKeyReleased(ImGuiKey_F5))
{
Play();
}
else if (ImGui::IsKeyReleased(ImGuiKey_F6))
{
Pause();
}
else if (ImGui::IsKeyReleased(ImGuiKey_F7))
{
Stop();
}
Render(); Render();
} }
@ -236,20 +251,20 @@ namespace SHADE
{ {
if(!std::filesystem::exists(io->IniFilename)) if(!std::filesystem::exists(io->IniFilename))
{ {
std::filesystem::copy_file("../../Assets/Editor/Layouts/Default.ini", io->IniFilename); std::filesystem::copy_file(DEFAULT_LAYOUT_PATH.data(), io->IniFilename);
} }
//eventually load preferred layout here //eventually load preferred layout here
} }
void SHEditor::InitFonts() noexcept void SHEditor::InitFonts() noexcept
{ {
ImFont* mainFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path ImFont* mainFont = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "Segoe UI.ttf").data(), 20.f);//TODO: Change to config based assets path
ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f; ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 }; constexpr ImWchar icon_ranges_fa[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/fa-solid-900.ttf", 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path ImFont* UIFontFA = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "fa-solid-900.ttf").data(), 20.f, &icons_config, icon_ranges_fa); //TODO: Change to config based assets path
constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 }; constexpr ImWchar icon_ranges_md[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path ImFont* UIFontMD = io->Fonts->AddFontFromFileTTF(std::string(FONT_FOLDER_PATH + "MaterialIcons-Regular.ttf").data(), 20.f, &icons_config, icon_ranges_md); //TODO: Change to config based assets path
io->Fonts->Build(); io->Fonts->Build();
} }
@ -501,8 +516,11 @@ namespace SHADE
ImGui_ImplVulkan_DestroyFontUploadObjects(); ImGui_ImplVulkan_DestroyFontUploadObjects();
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd) { renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer>& cmd)
{
cmd->BeginLabeledSegment("ImGui Draw");
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer()); ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
cmd->EndLabeledSegment();
}); });
#endif #endif
} }
@ -590,6 +608,48 @@ namespace SHADE
} }
} }
void SHEditor::Play()
{
if(editorState == State::PLAY)
return;
if (SaveScene())
{
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
{
.previousState = editorState
};
editorState = State::PLAY;
SHCommandManager::SwapStacks();
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
}
}
void SHEditor::Pause()
{
if (editorState == State::PAUSE)
return;
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
{
.previousState = editorState
};
editorState = State::PAUSE;
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT);
}
void SHEditor::Stop()
{
if (editorState == State::STOP)
return;
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
{
.previousState = editorState
};
editorState = SHEditor::State::STOP;
SHCommandManager::SwapStacks();
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
LoadScene(SHSceneManager::GetCurrentSceneAssetID());
}
void SHEditor::NewFrame() void SHEditor::NewFrame()
{ {
SDL_Event event; SDL_Event event;

View File

@ -36,73 +36,7 @@ namespace SHADE
class SHVkCommandBuffer; class SHVkCommandBuffer;
class SHVkCommandPool; class SHVkCommandPool;
class SHEditorWindowManager
{
public:
//#==============================================================#
//|| Type Aliases ||
//#==============================================================#
using EditorWindowID = uint8_t;
using EditorWindowPtr = std::unique_ptr<SHEditorWindow>;
using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>;
/**
* @brief Get ID for the Editor Window Type
*
* @tparam T Type of Editor Window
* @return EditorWindowID ID of Editor Window Type
*/
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
static EditorWindowID GetEditorWindowID()
{
static EditorWindowID id;
static bool idCreated = false;
if (!idCreated)
{
id = windowCount++;
idCreated = true;
}
return id;
}
/**
* @brief Create an Editor Window
*
* @tparam T Type of Editor Window to create
*/
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
static void CreateEditorWindow()
{
static bool isCreated = false;
if (!isCreated)
{
editorWindows[GetEditorWindowID<T>()] = std::make_unique<T>();
isCreated = true;
}
else
{
SHLog::Warning("Attempt to create duplicate of Editor window type");
}
}
/**
* @brief Get pointer to the Editor Window
*
* @tparam T Type of editor window to retrieve
* @return T* Pointer to the editor window
*/
template <typename T, std::enable_if_t<std::is_base_of_v<SHEditorWindow, T>, bool> = true>
static T* GetEditorWindow()
{
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
}
static EditorWindowMap editorWindows;
private:
// Number of windows; used for Editor Window ID Generation
static EditorWindowID windowCount;
// Map of Editor Windows
friend class SHEditor;
};
/** /**
* @brief SHEditor static class contains editor variables and implementation of editor functions. * @brief SHEditor static class contains editor variables and implementation of editor functions.
@ -184,6 +118,10 @@ namespace SHADE
void LoadScene(AssetID const& assetID) noexcept; void LoadScene(AssetID const& assetID) noexcept;
void Play();
void Pause();
void Stop();
// List of selected entities // List of selected entities
std::vector<EntityID> selectedEntities; std::vector<EntityID> selectedEntities;

View File

@ -53,9 +53,12 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* ImGui Wrapper Functions - Organizers */ /* ImGui Wrapper Functions - Organizers */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
bool SHEditorUI::CollapsingHeader(const std::string& title) bool SHEditorUI::CollapsingHeader(const std::string& title, bool* isHovered)
{ {
return ImGui::CollapsingHeader(title.c_str(), ImGuiTreeNodeFlags_DefaultOpen); const bool OPENED = ImGui::CollapsingHeader(title.c_str(), ImGuiTreeNodeFlags_DefaultOpen);
if (isHovered)
*isHovered = ImGui::IsItemHovered();
return OPENED;
} }
void SHEditorUI::SameLine() void SHEditorUI::SameLine()
@ -165,8 +168,10 @@ namespace SHADE
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::InputInt("##", &value, return ImGui::DragInt("##", &value, 0.001f,
1, 10, std::numeric_limits<int>::min(),
std::numeric_limits<int>::max(),
"%d",
ImGuiInputTextFlags_EnterReturnsTrue); ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered) bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered)
@ -190,31 +195,22 @@ namespace SHADE
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::InputFloat("##", &value, return ImGui::DragFloat("##", &value, 0.001f,
0.1f, 1.0f, "%.3f", std::numeric_limits<float>::lowest(),
std::numeric_limits<float>::max(),
"%.3f",
ImGuiInputTextFlags_EnterReturnsTrue); ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputDouble(const std::string& label, double& value, bool* isHovered) bool SHEditorUI::InputDouble(const std::string& label, double& value, bool* isHovered)
{ {
ImGui::Text(label.c_str()); float val = value;
if (isHovered) const bool CHANGED = InputFloat(label, val, isHovered);
*isHovered = ImGui::IsItemHovered(); if (CHANGED)
ImGui::SameLine();
return ImGui::InputDouble("##", &value,
0.1, 1.0, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
}
bool SHEditorUI::InputAngle(const std::string& label, double& value, bool* isHovered)
{ {
ImGui::Text(label.c_str()); value = static_cast<double>(val);
if (isHovered) }
*isHovered = ImGui::IsItemHovered(); return CHANGED;
ImGui::SameLine();
return ImGui::InputDouble("##", &value,
1.0, 45.0, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputSlider(const std::string& label, int min, int max, int& value, bool* isHovered /*= nullptr*/) bool SHEditorUI::InputSlider(const std::string& label, int min, int max, int& value, bool* isHovered /*= nullptr*/)
{ {
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
@ -266,10 +262,10 @@ namespace SHADE
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y" }; static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y" };
return SHEditorWidgets::DragN<float, 2>(label, COMPONENT_LABELS, { &value.x, &value.y }, 0.1f, "%.3f", float{}, float{}, 0, isHovered); return SHEditorWidgets::DragN<float, 2>(label, COMPONENT_LABELS, { &value.x, &value.y }, 0.1f, "%.3f", float{}, float{}, 0, isHovered);
} }
bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, bool* isHovered, float speed) bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, bool* isHovered)
{ {
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y", "Z"}; static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y", "Z"};
return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, speed, "%.3f", float{}, float{}, 0, isHovered); return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, 0.1f, "%.3f", float{}, float{}, 0, isHovered);
} }
bool SHEditorUI::InputTextField(const std::string& label, std::string& value, bool* isHovered) bool SHEditorUI::InputTextField(const std::string& label, std::string& value, bool* isHovered)
@ -288,7 +284,7 @@ namespace SHADE
return CHANGED; return CHANGED;
} }
bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered) bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered, bool alwaysNull)
{ {
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered) if (isHovered)
@ -296,7 +292,7 @@ namespace SHADE
ImGui::SameLine(); ImGui::SameLine();
SHEntity* entity = SHEntityManager::GetEntityByID(value); SHEntity* entity = SHEntityManager::GetEntityByID(value);
std::ostringstream oss; std::ostringstream oss;
if (entity) if (!alwaysNull && entity)
{ {
oss << value << ": " << entity->name; oss << value << ": " << entity->name;
} }
@ -314,6 +310,13 @@ namespace SHADE
SHDragDrop::EndTarget(); SHDragDrop::EndTarget();
} }
} }
ImGui::SameLine();
if (ImGui::Button("Clear"))
{
value = MAX_EID;
changed = true;
}
return changed; return changed;
} }

View File

@ -85,8 +85,9 @@ namespace SHADE
/// Wraps up ImGui::CollapsingHeader(). /// Wraps up ImGui::CollapsingHeader().
/// </summary> /// </summary>
/// <param name="title">Label for the header.</param> /// <param name="title">Label for the header.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the header is open, false otherwise.</returns> /// <returns>True if the header is open, false otherwise.</returns>
static bool CollapsingHeader(const std::string& title); static bool CollapsingHeader(const std::string& title, bool* isHovered = nullptr);
static void SameLine(); static void SameLine();
static void Separator(); static void Separator();
@ -219,17 +220,6 @@ namespace SHADE
/// <returns>True if the value was changed.</returns> /// <returns>True if the value was changed.</returns>
static bool InputDouble(const std::string& label, double& value, bool* isHovered = nullptr); static bool InputDouble(const std::string& label, double& value, bool* isHovered = nullptr);
/// <summary> /// <summary>
/// Creates a decimal field widget for double input with increments of higher
/// steps meant for angle variables.
/// <br/>
/// Wraps up ImGui::InputDouble().
/// </summary>
/// <param name="label">Label used to identify this widget.</param>
/// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns>
static bool InputAngle(const std::string& label, double& value, bool* isHovered = nullptr);
/// <summary>
/// Creates an int slider field widget for double input. /// Creates an int slider field widget for double input.
/// <br/> /// <br/>
/// Wraps up ImGui::SliderInt(). /// Wraps up ImGui::SliderInt().
@ -296,7 +286,7 @@ namespace SHADE
/// <param name="value">Reference to the variable to store the result.</param> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param> /// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns> /// <returns>True if the value was changed.</returns>
static bool InputVec3(const std::string& label, SHVec3& value, bool* isHovered = nullptr, float speed = 0.1f); static bool InputVec3(const std::string& label, SHVec3& value, bool* isHovered = nullptr);
/// <summary> /// <summary>
/// Creates a text field widget for string input. /// Creates a text field widget for string input.
/// <br/> /// <br/>
@ -313,8 +303,12 @@ namespace SHADE
/// <param name="label">Label used to identify this widget.</param> /// <param name="label">Label used to identify this widget.</param>
/// <param name="value">Reference to the variable to store the result.</param> /// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param> /// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <param name="alwaysNull>
/// If set, the field displayed will always be blank regardless of specified
/// GameObject.
/// </param>
/// <returns>True if the value was changed.</returns> /// <returns>True if the value was changed.</returns>
static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr); static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr, bool alwaysNull = false);
/// <summary> /// <summary>
/// Creates a combo box for enumeration input. /// Creates a combo box for enumeration input.
/// </summary> /// </summary>

View File

@ -11,9 +11,11 @@ constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 };
constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 }; constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 };
constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 }; constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 }; constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 6 }; constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 6 };
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 7 }; constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 7 };
constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 8 }; constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 8 };
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 9 }; constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 9 };
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 10 }; constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 10 };
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 11 };
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 12 };

View File

@ -12,6 +12,7 @@
#include "SHFileSystem.h" #include "SHFileSystem.h"
#include <filesystem> #include <filesystem>
#include <queue> #include <queue>
#include <stack>
#include "Assets/SHAssetMetaHandler.h" #include "Assets/SHAssetMetaHandler.h"
@ -24,29 +25,94 @@ namespace SHADE
return true; return true;
} }
void SHFileSystem::BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept bool SHFileSystem::IsRecognised(char const* ext) noexcept
{ {
std::queue<FolderPointer> folderQueue; for (auto const& e : EXTENSIONS)
{
if (strcmp(ext, e.data()) == 0)
{
return true;
}
}
return false;
}
bool SHFileSystem::IsCompilable(std::string ext) noexcept
{
for (auto const& external : EXTERNALS)
{
if (ext == external)
{
return true;
}
}
return false;
}
bool SHFileSystem::MatchExtention(FileExt raw, FileExt compiled) noexcept
{
if (raw == GLSL_EXTENSION)
{
if (compiled == SHADER_EXTENSION ||
compiled == SHADER_BUILT_IN_EXTENSION)
{
return true;
}
}
else if (raw == DDS_EXTENSION)
{
if (compiled == TEXTURE_EXTENSION)
{
return true;
}
}
else if (raw == FBX_EXTENSION)
{
if (compiled == MODEL_EXTENSION)
{
return true;
}
}
else if (raw == GLTF_EXTENSION)
{
if (compiled == MODEL_EXTENSION)
{
return true;
}
}
return false;
}
void SHFileSystem::BuildDirectory(
FolderPath path,
FolderPointer& root,
std::unordered_map<AssetID, SHAsset>& assetCollection,
std::vector<SHFile*>& toGenerate) noexcept
{
std::stack<FolderPointer> folderStack;
root = new SHFolder("root"); root = new SHFolder("root");
root->path = path; root->path = path;
folderQueue.push(root); folderStack.push(root);
while (!folderQueue.empty()) while (!folderStack.empty())
{ {
auto const folder = folderQueue.front(); auto const folder = folderStack.top();
folderQueue.pop(); folderStack.pop();
std::vector<SHAsset> assets; std::vector<SHAsset> assets;
for (auto const& dirEntry : std::filesystem::directory_iterator(folder->path)) // Get all subfolders/files in this current folder
for (auto& dirEntry : std::filesystem::directory_iterator(folder->path))
{ {
auto const& path = dirEntry.path(); auto path = dirEntry.path();
path.make_preferred();
if (!dirEntry.is_directory()) if (!dirEntry.is_directory())
{ {
if (path.extension().string() == META_EXTENSION) if (path.extension().string() == META_EXTENSION)
{ {
//auto asset = SHAssetMetaHandler::RetrieveMetaData(path);
//assetCollection.insert({ asset.id, asset });
assets.push_back(SHAssetMetaHandler::RetrieveMetaData(path)); assets.push_back(SHAssetMetaHandler::RetrieveMetaData(path));
} }
else else
@ -55,28 +121,114 @@ namespace SHADE
path.stem().string(), path.stem().string(),
path.string(), path.string(),
path.extension().string(), path.extension().string(),
nullptr nullptr,
IsCompilable(path.extension().string()),
false
); );
} }
continue; continue;
} }
auto newFolder{ folder->CreateSubFolderHere(path.stem().string()) }; // If item is folder
folderQueue.push(newFolder); if (path.stem().string() == "bin"
|| path.stem().string() == "obj"
|| !std::filesystem::exists(path))
{
SHLOG_INFO("[FileSystem] Skipped paths in directory building: {}", path.string());
continue;
} }
auto newFolder{ folder->CreateSubFolderHere(path.stem().string()) };
folderStack.push(newFolder);
}
for (auto& file : folder->files)
{
if (!IsRecognised(file.ext.c_str()))
{
continue;
}
bool found{ false };
for (auto const& asset : assets) for (auto const& asset : assets)
{ {
assetCollection.emplace(asset.id, asset); assetCollection.emplace(asset.id, asset);
for(auto& file : folder->files)
{
if (file.name == asset.name) if (file.name == asset.name)
{
AssetPath path{ file.path };
if (SHAssetMetaHandler::GetTypeFromExtension(path.extension().string()) == asset.type)
{ {
file.assetMeta = &assetCollection[asset.id]; file.assetMeta = &assetCollection[asset.id];
found = true;
break; break;
} }
} }
} }
if (!found)
{
toGenerate.push_back(&file);
}
}
//for (auto const& asset : assets)
//{
// assetCollection.emplace(asset.id, asset);
// for(auto& file : folder->files)
// {
// if (file.name == asset.name)
// {
// AssetPath path{ file.path };
// if (SHAssetMetaHandler::GetTypeFromExtension(path.extension().string()) == asset.type)
// {
// file.assetMeta = &assetCollection[asset.id];
// break;
// }
// }
// }
//}
for (auto i {0}; i < folder->files.size(); ++i)
{
auto& file = folder->files[i];
if (file.compilable)
{
for (auto j{ 0 }; j < folder->files.size(); ++j)
{
auto& check = folder->files[j];
if (i == j || check.compilable)
{
continue;
}
if (file.name == check.name)
{
if (MatchExtention(file.ext, check.ext))
{
file.compiled = true;
}
}
}
}
}
}
}
void SHFileSystem::DestroyDirectory(FolderPointer root) noexcept
{
std::stack<FolderPointer> folderStack;
folderStack.push(root);
while(!folderStack.empty())
{
auto const folder = folderStack.top();
folderStack.pop();
for (auto const& ptr : folder->subFolders)
{
folderStack.push(ptr);
}
delete folder;
} }
} }
} }

View File

@ -19,10 +19,17 @@ namespace SHADE
class SHFileSystem class SHFileSystem
{ {
public: public:
static void BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept; static void BuildDirectory(
FolderPath path,
FolderPointer& root,
std::unordered_map<AssetID, SHAsset>& assetCollection,
std::vector<SHFile*>& toGenerate) noexcept;
static void DestroyDirectory(FolderPointer root) noexcept;
static bool IsRecognised(char const*) noexcept;
private: private:
static bool DeleteFolder(FolderPointer location) noexcept; static bool DeleteFolder(FolderPointer location) noexcept;
static bool IsCompilable(std::string ext) noexcept;
static bool MatchExtention(FileExt raw, FileExt compiled) noexcept;
}; };
} }

View File

@ -33,6 +33,8 @@ namespace SHADE
FilePath path; FilePath path;
FileExt ext; FileExt ext;
SHAsset const* assetMeta; SHAsset const* assetMeta;
bool compilable;
bool compiled;
}; };
class SHFolder class SHFolder

View File

@ -221,9 +221,11 @@ namespace SHADE
&bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use RenderDoc to check buffer variables?) &bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use RenderDoc to check buffer variables?)
&allocCreateInfo, &allocCreateInfo,
&tempBuffer, &stagingAlloc, &allocInfo); &tempBuffer, &stagingAlloc, &allocInfo);
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] Staging - " + name);
// then assign it to the hpp version // then assign it to the hpp version
stagingBuffer = tempBuffer; stagingBuffer = tempBuffer;
SET_VK_OBJ_NAME(device, vk::ObjectType::eBuffer, stagingBuffer, "[Buffer] Staging - " + name);
// Just map, copy then unmap // Just map, copy then unmap
void* stagingBufferMappedPtr = nullptr; void* stagingBufferMappedPtr = nullptr;
@ -256,6 +258,10 @@ namespace SHADE
&bufferCreateInfo.operator VkBufferCreateInfo & (), &bufferCreateInfo.operator VkBufferCreateInfo & (),
&allocCreateInfo, &allocCreateInfo,
&tempBuffer, &alloc, &allocInfo); &tempBuffer, &alloc, &allocInfo);
#ifdef _DEBUG
if (!name.empty())
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] " + name);
#endif
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan buffer. "); SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan buffer. ");
@ -273,7 +279,7 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
SHVkBuffer::SHVkBuffer(std::reference_wrapper<VmaAllocator const> allocator) noexcept SHVkBuffer::SHVkBuffer(Handle<SHVkLogicalDevice> logicalDevice, std::reference_wrapper<VmaAllocator const> allocator) noexcept
: vkBuffer{} : vkBuffer{}
, stagingBuffer{} , stagingBuffer{}
, sizeStored{ 0 } , sizeStored{ 0 }
@ -281,19 +287,23 @@ namespace SHADE
, alloc {nullptr} , alloc {nullptr}
, randomAccessOptimized{false} , randomAccessOptimized{false}
, vmaAllocator{allocator} , vmaAllocator{allocator}
, device { logicalDevice }
{} {}
SHVkBuffer::SHVkBuffer( SHVkBuffer::SHVkBuffer(
Handle<SHVkLogicalDevice> logicalDevice,
uint32_t inSize, uint32_t inSize,
void* data, void* data,
uint32_t srcSize, uint32_t srcSize,
std::reference_wrapper<VmaAllocator const> allocator, std::reference_wrapper<VmaAllocator const> allocator,
vk::BufferUsageFlags bufferUsage, vk::BufferUsageFlags bufferUsage,
const std::string& name,
VmaMemoryUsage memUsage, VmaMemoryUsage memUsage,
VmaAllocationCreateFlags allocFlags VmaAllocationCreateFlags allocFlags
) noexcept ) noexcept
: SHVkBuffer(allocator) : SHVkBuffer(logicalDevice, allocator)
{ {
this->name = name;
Init(inSize, data, srcSize, bufferUsage, memUsage, allocFlags); Init(inSize, data, srcSize, bufferUsage, memUsage, allocFlags);
} }
@ -308,6 +318,8 @@ namespace SHADE
, bufferUsageFlags {rhs.bufferUsageFlags} , bufferUsageFlags {rhs.bufferUsageFlags}
, bufferCreateInfo { rhs.bufferCreateInfo } , bufferCreateInfo { rhs.bufferCreateInfo }
, allocCreateInfo { rhs.allocCreateInfo } , allocCreateInfo { rhs.allocCreateInfo }
, name { std::move(rhs.name) }
, device { rhs.device }
{ {
rhs.vkBuffer = VK_NULL_HANDLE; rhs.vkBuffer = VK_NULL_HANDLE;
@ -329,6 +341,8 @@ namespace SHADE
bufferCreateInfo = rhs.bufferCreateInfo; bufferCreateInfo = rhs.bufferCreateInfo;
allocCreateInfo = rhs.allocCreateInfo; allocCreateInfo = rhs.allocCreateInfo;
bufferUsageFlags = rhs.bufferUsageFlags; bufferUsageFlags = rhs.bufferUsageFlags;
name = std::move(rhs.name);
device = rhs.device;
return *this; return *this;
} }
@ -406,6 +420,8 @@ namespace SHADE
auto [tempBuffer, allocInfo] = createBuffer(sizeStored); auto [tempBuffer, allocInfo] = createBuffer(sizeStored);
vkBuffer = tempBuffer; vkBuffer = tempBuffer;
if (!name.empty())
SET_VK_OBJ_NAME(device, vk::ObjectType::eBuffer, vkBuffer, "[Buffer] " + name);
// This probably means that a HOST_CACHED memory type is used on allocation // This probably means that a HOST_CACHED memory type is used on allocation
if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT) if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)

View File

@ -12,6 +12,7 @@ namespace SHADE
//using SHVkBufferUsageBits = vk::BufferUsageFlagBits; //using SHVkBufferUsageBits = vk::BufferUsageFlagBits;
class SHVkCommandBuffer; class SHVkCommandBuffer;
class SHVkLogicalDevice;
class SHVkBuffer class SHVkBuffer
{ {
@ -51,6 +52,11 @@ namespace SHADE
//VmaAllocator const& vmaAllocator; //VmaAllocator const& vmaAllocator;
std::reference_wrapper<VmaAllocator const> vmaAllocator; std::reference_wrapper<VmaAllocator const> vmaAllocator;
//! Name of this buffer if any
std::string name;
//! Handle to the logical device that created this buffer
Handle<SHVkLogicalDevice> device;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -62,13 +68,15 @@ namespace SHADE
/* CTORS AND DTORS */ /* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
SHVkBuffer (void) noexcept = delete; SHVkBuffer (void) noexcept = delete;
SHVkBuffer (std::reference_wrapper<VmaAllocator const> allocator) noexcept; SHVkBuffer (Handle<SHVkLogicalDevice> logicalDevice, std::reference_wrapper<VmaAllocator const> allocator) noexcept;
SHVkBuffer ( SHVkBuffer (
Handle<SHVkLogicalDevice> logicalDevice,
uint32_t inSize, uint32_t inSize,
void* data, void* data,
uint32_t srcSize, uint32_t srcSize,
std::reference_wrapper<VmaAllocator const> allocator, std::reference_wrapper<VmaAllocator const> allocator,
vk::BufferUsageFlags bufferUsage, vk::BufferUsageFlags bufferUsage,
const std::string& name = "",
VmaMemoryUsage memUsage = VMA_MEMORY_USAGE_AUTO, VmaMemoryUsage memUsage = VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlags allocFlags = {} VmaAllocationCreateFlags allocFlags = {}
) noexcept; ) noexcept;

View File

@ -105,6 +105,9 @@ namespace SHADE
// Set the state to recording if the call above succeeded. // Set the state to recording if the call above succeeded.
cmdBufferState = SH_CMD_BUFFER_STATE::RECORDING; cmdBufferState = SH_CMD_BUFFER_STATE::RECORDING;
// Reset segment count
segmentDepth = 0;
} }
/***************************************************************************/ /***************************************************************************/
@ -507,6 +510,41 @@ namespace SHADE
SetState(SH_CMD_BUFFER_STATE::PENDING); SetState(SH_CMD_BUFFER_STATE::PENDING);
} }
void SHVkCommandBuffer::BeginLabeledSegment(const std::string& label) noexcept
{
#ifdef _DEBUG
static const std::array SEGMENT_COLOURS =
{
SHColour::LIGHTPINK,
SHColour::LIGHTBLUE,
SHColour::LIGHTGREEN,
SHColour::YELLOW,
SHColour::PINK,
SHColour::TEAL,
SHColour::LIME,
SHColour::ORANGE,
SHColour::VIOLET,
SHColour::MAROON,
SHColour::DARKGREEN,
SHColour::SANDYBROWN
};
const SHColour COLOR = SEGMENT_COLOURS[segmentDepth];
++segmentDepth;
if (segmentDepth >= static_cast<int>(SEGMENT_COLOURS.size()))
segmentDepth = 0;
vkCommandBuffer.beginDebugUtilsLabelEXT(vk::DebugUtilsLabelEXT().setPLabelName(label.data()).setColor({ COLOR.x, COLOR.y, COLOR.z, COLOR.w }));
#endif
}
void SHVkCommandBuffer::EndLabeledSegment() noexcept
{
#ifdef _DEBUG
vkCommandBuffer.endDebugUtilsLabelEXT();
segmentDepth = std::max(segmentDepth - 1, 0);
#endif
}
//void SHVkCommandBuffer::PipelineBarrier(vk::PipelineStageFlags ) const noexcept //void SHVkCommandBuffer::PipelineBarrier(vk::PipelineStageFlags ) const noexcept
//{ //{
// //vkCommandBuffer.pipelineBarrier() // //vkCommandBuffer.pipelineBarrier()

View File

@ -7,6 +7,7 @@
#include "Resource/SHResourceLibrary.h" #include "Resource/SHResourceLibrary.h"
#include "Graphics/Pipeline/SHVkPipelineLayout.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h"
#include "Graphics/Pipeline/SHPipelineType.h" #include "Graphics/Pipeline/SHPipelineType.h"
#include "Math/SHColour.h"
namespace SHADE namespace SHADE
{ {
@ -80,6 +81,9 @@ namespace SHADE
//! The push constant data for the command buffer //! The push constant data for the command buffer
uint8_t pushConstantData[PUSH_CONSTANT_SIZE]; uint8_t pushConstantData[PUSH_CONSTANT_SIZE];
//! Depth of segmenting of the command buffer (used for debug data)
int segmentDepth;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -107,7 +111,7 @@ namespace SHADE
void Reset(void); void Reset(void);
// Begins and Ends // Begins and Ends
void BeginRecording (void) noexcept; void BeginRecording () noexcept;
void EndRecording (void) noexcept; void EndRecording (void) noexcept;
void BeginRenderpass (Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> const& framebufferHdl, vk::Offset2D offset = {0, 0}, vk::Extent2D extent = {0, 0}) noexcept; void BeginRenderpass (Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> const& framebufferHdl, vk::Offset2D offset = {0, 0}, vk::Extent2D extent = {0, 0}) noexcept;
void EndRenderpass (void) noexcept; void EndRenderpass (void) noexcept;
@ -148,6 +152,10 @@ namespace SHADE
bool IsReadyToSubmit (void) const noexcept; bool IsReadyToSubmit (void) const noexcept;
void HandlePostSubmit (void) noexcept; void HandlePostSubmit (void) noexcept;
// Debugging
void BeginLabeledSegment(const std::string& label) noexcept;
void EndLabeledSegment() noexcept;
// Push Constant variable setting // Push Constant variable setting
template <typename T> template <typename T>
void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept

View File

@ -220,6 +220,7 @@ namespace SHADE
else else
{ {
SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Logical Device. "); SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Logical Device. ");
SET_VK_OBJ_NAME(this, vk::ObjectType::eDevice, vkLogicalDevice, "Logical Device");
} }
InitializeVMA(); InitializeVMA();
@ -419,9 +420,9 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
Handle<SHVkBuffer> SHVkLogicalDevice::CreateBuffer(uint32_t inSize, void* data, uint32_t srcSize, vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) const noexcept Handle<SHVkBuffer> SHVkLogicalDevice::CreateBuffer(uint32_t inSize, void* data, uint32_t srcSize, vk::BufferUsageFlags bufferUsage, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags, const std::string& name) const noexcept
{ {
return SHVkInstance::GetResourceManager().Create<SHVkBuffer>(inSize, data, srcSize, std::cref(vmaAllocator), bufferUsage, memUsage, allocFlags); return SHVkInstance::GetResourceManager().Create<SHVkBuffer>(GetHandle(), inSize, data, srcSize, std::cref(vmaAllocator), bufferUsage, name, memUsage, allocFlags);
} }
/***************************************************************************/ /***************************************************************************/
@ -455,12 +456,12 @@ namespace SHADE
/***************************************************************************/ /***************************************************************************/
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) const noexcept Handle<SHVkImage> SHVkLogicalDevice::CreateImage(uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) const noexcept
{ {
return SHVkInstance::GetResourceManager().Create<SHVkImage>(&vmaAllocator, w, h, levels, format, usage, create); return SHVkInstance::GetResourceManager().Create<SHVkImage>(GetHandle(), &vmaAllocator, w, h, levels, format, usage, create);
} }
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(SHImageCreateParams const& imageDetails, unsigned char* data, uint32_t dataSize, std::span<uint32_t> inMipOffsets, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) noexcept Handle<SHVkImage> SHVkLogicalDevice::CreateImage(SHImageCreateParams const& imageDetails, unsigned char* data, uint32_t dataSize, std::span<uint32_t> inMipOffsets, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) noexcept
{ {
return SHVkInstance::GetResourceManager().Create<SHVkImage>(&vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags); return SHVkInstance::GetResourceManager().Create<SHVkImage>(GetHandle(), &vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags);
} }
/***************************************************************************/ /***************************************************************************/

View File

@ -1,5 +1,4 @@
#ifndef SH_LOGICAL_DEVICE_H #pragma once
#define SH_LOGICAL_DEVICE_H
#include <optional> #include <optional>
#include <array> #include <array>
@ -67,7 +66,6 @@ namespace SHADE
class SHVkLogicalDevice : public ISelfHandle<SHVkLogicalDevice> class SHVkLogicalDevice : public ISelfHandle<SHVkLogicalDevice>
{ {
private: private:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */ /* PRIVATE MEMBER VARIABLES */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -147,7 +145,8 @@ namespace SHADE
uint32_t srcSize, uint32_t srcSize,
vk::BufferUsageFlags bufferUsage, vk::BufferUsageFlags bufferUsage,
VmaMemoryUsage memUsage, VmaMemoryUsage memUsage,
VmaAllocationCreateFlags allocFlags VmaAllocationCreateFlags allocFlags,
const std::string& name = ""
) const noexcept; ) const noexcept;
Handle<SHVkImage> CreateImage ( Handle<SHVkImage> CreateImage (
@ -204,6 +203,32 @@ namespace SHADE
void UpdateDescriptorSets(std::vector<vk::WriteDescriptorSet> const& writeDescSets) noexcept; void UpdateDescriptorSets(std::vector<vk::WriteDescriptorSet> const& writeDescSets) noexcept;
void UpdateDescriptorSet(vk::WriteDescriptorSet const& writeDescSet) noexcept; void UpdateDescriptorSet(vk::WriteDescriptorSet const& writeDescSet) noexcept;
/*-----------------------------------------------------------------------*/
/* Debug Tools */
/*-----------------------------------------------------------------------*/
#ifdef _DEBUG
/// <summary>
/// Sets a Vulkan HPP object's name for debugging purposes. This function will not be
/// compiled outside of Debug configurations. Hence, it is advised to use provided
/// macro function SET_VK_OBJ_NAME() instead of using this function directly.
/// </summary>
/// <param name="objType">Type of the object.</param>
/// <param name="objHandle">Handle to the Vulkan Object to name.</param>
/// <param name="objName">Object's name.</param>
template<typename T>
inline void SetVulkanObjectName(vk::ObjectType objType, T objHandle, const std::string& objName);
/// <summary>
/// Sets a Vulkan object's name for debugging purposes. This function will not be
/// compiled outside of Debug configurations. Hence, it is advised to use provided
/// macro function SET_VK_OBJ_NAME_VK() instead of using this function directly.
/// </summary>
/// <param name="objType">Type of the object.</param>
/// <param name="objHandle">Handle to the Vulkan Object to name.</param>
/// <param name="objName">Object's name.</param>
template<typename T>
inline void SetVulkanObjectNameVk(vk::ObjectType objType, T objVkHandle, const std::string& objName);
#endif
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */ /* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -220,4 +245,4 @@ namespace SHADE
}; };
} }
#endif #include "SHVkLogicalDevice.hpp"

View File

@ -0,0 +1,61 @@
/************************************************************************************//*!
\file SHVkLogicalDevice.hpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Nov 4, 2022
\brief Contains implementation of inline and template functions of
SHVkLogicalDevice.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
#include "SHVkLogicalDevice.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Debug Tools */
/*-----------------------------------------------------------------------------------*/
#ifdef _DEBUG
template<typename T>
void SHVkLogicalDevice::SetVulkanObjectName(vk::ObjectType objType, T objHandle, const std::string& objName)
{
if (objName.empty())
return;
vk::DebugUtilsObjectNameInfoEXT info;
info.objectType = objType;
info.objectHandle = (uint64_t) static_cast<typename T::NativeType>(objHandle);
info.pObjectName = objName.data();
vkLogicalDevice.setDebugUtilsObjectNameEXT(info);
}
template<typename T>
void SHVkLogicalDevice::SetVulkanObjectNameVk(vk::ObjectType objType, T objVkHandle, const std::string& objName)
{
if (objName.empty())
return;
vk::DebugUtilsObjectNameInfoEXT info;
info.objectType = objType;
info.objectHandle = (uint64_t) objVkHandle;
info.pObjectName = objName.data();
vkLogicalDevice.setDebugUtilsObjectNameEXT(info);
}
#endif
}
/*-------------------------------------------------------------------------------------*/
/* Macro Definitions */
/*-------------------------------------------------------------------------------------*/
#ifdef _DEBUG
#define SET_VK_OBJ_NAME(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) \
DEVICE->SetVulkanObjectName(OBJ_TYPE, OBJ_HDL, OBJ_NAME);
#define SET_VK_OBJ_NAME_VK(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME) \
DEVICE->SetVulkanObjectNameVk(OBJ_TYPE, OBJ_HDL, OBJ_NAME);
#else
#define SET_VK_OBJ_NAME(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME)
#define SET_VK_OBJ_NAME_VK(DEVICE, OBJ_TYPE, OBJ_HDL, OBJ_NAME)
#endif

View File

@ -61,6 +61,7 @@ namespace SHADE
&bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use renderdoc to check buffer variables?) &bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use renderdoc to check buffer variables?)
&allocCreateInfo, &allocCreateInfo,
&tempBuffer, &stagingAlloc, &allocInfo); &tempBuffer, &stagingAlloc, &allocInfo);
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] Staging Buffer for Image");
// then assign it to the hpp version // then assign it to the hpp version
stagingBuffer = tempBuffer; stagingBuffer = tempBuffer;
@ -107,6 +108,8 @@ namespace SHADE
VkImage tempImage; VkImage tempImage;
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo); auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
vkImage = tempImage; vkImage = tempImage;
//SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eImage, vkImage, "[Image] ");
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Device Memory] Image Memory");
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. "); SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
@ -115,6 +118,7 @@ namespace SHADE
} }
SHVkImage::SHVkImage( SHVkImage::SHVkImage(
Handle<SHVkLogicalDevice> logicalDeviceHdl,
VmaAllocator const* allocator, VmaAllocator const* allocator,
SHImageCreateParams const& imageDetails, SHImageCreateParams const& imageDetails,
const unsigned char* data, const unsigned char* data,
@ -137,6 +141,7 @@ namespace SHADE
, boundToCoherent{false} , boundToCoherent{false}
, randomAccessOptimized {false} , randomAccessOptimized {false}
, mappedPtr{nullptr} , mappedPtr{nullptr}
, device { logicalDeviceHdl }
{ {
usageFlags = imageDetails.usageFlags; usageFlags = imageDetails.usageFlags;
createFlags = imageDetails.createFlags; createFlags = imageDetails.createFlags;
@ -176,6 +181,8 @@ namespace SHADE
VkImage tempImage; VkImage tempImage;
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo); auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
//SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eImage, vkImage, "[Image] ");
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Device Memory] Image Memory");
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. "); SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
@ -220,7 +227,7 @@ namespace SHADE
//} //}
} }
SHVkImage::SHVkImage(VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept SHVkImage::SHVkImage(Handle<SHVkLogicalDevice> logicalDeviceHdl, VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept
: width {w} : width {w}
, height{h} , height{h}
, depth {1} , depth {1}
@ -230,11 +237,12 @@ namespace SHADE
, usageFlags{usage} , usageFlags{usage}
, createFlags {create} , createFlags {create}
, vmaAllocator {allocator} , vmaAllocator {allocator}
, device { logicalDeviceHdl }
{ {
CreateFramebufferImage(); CreateFramebufferImage();
} }
Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept Handle<SHVkImageView> SHVkImage::CreateImageView(Handle<SHVkLogicalDevice> inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept
{ {
return SHVkInstance::GetResourceManager().Create<SHVkImageView>(inLogicalDeviceHdl, parent, createParams); return SHVkInstance::GetResourceManager().Create<SHVkImageView>(inLogicalDeviceHdl, parent, createParams);
} }

View File

@ -104,6 +104,9 @@ namespace SHADE
//! Mipmap offsets for initializing the vk::BufferImageCopy during transfer to GPU resource //! Mipmap offsets for initializing the vk::BufferImageCopy during transfer to GPU resource
std::span<uint32_t> mipOffsets; std::span<uint32_t> mipOffsets;
//! Handle to the device that creates these images
Handle<SHVkLogicalDevice> device;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -117,6 +120,7 @@ namespace SHADE
SHVkImage(void) noexcept = default; SHVkImage(void) noexcept = default;
SHVkImage( SHVkImage(
Handle<SHVkLogicalDevice> logicalDeviceHdl,
VmaAllocator const* allocator, VmaAllocator const* allocator,
SHImageCreateParams const& imageDetails, SHImageCreateParams const& imageDetails,
const unsigned char* data, const unsigned char* data,
@ -126,7 +130,7 @@ namespace SHADE
VmaAllocationCreateFlags allocFlags VmaAllocationCreateFlags allocFlags
) noexcept; ) noexcept;
SHVkImage(VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept; SHVkImage(Handle<SHVkLogicalDevice> logicalDeviceHdl, VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept;
SHVkImage(SHVkImage&& rhs) noexcept = default; SHVkImage(SHVkImage&& rhs) noexcept = default;
SHVkImage& operator=(SHVkImage && rhs) noexcept = default; SHVkImage& operator=(SHVkImage && rhs) noexcept = default;
@ -134,7 +138,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */ /* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept; Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept;
void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept; void TransferToDeviceResource (Handle<SHVkCommandBuffer> cmdBufferHdl) noexcept;
void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept; void PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept; void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept;

View File

@ -392,20 +392,23 @@ namespace SHADE
SHVkUtil::EnsureBufferAndCopyHostVisibleData SHVkUtil::EnsureBufferAndCopyHostVisibleData
( (
device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES, device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES,
BuffUsage::eIndirectBuffer BuffUsage::eIndirectBuffer,
"Batch Draw Data Buffer"
); );
// - Transform Buffer // - Transform Buffer
const uint32_t TF_DATA_BYTES = static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix)); const uint32_t TF_DATA_BYTES = static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix));
SHVkUtil::EnsureBufferAndCopyHostVisibleData SHVkUtil::EnsureBufferAndCopyHostVisibleData
( (
device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES, device, transformDataBuffer[frameIndex], transformData.data(), TF_DATA_BYTES,
BuffUsage::eVertexBuffer BuffUsage::eVertexBuffer,
"Batch Transform Buffer"
); );
const uint32_t EID_DATA_BYTES = static_cast<uint32_t>(instancedIntegerData.size() * sizeof(SHInstancedIntegerData)); const uint32_t EID_DATA_BYTES = static_cast<uint32_t>(instancedIntegerData.size() * sizeof(SHInstancedIntegerData));
SHVkUtil::EnsureBufferAndCopyHostVisibleData SHVkUtil::EnsureBufferAndCopyHostVisibleData
( (
device, instancedIntegerBuffer[frameIndex], instancedIntegerData.data(), EID_DATA_BYTES, device, instancedIntegerBuffer[frameIndex], instancedIntegerData.data(), EID_DATA_BYTES,
BuffUsage::eVertexBuffer BuffUsage::eVertexBuffer,
"Batch Instance Data Buffer"
); );
// - Material Properties Buffer // - Material Properties Buffer
rebuildMaterialBuffers(frameIndex, descPool); rebuildMaterialBuffers(frameIndex, descPool);
@ -427,6 +430,7 @@ namespace SHADE
// Bind all required objects before drawing // Bind all required objects before drawing
static std::array<uint32_t, 1> dynamicOffset{ 0 }; static std::array<uint32_t, 1> dynamicOffset{ 0 };
cmdBuffer->BeginLabeledSegment("SHBatch");
cmdBuffer->BindPipeline(pipeline); cmdBuffer->BindPipeline(pipeline);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
@ -441,6 +445,7 @@ namespace SHADE
); );
} }
cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size())); cmdBuffer->DrawMultiIndirect(drawDataBuffer[frameIndex], static_cast<uint32_t>(drawData.size()));
cmdBuffer->EndLabeledSegment();
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -460,7 +465,8 @@ namespace SHADE
SHVkUtil::EnsureBufferAndCopyHostVisibleData SHVkUtil::EnsureBufferAndCopyHostVisibleData
( (
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize), device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
vk::BufferUsageFlagBits::eStorageBuffer vk::BufferUsageFlagBits::eStorageBuffer,
"Batch Material Data"
); );
if (!matPropsDescSet[frameIndex]) if (!matPropsDescSet[frameIndex])
@ -470,6 +476,13 @@ namespace SHADE
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] }, { SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] },
{ 0 } { 0 }
); );
#ifdef _DEBUG
const auto& DESC_SETS = matPropsDescSet[frameIndex]->GetVkHandle();
for (auto descSet : DESC_SETS)
{
SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, descSet, "[Descriptor Set] Batch Material Data");
}
#endif
} }
std::array<Handle<SHVkBuffer>, 1> bufferList = { matPropsBuffer[frameIndex] }; std::array<Handle<SHVkBuffer>, 1> bufferList = { matPropsBuffer[frameIndex] };
matPropsDescSet[frameIndex]->ModifyWriteDescBuffer matPropsDescSet[frameIndex]->ModifyWriteDescBuffer

View File

@ -13,7 +13,6 @@ namespace SHADE
/* Static Definitions */ /* Static Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsGlobalData::globalDescSetLayouts; std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsGlobalData::globalDescSetLayouts;
Handle<SHVkDescriptorSetGroup> SHGraphicsGlobalData::globalDescSets;
SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState; SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState;
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::dummyPipelineLayout; Handle<SHVkPipelineLayout> SHGraphicsGlobalData::dummyPipelineLayout;
@ -46,6 +45,7 @@ namespace SHADE
// For global data (generic data and textures) // For global data (generic data and textures)
Handle<SHVkDescriptorSetLayout> staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, { genericDataBinding, texturesBinding }); Handle<SHVkDescriptorSetLayout> staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, { genericDataBinding, texturesBinding });
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, staticGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Static Globals");
std::vector<SHVkDescriptorSetLayout::Binding> lightBindings{}; std::vector<SHVkDescriptorSetLayout::Binding> lightBindings{};
@ -60,7 +60,7 @@ namespace SHADE
}); });
for (uint32_t i = 1; i <= SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES); ++i) for (uint32_t i = 1; i <= SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES); ++i)
{ {
lightBindings.push_back (SHVkDescriptorSetLayout::Binding lightBindings.push_back (SHVkDescriptorSetLayout::Binding
{ {
@ -71,11 +71,11 @@ namespace SHADE
}); });
} }
// For Dynamic global data (lights) // For Dynamic global data (lights)
Handle<SHVkDescriptorSetLayout> dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, lightBindings); Handle<SHVkDescriptorSetLayout> dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, lightBindings);
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, dynamicGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Dynamic Globals");
// For High frequency global data (camera)
SHVkDescriptorSetLayout::Binding cameraDataBinding SHVkDescriptorSetLayout::Binding cameraDataBinding
{ {
.Type = vk::DescriptorType::eUniformBufferDynamic, .Type = vk::DescriptorType::eUniformBufferDynamic,
@ -83,10 +83,10 @@ namespace SHADE
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, .BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA,
.DescriptorCount = 1, .DescriptorCount = 1,
}; };
// For High frequency global data (camera)
Handle<SHVkDescriptorSetLayout> cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, { cameraDataBinding }); Handle<SHVkDescriptorSetLayout> cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, { cameraDataBinding });
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, cameraDataGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] High Frequency Globals");
// For per instance data (transforms, materials, etc.)
SHVkDescriptorSetLayout::Binding materialDataBinding SHVkDescriptorSetLayout::Binding materialDataBinding
{ {
.Type = vk::DescriptorType::eStorageBufferDynamic, .Type = vk::DescriptorType::eStorageBufferDynamic,
@ -94,9 +94,8 @@ namespace SHADE
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, .BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
.DescriptorCount = 1, .DescriptorCount = 1,
}; };
// For High frequency global data (camera)
Handle<SHVkDescriptorSetLayout> materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, { materialDataBinding }); Handle<SHVkDescriptorSetLayout> materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, { materialDataBinding });
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, materialDataPerInstanceLayout->GetVkHandle(), "[Descriptor Set Layout] Material Globals");
SHVkDescriptorSetLayout::Binding fontBitmapBinding SHVkDescriptorSetLayout::Binding fontBitmapBinding
{ {

View File

@ -17,9 +17,6 @@ namespace SHADE
//! Global descriptor set layouts. Used to allocate descriptor sets //! Global descriptor set layouts. Used to allocate descriptor sets
static std::vector<Handle<SHVkDescriptorSetLayout>> globalDescSetLayouts; static std::vector<Handle<SHVkDescriptorSetLayout>> globalDescSetLayouts;
//! Global Descriptor sets
static Handle<SHVkDescriptorSetGroup> globalDescSets;
//! Default vertex input state (used by everything). //! Default vertex input state (used by everything).
static SHVertexInputState defaultVertexInputState; static SHVertexInputState defaultVertexInputState;

View File

@ -98,6 +98,7 @@ namespace SHADE
// Don't draw if no points // Don't draw if no points
if (numPoints[FRAME_IDX] > 0) if (numPoints[FRAME_IDX] > 0)
{ {
cmdBuffer->BeginLabeledSegment("SHDebugDraw");
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline()); cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline());
cmdBuffer->SetLineWidth(LineWidth); cmdBuffer->SetLineWidth(LineWidth);
cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0); cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0);
@ -113,10 +114,12 @@ namespace SHADE
// Don't draw if no points // Don't draw if no points
if (numPersistentPoints[FRAME_IDX] > 0) if (numPersistentPoints[FRAME_IDX] > 0)
{ {
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Persistent)");
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawDepthPipeline()); cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawDepthPipeline());
cmdBuffer->SetLineWidth(LineWidth); cmdBuffer->SetLineWidth(LineWidth);
cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0); cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0);
cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0); cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0);
cmdBuffer->EndLabeledSegment();
} }
}); });
@ -138,7 +141,8 @@ namespace SHADE
0, 0,
vk::BufferUsageFlagBits::eVertexBuffer, vk::BufferUsageFlagBits::eVertexBuffer,
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT,
"Debug Draw Non-Persistent Vertex Buffer"
); );
} }
// - Persistent Draws // - Persistent Draws
@ -151,7 +155,8 @@ namespace SHADE
0, 0,
vk::BufferUsageFlagBits::eVertexBuffer, vk::BufferUsageFlagBits::eVertexBuffer,
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT,
"Debug Draw Persistent Vertex Buffer"
); );
} }
} }
@ -312,13 +317,14 @@ namespace SHADE
void SHDebugDrawSystem::drawSphere(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, double radius) void SHDebugDrawSystem::drawSphere(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, double radius)
{ {
if (spherePoints.empty()) //if (spherePoints.empty())
{ {
spherePoints.clear();
// Generate // Generate
static const SHMeshData SPHERE = SHPrimitiveGenerator::Sphere(); static const SHMeshData SPHERE = SHPrimitiveGenerator::Sphere();
for (const auto& idx : SPHERE.Indices) for (const auto& idx : SPHERE.Indices)
{ {
spherePoints.emplace_back(SPHERE.VertexPositions[idx]); spherePoints.emplace_back(SPHERE.VertexPositions[idx] * radius + pos);
} }
} }
drawLineSet(storage, color, spherePoints.begin(), spherePoints.end()); drawLineSet(storage, color, spherePoints.begin(), spherePoints.end());

View File

@ -1,5 +1,5 @@
/************************************************************************************//*! /************************************************************************************//*!
\file SHGraphicsSystem.cpp \file SHGrphicsSystem.cpp
\author Tng Kah Wei, kahwei.tng, 390009620 \author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu \par email: kahwei.tng\@digipen.edu
\date Aug 21, 2022 \date Aug 21, 2022
@ -117,8 +117,8 @@ namespace SHADE
// Create generic command buffer // Create generic command buffer
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true); graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl"); SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false);
SHAssetManager::CompileAsset("../../Assets/Shaders/Text_FS.glsl"); SHAssetManager::CompileAsset("../../Assets/Shaders/Text_FS.glsl", false);
// Load Built In Shaders // Load Built In Shaders
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT); static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
@ -174,7 +174,7 @@ namespace SHADE
/* WORLD RENDER GRAPH RESOURCES */ /* WORLD RENDER GRAPH RESOURCES */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// Initialize world render graph // Initialize world render graph
worldRenderGraph->Init(device, swapchain, &resourceManager); worldRenderGraph->Init("World Render Graph", device, swapchain, &resourceManager);
worldRenderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); worldRenderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
worldRenderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); worldRenderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
//worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); //worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
@ -223,6 +223,7 @@ namespace SHADE
ssaoStorage = resourceManager.Create<SHSSAO>(); ssaoStorage = resourceManager.Create<SHSSAO>();
ssaoTransferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); ssaoTransferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, ssaoTransferCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] SSAO Pass (Graphics)");
ssaoTransferCmdBuffer->BeginRecording(); ssaoTransferCmdBuffer->BeginRecording();
ssaoStorage->Init(device, ssaoTransferCmdBuffer); ssaoStorage->Init(device, ssaoTransferCmdBuffer);
@ -244,7 +245,7 @@ namespace SHADE
ssaoStorage->PrepareRotationVectorsVkData(device); ssaoStorage->PrepareRotationVectorsVkData(device);
Handle<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute(ssaoShader, {"Position", "Normals", "SSAO"}); Handle<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute("SSAO", ssaoShader, { "Position", "Normals", "SSAO" });
auto ssaoDataBuffer = ssaoStorage->GetBuffer(); auto ssaoDataBuffer = ssaoStorage->GetBuffer();
ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored()); ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored());
auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout(); auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout();
@ -252,12 +253,12 @@ namespace SHADE
ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1}); ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1});
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute(ssaoBlurShader, { "SSAO", "SSAO Blur"}); Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute("SSAO Blur Step", ssaoBlurShader, {"SSAO", "SSAO Blur"});
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* DEFERRED COMPOSITE SUBPASS INIT */ /* DEFERRED COMPOSITE SUBPASS INIT */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" }); gBufferNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, {"Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene"});
{ {
//// Dummy Node to transition scene render graph resource //// Dummy Node to transition scene render graph resource
@ -278,7 +279,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// Initialize screen render graph // Initialize screen render graph
screenRenderGraph = resourceManager.Create<SHRenderGraph>(); screenRenderGraph = resourceManager.Create<SHRenderGraph>();
screenRenderGraph->Init(device, swapchain, &resourceManager); screenRenderGraph->Init("Scene Render Graph", device, swapchain, &resourceManager);
screenRenderGraph->LinkNonOwningResource(worldRenderGraph, "Scene"); screenRenderGraph->LinkNonOwningResource(worldRenderGraph, "Scene");
auto screenSpaceNode = screenRenderGraph->AddNode("Screen Space Pass", { "Scene" }, {}); auto screenSpaceNode = screenRenderGraph->AddNode("Screen Space Pass", { "Scene" }, {});
@ -311,7 +312,11 @@ namespace SHADE
// Create debug draw pipeline // Create debug draw pipeline
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass); debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawPipeline->GetVkPipeline(), "[Pipeline] Debug Draw");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline Layout] Debug Draw Pipeline Layout");
debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass); debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, debugDrawDepthPipeline->GetVkPipeline(), "[Pipeline Layout] Debug Draw with Depth Test");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, debugDrawDepthPipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Debug Draw with Depth Test Pipeline Layout");
} }
void SHGraphicsSystem::InitMiddleEnd(void) noexcept void SHGraphicsSystem::InitMiddleEnd(void) noexcept
@ -398,7 +403,7 @@ namespace SHADE
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0]; renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
editorRenderGraph->Init(device, swapchain, &resourceManager); editorRenderGraph->Init("Editor Render Graph", device, swapchain, &resourceManager);
editorRenderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); editorRenderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
@ -726,6 +731,8 @@ namespace SHADE
auto renderGraphNode = subpass->GetParentNode(); auto renderGraphNode = subpass->GetParentNode();
auto pipeline = renderGraphNode->GetOrCreatePipeline(std::make_pair(vertShader, fragShader), subpass); auto pipeline = renderGraphNode->GetOrCreatePipeline(std::make_pair(vertShader, fragShader), subpass);
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipeline, pipeline->GetVkPipeline(), "[Pipeline] Custom Pipeline");
SET_VK_OBJ_NAME(device, vk::ObjectType::ePipelineLayout, pipeline->GetPipelineLayout()->GetVkPipelineLayout(), "[Pipeline] Custom Pipeline Layout");
mat->SetPipeline(pipeline); mat->SetPipeline(pipeline);
@ -773,6 +780,7 @@ namespace SHADE
void SHGraphicsSystem::BuildMeshBuffers() void SHGraphicsSystem::BuildMeshBuffers()
{ {
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, transferCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] Mesh Buffer Building (Transfer)");
device->WaitIdle(); device->WaitIdle();
transferCmdBuffer->BeginRecording(); transferCmdBuffer->BeginRecording();
meshLibrary.BuildBuffers(device, transferCmdBuffer); meshLibrary.BuildBuffers(device, transferCmdBuffer);
@ -799,13 +807,17 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Handle<SHTexture> SHGraphicsSystem::AddTexture(const SHTextureAsset& texAsset) Handle<SHTexture> SHGraphicsSystem::AddTexture(const SHTextureAsset& texAsset)
{ {
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast<float>(texAsset.mipOffsets.size()) }); const int MIPS = texAsset.mipOffsets.size();
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast<float>(MIPS) });
SET_VK_OBJ_NAME(device, vk::ObjectType::eSampler, sampler->GetVkSampler(), "[Sampler] Mips " + std::to_string(MIPS));
return texLibrary.Add(texAsset, sampler); return texLibrary.Add(texAsset, sampler);
} }
SHADE::Handle<SHADE::SHTexture> SHGraphicsSystem::AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets) SHADE::Handle<SHADE::SHTexture> SHGraphicsSystem::AddTexture(uint32_t pixelCount, const SHTexture::PixelChannel* const pixelData, uint32_t width, uint32_t height, SHTexture::TextureFormat format, std::vector<uint32_t> mipOffsets)
{ {
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast<float>(mipOffsets.size()) }); const int MIPS = mipOffsets.size();
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams{ .maxLod = static_cast<float>(MIPS) });
SET_VK_OBJ_NAME(device, vk::ObjectType::eSampler, sampler->GetVkSampler(), "[Sampler] Mips " + std::to_string(MIPS));
return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler); return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler);
} }
@ -817,6 +829,7 @@ namespace SHADE
void SHGraphicsSystem::BuildTextures() void SHGraphicsSystem::BuildTextures()
{ {
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, graphicsTexCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] Texture Building (Graphics)");
device->WaitIdle(); device->WaitIdle();
texLibrary.BuildTextures texLibrary.BuildTextures
( (

View File

@ -165,35 +165,40 @@ namespace SHADE
device, cmdBuffer, vertPosBuffer, device, cmdBuffer, vertPosBuffer,
vertPosStorage.data(), vertPosStorage.data(),
static_cast<uint32_t>(vertPosStorage.size()) * sizeof(SHMesh::VertexPosition), static_cast<uint32_t>(vertPosStorage.size()) * sizeof(SHMesh::VertexPosition),
BuffUsage::eVertexBuffer BuffUsage::eVertexBuffer,
"Mesh Library Vertex Positions"
); );
SHVkUtil::EnsureBufferAndCopyData SHVkUtil::EnsureBufferAndCopyData
( (
device, cmdBuffer, vertTexCoordBuffer, device, cmdBuffer, vertTexCoordBuffer,
vertTexCoordStorage.data(), vertTexCoordStorage.data(),
static_cast<uint32_t>(vertTexCoordStorage.size()) * sizeof(SHMesh::VertexTexCoord), static_cast<uint32_t>(vertTexCoordStorage.size()) * sizeof(SHMesh::VertexTexCoord),
BuffUsage::eVertexBuffer BuffUsage::eVertexBuffer,
"Mesh Library Vertex TexCoords"
); );
SHVkUtil::EnsureBufferAndCopyData SHVkUtil::EnsureBufferAndCopyData
( (
device, cmdBuffer, vertTangentBuffer, device, cmdBuffer, vertTangentBuffer,
vertTangentStorage.data(), vertTangentStorage.data(),
static_cast<uint32_t>(vertTangentStorage.size()) * sizeof(SHMesh::VertexTangent), static_cast<uint32_t>(vertTangentStorage.size()) * sizeof(SHMesh::VertexTangent),
BuffUsage::eVertexBuffer BuffUsage::eVertexBuffer,
"Mesh Library Vertex Tangents"
); );
SHVkUtil::EnsureBufferAndCopyData SHVkUtil::EnsureBufferAndCopyData
( (
device, cmdBuffer, vertNormalBuffer, device, cmdBuffer, vertNormalBuffer,
vertNormalStorage.data(), vertNormalStorage.data(),
static_cast<uint32_t>(vertNormalStorage.size()) * sizeof(SHMesh::VertexNormal), static_cast<uint32_t>(vertNormalStorage.size()) * sizeof(SHMesh::VertexNormal),
BuffUsage::eVertexBuffer BuffUsage::eVertexBuffer,
"Mesh Library Vertex Normals"
); );
SHVkUtil::EnsureBufferAndCopyData SHVkUtil::EnsureBufferAndCopyData
( (
device, cmdBuffer, indexBuffer, device, cmdBuffer, indexBuffer,
indexStorage.data(), indexStorage.data(),
static_cast<uint32_t>(indexStorage.size()) * sizeof(SHMesh::Index), static_cast<uint32_t>(indexStorage.size()) * sizeof(SHMesh::Index),
BuffUsage::eIndexBuffer BuffUsage::eIndexBuffer,
"Mesh Library Indices"
); );
isDirty = false; isDirty = false;

View File

@ -76,7 +76,7 @@ namespace SHADE
uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat()); uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat());
// Create the buffer // Create the buffer
imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Mouse Pick Image Data Destination");
} }
void SHMousePickSystem::SetViewportMousePos(SHVec2 vpMousePos) noexcept void SHMousePickSystem::SetViewportMousePos(SHVec2 vpMousePos) noexcept

View File

@ -39,9 +39,15 @@ namespace SHADE
cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 }); cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 });
#ifdef _DEBUG
const auto& CAM_DESC_SETS = cameraDescriptorSet->GetVkHandle();
for (int i = 0; i < static_cast<int>(CAM_DESC_SETS.size()); ++i)
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSet, CAM_DESC_SETS[i], "[Descriptor Set] Camera Data Frame #" + std::to_string(i));
#endif
cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData)); cameraDataAlignedSize = logicalDevice->PadUBOSize(sizeof(SHShaderCameraData));
cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); cameraBuffer = logicalDevice->CreateBuffer(cameraDataAlignedSize * numFrames, nullptr, cameraDataAlignedSize * numFrames, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Camera Data");
std::array cameraBufferArray{cameraBuffer}; std::array cameraBufferArray{cameraBuffer};

View File

@ -134,7 +134,7 @@ namespace SHADE
lightDataTotalAlignedSize = logicalDevice->PadSSBOSize(lightDataAlignedSize * maxLights); lightDataTotalAlignedSize = logicalDevice->PadSSBOSize(lightDataAlignedSize * maxLights);
// We want to initialize 3 times the amount of data required. // We want to initialize 3 times the amount of data required.
dataBuffer = logicalDevice->CreateBuffer(lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); dataBuffer = logicalDevice->CreateBuffer(lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightDataTotalAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eStorageBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Light Data");
} }
else else
{ {
@ -379,14 +379,18 @@ namespace SHADE
SHComponentManager::CreateComponentSparseSet<SHLightComponent>(); SHComponentManager::CreateComponentSparseSet<SHLightComponent>();
logicalDevice = device; logicalDevice = device;
uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES); uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES);
std::vector<uint32_t> variableSizes{ NUM_LIGHT_TYPES }; std::vector<uint32_t> variableSizes{ NUM_LIGHT_TYPES };
std::fill (variableSizes.begin(), variableSizes.end(), 1); std::fill (variableSizes.begin(), variableSizes.end(), 1);
// Create the descriptor set // Create the descriptor set
lightingDataDescSet = descPool->Allocate({ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS] }, variableSizes); lightingDataDescSet = descPool->Allocate({ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS] }, variableSizes);
#ifdef _DEBUG
const auto& CAM_DESC_SETS = lightingDataDescSet->GetVkHandle();
for (int i = 0; i < static_cast<int>(CAM_DESC_SETS.size()); ++i)
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSet, CAM_DESC_SETS[i], "[Descriptor Set] Light Data Frame #" + std::to_string(i));
#endif
for (uint32_t i = 0; i < NUM_LIGHT_TYPES; ++i) for (uint32_t i = 0; i < NUM_LIGHT_TYPES; ++i)
{ {
@ -402,7 +406,7 @@ namespace SHADE
lightCountsAlignedSize = logicalDevice->PadUBOSize(lightCountsAlignedSize); lightCountsAlignedSize = logicalDevice->PadUBOSize(lightCountsAlignedSize);
// Create the GPU buffer to hold light count // Create the GPU buffer to hold light count
lightCountsBuffer = logicalDevice->CreateBuffer(lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT); lightCountsBuffer = logicalDevice->CreateBuffer(lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Light Count Data");
lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT, {&lightCountsBuffer, 1}, 0, sizeof (uint32_t) * NUM_LIGHT_TYPES); lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT, {&lightCountsBuffer, 1}, 0, sizeof (uint32_t) * NUM_LIGHT_TYPES);
lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT); lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT);
@ -427,7 +431,7 @@ namespace SHADE
/***************************************************************************/ /***************************************************************************/
void SHLightingSubSystem::Run(SHMatrix const& viewMat, uint32_t frameIndex) noexcept void SHLightingSubSystem::Run(SHMatrix const& viewMat, uint32_t frameIndex) noexcept
{ {
static uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES); static uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES);
auto& lightComps = SHComponentManager::GetDense<SHLightComponent>(); auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
bool expanded = false; bool expanded = false;
@ -447,7 +451,7 @@ namespace SHADE
for (auto& light : lightComps) for (auto& light : lightComps)
{ {
auto enumValue = SHUtilities::ToUnderlying(light.GetLightData().type); auto enumValue = SHUtilities::ConvertEnum(light.GetLightData().type);
// First we want to make sure the light is already bound to the system. if it // First we want to make sure the light is already bound to the system. if it
// isn't, we write it to the correct buffer. // isn't, we write it to the correct buffer.
@ -487,7 +491,7 @@ namespace SHADE
// is a new buffer. If some expansion was detected, update descriptor sets. // is a new buffer. If some expansion was detected, update descriptor sets.
if (expanded) if (expanded)
{ {
uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES); uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES);
for (uint32_t i = 0; i < NUM_LIGHT_TYPES; ++i) for (uint32_t i = 0; i < NUM_LIGHT_TYPES; ++i)
{ {
UpdateDescSet(i); UpdateDescSet(i);

View File

@ -26,7 +26,7 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
void SHPerFrameData::Recreate(Handle<SHVkLogicalDevice> const& logicalDeviceHdl) noexcept void SHPerFrameData::Recreate(Handle<SHVkLogicalDevice> logicalDeviceHdl) noexcept
{ {
// Swapchain recreation means the images are just relinked to SHVkImages. Handles will remain the same. There is no need for this line. // Swapchain recreation means the images are just relinked to SHVkImages. Handles will remain the same. There is no need for this line.
//swapchainImageHdl = params.swapchainHdl->GetSwapchainImage(frameIndex); //swapchainImageHdl = params.swapchainHdl->GetSwapchainImage(frameIndex);
@ -44,14 +44,17 @@ namespace SHADE
// Create image views for the swapchain // Create image views for the swapchain
swapchainImageViewHdl = swapchainImageHdl->CreateImageView(logicalDeviceHdl, swapchainImageHdl, viewDetails); swapchainImageViewHdl = swapchainImageHdl->CreateImageView(logicalDeviceHdl, swapchainImageHdl, viewDetails);
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eImageView, swapchainImageViewHdl->GetImageView(), "[Image View] Swap Chain");
// Create a fence // Create a fence
fenceHdl = logicalDeviceHdl->CreateFence(); fenceHdl = logicalDeviceHdl->CreateFence();
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eFence, fenceHdl->GetVkFence(), "[Fence] Swap Chain");
// scope makes it easier to navigate // scope makes it easier to navigate
semImgAvailableHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore(); semImgAvailableHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore();
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eSemaphore, semImgAvailableHdl->GetVkSem(), "[Semaphore] Swap Chain Image Available");
semRenderFinishHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore(); semRenderFinishHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore();
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eSemaphore, semRenderFinishHdl->GetVkSem(), "[Semaphore] Swap Chain Render Finish");
} }
/***************************************************************************/ /***************************************************************************/

View File

@ -63,7 +63,7 @@ namespace SHADE
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// These are made into functions (instead of ctor and dtor) because we want to call these functions again when we resize the window // These are made into functions (instead of ctor and dtor) because we want to call these functions again when we resize the window
void Recreate (Handle<SHVkLogicalDevice> const& logicalDeviceHdl) noexcept; void Recreate (Handle<SHVkLogicalDevice> logicalDeviceHdl) noexcept;
void Destroy (void); void Destroy (void);
friend class SHRenderContext; friend class SHRenderContext;

View File

@ -50,7 +50,13 @@ namespace SHADE
for (uint32_t j = 0; j < params.numThreads; ++j) for (uint32_t j = 0; j < params.numThreads; ++j)
{ {
frameData[i].cmdPoolHdls.push_back(logicalDeviceHdl->CreateCommandPool(params.cmdPoolQueueFamilyType, params.cmdPoolResetMode, params.cmdBufferTransient)); auto cmdPool = logicalDeviceHdl->CreateCommandPool(params.cmdPoolQueueFamilyType, params.cmdPoolResetMode, params.cmdBufferTransient);
SET_VK_OBJ_NAME
(
logicalDeviceHdl, vk::ObjectType::eCommandPool, cmdPool->GetVkCommandPool(),
"[Command Pool] Render Context #" + std::to_string(i) + " Pool #" + std::to_string(j)
);
frameData[i].cmdPoolHdls.push_back(cmdPool);
} }
} }

View File

@ -23,6 +23,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
#include "Graphics/Images/SHVkImage.h" #include "Graphics/Images/SHVkImage.h"
#include "Graphics/Images/SHVkImageView.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" #include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Assets/Asset Types/SHTextureAsset.h" #include "Assets/Asset Types/SHTextureAsset.h"
@ -78,6 +79,7 @@ namespace SHADE
{ {
job.Image = resourceManager.Create<SHVkImage> job.Image = resourceManager.Create<SHVkImage>
( (
device,
&device->GetVMAAllocator(), &device->GetVMAAllocator(),
SHImageCreateParams SHImageCreateParams
{ {
@ -142,6 +144,7 @@ namespace SHADE
.layerCount = 1 .layerCount = 1
}; };
job.TextureHandle->ImageView = job.Image->CreateImageView(device, job.Image, DETAILS); job.TextureHandle->ImageView = job.Image->CreateImageView(device, job.Image, DETAILS);
SET_VK_OBJ_NAME(device, vk::ObjectType::eImageView, job.TextureHandle->ImageView->GetImageView(), "[Image View] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex));
} }
// Add Textures // Add Textures
@ -150,6 +153,9 @@ namespace SHADE
texOrder.emplace_back(job.TextureHandle); texOrder.emplace_back(job.TextureHandle);
combinedImageSamplers.emplace_back(std::make_tuple(job.TextureHandle->ImageView, job.Sampler, vk::ImageLayout::eShaderReadOnlyOptimal)); combinedImageSamplers.emplace_back(std::make_tuple(job.TextureHandle->ImageView, job.Sampler, vk::ImageLayout::eShaderReadOnlyOptimal));
job.TextureHandle->TextureArrayIndex = static_cast<uint32_t>(texOrder.size()) - 1U; job.TextureHandle->TextureArrayIndex = static_cast<uint32_t>(texOrder.size()) - 1U;
SET_VK_OBJ_NAME(device, vk::ObjectType::eImage, job.Image->GetVkImage(), "[Image] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex));
SET_VK_OBJ_NAME(device, vk::ObjectType::eImageView, job.TextureHandle->ImageView->GetImageView(), "[Image View] Texture Library Texture #" + std::to_string(job.TextureHandle->TextureArrayIndex));
} }
addJobs.clear(); addJobs.clear();
@ -165,6 +171,10 @@ namespace SHADE
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] }, { SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] },
{ static_cast<uint32_t>(texOrder.size()) } { static_cast<uint32_t>(texOrder.size()) }
); );
#ifdef _DEBUG
for (auto set : texDescriptors->GetVkHandle())
SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] Static Globals");
#endif
texDescriptors->ModifyWriteDescImage texDescriptors->ModifyWriteDescImage
( (
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,

View File

@ -60,7 +60,8 @@ namespace SHADE
format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format; format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format;
} }
renderGraphStorage->graphResources->try_emplace(resourceName, renderGraphStorage->resourceHub->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags)); auto resource = renderGraphStorage->resourceHub->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags);
renderGraphStorage->graphResources->try_emplace(resourceName, resource);
} }
void SHRenderGraph::LinkNonOwningResource(Handle<SHRenderGraph> resourceOrigin, std::string resourceName) noexcept void SHRenderGraph::LinkNonOwningResource(Handle<SHRenderGraph> resourceOrigin, std::string resourceName) noexcept
@ -160,7 +161,7 @@ namespace SHADE
// If resource is from another render graph, use the final layout it had when it was last used in that graph. This is initialized in LinkNonOwningResource. // If resource is from another render graph, use the final layout it had when it was last used in that graph. This is initialized in LinkNonOwningResource.
// We also want to load the attachment, not "don't care". // We also want to load the attachment, not "don't care".
if (resource->resourceTypeFlags & SHUtilities::ToUnderlying(SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED) && if (resource->resourceTypeFlags & SHUtilities::ConvertEnum(SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED) &&
renderGraphStorage->nonOwningResourceInitialLayouts.contains(resource.GetId().Raw)) renderGraphStorage->nonOwningResourceInitialLayouts.contains(resource.GetId().Raw))
{ {
att.initialLayout = renderGraphStorage->nonOwningResourceInitialLayouts.at (resource.GetId().Raw); att.initialLayout = renderGraphStorage->nonOwningResourceInitialLayouts.at (resource.GetId().Raw);
@ -415,7 +416,7 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
void SHRenderGraph::Init(Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain, SHResourceHub* resourceHub) noexcept void SHRenderGraph::Init(std::string graphName, Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain, SHResourceHub* resourceHub) noexcept
{ {
//resourceHub = std::make_shared<SHResourceHub>(); //resourceHub = std::make_shared<SHResourceHub>();
@ -427,6 +428,8 @@ namespace SHADE
renderGraphStorage->resourceHub = resourceHub; renderGraphStorage->resourceHub = resourceHub;
renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools(); renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools();
name = std::move(graphName);
} }
/***************************************************************************/ /***************************************************************************/
@ -443,7 +446,6 @@ namespace SHADE
SHRenderGraph::SHRenderGraph(void) noexcept SHRenderGraph::SHRenderGraph(void) noexcept
: renderGraphStorage{} : renderGraphStorage{}
, nodes{} , nodes{}
, resourceHub{nullptr}
{ {
} }
@ -451,7 +453,7 @@ namespace SHADE
: renderGraphStorage{ rhs.renderGraphStorage } : renderGraphStorage{ rhs.renderGraphStorage }
, nodeIndexing{ std::move(rhs.nodeIndexing) } , nodeIndexing{ std::move(rhs.nodeIndexing) }
, nodes{ std::move(rhs.nodes) } , nodes{ std::move(rhs.nodes) }
, resourceHub{ std::move(rhs.resourceHub) } , name { std::move(rhs.name) }
{ {
} }
@ -464,7 +466,7 @@ namespace SHADE
renderGraphStorage = rhs.renderGraphStorage; renderGraphStorage = rhs.renderGraphStorage;
nodeIndexing = std::move(rhs.nodeIndexing); nodeIndexing = std::move(rhs.nodeIndexing);
nodes = std::move(rhs.nodes); nodes = std::move(rhs.nodes);
resourceHub = std::move(rhs.resourceHub); name = std::move(rhs.name);
return *this; return *this;
} }
@ -529,9 +531,9 @@ namespace SHADE
} }
} }
nodes.emplace_back(renderGraphStorage->resourceHub->Create<SHRenderGraphNode>(renderGraphStorage, std::move(descInitParams), std::move(predecessors))); auto node = nodes.emplace_back(renderGraphStorage->resourceHub->Create<SHRenderGraphNode>(nodeName, renderGraphStorage, std::move(descInitParams), std::move(predecessors)));
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u); nodeIndexing.emplace(std::move(nodeName), static_cast<uint32_t>(nodes.size()) - 1u);
return nodes.at(nodeIndexing[nodeName]); return node;
} }
/***************************************************************************/ /***************************************************************************/
@ -578,8 +580,10 @@ namespace SHADE
// better way to manage these // better way to manage these
void SHRenderGraph::Execute(uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept void SHRenderGraph::Execute(uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept
{ {
cmdBuffer->BeginLabeledSegment(name);
for (auto& node : nodes) for (auto& node : nodes)
node->Execute(cmdBuffer, descPool, frameIndex); node->Execute(cmdBuffer, descPool, frameIndex);
cmdBuffer->EndLabeledSegment();
} }
void SHRenderGraph::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) void SHRenderGraph::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)

View File

@ -66,8 +66,8 @@ namespace SHADE
//! Render graph nodes //! Render graph nodes
std::vector<Handle<SHRenderGraphNode>> nodes; std::vector<Handle<SHRenderGraphNode>> nodes;
//! Resource library for graph handles //! Name of the RenderGraph
SHResourceHub* resourceHub; std::string name;
public: public:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
@ -81,7 +81,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */ /* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void Init (Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain, SHResourceHub* resourceHub) noexcept; void Init (std::string graphName, Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkSwapchain> swapchain, SHResourceHub* resourceHub) noexcept;
void AddResource(std::string resourceName, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {}); void AddResource(std::string resourceName, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
void LinkNonOwningResource (Handle<SHRenderGraph> resourceOrigin, std::string resourceName) noexcept; void LinkNonOwningResource (Handle<SHRenderGraph> resourceOrigin, std::string resourceName) noexcept;
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept; Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept;

View File

@ -25,6 +25,7 @@ namespace SHADE
void SHRenderGraphNode::CreateRenderpass(void) noexcept void SHRenderGraphNode::CreateRenderpass(void) noexcept
{ {
renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps); renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eRenderPass, renderpass->GetVkRenderpass(), "[RenderPass] " + name);
} }
/***************************************************************************/ /***************************************************************************/
@ -57,6 +58,7 @@ namespace SHADE
framebuffers[i] = graphStorage->logicalDevice->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight); framebuffers[i] = graphStorage->logicalDevice->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eFramebuffer, framebuffers[i]->GetVkFramebuffer(), "[Framebuffer] " + name + std::to_string(i));
} }
} }
@ -116,7 +118,7 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
SHRenderGraphNode::SHRenderGraphNode(Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept SHRenderGraphNode::SHRenderGraphNode(std::string nodeName, Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept
: graphStorage{ renderGraphStorage} : graphStorage{ renderGraphStorage}
, renderpass{} , renderpass{}
, framebuffers{} , framebuffers{}
@ -128,6 +130,7 @@ namespace SHADE
, executed{ false } , executed{ false }
, configured{ false } , configured{ false }
, nodeComputes{} , nodeComputes{}
, name { std::move(nodeName) }
{ {
// pipeline library initialization // pipeline library initialization
pipelineLibrary.Init(graphStorage->logicalDevice); pipelineLibrary.Init(graphStorage->logicalDevice);
@ -189,6 +192,7 @@ namespace SHADE
, spDescs{ std::move(rhs.spDescs) } , spDescs{ std::move(rhs.spDescs) }
, spDeps{ std::move(rhs.spDeps) } , spDeps{ std::move(rhs.spDeps) }
, nodeComputes{ std::move(rhs.nodeComputes) } , nodeComputes{ std::move(rhs.nodeComputes) }
, name { std::move(rhs.name) }
{ {
rhs.renderpass = {}; rhs.renderpass = {};
@ -213,7 +217,7 @@ namespace SHADE
spDescs = std::move(rhs.spDescs); spDescs = std::move(rhs.spDescs);
spDeps = std::move(rhs.spDeps); spDeps = std::move(rhs.spDeps);
nodeComputes = std::move(rhs.nodeComputes); nodeComputes = std::move(rhs.nodeComputes);
name = std::move(rhs.name);
rhs.renderpass = {}; rhs.renderpass = {};
@ -263,7 +267,7 @@ namespace SHADE
return subpass; return subpass;
} }
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, float numWorkGroupScale/* = 1.0f*/) noexcept Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, float numWorkGroupScale/* = 1.0f*/) noexcept
{ {
// Look for the required resources in the graph // Look for the required resources in the graph
std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{}; std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{};
@ -279,7 +283,7 @@ namespace SHADE
std::vector<Handle<SHRenderGraphResource>> temp (nodeComputeResources); std::vector<Handle<SHRenderGraphResource>> temp (nodeComputeResources);
// Create the subpass compute with the resources // Create the subpass compute with the resources
auto nodeCompute = graphStorage->resourceHub->Create<SHRenderGraphNodeCompute>(graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty()); auto nodeCompute = graphStorage->resourceHub->Create<SHRenderGraphNodeCompute>(std::move(nodeName), graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty());
nodeComputes.push_back(nodeCompute); nodeComputes.push_back(nodeCompute);
for (auto& resource : temp) for (auto& resource : temp)

View File

@ -78,8 +78,11 @@ namespace SHADE
//! Whether or not the node has been configured already or not //! Whether or not the node has been configured already or not
bool configured; bool configured;
//! Manages batching for this RenderPass
SHBatcher batcher; SHBatcher batcher;
//! Name of this node
std::string name;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */ /* PRIVATE MEMBER FUNCTIONS */
@ -92,7 +95,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */ /* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
SHRenderGraphNode(Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept; SHRenderGraphNode(std::string nodeName, Handle<SHRenderGraphStorage> renderGraphStorage, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors) noexcept;
SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept; SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;
@ -100,7 +103,7 @@ namespace SHADE
/* PUBLIC MEMBER FUNCTIONS */ /* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
Handle<SHSubpass> AddSubpass(std::string subpassName) noexcept; Handle<SHSubpass> AddSubpass(std::string subpassName) noexcept;
Handle<SHRenderGraphNodeCompute> AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept; Handle<SHRenderGraphNodeCompute> AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept;
void AddDummySubpassIfNeeded (void) noexcept; void AddDummySubpassIfNeeded (void) noexcept;
// TODO: RemoveSubpass() // TODO: RemoveSubpass()

View File

@ -13,7 +13,7 @@
namespace SHADE namespace SHADE
{ {
SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale/* = 1.0f*/) noexcept SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale/* = 1.0f*/) noexcept
: computePipeline{} : computePipeline{}
, pipelineLayout{} , pipelineLayout{}
, resources{} , resources{}
@ -22,6 +22,7 @@ namespace SHADE
, followingEndRenderpass {followingEndRP} , followingEndRenderpass {followingEndRP}
, numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)} , numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)}
, computeResource{} , computeResource{}
, name { std::move(nodeName) }
{ {
SHPipelineLayoutParams pipelineLayoutParams SHPipelineLayoutParams pipelineLayoutParams
{ {
@ -38,6 +39,8 @@ namespace SHADE
// and construct it // and construct it
computePipeline->ConstructPipeline(); computePipeline->ConstructPipeline();
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::ePipelineLayout, pipelineLayout->GetVkPipelineLayout(), "[Compute Pipeline Layout] " + name);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::ePipeline, computePipeline->GetVkPipeline(), "[Compute Pipeline] " + name);
// save the resources // save the resources
resources = std::move (subpassComputeResources); resources = std::move (subpassComputeResources);
@ -51,6 +54,10 @@ namespace SHADE
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
{ {
graphResourceDescSets[i] = graphStorage->descriptorPool->Allocate({graphResourceLayout}, { 1 }); graphResourceDescSets[i] = graphStorage->descriptorPool->Allocate({graphResourceLayout}, { 1 });
#ifdef _DEBUG
for (auto set : graphResourceDescSets[i]->GetVkHandle())
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] " + name + " #" + std::to_string(i));
#endif
} }
@ -62,6 +69,10 @@ namespace SHADE
computeResource = graphStorage->resourceHub->Create<ComputeResource>(); computeResource = graphStorage->resourceHub->Create<ComputeResource>();
auto computeResourceLayout = layouts[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE]; auto computeResourceLayout = layouts[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE];
computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 }); computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 });
#ifdef _DEBUG
for (auto set : computeResource->descSet->GetVkHandle())
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] " + name + " Resources");
#endif
// Allocate for descriptor offsets // Allocate for descriptor offsets
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)

View File

@ -65,8 +65,11 @@ namespace SHADE
std::array<std::vector<vk::ImageMemoryBarrier>, SHGraphicsConstants::NUM_FRAME_BUFFERS> memoryBarriers; std::array<std::vector<vk::ImageMemoryBarrier>, SHGraphicsConstants::NUM_FRAME_BUFFERS> memoryBarriers;
//! Name of this node
std::string name;
public: public:
SHRenderGraphNodeCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept; SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept;
void Execute (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept; void Execute (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
void HandleResize (void) noexcept; void HandleResize (void) noexcept;

View File

@ -114,6 +114,7 @@ namespace SHADE
{ {
images[i] = graphStorage->swapchain->GetSwapchainImage(i); images[i] = graphStorage->swapchain->GetSwapchainImage(i);
imageViews[i] = images[i]->CreateImageView(graphStorage->logicalDevice, images[i], viewDetails); imageViews[i] = images[i]->CreateImageView(graphStorage->logicalDevice, images[i], viewDetails);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eImageView, imageViews[i]->GetImageView(), "[Image View] " + resourceName + " #" + std::to_string(i));
} }
} }
else // if swapchain image resource else // if swapchain image resource
@ -161,7 +162,9 @@ namespace SHADE
} }
// The resource is not a swapchain image, just use the first slot of the vector // The resource is not a swapchain image, just use the first slot of the vector
images.push_back(graphStorage->logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags)); auto image = graphStorage->logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eImage, image->GetVkImage(), "[Image] " + resourceName);
images.push_back(image);
// prepare image view details // prepare image view details
SHImageViewDetails viewDetails SHImageViewDetails viewDetails
@ -176,7 +179,9 @@ namespace SHADE
}; };
// just 1 image view created // just 1 image view created
imageViews.push_back(images[0]->CreateImageView(graphStorage->logicalDevice, images[0], viewDetails)); auto imageView = images[0]->CreateImageView(graphStorage->logicalDevice, images[0], viewDetails);
imageViews.push_back(imageView);
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eImageView, imageView->GetImageView(), "[Image View] " + resourceName);
} }
infoTracker = renderGraphStorage->resourceHub->Create<InfoTracker>(); infoTracker = renderGraphStorage->resourceHub->Create<InfoTracker>();

View File

@ -201,6 +201,7 @@ namespace SHADE
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
{ {
commandBuffer->BeginLabeledSegment(name);
// Ensure correct transforms are provided // Ensure correct transforms are provided
superBatch->UpdateBuffers(frameIndex, descPool); superBatch->UpdateBuffers(frameIndex, descPool);
@ -212,7 +213,7 @@ namespace SHADE
{ {
drawCall(commandBuffer); drawCall(commandBuffer);
} }
commandBuffer->EndLabeledSegment();
} }
void SHSubpass::HandleResize(void) noexcept void SHSubpass::HandleResize(void) noexcept
@ -301,6 +302,11 @@ namespace SHADE
group.Free(); group.Free();
group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts); group = graphStorage->descriptorPool->Allocate({ inputDescriptorLayout }, variableCounts);
#ifdef _DEBUG
const auto& GROUP_HANDLES = group->GetVkHandle();
for (int i = 0; i < static_cast<int>(GROUP_HANDLES.size()); ++i)
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, GROUP_HANDLES[i], "[Descriptor Set] " + name + " #" + std::to_string(i));
#endif
uint32_t i = 0; uint32_t i = 0;
for (auto& binding : bindings) for (auto& binding : bindings)

View File

@ -82,7 +82,7 @@ namespace SHADE
} }
} }
void SHVkUtil::EnsureBufferAndCopyData(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage) void SHVkUtil::EnsureBufferAndCopyData(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name)
{ {
if (bufferHandle) if (bufferHandle)
{ {
@ -100,7 +100,8 @@ namespace SHADE
size, size,
usage | BuffUsage::eTransferDst, usage | BuffUsage::eTransferDst,
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
name
); );
} }
@ -108,7 +109,7 @@ namespace SHADE
bufferHandle->TransferToDeviceResource(cmdBuffer); bufferHandle->TransferToDeviceResource(cmdBuffer);
} }
void SHVkUtil::EnsureBufferAndCopyHostVisibleData(Handle<SHVkLogicalDevice> device, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage) void SHVkUtil::EnsureBufferAndCopyHostVisibleData(Handle<SHVkLogicalDevice> device, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name)
{ {
if (bufferHandle) if (bufferHandle)
{ {
@ -126,7 +127,8 @@ namespace SHADE
size, size,
usage, usage,
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO, VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT,
name
); );
} }
} }

View File

@ -54,7 +54,7 @@ namespace SHADE
*/ */
/***********************************************************************************/ /***********************************************************************************/
static void EnsureBufferAndCopyData(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage); static void EnsureBufferAndCopyData(Handle<SHVkLogicalDevice> device, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name = "");
/***********************************************************************************/ /***********************************************************************************/
/*! /*!
@ -80,7 +80,7 @@ namespace SHADE
*/ */
/***********************************************************************************/ /***********************************************************************************/
static void EnsureBufferAndCopyHostVisibleData(Handle<SHVkLogicalDevice> device, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage); static void EnsureBufferAndCopyHostVisibleData(Handle<SHVkLogicalDevice> device, Handle<SHVkBuffer>& bufferHandle, void* src, uint32_t size, vk::BufferUsageFlagBits usage, const std::string& name = "");
static BindingAndSetHash GenBindingSetHash (uint32_t set, uint32_t binding) noexcept; static BindingAndSetHash GenBindingSetHash (uint32_t set, uint32_t binding) noexcept;
}; };

View File

@ -25,11 +25,13 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHBoundingBox::SHBoundingBox() noexcept SHBoundingBox::SHBoundingBox() noexcept
: RelativeExtents { SHVec3::One }
{ {
type = Type::BOX; type = Type::BOX;
} }
SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept
: RelativeExtents { SHVec3::One }
{ {
type = Type::BOX; type = Type::BOX;
@ -47,6 +49,7 @@ namespace SHADE
Center = rhs.Center; Center = rhs.Center;
Extents = rhs.Extents; Extents = rhs.Extents;
RelativeExtents = rhs.RelativeExtents;
} }
SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept
@ -55,6 +58,7 @@ namespace SHADE
Center = rhs.Center; Center = rhs.Center;
Extents = rhs.Extents; Extents = rhs.Extents;
RelativeExtents = rhs.RelativeExtents;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -71,6 +75,7 @@ namespace SHADE
{ {
Center = rhs.Center; Center = rhs.Center;
Extents = rhs.Extents; Extents = rhs.Extents;
RelativeExtents = rhs.RelativeExtents;
} }
return *this; return *this;
@ -86,6 +91,7 @@ namespace SHADE
{ {
Center = rhs.Center; Center = rhs.Center;
Extents = rhs.Extents; Extents = rhs.Extents;
RelativeExtents = rhs.RelativeExtents;
} }
return *this; return *this;
@ -100,11 +106,16 @@ namespace SHADE
return Center; return Center;
} }
SHVec3 SHBoundingBox::GetHalfExtents() const noexcept SHVec3 SHBoundingBox::GetWorldExtents() const noexcept
{ {
return Extents; return Extents;
} }
const SHVec3& SHBoundingBox::GetRelativeExtents() const noexcept
{
return RelativeExtents;
}
SHVec3 SHBoundingBox::GetMin() const noexcept SHVec3 SHBoundingBox::GetMin() const noexcept
{ {
return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z }; return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z };
@ -124,9 +135,14 @@ namespace SHADE
Center = newCenter; Center = newCenter;
} }
void SHBoundingBox::SetHalfExtents(const SHVec3& newHalfExtents) noexcept void SHBoundingBox::SetWorldExtents(const SHVec3& newWorldExtents) noexcept
{ {
Extents = newHalfExtents; Extents = newWorldExtents;
}
void SHBoundingBox::SetRelativeExtents(const SHVec3& newRelativeExtents) noexcept
{
RelativeExtents = newRelativeExtents;
} }
void SHBoundingBox::SetMin(const SHVec3& min) noexcept void SHBoundingBox::SetMin(const SHVec3& min) noexcept

View File

@ -55,7 +55,8 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] SHVec3 GetCenter () const noexcept; [[nodiscard]] SHVec3 GetCenter () const noexcept;
[[nodiscard]] SHVec3 GetHalfExtents() const noexcept; [[nodiscard]] SHVec3 GetWorldExtents () const noexcept;
[[nodiscard]] const SHVec3& GetRelativeExtents () const noexcept;
[[nodiscard]] SHVec3 GetMin () const noexcept; [[nodiscard]] SHVec3 GetMin () const noexcept;
[[nodiscard]] SHVec3 GetMax () const noexcept; [[nodiscard]] SHVec3 GetMax () const noexcept;
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept; [[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
@ -65,7 +66,8 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SetCenter (const SHVec3& newCenter) noexcept; void SetCenter (const SHVec3& newCenter) noexcept;
void SetHalfExtents (const SHVec3& newHalfExtents) noexcept; void SetWorldExtents (const SHVec3& newWorldExtents) noexcept;
void SetRelativeExtents (const SHVec3& newRelativeExtents) noexcept;
void SetMin (const SHVec3& min) noexcept; void SetMin (const SHVec3& min) noexcept;
void SetMax (const SHVec3& max) noexcept; void SetMax (const SHVec3& max) noexcept;
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept; void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
@ -89,6 +91,13 @@ namespace SHADE
[[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept; [[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept;
[[nodiscard]] static SHBoundingBox BuildFromBoxes (const SHBoundingBox* boxes, size_t numBoxes) noexcept; [[nodiscard]] static SHBoundingBox BuildFromBoxes (const SHBoundingBox* boxes, size_t numBoxes) noexcept;
[[nodiscard]] static SHBoundingBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept; [[nodiscard]] static SHBoundingBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
private:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
SHVec3 RelativeExtents;
}; };

Some files were not shown because too many files have changed in this diff Show More