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
Name: Default
Name: Camera
IsActive: true
NumberOfChildren: 0
Components:
Camera Component:
Position: {x: 0, y: 0, z: 0}
Position: {x: 0, y: 0, z: 8}
Pitch: 0
Yaw: 0
Roll: 0
@ -22,7 +22,7 @@
Strength: 0
Scripts: ~
- EID: 1
Name: Default
Name: Floor
IsActive: true
NumberOfChildren: 0
Components:
@ -36,8 +36,8 @@
RigidBody Component:
Type: Static
Mass: 1
Drag: 0
Angular Drag: 0
Drag: 0.00999999978
Angular Drag: 0.00999999978
Use Gravity: true
Interpolate: true
Freeze Position X: false
@ -50,24 +50,21 @@
Colliders:
- Is Trigger: false
Type: Box
Half Extents: {x: 24.7399445, y: 0.25, z: 8.75}
Half Extents: {x: 1, y: 1, z: 1}
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0, z: 0}
Scripts: ~
- EID: 2
Name: Player
- EID: 10
Name: Default
IsActive: true
NumberOfChildren: 3
NumberOfChildren: 0
Components:
Transform Component:
Translate: {x: -3.06177855, y: -2, z: -5}
Rotate: {x: -0, y: 0, z: -0}
Scale: {x: 2, y: 2, z: 2}
Renderable Component:
Mesh: 149697411
Material: 126974645
Translate: {x: -4.40482807, y: 2.57871056, z: -5.21213436}
Rotate: {x: -0.361265004, y: 1.11661232, z: -0.626627684}
Scale: {x: 0.999982238, y: 0.999987125, z: 0.999981165}
RigidBody Component:
Type: Dynamic
Mass: 1
@ -89,26 +86,10 @@
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0.5, z: 0}
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
Position Offset: {x: 0, y: 0, z: 0}
Scripts: ~
- EID: 3
Name: Default
Name: Empty
IsActive: true
NumberOfChildren: 0
Components:
@ -118,7 +99,7 @@
Scale: {x: 1, y: 1, z: 1}
Scripts: ~
- EID: 4
Name: Default
Name: Empty2
IsActive: true
NumberOfChildren: 0
Components:
@ -126,14 +107,9 @@
Translate: {x: 0, y: 0, z: 0}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1}
Scripts:
- Type: SHADE_Scripting.ThirdPersonCamera
armLength: 2
turnSpeedPitch: 0.300000012
turnSpeedYaw: 0.5
pitchClamp: 45
Scripts: ~
- EID: 9
Name: Default
Name: Bag
IsActive: true
NumberOfChildren: 0
Components:
@ -145,6 +121,67 @@
Mesh: 144838771
Material: 123745521
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
Name: item
IsActive: true
@ -189,71 +226,6 @@
Scripts:
- Type: Item
currCategory: 0
- 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:
- 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: ~
- Type: PickAndThrow
throwForce: [100, 200, 100]
item: 51000

View File

@ -51,7 +51,6 @@ public class AIPrototype : Script
private GameObject? player;
public AIPrototype(GameObject gameObj) : base(gameObj) { }
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 CameraControl(GameObject go) : base(go) { }
protected override void update()
{
//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 CameraFix(GameObject gameObj) : base(gameObj) { }
private Transform tranform;
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 Item(GameObject gameObj) : base(gameObj) { }
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 RigidBody RigidBody;
private Collider Collider;
public PhysicsTest(GameObject gameObj) : base(gameObj) { }
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 lastZDir;
private bool inRange = false;
public PickAndThrow(GameObject gameObj) : base(gameObj) { }
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 heavyMultiper = 0.25f;
public PlayerController(GameObject gameObj) : base(gameObj) { }
protected override void awake()
{
//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 PrintWhenActive(GameObject gameObj) : base(gameObj) { }
protected override void update()
{
Debug.Log("Active!");

View File

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

View File

@ -1,5 +1,6 @@
using SHADE;
using System;
using System.Collections.Generic;
public class RaccoonShowcase : Script
{
@ -17,7 +18,11 @@ public class RaccoonShowcase : Script
private double rotation = 0.0;
private Vector3 scale = Vector3.Zero;
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()
{
@ -27,6 +32,11 @@ public class RaccoonShowcase : Script
Debug.LogError("Transform is NULL!");
}
foreach (var child in Owner)
{
Debug.Log(child.Name);
}
originalScale = Transform.LocalScale.z;
}
protected override void update()
@ -36,4 +46,10 @@ public class RaccoonShowcase : Script
//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);
}
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 rotation = 0.0f;
[SerializeField]
private CallbackEvent emptyEvent;
[SerializeField]
private CallbackEvent<int> testEvent;
[SerializeField]
private CallbackEvent<int, double, Vector3> testEvent3 = new CallbackEvent<int, double, Vector3>();
private Transform Transform;
public RaccoonSpin(GameObject gameObj) : base(gameObj) { }
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>();
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 turnSpeedYaw = 0.5f;
public float pitchClamp = 45.0f;
public ThirdPersonCamera(GameObject go) : base(go) { }
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"
// 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 "Camera/SHCameraSystem.h"
#include "FRC/SHFramerateController.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
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
@ -39,7 +40,6 @@
#include "Scenes/SBTestScene.h"
#include "Assets/SHAssetManager.h"
#include "Scenes/SBMainScene.h"
#include "Serialization/Configurations/SHConfigurationManager.h"
@ -67,16 +67,21 @@ namespace Sandbox
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow, wndData);
// Create Systems
SHSystemManager::CreateSystem<SHGraphicsSystem>();
SHSystemManager::CreateSystem<SHScriptEngine>();
SHSystemManager::CreateSystem<SHPhysicsSystem>();
SHSystemManager::CreateSystem<SHTransformSystem>();
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
SHSystemManager::CreateSystem<SHPhysicsSystem>();
SHSystemManager::CreateSystem<SHPhysicsDebugDrawSystem>();
SHSystemManager::CreateSystem<SHAudioSystem>();
SHSystemManager::CreateSystem<SHCameraSystem>();
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
SHSystemManager::CreateSystem<SHGraphicsSystem>();
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
// Link up SHDebugDraw
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
#ifdef SHEDITOR
@ -101,11 +106,13 @@ namespace Sandbox
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsDebugDraw>();
SHSystemManager::RegisterRoutine<SHPhysicsDebugDrawSystem, SHPhysicsDebugDrawSystem::PhysicsDebugDrawRoutine>();
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
SHSystemManager::RegisterRoutine<SHScriptEngine, SHScriptEngine::GizmosDrawRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
@ -164,7 +171,7 @@ namespace Sandbox
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
{
drawColliders = !drawColliders;
SHSystemManager::GetSystem<SHPhysicsSystem>()->SetDrawColliders(drawColliders);
SHSystemManager::GetSystem<SHPhysicsDebugDrawSystem>()->SetDebugDrawFlag(SHPhysicsDebugDrawSystem::DebugDrawFlags::COLLIDER, drawColliders);
}
}
// Finish all graphics jobs first

View File

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

View File

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

View File

@ -34,6 +34,99 @@ namespace SHADE
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>
/// Represents a function call that can be serialised and put togetheer with scripts.
/// This variant accepts functions with 1 parameter.

View File

@ -50,12 +50,12 @@ namespace SHADE
Object TargetObject { get; }
}
<# for (int i = 1; i <= max; ++i) { #>
<# for (int i = 0; i <= max; ++i) { #>
/// <summary>
/// Represents a function call that can be serialised and put togetheer with scripts.
/// This variant accepts functions with <#=i#> parameter<# if (i > 1) {#>s<#} #>.
/// </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 ------------------------------------------------------------
/// <inheritdoc/>
@ -68,7 +68,7 @@ namespace SHADE
#region Fields ------------------------------------------------------------------
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;
#endregion
@ -121,7 +121,7 @@ namespace SHADE
/// Constructs a Callback action based on an action.
/// </summary>
/// <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;
}

View File

@ -45,6 +45,92 @@ namespace SHADE
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>
/// A container of CallbackActions that is correlated to a specific scenario as
/// specified by the user of this class.
@ -88,7 +174,7 @@ namespace SHADE
actions.Add(action);
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// Constructs and adds a CallbackAction into the event.
/// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<T1> action)
@ -96,7 +182,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1>(action));
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// 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>
@ -174,7 +260,7 @@ namespace SHADE
actions.Add(action);
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// Constructs and adds a CallbackAction into the event.
/// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<T1, T2> action)
@ -182,7 +268,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1, T2>(action));
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// 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>
@ -260,7 +346,7 @@ namespace SHADE
actions.Add(action);
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// Constructs and adds a CallbackAction into the event.
/// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<T1, T2, T3> action)
@ -268,7 +354,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1, T2, T3>(action));
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// 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>
@ -346,7 +432,7 @@ namespace SHADE
actions.Add(action);
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// Constructs and adds a CallbackAction into the event.
/// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param>
public void RegisterAction(Action<T1, T2, T3, T4> action)
@ -354,7 +440,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1, T2, T3, T4>(action));
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// 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>
@ -432,7 +518,7 @@ namespace SHADE
actions.Add(action);
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// Constructs and adds a CallbackAction into the event.
/// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param>
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));
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// 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>
@ -518,7 +604,7 @@ namespace SHADE
actions.Add(action);
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// Constructs and adds a CallbackAction into the event.
/// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param>
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));
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// 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>
@ -604,7 +690,7 @@ namespace SHADE
actions.Add(action);
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// Constructs and adds a CallbackAction into the event.
/// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param>
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));
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// 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>
@ -690,7 +776,7 @@ namespace SHADE
actions.Add(action);
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// Constructs and adds a CallbackAction into the event.
/// </summary>
/// <param name="action">System.Action to add as a CallbackAction.</param>
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));
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// 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>
@ -776,7 +862,7 @@ namespace SHADE
actions.Add(action);
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// Constructs and adds a CallbackAction into the event.
/// </summary>
/// <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)
@ -784,7 +870,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8, T9>(action));
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// 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>
@ -862,7 +948,7 @@ namespace SHADE
actions.Add(action);
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// Constructs and adds a CallbackAction into the event.
/// </summary>
/// <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)
@ -870,7 +956,7 @@ namespace SHADE
actions.Add(new CallbackAction<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(action));
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// 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>

View File

@ -61,13 +61,13 @@ namespace SHADE
IEnumerable<ICallbackAction> Actions { get; }
}
<# for (int i = 1; i <= max; ++i) { #>
<# for (int i = 0; i <= max; ++i) { #>
/// <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<<# 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 --------------------------------------------------------------
/// <inheritdoc/>
@ -82,13 +82,13 @@ namespace SHADE
/// <inheritdoc/>
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/>
public void RegisterAction(ICallbackAction 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);
return;
@ -100,26 +100,26 @@ namespace SHADE
/// Adds a CallbackAction into the event.
/// </summary>
/// <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);
}
/// <summary>
/// Constructs and adds a CallbackACtion into the event.
/// Constructs and adds a CallbackAction into the event.
/// </summary>
/// <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>
/// Constructs and adds a CallbackACtion into the event.
/// 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<<# 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/>
public void DeregisterAction(ICallbackAction action)
@ -132,9 +132,9 @@ namespace SHADE
/// <summary>
/// Invokes all stored CallbackActions with the specified parameters.
/// </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
{

View File

@ -52,6 +52,8 @@ enum class AssetType : AssetTypeMeta
PREFAB,
MATERIAL,
MESH,
SCRIPT,
FONT,
MAX_COUNT
};
constexpr size_t TYPE_COUNT{ static_cast<size_t>(AssetType::MAX_COUNT) };
@ -86,33 +88,38 @@ constexpr std::string_view SCENE_EXTENSION {".shade"};
constexpr std::string_view PREFAB_EXTENSION {".shprefab"};
constexpr std::string_view MATERIAL_EXTENSION {".shmat"};
constexpr std::string_view TEXTURE_EXTENSION {".shtex"};
constexpr std::string_view MODEL_EXTENSION {".shmodel"};
constexpr std::string_view MODEL_EXTENSION{ ".shmodel" };
constexpr std::string_view EXTENSIONS[] = {
AUDIO_EXTENSION,
SHADER_EXTENSION,
SHADER_BUILT_IN_EXTENSION,
FONT_EXTENSION,
MATERIAL_EXTENSION,
TEXTURE_EXTENSION,
SHADER_BUILT_IN_EXTENSION,
TEXTURE_EXTENSION,
MODEL_EXTENSION,
SCRIPT_EXTENSION,
SCENE_EXTENSION,
SCENE_EXTENSION,
PREFAB_EXTENSION,
MATERIAL_EXTENSION,
"dummy",
SCRIPT_EXTENSION,
FONT_EXTENSION,
AUDIO_WAV_EXTENSION,
};
constexpr size_t EXTENSIONS_COUNT{ 11 };
// EXTERNAL EXTENSIONS
constexpr std::string_view GLSL_EXTENSION{ ".glsl" };
constexpr std::string_view DDS_EXTENSION{ ".dds" };
constexpr std::string_view FBX_EXTENSION{ ".fbx" };
constexpr std::string_view GLTF_EXTENSION{ ".gltf" };
constexpr std::string_view TTF_EXTENSION{ ".ttf" };
constexpr std::string_view EXTERNALS[] = {
GLSL_EXTENSION,
DDS_EXTENSION,
FBX_EXTENSION,
GLTF_EXTENSION
GLTF_EXTENSION,
TTF_EXTENSION
};
// 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 };
// 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

View File

@ -83,7 +83,7 @@ namespace SHADE
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
return std::filesystem::path();
@ -338,7 +338,7 @@ namespace SHADE
return result;
}
void SHAssetManager::CompileAsset(AssetPath const& path) noexcept
void SHAssetManager::CompileAsset(AssetPath const& path, bool genMeta) noexcept
{
if (!std::filesystem::exists(path))
{
@ -360,10 +360,12 @@ namespace SHADE
std::string modelPath = path.string().substr(0, path.string().find_last_of('.'));
modelPath += MODEL_EXTENSION;
newPath = modelPath;
GenerateNewMeta(newPath);
}
if (genMeta)
{
GenerateNewMeta(newPath);
}
}
FolderPointer SHAssetManager::GetRootFolder() noexcept
@ -371,18 +373,12 @@ namespace SHADE
return folderRoot;
}
bool SHAssetManager::IsRecognised(char const* ext) noexcept
{
for (auto const& e : EXTENSIONS)
{
if (strcmp(ext, e.data()) == 0)
{
return true;
}
}
return false;
}
void SHAssetManager::RefreshDirectory() noexcept
{
SHFileSystem::DestroyDirectory(folderRoot);
assetCollection.clear();
BuildAssetCollection();
}
SHAsset SHAssetManager::CreateAssetFromPath(AssetPath path) noexcept
{
@ -396,51 +392,6 @@ namespace SHADE
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
{
//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();
if (ext == SHADER_BUILT_IN_EXTENSION.data())
@ -597,11 +548,32 @@ namespace SHADE
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
{
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))
{

View File

@ -87,9 +87,10 @@ namespace SHADE
static std::vector<SHAssetData const*> GetAllDataOfType(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 void RefreshDirectory() noexcept;
private:
@ -98,16 +99,12 @@ namespace SHADE
static SHAssetData* LoadData(SHAsset const& asset) noexcept;
static SHAssetData* LoadSubData(SHAsset const& asset) 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;
static bool IsRecognised(char const*) noexcept;
static SHAsset CreateAssetFromPath(AssetPath path) noexcept;
static void CompileAll() noexcept;
static bool DeleteLocalFile(AssetPath path) noexcept;
//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
{
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)
{
@ -98,6 +98,7 @@ namespace SHADE
meta.type = static_cast<AssetType>(type);
meta.isSubAsset = false;
meta.parent = 0;
// Burn Line
if (std::getline(metaFile, line))

View File

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

View File

@ -7,13 +7,15 @@
#include "ECS_Base/Managers/SHComponentManager.h"
#include "Math/Transform/SHTransformComponent.h"
#include <math.h>
#include "Scene/SHSceneManager.h"
namespace SHADE
{
void SHCameraSystem::UpdateEditorCamera(double dt) noexcept
{
auto& camera = editorCamera;
SHVec3 view, right, UP;
GetCameraAxis(camera, view, right, UP);
@ -61,63 +63,43 @@ namespace SHADE
}
UpdateCameraComponent(editorCamera);
}
void SHCameraSystem::UpdateEditorArm(double dt,bool active ,SHVec3 const& targetPos) noexcept
{
if (active == false)
{
editorCameraArm.offset = SHVec3{0.0f};
return;
}
editorCamera.SetPosition(targetPos);
double mouseX, mouseY;
SHInputManager::GetMouseVelocity(&mouseX, &mouseY);
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);
}
void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept
{
SHCameraSystem* system = static_cast<SHCameraSystem*>(GetSystem());
auto& camera = system->editorCamera;
SHVec3 view, right, UP;
system->GetCameraAxis(camera, view, right, UP);
if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::A))
{
//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;
SHInputManager::GetMouseVelocity(&mouseX,&mouseY);
//std::cout << camera.yaw << std::endl;
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)
{
@ -164,6 +146,9 @@ namespace SHADE
void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept
{
if (camera.isActive == false)
return;
if (SHComponentManager::HasComponent<SHTransformComponent>(camera.GetEID()) == true && &camera != &editorCamera)
{
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(camera.GetEID());
@ -183,11 +168,17 @@ namespace SHADE
if (SHComponentManager::HasComponent<SHCameraArmComponent>(camera.GetEID()))
{
auto arm = SHComponentManager::GetComponent<SHCameraArmComponent>(camera.GetEID());
camera.offset = arm->GetOffset();
if(arm->lookAtCameraOrigin)
CameraLookAt(camera, camera.position);
if (arm->isActive == true)
{
camera.offset = arm->GetOffset();
if (arm->lookAtCameraOrigin)
CameraLookAt(camera, camera.position);
}
}
SHVec3 view, right, UP;
@ -287,12 +278,14 @@ namespace SHADE
for (auto& pivot : pivotDense)
{
system->UpdatePivotArmComponent(pivot);
if(SHSceneManager::CheckNodeAndComponentsActive<SHCameraArmComponent>(pivot.GetEID()))
system->UpdatePivotArmComponent(pivot);
}
for (auto& cam : dense)
{
system->UpdateCameraComponent(cam);
if (SHSceneManager::CheckNodeAndComponentsActive<SHCameraComponent>(cam.GetEID()))
system->UpdateCameraComponent(cam);
}
for (auto& handle : system->directorHandleList)
{
@ -399,7 +392,7 @@ namespace SHADE
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);

View File

@ -5,6 +5,7 @@
#include "ECS_Base/System/SHSystemRoutine.h"
#include "Resource/SHResourceLibrary.h"
#include "SHCameraDirector.h"
#include "SHCameraArmComponent.h"
#include "SH_API.h"
namespace SHADE
@ -18,6 +19,7 @@ namespace SHADE
//A camera component that represents editor camera.
//This is not tied to any entity. Hence this EID should not be used.
SHCameraComponent editorCamera;
SHCameraArmComponent editorCameraArm;
SHResourceLibrary<SHCameraDirector> directorLibrary;
std::vector<DirectorHandle> directorHandleList;
@ -34,14 +36,7 @@ namespace SHADE
void Init (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;
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 SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) 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
{
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)
{
redoStack = CommandStack();
*pCurrRedoStack = CommandStack(defaultStackSize);
commandPtr->Execute();
if (overrideValue && !undoStack.empty())
if (overrideValue && !pCurrUndoStack->Empty())
{
undoStack.top()->Merge(commandPtr);
pCurrUndoStack->Top()->Merge(commandPtr);
}
else
{
undoStack.push(commandPtr);
pCurrUndoStack->Push(commandPtr);
}
}
void SHCommandManager::RegisterCommand(BaseCommandPtr commandPtr)
{
undoStack.push(commandPtr);
pCurrUndoStack->Push(commandPtr);
}
void SHCommandManager::UndoCommand()
{
if (undoStack.empty())
if (pCurrUndoStack->Empty())
return;
undoStack.top()->Undo();
redoStack.push(undoStack.top());
undoStack.pop();
pCurrUndoStack->Top()->Undo();
pCurrRedoStack->Push(pCurrUndoStack->Top());
pCurrUndoStack->Pop();
}
void SHCommandManager::RedoCommand()
{
if (redoStack.empty())
if (pCurrRedoStack->Empty())
return;
redoStack.top()->Execute();
undoStack.push(redoStack.top());
redoStack.pop();
pCurrRedoStack->Top()->Execute();
pCurrUndoStack->Push(pCurrRedoStack->Top());
pCurrRedoStack->Pop();
}
std::size_t SHCommandManager::GetUndoStackSize()
{
return undoStack.size();
return pCurrUndoStack->Size();
}
std::size_t SHCommandManager::GetRedoStackSize()
{
return redoStack.size();
return pCurrRedoStack->Size();
}
void SHCommandManager::PopLatestCommandFromRedoStack()
{
redoStack.pop();
pCurrRedoStack->Pop();
}
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

View File

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

View File

@ -13,11 +13,12 @@
#include "Editor/SHEditor.h"
#include "Editor/DragDrop/SHDragDrop.hpp"
#include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h"
#include "Editor/EditorWindow/SHEditorWindowManager.h"
namespace SHADE
{
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);
DrawMenuBar();
DrawCurrentFolder();
DrawAssetBeingCreated();
}
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()
{
if (ImGui::BeginMenuBar())
{
if(ImGui::SmallButton(ICON_MD_SYNC))
{
QueueRefresh();
}
if(ImGui::SmallButton(ICON_FA_CIRCLE_PLUS))
{
isAssetBeingCreated = true;
}
ImGui::EndMenuBar();
}
}
//if !compiled, set genMeta to true
ImRect SHAssetBrowser::RecursivelyDrawTree(FolderPointer folder)
{
auto const& subFolders = folder->subFolders;
auto const& files = folder->files;
auto files = folder->files;
const bool isSelected = std::ranges::find(selectedFolders, folder) != selectedFolders.end();
ImGuiTreeNodeFlags flags = (subFolders.empty() && files.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow;
if (isSelected)
@ -62,21 +88,10 @@ namespace SHADE
ImGuiID folderID = ImGui::GetItemID();
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
if (ImGui::BeginPopupContextItem())
{
if (ImGui::BeginMenu("Create Asset"))
{
//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::BeginPopupContextItem())
//{
// ImGui::EndPopup();
//}
if (ImGui::IsItemClicked())
{
@ -100,19 +115,15 @@ namespace SHADE
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
vertLineEnd.y = midPoint;
}
for (auto const& file : files)
for (auto& file : files)
{
if(file.assetMeta == nullptr)
continue;
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;
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
vertLineEnd.y = midPoint;
}
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1);
if(assetBeingCreated.has_value() && std::get<0>(assetBeingCreated.value()) == folder)
DrawAssetBeingCreated();
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)
return ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
@ -173,7 +210,7 @@ namespace SHADE
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());
if (SHDragDrop::BeginSource())
{
@ -212,7 +249,6 @@ namespace SHADE
case AssetType::MAX_COUNT: break;
default:;
}
}
//TODO: Combine Draw asset and Draw Folder recursive drawing
@ -227,7 +263,7 @@ namespace SHADE
for(auto const& subAsset : asset->subAssets)
{
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;
drawList->AddLine(ImVec2(vertLineStart.x, midPoint), ImVec2(vertLineStart.x + horizontalLineSize, midPoint), treeLineColor, 1);
vertLineEnd.y = midPoint;
@ -240,19 +276,52 @@ namespace SHADE
void SHAssetBrowser::DrawAssetBeingCreated() noexcept
{
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))
if(isAssetBeingCreated)
ImGui::OpenPopup(newAssetPopup.data());
if(ImGui::BeginPopupModal(newAssetPopup.data(), &isAssetBeingCreated))
{
AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName);
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
ImGui::RadioButton("Material", true);
ImGui::SameLine();
if (ImGui::InputText("##newAssetName", &nameOfAssetBeingCreated, ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_AutoSelectAll))
{
matInspector->OpenMaterial(assetId, true);
AssetID assetId = SHAssetManager::CreateNewAsset(AssetType::MATERIAL, nameOfAssetBeingCreated);
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
{
matInspector->OpenMaterial(assetId, true);
}
nameOfAssetBeingCreated.clear();
QueueRefresh();
isAssetBeingCreated = false;
ImGui::CloseCurrentPopup();
}
assetBeingCreated.reset();
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
{
public:
using AssetEntry = std::tuple<FolderPointer, AssetType, std::string>;
SHAssetBrowser();
void Init();
void Update();
void Refresh();
void QueueRefresh() noexcept;
private:
void DrawMenuBar();
ImRect RecursivelyDrawTree(FolderPointer folder);
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 Refresh() noexcept;
FolderPointer rootFolder, prevFolder, currentFolder;
std::optional<AssetEntry> assetBeingCreated;
std::vector<FolderPointer> selectedFolders;
std::vector<AssetID> selectedAssets;
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 "Tools/SHException.h"
#include "Editor/IconsMaterialDesign.h"
#include "SHHierarchyPanelCommands.h"
//#==============================================================#
//|| Library Includes ||
@ -105,14 +106,21 @@ namespace SHADE
PasteEntities(editor->selectedEntities.back());
}
}
if(ImGui::IsKeyReleased(ImGuiKey_Delete))
{
DeleteSelectedEntities();
}
}
}
if(ImGui::IsWindowHovered() && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
{
ParentSelectedEntities(MAX_EID, draggingEntities);
draggingEntities.clear();
ImGui::ClearDragDrop();
if(ImGui::IsDragDropActive())
{
ParentSelectedEntities(MAX_EID, draggingEntities);
draggingEntities.clear();
ImGui::ClearDragDrop();
}
}
ImGui::End();
}
@ -255,9 +263,10 @@ namespace SHADE
PasteEntities(eid);
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()))
@ -282,9 +291,12 @@ namespace SHADE
}
else editor->selectedEntities.clear();
}
else if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
editor->selectedEntities.clear();
editor->selectedEntities.push_back(eid);
else
{
if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
editor->selectedEntities.clear();
editor->selectedEntities.push_back(eid);
}
}//if not selected
else
{
@ -365,14 +377,16 @@ namespace SHADE
if (eid == beginEID || eid == endEID)
{
startSelecting = true;
editor->selectedEntities.push_back(eid);
if(std::ranges::find(editor->selectedEntities, eid) == editor->selectedEntities.end())
editor->selectedEntities.push_back(eid);
}
}
else
{
if (!endSelecting)
{
editor->selectedEntities.push_back(eid);
if (std::ranges::find(editor->selectedEntities, eid) == editor->selectedEntities.end())
editor->selectedEntities.push_back(eid);
if (eid == endEID || eid == beginEID)
{
endSelecting = true;
@ -397,47 +411,39 @@ namespace SHADE
void SHHierarchyPanel::CopySelectedEntities()
{
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)
{
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()
{
EntityID newEID = SHEntityManager::CreateEntity(eid);
if (eid == MAX_EID)
eid = newEID;
}
void SHCreateEntityCommand::Undo()
{
SHEntityManager::DestroyEntity(eid);
}
void SHEntityParentCommand::Execute()
void SHHierarchyPanel::DeleteSelectedEntities()
{
const auto editor = SHSystemManager::GetSystem<SHEditor>();
auto const& 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);
}
std::vector<EntityID> entitiesToDelete{};
std::ranges::copy_if(editor->selectedEntities, std::back_inserter(entitiesToDelete), [&sceneGraph, &selectedEntities = editor->selectedEntities](EntityID const& eid)
{
EntityID parentEID = sceneGraph.GetParent(eid)->GetEntityID();
if (parentEID == MAX_EID)
return true;
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

View File

@ -10,7 +10,6 @@
#include "imgui_internal.h"
#include "ECS_Base/SHECSMacros.h"
#include "Editor/EditorWindow/SHEditorWindow.h"
#include "Editor/Command/SHCommand.hpp"
namespace SHADE
{
class SHSceneNode;
@ -33,6 +32,7 @@ namespace SHADE
void SelectAllEntities();
void CopySelectedEntities();
void PasteEntities(EntityID parentEID = MAX_EID);
void DeleteSelectedEntities();
bool skipFrame = false;
std::string filter;
bool isAnyNodeSelected = false;
@ -41,33 +41,4 @@ namespace SHADE
};//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

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 "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
#include "Physics/Components/SHColliderComponent.h"
#include "Physics/Interface/SHColliderComponent.h"
#include "Reflection/SHReflectionMetadata.h"
#include "Resource/SHResourceManager.h"
@ -224,9 +224,6 @@ namespace SHADE
if (!component)
return;
// Get transform component for extrapolating relative sizes
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(component->GetEID());
const auto componentType = rttr::type::get(*component);
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
ImGui::SameLine();
@ -234,46 +231,39 @@ namespace SHADE
{
DrawContextMenu(component);
auto& colliders = component->GetColliders();
auto& colliders = component->GetCollisionShapes();
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 };
for (int i{}; i < size; ++i)
{
ImGui::PushID(i);
SHCollider* collider = &component->GetCollider(i);
SHCollisionShape* collider = &component->GetCollisionShape(i);
auto cursorPos = ImGui::GetCursorPos();
//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::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger");
auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
SHEditorWidgets::BeginPanel(std::format("{} Box #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
const auto* BOX = reinterpret_cast<const SHBoundingBox*>(collider->GetShape());
SHEditorWidgets::DragVec3
(
"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); });
}
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::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger");
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
const auto* SPHERE = reinterpret_cast<const SHBoundingSphere*>(collider->GetShape());
SHEditorWidgets::DragFloat
(
"Radius",
[sphere, transformComponent]
{
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;
},
[SPHERE] { return SPHERE->GetRelativeRadius(); },
[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 "ECS_Base/Managers/SHSystemManager.h"
#include "Physics/Components/SHRigidBodyComponent.h"
#include "Physics/Components/SHColliderComponent.h"
#include "Physics/Interface/SHRigidBodyComponent.h"
#include "Physics/Interface/SHColliderComponent.h"
#include "Camera/SHCameraComponent.h"
#include "Camera/SHCameraArmComponent.h"
#include "SHEditorComponentView.h"
@ -93,13 +93,14 @@ namespace SHADE
{
EntityID const& eid = editor->selectedEntities[0];
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
if(!entity)
SHSceneNode* entityNode = SHSceneManager::GetCurrentSceneGraph().GetNode(eid);
if(!entity || !entityNode)
{
ImGui::End();
return;
}
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::InputText("##EntityName", &entity->name);

View File

@ -23,6 +23,9 @@
#include "Scene/SHSceneManager.h"
#include "Serialization/SHSerialization.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
{
@ -43,8 +46,7 @@ namespace SHADE
void SHEditorMenuBar::Init()
{
SHEditorWindow::Init();
constexpr std::string_view path = "../../Assets/Editor/Layouts";
for(auto const& entry : std::filesystem::directory_iterator(path))
for(auto const& entry : std::filesystem::directory_iterator(LAYOUT_FOLDER_PATH))
{
layoutPaths.push_back(entry.path());
}
@ -221,39 +223,20 @@ namespace SHADE
{
if(editor->SaveScene())
{
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
{
.previousState = editor->editorState
};
editor->editorState = SHEditor::State::PLAY;
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
editor->Play();
}
}
ImGui::EndDisabled();
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE);
if(ImGui::SmallButton(ICON_MD_PAUSE))
{
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
{
.previousState = editor->editorState
};
editor->editorState = SHEditor::State::PAUSE;
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT);
editor->Pause();
}
ImGui::EndDisabled();
ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP);
if(ImGui::SmallButton(ICON_MD_STOP))
{
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
{
.previousState = editor->editorState
};
editor->editorState = SHEditor::State::STOP;
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
editor->LoadScene(SHSceneManager::GetCurrentSceneAssetID());
editor->Stop();
}
ImGui::EndDisabled();
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()
{
SHEditorWindow::Update();
if (shouldUpdateCamera)
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)
{
auto camSystem = SHSystemManager::GetSystem<SHCameraSystem>();
camSystem->UpdateEditorCamera(SHFrameRateController::GetRawDeltaTime());
shouldUpdateCamera = false;
}
camSystem->UpdateEditorArm(SHFrameRateController::GetRawDeltaTime(), shouldUpdateCamArm, targetPos);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
if (Begin())
@ -51,7 +70,6 @@ namespace SHADE
beginCursorPos = ImGui::GetCursorScreenPos();
viewportMousePos = { mousePos.x - beginCursorPos.x, mousePos.y - beginCursorPos.y };
gfxSystem->GetMousePickSystem()->SetViewportMousePos(viewportMousePos);
ImGui::Image((ImTextureID)descriptorSet, { beginContentRegionAvailable.x, beginContentRegionAvailable.y });
if (ImGui::IsWindowHovered() && ImGui::IsMouseDown(ImGuiMouseButton_Right))
@ -64,24 +82,28 @@ namespace SHADE
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;
}
if (ImGui::IsKeyReleased(ImGuiKey_W))
if (ImGui::IsKeyReleased(ImGuiKey_E))
{
transformGizmo.operation = SHTransformGizmo::Operation::ROTATE;
}
if (ImGui::IsKeyReleased(ImGuiKey_E))
if (ImGui::IsKeyReleased(ImGuiKey_R))
{
transformGizmo.operation = SHTransformGizmo::Operation::SCALE;
}
}
}
ImGuizmo::SetRect(beginCursorPos.x, beginCursorPos.y, beginContentRegionAvailable.x, beginContentRegionAvailable.y);
transformGizmo.Draw();
if(editor->editorState != SHEditor::State::PLAY)
transformGizmo.Draw();
ImGui::End();
ImGui::PopStyleVar();
}

View File

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

View File

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

View File

@ -29,6 +29,7 @@
//#==============================================================#
//|| Editor Window Includes ||
//#==============================================================#
#include "EditorWindow/SHEditorWindowManager.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
{
@ -73,8 +78,6 @@ namespace SHADE
//#==============================================================#
//Handle<SHVkCommandPool> SHEditor::imguiCommandPool;
//Handle<SHVkCommandBuffer> SHEditor::imguiCommandBuffer;
SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{};
SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{};
//std::vector<EntityID> SHEditor::selectedEntities;
//#==============================================================#
@ -106,7 +109,7 @@ namespace SHADE
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini";
io->IniFilename = USER_LAYOUT_PATH.data();
io->ConfigWindowsMoveFromTitleBarOnly = true;
InitLayout();
@ -164,7 +167,19 @@ namespace SHADE
{
SHCommandManager::UndoCommand();
}
if(ImGui::IsKeyReleased(ImGuiKey_F5))
{
Play();
}
else if (ImGui::IsKeyReleased(ImGuiKey_F6))
{
Pause();
}
else if (ImGui::IsKeyReleased(ImGuiKey_F7))
{
Stop();
}
Render();
}
@ -236,20 +251,20 @@ namespace SHADE
{
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
}
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;
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 };
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();
}
@ -501,9 +516,12 @@ namespace SHADE
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());
});
cmd->EndLabeledSegment();
});
#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()
{
SDL_Event event;

View File

@ -36,73 +36,7 @@ namespace SHADE
class SHVkCommandBuffer;
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.
@ -184,6 +118,10 @@ namespace SHADE
void LoadScene(AssetID const& assetID) noexcept;
void Play();
void Pause();
void Stop();
// List of selected entities
std::vector<EntityID> selectedEntities;

View File

@ -53,9 +53,12 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
/* 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()
@ -75,7 +78,7 @@ namespace SHADE
bool SHEditorUI::BeginMenu(const std::string& label)
{
return ImGui::BeginMenu(label.data());
return ImGui::BeginMenu(label.data());
}
bool SHEditorUI::BeginMenu(const std::string& label, const char* icon)
@ -143,7 +146,7 @@ namespace SHADE
bool SHEditorUI::Selectable(const std::string& label)
{
return ImGui::Selectable(label.data());
return ImGui::Selectable(label.data());
}
bool SHEditorUI::Selectable(const std::string& label, const char* icon)
@ -165,8 +168,10 @@ namespace SHADE
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::InputInt("##", &value,
1, 10,
return ImGui::DragInt("##", &value, 0.001f,
std::numeric_limits<int>::min(),
std::numeric_limits<int>::max(),
"%d",
ImGuiInputTextFlags_EnterReturnsTrue);
}
bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered)
@ -190,31 +195,22 @@ namespace SHADE
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::InputFloat("##", &value,
0.1f, 1.0f, "%.3f",
return ImGui::DragFloat("##", &value, 0.001f,
std::numeric_limits<float>::lowest(),
std::numeric_limits<float>::max(),
"%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
}
bool SHEditorUI::InputDouble(const std::string& label, double& value, bool* isHovered)
{
ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::InputDouble("##", &value,
0.1, 1.0, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
float val = value;
const bool CHANGED = InputFloat(label, val, isHovered);
if (CHANGED)
{
value = static_cast<double>(val);
}
return CHANGED;
}
bool SHEditorUI::InputAngle(const std::string& label, double& value, bool* isHovered)
{
ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
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*/)
{
ImGui::Text(label.c_str());
@ -266,10 +262,10 @@ namespace SHADE
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);
}
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"};
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)
@ -288,7 +284,7 @@ namespace SHADE
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());
if (isHovered)
@ -296,7 +292,7 @@ namespace SHADE
ImGui::SameLine();
SHEntity* entity = SHEntityManager::GetEntityByID(value);
std::ostringstream oss;
if (entity)
if (!alwaysNull && entity)
{
oss << value << ": " << entity->name;
}
@ -314,6 +310,13 @@ namespace SHADE
SHDragDrop::EndTarget();
}
}
ImGui::SameLine();
if (ImGui::Button("Clear"))
{
value = MAX_EID;
changed = true;
}
return changed;
}

View File

@ -85,8 +85,9 @@ namespace SHADE
/// Wraps up ImGui::CollapsingHeader().
/// </summary>
/// <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>
static bool CollapsingHeader(const std::string& title);
static bool CollapsingHeader(const std::string& title, bool* isHovered = nullptr);
static void SameLine();
static void Separator();
@ -219,17 +220,6 @@ namespace SHADE
/// <returns>True if the value was changed.</returns>
static bool InputDouble(const std::string& label, double& value, bool* isHovered = nullptr);
/// <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.
/// <br/>
/// Wraps up ImGui::SliderInt().
@ -296,7 +286,7 @@ namespace SHADE
/// <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 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>
/// Creates a text field widget for string input.
/// <br/>
@ -313,8 +303,12 @@ namespace SHADE
/// <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>
/// <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>
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>
/// Creates a combo box for enumeration input.
/// </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_REMOVED_EVENT { 4 };
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 6 };
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 7 };
constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 8 };
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 9 };
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 10 };
constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 6 };
constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 7 };
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 8 };
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 9 };
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 <filesystem>
#include <queue>
#include <stack>
#include "Assets/SHAssetMetaHandler.h"
@ -24,29 +25,94 @@ namespace SHADE
return true;
}
void SHFileSystem::BuildDirectory(FolderPath path, FolderPointer& root, std::unordered_map<AssetID, SHAsset>& assetCollection) noexcept
bool SHFileSystem::IsRecognised(char const* ext) noexcept
{
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::queue<FolderPointer> folderQueue;
std::stack<FolderPointer> folderStack;
root = new SHFolder("root");
root->path = path;
folderQueue.push(root);
folderStack.push(root);
while (!folderQueue.empty())
while (!folderStack.empty())
{
auto const folder = folderQueue.front();
folderQueue.pop();
auto const folder = folderStack.top();
folderStack.pop();
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 (path.extension().string() == META_EXTENSION)
{
//auto asset = SHAssetMetaHandler::RetrieveMetaData(path);
//assetCollection.insert({ asset.id, asset });
assets.push_back(SHAssetMetaHandler::RetrieveMetaData(path));
}
else
@ -55,28 +121,114 @@ namespace SHADE
path.stem().string(),
path.string(),
path.extension().string(),
nullptr
nullptr,
IsCompilable(path.extension().string()),
false
);
}
continue;
}
// If item is folder
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()) };
folderQueue.push(newFolder);
folderStack.push(newFolder);
}
for (auto const& asset : assets)
for (auto& file : folder->files)
{
assetCollection.emplace(asset.id, asset);
for(auto& file : folder->files)
if (!IsRecognised(file.ext.c_str()))
{
continue;
}
bool found{ false };
for (auto const& asset : assets)
{
assetCollection.emplace(asset.id, asset);
if (file.name == asset.name)
{
file.assetMeta = &assetCollection[asset.id];
break;
AssetPath path{ file.path };
if (SHAssetMetaHandler::GetTypeFromExtension(path.extension().string()) == asset.type)
{
file.assetMeta = &assetCollection[asset.id];
found = true;
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
{
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:
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;
FileExt ext;
SHAsset const* assetMeta;
bool compilable;
bool compiled;
};
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?)
&allocCreateInfo,
&tempBuffer, &stagingAlloc, &allocInfo);
SET_VK_OBJ_NAME_VK(device, vk::ObjectType::eDeviceMemory, allocInfo.deviceMemory, "[Memory] Staging - " + name);
// then assign it to the hpp version
stagingBuffer = tempBuffer;
SET_VK_OBJ_NAME(device, vk::ObjectType::eBuffer, stagingBuffer, "[Buffer] Staging - " + name);
// Just map, copy then unmap
void* stagingBufferMappedPtr = nullptr;
@ -255,7 +257,11 @@ namespace SHADE
auto result = vmaCreateBuffer(vmaAllocator,
&bufferCreateInfo.operator VkBufferCreateInfo & (),
&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)
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{}
, stagingBuffer{}
, sizeStored{ 0 }
@ -281,19 +287,23 @@ namespace SHADE
, alloc {nullptr}
, randomAccessOptimized{false}
, vmaAllocator{allocator}
, device { logicalDevice }
{}
SHVkBuffer::SHVkBuffer(
Handle<SHVkLogicalDevice> logicalDevice,
uint32_t inSize,
void* data,
uint32_t srcSize,
std::reference_wrapper<VmaAllocator const> allocator,
vk::BufferUsageFlags bufferUsage,
const std::string& name,
VmaMemoryUsage memUsage,
VmaAllocationCreateFlags allocFlags
) noexcept
: SHVkBuffer(allocator)
: SHVkBuffer(logicalDevice, allocator)
{
this->name = name;
Init(inSize, data, srcSize, bufferUsage, memUsage, allocFlags);
}
@ -308,6 +318,8 @@ namespace SHADE
, bufferUsageFlags {rhs.bufferUsageFlags}
, bufferCreateInfo { rhs.bufferCreateInfo }
, allocCreateInfo { rhs.allocCreateInfo }
, name { std::move(rhs.name) }
, device { rhs.device }
{
rhs.vkBuffer = VK_NULL_HANDLE;
@ -329,6 +341,8 @@ namespace SHADE
bufferCreateInfo = rhs.bufferCreateInfo;
allocCreateInfo = rhs.allocCreateInfo;
bufferUsageFlags = rhs.bufferUsageFlags;
name = std::move(rhs.name);
device = rhs.device;
return *this;
}
@ -406,6 +420,8 @@ namespace SHADE
auto [tempBuffer, allocInfo] = createBuffer(sizeStored);
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
if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)

View File

@ -12,6 +12,7 @@ namespace SHADE
//using SHVkBufferUsageBits = vk::BufferUsageFlagBits;
class SHVkCommandBuffer;
class SHVkLogicalDevice;
class SHVkBuffer
{
@ -51,6 +52,11 @@ namespace SHADE
//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 */
/*-----------------------------------------------------------------------*/
@ -62,13 +68,15 @@ namespace SHADE
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
SHVkBuffer (void) noexcept = delete;
SHVkBuffer (std::reference_wrapper<VmaAllocator const> allocator) noexcept;
SHVkBuffer (Handle<SHVkLogicalDevice> logicalDevice, std::reference_wrapper<VmaAllocator const> allocator) noexcept;
SHVkBuffer (
Handle<SHVkLogicalDevice> logicalDevice,
uint32_t inSize,
void* data,
uint32_t srcSize,
std::reference_wrapper<VmaAllocator const> allocator,
vk::BufferUsageFlags bufferUsage,
vk::BufferUsageFlags bufferUsage,
const std::string& name = "",
VmaMemoryUsage memUsage = VMA_MEMORY_USAGE_AUTO,
VmaAllocationCreateFlags allocFlags = {}
) noexcept;
@ -84,7 +92,7 @@ namespace SHADE
uint32_t inSize,
void* data,
uint32_t srcSize,
vk::BufferUsageFlags bufferUsage,
vk::BufferUsageFlags bufferUsage,
VmaMemoryUsage memUsage,
VmaAllocationCreateFlags allocFlags
) noexcept;

View File

@ -105,6 +105,9 @@ namespace SHADE
// Set the state to recording if the call above succeeded.
cmdBufferState = SH_CMD_BUFFER_STATE::RECORDING;
// Reset segment count
segmentDepth = 0;
}
/***************************************************************************/
@ -507,6 +510,41 @@ namespace SHADE
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
//{
// //vkCommandBuffer.pipelineBarrier()

View File

@ -7,6 +7,7 @@
#include "Resource/SHResourceLibrary.h"
#include "Graphics/Pipeline/SHVkPipelineLayout.h"
#include "Graphics/Pipeline/SHPipelineType.h"
#include "Math/SHColour.h"
namespace SHADE
{
@ -78,7 +79,10 @@ namespace SHADE
std::array<PipelineBindPointData, static_cast<uint32_t>(SH_PIPELINE_TYPE::NUM_TYPES)> bindPointData;
//! 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 */
@ -107,7 +111,7 @@ namespace SHADE
void Reset(void);
// Begins and Ends
void BeginRecording (void) noexcept;
void BeginRecording () 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 EndRenderpass (void) noexcept;
@ -148,6 +152,10 @@ namespace SHADE
bool IsReadyToSubmit (void) const noexcept;
void HandlePostSubmit (void) noexcept;
// Debugging
void BeginLabeledSegment(const std::string& label) noexcept;
void EndLabeledSegment() noexcept;
// Push Constant variable setting
template <typename T>
void SetPushConstantVariable(std::string variableName, T const& data, SH_PIPELINE_TYPE bindPoint) noexcept

View File

@ -220,6 +220,7 @@ namespace SHADE
else
{
SHVulkanDebugUtil::ReportVkSuccess("Successfully created a Logical Device. ");
SET_VK_OBJ_NAME(this, vk::ObjectType::eDevice, vkLogicalDevice, "Logical Device");
}
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
{
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
{
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
#define SH_LOGICAL_DEVICE_H
#pragma once
#include <optional>
#include <array>
@ -67,7 +66,6 @@ namespace SHADE
class SHVkLogicalDevice : public ISelfHandle<SHVkLogicalDevice>
{
private:
/*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */
/*-----------------------------------------------------------------------*/
@ -147,7 +145,8 @@ namespace SHADE
uint32_t srcSize,
vk::BufferUsageFlags bufferUsage,
VmaMemoryUsage memUsage,
VmaAllocationCreateFlags allocFlags
VmaAllocationCreateFlags allocFlags,
const std::string& name = ""
) const noexcept;
Handle<SHVkImage> CreateImage (
@ -202,7 +201,33 @@ namespace SHADE
Handle<SHVkSemaphore> CreateSemaphore (void) const 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 */
@ -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?)
&allocCreateInfo,
&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
stagingBuffer = tempBuffer;
@ -107,6 +108,8 @@ namespace SHADE
VkImage tempImage;
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
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)
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
@ -115,7 +118,8 @@ namespace SHADE
}
SHVkImage::SHVkImage(
VmaAllocator const* allocator,
Handle<SHVkLogicalDevice> logicalDeviceHdl,
VmaAllocator const* allocator,
SHImageCreateParams const& imageDetails,
const unsigned char* data,
uint32_t dataSize,
@ -137,6 +141,7 @@ namespace SHADE
, boundToCoherent{false}
, randomAccessOptimized {false}
, mappedPtr{nullptr}
, device { logicalDeviceHdl }
{
usageFlags = imageDetails.usageFlags;
createFlags = imageDetails.createFlags;
@ -175,7 +180,9 @@ namespace SHADE
VmaAllocationInfo allocInfo{};
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)
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}
, height{h}
, depth {1}
@ -230,11 +237,12 @@ namespace SHADE
, usageFlags{usage}
, createFlags {create}
, vmaAllocator {allocator}
, device { logicalDeviceHdl }
{
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);
}

View File

@ -104,6 +104,9 @@ namespace SHADE
//! Mipmap offsets for initializing the vk::BufferImageCopy during transfer to GPU resource
std::span<uint32_t> mipOffsets;
//! Handle to the device that creates these images
Handle<SHVkLogicalDevice> device;
/*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
@ -117,6 +120,7 @@ namespace SHADE
SHVkImage(void) noexcept = default;
SHVkImage(
Handle<SHVkLogicalDevice> logicalDeviceHdl,
VmaAllocator const* allocator,
SHImageCreateParams const& imageDetails,
const unsigned char* data,
@ -126,7 +130,7 @@ namespace SHADE
VmaAllocationCreateFlags allocFlags
) 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& operator=(SHVkImage && rhs) noexcept = default;
@ -134,7 +138,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* 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 PrepareImageTransitionInfo (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
void HandleResizeFramebufferImage(uint32_t newWidth, uint32_t newHeight) noexcept;

View File

@ -392,20 +392,23 @@ namespace SHADE
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
device, drawDataBuffer[frameIndex], drawData.data(), DRAW_DATA_BYTES,
BuffUsage::eIndirectBuffer
BuffUsage::eIndirectBuffer,
"Batch Draw Data Buffer"
);
// - Transform Buffer
const uint32_t TF_DATA_BYTES = static_cast<uint32_t>(transformData.size() * sizeof(SHMatrix));
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
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));
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
device, instancedIntegerBuffer[frameIndex], instancedIntegerData.data(), EID_DATA_BYTES,
BuffUsage::eVertexBuffer
BuffUsage::eVertexBuffer,
"Batch Instance Data Buffer"
);
// - Material Properties Buffer
rebuildMaterialBuffers(frameIndex, descPool);
@ -427,6 +430,7 @@ namespace SHADE
// Bind all required objects before drawing
static std::array<uint32_t, 1> dynamicOffset{ 0 };
cmdBuffer->BeginLabeledSegment("SHBatch");
cmdBuffer->BindPipeline(pipeline);
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[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->EndLabeledSegment();
}
/*---------------------------------------------------------------------------------*/
@ -460,7 +465,8 @@ namespace SHADE
SHVkUtil::EnsureBufferAndCopyHostVisibleData
(
device, matPropsBuffer[frameIndex], matPropsData.get(), static_cast<uint32_t>(matPropsDataSize),
vk::BufferUsageFlagBits::eStorageBuffer
vk::BufferUsageFlagBits::eStorageBuffer,
"Batch Material Data"
);
if (!matPropsDescSet[frameIndex])
@ -470,6 +476,13 @@ namespace SHADE
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] },
{ 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] };
matPropsDescSet[frameIndex]->ModifyWriteDescBuffer

View File

@ -13,14 +13,13 @@ namespace SHADE
/* Static Definitions */
/*-----------------------------------------------------------------------------------*/
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsGlobalData::globalDescSetLayouts;
Handle<SHVkDescriptorSetGroup> SHGraphicsGlobalData::globalDescSets;
SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState;
Handle<SHVkPipelineLayout> SHGraphicsGlobalData::dummyPipelineLayout;
void SHGraphicsGlobalData::InitHighFrequencyGlobalData(void) noexcept
{
}
}
/*-----------------------------------------------------------------------------------*/
/* Function Definitions */
@ -45,7 +44,8 @@ namespace SHADE
};
// 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{};
@ -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
{
@ -71,11 +71,11 @@ namespace SHADE
});
}
// For Dynamic global data (lights)
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
{
.Type = vk::DescriptorType::eUniformBufferDynamic,
@ -83,10 +83,10 @@ namespace SHADE
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA,
.DescriptorCount = 1,
};
// For High frequency global data (camera)
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
{
.Type = vk::DescriptorType::eStorageBufferDynamic,
@ -94,9 +94,8 @@ namespace SHADE
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
.DescriptorCount = 1,
};
// For High frequency global data (camera)
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
{

View File

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

View File

@ -98,6 +98,7 @@ namespace SHADE
// Don't draw if no points
if (numPoints[FRAME_IDX] > 0)
{
cmdBuffer->BeginLabeledSegment("SHDebugDraw");
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline());
cmdBuffer->SetLineWidth(LineWidth);
cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0);
@ -113,10 +114,12 @@ namespace SHADE
// Don't draw if no points
if (numPersistentPoints[FRAME_IDX] > 0)
{
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Persistent)");
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawDepthPipeline());
cmdBuffer->SetLineWidth(LineWidth);
cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0);
cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0);
cmdBuffer->EndLabeledSegment();
}
});
@ -138,7 +141,8 @@ namespace SHADE
0,
vk::BufferUsageFlagBits::eVertexBuffer,
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
@ -151,7 +155,8 @@ namespace SHADE
0,
vk::BufferUsageFlagBits::eVertexBuffer,
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)
{
if (spherePoints.empty())
//if (spherePoints.empty())
{
spherePoints.clear();
// Generate
static const SHMeshData SPHERE = SHPrimitiveGenerator::Sphere();
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());

View File

@ -1,5 +1,5 @@
/************************************************************************************//*!
\file SHGraphicsSystem.cpp
\file SHGrphicsSystem.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Aug 21, 2022
@ -117,8 +117,8 @@ namespace SHADE
// Create generic command buffer
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_FS.glsl");
SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false);
SHAssetManager::CompileAsset("../../Assets/Shaders/Text_FS.glsl", false);
// Load Built In Shaders
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
@ -174,7 +174,7 @@ namespace SHADE
/* WORLD RENDER GRAPH RESOURCES */
/*-----------------------------------------------------------------------*/
// 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("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);
@ -223,6 +223,7 @@ namespace SHADE
ssaoStorage = resourceManager.Create<SHSSAO>();
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();
ssaoStorage->Init(device, ssaoTransferCmdBuffer);
@ -244,7 +245,7 @@ namespace SHADE
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();
ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored());
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});
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 */
/*-----------------------------------------------------------------------*/
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
@ -278,7 +279,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
// Initialize screen render graph
screenRenderGraph = resourceManager.Create<SHRenderGraph>();
screenRenderGraph->Init(device, swapchain, &resourceManager);
screenRenderGraph->Init("Scene Render Graph", device, swapchain, &resourceManager);
screenRenderGraph->LinkNonOwningResource(worldRenderGraph, "Scene");
auto screenSpaceNode = screenRenderGraph->AddNode("Screen Space Pass", { "Scene" }, {});
@ -311,7 +312,11 @@ namespace SHADE
// Create debug draw pipeline
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);
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
@ -398,7 +403,7 @@ namespace SHADE
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
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);
@ -726,6 +731,8 @@ namespace SHADE
auto renderGraphNode = subpass->GetParentNode();
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);
@ -772,14 +779,15 @@ namespace SHADE
void SHGraphicsSystem::BuildMeshBuffers()
{
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
device->WaitIdle();
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();
transferCmdBuffer->BeginRecording();
meshLibrary.BuildBuffers(device, transferCmdBuffer);
transferCmdBuffer->EndRecording();
graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer });
device->WaitIdle();
transferCmdBuffer.Free(); transferCmdBuffer = {};
device->WaitIdle();
transferCmdBuffer.Free(); transferCmdBuffer = {};
}
Handle<SHMesh> SHGraphicsSystem::GetMeshPrimitive(PrimitiveType type) const noexcept
@ -799,14 +807,18 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
Handle<SHTexture> SHGraphicsSystem::AddTexture(const SHTextureAsset& texAsset)
{
auto sampler = samplerCache.GetSampler(device, SHVkSamplerParams { .maxLod = static_cast<float>(texAsset.mipOffsets.size()) });
return texLibrary.Add(texAsset, sampler);
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);
}
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()) });
return texLibrary.Add(pixelCount, pixelData, width, height, format, mipOffsets, sampler);
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);
}
void SHGraphicsSystem::RemoveTexture(Handle<SHTexture> tex)
@ -817,6 +829,7 @@ namespace SHADE
void SHGraphicsSystem::BuildTextures()
{
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();
texLibrary.BuildTextures
(

View File

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

View File

@ -76,7 +76,7 @@ namespace SHADE
uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat());
// 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

View File

@ -39,9 +39,15 @@ namespace SHADE
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));
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};

View File

@ -134,7 +134,7 @@ namespace SHADE
lightDataTotalAlignedSize = logicalDevice->PadSSBOSize(lightDataAlignedSize * maxLights);
// 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
{
@ -379,14 +379,18 @@ namespace SHADE
SHComponentManager::CreateComponentSparseSet<SHLightComponent>();
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::fill (variableSizes.begin(), variableSizes.end(), 1);
// 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)
{
@ -402,7 +406,7 @@ namespace SHADE
lightCountsAlignedSize = logicalDevice->PadUBOSize(lightCountsAlignedSize);
// 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->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
{
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>();
bool expanded = false;
@ -447,7 +451,7 @@ namespace SHADE
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
// 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.
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)
{
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.
//swapchainImageHdl = params.swapchainHdl->GetSwapchainImage(frameIndex);
@ -44,14 +44,17 @@ namespace SHADE
// Create image views for the swapchain
swapchainImageViewHdl = swapchainImageHdl->CreateImageView(logicalDeviceHdl, swapchainImageHdl, viewDetails);
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eImageView, swapchainImageViewHdl->GetImageView(), "[Image View] Swap Chain");
// Create a fence
fenceHdl = logicalDeviceHdl->CreateFence();
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eFence, fenceHdl->GetVkFence(), "[Fence] Swap Chain");
// scope makes it easier to navigate
semImgAvailableHdl = logicalDeviceHdl->SHVkLogicalDevice::CreateSemaphore();
SET_VK_OBJ_NAME(logicalDeviceHdl, vk::ObjectType::eSemaphore, semImgAvailableHdl->GetVkSem(), "[Semaphore] Swap Chain Image Available");
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 */
/*-----------------------------------------------------------------------*/
// 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);
friend class SHRenderContext;

View File

@ -50,7 +50,13 @@ namespace SHADE
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/Descriptors/SHVkDescriptorSetGroup.h"
#include "Graphics/Images/SHVkImage.h"
#include "Graphics/Images/SHVkImageView.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h"
#include "Assets/Asset Types/SHTextureAsset.h"
@ -78,6 +79,7 @@ namespace SHADE
{
job.Image = resourceManager.Create<SHVkImage>
(
device,
&device->GetVMAAllocator(),
SHImageCreateParams
{
@ -142,6 +144,7 @@ namespace SHADE
.layerCount = 1
};
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
@ -150,6 +153,9 @@ namespace SHADE
texOrder.emplace_back(job.TextureHandle);
combinedImageSamplers.emplace_back(std::make_tuple(job.TextureHandle->ImageView, job.Sampler, vk::ImageLayout::eShaderReadOnlyOptimal));
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();
@ -165,6 +171,10 @@ namespace SHADE
{ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] },
{ 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
(
SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS,

View File

@ -60,7 +60,8 @@ namespace SHADE
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
@ -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.
// 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))
{
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>();
@ -427,6 +428,8 @@ namespace SHADE
renderGraphStorage->resourceHub = resourceHub;
renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools();
name = std::move(graphName);
}
/***************************************************************************/
@ -443,7 +446,6 @@ namespace SHADE
SHRenderGraph::SHRenderGraph(void) noexcept
: renderGraphStorage{}
, nodes{}
, resourceHub{nullptr}
{
}
@ -451,7 +453,7 @@ namespace SHADE
: renderGraphStorage{ rhs.renderGraphStorage }
, nodeIndexing{ std::move(rhs.nodeIndexing) }
, nodes{ std::move(rhs.nodes) }
, resourceHub{ std::move(rhs.resourceHub) }
, name { std::move(rhs.name) }
{
}
@ -464,7 +466,7 @@ namespace SHADE
renderGraphStorage = rhs.renderGraphStorage;
nodeIndexing = std::move(rhs.nodeIndexing);
nodes = std::move(rhs.nodes);
resourceHub = std::move(rhs.resourceHub);
name = std::move(rhs.name);
return *this;
}
@ -529,9 +531,9 @@ namespace SHADE
}
}
nodes.emplace_back(renderGraphStorage->resourceHub->Create<SHRenderGraphNode>(renderGraphStorage, std::move(descInitParams), std::move(predecessors)));
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
return nodes.at(nodeIndexing[nodeName]);
auto node = nodes.emplace_back(renderGraphStorage->resourceHub->Create<SHRenderGraphNode>(nodeName, renderGraphStorage, std::move(descInitParams), std::move(predecessors)));
nodeIndexing.emplace(std::move(nodeName), static_cast<uint32_t>(nodes.size()) - 1u);
return node;
}
/***************************************************************************/
@ -578,8 +580,10 @@ namespace SHADE
// better way to manage these
void SHRenderGraph::Execute(uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept
{
cmdBuffer->BeginLabeledSegment(name);
for (auto& node : nodes)
node->Execute(cmdBuffer, descPool, frameIndex);
cmdBuffer->EndLabeledSegment();
}
void SHRenderGraph::FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool)

View File

@ -66,8 +66,8 @@ namespace SHADE
//! Render graph nodes
std::vector<Handle<SHRenderGraphNode>> nodes;
//! Resource library for graph handles
SHResourceHub* resourceHub;
//! Name of the RenderGraph
std::string name;
public:
/*-----------------------------------------------------------------------*/
@ -81,7 +81,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* 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 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;

View File

@ -25,6 +25,7 @@ namespace SHADE
void SHRenderGraphNode::CreateRenderpass(void) noexcept
{
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);
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}
, renderpass{}
, framebuffers{}
@ -128,6 +130,7 @@ namespace SHADE
, executed{ false }
, configured{ false }
, nodeComputes{}
, name { std::move(nodeName) }
{
// pipeline library initialization
pipelineLibrary.Init(graphStorage->logicalDevice);
@ -189,6 +192,7 @@ namespace SHADE
, spDescs{ std::move(rhs.spDescs) }
, spDeps{ std::move(rhs.spDeps) }
, nodeComputes{ std::move(rhs.nodeComputes) }
, name { std::move(rhs.name) }
{
rhs.renderpass = {};
@ -213,7 +217,7 @@ namespace SHADE
spDescs = std::move(rhs.spDescs);
spDeps = std::move(rhs.spDeps);
nodeComputes = std::move(rhs.nodeComputes);
name = std::move(rhs.name);
rhs.renderpass = {};
@ -263,7 +267,7 @@ namespace SHADE
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
std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{};
@ -279,7 +283,7 @@ namespace SHADE
std::vector<Handle<SHRenderGraphResource>> temp (nodeComputeResources);
// 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);
for (auto& resource : temp)

View File

@ -78,8 +78,11 @@ namespace SHADE
//! Whether or not the node has been configured already or not
bool configured;
//! Manages batching for this RenderPass
SHBatcher batcher;
//! Name of this node
std::string name;
/*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */
@ -92,7 +95,7 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* 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& operator= (SHRenderGraphNode&& rhs) noexcept;
@ -100,7 +103,7 @@ namespace SHADE
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
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;
// TODO: RemoveSubpass()

View File

@ -13,7 +13,7 @@
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{}
, pipelineLayout{}
, resources{}
@ -22,6 +22,7 @@ namespace SHADE
, followingEndRenderpass {followingEndRP}
, numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)}
, computeResource{}
, name { std::move(nodeName) }
{
SHPipelineLayoutParams pipelineLayoutParams
{
@ -31,13 +32,15 @@ namespace SHADE
};
// Create pipeline layout from parameters
pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout (pipelineLayoutParams);
pipelineLayout = graphStorage->logicalDevice->CreatePipelineLayout(pipelineLayoutParams);
// Create the compute pipeline
computePipeline = graphStorage->logicalDevice->CreateComputePipeline(pipelineLayout);
// and construct it
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
resources = std::move (subpassComputeResources);
@ -51,6 +54,10 @@ namespace SHADE
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
{
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>();
auto computeResourceLayout = layouts[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE];
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
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;
//! Name of this node
std::string name;
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 HandleResize (void) noexcept;

View File

@ -114,6 +114,7 @@ namespace SHADE
{
images[i] = graphStorage->swapchain->GetSwapchainImage(i);
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
@ -161,7 +162,9 @@ namespace SHADE
}
// 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
SHImageViewDetails viewDetails
@ -176,7 +179,9 @@ namespace SHADE
};
// 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>();

View File

@ -201,6 +201,7 @@ namespace SHADE
void SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
{
commandBuffer->BeginLabeledSegment(name);
// Ensure correct transforms are provided
superBatch->UpdateBuffers(frameIndex, descPool);
@ -212,7 +213,7 @@ namespace SHADE
{
drawCall(commandBuffer);
}
commandBuffer->EndLabeledSegment();
}
void SHSubpass::HandleResize(void) noexcept
@ -301,6 +302,11 @@ namespace SHADE
group.Free();
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;
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)
{
@ -100,7 +100,8 @@ namespace SHADE
size,
usage | BuffUsage::eTransferDst,
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);
}
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)
{
@ -126,7 +127,8 @@ namespace SHADE
size,
usage,
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;
};

View File

@ -25,11 +25,13 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/
SHBoundingBox::SHBoundingBox() noexcept
: RelativeExtents { SHVec3::One }
{
type = Type::BOX;
}
SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept
: RelativeExtents { SHVec3::One }
{
type = Type::BOX;
@ -45,16 +47,18 @@ namespace SHADE
type = Type::BOX;
Center = rhs.Center;
Extents = rhs.Extents;
Center = rhs.Center;
Extents = rhs.Extents;
RelativeExtents = rhs.RelativeExtents;
}
SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept
{
type = Type::BOX;
Center = rhs.Center;
Extents = rhs.Extents;
Center = rhs.Center;
Extents = rhs.Extents;
RelativeExtents = rhs.RelativeExtents;
}
/*-----------------------------------------------------------------------------------*/
@ -69,8 +73,9 @@ namespace SHADE
}
else if (this != &rhs)
{
Center = rhs.Center;
Extents = rhs.Extents;
Center = rhs.Center;
Extents = rhs.Extents;
RelativeExtents = rhs.RelativeExtents;
}
return *this;
@ -84,8 +89,9 @@ namespace SHADE
}
else
{
Center = rhs.Center;
Extents = rhs.Extents;
Center = rhs.Center;
Extents = rhs.Extents;
RelativeExtents = rhs.RelativeExtents;
}
return *this;
@ -100,11 +106,16 @@ namespace SHADE
return Center;
}
SHVec3 SHBoundingBox::GetHalfExtents() const noexcept
SHVec3 SHBoundingBox::GetWorldExtents() const noexcept
{
return Extents;
}
const SHVec3& SHBoundingBox::GetRelativeExtents() const noexcept
{
return RelativeExtents;
}
SHVec3 SHBoundingBox::GetMin() const noexcept
{
return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z };
@ -124,9 +135,14 @@ namespace SHADE
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

View File

@ -54,21 +54,23 @@ namespace SHADE
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] SHVec3 GetCenter () const noexcept;
[[nodiscard]] SHVec3 GetHalfExtents() const noexcept;
[[nodiscard]] SHVec3 GetMin () const noexcept;
[[nodiscard]] SHVec3 GetMax () const noexcept;
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
[[nodiscard]] SHVec3 GetCenter () const noexcept;
[[nodiscard]] SHVec3 GetWorldExtents () const noexcept;
[[nodiscard]] const SHVec3& GetRelativeExtents () const noexcept;
[[nodiscard]] SHVec3 GetMin () const noexcept;
[[nodiscard]] SHVec3 GetMax () const noexcept;
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetCenter (const SHVec3& newCenter) noexcept;
void SetHalfExtents (const SHVec3& newHalfExtents) noexcept;
void SetMin (const SHVec3& min) noexcept;
void SetMax (const SHVec3& max) noexcept;
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
void SetCenter (const SHVec3& newCenter) noexcept;
void SetWorldExtents (const SHVec3& newWorldExtents) noexcept;
void SetRelativeExtents (const SHVec3& newRelativeExtents) noexcept;
void SetMin (const SHVec3& min) noexcept;
void SetMax (const SHVec3& max) noexcept;
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
@ -89,6 +91,13 @@ namespace SHADE
[[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 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