Bug fixes for textrenderable and sterilization, added base for game pause #354

Merged
glencelow merged 5 commits from PlayerController into main 2023-02-21 15:49:10 +08:00
39 changed files with 882 additions and 65 deletions
Showing only changes of commit f2e9d3b349 - Show all commits

View File

@ -8440,6 +8440,11 @@
IsActive: true IsActive: true
NumberOfChildren: 0 NumberOfChildren: 0
Components: Components:
Transform Component:
Translate: {x: 0, y: 0, z: 0}
Rotate: {x: 0, y: 0, z: 0}
Scale: {x: 1, y: 1, z: 1}
IsActive: true
Light Component: Light Component:
Position: {x: 0, y: 0, z: 0} Position: {x: 0, y: 0, z: 0}
Type: Directional Type: Directional
@ -8469,14 +8474,14 @@
NumberOfChildren: 0 NumberOfChildren: 0
Components: Components:
Transform Component: Transform Component:
Translate: {x: 2, y: 1.5, z: -5.5999999} Translate: {x: 0.242245644, y: 1.56757355, z: -6.07086945}
Rotate: {x: -0, y: 0, z: -0} Rotate: {x: -0, y: 0, z: -0}
Scale: {x: 1, y: 1, z: 1} Scale: {x: 1, y: 1, z: 1}
IsActive: true IsActive: true
Light Component: Light Component:
Position: {x: 2, y: 1.5, z: -5.5999999} Position: {x: 2, y: 1.5, z: -5.5999999}
Type: Directional Type: Directional
Direction: {x: -0.245000005, y: 0, z: 0} Direction: {x: 0, y: 0, z: -1}
Color: {x: 0, y: 0, z: 0, w: 1} Color: {x: 0, y: 0, z: 0, w: 1}
Layer: 4294967295 Layer: 4294967295
Strength: 1 Strength: 1

View File

@ -0,0 +1,37 @@
using SHADE;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SHADE_Scripting
{
public class StaticTest
{
public static int x;
static StaticTest()
{
x = 5;
Debug.Log("Static Constructor!");
}
}
public class ImplicitStaticTest : Script
{
public static int x = 5;
static ImplicitStaticTest()
{
Debug.Log("Static Constructor!");
}
protected override void awake()
{
Debug.LogWarning($"Before Add: x = {x}");
++x;
Debug.LogWarning($"After Add: x = {x}");
}
}
}

View File

@ -0,0 +1,3 @@
Name: StaticTest
ID: 159057282
Type: 9

View File

@ -48,19 +48,34 @@ layout(std430, set = 1, binding = 4) buffer AmbientLightData
AmbientLightStruct aLightData[]; AmbientLightStruct aLightData[];
} AmbLightData; } AmbLightData;
float LinStep (float val, float low, float high)
{
return clamp ((val - low)/(high - low), 0.0f, 1.0f);
}
float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV) float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV)
{ {
// clip space for fragment from light view space
vec4 fragPosLightPOV = lightPV * worldSpaceFragPos; vec4 fragPosLightPOV = lightPV * worldSpaceFragPos;
// Perform perspective division and convert to 0 to 1 range
vec3 converted = (fragPosLightPOV.xyz / fragPosLightPOV.w) * vec3(0.5f) + vec3(0.5f); vec3 converted = (fragPosLightPOV.xyz / fragPosLightPOV.w) * vec3(0.5f) + vec3(0.5f);
float sampledDepth = texture(shadowMap, converted.xy).r; // float sampledDepth = texture(shadowMap, converted.xy).r;
// float sampledDepth = texture(shadowMap, converted.xy).z;
vec2 moments = texture(shadowMap, converted.xy).xy;
if (converted.x < 0.0f || converted.x > 1.0f || converted.y < 0.0f || converted.y > 1.0f) if (converted.x < 0.0f || converted.x > 1.0f || converted.y < 0.0f || converted.y > 1.0f)
return 1.0f; return 1.0f;
if (fragPosLightPOV.z > sampledDepth && fragPosLightPOV.w > 0.0f) if (fragPosLightPOV.z > moments.x && fragPosLightPOV.w > 0.0f)
{ {
return 0.7f; float p = step (fragPosLightPOV.z, moments.x);
float variance = max (moments.y - (moments.x * moments.x), 0.00002f);
float d = fragPosLightPOV.z - moments.x;
float pMax = LinStep (variance / (variance + (d * d)), 0.9f, 1.0f);
return min (max (p, pMax), 1.0f);
} }
else else
return 1.0f; return 1.0f;

View File

@ -3,8 +3,10 @@
#extension GL_ARB_shading_language_420pack : enable #extension GL_ARB_shading_language_420pack : enable
#extension GL_EXT_nonuniform_qualifier : require #extension GL_EXT_nonuniform_qualifier : require
layout(location = 0) out vec4 shadowMap;
void main() void main()
{ {
// shadowMap = vec4 (0.0f, 0.0f, gl_FragCoord.z, 1.0f);
shadowMap = vec4 (gl_FragCoord.z, gl_FragCoord.z * gl_FragCoord.z, 0.0f, 1.0f);
} }

View File

@ -0,0 +1,22 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
#extension GL_EXT_nonuniform_qualifier : require
layout(location = 0) in struct
{
vec4 vertPos; // location 0
vec2 uv; // location = 1
vec4 color; // location = 2
} In;
layout(location = 0) out vec4 fragColor;
void main()
{
// default red first
fragColor = In.color;
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: Trajectory_FS
ID: 45635685
Type: 2

View File

@ -0,0 +1,36 @@
#version 450
#extension GL_KHR_vulkan_glsl : enable
// vertex inputs
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec2 aUV;
layout(location = 2) in vec4 aColor;
layout(location = 3) in mat4 aTransform;
// between shader stages
layout(location = 0) out struct
{
vec4 vertPos; // location 0
vec2 uv; // location = 1
vec4 color; // location = 2
} Out;
// Camera data
layout(set = 1, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 projMat;
} cameraData;
void main()
{
Out.uv = aUV;
Out.color = aColor;
gl_Position = cameraData.projMat * aTransform * vec4(aPos, 1.0f);
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: Trajectory_VS
ID: 41042628
Type: 2

View File

@ -254,7 +254,8 @@ RTTR_REGISTRATION
.property("Height", &SHCameraComponent::GetHeight, &SHCameraComponent::SetHeight) .property("Height", &SHCameraComponent::GetHeight, &SHCameraComponent::SetHeight)
.property("Near", &SHCameraComponent::GetNear, &SHCameraComponent::SetNear) .property("Near", &SHCameraComponent::GetNear, &SHCameraComponent::SetNear)
.property("Far", &SHCameraComponent::GetFar, &SHCameraComponent::SetFar) .property("Far", &SHCameraComponent::GetFar, &SHCameraComponent::SetFar)
.property("Perspective", &SHCameraComponent::GetIsPerspective, &SHCameraComponent::SetIsPerspective); .property("Perspective", &SHCameraComponent::GetIsPerspective, &SHCameraComponent::SetIsPerspective)
.property("FOV",&SHCameraComponent::GetFOV, &SHCameraComponent::SetFOV);
} }

View File

@ -12,6 +12,7 @@
#include "Editor/SHEditor.h" #include "Editor/SHEditor.h"
#include "Math/SHRay.h" #include "Math/SHRay.h"
#include "Physics/System/SHPhysicsSystem.h" #include "Physics/System/SHPhysicsSystem.h"
#include "Graphics/Events/SHGraphicsEvents.h"
namespace SHADE namespace SHADE
@ -123,6 +124,13 @@ namespace SHADE
SHComponentManager::CreateComponentSparseSet<SHCameraComponent>(); SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
SHComponentManager::CreateComponentSparseSet<SHCameraArmComponent>(); SHComponentManager::CreateComponentSparseSet<SHCameraArmComponent>();
std::shared_ptr<SHEventReceiverSpec<SHCameraSystem>> thisReceiver
{
std::make_shared<SHEventReceiverSpec<SHCameraSystem>>(this, &SHCameraSystem::ReceiveWindowResizeEvent)
};
ReceiverPtr receiver = std::dynamic_pointer_cast<SHEventReceiver>(thisReceiver);
SHEventManager::SubscribeTo(SH_WINDOW_RESIZE_EVENT, receiver);
} }
void SHCameraSystem::Exit(void) void SHCameraSystem::Exit(void)
@ -130,6 +138,29 @@ namespace SHADE
} }
SHEventHandle SHCameraSystem::ReceiveWindowResizeEvent(SHEventPtr eventPtr) noexcept
{
auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHWindowResizeEvent>*>(eventPtr.get())->data;
//std::cout << EVENT_DATA->resizeWidth << std::endl;
//std::cout << EVENT_DATA->resizeHeight << std::endl;
for (auto director : directorHandleList)
{
auto camera = SHComponentManager::GetComponent_s<SHCameraComponent>(director->mainCameraEID);
if (camera)
{
camera->SetWidth(EVENT_DATA->resizeWidth);
camera->SetHeight(EVENT_DATA->resizeHeight);
}
}
return eventPtr->handle;
}
SHCameraComponent* SHCameraSystem::GetEditorCamera(void) noexcept SHCameraComponent* SHCameraSystem::GetEditorCamera(void) noexcept
{ {
return &editorCamera; return &editorCamera;
@ -204,8 +235,8 @@ namespace SHADE
//SHLOG_INFO("CAMERA COLLISION HIT, {} armlength: {}, true armlength: {}", hitResult.distance, hitResult.distance, (cameraPos - camera->position).Length()); //SHLOG_INFO("CAMERA COLLISION HIT, {} armlength: {}, true armlength: {}", hitResult.distance, hitResult.distance, (cameraPos - camera->position).Length());
//SHLOG_INFO("Racoon Position {}, {}, {}, Camera Position: {}, {}, {}, Distance {}", cameraTarget.x, cameraTarget.y, cameraTarget.z, cameraPos.x, cameraPos.y, cameraPos.z, SHVec3::Distance(cameraTarget, cameraPos)); //SHLOG_INFO("Racoon Position {}, {}, {}, Camera Position: {}, {}, {}, Distance {}", cameraTarget.x, cameraTarget.y, cameraTarget.z, cameraPos.x, cameraPos.y, cameraPos.z, SHVec3::Distance(cameraTarget, cameraPos));
//SHLOG_INFO("Camera Position: {}, {}, {}", cameraPos.x, cameraPos.y, cameraPos.z); //SHLOG_INFO("Camera Position: {}, {}, {}", cameraPos.x, cameraPos.y, cameraPos.z);
auto otherTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(hitResult.entityHit); //auto otherTransform = SHComponentManager::GetComponent_s<SHTransformComponent>(hitResult.entityHit);
SHVec3 otherPos = hitResult.position; //SHVec3 otherPos = hitResult.position;

View File

@ -46,6 +46,11 @@ namespace SHADE
}; };
friend class CameraSystemUpdate; friend class CameraSystemUpdate;
/*-----------------------------------------------------------------------*/
/* Light functions */
/*-----------------------------------------------------------------------*/
SHEventHandle ReceiveWindowResizeEvent(SHEventPtr eventPtr) noexcept;
SHCameraComponent* GetEditorCamera (void) noexcept; SHCameraComponent* GetEditorCamera (void) noexcept;
void GetCameraAxis(SHCameraComponent const& camera, SHVec3& forward, SHVec3& right, SHVec3& up) const noexcept; void GetCameraAxis(SHCameraComponent const& camera, SHVec3& forward, SHVec3& right, SHVec3& up) const noexcept;

View File

@ -25,4 +25,5 @@ constexpr SHEventIdentifier SH_SCENE_EXIT_POST { 16 };
constexpr SHEventIdentifier SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT { 17 }; constexpr SHEventIdentifier SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT { 17 };
constexpr SHEventIdentifier SH_BUTTON_CLICK_EVENT { 18 }; constexpr SHEventIdentifier SH_BUTTON_CLICK_EVENT { 18 };
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_DRAW_EVENT { 19 }; constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_DRAW_EVENT { 19 };
constexpr SHEventIdentifier SH_WINDOW_RESIZE_EVENT { 20 };

View File

@ -14,4 +14,13 @@ namespace SHADE
//! Generate a renderer for the light component //! Generate a renderer for the light component
bool generateRenderer; bool generateRenderer;
}; };
struct SHWindowResizeEvent
{
// New width when window resizes
uint32_t resizeWidth;
// New height when window resizes
uint32_t resizeHeight;
};
} }

View File

@ -52,6 +52,12 @@ namespace SHADE
{SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE, 3}, {SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE, 3},
{SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE, 4}, {SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE, 4},
}); });
perSystemData[SHUtilities::ConvertEnum(SystemType::TRAJECTORY_RENDERING)].descMappings.AddMappings
({
{SHPredefinedDescriptorTypes::STATIC_DATA, 0},
{SHPredefinedDescriptorTypes::CAMERA, 1},
});
} }
void SHGraphicsPredefinedData::InitDummyPipelineLayouts(Handle<SHVkLogicalDevice> logicalDevice) noexcept void SHGraphicsPredefinedData::InitDummyPipelineLayouts(Handle<SHVkLogicalDevice> logicalDevice) noexcept
@ -222,6 +228,12 @@ namespace SHADE
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA | SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA |
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::LIGHTS SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::LIGHTS
); );
perSystemData[SHUtilities::ConvertEnum(SystemType::TRAJECTORY_RENDERING)].descSetLayouts = GetPredefinedDescSetLayouts
(
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA |
SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA
);
} }
void SHGraphicsPredefinedData::InitPredefinedVertexInputState(void) noexcept void SHGraphicsPredefinedData::InitPredefinedVertexInputState(void) noexcept

View File

@ -38,6 +38,7 @@ namespace SHADE
BATCHING_ANIM, BATCHING_ANIM,
TEXT_RENDERING, TEXT_RENDERING,
RENDER_GRAPH_NODE_COMPUTE, RENDER_GRAPH_NODE_COMPUTE,
TRAJECTORY_RENDERING,
NUM_TYPES NUM_TYPES
}; };
static constexpr int SYSTEM_TYPE_COUNT = static_cast<int>(SystemType::NUM_TYPES); static constexpr int SYSTEM_TYPE_COUNT = static_cast<int>(SystemType::NUM_TYPES);

View File

@ -64,6 +64,17 @@ namespace SHADE
/***************************************************************************/ /***************************************************************************/
static constexpr std::string_view DEFERRED_COMPOSITE_PASS = "Deferred Comp Pass"; static constexpr std::string_view DEFERRED_COMPOSITE_PASS = "Deferred Comp Pass";
/***************************************************************************/
/*!
\brief
Name of vfx render graph node.
*/
/***************************************************************************/
static constexpr std::string_view VFX_PASS = "Vfx Pass";
/***************************************************************************/ /***************************************************************************/
/*! /*!
@ -117,6 +128,7 @@ namespace SHADE
static constexpr std::string_view GBUFFER_WRITE_SUBPASS = "G-Buffer Write"; static constexpr std::string_view GBUFFER_WRITE_SUBPASS = "G-Buffer Write";
static constexpr std::string_view UI_SUBPASS = "UI"; static constexpr std::string_view UI_SUBPASS = "UI";
static constexpr std::string_view VFX_SUBPASS = "VFX";
static constexpr std::array USABLE_SUBPASSES = static constexpr std::array USABLE_SUBPASSES =
{ {
@ -282,6 +294,13 @@ namespace SHADE
*/ */
/***************************************************************************/ /***************************************************************************/
static constexpr uint32_t BONE_MATRIX_FIRST_INDEX = 8; static constexpr uint32_t BONE_MATRIX_FIRST_INDEX = 8;
/***************************************************************************/
/*!
\brief
Vertex buffer bindings for color
*/
/***************************************************************************/
static constexpr uint32_t TRAJECTORY_COLOR = 2;
static constexpr uint32_t CALCULATED_GLYPH_POSITION = 0; static constexpr uint32_t CALCULATED_GLYPH_POSITION = 0;
static constexpr uint32_t GLYPH_INDEX = 1; static constexpr uint32_t GLYPH_INDEX = 1;

View File

@ -129,6 +129,7 @@ namespace SHADE
//SHAssetManager::CompileAsset("../../Assets/Shaders/DeferredComposite_CS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/DeferredComposite_CS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/ShadowMap_FS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/ShadowMap_FS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/ShadowMap_FS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/SSAO_CS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/SSAO_CS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/SSAOBlur_CS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/SSAOBlur_CS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/PureCopy_CS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/PureCopy_CS.glsl", false);
@ -137,7 +138,8 @@ namespace SHADE
//SHAssetManager::CompileAsset("../../Assets/Shaders/UI_VS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/UI_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/UI_FS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/UI_FS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false); //SHAssetManager::CompileAsset("../../Assets/Shaders/Text_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/Trajectory_VS.glsl", false);
//SHAssetManager::CompileAsset("../../Assets/Shaders/Trajectory_FS.glsl", false);
// Load Built In Shaders // Load Built In Shaders
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT); static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
@ -155,6 +157,8 @@ namespace SHADE
static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_FS); static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_FS);
static constexpr AssetID SHADOW_MAP_VS = 44646107; shadowMapVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(SHADOW_MAP_VS); static constexpr AssetID SHADOW_MAP_VS = 44646107; shadowMapVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(SHADOW_MAP_VS);
static constexpr AssetID SHADOW_MAP_FS = 45925790; shadowMapFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(SHADOW_MAP_FS); static constexpr AssetID SHADOW_MAP_FS = 45925790; shadowMapFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(SHADOW_MAP_FS);
static constexpr AssetID TRAJECTORY_VS = 41042628; trajectoryVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TRAJECTORY_VS);
static constexpr AssetID TRAJECTORY_FS = 45635685; trajectoryFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TRAJECTORY_FS);
} }
@ -307,13 +311,24 @@ namespace SHADE
lightingSubSystem->PrepareShadowMapsForRead(cmdBuffer); lightingSubSystem->PrepareShadowMapsForRead(cmdBuffer);
}); });
/*-----------------------------------------------------------------------*/
/* VFX PASS */
/*-----------------------------------------------------------------------*/
auto vfxPass = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::VFX_PASS.data(), { "Scene", "Depth Buffer" }, { SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data(), SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data() });
auto vfxSubpass = vfxPass->AddSubpass("Vfx Subpass", worldViewport, worldRenderer);
vfxSubpass->AddColorOutput("Scene");
vfxSubpass->AddDepthOutput("Depth Buffer");
vfxSubpass->AddExteriorDrawCalls([=](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
{
trajectoryRenderingSubSystem->Render(cmdBuffer, renderer, frameIndex);
});
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* DEBUG DRAW PASS INIT */ /* DEBUG DRAW PASS INIT */
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
// Set up Debug Draw Passes // Set up Debug Draw Passes
// - Depth Tested // - Depth Tested
auto debugDrawNodeDepth = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW_DEPTH_PASS.data(), {"Scene", "Depth Buffer"}, {SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data(), SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data()}); auto debugDrawNodeDepth = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW_DEPTH_PASS.data(), {"Scene", "Depth Buffer"}, { SHGraphicsConstants::RenderGraphEntityNames::VFX_PASS.data()/*, SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data()*/});
auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth", worldViewport, worldRenderer); auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth", worldViewport, worldRenderer);
debugDrawDepthSubpass->AddColorOutput("Scene"); debugDrawDepthSubpass->AddColorOutput("Scene");
debugDrawDepthSubpass->AddDepthOutput("Depth Buffer"); debugDrawDepthSubpass->AddDepthOutput("Depth Buffer");
@ -432,6 +447,11 @@ namespace SHADE
auto uiNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS.data()); auto uiNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS.data());
textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::UI_SUBPASS), descPool, textVS, textFS); textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::UI_SUBPASS), descPool, textVS, textFS);
trajectoryRenderingSubSystem = resourceManager.Create<SHTrajectoryRenderingSubSystem>();
auto vfxNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS.data());
trajectoryRenderingSubSystem->Init(device, vfxNode->GetRenderpass(), vfxNode->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::UI_SUBPASS), trajectoryVS, trajectoryFS);
SHGlobalDescriptorSets::SetLightingSubSystem(lightingSubSystem); SHGlobalDescriptorSets::SetLightingSubSystem(lightingSubSystem);
} }
@ -566,6 +586,7 @@ namespace SHADE
} }
textRenderingSubSystem->Run(frameIndex); textRenderingSubSystem->Run(frameIndex);
trajectoryRenderingSubSystem->Run(frameIndex);
for (auto renderer : renderers) for (auto renderer : renderers)
@ -588,19 +609,19 @@ namespace SHADE
static bool shadowAdded = false; static bool shadowAdded = false;
if (shadowAdded == false/* && SHInputManager::GetKey(SHInputManager::SH_KEYCODE::B)*/) //if (shadowAdded == false && SHInputManager::GetKey(SHInputManager::SH_KEYCODE::B))
{
shadowAdded = true;
auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
if (lightComps.size() > 2)
{
lightComps[2].SetEnableShadow(true);
}
//for (auto& comp : lightComps)
//{ //{
// shadowAdded = true;
// auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
// //if (lightComps.size() > 2)
// //{
// // lightComps[2].SetEnableShadow(true);
// //}
// for (auto& comp : lightComps)
// {
// comp.SetEnableShadow(true); // comp.SetEnableShadow(true);
// }
//} //}
}
renderGraph->Begin(frameIndex); renderGraph->Begin(frameIndex);
auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex); auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex);
@ -781,7 +802,8 @@ namespace SHADE
auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHLightEnableShadowEvent>*>(eventPtr.get())->data; auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHLightEnableShadowEvent>*>(eventPtr.get())->data;
auto* lightComp = SHComponentManager::GetComponent<SHLightComponent>(EVENT_DATA->lightEntity); auto* lightComp = SHComponentManager::GetComponent<SHLightComponent>(EVENT_DATA->lightEntity);
std::string resourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity); std::string depthResourceName = "ShadowMap_Depth " + std::to_string(EVENT_DATA->lightEntity);
std::string shadowMapResourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity);
Handle<SHSubpass> companionSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS); Handle<SHSubpass> companionSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS);
if (EVENT_DATA->generateRenderer) if (EVENT_DATA->generateRenderer)
@ -795,14 +817,16 @@ namespace SHADE
} }
// Add the shadow map resource to the graph // Add the shadow map resource to the graph
renderGraph->AddResource(resourceName, {SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT}, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eD32Sfloat); renderGraph->AddResource(depthResourceName, {SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH}, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eD32Sfloat);
renderGraph->AddResource(shadowMapResourceName, { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT }, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eR32G32B32A32Sfloat);
// link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer. // link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer.
auto shadowMapNode = renderGraph->AddNodeAfter(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + resourceName, {resourceName.c_str()}, SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data()); auto shadowMapNode = renderGraph->AddNodeAfter(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + shadowMapResourceName, {depthResourceName.c_str(), shadowMapResourceName.c_str()}, SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data());
// Add a subpass to render to that shadow map // Add a subpass to render to that shadow map
auto newSubpass = shadowMapNode->RuntimeAddSubpass(resourceName + " Subpass", shadowMapViewport, lightComp->GetRenderer()); auto newSubpass = shadowMapNode->RuntimeAddSubpass(shadowMapResourceName + " Subpass", shadowMapViewport, lightComp->GetRenderer());
newSubpass->AddDepthOutput(resourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH); newSubpass->AddColorOutput(shadowMapResourceName);
newSubpass->AddDepthOutput(depthResourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH);
// regenerate the node // regenerate the node
shadowMapNode->RuntimeStandaloneRegenerate(); shadowMapNode->RuntimeStandaloneRegenerate();
@ -828,7 +852,7 @@ namespace SHADE
newSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline newSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline
// add the shadow map to the lighting system // add the shadow map to the lighting system
uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(resourceName), EVENT_DATA->lightEntity); uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(shadowMapResourceName), EVENT_DATA->lightEntity);
auto nodeCompute = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data()); auto nodeCompute = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data());
nodeCompute->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, lightingSubSystem->GetViewSamplerLayout(NEW_SHADOW_MAP_INDEX), NEW_SHADOW_MAP_INDEX); nodeCompute->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, lightingSubSystem->GetViewSamplerLayout(NEW_SHADOW_MAP_INDEX), NEW_SHADOW_MAP_INDEX);
@ -1154,6 +1178,14 @@ namespace SHADE
#ifdef SHEDITOR #ifdef SHEDITOR
cameraSystem->GetEditorCamera()->SetWidth(static_cast<float>(resizeWidth)); cameraSystem->GetEditorCamera()->SetWidth(static_cast<float>(resizeWidth));
cameraSystem->GetEditorCamera()->SetHeight(static_cast<float>(resizeHeight)); cameraSystem->GetEditorCamera()->SetHeight(static_cast<float>(resizeHeight));
// Create new event and broadcast it
SHWindowResizeEvent newEvent;
newEvent.resizeWidth = resizeWidth;
newEvent.resizeHeight = resizeHeight;
SHEventManager::BroadcastEvent<SHWindowResizeEvent>(newEvent, SH_WINDOW_RESIZE_EVENT);
#else #else
#endif #endif

View File

@ -36,6 +36,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Graphics/MiddleEnd/TextRendering/SHFontLibrary.h" #include "Graphics/MiddleEnd/TextRendering/SHFontLibrary.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h" #include "Graphics/MiddleEnd/Interface/SHRenderer.h"
#include "Graphics/Events/SHGraphicsEvents.h" #include "Graphics/Events/SHGraphicsEvents.h"
#include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderingSubSystem.h"
namespace SHADE namespace SHADE
{ {
@ -470,6 +471,8 @@ namespace SHADE
Handle<SHVkShaderModule> renderToSwapchainFS; Handle<SHVkShaderModule> renderToSwapchainFS;
Handle<SHVkShaderModule> shadowMapVS; Handle<SHVkShaderModule> shadowMapVS;
Handle<SHVkShaderModule> shadowMapFS; Handle<SHVkShaderModule> shadowMapFS;
Handle<SHVkShaderModule> trajectoryVS;
Handle<SHVkShaderModule> trajectoryFS;
// Fonts // Fonts
Handle<SHFont> testFont; Handle<SHFont> testFont;
@ -505,6 +508,7 @@ namespace SHADE
Handle<SHPostOffscreenRenderSystem> postOffscreenRenderSubSystem; Handle<SHPostOffscreenRenderSystem> postOffscreenRenderSubSystem;
Handle<SHLightingSubSystem> lightingSubSystem; Handle<SHLightingSubSystem> lightingSubSystem;
Handle<SHTextRenderingSubSystem> textRenderingSubSystem; Handle<SHTextRenderingSubSystem> textRenderingSubSystem;
Handle<SHTrajectoryRenderingSubSystem> trajectoryRenderingSubSystem;
Handle<SHSSAO> ssaoStorage; Handle<SHSSAO> ssaoStorage;
uint32_t resizeWidth = 1; uint32_t resizeWidth = 1;

View File

@ -395,7 +395,11 @@ namespace SHADE
switch (lightComp->GetLightData().type) switch (lightComp->GetLightData().type)
{ {
case SH_LIGHT_TYPE::DIRECTIONAL: case SH_LIGHT_TYPE::DIRECTIONAL:
return SHMatrix::Transpose(SHMatrix::LookAtLH(lightComp->GetLightData().position, SHVec3::Normalise (lightComp->GetLightData().direction), SHVec3(0.0f, -1.0f, 0.0f))); {
SHTransformComponent* transform = SHComponentManager::GetComponent<SHTransformComponent>(lightComp->GetEID());
return SHMatrix::Transpose(SHMatrix::LookAtLH(transform->GetWorldPosition(), SHVec3::Normalise(lightComp->GetLightData().direction), SHVec3(0.0f, -1.0f, 0.0f)));
}
//return SHMatrix::Transpose(SHMatrix::LookAtLH(/*lightComp->GetLightData().position*/SHVec3(1.27862f, 4.78952f, 4.12811f), SHVec3(-0.280564f, -0.66262f, -0.69422f), SHVec3(0.0f, -1.0f, 0.0f))); //return SHMatrix::Transpose(SHMatrix::LookAtLH(/*lightComp->GetLightData().position*/SHVec3(1.27862f, 4.78952f, 4.12811f), SHVec3(-0.280564f, -0.66262f, -0.69422f), SHVec3(0.0f, -1.0f, 0.0f)));
case SH_LIGHT_TYPE::POINT: case SH_LIGHT_TYPE::POINT:
return {}; return {};
@ -518,7 +522,7 @@ namespace SHADE
if (auto renderer = light.GetRenderer()) if (auto renderer = light.GetRenderer())
{ {
//SHMatrix orthoMatrix = SHMatrix::OrthographicRH() //SHMatrix orthoMatrix = SHMatrix::OrthographicRH()
renderer->UpdateDataManual(frameIndex, GetViewMatrix(&light), SHMatrix::OrthographicLH(10.0f, 10.0f, 1.0f, 50.0f)); renderer->UpdateDataManual(frameIndex, GetViewMatrix(&light), SHMatrix::OrthographicLH(12.0f, 12.0f, 1.0f, 80.0f));
} }
auto enumValue = SHUtilities::ConvertEnum(light.GetLightData().type); auto enumValue = SHUtilities::ConvertEnum(light.GetLightData().type);
@ -627,16 +631,16 @@ namespace SHADE
// add to barriers // add to barriers
shadowMapMemoryBarriers.push_back (vk::ImageMemoryBarrier shadowMapMemoryBarriers.push_back (vk::ImageMemoryBarrier
{ {
.srcAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentWrite, .srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead,
.dstAccessMask = vk::AccessFlagBits::eShaderRead, .dstAccessMask = vk::AccessFlagBits::eShaderRead,
.oldLayout = vk::ImageLayout::eDepthAttachmentOptimal, .oldLayout = vk::ImageLayout::eColorAttachmentOptimal,
.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal, .newLayout = vk::ImageLayout::eShaderReadOnlyOptimal,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = newShadowMap->GetImage()->GetVkImage(), .image = newShadowMap->GetImage()->GetVkImage(),
.subresourceRange = vk::ImageSubresourceRange .subresourceRange = vk::ImageSubresourceRange
{ {
.aspectMask = vk::ImageAspectFlagBits::eDepth, .aspectMask = vk::ImageAspectFlagBits::eColor,
.baseMipLevel = 0, .baseMipLevel = 0,
.levelCount = 1, .levelCount = 1,
.baseArrayLayer = 0, .baseArrayLayer = 0,
@ -651,7 +655,7 @@ namespace SHADE
void SHLightingSubSystem::PrepareShadowMapsForRead(Handle<SHVkCommandBuffer> cmdBuffer) noexcept void SHLightingSubSystem::PrepareShadowMapsForRead(Handle<SHVkCommandBuffer> cmdBuffer) noexcept
{ {
// Issue barrier to transition shadow maps for reading in compute shader // Issue barrier to transition shadow maps for reading in compute shader
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, shadowMapMemoryBarriers); cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, shadowMapMemoryBarriers);
} }
//void SHLightingSubSystem::HandleResize(Handle<SHRenderGraphNodeCompute> compute) noexcept //void SHLightingSubSystem::HandleResize(Handle<SHRenderGraphNodeCompute> compute) noexcept

View File

@ -0,0 +1,41 @@
#pragma once
#include "Resource/SHHandle.h"
#include "Graphics/Pipeline/SHPipelineState.h"
#include "Math/SHMatrix.h"
namespace SHADE
{
class SHVkLogicalDevice;
class SHVkDescriptorPool;
class SHVkDescriptorSetGroup;
class SHVkDescriptorSetLayout;
class SHVkBuffer;
class SHLightComponent;
class SHVkCommandBuffer;
class SHVkPipeline;
class SHVkPipelineLayout;
class SHVkRenderpass;
class SHSubpass;
class SHVkShaderModule;
class SHRenderer;
class SHParticleSubSystem
{
private:
Handle<SHVkLogicalDevice> logicalDevice;
public:
void Init(Handle<SHVkLogicalDevice> device, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass) noexcept;
void Run(uint32_t frameIndex) noexcept;
void Render(Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex) noexcept;
void Exit(void) noexcept;
};
}

View File

@ -0,0 +1,7 @@
#include "SHpch.h"
#include "SHParticleSubSustem.h"
namespace SHADE
{
}

View File

@ -0,0 +1,96 @@
#include "SHpch.h"
#include "SHTrajectoryRenderableComponent.h"
namespace SHADE
{
/***************************************************************************/
/*!
\brief
On create the text has nothing.
*/
/***************************************************************************/
void SHTrajectoryRenderableComponent::OnCreate(void)
{
}
void SHTrajectoryRenderableComponent::OnDestroy(void)
{
}
void SHTrajectoryRenderableComponent::ClearPositions(void) noexcept
{
positions.clear();
}
bool SHTrajectoryRenderableComponent::HasPositions(void) const noexcept
{
return !positions.empty();
}
std::vector<SHVec3> SHTrajectoryRenderableComponent::GetPositions(void) const noexcept
{
return positions;
}
Handle<SHMesh> SHTrajectoryRenderableComponent::GetMesh(void) const noexcept
{
return mesh;
}
SHVec4 const& SHTrajectoryRenderableComponent::GetStartColor(void) const noexcept
{
return startColor;
}
SHVec4 const& SHTrajectoryRenderableComponent::GetEndColor(void) const noexcept
{
return endColor;
}
float SHTrajectoryRenderableComponent::GetColorEvolveRate(void) const noexcept
{
return colorEvolveRate;
}
void SHTrajectoryRenderableComponent::SetMesh(Handle<SHMesh> newMesh) noexcept
{
mesh = newMesh;
}
void SHTrajectoryRenderableComponent::SetPositions(std::vector<SHVec3> const& inPositions) noexcept
{
positions = inPositions;
}
void SHTrajectoryRenderableComponent::SetStartColor(SHVec4 color) noexcept
{
startColor = color;
}
void SHTrajectoryRenderableComponent::SetEndColor(SHVec4 color) noexcept
{
endColor = color;
}
void SHTrajectoryRenderableComponent::SetColorEvolveRate(float rate) noexcept
{
colorEvolveRate = rate;
}
}
namespace rttr
{
RTTR_REGISTRATION
{
using namespace SHADE;
registration::class_<SHTrajectoryRenderableComponent>("Trajectory Renderer Component");
};
}

View File

@ -0,0 +1,58 @@
#pragma once
#include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h"
#include "Resource/SHHandle.h"
#include "ECS_Base/Components/SHComponent.h"
#include <rttr/registration>
namespace SHADE
{
class SHMesh;
class SHTrajectoryRenderableComponent : public SHComponent
{
private:
//! Mesh used to render the trajectory
Handle<SHMesh> mesh;
//! positions to plot for rendering. Will be cleared every frame.
std::vector<SHVec3> positions;
//! Starting color of the trajectory
SHVec4 startColor;
//! Color the trajectory should evolve to the longer it is
SHVec4 endColor;
//! evolving rate of the color
float colorEvolveRate;
public:
/*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
void SetMesh(Handle<SHMesh> newMesh) noexcept;
void SetPositions (std::vector<SHVec3> const& inPositions) noexcept;
void SetStartColor(SHVec4 startColor) noexcept;
void SetEndColor (SHVec4 endColor) noexcept;
void SetColorEvolveRate (float rate) noexcept;
std::vector<SHVec3> GetPositions (void) const noexcept;
Handle<SHMesh> GetMesh (void) const noexcept;
SHVec4 const& GetStartColor (void) const noexcept;
SHVec4 const& GetEndColor (void) const noexcept;
float GetColorEvolveRate (void) const noexcept;
void OnCreate(void) override final;
void OnDestroy(void) override final;
void ClearPositions(void) noexcept;
bool HasPositions(void) const noexcept;
RTTR_ENABLE()
};
}

View File

@ -0,0 +1,191 @@
#include "SHpch.h"
#include "SHTrajectoryRenderingSubSystem.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "Graphics/MiddleEnd/TrajectoryRendering/SHTrajectoryRenderableComponent.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Graphics\MiddleEnd\Interface\SHMeshLibrary.h"
#include "Graphics/SHVkUtil.h"
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
#include "Graphics/Pipeline/SHVkPipeline.h"
#include "Graphics/RenderGraph/SHSubpass.h"
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
namespace SHADE
{
void SHTrajectoryRenderingSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkShaderModule> trajectoryVS, Handle<SHVkShaderModule> trajectoryFS) noexcept
{
logicalDevice = device;
SHComponentManager::CreateComponentSparseSet<SHTrajectoryRenderableComponent>();
// prepare pipeline layout params
SHPipelineLayoutParams plParams
{
.shaderModules = {trajectoryVS, trajectoryFS},
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::TRAJECTORY_RENDERING).descSetLayouts
};
pipelineLayout = logicalDevice->CreatePipelineLayout(plParams);
// Create pipeline
pipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, compatibleRenderpass, subpass);
// vertex input state of the pipeline
SHVertexInputState vertexInputState;
vertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Attribute positions at binding 0
vertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // Attribute uv at binding 1
vertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::FLOAT_4D) }); // Instanced attribute color at binding 2
vertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Instanced Transform at binding 3 - 6 (4 slots)
pipeline->GetPipelineState().SetVertexInputState(vertexInputState);
SHColorBlendState colorBlendState{};
colorBlendState.logic_op_enable = VK_FALSE;
colorBlendState.logic_op = vk::LogicOp::eCopy;
auto const& subpassColorReferences = subpass->GetColorAttachmentReferences();
colorBlendState.attachments.reserve(static_cast<uint32_t>(subpassColorReferences.size()));
for (auto& att : subpassColorReferences)
{
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
{
.blendEnable = SHVkUtil::IsBlendCompatible(subpass->GetFormatFromAttachmentReference(att.attachment)) ? true : false,
.srcColorBlendFactor = vk::BlendFactor::eSrcAlpha,
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
.colorBlendOp = vk::BlendOp::eAdd,
.srcAlphaBlendFactor = vk::BlendFactor::eOne,
.dstAlphaBlendFactor = vk::BlendFactor::eZero,
.alphaBlendOp = vk::BlendOp::eAdd,
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
}
);
}
pipeline->GetPipelineState().SetColorBlenState(colorBlendState);
}
void SHTrajectoryRenderingSubSystem::Run(uint32_t frameIndex) noexcept
{
auto& comps = SHComponentManager::GetDense<SHTrajectoryRenderableComponent>();
for (auto& comp : comps)
{
comp.SetPositions(std::vector
{
SHVec3 {},
SHVec3 {}
});
// If has positions, feed data to buffer.
if (comp.HasPositions())
{
SHTransformComponent* transform = SHComponentManager::GetComponent_s<SHTransformComponent>(comp.GetEID());
if (transform)
{
// convenient variable
SHVec4 const& startColor = comp.GetStartColor();
SHVec4 const& endColor = comp.GetEndColor();
float colorEvolveRate = comp.GetColorEvolveRate();
// trs to be reused
SHMatrix trs = transform->GetTRS();
// starting color of trajectory
SHVec4 currentColor = comp.GetStartColor();
// Start from 0 and slowly evolve to 1
float lerpValue = 0.0f;
// Will be used for baseInstance later
uint32_t oldTransformDataSize = transformData.size();
auto meshHandle = comp.GetMesh();
auto const& positions = comp.GetPositions();
for (auto& pos : positions)
{
// modify position and reuse matrix
trs.m[3][0] = pos.x;
trs.m[3][1] = pos.y;
trs.m[3][2] = pos.z;
transformData.push_back(trs);
colorData.push_back(currentColor);
// evolve color
currentColor = SHVec4::Lerp(startColor, endColor, lerpValue);
// evolve lerp value and clamp to 1
lerpValue = std::max (1.0f, lerpValue + colorEvolveRate);
}
// add draw data for this trajectory
drawData.push_back(vk::DrawIndexedIndirectCommand
{
.indexCount = meshHandle->IndexCount,
.instanceCount = static_cast<uint32_t>(transformData.size()) - oldTransformDataSize,
.firstIndex = meshHandle->FirstIndex,
.vertexOffset = meshHandle->FirstVertex,
.firstInstance = oldTransformDataSize
});
}
}
// clear at the end of every frame since data is already in buffers
comp.ClearPositions();
}
if (!transformData.empty())
{
// read transform data to buffer
// read draw data to buffer
SHVkUtil::EnsureBufferAndCopyHostVisibleData(logicalDevice, transformBuffer, transformData.data(), sizeof (SHMatrix) * transformData.size(), vk::BufferUsageFlagBits::eVertexBuffer, "Trajectory System Transform Buffer");
SHVkUtil::EnsureBufferAndCopyHostVisibleData(logicalDevice, drawDataBuffer, drawData.data(), sizeof(vk::DrawIndexedIndirectCommand) * drawData.size(), vk::BufferUsageFlagBits::eIndirectBuffer, "Trajectory System Draw Data Buffer");
SHVkUtil::EnsureBufferAndCopyHostVisibleData(logicalDevice, colorBuffer, colorData.data(), sizeof(SHVec4) * colorData.size(), vk::BufferUsageFlagBits::eVertexBuffer, "Trajectory System Color Data Buffer");
}
}
void SHTrajectoryRenderingSubSystem::Render(Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex) noexcept
{
if (!transformData.empty())
{
auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::TRAJECTORY_RENDERING);
uint32_t staticGlobalSetIndex = mappings.at(SHPredefinedDescriptorTypes::STATIC_DATA);
uint32_t cameraSetIndex = mappings.at(SHPredefinedDescriptorTypes::CAMERA);
cmdBuffer->BindPipeline(pipeline);
// Bind global data
SHGlobalDescriptorSets::BindStaticGlobalData(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, staticGlobalSetIndex);
// Bind camera data
renderer->BindDescriptorSet(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, cameraSetIndex, frameIndex);
// Bind color vertex buffer
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRAJECTORY_COLOR, colorBuffer, 0);
// call draw call
cmdBuffer->DrawMultiIndirect(drawDataBuffer, drawData.size());
// clear CPU transform and draw data
transformData.clear();
drawData.clear();
colorData.clear();
}
}
void SHTrajectoryRenderingSubSystem::Exit(void) noexcept
{
}
}

View File

@ -0,0 +1,66 @@
#pragma once
#include "Resource/SHHandle.h"
#include "Graphics/Pipeline/SHPipelineState.h"
#include "Math/SHMatrix.h"
namespace SHADE
{
class SHVkLogicalDevice;
class SHVkDescriptorPool;
class SHVkDescriptorSetGroup;
class SHVkDescriptorSetLayout;
class SHVkBuffer;
class SHLightComponent;
class SHVkCommandBuffer;
class SHVkPipeline;
class SHVkPipelineLayout;
class SHVkRenderpass;
class SHSubpass;
class SHVkShaderModule;
class SHRenderer;
class SHTrajectoryRenderingSubSystem
{
private:
Handle<SHVkLogicalDevice> logicalDevice;
//! Every trajectory renderable will have one of these
std::vector<vk::DrawIndexedIndirectCommand> drawData;
//! For the MDI call
Handle<SHVkBuffer> drawDataBuffer;
//! matrix data to copy into buffer
std::vector<SHMatrix> transformData;
//! All trajectory renderables will use this transform buffer
Handle<SHVkBuffer> transformBuffer;
//! Each object will have their own color data
std::vector<SHVec4> colorData;
//! buffer to hold color data for objects
Handle<SHVkBuffer> colorBuffer;
//! Pipeline for rendering the trajectories
Handle<SHVkPipeline> pipeline;
//! Pipeline layout for the pipeline
Handle<SHVkPipelineLayout> pipelineLayout;
public:
void Init (Handle<SHVkLogicalDevice> device, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkShaderModule> textVS, Handle<SHVkShaderModule> textFS) noexcept;
void Run(uint32_t frameIndex) noexcept;
void Render(Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex) noexcept;
void Exit(void) noexcept;
};
}

View File

@ -387,6 +387,7 @@ namespace SHADE
{ {
auto eventData = reinterpret_cast<const SHEventSpec<SHEditorStateChangeEvent>*>(eventPtr.get()); auto eventData = reinterpret_cast<const SHEventSpec<SHEditorStateChangeEvent>*>(eventPtr.get());
csScriptRemoveAllForAllNow(true); csScriptRemoveAllForAllNow(true);
csEngineReloadScripts();
return eventData->handle; return eventData->handle;
} }
@ -569,7 +570,7 @@ namespace SHADE
SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(destroyedEventReceiver)); SHEventManager::SubscribeTo(SH_ENTITY_DESTROYED_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(destroyedEventReceiver));
/* Editor */ /* Editor */
// Register for editor state change event // Register for editor state change events
std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> destroyedSceneEventReceiver std::shared_ptr<SHEventReceiverSpec<SHScriptEngine>> destroyedSceneEventReceiver
{ {
std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onSceneDestroyed) std::make_shared<SHEventReceiverSpec<SHScriptEngine>>(this, &SHScriptEngine::onSceneDestroyed)

View File

@ -233,6 +233,10 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="path"></param> /// <param name="path"></param>
void OpenFile(const std::filesystem::path& path); void OpenFile(const std::filesystem::path& path);
/// <summary>
/// Resets all static data in the loaded assemblies to their default values.
/// </summary>
static void ResetStaticDataInLoadedAssembly();
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

View File

@ -81,7 +81,8 @@ namespace SHADE
// Add the script // Add the script
Script^ script; Script^ script;
ScriptStore::AddScriptViaNameWithRef(entity, type->Name, script); ScriptStore::AddScriptViaNameWithRef(entity, type->Name, script);
registerUndoScriptAddAction(entity, script); // TODO: Re-enable when undo-redo is fixed
// registerUndoScriptAddAction(entity, script);
break; break;
} }
} }
@ -375,7 +376,8 @@ namespace SHADE
{ {
// Mark script for removal // Mark script for removal
ScriptStore::RemoveScript(entity, script); ScriptStore::RemoveScript(entity, script);
registerUndoScriptRemoveAction(entity, script, scriptIndex); // TODO: Re-enable when undo-redo is fixed
// registerUndoScriptRemoveAction(entity, script, scriptIndex);
} }
SHEditorUI::EndPopup(); SHEditorUI::EndPopup();
} }

View File

@ -22,6 +22,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Utility/Debug.hxx" #include "Utility/Debug.hxx"
#include "Utility/Convert.hxx" #include "Utility/Convert.hxx"
#include "Scripts/ScriptStore.hxx" #include "Scripts/ScriptStore.hxx"
#include "Serialisation/SerialisationUtilities.hxx"
namespace SHADE namespace SHADE
{ {
@ -267,7 +268,9 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
ScriptAddCommand::ScriptAddCommand(EntityID id, Script^ script) ScriptAddCommand::ScriptAddCommand(EntityID id, Script^ script)
: entity { id } : entity { id }
, addedScript { script } , typeName { script->GetType()->FullName }
, serialisedScript { SerialisationUtilities::Serialise(script) }
, insertedIndex { ScriptStore::GetScriptIndex(script) }
{} {}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -275,12 +278,20 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
bool ScriptAddCommand::Execute() bool ScriptAddCommand::Execute()
{ {
return ScriptStore::AddScript(entity, addedScript) != nullptr; Script^ script = nullptr;
if (ScriptStore::AddScriptViaNameWithRef(entity, typeName, script))
{
SerialisationUtilities::Deserialise(script, serialisedScript);
insertedIndex = ScriptStore::GetScriptIndex(script);
return true;
}
return false;
} }
bool ScriptAddCommand::Unexceute() bool ScriptAddCommand::Unexceute()
{ {
return ScriptStore::RemoveScript(entity, addedScript); return ScriptStore::RemoveScript(entity, insertedIndex);
} }
bool ScriptAddCommand::Merge(ICommand^) bool ScriptAddCommand::Merge(ICommand^)
@ -293,8 +304,9 @@ namespace SHADE
/* ScriptRemoveCommand - Constructor */ /* ScriptRemoveCommand - Constructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
ScriptRemoveCommand::ScriptRemoveCommand(EntityID id, Script^ script, int index) ScriptRemoveCommand::ScriptRemoveCommand(EntityID id, Script^ script, int index)
: entity { id } : entity{ id }
, removedScript { script } , typeName{ script->GetType()->FullName }
, serialisedScript{ SerialisationUtilities::Serialise(script) }
, originalIndex { index } , originalIndex { index }
{} {}
@ -303,12 +315,19 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
bool ScriptRemoveCommand::Execute() bool ScriptRemoveCommand::Execute()
{ {
return ScriptStore::RemoveScript(entity, removedScript); return ScriptStore::RemoveScript(entity, originalIndex);
} }
bool ScriptRemoveCommand::Unexceute() bool ScriptRemoveCommand::Unexceute()
{ {
return ScriptStore::AddScript(entity, removedScript, originalIndex) != nullptr; Script^ script = nullptr;
if (ScriptStore::AddScriptViaNameWithRef(entity, typeName, script, originalIndex))
{
SerialisationUtilities::Deserialise(script, serialisedScript);
return true;
}
return false;
} }
bool ScriptRemoveCommand::Merge(ICommand^) bool ScriptRemoveCommand::Merge(ICommand^)

View File

@ -114,7 +114,9 @@ namespace SHADE
private: private:
EntityID entity; EntityID entity;
Script^ addedScript; System::String^ typeName;
System::String^ serialisedScript;
int insertedIndex;
}; };
private ref class ScriptRemoveCommand sealed : public ICommand private ref class ScriptRemoveCommand sealed : public ICommand
@ -128,7 +130,8 @@ namespace SHADE
private: private:
EntityID entity; EntityID entity;
Script^ removedScript; System::String^ typeName;
System::String^ serialisedScript;
int originalIndex; int originalIndex;
}; };

View File

@ -100,6 +100,11 @@ namespace SHADE
} }
bool ScriptStore::AddScriptViaNameWithRef(Entity entity, System::String^ scriptName, Script^% createdScript) bool ScriptStore::AddScriptViaNameWithRef(Entity entity, System::String^ scriptName, Script^% createdScript)
{
return AddScriptViaNameWithRef(entity, scriptName, createdScript, System::Int32::MaxValue);
}
bool ScriptStore::AddScriptViaNameWithRef(Entity entity, System::String^ scriptName, [System::Runtime::InteropServices::Out] Script^% createdScript, int index)
{ {
// Check if we are set up to get scripts // Check if we are set up to get scripts
if (addScriptMethod == nullptr) if (addScriptMethod == nullptr)
@ -120,17 +125,18 @@ namespace SHADE
return false; return false;
} }
// Otherwise, add the script // Add the script
System::Reflection::MethodInfo^ method = addScriptMethod->MakeGenericMethod(scriptType); System::Reflection::MethodInfo^ method = addScriptMethod->MakeGenericMethod(scriptType);
try try
{ {
array<Object^>^ params = gcnew array<Object^>{entity}; // Create the script and add it in
createdScript = safe_cast<Script^>(method->Invoke(nullptr, params)); createdScript = safe_cast<Script^>(System::Activator::CreateInstance(scriptType));
AddScript(entity, createdScript, index);
} }
catch (System::Exception^ e) catch (System::Exception^ e)
{ {
std::ostringstream oss; std::ostringstream oss;
oss << "[ScriptStore] Failed to add Script named \"" << Convert::ToNative(scriptName) oss << "[ScriptStore] Failed to add Script named \"" << Convert::ToNative(scriptType->Name)
<< "\" to Entity #" << entity << "! (" << Convert::ToNative(e->GetType()->Name) << ")"; << "\" to Entity #" << entity << "! (" << Convert::ToNative(e->GetType()->Name) << ")";
oss << Convert::ToNative(e->ToString()); oss << Convert::ToNative(e->ToString());
Debug::LogError(oss.str()); Debug::LogError(oss.str());
@ -321,6 +327,19 @@ namespace SHADE
} }
return nullptr; return nullptr;
} }
int ScriptStore::GetScriptIndex(Script^ script)
{
// Check if entity exists in the script storage
if (!scripts.ContainsKey(script->Owner.EntityId))
{
Debug::LogError("[ScriptStore] Attempted to query a Script that does not belong to the ScriptStore.");
return -1;
}
return scripts[script->Owner.EntityId]->IndexOf(script);
}
generic<typename T> generic<typename T>
void ScriptStore::RemoveScript(Entity entity) void ScriptStore::RemoveScript(Entity entity)
{ {
@ -376,6 +395,35 @@ namespace SHADE
removeScript(script); removeScript(script);
return true; return true;
} }
bool ScriptStore::RemoveScript(Entity entity, int index)
{
// Check if entity exists
if (!EntityUtils::IsValid(entity))
{
Debug::LogError("[ScriptStore] Attempted to remove a Script from an invalid Entity!");
return false;
}
// Check if entity exists in the script storage
if (!scripts.ContainsKey(entity))
{
Debug::LogError("[ScriptStore] Attempted to remove a Script that does not belong to the specified Entity!");
return false;
}
// Check if the script index is out of bounds
if (index < 0 || index >= scripts[entity]->Count)
{
Debug::LogError("[ScriptStore] Attempted to remove a Script from an out of range index!");
return false;
}
// Script found, queue it for deletion
removeScript((*scripts[entity])[index]);
return true;
}
void ScriptStore::RemoveAllScripts(Entity entity) void ScriptStore::RemoveAllScripts(Entity entity)
{ {
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN

View File

@ -82,9 +82,9 @@ namespace SHADE
/// <summary> /// <summary>
/// Adds a Script to a specified Entity. /// Adds a Script to a specified Entity.
/// <br/> /// <br/>
/// This function is meant for consumption from native code or for serialisation /// This function is meant for deserialisation purposes. If you are writing in
/// purposes. If you are writing in C# or C++/CLI and not doing serialisation, /// C# or C++/CLI and not doing serialisation, use AddScript&lt;T&gt;() instead
/// use AddScript&lt;T&gt;() instead as it is faster. /// as it is faster.
/// </summary> /// </summary>
/// <param name="entity">The entity to add a script to.</param> /// <param name="entity">The entity to add a script to.</param>
/// <param name="scriptName">The entity to add a script to.</param> /// <param name="scriptName">The entity to add a script to.</param>
@ -96,6 +96,7 @@ namespace SHADE
/// console. /// console.
/// </returns> /// </returns>
static bool AddScriptViaNameWithRef(Entity entity, System::String^ scriptName, [System::Runtime::InteropServices::Out] Script^% createdScript); static bool AddScriptViaNameWithRef(Entity entity, System::String^ scriptName, [System::Runtime::InteropServices::Out] Script^% createdScript);
static bool AddScriptViaNameWithRef(Entity entity, System::String^ scriptName, [System::Runtime::InteropServices::Out] Script^% createdScript, int index);
/// <summary> /// <summary>
/// Retrieves the first Script from the specified Entity that matches the /// Retrieves the first Script from the specified Entity that matches the
/// specified type. /// specified type.
@ -190,6 +191,12 @@ namespace SHADE
/// </returns> /// </returns>
static System::Collections::Generic::IEnumerable<Script^>^ GetAllScripts(Entity entity); static System::Collections::Generic::IEnumerable<Script^>^ GetAllScripts(Entity entity);
/// <summary> /// <summary>
/// Retrieves the index of a Script within the list of it's Entity's script list.
/// </summary>
/// <param name="script">Script to get the index of.</param>
/// <returns>Script index if valid. Otherwise -1.</returns>
static int GetScriptIndex(Script^ script);
/// <summary>
/// Removes all Scripts of the specified type from the specified Entity. /// Removes all Scripts of the specified type from the specified Entity.
/// </summary> /// </summary>
/// <typeparam name="T"> /// <typeparam name="T">
@ -210,6 +217,13 @@ namespace SHADE
/// <returns>True if successfully removed. False otherwise.</returns> /// <returns>True if successfully removed. False otherwise.</returns>
static bool RemoveScript(Entity entity, Script^ script); static bool RemoveScript(Entity entity, Script^ script);
/// <summary> /// <summary>
/// Removes a script at a specified index from the specified entity.
/// </summary>
/// <param name="entity">The entity to remove the script from.</param>
/// <param name="index">Index of the script to remove.</param>
/// <returns>True if successfully removed. False otherwise.</returns>
static bool RemoveScript(Entity entity, int index);
/// <summary>
/// Removes all Scripts attached to the specified Entity. Does not do anything /// Removes all Scripts attached to the specified Entity. Does not do anything
/// if the specified Entity is invalid or does not have any Scripts /// if the specified Entity is invalid or does not have any Scripts
/// attached. /// attached.

View File

@ -22,6 +22,7 @@ of DigiPen Institute of Technology is prohibited.
#include "Assets/MaterialAsset.hxx" #include "Assets/MaterialAsset.hxx"
#include "Assets/MeshAsset.hxx" #include "Assets/MeshAsset.hxx"
#include "Scripts/Script.hxx" #include "Scripts/Script.hxx"
#include "Scripts/ScriptStore.hxx"
/*-------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------*/
/* File-Level Constants */ /* File-Level Constants */
@ -79,6 +80,19 @@ namespace SHADE
scriptListNode.push_back(scriptNode); scriptListNode.push_back(scriptNode);
} }
System::String^ SerialisationUtilities::Serialise(Script^ script)
{
YAML::Node node;
node.SetStyle(YAML::EmitterStyle::Block);
Serialise(script, node);
YAML::Emitter emitter;
emitter << YAML::BeginMap;
emitter << node;
emitter << YAML::EndMap;
return Convert::ToCLI(emitter.c_str());
}
void SerialisationUtilities::Deserialise(Object^ object, YAML::Node& yamlNode) void SerialisationUtilities::Deserialise(Object^ object, YAML::Node& yamlNode)
{ {
using namespace System::Reflection; using namespace System::Reflection;
@ -135,6 +149,12 @@ namespace SHADE
} }
} }
} }
void SerialisationUtilities::Deserialise(Script^ script, System::String^ yamlString)
{
Deserialise(script, YAML::Load(Convert::ToNative(yamlString)));
}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Serialization Helper Functions */ /* Serialization Helper Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -39,6 +39,7 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="object">The object to serialise.</param> /// <param name="object">The object to serialise.</param>
static void Serialise(System::Object^ object, YAML::Node& yamlNode); static void Serialise(System::Object^ object, YAML::Node& yamlNode);
static System::String^ Serialise(Script^ script);
/// <summary> /// <summary>
/// Deserialises a YAML node that contains a map of Scripts and copies the /// Deserialises a YAML node that contains a map of Scripts and copies the
/// deserialised data into the specified object if there are matching fields. /// deserialised data into the specified object if there are matching fields.
@ -48,6 +49,7 @@ namespace SHADE
/// </param> /// </param>
/// <param name="object">The object to copy deserialised data into.</param> /// <param name="object">The object to copy deserialised data into.</param>
static void Deserialise(System::Object^ object, YAML::Node& yamlNode); static void Deserialise(System::Object^ object, YAML::Node& yamlNode);
static void Deserialise(Script^ script, System::String^ yamlString);
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/