PlayerController and PickAndThrow #167
|
@ -21,7 +21,8 @@ layout(set = 4, binding = 0, rgba32f) uniform image2D positions;
|
||||||
layout(set = 4, binding = 1, rgba32f) uniform image2D normals;
|
layout(set = 4, binding = 1, rgba32f) uniform image2D normals;
|
||||||
layout(set = 4, binding = 2, rgba8) uniform image2D albedo;
|
layout(set = 4, binding = 2, rgba8) uniform image2D albedo;
|
||||||
layout(set = 4, binding = 3, r32ui) uniform uimage2D lightLayerData;
|
layout(set = 4, binding = 3, r32ui) uniform uimage2D lightLayerData;
|
||||||
layout(set = 4, binding = 4, rgba8) uniform image2D targetImage;
|
layout(set = 4, binding = 4, r8) uniform image2D ssaoBlurredImage;
|
||||||
|
layout(set = 4, binding = 5, rgba8) uniform image2D targetImage;
|
||||||
|
|
||||||
layout(set = 1, binding = 0) uniform LightCounts
|
layout(set = 1, binding = 0) uniform LightCounts
|
||||||
{
|
{
|
||||||
|
@ -51,33 +52,46 @@ void main()
|
||||||
vec3 pixelDiffuse = imageLoad (albedo, globalThread).rgb;
|
vec3 pixelDiffuse = imageLoad (albedo, globalThread).rgb;
|
||||||
|
|
||||||
// Get position of fragment in world space
|
// Get position of fragment in world space
|
||||||
vec3 positionWorld = imageLoad (positions, globalThread).rgb;
|
vec3 positionView = imageLoad (positions, globalThread).rgb;
|
||||||
|
|
||||||
// normal of fragment
|
// normal of fragment
|
||||||
vec3 normalWorld = imageLoad(normals, globalThread).rgb;
|
vec3 normalView = imageLoad(normals, globalThread).rgb;
|
||||||
|
|
||||||
|
// light layer index
|
||||||
|
uint lightLayer = imageLoad (lightLayerData, globalThread).r;
|
||||||
|
|
||||||
vec3 fragColor = vec3 (0.0f);
|
vec3 fragColor = vec3 (0.0f);
|
||||||
|
|
||||||
for (int i = 0; i < lightCounts.directionalLights; ++i)
|
for (int i = 0; i < lightCounts.directionalLights; ++i)
|
||||||
{
|
{
|
||||||
// get normalized direction of light
|
if ((lightLayer & DirLightData.dLightData[i].cullingMask) != 0)
|
||||||
vec3 dLightNormalized = normalize (DirLightData.dLightData[i].direction);
|
{
|
||||||
|
// get normalized direction of light
|
||||||
|
vec3 dLightNormalized = normalize (DirLightData.dLightData[i].direction);
|
||||||
|
|
||||||
// Get diffuse strength
|
// Get diffuse strength
|
||||||
float diffuseStrength = max (0, dot (dLightNormalized, normalWorld));
|
float diffuseStrength = max (0, dot (dLightNormalized, normalView));
|
||||||
|
|
||||||
// Calculate the fragment color
|
// Calculate the fragment color
|
||||||
fragColor += DirLightData.dLightData[i].diffuseColor.rgb * diffuseStrength.rrr * pixelDiffuse;
|
fragColor += DirLightData.dLightData[i].diffuseColor.rgb * diffuseStrength.rrr * pixelDiffuse;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < lightCounts.ambientLights; ++i)
|
for (int i = 0; i < lightCounts.ambientLights; ++i)
|
||||||
{
|
{
|
||||||
// Just do some add
|
if ((lightLayer & AmbLightData.aLightData[i].cullingMask) != 0)
|
||||||
//fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (0.5f);
|
{
|
||||||
fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (AmbLightData.aLightData[i].strength);
|
// Just do some add
|
||||||
|
//fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (0.5f);
|
||||||
|
fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (AmbLightData.aLightData[i].strength);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float ssaoVal = imageLoad (ssaoBlurredImage, globalThread).r;
|
||||||
|
fragColor *= ssaoVal;
|
||||||
|
|
||||||
// store result into result image
|
// store result into result image
|
||||||
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor, 1.0f));
|
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor.rgb, 1.0f));
|
||||||
|
//imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(ssaoVal.rrr, 1.0f));
|
||||||
|
|
||||||
}
|
}
|
Binary file not shown.
|
@ -0,0 +1,58 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
#define BLUR_WIDTH 5
|
||||||
|
#define BLUR_HALF_WIDTH BLUR_WIDTH / 2
|
||||||
|
#define SHM_WIDTH BLUR_WIDTH + 16 - 1
|
||||||
|
|
||||||
|
layout(local_size_x = 16, local_size_y = 16) in;
|
||||||
|
layout(set = 4, binding = 0, r8) uniform image2D ssaoImage;
|
||||||
|
layout(set = 4, binding = 1, r8) uniform image2D ssaoBlurImage;
|
||||||
|
|
||||||
|
|
||||||
|
float GetSSAOValue(ivec2 uv, ivec2 imageSize)
|
||||||
|
{
|
||||||
|
if (uv.x >= 0 && uv.y >= 0 && uv.x < imageSize.x && uv.y < imageSize.y)
|
||||||
|
{
|
||||||
|
return imageLoad (ssaoImage, uv).r;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared float sharedPixels[16 + BLUR_WIDTH - 1][16 + BLUR_WIDTH - 1];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ivec2 globalThread = ivec2 (gl_GlobalInvocationID.xy);
|
||||||
|
ivec2 localThread = ivec2 (gl_LocalInvocationID.xy);
|
||||||
|
ivec2 inputImageSize = imageSize(ssaoImage);
|
||||||
|
|
||||||
|
// Load color into shared memory
|
||||||
|
ivec2 start = ivec2 (gl_WorkGroupID) * ivec2 (gl_WorkGroupSize) - (BLUR_HALF_WIDTH);
|
||||||
|
for (int i = localThread.x; i < SHM_WIDTH; i += int (gl_WorkGroupSize.x))
|
||||||
|
{
|
||||||
|
for (int j = localThread.y; j < SHM_WIDTH; j += int (gl_WorkGroupSize.y))
|
||||||
|
{
|
||||||
|
float value = GetSSAOValue (start + ivec2 (i, j), inputImageSize);
|
||||||
|
sharedPixels[i][j] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for all shared memory to load
|
||||||
|
barrier();
|
||||||
|
|
||||||
|
ivec2 shmStart = ivec2 (localThread + (BLUR_HALF_WIDTH));
|
||||||
|
|
||||||
|
float sum = 0;
|
||||||
|
for (int i = -BLUR_HALF_WIDTH; i <= BLUR_HALF_WIDTH; ++i)
|
||||||
|
{
|
||||||
|
for (int j = -BLUR_HALF_WIDTH; j <= BLUR_HALF_WIDTH; ++j)
|
||||||
|
{
|
||||||
|
float sharedVal = sharedPixels[shmStart.x + i][shmStart.y + j];
|
||||||
|
sum += sharedVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sum /= (BLUR_WIDTH * BLUR_WIDTH);
|
||||||
|
imageStore(ssaoBlurImage, globalThread, vec4(sum.rrr, 1.0f));
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: SSAOBlur_CS
|
||||||
|
ID: 39760835
|
||||||
|
Type: 2
|
|
@ -0,0 +1,104 @@
|
||||||
|
#version 450
|
||||||
|
|
||||||
|
const uint NUM_SAMPLES = 64;
|
||||||
|
const uint NUM_ROTATIONS = 16;
|
||||||
|
const int ROTATION_KERNEL_W = 4;
|
||||||
|
const int ROTATION_KERNEL_H = 4;
|
||||||
|
|
||||||
|
// can perhaps pass in as push constant.
|
||||||
|
const float RADIUS = 0.5f;
|
||||||
|
const float BIAS = 0.025f;
|
||||||
|
|
||||||
|
layout(local_size_x = 16, local_size_y = 16) in;
|
||||||
|
layout(set = 4, binding = 0, rgba32f) uniform image2D positions;
|
||||||
|
layout(set = 4, binding = 1, rgba32f) uniform image2D normals;
|
||||||
|
layout(set = 4, binding = 2, rgba32f) uniform image2D outputImage;
|
||||||
|
|
||||||
|
|
||||||
|
// SSAO data
|
||||||
|
layout(std430, set = 5, binding = 0) buffer SSAOData
|
||||||
|
{
|
||||||
|
vec4 samples[NUM_SAMPLES];
|
||||||
|
|
||||||
|
} ssaoData;
|
||||||
|
|
||||||
|
layout (set = 5, binding = 1) uniform sampler2D noiseTexture;
|
||||||
|
|
||||||
|
layout(set = 2, binding = 0) uniform CameraData
|
||||||
|
{
|
||||||
|
vec4 position;
|
||||||
|
mat4 vpMat;
|
||||||
|
mat4 viewMat;
|
||||||
|
mat4 projMat;
|
||||||
|
|
||||||
|
} cameraData;
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// image size of the SSAO image
|
||||||
|
ivec2 ssaoSize = imageSize (outputImage);
|
||||||
|
|
||||||
|
// global thread
|
||||||
|
ivec2 globalThread = ivec2 (gl_GlobalInvocationID.xy);
|
||||||
|
|
||||||
|
// load all the necessary variables
|
||||||
|
vec3 viewSpacePos = imageLoad (positions, globalThread).rgb;
|
||||||
|
vec3 viewSpaceNormal = normalize (imageLoad (normals, globalThread).rgb);
|
||||||
|
|
||||||
|
// Get the noise dimension. This should be 4x4
|
||||||
|
vec2 noiseDim = vec2 (textureSize(noiseTexture, 0));
|
||||||
|
|
||||||
|
// Get normlized thread UV coordinates
|
||||||
|
vec2 threadUV = (vec2(globalThread)) / vec2(ssaoSize);
|
||||||
|
vec2 noiseUVMult = vec2 (vec2(ssaoSize) / noiseDim);
|
||||||
|
noiseUVMult *= threadUV;
|
||||||
|
|
||||||
|
// sample from the noise
|
||||||
|
vec3 randomVec = texture(noiseTexture, noiseUVMult).rgb;
|
||||||
|
|
||||||
|
// Gram schmidt
|
||||||
|
vec3 tangent = normalize (randomVec - (viewSpaceNormal * dot(viewSpaceNormal, randomVec)));
|
||||||
|
vec3 bitangent = normalize (cross (tangent, viewSpaceNormal));
|
||||||
|
|
||||||
|
// matrix for tangent space to view space
|
||||||
|
mat3 TBN = mat3(tangent, bitangent, viewSpaceNormal);
|
||||||
|
|
||||||
|
float occlusion = 0.0f;
|
||||||
|
for (int i = 0; i < NUM_SAMPLES; ++i)
|
||||||
|
{
|
||||||
|
// We want to get a position at an offset from the view space position. Offset scaled by radius.
|
||||||
|
vec3 displacementVector = TBN * ssaoData.samples[i].rgb;
|
||||||
|
|
||||||
|
// Why are we adding positions?
|
||||||
|
displacementVector = viewSpacePos + displacementVector * RADIUS;
|
||||||
|
|
||||||
|
// Now we take that offset position and bring it to clip space
|
||||||
|
vec4 offsetPos = vec4 (displacementVector, 1.0f);
|
||||||
|
offsetPos = cameraData.projMat * offsetPos;
|
||||||
|
|
||||||
|
// then we do perspective division
|
||||||
|
offsetPos.xyz /= offsetPos.w;
|
||||||
|
|
||||||
|
// and bring it from [-1, 1] to screen coordinates
|
||||||
|
offsetPos.xyz = ((offsetPos.xyz * 0.5f) + 0.5f);
|
||||||
|
offsetPos.xy *= vec2(ssaoSize.xy);
|
||||||
|
|
||||||
|
// Now we attempt to get a position at that point.
|
||||||
|
float sampleDepth = imageLoad (positions, ivec2 (offsetPos.xy)).z;
|
||||||
|
|
||||||
|
// skip checks
|
||||||
|
if (sampleDepth == 0.0f)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// if sampled fragment is in front of current fragment, just occlude
|
||||||
|
float rangeCheck = smoothstep (0.0f, 1.0f, RADIUS / abs (viewSpacePos.z - sampleDepth));
|
||||||
|
occlusion += (sampleDepth <= displacementVector.z - BIAS ? 1.0f : 0.0f) * rangeCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
occlusion = 1.0f - (occlusion / float(NUM_SAMPLES));
|
||||||
|
|
||||||
|
// store result into result image
|
||||||
|
imageStore(outputImage, globalThread, occlusion.rrrr);
|
||||||
|
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: SSAO_CS
|
||||||
|
ID: 38430899
|
||||||
|
Type: 2
|
|
@ -33,18 +33,31 @@ layout(set = 2, binding = 0) uniform CameraData
|
||||||
{
|
{
|
||||||
vec4 position;
|
vec4 position;
|
||||||
mat4 vpMat;
|
mat4 vpMat;
|
||||||
|
mat4 viewMat;
|
||||||
|
mat4 projMat;
|
||||||
} cameraData;
|
} cameraData;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
|
||||||
Out2.materialIndex = gl_InstanceIndex;
|
Out2.materialIndex = gl_InstanceIndex;
|
||||||
Out2.eid = integerData[0];
|
Out2.eid = integerData[0];
|
||||||
Out2.lightLayerIndex = integerData[1];
|
Out2.lightLayerIndex = integerData[1];
|
||||||
|
|
||||||
Out.vertPos = worldTransform * vec4(aVertexPos, 1.0f);
|
// for transforming gBuffer position and normal data
|
||||||
|
mat4 modelViewMat = cameraData.viewMat * worldTransform;
|
||||||
|
|
||||||
|
// gBuffer position will be in view space
|
||||||
|
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
||||||
|
|
||||||
|
// uvs for texturing in fragment shader
|
||||||
Out.uv = aUV;
|
Out.uv = aUV;
|
||||||
Out.normal.rgb = mat3(transpose(inverse(worldTransform))) * aNormal.rgb;
|
|
||||||
|
mat3 transposeInv = mat3 (transpose(inverse(modelViewMat)));
|
||||||
|
|
||||||
|
// normals are also in view space
|
||||||
|
Out.normal.rgb = transposeInv * aNormal.rgb;
|
||||||
Out.normal.rgb = normalize (Out.normal.rgb);
|
Out.normal.rgb = normalize (Out.normal.rgb);
|
||||||
|
|
||||||
|
// clip space for rendering
|
||||||
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
|
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
|
||||||
}
|
}
|
Binary file not shown.
|
@ -72,6 +72,9 @@ namespace Sandbox
|
||||||
SHSystemManager::CreateSystem<SHAudioSystem>();
|
SHSystemManager::CreateSystem<SHAudioSystem>();
|
||||||
SHSystemManager::CreateSystem<SHCameraSystem>();
|
SHSystemManager::CreateSystem<SHCameraSystem>();
|
||||||
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
|
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
|
||||||
|
|
||||||
|
// Link up SHDebugDraw
|
||||||
|
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
|
@ -91,6 +94,7 @@ namespace Sandbox
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
|
||||||
|
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsDebugDraw>();
|
||||||
|
|
||||||
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
|
||||||
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
|
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
|
||||||
|
@ -148,6 +152,13 @@ namespace Sandbox
|
||||||
#endif
|
#endif
|
||||||
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
|
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
|
||||||
editor->PollPicking();
|
editor->PollPicking();
|
||||||
|
|
||||||
|
static bool drawColliders = false;
|
||||||
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::SPACE))
|
||||||
|
{
|
||||||
|
drawColliders = !drawColliders;
|
||||||
|
SHSystemManager::GetSystem<SHPhysicsSystem>()->SetDrawColliders(drawColliders);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Finish all graphics jobs first
|
// Finish all graphics jobs first
|
||||||
graphicsSystem->AwaitGraphicsExecution();
|
graphicsSystem->AwaitGraphicsExecution();
|
||||||
|
|
|
@ -269,14 +269,15 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
const SHVec3& TF_WORLD_SCALE = transformComponent->GetWorldScale();
|
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 });
|
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
|
||||||
return sphere->GetRadius() / MAX_SCALE;
|
return (sphere->GetRadius() / MAX_SCALE) * 2.0f;
|
||||||
},
|
},
|
||||||
[collider](float const& value) { collider->SetBoundingSphere(value); });
|
[collider](float const& value) { collider->SetBoundingSphere(value); });
|
||||||
}
|
}
|
||||||
else if (collider->GetType() == SHCollider::Type::CAPSULE)
|
else if (collider->GetType() == SHCollider::Type::CAPSULE)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel("Offsets",{ ImGui::GetContentRegionAvail().x, 30.0f });
|
SHEditorWidgets::BeginPanel("Offsets",{ ImGui::GetContentRegionAvail().x, 30.0f });
|
||||||
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider->GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider->SetPositionOffset(vec); });
|
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider->GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider->SetPositionOffset(vec); });
|
||||||
|
@ -301,6 +302,9 @@ namespace SHADE
|
||||||
});
|
});
|
||||||
SHEditorWidgets::EndPanel();
|
SHEditorWidgets::EndPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHEditorWidgets::CheckBox("Is Trigger", [collider] { return collider->IsTrigger(); }, [collider](bool value) { collider->SetIsTrigger(value); });
|
||||||
|
|
||||||
if (ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
|
if (ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
|
||||||
{
|
{
|
||||||
colliderToDelete = i;
|
colliderToDelete = i;
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include <backends/imgui_impl_vulkan.h>
|
#include <backends/imgui_impl_vulkan.h>
|
||||||
|
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
|
||||||
|
#include "Tools/SHDebugDraw.h"
|
||||||
|
|
||||||
RTTR_REGISTRATION
|
RTTR_REGISTRATION
|
||||||
{
|
{
|
||||||
|
@ -77,7 +78,6 @@ namespace SHADE
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
void SHEditor::Init()
|
void SHEditor::Init()
|
||||||
{
|
{
|
||||||
|
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
if(auto context = ImGui::CreateContext())
|
if(auto context = ImGui::CreateContext())
|
||||||
{
|
{
|
||||||
|
@ -120,6 +120,17 @@ namespace SHADE
|
||||||
window->Init();
|
window->Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Editor View Gridlines */
|
||||||
|
SetUpGridLines(true, true);
|
||||||
|
// Handle state changes so that we only show in edit mode
|
||||||
|
std::shared_ptr<SHEventReceiverSpec<SHEditor>> stateChangeEventReceiver
|
||||||
|
{
|
||||||
|
std::make_shared<SHEventReceiverSpec<SHEditor>>(this, &SHEditor::onEditorStateChanged)
|
||||||
|
};
|
||||||
|
SHEventManager::SubscribeTo(SH_EDITOR_ON_PLAY_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(stateChangeEventReceiver));
|
||||||
|
SHEventManager::SubscribeTo(SH_EDITOR_ON_PAUSE_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(stateChangeEventReceiver));
|
||||||
|
SHEventManager::SubscribeTo(SH_EDITOR_ON_STOP_EVENT, std::dynamic_pointer_cast<SHEventReceiver>(stateChangeEventReceiver));
|
||||||
|
|
||||||
SHLOG_INFO("Successfully initialised SHADE Engine Editor")
|
SHLOG_INFO("Successfully initialised SHADE Engine Editor")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,6 +191,97 @@ namespace SHADE
|
||||||
io->Fonts->Build();
|
io->Fonts->Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHEditor::SetUpGridLines(bool drawGrid, bool drawAxes)
|
||||||
|
{
|
||||||
|
// Clear existing lines
|
||||||
|
SHDebugDraw::ClearPersistentDraws();
|
||||||
|
|
||||||
|
static constexpr float DELTA = 1.0f;
|
||||||
|
static constexpr int EXTENT_COUNT = static_cast<int>(500.0f /* TODO: Remove hard code */ / DELTA);
|
||||||
|
static constexpr float LINE_HALF_LENGTH = (DELTA * static_cast<float>(EXTENT_COUNT)) * 0.5f;
|
||||||
|
|
||||||
|
// Render Grid
|
||||||
|
static const SHColour GRID_COL = { 0.2f, 0.2f, 0.2f, 1.0f };
|
||||||
|
if (drawGrid)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < EXTENT_COUNT; ++i)
|
||||||
|
{
|
||||||
|
// X-Axis Lines
|
||||||
|
SHDebugDraw::PersistentLine
|
||||||
|
(
|
||||||
|
GRID_COL,
|
||||||
|
SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * DELTA },
|
||||||
|
SHVec3 { LINE_HALF_LENGTH, 0.0f, i * DELTA }
|
||||||
|
);
|
||||||
|
SHDebugDraw::PersistentLine
|
||||||
|
(
|
||||||
|
GRID_COL,
|
||||||
|
SHVec3 { -LINE_HALF_LENGTH, 0.0f, i * -DELTA },
|
||||||
|
SHVec3 { LINE_HALF_LENGTH, 0.0f, i * -DELTA }
|
||||||
|
);
|
||||||
|
// Y-Axis Lines
|
||||||
|
SHDebugDraw::PersistentLine
|
||||||
|
(
|
||||||
|
GRID_COL,
|
||||||
|
SHVec3 { i * DELTA, 0.0f, -LINE_HALF_LENGTH },
|
||||||
|
SHVec3 { i * DELTA, 0.0f, LINE_HALF_LENGTH }
|
||||||
|
);
|
||||||
|
SHDebugDraw::PersistentLine
|
||||||
|
(
|
||||||
|
GRID_COL,
|
||||||
|
SHVec3 { -i * DELTA, 0.0f, -LINE_HALF_LENGTH },
|
||||||
|
SHVec3 { -i * DELTA, 0.0f, LINE_HALF_LENGTH }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render World Axes
|
||||||
|
if (drawAxes || drawGrid)
|
||||||
|
{
|
||||||
|
const SHColour X_AXIS_COL = drawAxes ? SHColour::RED : GRID_COL;
|
||||||
|
const SHColour Y_AXIS_COL = drawAxes ? SHColour::GREEN : GRID_COL;
|
||||||
|
const SHColour Z_AXIS_COL = drawAxes ? SHColour::BLUE : GRID_COL;
|
||||||
|
// X
|
||||||
|
SHDebugDraw::PersistentLine
|
||||||
|
(
|
||||||
|
X_AXIS_COL,
|
||||||
|
SHVec3 { -LINE_HALF_LENGTH, 0.0f, 0.0f },
|
||||||
|
SHVec3 { LINE_HALF_LENGTH, 0.0f, 0.0f }
|
||||||
|
);
|
||||||
|
// Y
|
||||||
|
SHDebugDraw::PersistentLine
|
||||||
|
(
|
||||||
|
Y_AXIS_COL,
|
||||||
|
SHVec3 { 0.0f, -LINE_HALF_LENGTH, 0.0f },
|
||||||
|
SHVec3 { 0.0f, LINE_HALF_LENGTH, 0.0f }
|
||||||
|
);
|
||||||
|
// Z
|
||||||
|
SHDebugDraw::PersistentLine
|
||||||
|
(
|
||||||
|
Z_AXIS_COL,
|
||||||
|
SHVec3 { 0.0f, 0.0f, -LINE_HALF_LENGTH },
|
||||||
|
SHVec3 { 0.0f, 0.0f, LINE_HALF_LENGTH }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHEventHandle SHEditor::onEditorStateChanged(SHEventPtr eventPtr)
|
||||||
|
{
|
||||||
|
auto eventData = reinterpret_cast<const SHEventSpec<SHEditorStateChangeEvent>*>(eventPtr.get());
|
||||||
|
switch (editorState)
|
||||||
|
{
|
||||||
|
case State::PAUSE:
|
||||||
|
case State::STOP:
|
||||||
|
SetUpGridLines(true, true);
|
||||||
|
break;
|
||||||
|
case State::PLAY:
|
||||||
|
default:
|
||||||
|
SHDebugDraw::ClearPersistentDraws();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return eventData->handle;
|
||||||
|
}
|
||||||
|
|
||||||
void SHEditor::Exit()
|
void SHEditor::Exit()
|
||||||
{
|
{
|
||||||
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
||||||
|
|
|
@ -16,8 +16,9 @@
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#include "EditorWindow/SHEditorWindow.h"
|
#include "EditorWindow/SHEditorWindow.h"
|
||||||
#include "Tools/SHLog.h"
|
#include "Tools/SHLog.h"
|
||||||
#include "Gizmos/SHTransformGizmo.h"
|
#include "Gizmos/SHTransformGizmo.h"`
|
||||||
|
#include "Events/SHEventDefines.h"
|
||||||
|
#include "Events/SHEvent.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Library Includes ||
|
//|| Library Includes ||
|
||||||
|
@ -194,6 +195,10 @@ namespace SHADE
|
||||||
|
|
||||||
void InitFonts() noexcept;
|
void InitFonts() noexcept;
|
||||||
|
|
||||||
|
void SetUpGridLines(bool drawGrid, bool drawAxes);
|
||||||
|
|
||||||
|
SHEventHandle onEditorStateChanged(SHEventPtr eventPtr);
|
||||||
|
|
||||||
// Handle to command pool used for ImGui Vulkan Backend
|
// Handle to command pool used for ImGui Vulkan Backend
|
||||||
Handle<SHVkCommandPool> imguiCommandPool;
|
Handle<SHVkCommandPool> imguiCommandPool;
|
||||||
// Handle to command buffer used for ImGui Vulkan Backend
|
// Handle to command buffer used for ImGui Vulkan Backend
|
||||||
|
|
|
@ -157,7 +157,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::Checkbox("#", &value);
|
return ImGui::Checkbox("##", &value);
|
||||||
}
|
}
|
||||||
bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered)
|
bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered)
|
||||||
{
|
{
|
||||||
|
@ -165,7 +165,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputInt("#", &value,
|
return ImGui::InputInt("##", &value,
|
||||||
1, 10,
|
1, 10,
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
const bool CHANGED = InputInt("#", signedVal);
|
const bool CHANGED = InputInt("##", signedVal);
|
||||||
if (CHANGED)
|
if (CHANGED)
|
||||||
{
|
{
|
||||||
signedVal = std::clamp(signedVal, 0, std::numeric_limits<int>::max());
|
signedVal = std::clamp(signedVal, 0, std::numeric_limits<int>::max());
|
||||||
|
@ -190,7 +190,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputFloat("#", &value,
|
return ImGui::InputFloat("##", &value,
|
||||||
0.1f, 1.0f, "%.3f",
|
0.1f, 1.0f, "%.3f",
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputDouble("#", &value,
|
return ImGui::InputDouble("##", &value,
|
||||||
0.1, 1.0, "%.3f",
|
0.1, 1.0, "%.3f",
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
return ImGui::InputDouble("#", &value,
|
return ImGui::InputDouble("##", &value,
|
||||||
1.0, 45.0, "%.3f",
|
1.0, 45.0, "%.3f",
|
||||||
ImGuiInputTextFlags_EnterReturnsTrue);
|
ImGuiInputTextFlags_EnterReturnsTrue);
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
const bool CHANGED = ImGui::InputText("#", &buffer[0], TEXT_FIELD_MAX_LENGTH);
|
const bool CHANGED = ImGui::InputText("##", &buffer[0], TEXT_FIELD_MAX_LENGTH);
|
||||||
if (CHANGED)
|
if (CHANGED)
|
||||||
{
|
{
|
||||||
value = std::string(buffer.data(), buffer.data() + TEXT_FIELD_MAX_LENGTH);
|
value = std::string(buffer.data(), buffer.data() + TEXT_FIELD_MAX_LENGTH);
|
||||||
|
@ -327,7 +327,7 @@ namespace SHADE
|
||||||
if (isHovered)
|
if (isHovered)
|
||||||
*isHovered = ImGui::IsItemHovered();
|
*isHovered = ImGui::IsItemHovered();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::BeginCombo("#", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
|
if (ImGui::BeginCombo("##", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < enumNames.size(); ++i)
|
for (int i = 0; i < enumNames.size(); ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,6 +64,11 @@ namespace SHADE
|
||||||
return bufferUsageFlags;
|
return bufferUsageFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SHVkBuffer::GetSizeStored(void) const noexcept
|
||||||
|
{
|
||||||
|
return sizeStored;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
|
@ -102,8 +102,9 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
vk::Buffer GetVkBuffer (void) const noexcept;
|
vk::Buffer GetVkBuffer (void) const noexcept;
|
||||||
vk::BufferUsageFlags GetUsageBits(void) const noexcept;
|
vk::BufferUsageFlags GetUsageBits(void) const noexcept;
|
||||||
|
uint32_t GetSizeStored (void) const noexcept;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T GetDataFromMappedPointer(uint32_t index) const noexcept
|
T GetDataFromMappedPointer(uint32_t index) const noexcept
|
||||||
|
|
|
@ -119,6 +119,18 @@ namespace SHADE
|
||||||
return setIndex;
|
return setIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SHVkDescriptorSetLayout::GetNumDynamicOffsetsRequired(void) const noexcept
|
||||||
|
{
|
||||||
|
uint32_t numDynamicBindings = 0;
|
||||||
|
for (auto& binding : layoutDesc)
|
||||||
|
{
|
||||||
|
if (binding.Type == vk::DescriptorType::eUniformBufferDynamic || binding.Type == vk::DescriptorType::eStorageBufferDynamic)
|
||||||
|
++numDynamicBindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
return numDynamicBindings;
|
||||||
|
}
|
||||||
|
|
||||||
SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept
|
SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept
|
||||||
{
|
{
|
||||||
if (&rhs == this)
|
if (&rhs == this)
|
||||||
|
|
|
@ -99,6 +99,7 @@ namespace SHADE
|
||||||
inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; }
|
inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; }
|
||||||
std::vector<Binding> const& GetBindings (void) const noexcept;
|
std::vector<Binding> const& GetBindings (void) const noexcept;
|
||||||
SetIndex GetSetIndex (void) const noexcept;
|
SetIndex GetSetIndex (void) const noexcept;
|
||||||
|
uint32_t GetNumDynamicOffsetsRequired (void) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace SHADE
|
||||||
SHVkDescriptorSetLayout::Binding cameraDataBinding
|
SHVkDescriptorSetLayout::Binding cameraDataBinding
|
||||||
{
|
{
|
||||||
.Type = vk::DescriptorType::eUniformBufferDynamic,
|
.Type = vk::DescriptorType::eUniformBufferDynamic,
|
||||||
.Stage = vk::ShaderStageFlagBits::eVertex,
|
.Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eCompute,
|
||||||
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA,
|
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA,
|
||||||
.DescriptorCount = 1,
|
.DescriptorCount = 1,
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,20 +43,41 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the system
|
||||||
|
SHDebugDrawSystem* system = static_cast<SHDebugDrawSystem*>(GetSystem());
|
||||||
|
|
||||||
// Get current frame index
|
// Get current frame index
|
||||||
const uint32_t FRAME_IDX = gfxSys->GetCurrentFrameIndex();
|
const uint32_t FRAME_IDX = gfxSys->GetCurrentFrameIndex();
|
||||||
|
|
||||||
// Create the buffer if it doesn't exist or just update it
|
/* Non-Persistent Buffer */
|
||||||
SHDebugDrawSystem* system = static_cast<SHDebugDrawSystem*>(GetSystem());
|
// Update the buffer
|
||||||
system->numPoints[FRAME_IDX] = system->points.size();
|
system->numPoints[FRAME_IDX] = system->points.size();
|
||||||
const uint32_t DATA_SIZE = sizeof(PointVertex) * system->points.size();
|
const uint32_t DATA_SIZE = sizeof(PointVertex) * system->points.size();
|
||||||
if (DATA_SIZE > 0)
|
if (DATA_SIZE > 0)
|
||||||
{
|
{
|
||||||
system->vertexBuffers[FRAME_IDX]->WriteToMemory(system->points.data(), DATA_SIZE, 0, 0);
|
system->vertexBuffers[FRAME_IDX]->WriteToMemory(system->points.data(), DATA_SIZE, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset for next frame
|
// Reset for next frame
|
||||||
system->points.clear();
|
system->points.clear();
|
||||||
|
|
||||||
|
/* Persistent Buffer */
|
||||||
|
// Check if there are changes
|
||||||
|
if (system->persistentBuffersCleared[FRAME_IDX]
|
||||||
|
||
|
||||||
|
system->numPersistentPoints[FRAME_IDX] != system->persistentPoints.size())
|
||||||
|
{
|
||||||
|
// Update Buffer
|
||||||
|
system->numPersistentPoints[FRAME_IDX] = system->persistentPoints.size();
|
||||||
|
const uint32_t DATA_SIZE = sizeof(PointVertex) * system->persistentPoints.size();
|
||||||
|
if (DATA_SIZE > 0)
|
||||||
|
{
|
||||||
|
system->persistentVertexBuffers[FRAME_IDX]->WriteToMemory(system->persistentPoints.data(), DATA_SIZE, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset Flag
|
||||||
|
system->persistentBuffersCleared[FRAME_IDX] = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -75,31 +96,63 @@ namespace SHADE
|
||||||
const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex();
|
const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex();
|
||||||
|
|
||||||
// Don't draw if no points
|
// Don't draw if no points
|
||||||
if (numPoints[FRAME_IDX] <= 0)
|
if (numPoints[FRAME_IDX] > 0)
|
||||||
return;
|
{
|
||||||
|
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline());
|
||||||
|
cmdBuffer->SetLineWidth(LineWidth);
|
||||||
|
cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0);
|
||||||
|
cmdBuffer->DrawArrays(numPoints[FRAME_IDX], 1, 0, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth");
|
||||||
|
subPassWithDepth->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle<SHVkCommandBuffer>& cmdBuffer)
|
||||||
|
{
|
||||||
|
// Get Current frame index
|
||||||
|
const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex();
|
||||||
|
|
||||||
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawPipeline());
|
// Don't draw if no points
|
||||||
cmdBuffer->SetLineWidth(LineWidth);
|
if (numPersistentPoints[FRAME_IDX] > 0)
|
||||||
cmdBuffer->BindVertexBuffer(0, vertexBuffers[FRAME_IDX], 0);
|
{
|
||||||
cmdBuffer->DrawArrays(numPoints[FRAME_IDX], 1, 0, 0);
|
cmdBuffer->BindPipeline(GFX_SYSTEM->GetDebugDrawDepthPipeline());
|
||||||
|
cmdBuffer->SetLineWidth(LineWidth);
|
||||||
|
cmdBuffer->BindVertexBuffer(0, persistentVertexBuffers[FRAME_IDX], 0);
|
||||||
|
cmdBuffer->DrawArrays(numPersistentPoints[FRAME_IDX], 1, 0, 0);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Reset trackers
|
// Reset trackers
|
||||||
std::fill_n(numPoints.begin(), numPoints.size(), 0);
|
std::fill_n(numPoints.begin(), numPoints.size(), 0);
|
||||||
|
std::fill_n(numPersistentPoints.begin(), numPersistentPoints.size(), 0);
|
||||||
|
for (bool& cleared : persistentBuffersCleared)
|
||||||
|
cleared = true;
|
||||||
|
|
||||||
// Allocate buffers
|
// Allocate buffers
|
||||||
|
// - Non-Persistent Draws
|
||||||
static constexpr uint32_t BUFFER_SIZE = MAX_POINTS * sizeof(PointVertex);
|
static constexpr uint32_t BUFFER_SIZE = MAX_POINTS * sizeof(PointVertex);
|
||||||
for (Handle<SHVkBuffer>& bufHandle : vertexBuffers)
|
for (Handle<SHVkBuffer>& bufHandle : vertexBuffers)
|
||||||
{
|
{
|
||||||
bufHandle = GFX_SYSTEM->GetDevice()->CreateBuffer
|
bufHandle = GFX_SYSTEM->GetDevice()->CreateBuffer
|
||||||
(
|
(
|
||||||
BUFFER_SIZE,
|
BUFFER_SIZE,
|
||||||
nullptr,
|
nullptr,
|
||||||
0,
|
0,
|
||||||
vk::BufferUsageFlagBits::eVertexBuffer,
|
vk::BufferUsageFlagBits::eVertexBuffer,
|
||||||
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
|
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
|
||||||
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT
|
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
// - Persistent Draws
|
||||||
|
for (Handle<SHVkBuffer>& bufHandle : persistentVertexBuffers)
|
||||||
|
{
|
||||||
|
bufHandle = GFX_SYSTEM->GetDevice()->CreateBuffer
|
||||||
|
(
|
||||||
|
BUFFER_SIZE,
|
||||||
|
nullptr,
|
||||||
|
0,
|
||||||
|
vk::BufferUsageFlagBits::eVertexBuffer,
|
||||||
|
VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO,
|
||||||
|
VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +163,11 @@ namespace SHADE
|
||||||
if (vertexBuffer)
|
if (vertexBuffer)
|
||||||
vertexBuffer.Free();
|
vertexBuffer.Free();
|
||||||
}
|
}
|
||||||
|
for (auto vertexBuffer : persistentVertexBuffers)
|
||||||
|
{
|
||||||
|
if (vertexBuffer)
|
||||||
|
vertexBuffer.Free();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -117,54 +175,120 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
void SHDebugDrawSystem::DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
|
void SHDebugDrawSystem::DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
|
||||||
{
|
{
|
||||||
if (points.size() > MAX_POINTS)
|
drawLine(points, color, startPt, endPt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3)
|
||||||
|
{
|
||||||
|
drawPoly(points, color, { pt1, pt2, pt3 });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4)
|
||||||
|
{
|
||||||
|
drawPoly(points, color, { pt1, pt2, pt3, pt4 });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList)
|
||||||
|
{
|
||||||
|
drawPoly(points, color, pointList.begin(), pointList.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size)
|
||||||
|
{
|
||||||
|
drawCube(points, color, pos, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawSphere(const SHVec4& color, const SHVec3& pos, double radius)
|
||||||
|
{
|
||||||
|
drawSphere(points, color, pos, radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Persistent Draw Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void SHDebugDrawSystem::DrawPersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
|
||||||
|
{
|
||||||
|
drawLine(persistentPoints, color, startPt, endPt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawPersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3)
|
||||||
|
{
|
||||||
|
drawPoly(persistentPoints, color, { pt1, pt2, pt3 });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawPersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4)
|
||||||
|
{
|
||||||
|
drawPoly(persistentPoints, color, { pt1, pt2, pt3, pt4 });
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawPersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList)
|
||||||
|
{
|
||||||
|
drawPoly(persistentPoints, color, pointList.begin(), pointList.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawPersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size)
|
||||||
|
{
|
||||||
|
drawCube(persistentPoints, color, pos, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::DrawPersistentSphere(const SHVec4& color, const SHVec3& pos, double radius)
|
||||||
|
{
|
||||||
|
drawSphere(persistentPoints, color, pos, radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::ClearPersistentDraws()
|
||||||
|
{
|
||||||
|
persistentPoints.clear();
|
||||||
|
for (bool& cleared : persistentBuffersCleared)
|
||||||
|
cleared = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDrawSystem::drawLine(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
|
||||||
|
{
|
||||||
|
if (storage.size() > MAX_POINTS)
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
|
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
points.emplace_back(PointVertex{ startPt, color });
|
storage.emplace_back(PointVertex{ startPt, color });
|
||||||
points.emplace_back(PointVertex{ endPt, color });
|
storage.emplace_back(PointVertex{ endPt, color });
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHDebugDrawSystem::DrawTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3)
|
void SHDebugDrawSystem::drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList)
|
||||||
{
|
{
|
||||||
DrawPoly(color, { pt1, pt2, pt3 });
|
drawLineSet(storage, color, pointList.begin(), pointList.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHDebugDrawSystem::DrawQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4)
|
void SHDebugDrawSystem::drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList)
|
||||||
{
|
{
|
||||||
DrawPoly(color, { pt1, pt2, pt3, pt4 });
|
drawPoly(storage, color, pointList.begin(), pointList.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHDebugDrawSystem::DrawPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList)
|
void SHDebugDrawSystem::drawCube(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, const SHVec3& size)
|
||||||
{
|
{
|
||||||
DrawPoly(color, pointList.begin(), pointList.end());
|
static const SHVec3 EXTENTS = SHVec3{ 0.5f, 0.5f, 0.5f };
|
||||||
}
|
static const SHVec3 UNIT_BOT_LEFT_FRONT = SHVec3{ pos - EXTENTS };
|
||||||
|
static const SHVec3 UNIT_BOT_RIGHT_FRONT = SHVec3{ pos + SHVec3 { EXTENTS.x, -EXTENTS.y, -EXTENTS.z } };
|
||||||
|
static const SHVec3 UNIT_BOT_RIGHT_BACK = SHVec3{ pos + SHVec3 { EXTENTS.x, -EXTENTS.y, EXTENTS.z } };
|
||||||
|
static const SHVec3 UNIT_BOT_LEFT_BACK = SHVec3{ pos + SHVec3 { -EXTENTS.x, -EXTENTS.y, EXTENTS.z } };
|
||||||
|
static const SHVec3 UNIT_TOP_LEFT_BACK = SHVec3{ pos + SHVec3 { -EXTENTS.x, EXTENTS.y, EXTENTS.z } };
|
||||||
|
static const SHVec3 UNIT_TOP_RIGHT_FRONT = SHVec3{ pos + SHVec3 { EXTENTS.x, EXTENTS.y, -EXTENTS.z } };
|
||||||
|
static const SHVec3 UNIT_TOP_LEFT_FRONT = SHVec3{ pos + SHVec3 { -EXTENTS.x, EXTENTS.y, -EXTENTS.z } };
|
||||||
|
static const SHVec3 UNIT_TOP_RIGHT_BACK = SHVec3{ pos + EXTENTS };
|
||||||
|
|
||||||
void SHDebugDrawSystem::DrawCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size)
|
const SHVec3 BOT_LEFT_BACK = UNIT_BOT_LEFT_BACK * size;
|
||||||
{
|
const SHVec3 BOT_RIGHT_BACK = UNIT_BOT_RIGHT_BACK * size;
|
||||||
static const SHVec3 EXTENTS = SHVec3 { 0.5f, 0.5f, 0.5f };
|
const SHVec3 BOT_LEFT_FRONT = UNIT_BOT_LEFT_FRONT * size;
|
||||||
static const SHVec3 UNIT_BOT_LEFT_FRONT = SHVec3 { pos - EXTENTS };
|
|
||||||
static const SHVec3 UNIT_BOT_RIGHT_FRONT = SHVec3 { pos + SHVec3 { EXTENTS.x, -EXTENTS.y, -EXTENTS.z } };
|
|
||||||
static const SHVec3 UNIT_BOT_RIGHT_BACK = SHVec3 { pos + SHVec3 { EXTENTS.x, -EXTENTS.y, EXTENTS.z } };
|
|
||||||
static const SHVec3 UNIT_BOT_LEFT_BACK = SHVec3 { pos + SHVec3 { -EXTENTS.x, -EXTENTS.y, EXTENTS.z } };
|
|
||||||
static const SHVec3 UNIT_TOP_LEFT_BACK = SHVec3 { pos + SHVec3 { -EXTENTS.x, EXTENTS.y, EXTENTS.z } };
|
|
||||||
static const SHVec3 UNIT_TOP_RIGHT_FRONT = SHVec3 { pos + SHVec3 { EXTENTS.x, EXTENTS.y, -EXTENTS.z } };
|
|
||||||
static const SHVec3 UNIT_TOP_LEFT_FRONT = SHVec3 { pos + SHVec3 { -EXTENTS.x, EXTENTS.y, -EXTENTS.z } };
|
|
||||||
static const SHVec3 UNIT_TOP_RIGHT_BACK = SHVec3 { pos + EXTENTS };
|
|
||||||
|
|
||||||
const SHVec3 BOT_LEFT_BACK = UNIT_BOT_LEFT_BACK * size;
|
|
||||||
const SHVec3 BOT_RIGHT_BACK = UNIT_BOT_RIGHT_BACK * size;
|
|
||||||
const SHVec3 BOT_LEFT_FRONT = UNIT_BOT_LEFT_FRONT * size;
|
|
||||||
const SHVec3 BOT_RIGHT_FRONT = UNIT_BOT_RIGHT_FRONT * size;
|
const SHVec3 BOT_RIGHT_FRONT = UNIT_BOT_RIGHT_FRONT * size;
|
||||||
const SHVec3 TOP_LEFT_BACK = UNIT_TOP_LEFT_BACK * size;
|
const SHVec3 TOP_LEFT_BACK = UNIT_TOP_LEFT_BACK * size;
|
||||||
const SHVec3 TOP_RIGHT_BACK = UNIT_TOP_RIGHT_BACK * size;
|
const SHVec3 TOP_RIGHT_BACK = UNIT_TOP_RIGHT_BACK * size;
|
||||||
const SHVec3 TOP_LEFT_FRONT = UNIT_TOP_LEFT_FRONT * size;
|
const SHVec3 TOP_LEFT_FRONT = UNIT_TOP_LEFT_FRONT * size;
|
||||||
const SHVec3 TOP_RIGHT_FRONT = UNIT_TOP_RIGHT_FRONT * size;
|
const SHVec3 TOP_RIGHT_FRONT = UNIT_TOP_RIGHT_FRONT * size;
|
||||||
|
|
||||||
DrawPoly
|
drawLineSet
|
||||||
(
|
(
|
||||||
|
storage,
|
||||||
color,
|
color,
|
||||||
{
|
{
|
||||||
// Bottom Square
|
// Bottom Square
|
||||||
|
@ -186,7 +310,7 @@ namespace SHADE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHDebugDrawSystem::DrawSphere(const SHVec4& color, const SHVec3& pos, double radius)
|
void SHDebugDrawSystem::drawSphere(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, double radius)
|
||||||
{
|
{
|
||||||
if (spherePoints.empty())
|
if (spherePoints.empty())
|
||||||
{
|
{
|
||||||
|
@ -197,6 +321,6 @@ namespace SHADE
|
||||||
spherePoints.emplace_back(SPHERE.VertexPositions[idx]);
|
spherePoints.emplace_back(SPHERE.VertexPositions[idx]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DrawPoly(color, spherePoints.begin(), spherePoints.end());
|
drawLineSet(storage, color, spherePoints.begin(), spherePoints.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -126,6 +126,82 @@ namespace SHADE
|
||||||
/// <param name="size">Size of the rendered sphere.</param>
|
/// <param name="size">Size of the rendered sphere.</param>
|
||||||
void DrawSphere(const SHVec4& color, const SHVec3& pos, double radius);
|
void DrawSphere(const SHVec4& color, const SHVec3& pos, double radius);
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Persistent Draw Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a line between two points in world space that will persist until
|
||||||
|
/// ClearPersistentDraws() is called. These lines are depth tested.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the line.</param>
|
||||||
|
/// <param name="startPt">First point of the line.</param>
|
||||||
|
/// <param name="endPt">Second point of the line.</param>
|
||||||
|
void DrawPersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a triangle indicated by three points in world space that will persist
|
||||||
|
/// until ClearPersistentDraws() is called. These lines are depth tested.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the triangle.</param>
|
||||||
|
/// <param name="pt1">First point of the triangle.</param>
|
||||||
|
/// <param name="pt2">Second point of the triangle.</param>
|
||||||
|
/// <param name="pt3">Third point of the triangle.</param>
|
||||||
|
void DrawPersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a quadrilateral indicated by four points in world space that will persist
|
||||||
|
/// until ClearPersistentDraws() is called. These lines are depth tested.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the quadrilateral.</param>
|
||||||
|
/// <param name="pt1">First point of the triangle.</param>
|
||||||
|
/// <param name="pt2">Second point of the quadrilateral.</param>
|
||||||
|
/// <param name="pt3">Third point of the quadrilateral.</param>
|
||||||
|
/// <param name="pt4">Third point of the quadrilateral.</param>
|
||||||
|
void DrawPersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a polygon indicated by the specified set of points in world space that
|
||||||
|
/// will persist until ClearPersistentDraws() is called. These lines are depth
|
||||||
|
/// tested.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the polygon.</param>
|
||||||
|
/// <param name="pointList">List of points for the polygon.</param>
|
||||||
|
void DrawPersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a polygon indicated by the specified set of points in world space that
|
||||||
|
/// will persist until ClearPersistentDraws() is called. These lines are depth
|
||||||
|
/// tested.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="IterType">Iterator for a STL-like container.</typeparam>
|
||||||
|
/// <param name="color">Colour of the polygon.</param>
|
||||||
|
/// <param name="pointListBegin">
|
||||||
|
/// Iterator to the first point of the point container.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="pointListEnd">
|
||||||
|
/// One past last iterator of the point container.
|
||||||
|
/// </param>
|
||||||
|
template<typename IterType>
|
||||||
|
void DrawPersistentPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a wireframe cube centered around the position specified in world space
|
||||||
|
/// that will persist until ClearPersistentDraws() is called. These lines are depth
|
||||||
|
/// tested.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the cube.</param>
|
||||||
|
/// <param name="pos">Position where the cube wil be centered at.</param>
|
||||||
|
/// <param name="size">Size of the rendered cube.</param>
|
||||||
|
void DrawPersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a wireframe sphere centered around the position specified in world space
|
||||||
|
/// that will persist until ClearPersistentDraws() is called. These lines are depth
|
||||||
|
/// tested.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the sphere.</param>
|
||||||
|
/// <param name="pos">Position where the sphere wil be centered at.</param>
|
||||||
|
/// <param name="size">Size of the rendered sphere.</param>
|
||||||
|
void DrawPersistentSphere(const SHVec4& color, const SHVec3& pos, double radius);
|
||||||
|
/// <summary>
|
||||||
|
/// Clears any persistent drawn debug primitives.
|
||||||
|
/// </summary>
|
||||||
|
void ClearPersistentDraws();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
|
@ -136,7 +212,8 @@ namespace SHADE
|
||||||
SHVec4 Color;
|
SHVec4 Color;
|
||||||
};
|
};
|
||||||
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
|
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
|
||||||
using TripleUInt = std::array<uint32_t, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
|
using TripleUInt = std::array<uint32_t , SHGraphicsConstants::NUM_FRAME_BUFFERS>;
|
||||||
|
using TripleBool = std::array<bool , SHGraphicsConstants::NUM_FRAME_BUFFERS>;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Constants */
|
/* Constants */
|
||||||
|
@ -148,11 +225,28 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
// CPU Buffers
|
// CPU Buffers
|
||||||
std::vector<PointVertex> points;
|
std::vector<PointVertex> points;
|
||||||
|
std::vector<PointVertex> persistentPoints;
|
||||||
// GPU Buffers
|
// GPU Buffers
|
||||||
TripleBuffer vertexBuffers;
|
TripleBuffer vertexBuffers;
|
||||||
TripleUInt numPoints;
|
TripleUInt numPoints;
|
||||||
|
TripleBuffer persistentVertexBuffers;
|
||||||
|
TripleUInt numPersistentPoints;
|
||||||
|
TripleBool persistentBuffersCleared;
|
||||||
// Cached Points for polygon drawing
|
// Cached Points for polygon drawing
|
||||||
std::vector<SHVec3> spherePoints;
|
std::vector<SHVec3> spherePoints;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Draw Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void drawLine(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt);
|
||||||
|
void drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList);
|
||||||
|
template<typename IterType>
|
||||||
|
void drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd);
|
||||||
|
void drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList);
|
||||||
|
template<typename IterType>
|
||||||
|
void drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd);
|
||||||
|
void drawCube(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, const SHVec3& size);
|
||||||
|
void drawSphere(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, double radius);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,21 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
template<typename IterType>
|
template<typename IterType>
|
||||||
void SHDebugDrawSystem::DrawPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd)
|
void SHDebugDrawSystem::DrawPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd)
|
||||||
|
{
|
||||||
|
drawPoly(points, color, pointListBegin, pointListEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Draw Functions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
template<typename IterType>
|
||||||
|
void SHDebugDrawSystem::drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd)
|
||||||
{
|
{
|
||||||
// Ensure dereferenced type is SHVec3
|
// Ensure dereferenced type is SHVec3
|
||||||
static_assert(std::is_same_v<SHVec3, std::remove_cvref_t<decltype(*pointListBegin)>>, "Parameters to DrawPoly must be SHVec3.");
|
static_assert(std::is_same_v<SHVec3, std::remove_cvref_t<decltype(*pointListBegin)>>, "Parameters to DrawPoly must be SHVec3.");
|
||||||
|
|
||||||
// Check if points exceeded max
|
// Check if points exceeded max
|
||||||
if (points.size() > MAX_POINTS)
|
if (storage.size() > MAX_POINTS)
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
|
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
|
||||||
return;
|
return;
|
||||||
|
@ -42,7 +51,39 @@ namespace SHADE
|
||||||
const size_t POINTS_ROUNDED_COUNT = POINTS_COUNT / 2 * 2;
|
const size_t POINTS_ROUNDED_COUNT = POINTS_COUNT / 2 * 2;
|
||||||
for (auto pointIter = pointListBegin; pointIter != (pointListBegin + POINTS_ROUNDED_COUNT); ++pointIter)
|
for (auto pointIter = pointListBegin; pointIter != (pointListBegin + POINTS_ROUNDED_COUNT); ++pointIter)
|
||||||
{
|
{
|
||||||
points.emplace_back(PointVertex{ *pointIter, color });
|
storage.emplace_back(PointVertex{ *pointIter, color });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
template<typename IterType>
|
||||||
|
void SHDebugDrawSystem::drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, IterType pointListBegin, IterType pointListEnd)
|
||||||
|
{
|
||||||
|
// Ensure dereferenced type is SHVec3
|
||||||
|
static_assert(std::is_same_v<SHVec3, std::remove_cvref_t<decltype(*pointListBegin)>>, "Parameters to DrawPoly must be SHVec3.");
|
||||||
|
|
||||||
|
// Check if points exceeded max
|
||||||
|
if (storage.size() > MAX_POINTS)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[DebugDraw] Exceeded maximum size of drawable debug elements.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t POINTS_COUNT = pointListEnd - pointListBegin;
|
||||||
|
// Invalid polygon
|
||||||
|
if (POINTS_COUNT < 2)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("[SHDebugDraw] Invalid polygon provided to DrawPoly().");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trace the polygon
|
||||||
|
for (auto pointIter = pointListBegin + 1; pointIter != pointListEnd; ++pointIter)
|
||||||
|
{
|
||||||
|
storage.emplace_back(PointVertex{ *(pointIter - 1), color });
|
||||||
|
storage.emplace_back(PointVertex{ *pointIter , color });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the line loop
|
||||||
|
storage.emplace_back(PointVertex{ *(pointListEnd - 1), color });
|
||||||
|
storage.emplace_back(PointVertex{ *pointListBegin , color });
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -70,7 +70,17 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
static constexpr uint32_t RENDERGRAPH_RESOURCE = 4;
|
static constexpr uint32_t RENDERGRAPH_RESOURCE = 4;
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
DescriptorSet Index for render graph node compute resources. For data
|
||||||
|
that we wish to pass to compute shaders in the render graph, this is
|
||||||
|
the set to use. Unlike the sets from 1 to 3, this set index does not have
|
||||||
|
hard coded bindings and is NOT part of the layouts included in the global
|
||||||
|
data.
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr uint32_t RENDERGRAPH_NODE_COMPUTE_RESOURCE = 5;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -119,6 +129,7 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
static constexpr uint32_t BATCHED_PER_INST_DATA = 0;
|
static constexpr uint32_t BATCHED_PER_INST_DATA = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexBufferBindings
|
struct VertexBufferBindings
|
||||||
|
|
|
@ -40,6 +40,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Assets/SHAssetManager.h"
|
#include "Assets/SHAssetManager.h"
|
||||||
#include "Resource/SHResourceManager.h"
|
#include "Resource/SHResourceManager.h"
|
||||||
#include "Graphics/SHVkUtil.h"
|
#include "Graphics/SHVkUtil.h"
|
||||||
|
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -115,6 +116,8 @@ namespace SHADE
|
||||||
static constexpr AssetID VS_DEBUG = 48002439; debugVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEBUG);
|
static constexpr AssetID VS_DEBUG = 48002439; debugVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEBUG);
|
||||||
static constexpr AssetID FS_DEBUG = 36671027; debugFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEBUG);
|
static constexpr AssetID FS_DEBUG = 36671027; debugFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEBUG);
|
||||||
static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(CS_COMPOSITE);
|
static constexpr AssetID CS_COMPOSITE = 45072428; deferredCompositeShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(CS_COMPOSITE);
|
||||||
|
static constexpr AssetID SSAO = 38430899; ssaoShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO);
|
||||||
|
static constexpr AssetID SSAO_BLUR = 39760835; ssaoBlurShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(SSAO_BLUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
|
void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
|
||||||
|
@ -153,52 +156,109 @@ namespace SHADE
|
||||||
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
|
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* SCENE RENDER GRAPH RESOURCES */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
// Initialize world render graph
|
// Initialize world render graph
|
||||||
worldRenderGraph->Init(device, swapchain);
|
worldRenderGraph->Init(device, swapchain);
|
||||||
worldRenderGraph->AddResource("Position", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
worldRenderGraph->AddResource("Position", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
||||||
worldRenderGraph->AddResource("Normals", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
worldRenderGraph->AddResource("Normals", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
||||||
|
//worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
||||||
worldRenderGraph->AddResource("Albedo", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
worldRenderGraph->AddResource("Albedo", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
||||||
worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
||||||
worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||||
worldRenderGraph->AddResource("Light Layer Indices", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
worldRenderGraph->AddResource("Light Layer Indices", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||||
worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
||||||
|
worldRenderGraph->AddResource("SSAO", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
||||||
|
worldRenderGraph->AddResource("SSAO Blur", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* MAIN NODE */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
auto gBufferNode = worldRenderGraph->AddNode("G-Buffer",
|
auto gBufferNode = worldRenderGraph->AddNode("G-Buffer",
|
||||||
{
|
{
|
||||||
"Position",
|
"Position",
|
||||||
"Entity ID",
|
"Entity ID",
|
||||||
"Light Layer Indices",
|
"Light Layer Indices",
|
||||||
"Normals",
|
"Normals",
|
||||||
|
//"Tangents",
|
||||||
"Albedo",
|
"Albedo",
|
||||||
"Depth Buffer",
|
"Depth Buffer",
|
||||||
"Scene"
|
"Scene",
|
||||||
|
"SSAO",
|
||||||
|
"SSAO Blur"
|
||||||
},
|
},
|
||||||
{}); // no predecessors
|
{}); // no predecessors
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* G-BUFFER SUBPASS INIT */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
auto gBufferSubpass = gBufferNode->AddSubpass("G-Buffer Write");
|
auto gBufferSubpass = gBufferNode->AddSubpass("G-Buffer Write");
|
||||||
gBufferSubpass->AddColorOutput("Position");
|
gBufferSubpass->AddColorOutput("Position");
|
||||||
gBufferSubpass->AddColorOutput("Entity ID");
|
gBufferSubpass->AddColorOutput("Entity ID");
|
||||||
gBufferSubpass->AddColorOutput("Light Layer Indices");
|
gBufferSubpass->AddColorOutput("Light Layer Indices");
|
||||||
gBufferSubpass->AddColorOutput("Normals");
|
gBufferSubpass->AddColorOutput("Normals");
|
||||||
|
//gBufferSubpass->AddColorOutput("Tangents");
|
||||||
gBufferSubpass->AddColorOutput("Albedo");
|
gBufferSubpass->AddColorOutput("Albedo");
|
||||||
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
|
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
|
||||||
|
|
||||||
// deferred composite
|
/*-----------------------------------------------------------------------*/
|
||||||
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "Scene" });
|
/* SSAO PASS AND DATA INIT */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
ssaoStorage = resourceManager.Create<SHSSAO>();
|
||||||
|
|
||||||
// Set up Debug Draw Pass
|
ssaoTransferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
auto debugDrawNode = worldRenderGraph->AddNode("Debug Draw", { "Scene" }, {"G-Buffer"});
|
ssaoTransferCmdBuffer->BeginRecording();
|
||||||
|
|
||||||
|
ssaoStorage->Init(device, ssaoTransferCmdBuffer);
|
||||||
|
|
||||||
|
ssaoTransferCmdBuffer->EndRecording();
|
||||||
|
graphicsQueue->SubmitCommandBuffer({ ssaoTransferCmdBuffer });
|
||||||
|
// Set up Debug Draw Passes
|
||||||
|
// - Depth Tested
|
||||||
|
auto debugDrawNodeDepth = worldRenderGraph->AddNode("Debug Draw with Depth", { "Scene", "Depth Buffer" }, {"G-Buffer"});
|
||||||
|
auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth");
|
||||||
|
debugDrawDepthSubpass->AddColorOutput("Scene");
|
||||||
|
debugDrawDepthSubpass->AddDepthOutput("Depth Buffer");
|
||||||
|
// - No Depth Test
|
||||||
|
auto debugDrawNode = worldRenderGraph->AddNode("Debug Draw", { "Scene" }, { "Debug Draw with Depth" });
|
||||||
auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw");
|
auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw");
|
||||||
debugDrawSubpass->AddColorOutput("Scene");
|
debugDrawSubpass->AddColorOutput("Scene");
|
||||||
|
|
||||||
|
graphicsQueue->WaitIdle();
|
||||||
|
|
||||||
|
ssaoStorage->PrepareRotationVectorsVkData(device);
|
||||||
|
|
||||||
|
Handle<SHRenderGraphNodeCompute> ssaoPass = gBufferNode->AddNodeCompute(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();
|
||||||
|
|
||||||
|
ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1});
|
||||||
|
|
||||||
|
|
||||||
|
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute(ssaoBlurShader, { "SSAO", "SSAO Blur"});
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* DEFERRED COMPOSITE SUBPASS INIT */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" });
|
||||||
|
|
||||||
// Dummy Node
|
// Dummy Node
|
||||||
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors
|
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors
|
||||||
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass");
|
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass");
|
||||||
dummySubpass->AddInput("Scene");
|
dummySubpass->AddInput("Scene");
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* GENERATE RENDER GRAPH */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
// Generate world render graph
|
// Generate world render graph
|
||||||
worldRenderGraph->Generate();
|
worldRenderGraph->Generate();
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* BIND RENDER GRAPH TO RENDERER */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
// Add world renderer to default viewport
|
// Add world renderer to default viewport
|
||||||
worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
|
worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
|
||||||
worldRenderer->SetCamera(worldCamera);
|
worldRenderer->SetCamera(worldCamera);
|
||||||
|
@ -209,53 +269,8 @@ namespace SHADE
|
||||||
defaultMaterial = AddMaterial(defaultVertShader, defaultFragShader, gBufferSubpass);
|
defaultMaterial = AddMaterial(defaultVertShader, defaultFragShader, gBufferSubpass);
|
||||||
|
|
||||||
// Create debug draw pipeline
|
// Create debug draw pipeline
|
||||||
auto debugDrawPipelineLayout = resourceManager.Create<SHVkPipelineLayout>
|
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass);
|
||||||
(
|
debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass);
|
||||||
device, SHPipelineLayoutParams
|
|
||||||
{
|
|
||||||
.shaderModules = { debugVertShader, debugFragShader },
|
|
||||||
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
debugDrawPipeline = resourceManager.Create<SHVkPipeline>(device, debugDrawPipelineLayout, nullptr, debugDrawNode->GetRenderpass(), debugDrawSubpass);
|
|
||||||
debugDrawPipeline->GetPipelineState().SetRasterizationState(SHRasterizationState
|
|
||||||
{
|
|
||||||
.polygonMode = vk::PolygonMode::eLine,
|
|
||||||
.cull_mode = vk::CullModeFlagBits::eNone
|
|
||||||
});
|
|
||||||
debugDrawPipeline->GetPipelineState().SetInputAssemblyState(SHInputAssemblyState
|
|
||||||
{
|
|
||||||
.topology = vk::PrimitiveTopology::eLineList
|
|
||||||
});
|
|
||||||
|
|
||||||
SHVertexInputState debugDrawVertexInputState;
|
|
||||||
debugDrawVertexInputState.AddBinding(false, true, { SHVertexAttribute(SHAttribFormat::FLOAT_4D), SHVertexAttribute(SHAttribFormat::FLOAT_4D) });
|
|
||||||
debugDrawPipeline->GetPipelineState().SetVertexInputState(debugDrawVertexInputState);
|
|
||||||
SHColorBlendState colorBlendState{};
|
|
||||||
colorBlendState.logic_op_enable = VK_FALSE;
|
|
||||||
colorBlendState.logic_op = vk::LogicOp::eCopy;
|
|
||||||
|
|
||||||
auto const& subpassColorReferences = debugDrawSubpass->GetColorAttachmentReferences();
|
|
||||||
colorBlendState.attachments.reserve(subpassColorReferences.size());
|
|
||||||
|
|
||||||
for (auto& att : subpassColorReferences)
|
|
||||||
{
|
|
||||||
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
|
|
||||||
{
|
|
||||||
.blendEnable = SHVkUtil::IsBlendCompatible(debugDrawSubpass->GetFormatFromAttachmentReference(att.attachment)),
|
|
||||||
.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,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
debugDrawPipeline->GetPipelineState().SetColorBlenState(colorBlendState);
|
|
||||||
debugDrawPipeline->ConstructPipeline();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
|
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
|
||||||
|
@ -294,6 +309,7 @@ namespace SHADE
|
||||||
|
|
||||||
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
|
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
|
||||||
lightingSubSystem->Init(device, descPool);
|
lightingSubSystem->Init(device, descPool);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
|
@ -399,6 +415,17 @@ namespace SHADE
|
||||||
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
#ifdef SHEDITOR
|
||||||
|
auto editorSystem = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
if (editorSystem->editorState != SHEditor::State::PLAY)
|
||||||
|
lightingSubSystem->Run(cameraSystem->GetEditorCamera()->GetViewMatrix(), frameIndex);
|
||||||
|
else
|
||||||
|
lightingSubSystem->Run(worldRenderer->GetCameraDirector()->GetViewMatrix(), frameIndex);
|
||||||
|
#else
|
||||||
|
lightingSubSystem->Run(worldRenderer->GetCameraDirector()->GetViewMatrix(), frameIndex);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// For every viewport
|
// For every viewport
|
||||||
for (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex)
|
for (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex)
|
||||||
|
@ -435,8 +462,7 @@ namespace SHADE
|
||||||
currentCmdBuffer->BindIndexBuffer(buffer, 0);
|
currentCmdBuffer->BindIndexBuffer(buffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind the descriptor set for lights
|
lightingSubSystem->BindDescSet(currentCmdBuffer, frameIndex);
|
||||||
lightingSubSystem->Run(currentCmdBuffer, frameIndex);
|
|
||||||
|
|
||||||
// Bind textures
|
// Bind textures
|
||||||
auto textureDescSet = texLibrary.GetTextureDescriptorSetGroup();
|
auto textureDescSet = texLibrary.GetTextureDescriptorSetGroup();
|
||||||
|
@ -460,7 +486,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
auto editorSystem = SHSystemManager::GetSystem<SHEditor>();
|
auto editorSystem = SHSystemManager::GetSystem<SHEditor>();
|
||||||
if (editorSystem->editorState != SHEditor::State::PLAY)
|
if (editorSystem->editorState != SHEditor::State::PLAY)
|
||||||
worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, SHMatrix::Transpose(cameraSystem->GetEditorCamera()->GetProjMatrix() * cameraSystem->GetEditorCamera()->GetViewMatrix()));
|
worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, cameraSystem->GetEditorCamera()->GetViewMatrix(), cameraSystem->GetEditorCamera()->GetProjMatrix());
|
||||||
else
|
else
|
||||||
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
|
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
|
||||||
}
|
}
|
||||||
|
@ -867,5 +893,57 @@ namespace SHADE
|
||||||
return worldRenderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data());
|
return worldRenderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHVkPipeline> SHGraphicsSystem::createDebugDrawPipeline(Handle<SHVkRenderpass> renderPass, Handle<SHSubpass> subpass)
|
||||||
|
{
|
||||||
|
auto pipelineLayout = resourceManager.Create<SHVkPipelineLayout>
|
||||||
|
(
|
||||||
|
device, SHPipelineLayoutParams
|
||||||
|
{
|
||||||
|
.shaderModules = { debugVertShader, debugFragShader },
|
||||||
|
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
auto pipeline = resourceManager.Create<SHVkPipeline>(device, pipelineLayout, nullptr, renderPass, subpass);
|
||||||
|
pipeline->GetPipelineState().SetRasterizationState(SHRasterizationState
|
||||||
|
{
|
||||||
|
.polygonMode = vk::PolygonMode::eLine,
|
||||||
|
.cull_mode = vk::CullModeFlagBits::eNone
|
||||||
|
});
|
||||||
|
pipeline->GetPipelineState().SetInputAssemblyState(SHInputAssemblyState
|
||||||
|
{
|
||||||
|
.topology = vk::PrimitiveTopology::eLineList
|
||||||
|
});
|
||||||
|
|
||||||
|
SHVertexInputState debugDrawVertexInputState;
|
||||||
|
debugDrawVertexInputState.AddBinding(false, true, { SHVertexAttribute(SHAttribFormat::FLOAT_4D), SHVertexAttribute(SHAttribFormat::FLOAT_4D) });
|
||||||
|
pipeline->GetPipelineState().SetVertexInputState(debugDrawVertexInputState);
|
||||||
|
SHColorBlendState colorBlendState{};
|
||||||
|
colorBlendState.logic_op_enable = VK_FALSE;
|
||||||
|
colorBlendState.logic_op = vk::LogicOp::eCopy;
|
||||||
|
|
||||||
|
auto const& subpassColorReferences = subpass->GetColorAttachmentReferences();
|
||||||
|
colorBlendState.attachments.reserve(subpassColorReferences.size());
|
||||||
|
|
||||||
|
for (auto& att : subpassColorReferences)
|
||||||
|
{
|
||||||
|
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
|
||||||
|
{
|
||||||
|
.blendEnable = SHVkUtil::IsBlendCompatible(subpass->GetFormatFromAttachmentReference(att.attachment)),
|
||||||
|
.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);
|
||||||
|
pipeline->ConstructPipeline();
|
||||||
|
|
||||||
|
return pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma endregion MISC
|
#pragma endregion MISC
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "../Textures/SHVkSamplerCache.h"
|
#include "../Textures/SHVkSamplerCache.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h"
|
||||||
#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h"
|
#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h"
|
||||||
|
#include "Graphics/MiddleEnd/PostProcessing/SHSSAO.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -289,6 +290,7 @@ namespace SHADE
|
||||||
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
|
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
|
||||||
Handle<SHRenderGraphNode> GetPrimaryRenderpass() const noexcept;
|
Handle<SHRenderGraphNode> GetPrimaryRenderpass() const noexcept;
|
||||||
Handle<SHVkPipeline> GetDebugDrawPipeline(void) const noexcept { return debugDrawPipeline; }
|
Handle<SHVkPipeline> GetDebugDrawPipeline(void) const noexcept { return debugDrawPipeline; }
|
||||||
|
Handle<SHVkPipeline> GetDebugDrawDepthPipeline(void) const noexcept { return debugDrawDepthPipeline; }
|
||||||
uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); }
|
uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); }
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -315,6 +317,7 @@ namespace SHADE
|
||||||
Handle<SHVkDescriptorPool> descPool;
|
Handle<SHVkDescriptorPool> descPool;
|
||||||
Handle<SHVkCommandPool> graphicsCmdPool;
|
Handle<SHVkCommandPool> graphicsCmdPool;
|
||||||
Handle<SHVkCommandBuffer> transferCmdBuffer;
|
Handle<SHVkCommandBuffer> transferCmdBuffer;
|
||||||
|
Handle<SHVkCommandBuffer> ssaoTransferCmdBuffer;
|
||||||
Handle<SHVkCommandBuffer> graphicsTexCmdBuffer;
|
Handle<SHVkCommandBuffer> graphicsTexCmdBuffer;
|
||||||
SHRenderContext renderContext;
|
SHRenderContext renderContext;
|
||||||
std::array<Handle<SHVkSemaphore>, 2> graphSemaphores;
|
std::array<Handle<SHVkSemaphore>, 2> graphSemaphores;
|
||||||
|
@ -351,10 +354,14 @@ namespace SHADE
|
||||||
Handle<SHVkShaderModule> debugVertShader;
|
Handle<SHVkShaderModule> debugVertShader;
|
||||||
Handle<SHVkShaderModule> debugFragShader;
|
Handle<SHVkShaderModule> debugFragShader;
|
||||||
Handle<SHVkShaderModule> deferredCompositeShader;
|
Handle<SHVkShaderModule> deferredCompositeShader;
|
||||||
|
Handle<SHVkShaderModule> ssaoShader;
|
||||||
|
Handle<SHVkShaderModule> ssaoBlurShader;
|
||||||
|
|
||||||
|
|
||||||
// Built-In Materials
|
// Built-In Materials
|
||||||
Handle<SHMaterial> defaultMaterial;
|
Handle<SHMaterial> defaultMaterial;
|
||||||
Handle<SHVkPipeline> debugDrawPipeline;
|
Handle<SHVkPipeline> debugDrawPipeline;
|
||||||
|
Handle<SHVkPipeline> debugDrawDepthPipeline;
|
||||||
|
|
||||||
Handle<SHRenderGraph> worldRenderGraph;
|
Handle<SHRenderGraph> worldRenderGraph;
|
||||||
|
|
||||||
|
@ -362,10 +369,15 @@ namespace SHADE
|
||||||
Handle<SHMousePickSystem> mousePickSystem;
|
Handle<SHMousePickSystem> mousePickSystem;
|
||||||
Handle<SHPostOffscreenRenderSystem> postOffscreenRender;
|
Handle<SHPostOffscreenRenderSystem> postOffscreenRender;
|
||||||
Handle<SHLightingSubSystem> lightingSubSystem;
|
Handle<SHLightingSubSystem> lightingSubSystem;
|
||||||
|
Handle<SHSSAO> ssaoStorage;
|
||||||
|
|
||||||
uint32_t resizeWidth;
|
uint32_t resizeWidth = 1;
|
||||||
uint32_t resizeHeight;
|
uint32_t resizeHeight = 1;
|
||||||
bool restoredFromMinimize = false;
|
bool restoredFromMinimize = false;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
Handle<SHVkPipeline> createDebugDrawPipeline(Handle<SHVkRenderpass> renderPass, Handle<SHSubpass> subpass);
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -83,13 +83,14 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (camera && cameraDirector)
|
if (camera && cameraDirector)
|
||||||
{
|
{
|
||||||
UpdateDataAndBind(cmdBuffer, frameIndex, SHMatrix::Transpose(cameraDirector->GetVPMatrix()));
|
//UpdateDataAndBind(cmdBuffer, frameIndex, SHMatrix::Transpose(cameraDirector->GetVPMatrix()));
|
||||||
|
UpdateDataAndBind(cmdBuffer, frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetProjMatrix());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix exteriorMatrix) noexcept
|
void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept
|
||||||
{
|
{
|
||||||
SetViewProjectionMatrix(exteriorMatrix);
|
SetViewProjectionMatrix(viewMatrix, projMatrix);
|
||||||
|
|
||||||
//cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix();
|
//cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix();
|
||||||
cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex);
|
cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex);
|
||||||
|
@ -97,16 +98,19 @@ namespace SHADE
|
||||||
std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
|
std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
|
||||||
|
|
||||||
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
|
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
|
||||||
|
cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderer::UpdateCameraDataToBuffer(void) noexcept
|
void SHRenderer::UpdateCameraDataToBuffer(void) noexcept
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderer::SetViewProjectionMatrix(SHMatrix const& vpMatrix) noexcept
|
void SHRenderer::SetViewProjectionMatrix(SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept
|
||||||
{
|
{
|
||||||
//cpuCameraData.viewProjectionMatrix = camera->GetViewMatrix() * camera->GetProjectionMatrix();
|
//cpuCameraData.viewProjectionMatrix = camera->GetViewMatrix() * camera->GetProjectionMatrix();
|
||||||
cpuCameraData.viewProjectionMatrix = vpMatrix;
|
cpuCameraData.viewProjectionMatrix = SHMatrix::Transpose(projMatrix * viewMatrix);
|
||||||
|
cpuCameraData.viewMatrix = SHMatrix::Transpose(viewMatrix);
|
||||||
|
cpuCameraData.projectionMatrix = SHMatrix::Transpose(projMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHRenderGraph> SHRenderer::GetRenderGraph(void) const noexcept
|
Handle<SHRenderGraph> SHRenderer::GetRenderGraph(void) const noexcept
|
||||||
|
@ -119,4 +123,9 @@ namespace SHADE
|
||||||
return commandBuffers[frameIndex];
|
return commandBuffers[frameIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHCameraDirector> SHRenderer::GetCameraDirector(void) const noexcept
|
||||||
|
{
|
||||||
|
return cameraDirector;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,8 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHVec4 cameraPosition;
|
SHVec4 cameraPosition;
|
||||||
SHMatrix viewProjectionMatrix;
|
SHMatrix viewProjectionMatrix;
|
||||||
|
SHMatrix viewMatrix;
|
||||||
|
SHMatrix projectionMatrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -79,15 +81,16 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
void Draw(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept;
|
void Draw(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||||
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||||
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix exteriorMatrix) noexcept;
|
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept;
|
||||||
void UpdateCameraDataToBuffer (void) noexcept;
|
void UpdateCameraDataToBuffer (void) noexcept;
|
||||||
void SetViewProjectionMatrix (SHMatrix const& vpMatrix) noexcept;
|
void SetViewProjectionMatrix (SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Setters and Getters */
|
/* Setters and Getters */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHRenderGraph> GetRenderGraph (void) const noexcept;
|
Handle<SHRenderGraph> GetRenderGraph (void) const noexcept;
|
||||||
Handle<SHVkCommandBuffer> GetCommandBuffer(uint32_t frameIndex) const noexcept;
|
Handle<SHVkCommandBuffer> GetCommandBuffer(uint32_t frameIndex) const noexcept;
|
||||||
|
Handle<SHCameraDirector> GetCameraDirector (void) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -9,9 +9,9 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
lightData.Reset();
|
lightData.Reset();
|
||||||
SetType(SH_LIGHT_TYPE::DIRECTIONAL);
|
SetType(SH_LIGHT_TYPE::DIRECTIONAL);
|
||||||
indexInBuffer = std::numeric_limits<uint32_t>::max();
|
//indexInBuffer = std::numeric_limits<uint32_t>::max();
|
||||||
isActive = true;
|
isActive = true;
|
||||||
Unbind();
|
//Unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,28 +23,28 @@ namespace SHADE
|
||||||
void SHLightComponent::SetPosition(SHVec3 const& position) noexcept
|
void SHLightComponent::SetPosition(SHVec3 const& position) noexcept
|
||||||
{
|
{
|
||||||
lightData.position = position;
|
lightData.position = position;
|
||||||
MakeDirty();
|
//MakeDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHLightComponent::SetType(SH_LIGHT_TYPE type) noexcept
|
void SHLightComponent::SetType(SH_LIGHT_TYPE type) noexcept
|
||||||
{
|
{
|
||||||
lightData.type = type;
|
lightData.type = type;
|
||||||
MakeDirty();
|
//MakeDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHLightComponent::SetDirection(SHVec3 const& direction) noexcept
|
void SHLightComponent::SetDirection(SHVec3 const& direction) noexcept
|
||||||
{
|
{
|
||||||
lightData.direction = direction;
|
lightData.direction = direction;
|
||||||
MakeDirty();
|
//MakeDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHLightComponent::SetColor(SHVec4 const& color) noexcept
|
void SHLightComponent::SetColor(SHVec4 const& color) noexcept
|
||||||
{
|
{
|
||||||
lightData.color = color;
|
lightData.color = color;
|
||||||
MakeDirty();
|
//MakeDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHLightComponent::ModifyCullingMask(uint8_t layerIndex, bool value) noexcept
|
void SHLightComponent::ModifyCullingMask(uint8_t layerIndex, bool value) noexcept
|
||||||
|
@ -54,7 +54,7 @@ namespace SHADE
|
||||||
else
|
else
|
||||||
lightData.cullingMask &= ~(1u << layerIndex);
|
lightData.cullingMask &= ~(1u << layerIndex);
|
||||||
|
|
||||||
MakeDirty();
|
//MakeDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHLightComponent::SetCullingMask(uint32_t const& value) noexcept
|
void SHLightComponent::SetCullingMask(uint32_t const& value) noexcept
|
||||||
|
@ -65,43 +65,43 @@ namespace SHADE
|
||||||
void SHLightComponent::SetAllLayers(void) noexcept
|
void SHLightComponent::SetAllLayers(void) noexcept
|
||||||
{
|
{
|
||||||
lightData.cullingMask = std::numeric_limits<uint32_t>::max();
|
lightData.cullingMask = std::numeric_limits<uint32_t>::max();
|
||||||
MakeDirty();
|
//MakeDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHLightComponent::ClearAllLayers(void) noexcept
|
void SHLightComponent::ClearAllLayers(void) noexcept
|
||||||
{
|
{
|
||||||
lightData.cullingMask = 0;
|
lightData.cullingMask = 0;
|
||||||
MakeDirty();
|
//MakeDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHLightComponent::MakeDirty(void) noexcept
|
//void SHLightComponent::MakeDirty(void) noexcept
|
||||||
{
|
//{
|
||||||
dirty = true;
|
// dirty = true;
|
||||||
}
|
//}
|
||||||
|
|
||||||
void SHLightComponent::ClearDirtyFlag(void) noexcept
|
//void SHLightComponent::ClearDirtyFlag(void) noexcept
|
||||||
{
|
//{
|
||||||
dirty = false;
|
// dirty = false;
|
||||||
}
|
//}
|
||||||
|
|
||||||
void SHLightComponent::Unbind(void) noexcept
|
// void SHLightComponent::Unbind(void) noexcept
|
||||||
{
|
// {
|
||||||
bound = false;
|
// bound = false;
|
||||||
MakeDirty();
|
// MakeDirty();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
void SHLightComponent::SetBound(uint32_t inIndexInBuffer) noexcept
|
// void SHLightComponent::SetBound(uint32_t inIndexInBuffer) noexcept
|
||||||
{
|
//{
|
||||||
bound = true;
|
// bound = true;
|
||||||
indexInBuffer = inIndexInBuffer;
|
// indexInBuffer = inIndexInBuffer;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
void SHLightComponent::SetStrength(float value) noexcept
|
void SHLightComponent::SetStrength(float value) noexcept
|
||||||
{
|
{
|
||||||
lightData.strength = value;
|
lightData.strength = value;
|
||||||
MakeDirty();
|
//MakeDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
SHLightData const& SHLightComponent::GetLightData(void) const noexcept
|
SHLightData const& SHLightComponent::GetLightData(void) const noexcept
|
||||||
|
@ -135,20 +135,20 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SHLightComponent::IsDirty(void) const noexcept
|
//bool SHLightComponent::IsDirty(void) const noexcept
|
||||||
{
|
//{
|
||||||
return dirty;
|
// return dirty;
|
||||||
}
|
//}
|
||||||
|
|
||||||
bool SHLightComponent::GetBound(void) const noexcept
|
//bool SHLightComponent::GetBound(void) const noexcept
|
||||||
{
|
//{
|
||||||
return bound;
|
// return bound;
|
||||||
}
|
//}
|
||||||
|
|
||||||
uint32_t SHLightComponent::GetIndexInBuffer(void) const noexcept
|
//uint32_t SHLightComponent::GetIndexInBuffer(void) const noexcept
|
||||||
{
|
//{
|
||||||
return indexInBuffer;
|
// return indexInBuffer;
|
||||||
}
|
//}
|
||||||
|
|
||||||
float SHLightComponent::GetStrength(void) const noexcept
|
float SHLightComponent::GetStrength(void) const noexcept
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,13 +17,13 @@ namespace SHADE
|
||||||
//! Since the lighting system is gonna be self contained and light weight, we store this
|
//! Since the lighting system is gonna be self contained and light weight, we store this
|
||||||
//! so that we only write this to the CPU buffer when this light component change, we don't
|
//! so that we only write this to the CPU buffer when this light component change, we don't
|
||||||
//! rewrite everything. However we still write to the GPU buffer when everything changes.
|
//! rewrite everything. However we still write to the GPU buffer when everything changes.
|
||||||
uint32_t indexInBuffer;
|
//uint32_t indexInBuffer;
|
||||||
|
|
||||||
//! If the light component changed some value we mark this true.
|
////! If the light component changed some value we mark this true.
|
||||||
bool dirty;
|
//bool dirty;
|
||||||
|
|
||||||
//! If the light's data is already in the buffers, this will be set to true.
|
////! If the light's data is already in the buffers, this will be set to true.
|
||||||
bool bound;
|
//bool bound;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -44,10 +44,10 @@ namespace SHADE
|
||||||
void SetCullingMask (uint32_t const& value) noexcept;
|
void SetCullingMask (uint32_t const& value) noexcept;
|
||||||
void SetAllLayers (void) noexcept; // serialized
|
void SetAllLayers (void) noexcept; // serialized
|
||||||
void ClearAllLayers (void) noexcept; // serialized
|
void ClearAllLayers (void) noexcept; // serialized
|
||||||
void MakeDirty (void) noexcept;
|
//void MakeDirty (void) noexcept;
|
||||||
void ClearDirtyFlag (void) noexcept;
|
//void ClearDirtyFlag (void) noexcept;
|
||||||
void Unbind (void) noexcept;
|
//void Unbind (void) noexcept;
|
||||||
void SetBound (uint32_t inIndexInBuffer) noexcept;
|
//void SetBound (uint32_t inIndexInBuffer) noexcept;
|
||||||
void SetStrength (float value) noexcept; // serialized
|
void SetStrength (float value) noexcept; // serialized
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,8 +57,8 @@ namespace SHADE
|
||||||
SHVec3 const& GetDirection (void) const noexcept; // serialized
|
SHVec3 const& GetDirection (void) const noexcept; // serialized
|
||||||
SHVec4 const& GetColor (void) const noexcept; // serialized
|
SHVec4 const& GetColor (void) const noexcept; // serialized
|
||||||
uint32_t const& GetCullingMask (void) const noexcept; // serialized
|
uint32_t const& GetCullingMask (void) const noexcept; // serialized
|
||||||
bool IsDirty (void) const noexcept;
|
//bool IsDirty (void) const noexcept;
|
||||||
bool GetBound (void) const noexcept;
|
//bool GetBound (void) const noexcept;
|
||||||
uint32_t GetIndexInBuffer (void) const noexcept;
|
uint32_t GetIndexInBuffer (void) const noexcept;
|
||||||
float GetStrength (void) const noexcept;
|
float GetStrength (void) const noexcept;
|
||||||
RTTR_ENABLE()
|
RTTR_ENABLE()
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include "SHLightComponent.h"
|
#include "SHLightComponent.h"
|
||||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
#include "SHLightComponent.h"
|
#include "SHLightComponent.h"
|
||||||
|
#include "Math/Vector/SHVec4.h"
|
||||||
|
#include "Math/SHMatrix.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -31,7 +33,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHLightingSubSystem::PerTypeData::WriteLightToAddress(void* address, SHLightComponent* lightComp) noexcept
|
void SHLightingSubSystem::PerTypeData::WriteLightToAddress(void* address, SHMatrix const& viewMat, SHLightComponent* lightComp) noexcept
|
||||||
{
|
{
|
||||||
auto const& lightData = lightComp->GetLightData();
|
auto const& lightData = lightComp->GetLightData();
|
||||||
switch (lightData.type)
|
switch (lightData.type)
|
||||||
|
@ -40,8 +42,12 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHDirectionalLightData* lightPtr = reinterpret_cast<SHDirectionalLightData*>(address);
|
SHDirectionalLightData* lightPtr = reinterpret_cast<SHDirectionalLightData*>(address);
|
||||||
|
|
||||||
|
// #NoteToSelf: NEED TO TRANSPOSE HERE BECAUSE MULTIPLICATION IS ROW MAJOR.
|
||||||
|
SHVec4 transformedDir = SHMatrix::Transpose(viewMat) * SHVec4(lightData.direction[0], lightData.direction[1], lightData.direction[2], 0.0f);
|
||||||
|
|
||||||
lightPtr->cullingMask = lightData.cullingMask;
|
lightPtr->cullingMask = lightData.cullingMask;
|
||||||
lightPtr->direction = lightData.direction;
|
lightPtr->direction = SHVec3 (transformedDir.x, transformedDir.y, transformedDir.z);
|
||||||
|
//lightPtr->direction = lightData.direction;
|
||||||
lightPtr->diffuseColor = lightData.color;
|
lightPtr->diffuseColor = lightData.color;
|
||||||
lightPtr->active = lightComp->isActive;
|
lightPtr->active = lightComp->isActive;
|
||||||
break;
|
break;
|
||||||
|
@ -240,7 +246,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHLightingSubSystem::PerTypeData::AddLight(Handle<SHVkLogicalDevice> logicalDevice, SHLightComponent* unboundLight, bool expanded) noexcept
|
void SHLightingSubSystem::PerTypeData::AddLight(Handle<SHVkLogicalDevice> logicalDevice, SHLightComponent* unboundLight, SHMatrix const& viewMat, bool& expanded) noexcept
|
||||||
{
|
{
|
||||||
if (unboundLight)
|
if (unboundLight)
|
||||||
{
|
{
|
||||||
|
@ -259,10 +265,10 @@ namespace SHADE
|
||||||
void* writeLocation = reinterpret_cast<uint8_t*>(intermediateData.get()) + (lightDataAlignedSize * numLights);
|
void* writeLocation = reinterpret_cast<uint8_t*>(intermediateData.get()) + (lightDataAlignedSize * numLights);
|
||||||
|
|
||||||
// Write the light data to address
|
// Write the light data to address
|
||||||
WriteLightToAddress(writeLocation, unboundLight);
|
WriteLightToAddress(writeLocation, viewMat, unboundLight);
|
||||||
|
|
||||||
// Set the light component to be bound to that location
|
// Set the light component to be bound to that location
|
||||||
unboundLight->SetBound(numLights);
|
//unboundLight->SetBound(numLights);
|
||||||
|
|
||||||
// Increase light count
|
// Increase light count
|
||||||
++numLights;
|
++numLights;
|
||||||
|
@ -280,11 +286,11 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHLightingSubSystem::PerTypeData::ModifyLight(SHLightComponent* lightComp) noexcept
|
//void SHLightingSubSystem::PerTypeData::ModifyLight(SHLightComponent* lightComp) noexcept
|
||||||
{
|
//{
|
||||||
void* writeLocation = reinterpret_cast<uint8_t*>(intermediateData.get()) + (lightDataAlignedSize * lightComp->GetIndexInBuffer());
|
// void* writeLocation = reinterpret_cast<uint8_t*>(intermediateData.get()) + (lightDataAlignedSize * lightComp->GetIndexInBuffer());
|
||||||
WriteLightToAddress(writeLocation, lightComp);
|
// WriteLightToAddress(writeLocation, lightComp);
|
||||||
}
|
//}
|
||||||
|
|
||||||
void SHLightingSubSystem::PerTypeData::WriteToGPU(uint32_t frameIndex) noexcept
|
void SHLightingSubSystem::PerTypeData::WriteToGPU(uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
|
@ -406,7 +412,7 @@ namespace SHADE
|
||||||
dynamicOffsets[i].resize(NUM_LIGHT_TYPES + 1); // +1 for the count
|
dynamicOffsets[i].resize(NUM_LIGHT_TYPES + 1); // +1 for the count
|
||||||
}
|
}
|
||||||
|
|
||||||
numLightComponents = 0;
|
//numLightComponents = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -419,21 +425,25 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHLightingSubSystem::Run(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
void SHLightingSubSystem::Run(SHMatrix const& viewMat, uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
static uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES);
|
static uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ToUnderlying(SH_LIGHT_TYPE::NUM_TYPES);
|
||||||
|
|
||||||
auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
|
auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
|
||||||
bool expanded = false;
|
bool expanded = false;
|
||||||
bool rewrite = false;
|
|
||||||
|
|
||||||
if (numLightComponents > lightComps.size())
|
// First we reset the number of lights. We do this every frame so that we can count how many lights we have
|
||||||
{
|
ResetNumLights();
|
||||||
rewrite = true;
|
|
||||||
ResetNumLights();
|
|
||||||
}
|
|
||||||
|
|
||||||
numLightComponents = lightComps.size();
|
//bool rewrite = false;
|
||||||
|
|
||||||
|
//if (numLightComponents > lightComps.size())
|
||||||
|
//{
|
||||||
|
// rewrite = true;
|
||||||
|
// ResetNumLights();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//numLightComponents = lightComps.size();
|
||||||
|
|
||||||
for (auto& light : lightComps)
|
for (auto& light : lightComps)
|
||||||
{
|
{
|
||||||
|
@ -441,22 +451,22 @@ namespace SHADE
|
||||||
|
|
||||||
// First we want to make sure the light is already bound to the system. if it
|
// First we want to make sure the light is already bound to the system. if it
|
||||||
// isn't, we write it to the correct buffer.
|
// isn't, we write it to the correct buffer.
|
||||||
if (!light.GetBound() || rewrite)
|
//if (!light.GetBound() || rewrite)
|
||||||
{
|
{
|
||||||
perTypeData[enumValue].AddLight(logicalDevice, &light, expanded);
|
perTypeData[enumValue].AddLight(logicalDevice, &light, viewMat, expanded);
|
||||||
|
|
||||||
//// add to light count
|
// add to light count
|
||||||
//++lightCountsData[enumValue];
|
//++lightCountsData[enumValue];
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there was modification to the light data
|
// if there was modification to the light data
|
||||||
if (light.IsDirty())
|
//if (light.IsDirty())
|
||||||
{
|
{
|
||||||
// Write the data to the CPU
|
// Write the data to the CPU
|
||||||
perTypeData[enumValue].ModifyLight(&light);
|
//perTypeData[enumValue].ModifyLight(&light);
|
||||||
|
|
||||||
// Light is now updated in the container
|
// Light is now updated in the container
|
||||||
light.ClearDirtyFlag();
|
//light.ClearDirtyFlag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,8 +498,6 @@ namespace SHADE
|
||||||
// so we do it anyway. #NoteToSelf: if at any point it affects performance, do a check before computing.
|
// so we do it anyway. #NoteToSelf: if at any point it affects performance, do a check before computing.
|
||||||
ComputeDynamicOffsets();
|
ComputeDynamicOffsets();
|
||||||
|
|
||||||
// Bind descriptor set (We bind at an offset because the buffer holds NUM_FRAME_BUFFERS sets of data).
|
|
||||||
cmdBuffer->BindDescriptorSet(lightingDataDescSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, {dynamicOffsets[frameIndex]});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,4 +513,12 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHLightingSubSystem::BindDescSet(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
||||||
|
{
|
||||||
|
//Bind descriptor set(We bind at an offset because the buffer holds NUM_FRAME_BUFFERS sets of data).
|
||||||
|
cmdBuffer->BindDescriptorSet(lightingDataDescSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, { dynamicOffsets[frameIndex] });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,15 +95,15 @@ namespace SHADE
|
||||||
//! to the GPU that stores NUM_FRAME_BUFFERS copies.
|
//! to the GPU that stores NUM_FRAME_BUFFERS copies.
|
||||||
std::unique_ptr<uint8_t[]> intermediateData;
|
std::unique_ptr<uint8_t[]> intermediateData;
|
||||||
|
|
||||||
void WriteLightToAddress (void* address, SHLightComponent* lightComp) noexcept;
|
void WriteLightToAddress (void* address, SHMatrix const& viewMat, SHLightComponent* lightComp) noexcept;
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void InitializeData (Handle<SHVkLogicalDevice> logicalDevice, SH_LIGHT_TYPE type) noexcept;
|
void InitializeData (Handle<SHVkLogicalDevice> logicalDevice, SH_LIGHT_TYPE type) noexcept;
|
||||||
void Expand (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
void Expand (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||||
void AddLight (Handle<SHVkLogicalDevice> logicalDevice, SHLightComponent* unboundLight, bool expanded) noexcept;
|
void AddLight (Handle<SHVkLogicalDevice> logicalDevice, SHLightComponent* unboundLight, SHMatrix const& viewMat, bool& expanded) noexcept;
|
||||||
void ModifyLight (SHLightComponent* lightComp) noexcept;
|
//void ModifyLight (SHLightComponent* lightComp) noexcept;
|
||||||
void WriteToGPU (uint32_t frameIndex) noexcept;
|
void WriteToGPU (uint32_t frameIndex) noexcept;
|
||||||
void ResetNumLights (void) noexcept;
|
void ResetNumLights (void) noexcept;
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ namespace SHADE
|
||||||
//! Number of SHLightComponents recorded. If at the beginning of the run function the size returned by the dense
|
//! Number of SHLightComponents recorded. If at the beginning of the run function the size returned by the dense
|
||||||
//! set is less than the size recorded, rewrite all light components into the its respective buffers. If its more,
|
//! set is less than the size recorded, rewrite all light components into the its respective buffers. If its more,
|
||||||
//! don't do anything.
|
//! don't do anything.
|
||||||
uint32_t numLightComponents;
|
//uint32_t numLightComponents;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
|
@ -159,8 +159,10 @@ namespace SHADE
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void Init (Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool) noexcept;
|
void Init (Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||||
void Run (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept;
|
||||||
void Exit (void) noexcept;
|
void Exit (void) noexcept;
|
||||||
|
|
||||||
|
void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHSSAO.h"
|
||||||
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
|
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||||
|
#include "Graphics/Images/SHVkImage.h"
|
||||||
|
#include "Graphics/Images/SHVkSampler.h"
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
void SHSSAO::Init(Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkCommandBuffer> cmdBuffer) noexcept
|
||||||
|
{
|
||||||
|
// Initialize a distribution to get values from 0 to 1
|
||||||
|
std::uniform_real_distribution<float> distrib{0.0f, 1.0f};
|
||||||
|
|
||||||
|
// generator for random number
|
||||||
|
std::default_random_engine generator;
|
||||||
|
|
||||||
|
// generate samples
|
||||||
|
for (uint32_t i = 0; i < NUM_SAMPLES; ++i)
|
||||||
|
{
|
||||||
|
//SHVec3 temp
|
||||||
|
//{
|
||||||
|
// distrib(generator) * 2.0f - 1.0f, // -1.0f - 1.0f
|
||||||
|
// distrib(generator) * 2.0f - 1.0f, // -1.0f - 1.0f
|
||||||
|
// distrib(generator), // 0.0f - 1.0f so that sample space is a hemisphere
|
||||||
|
//};
|
||||||
|
|
||||||
|
//temp = SHVec3::Normalise(temp);
|
||||||
|
//temp *= distrib(generator);
|
||||||
|
|
||||||
|
//// This makes sure that most points are closer to fragment's position
|
||||||
|
//float scale = 1.0f / static_cast<float>(NUM_SAMPLES);
|
||||||
|
//scale = std::lerp(0.1f, 1.0f, scale * scale);
|
||||||
|
//temp *= scale;
|
||||||
|
//samples[i] = SHVec4 (temp.x, temp.y, temp.z, 0.0f);
|
||||||
|
|
||||||
|
|
||||||
|
samples[i] = SHVec4
|
||||||
|
{
|
||||||
|
distrib(generator) * 2.0f - 1.0f, // -1.0f - 1.0f
|
||||||
|
distrib(generator) * 2.0f - 1.0f, // -1.0f - 1.0f
|
||||||
|
distrib(generator), // 0.0f - 1.0f so that sample space is a hemisphere
|
||||||
|
0.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
// This makes sure that most points are closer to fragment's position
|
||||||
|
float scale = 1.0f / static_cast<float>(NUM_SAMPLES);
|
||||||
|
scale = std::lerp(0.1f, 1.0f, scale * scale);
|
||||||
|
samples[i] *= scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate rotation vector
|
||||||
|
for (uint32_t i = 0; i < NUM_ROTATION_VECTORS; ++i)
|
||||||
|
{
|
||||||
|
rotationVectors[i] = SHVec4
|
||||||
|
{
|
||||||
|
distrib(generator) * 2.0f - 1.0f, // -1.0f - 1.0f
|
||||||
|
distrib(generator) * 2.0f - 1.0f, // -1.0f - 1.0f
|
||||||
|
0.0f, // we want to rotate about the z axis in tangent space
|
||||||
|
0.0f
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SHImageCreateParams imageDetails =
|
||||||
|
{
|
||||||
|
.imageType = vk::ImageType::e2D,
|
||||||
|
.width = NUM_ROTATION_VECTORS_W,
|
||||||
|
.height = NUM_ROTATION_VECTORS_H,
|
||||||
|
.depth = 1,
|
||||||
|
.levels = 1,
|
||||||
|
.arrayLayers = 1,
|
||||||
|
.imageFormat = vk::Format::eR32G32B32A32Sfloat,
|
||||||
|
.usageFlags = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst,
|
||||||
|
.createFlags = {}
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t mipOffset = 0;
|
||||||
|
rotationVectorsImage = logicalDevice->CreateImage(imageDetails, reinterpret_cast<unsigned char*>( rotationVectors.data()), static_cast<uint32_t>(sizeof(rotationVectors)), {&mipOffset, 1}, VMA_MEMORY_USAGE_AUTO, {});
|
||||||
|
|
||||||
|
vk::ImageMemoryBarrier transferBarrier{};
|
||||||
|
rotationVectorsImage->PrepareImageTransitionInfo(vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal, transferBarrier);
|
||||||
|
|
||||||
|
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, {}, {}, {transferBarrier});
|
||||||
|
|
||||||
|
rotationVectorsImage->TransferToDeviceResource(cmdBuffer);
|
||||||
|
|
||||||
|
vk::ImageMemoryBarrier shaderReadBarrier{};
|
||||||
|
rotationVectorsImage->PrepareImageTransitionInfo(vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal, shaderReadBarrier);
|
||||||
|
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, { shaderReadBarrier });
|
||||||
|
|
||||||
|
|
||||||
|
// Get aligned size for buffer
|
||||||
|
uint32_t alignedSize = logicalDevice->PadSSBOSize(sizeof (samples));
|
||||||
|
|
||||||
|
// Create buffer
|
||||||
|
ssaoDataBuffer = logicalDevice->CreateBuffer(alignedSize, samples.data(), alignedSize, vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, {});
|
||||||
|
|
||||||
|
ssaoDataBuffer->TransferToDeviceResource(cmdBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSSAO::PrepareRotationVectorsVkData(Handle<SHVkLogicalDevice> logicalDevice) noexcept
|
||||||
|
{
|
||||||
|
SHImageViewDetails DETAILS =
|
||||||
|
{
|
||||||
|
.viewType = vk::ImageViewType::e2D,
|
||||||
|
.format = vk::Format::eR32G32B32A32Sfloat,
|
||||||
|
.imageAspectFlags = vk::ImageAspectFlagBits::eColor,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.mipLevelCount = 1,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1
|
||||||
|
};
|
||||||
|
rotationVectorsImageView = rotationVectorsImage->CreateImageView(logicalDevice, rotationVectorsImage, DETAILS);
|
||||||
|
|
||||||
|
SHVkSamplerParams samplerParams
|
||||||
|
{
|
||||||
|
.minFilter = vk::Filter::eNearest,
|
||||||
|
.magFilter = vk::Filter::eNearest,
|
||||||
|
.addressMode = vk::SamplerAddressMode::eRepeat,
|
||||||
|
.mipmapMode = vk::SamplerMipmapMode::eNearest,
|
||||||
|
.maxLod = 1u
|
||||||
|
};
|
||||||
|
|
||||||
|
rotationVectorsSampler = logicalDevice->CreateSampler(samplerParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVkDescriptorSetGroup::viewSamplerLayout SHSSAO::GetViewSamplerLayout(void) const noexcept
|
||||||
|
{
|
||||||
|
return std::make_tuple(rotationVectorsImageView, rotationVectorsSampler, vk::ImageLayout::eShaderReadOnlyOptimal);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHVkBuffer> SHSSAO::GetBuffer(void) const noexcept
|
||||||
|
{
|
||||||
|
return ssaoDataBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Resource/SHHandle.h"
|
||||||
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
|
#include "Math/Vector/SHVec4.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHVkBuffer;
|
||||||
|
class SHVkLogicalDevice;
|
||||||
|
class SHVkCommandBuffer;
|
||||||
|
class SHVkImage;
|
||||||
|
class SHVkImageView;
|
||||||
|
class SHVkSampler;
|
||||||
|
|
||||||
|
class SHSSAO
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr uint32_t DESC_SET_BUFFER_BINDING = 0;
|
||||||
|
static constexpr uint32_t DESC_SET_IMAGE_BINDING = 1;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr uint32_t NUM_SAMPLES = 64;
|
||||||
|
static constexpr uint32_t NUM_ROTATION_VECTORS_W = 4;
|
||||||
|
static constexpr uint32_t NUM_ROTATION_VECTORS_H = 4;
|
||||||
|
static constexpr uint32_t NUM_ROTATION_VECTORS = NUM_ROTATION_VECTORS_W * NUM_ROTATION_VECTORS_H;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! distances from a pixel we want to sample
|
||||||
|
std::array<SHVec4, NUM_SAMPLES> samples;
|
||||||
|
|
||||||
|
//! For passing SSAO samples and kernel to GPU
|
||||||
|
Handle<SHVkBuffer> ssaoDataBuffer;
|
||||||
|
|
||||||
|
std::array<SHVec4, NUM_ROTATION_VECTORS> rotationVectors;
|
||||||
|
|
||||||
|
Handle<SHVkImage> rotationVectorsImage;
|
||||||
|
Handle<SHVkImageView> rotationVectorsImageView;
|
||||||
|
Handle<SHVkSampler> rotationVectorsSampler;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void Init (Handle<SHVkLogicalDevice> logicalDevice, Handle<SHVkCommandBuffer> cmdBuffer) noexcept;
|
||||||
|
void PrepareRotationVectorsVkData (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||||
|
SHVkDescriptorSetGroup::viewSamplerLayout GetViewSamplerLayout (void) const noexcept;
|
||||||
|
|
||||||
|
Handle<SHVkBuffer> GetBuffer (void) const noexcept;
|
||||||
|
};
|
||||||
|
}
|
|
@ -2,8 +2,10 @@
|
||||||
#define SH_PIPELINE_LAYOUT_PARAMS_H
|
#define SH_PIPELINE_LAYOUT_PARAMS_H
|
||||||
|
|
||||||
#include "Graphics/SHVulkanIncludes.h"
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
|
#include "Graphics/SHVulkanDefines.h"
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -24,6 +26,12 @@ namespace SHADE
|
||||||
//! want to use the layout to initialize the pipeline layout but we do not
|
//! want to use the layout to initialize the pipeline layout but we do not
|
||||||
//! want to use it for allocating descriptor sets.
|
//! want to use it for allocating descriptor sets.
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> const& globalDescSetLayouts = {};
|
std::vector<Handle<SHVkDescriptorSetLayout>> const& globalDescSetLayouts = {};
|
||||||
|
|
||||||
|
//! Since both SPIRV-Reflect and GLSL don't provide ways to describe UBOs or
|
||||||
|
//! SSBOs as dynamic, we need to do it ourselves. This will store bindings
|
||||||
|
//! which we will use when parsing for descriptor set layouts. If a parsed
|
||||||
|
//! binding is in this container, we make that binding's descriptor dynamic.
|
||||||
|
std::unordered_set<BindingAndSetHash> dynamicBufferBindings;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHPipelineLayoutParamsDummy
|
struct SHPipelineLayoutParamsDummy
|
||||||
|
|
|
@ -165,6 +165,28 @@ namespace SHADE
|
||||||
newBinding.Stage = shaderModule->GetShaderStageFlagBits();
|
newBinding.Stage = shaderModule->GetShaderStageFlagBits();
|
||||||
newBinding.Type = descBindingInfo.ConvertFromReflectDescType(reflectedBinding->descriptor_type);
|
newBinding.Type = descBindingInfo.ConvertFromReflectDescType(reflectedBinding->descriptor_type);
|
||||||
|
|
||||||
|
// Here we want to check if a binding is supposed to be dynamic. If it is, make it dynamic.
|
||||||
|
if (newBinding.Type == vk::DescriptorType::eUniformBuffer || newBinding.Type == vk::DescriptorType::eStorageBuffer)
|
||||||
|
{
|
||||||
|
for (auto& bsHash : dynamicBufferBindings)
|
||||||
|
{
|
||||||
|
uint32_t set = static_cast<uint32_t>(bsHash >> 32);
|
||||||
|
uint32_t binding = static_cast<uint32_t>(bsHash & 0xFFFFFFFF);
|
||||||
|
if (set == CURRENT_SET && binding == newBinding.BindPoint)
|
||||||
|
{
|
||||||
|
switch (newBinding.Type)
|
||||||
|
{
|
||||||
|
case vk::DescriptorType::eUniformBuffer:
|
||||||
|
newBinding.Type = vk::DescriptorType::eUniformBufferDynamic;
|
||||||
|
break;
|
||||||
|
case vk::DescriptorType::eStorageBuffer:
|
||||||
|
newBinding.Type = vk::DescriptorType::eStorageBufferDynamic;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// In reality, the check for variable descriptor sets do not exists in spirv-reflect. Fortunately, when a shader
|
// In reality, the check for variable descriptor sets do not exists in spirv-reflect. Fortunately, when a shader
|
||||||
// defines a boundless descriptor binding in the shader, the information reflected makes the array dimensions
|
// defines a boundless descriptor binding in the shader, the information reflected makes the array dimensions
|
||||||
// contain a 1 element of value 1. Knowing that having an array [1] doesn't make sense, we can use this to
|
// contain a 1 element of value 1. Knowing that having an array [1] doesn't make sense, we can use this to
|
||||||
|
@ -300,6 +322,7 @@ namespace SHADE
|
||||||
, vkDescriptorSetLayoutsAllocate{}
|
, vkDescriptorSetLayoutsAllocate{}
|
||||||
, descriptorSetLayoutsPipeline{}
|
, descriptorSetLayoutsPipeline{}
|
||||||
, vkDescriptorSetLayoutsPipeline{}
|
, vkDescriptorSetLayoutsPipeline{}
|
||||||
|
, dynamicBufferBindings{std::move (pipelineLayoutParams.dynamicBufferBindings)}
|
||||||
{
|
{
|
||||||
for (auto& mod : shaderModules)
|
for (auto& mod : shaderModules)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,6 +29,9 @@ namespace SHADE
|
||||||
//! Push constant interface
|
//! Push constant interface
|
||||||
SHPushConstantInterface pushConstantInterface;
|
SHPushConstantInterface pushConstantInterface;
|
||||||
|
|
||||||
|
//! See SHPipelineLayoutParams for details
|
||||||
|
std::unordered_set<BindingAndSetHash> dynamicBufferBindings;
|
||||||
|
|
||||||
//! Push constant ranges
|
//! Push constant ranges
|
||||||
std::vector<vk::PushConstantRange> vkPcRanges;
|
std::vector<vk::PushConstantRange> vkPcRanges;
|
||||||
|
|
||||||
|
|
|
@ -129,4 +129,9 @@ namespace SHADE
|
||||||
return vkQueue;
|
return vkQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkQueue::WaitIdle(void) const noexcept
|
||||||
|
{
|
||||||
|
vkQueue.waitIdle();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -50,6 +50,8 @@ namespace SHADE
|
||||||
void SubmitCommandBuffer (std::initializer_list<Handle<SHVkCommandBuffer>> cmdBuffers, std::initializer_list<Handle<SHVkSemaphore>> signalSems = {}, std::initializer_list<Handle<SHVkSemaphore>> waitSems = {}, vk::PipelineStageFlags waitDstStageMask = {}, Handle<SHVkFence> const& fence = {}) noexcept;
|
void SubmitCommandBuffer (std::initializer_list<Handle<SHVkCommandBuffer>> cmdBuffers, std::initializer_list<Handle<SHVkSemaphore>> signalSems = {}, std::initializer_list<Handle<SHVkSemaphore>> waitSems = {}, vk::PipelineStageFlags waitDstStageMask = {}, Handle<SHVkFence> const& fence = {}) noexcept;
|
||||||
vk::Result Present (Handle<SHVkSwapchain> const& swapchain, std::initializer_list<Handle<SHVkSemaphore>> waitSems, uint32_t frameIndex) noexcept;
|
vk::Result Present (Handle<SHVkSwapchain> const& swapchain, std::initializer_list<Handle<SHVkSemaphore>> waitSems, uint32_t frameIndex) noexcept;
|
||||||
vk::Queue GetVkQueue() noexcept;
|
vk::Queue GetVkQueue() noexcept;
|
||||||
|
|
||||||
|
void WaitIdle (void) const noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ namespace SHADE
|
||||||
return subpass;
|
return subpass;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, float numWorkGroupScale/* = 1.0f*/) noexcept
|
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, float numWorkGroupScale/* = 1.0f*/) noexcept
|
||||||
{
|
{
|
||||||
// Look for the required resources in the graph
|
// Look for the required resources in the graph
|
||||||
std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{};
|
std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{};
|
||||||
|
@ -276,7 +276,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the subpass compute with the resources
|
// Create the subpass compute with the resources
|
||||||
auto nodeCompute = graphStorage->resourceManager->Create<SHRenderGraphNodeCompute>(graphStorage, computeShaderModule, std::move(nodeComputeResources), nodeComputes.empty());
|
auto nodeCompute = graphStorage->resourceManager->Create<SHRenderGraphNodeCompute>(graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty());
|
||||||
nodeComputes.push_back(nodeCompute);
|
nodeComputes.push_back(nodeCompute);
|
||||||
|
|
||||||
return nodeCompute;
|
return nodeCompute;
|
||||||
|
|
|
@ -100,7 +100,7 @@ namespace SHADE
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
Handle<SHSubpass> AddSubpass(std::string subpassName) noexcept;
|
Handle<SHSubpass> AddSubpass(std::string subpassName) noexcept;
|
||||||
Handle<SHRenderGraphNodeCompute> AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, float numWorkGroupScale = 1.0f) noexcept;
|
Handle<SHRenderGraphNodeCompute> AddNodeCompute(Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept;
|
||||||
void AddDummySubpassIfNeeded (void) noexcept;
|
void AddDummySubpassIfNeeded (void) noexcept;
|
||||||
|
|
||||||
// TODO: RemoveSubpass()
|
// TODO: RemoveSubpass()
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, bool followingEndRP, float inNumWorkGroupScale/* = 1.0f*/) noexcept
|
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
|
||||||
: computePipeline{}
|
: computePipeline{}
|
||||||
, pipelineLayout{}
|
, pipelineLayout{}
|
||||||
, resources{}
|
, resources{}
|
||||||
|
@ -21,11 +21,13 @@ namespace SHADE
|
||||||
, groupSizeY{0}
|
, groupSizeY{0}
|
||||||
, followingEndRenderpass {followingEndRP}
|
, followingEndRenderpass {followingEndRP}
|
||||||
, numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)}
|
, numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)}
|
||||||
|
, computeResource{}
|
||||||
{
|
{
|
||||||
SHPipelineLayoutParams pipelineLayoutParams
|
SHPipelineLayoutParams pipelineLayoutParams
|
||||||
{
|
{
|
||||||
.shaderModules = {computeShaderModule},
|
.shaderModules = {computeShaderModule},
|
||||||
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts()
|
.globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts(),
|
||||||
|
.dynamicBufferBindings = std::move(dynamicBufferBindings),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create pipeline layout from parameters
|
// Create pipeline layout from parameters
|
||||||
|
@ -42,16 +44,31 @@ namespace SHADE
|
||||||
|
|
||||||
//Get the descriptor set layouts required to allocate. We only want the ones for allocate because
|
//Get the descriptor set layouts required to allocate. We only want the ones for allocate because
|
||||||
//global descriptors are already bound in the main system.
|
//global descriptors are already bound in the main system.
|
||||||
auto const& layouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsAllocate();
|
auto const& graphResourceLayout = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline()[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE];
|
||||||
|
|
||||||
//Variable counts for the descriptor sets (all should be 1).
|
|
||||||
std::vector<uint32_t> variableCounts{ static_cast<uint32_t>(layouts.size()) };
|
|
||||||
std::fill(variableCounts.begin(), variableCounts.end(), 0);
|
|
||||||
|
|
||||||
// Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE)
|
// Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE)
|
||||||
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
||||||
{
|
{
|
||||||
descSetGroups[i] = graphStorage->descriptorPool->Allocate(layouts, variableCounts);
|
graphResourceDescSets[i] = graphStorage->descriptorPool->Allocate({graphResourceLayout}, { 1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto const& layouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline();
|
||||||
|
|
||||||
|
if (layouts.size() == SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE + 1)
|
||||||
|
{
|
||||||
|
// create compute resources
|
||||||
|
computeResource = graphStorage->resourceManager->Create<ComputeResource>();
|
||||||
|
auto computeResourceLayout = layouts[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE];
|
||||||
|
computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 });
|
||||||
|
|
||||||
|
// Allocate for descriptor offsets
|
||||||
|
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
||||||
|
computeResource->dynamicOffsets[i].resize(computeResourceLayout->GetNumDynamicOffsetsRequired());
|
||||||
|
|
||||||
|
// 1st set all start at 0
|
||||||
|
for (auto& index : computeResource->dynamicOffsets[0])
|
||||||
|
index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleResize();
|
HandleResize();
|
||||||
|
@ -63,7 +80,12 @@ namespace SHADE
|
||||||
cmdBuffer->BindPipeline(computePipeline);
|
cmdBuffer->BindPipeline(computePipeline);
|
||||||
|
|
||||||
// bind descriptor sets
|
// bind descriptor sets
|
||||||
cmdBuffer->BindDescriptorSet(descSetGroups[frameIndex], SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, {});
|
cmdBuffer->BindDescriptorSet(graphResourceDescSets[frameIndex], SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, {});
|
||||||
|
|
||||||
|
if (computeResource)
|
||||||
|
{
|
||||||
|
cmdBuffer->BindDescriptorSet(computeResource->descSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, computeResource->dynamicOffsets[frameIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
// dispatch compute
|
// dispatch compute
|
||||||
cmdBuffer->ComputeDispatch(groupSizeX, groupSizeY, 1);
|
cmdBuffer->ComputeDispatch(groupSizeX, groupSizeY, 1);
|
||||||
|
@ -89,8 +111,8 @@ namespace SHADE
|
||||||
uint32_t imageIndex = (resources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? frameIndex : 0;
|
uint32_t imageIndex = (resources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? frameIndex : 0;
|
||||||
|
|
||||||
SHVkDescriptorSetGroup::viewSamplerLayout vsl = std::make_tuple(resources[i]->GetImageView(imageIndex), Handle<SHVkSampler>{}, vk::ImageLayout::eGeneral);
|
SHVkDescriptorSetGroup::viewSamplerLayout vsl = std::make_tuple(resources[i]->GetImageView(imageIndex), Handle<SHVkSampler>{}, vk::ImageLayout::eGeneral);
|
||||||
descSetGroups[frameIndex]->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, { &vsl, 1 });
|
graphResourceDescSets[frameIndex]->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, { &vsl, 1 });
|
||||||
descSetGroups[frameIndex]->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint);
|
graphResourceDescSets[frameIndex]->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,4 +159,27 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::SetDynamicOffsets(std::span<uint32_t> perFrameSizes) noexcept
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i)
|
||||||
|
{
|
||||||
|
auto dynamicOffsets = computeResource->dynamicOffsets[i];
|
||||||
|
for (uint32_t j = 0; j < perFrameSizes.size(); ++j)
|
||||||
|
dynamicOffsets[j] = perFrameSizes[j] * i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::ModifyWriteDescBufferComputeResource(uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept
|
||||||
|
{
|
||||||
|
computeResource->descSet->ModifyWriteDescBuffer(set, binding, buffers, offset, range);
|
||||||
|
computeResource->descSet->UpdateDescriptorSetBuffer(set, binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::ModifyWriteDescImageComputeResource(uint32_t set, uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept
|
||||||
|
{
|
||||||
|
computeResource->descSet->ModifyWriteDescImage(set, binding, viewSamplerLayouts);
|
||||||
|
computeResource->descSet->UpdateDescriptorSetImages(set, binding);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
|
||||||
#include "Graphics/SHVulkanIncludes.h"
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -10,7 +11,6 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
class SHVkPipeline;
|
class SHVkPipeline;
|
||||||
class SHVkDescriptorSetGroup;
|
|
||||||
class SHVkDescriptorPool;
|
class SHVkDescriptorPool;
|
||||||
class SHVkLogicalDevice;
|
class SHVkLogicalDevice;
|
||||||
class SHVkPipelineLayout;
|
class SHVkPipelineLayout;
|
||||||
|
@ -18,9 +18,22 @@ namespace SHADE
|
||||||
class SHRenderGraphResource;
|
class SHRenderGraphResource;
|
||||||
class SHVkShaderModule;
|
class SHVkShaderModule;
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
|
class SHVkBuffer;
|
||||||
|
|
||||||
|
|
||||||
class SHRenderGraphNodeCompute
|
class SHRenderGraphNodeCompute
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
// Binding of set SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE
|
||||||
|
struct ComputeResource
|
||||||
|
{
|
||||||
|
//! Descriptor set (initialized by parent class)
|
||||||
|
Handle<SHVkDescriptorSetGroup> descSet {};
|
||||||
|
|
||||||
|
//! Dynamic offsets into these resources (initialized from the outside).
|
||||||
|
std::array<std::vector<uint32_t>, SHGraphicsConstants::NUM_FRAME_BUFFERS> dynamicOffsets {};
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint32_t workGroupSizeX = 16;
|
static constexpr uint32_t workGroupSizeX = 16;
|
||||||
static constexpr uint32_t workGroupSizeY = 16;
|
static constexpr uint32_t workGroupSizeY = 16;
|
||||||
|
@ -32,7 +45,10 @@ namespace SHADE
|
||||||
Handle<SHVkPipelineLayout> pipelineLayout;
|
Handle<SHVkPipelineLayout> pipelineLayout;
|
||||||
|
|
||||||
//! Descriptor set group to hold the images for reading (STORAGE_IMAGE)
|
//! Descriptor set group to hold the images for reading (STORAGE_IMAGE)
|
||||||
std::array<Handle<SHVkDescriptorSetGroup>, SHGraphicsConstants::NUM_FRAME_BUFFERS> descSetGroups;
|
std::array<Handle<SHVkDescriptorSetGroup>, SHGraphicsConstants::NUM_FRAME_BUFFERS> graphResourceDescSets;
|
||||||
|
|
||||||
|
//! Compute resources
|
||||||
|
Handle<ComputeResource> computeResource;
|
||||||
|
|
||||||
//! vector of resources needed by the subpass compute
|
//! vector of resources needed by the subpass compute
|
||||||
std::vector<Handle<SHRenderGraphResource>> resources;
|
std::vector<Handle<SHRenderGraphResource>> resources;
|
||||||
|
@ -50,11 +66,17 @@ namespace SHADE
|
||||||
std::array<std::vector<vk::ImageMemoryBarrier>, SHGraphicsConstants::NUM_FRAME_BUFFERS> memoryBarriers;
|
std::array<std::vector<vk::ImageMemoryBarrier>, SHGraphicsConstants::NUM_FRAME_BUFFERS> memoryBarriers;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHRenderGraphNodeCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept;
|
SHRenderGraphNodeCompute(Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept;
|
||||||
|
|
||||||
void Execute (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
void Execute (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||||
void HandleResize (void) noexcept;
|
void HandleResize (void) noexcept;
|
||||||
|
|
||||||
|
void SetDynamicOffsets (std::span<uint32_t> perFrameSizes) noexcept;
|
||||||
|
|
||||||
|
void ModifyWriteDescBufferComputeResource (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
||||||
|
void ModifyWriteDescImageComputeResource(uint32_t set, uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept;
|
||||||
|
|
||||||
|
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
friend class SHRenderGraphNode;
|
friend class SHRenderGraphNode;
|
||||||
};
|
};
|
||||||
|
|
|
@ -142,6 +142,16 @@ namespace SHADE
|
||||||
case SpvOp::SpvOpTypeRuntimeArray:
|
case SpvOp::SpvOpTypeRuntimeArray:
|
||||||
recurseForInfo(&member, interfaceHdl, member.offset, biggestAlignment, parentVarName + std::string(member.name) + ".");
|
recurseForInfo(&member, interfaceHdl, member.offset, biggestAlignment, parentVarName + std::string(member.name) + ".");
|
||||||
break;
|
break;
|
||||||
|
case SpvOp::SpvOpTypeArray:
|
||||||
|
interfaceHdl->AddVariable(parentVarName + std::string (member.name),
|
||||||
|
SHShaderBlockInterface::Variable
|
||||||
|
(
|
||||||
|
parentOffset + member.offset,
|
||||||
|
SHShaderBlockInterface::Variable::Type::OTHER
|
||||||
|
)
|
||||||
|
);
|
||||||
|
biggestAlignment = std::max(biggestAlignment, member.size);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -118,6 +118,17 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
SHColour::SHColour(uint32_t rgba) noexcept
|
||||||
|
: XMFLOAT4 { 0.0f, 0.0f, 0.0f, 1.0f }
|
||||||
|
{
|
||||||
|
const SHColour32 TMP { ._32bitValue = rgba };
|
||||||
|
|
||||||
|
x = static_cast<float>(TMP._8bitValues[0]) / 255.0f;
|
||||||
|
y = static_cast<float>(TMP._8bitValues[1]) / 255.0f;
|
||||||
|
z = static_cast<float>(TMP._8bitValues[2]) / 255.0f;
|
||||||
|
w = static_cast<float>(TMP._8bitValues[3]) / 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
SHColour::SHColour(const SHVec3& rgb) noexcept
|
SHColour::SHColour(const SHVec3& rgb) noexcept
|
||||||
: XMFLOAT4 { rgb.x, rgb.y, rgb.z, 1.0f }
|
: XMFLOAT4 { rgb.x, rgb.y, rgb.z, 1.0f }
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -34,6 +34,12 @@ namespace SHADE
|
||||||
float v = 0.0f;
|
float v = 0.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union SH_API SHColour32
|
||||||
|
{
|
||||||
|
uint32_t _32bitValue;
|
||||||
|
uint8_t _8bitValues[4];
|
||||||
|
};
|
||||||
|
|
||||||
class SH_API SHColour : public DirectX::XMFLOAT4
|
class SH_API SHColour : public DirectX::XMFLOAT4
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -46,6 +52,7 @@ namespace SHADE
|
||||||
SHColour (float r, float g, float b, float a) noexcept;
|
SHColour (float r, float g, float b, float a) noexcept;
|
||||||
SHColour (uint8_t r, uint8_t g, uint8_t b) noexcept;
|
SHColour (uint8_t r, uint8_t g, uint8_t b) noexcept;
|
||||||
SHColour (uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept;
|
SHColour (uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept;
|
||||||
|
SHColour (uint32_t rgba) noexcept;
|
||||||
|
|
||||||
SHColour (const SHVec3& rgb) noexcept;
|
SHColour (const SHVec3& rgb) noexcept;
|
||||||
SHColour (const SHVec4& rgba) noexcept;
|
SHColour (const SHVec4& rgba) noexcept;
|
||||||
|
|
|
@ -212,7 +212,7 @@ namespace SHADE
|
||||||
const SHVec3 TF_WORLD_SCALE = transformComponent->GetWorldScale();
|
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 });
|
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
|
||||||
|
|
||||||
worldRadius *= MAX_SCALE;
|
worldRadius *= MAX_SCALE * 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == Type::SPHERE)
|
if (type == Type::SPHERE)
|
||||||
|
|
|
@ -17,10 +17,12 @@
|
||||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
#include "ECS_Base/Managers/SHEntityManager.h"
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
|
||||||
#include "Math/SHMathHelpers.h"
|
#include "Math/SHMathHelpers.h"
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
#include "Scripting/SHScriptEngine.h"
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
#include "Tools/SHUtilities.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -30,6 +32,7 @@ namespace SHADE
|
||||||
|
|
||||||
SHPhysicsSystem::SHPhysicsSystem()
|
SHPhysicsSystem::SHPhysicsSystem()
|
||||||
: worldUpdated { false }
|
: worldUpdated { false }
|
||||||
|
, debugDrawFlags { 0 }
|
||||||
, interpolationFactor { 0.0 }
|
, interpolationFactor { 0.0 }
|
||||||
, fixedDT { 60.0 }
|
, fixedDT { 60.0 }
|
||||||
, world { nullptr }
|
, world { nullptr }
|
||||||
|
@ -47,6 +50,11 @@ namespace SHADE
|
||||||
: SHSystemRoutine { "Physics PostUpdate", false }
|
: SHSystemRoutine { "Physics PostUpdate", false }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
SHPhysicsSystem::PhysicsDebugDraw::PhysicsDebugDraw()
|
||||||
|
: SHSystemRoutine { "Physics DebugDraw", true }
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Getter Function Definitions */
|
/* Getter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -99,6 +107,31 @@ namespace SHADE
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SHPhysicsSystem::GetDrawColliders() const noexcept
|
||||||
|
{
|
||||||
|
return debugDrawFlags & SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHPhysicsSystem::GetDrawColliderAABBs() const noexcept
|
||||||
|
{
|
||||||
|
return debugDrawFlags & SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER_AABB);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHPhysicsSystem::GetDrawBroadPhase() const noexcept
|
||||||
|
{
|
||||||
|
return debugDrawFlags & SHUtilities::ConvertEnum(DebugDrawFlags::BROAD_PHASE_AABB);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHPhysicsSystem::GetDrawContactPoints() const noexcept
|
||||||
|
{
|
||||||
|
return debugDrawFlags & SHUtilities::ConvertEnum(DebugDrawFlags::CONTACT_POINTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHPhysicsSystem::GetDrawContactNormals() const noexcept
|
||||||
|
{
|
||||||
|
return debugDrawFlags & SHUtilities::ConvertEnum(DebugDrawFlags::CONTACT_NORMALS);
|
||||||
|
}
|
||||||
|
|
||||||
const SHPhysicsSystem::CollisionEvents& SHPhysicsSystem::GetCollisionInfo() const noexcept
|
const SHPhysicsSystem::CollisionEvents& SHPhysicsSystem::GetCollisionInfo() const noexcept
|
||||||
{
|
{
|
||||||
return collisionInfo;
|
return collisionInfo;
|
||||||
|
@ -181,6 +214,96 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::SetDrawColliders(bool shouldDraw) noexcept
|
||||||
|
{
|
||||||
|
static constexpr auto FLAG_VALUE = SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER);
|
||||||
|
shouldDraw ? debugDrawFlags |= FLAG_VALUE : debugDrawFlags &= ~(FLAG_VALUE);
|
||||||
|
|
||||||
|
if (world == nullptr)
|
||||||
|
{
|
||||||
|
SHLOGV_WARNING("No physics world has been initialised!")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
world->getDebugRenderer().setIsDebugItemDisplayed
|
||||||
|
(
|
||||||
|
rp3d::DebugRenderer::DebugItem::COLLISION_SHAPE,
|
||||||
|
shouldDraw
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::SetDrawColliderAABBs(bool shouldDraw) noexcept
|
||||||
|
{
|
||||||
|
static constexpr auto FLAG_VALUE = SHUtilities::ConvertEnum(DebugDrawFlags::COLLIDER_AABB);
|
||||||
|
shouldDraw ? debugDrawFlags |= FLAG_VALUE : debugDrawFlags &= ~(FLAG_VALUE);
|
||||||
|
|
||||||
|
if (world == nullptr)
|
||||||
|
{
|
||||||
|
SHLOGV_WARNING("No physics world has been initialised!")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
world->getDebugRenderer().setIsDebugItemDisplayed
|
||||||
|
(
|
||||||
|
rp3d::DebugRenderer::DebugItem::COLLIDER_AABB,
|
||||||
|
shouldDraw
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::SetDrawBroadPhase(bool shouldDraw) noexcept
|
||||||
|
{
|
||||||
|
static constexpr auto FLAG_VALUE = SHUtilities::ConvertEnum(DebugDrawFlags::BROAD_PHASE_AABB);
|
||||||
|
shouldDraw ? debugDrawFlags |= FLAG_VALUE : debugDrawFlags &= ~(FLAG_VALUE);
|
||||||
|
|
||||||
|
if (world == nullptr)
|
||||||
|
{
|
||||||
|
SHLOGV_WARNING("No physics world has been initialised!")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
world->getDebugRenderer().setIsDebugItemDisplayed
|
||||||
|
(
|
||||||
|
rp3d::DebugRenderer::DebugItem::COLLIDER_BROADPHASE_AABB,
|
||||||
|
shouldDraw
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::SetDrawContactPoints(bool shouldDraw) noexcept
|
||||||
|
{
|
||||||
|
static constexpr auto FLAG_VALUE = SHUtilities::ConvertEnum(DebugDrawFlags::CONTACT_POINTS);
|
||||||
|
shouldDraw ? debugDrawFlags |= FLAG_VALUE : debugDrawFlags &= ~(FLAG_VALUE);
|
||||||
|
|
||||||
|
if (world == nullptr)
|
||||||
|
{
|
||||||
|
SHLOGV_WARNING("No physics world has been initialised!")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
world->getDebugRenderer().setIsDebugItemDisplayed
|
||||||
|
(
|
||||||
|
rp3d::DebugRenderer::DebugItem::CONTACT_POINT,
|
||||||
|
shouldDraw
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::SetDrawContactNormals(bool shouldDraw) noexcept
|
||||||
|
{
|
||||||
|
static constexpr auto FLAG_VALUE = SHUtilities::ConvertEnum(DebugDrawFlags::CONTACT_NORMALS);
|
||||||
|
shouldDraw ? debugDrawFlags |= FLAG_VALUE : debugDrawFlags &= ~(FLAG_VALUE);
|
||||||
|
|
||||||
|
if (world == nullptr)
|
||||||
|
{
|
||||||
|
SHLOGV_WARNING("No physics world has been initialised!")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
world->getDebugRenderer().setIsDebugItemDisplayed
|
||||||
|
(
|
||||||
|
rp3d::DebugRenderer::DebugItem::CONTACT_NORMAL,
|
||||||
|
shouldDraw
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Public Function Member Definitions */
|
/* Public Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -198,6 +321,7 @@ namespace SHADE
|
||||||
|
|
||||||
world = factory.createPhysicsWorld(settings);
|
world = factory.createPhysicsWorld(settings);
|
||||||
world->setEventListener(this);
|
world->setEventListener(this);
|
||||||
|
world->setIsDebugRenderingEnabled(true);
|
||||||
|
|
||||||
// Set up solvers
|
// Set up solvers
|
||||||
world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES);
|
world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES);
|
||||||
|
@ -323,7 +447,7 @@ namespace SHADE
|
||||||
auto* scriptingSystem = SHSystemManager::GetSystem<SHScriptEngine>();
|
auto* scriptingSystem = SHSystemManager::GetSystem<SHScriptEngine>();
|
||||||
if (scriptingSystem == nullptr)
|
if (scriptingSystem == nullptr)
|
||||||
{
|
{
|
||||||
SHLOGV_WARNING("Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!");
|
SHLOGV_ERROR("Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!");
|
||||||
}
|
}
|
||||||
|
|
||||||
fixedTimeStep = 1.0 / physicsSystem->fixedDT;
|
fixedTimeStep = 1.0 / physicsSystem->fixedDT;
|
||||||
|
@ -353,7 +477,7 @@ namespace SHADE
|
||||||
auto* scriptingSystem = SHSystemManager::GetSystem<SHScriptEngine>();
|
auto* scriptingSystem = SHSystemManager::GetSystem<SHScriptEngine>();
|
||||||
if (scriptingSystem == nullptr)
|
if (scriptingSystem == nullptr)
|
||||||
{
|
{
|
||||||
SHLOGV_WARNING("Unable to invoke collision and trigger script events due to missing SHScriptEngine!");
|
SHLOGV_ERROR("Unable to invoke collision and trigger script events due to missing SHScriptEngine!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interpolate transforms for rendering
|
// Interpolate transforms for rendering
|
||||||
|
@ -369,6 +493,40 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::PhysicsDebugDraw::Execute(double) noexcept
|
||||||
|
{
|
||||||
|
const auto* PHYSICS_SYSTEM = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||||
|
if (PHYSICS_SYSTEM->debugDrawFlags == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto* debugDrawSystem = SHSystemManager::GetSystem<SHDebugDrawSystem>();
|
||||||
|
if (debugDrawSystem == nullptr)
|
||||||
|
{
|
||||||
|
SHLOGV_ERROR("Unable to debug draw physics objects due to missing SHDebugDrawSystem!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& RP3D_DEBUG_RENDERER = PHYSICS_SYSTEM->world->getDebugRenderer();
|
||||||
|
|
||||||
|
const auto& LINES = RP3D_DEBUG_RENDERER.getLines();
|
||||||
|
const auto& TRIANGLES = RP3D_DEBUG_RENDERER.getTriangles();
|
||||||
|
|
||||||
|
// Draw all lines
|
||||||
|
for (uint32_t i = 0; i < RP3D_DEBUG_RENDERER.getNbLines(); ++i)
|
||||||
|
{
|
||||||
|
const auto& LINE = LINES[i];
|
||||||
|
debugDrawSystem->DrawLine(SHColour{ LINE.color1 }, LINE.point1, LINE.point2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < RP3D_DEBUG_RENDERER.getNbTriangles(); ++i)
|
||||||
|
{
|
||||||
|
const auto& TRIANGLE = TRIANGLES[i];
|
||||||
|
SHColour triColour{ TRIANGLE.color1 };
|
||||||
|
triColour.a() = 1.0f;
|
||||||
|
debugDrawSystem->DrawTri(triColour, TRIANGLE.point1, TRIANGLE.point2, TRIANGLE.point3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::onContact(const CallbackData& callbackData)
|
void SHPhysicsSystem::onContact(const CallbackData& callbackData)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i)
|
for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i)
|
||||||
|
|
|
@ -51,6 +51,15 @@ namespace SHADE
|
||||||
|
|
||||||
using CollisionEvents = std::vector<SHCollisionEvent>;
|
using CollisionEvents = std::vector<SHCollisionEvent>;
|
||||||
|
|
||||||
|
enum class DebugDrawFlags : uint8_t
|
||||||
|
{
|
||||||
|
COLLIDER = 1
|
||||||
|
, COLLIDER_AABB = 2
|
||||||
|
, BROAD_PHASE_AABB = 4
|
||||||
|
, CONTACT_POINTS = 8
|
||||||
|
, CONTACT_NORMALS = 16
|
||||||
|
};
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Constructors & Destructor */
|
/* Constructors & Destructor */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -69,6 +78,12 @@ namespace SHADE
|
||||||
[[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept;
|
[[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept;
|
||||||
[[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept;
|
[[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] bool GetDrawColliders () const noexcept;
|
||||||
|
[[nodiscard]] bool GetDrawColliderAABBs () const noexcept;
|
||||||
|
[[nodiscard]] bool GetDrawBroadPhase () const noexcept;
|
||||||
|
[[nodiscard]] bool GetDrawContactPoints () const noexcept;
|
||||||
|
[[nodiscard]] bool GetDrawContactNormals () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const CollisionEvents& GetCollisionInfo () const noexcept;
|
[[nodiscard]] const CollisionEvents& GetCollisionInfo () const noexcept;
|
||||||
[[nodiscard]] const CollisionEvents& GetTriggerInfo () const noexcept;
|
[[nodiscard]] const CollisionEvents& GetTriggerInfo () const noexcept;
|
||||||
|
|
||||||
|
@ -85,6 +100,13 @@ namespace SHADE
|
||||||
|
|
||||||
void SetWorldSettings (const WorldSettings& settings) const noexcept;
|
void SetWorldSettings (const WorldSettings& settings) const noexcept;
|
||||||
|
|
||||||
|
// TODO(Diren): Can the debug draw flags be done through an enum?
|
||||||
|
void SetDrawColliders (bool shouldDraw) noexcept;
|
||||||
|
void SetDrawColliderAABBs (bool shouldDraw) noexcept;
|
||||||
|
void SetDrawBroadPhase (bool shouldDraw) noexcept;
|
||||||
|
void SetDrawContactPoints (bool shouldDraw) noexcept;
|
||||||
|
void SetDrawContactNormals (bool shouldDraw) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -105,48 +127,31 @@ namespace SHADE
|
||||||
class SH_API PhysicsPreUpdate final : public SHSystemRoutine
|
class SH_API PhysicsPreUpdate final : public SHSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*-------------------------------------------------------------------------------*/
|
|
||||||
/* Constructors & Destructor */
|
|
||||||
/*-------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
PhysicsPreUpdate();
|
PhysicsPreUpdate();
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------*/
|
|
||||||
/* Function Members */
|
|
||||||
/*-------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void Execute(double dt) noexcept override;
|
void Execute(double dt) noexcept override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine
|
class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*-------------------------------------------------------------------------------*/
|
|
||||||
/* Constructors & Destructor */
|
|
||||||
/*-------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
PhysicsFixedUpdate();
|
PhysicsFixedUpdate();
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------*/
|
|
||||||
/* Function Members */
|
|
||||||
/*-------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void Execute (double dt) noexcept override;
|
void Execute (double dt) noexcept override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SH_API PhysicsPostUpdate final : public SHSystemRoutine
|
class SH_API PhysicsPostUpdate final : public SHSystemRoutine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*-------------------------------------------------------------------------------*/
|
|
||||||
/* Constructors & Destructor */
|
|
||||||
/*-------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
PhysicsPostUpdate();
|
PhysicsPostUpdate();
|
||||||
|
void Execute(double dt) noexcept override;
|
||||||
|
};
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------*/
|
class SH_API PhysicsDebugDraw final : public SHSystemRoutine
|
||||||
/* Function Members */
|
{
|
||||||
/*-------------------------------------------------------------------------------*/
|
public:
|
||||||
|
PhysicsDebugDraw();
|
||||||
void Execute(double dt) noexcept override;
|
void Execute(double dt) noexcept override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -162,6 +167,7 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
bool worldUpdated;
|
bool worldUpdated;
|
||||||
|
uint8_t debugDrawFlags;
|
||||||
|
|
||||||
double interpolationFactor;
|
double interpolationFactor;
|
||||||
double fixedDT;
|
double fixedDT;
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace SHADE
|
||||||
/* Static Member Definitions */
|
/* Static Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
SHDebugDrawSystem* SHDebugDraw::dbgDrawSys = nullptr;
|
SHDebugDrawSystem* SHDebugDraw::dbgDrawSys = nullptr;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Lifecycle Functions */
|
/* Lifecycle Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -70,4 +70,40 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
dbgDrawSys->DrawSphere(color, pos, radius);
|
dbgDrawSys->DrawSphere(color, pos, radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHDebugDraw::PersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
|
||||||
|
{
|
||||||
|
dbgDrawSys->DrawPersistentLine(color, startPt, endPt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDraw::PersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3)
|
||||||
|
{
|
||||||
|
dbgDrawSys->DrawPersistentTri(color, pt1, pt2, pt3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDraw::PersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4)
|
||||||
|
{
|
||||||
|
dbgDrawSys->DrawPersistentQuad(color, pt1, pt2, pt3, pt4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDraw::PersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList)
|
||||||
|
{
|
||||||
|
dbgDrawSys->DrawPersistentPoly(color, pointList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDraw::PersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size)
|
||||||
|
{
|
||||||
|
dbgDrawSys->DrawPersistentCube(color, pos, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDraw::PersistentSphere(const SHVec4& color, const SHVec3& pos, double radius)
|
||||||
|
{
|
||||||
|
dbgDrawSys->DrawPersistentSphere(color, pos, radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDebugDraw::ClearPersistentDraws()
|
||||||
|
{
|
||||||
|
dbgDrawSys->ClearPersistentDraws();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -92,6 +92,64 @@ namespace SHADE
|
||||||
/// <param name="size">Size of the rendered sphere.</param>
|
/// <param name="size">Size of the rendered sphere.</param>
|
||||||
static void Sphere(const SHVec4& color, const SHVec3& pos, double radius);
|
static void Sphere(const SHVec4& color, const SHVec3& pos, double radius);
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Persistent Draw Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a line between two points in world space that will persist until
|
||||||
|
/// ClearPersistentDraws() is called.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the line.</param>
|
||||||
|
/// <param name="startPt">First point of the line.</param>
|
||||||
|
/// <param name="endPt">Second point of the line.</param>
|
||||||
|
static void PersistentLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a triangle indicated by three points in world space that will persist
|
||||||
|
/// until ClearPersistentDraws() is called.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the triangle.</param>
|
||||||
|
/// <param name="pt1">First point of the triangle.</param>
|
||||||
|
/// <param name="pt2">Second point of the triangle.</param>
|
||||||
|
/// <param name="pt3">Third point of the triangle.</param>
|
||||||
|
static void PersistentTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a quadrilateral indicated by four points in world space that will persist
|
||||||
|
/// until ClearPersistentDraws() is called.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the quadrilateral.</param>
|
||||||
|
/// <param name="pt1">First point of the triangle.</param>
|
||||||
|
/// <param name="pt2">Second point of the quadrilateral.</param>
|
||||||
|
/// <param name="pt3">Third point of the quadrilateral.</param>
|
||||||
|
/// <param name="pt4">Third point of the quadrilateral.</param>
|
||||||
|
static void PersistentQuad(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3, const SHVec3& pt4);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a polygon indicated by the specified set of points in world space that
|
||||||
|
/// will persist until ClearPersistentDraws() is called.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the polygon.</param>
|
||||||
|
/// <param name="pointList">List of points for the polygon.</param>
|
||||||
|
static void PersistentPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a wireframe cube centered around the position specified in world space
|
||||||
|
/// that will persist until ClearPersistentDraws() is called.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the cube.</param>
|
||||||
|
/// <param name="pos">Position where the cube wil be centered at.</param>
|
||||||
|
/// <param name="size">Size of the rendered cube.</param>
|
||||||
|
static void PersistentCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size);
|
||||||
|
/// <summary>
|
||||||
|
/// Renders a wireframe sphere centered around the position specified in world space
|
||||||
|
/// that will persist until ClearPersistentDraws() is called.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="color">Colour of the sphere.</param>
|
||||||
|
/// <param name="pos">Position where the sphere wil be centered at.</param>
|
||||||
|
/// <param name="size">Size of the rendered sphere.</param>
|
||||||
|
static void PersistentSphere(const SHVec4& color, const SHVec3& pos, double radius);
|
||||||
|
/// <summary>
|
||||||
|
/// Clears any persistent drawn debug primitives.
|
||||||
|
/// </summary>
|
||||||
|
static void ClearPersistentDraws();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Static Data Members */
|
/* Static Data Members */
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace SHADE
|
||||||
* @param[in] enumClassMember A member of the specified enum class.
|
* @param[in] enumClassMember A member of the specified enum class.
|
||||||
* @returns The value of the enum class member in the output type.
|
* @returns The value of the enum class member in the output type.
|
||||||
*/
|
*/
|
||||||
template <IsEnum InputType, IsIntegral OutputType = int>
|
template <IsEnum InputType, IsIntegral OutputType = std::underlying_type_t<InputType>>
|
||||||
static constexpr OutputType ConvertEnum(InputType enumClassMember) noexcept;
|
static constexpr OutputType ConvertEnum(InputType enumClassMember) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -148,6 +148,14 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
return Convert::ToCLI(GetNativeComponent()->GetTorque());
|
return Convert::ToCLI(GetNativeComponent()->GetTorque());
|
||||||
}
|
}
|
||||||
|
bool RigidBody::Interpolating::get()
|
||||||
|
{
|
||||||
|
return GetNativeComponent()->IsInterpolating();
|
||||||
|
}
|
||||||
|
void RigidBody::Interpolating::set(bool value)
|
||||||
|
{
|
||||||
|
GetNativeComponent()->SetInterpolate(value);
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Force Functions */
|
/* Force Functions */
|
||||||
|
|
|
@ -129,6 +129,11 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
Vector3 get();
|
Vector3 get();
|
||||||
}
|
}
|
||||||
|
property bool Interpolating
|
||||||
|
{
|
||||||
|
bool get();
|
||||||
|
void set(bool value);
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Force Functions */
|
/* Force Functions */
|
||||||
|
|
Loading…
Reference in New Issue