Merge branch 'main' into SP3-13-Assets-Manager

This commit is contained in:
Xiao Qi 2022-11-04 17:49:13 +08:00
commit 6d0089ee12
190 changed files with 7304 additions and 1601 deletions

View File

@ -1,16 +1,16 @@
[Window][MainStatusBar]
Pos=0,1060
Pos=0,1007
Size=1920,20
Collapsed=0
[Window][SHEditorMenuBar]
Pos=0,48
Size=1920,1012
Size=1920,959
Collapsed=0
[Window][Hierarchy Panel]
Pos=0,197
Size=308,863
Pos=0,189
Size=308,818
Collapsed=0
DockId=0x00000004,0
@ -21,13 +21,13 @@ Collapsed=0
[Window][Inspector]
Pos=1528,48
Size=392,1012
Size=392,959
Collapsed=0
DockId=0x00000006,0
[Window][Profiler]
Pos=0,48
Size=308,147
Size=308,139
Collapsed=0
DockId=0x00000003,0
@ -76,7 +76,7 @@ DockId=0x0000000B,0
[Window][ Viewport]
Pos=310,48
Size=1216,715
Size=1216,662
Collapsed=0
DockId=0x0000000B,0
@ -93,13 +93,19 @@ Collapsed=0
DockId=0x0000000A,0
[Window][ Asset Browser]
Pos=310,765
Pos=310,712
Size=1216,295
Collapsed=0
DockId=0x0000000C,0
[Window][Material Inspector]
Pos=1528,48
Size=392,959
Collapsed=0
DockId=0x00000006,1
[Docking][Data]
DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Split=X
DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=0,71 Size=1920,959 Split=X
DockNode ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1526,1036 Split=X
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=308,1036 Split=Y Selected=0x1E6EB881
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=225,147 Selected=0x1E6EB881
@ -111,5 +117,5 @@ DockSpace ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,79 Size=1920,1012 Spli
DockNode ID=0x0000000C Parent=0x00000009 SizeRef=1501,295 Selected=0xB128252A
DockNode ID=0x0000000A Parent=0x00000007 SizeRef=1501,310 Selected=0xD446F7B6
DockNode ID=0x00000008 Parent=0x00000002 SizeRef=1501,338 Selected=0xD9F31532
DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=392,1036 Selected=0xE7039252
DockNode ID=0x00000006 Parent=0xC5C9B8AB SizeRef=392,1036 Selected=0xD3697FB6

View File

@ -0,0 +1,8 @@
- VertexShader: 39210065
FragmentShader: 46377769
SubPass: G-Buffer Write
Properties:
data.color: {x: 1, y: 0.200000003, z: 0.100000001, w: 1}
data.textureIndex: 64651793
data.alpha: 0
data.beta: {x: 1, y: 1, z: 1}

View File

@ -0,0 +1,3 @@
Name: TestMat
ID: 126974645
Type: 7

View File

@ -0,0 +1,17 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
#extension GL_EXT_nonuniform_qualifier : require
layout(location = 0) in struct
{
vec4 vertColor;
} In;
layout(location = 0) out vec4 outColor;
void main()
{
outColor = In.vertColor;
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: DebugDraw_FS
ID: 36671027
Type: 2

View File

@ -0,0 +1,24 @@
#version 450
#extension GL_KHR_vulkan_glsl : enable
layout(location = 0) in vec4 aVertexPos;
layout(location = 1) in vec4 aVertColor;
layout(location = 0) out struct
{
vec4 vertColor; // location 0
} Out;
layout(set = 2, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
} cameraData;
void main()
{
gl_Position = cameraData.vpMat * vec4 (aVertexPos.xyz, 1.0f);
Out.vertColor = aVertColor;
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: DebugDraw_VS
ID: 48002439
Type: 2

View File

@ -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 = 2, rgba8) uniform image2D albedo;
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
{
@ -51,33 +52,46 @@ void main()
vec3 pixelDiffuse = imageLoad (albedo, globalThread).rgb;
// Get position of fragment in world space
vec3 positionWorld = imageLoad (positions, globalThread).rgb;
vec3 positionView = imageLoad (positions, globalThread).rgb;
// 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);
for (int i = 0; i < lightCounts.directionalLights; ++i)
{
// get normalized direction of light
vec3 dLightNormalized = normalize (DirLightData.dLightData[i].direction);
if ((lightLayer & DirLightData.dLightData[i].cullingMask) != 0)
{
// get normalized direction of light
vec3 dLightNormalized = normalize (DirLightData.dLightData[i].direction);
// Get diffuse strength
float diffuseStrength = max (0, dot (dLightNormalized, normalWorld));
// Get diffuse strength
float diffuseStrength = max (0, dot (dLightNormalized, normalView));
// Calculate the fragment color
fragColor += DirLightData.dLightData[i].diffuseColor.rgb * diffuseStrength.rrr * pixelDiffuse;
// Calculate the fragment color
fragColor += DirLightData.dLightData[i].diffuseColor.rgb * diffuseStrength.rrr * pixelDiffuse;
}
}
for (int i = 0; i < lightCounts.ambientLights; ++i)
{
// 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);
if ((lightLayer & AmbLightData.aLightData[i].cullingMask) != 0)
{
// 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
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));
}

View File

@ -1,3 +1,3 @@
Name: DeferredComposite_CS
ID: 42814284
ID: 45072428
Type: 2

Binary file not shown.

Binary file not shown.

View File

@ -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.

View File

@ -0,0 +1,3 @@
Name: SSAOBlur_CS
ID: 39760835
Type: 2

104
Assets/Shaders/SSAO_CS.glsl Normal file
View File

@ -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.

View File

@ -0,0 +1,3 @@
Name: SSAO_CS
ID: 38430899
Type: 2

View File

@ -43,7 +43,7 @@ void main()
{
position = In.vertPos;
normals = In.normal;
albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) + MatProp.data[In2.materialIndex].color / MatProp.data[In2.materialIndex].alpha;
albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) * MatProp.data[In2.materialIndex].color;
outEntityID = In2.eid;
lightLayerIndices = In2.lightLayerIndex;

Binary file not shown.

View File

@ -1,3 +1,3 @@
Name: TestCube_FS
ID: 37450402
ID: 46377769
Type: 2

View File

@ -33,18 +33,31 @@ layout(set = 2, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 projMat;
} cameraData;
void main()
{
Out2.materialIndex = gl_InstanceIndex;
Out2.eid = integerData[0];
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.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);
// clip space for rendering
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
}

Binary file not shown.

View File

@ -1,3 +1,3 @@
Name: TestCube_VS
ID: 41688429
ID: 39210065
Type: 2

View File

@ -31,6 +31,7 @@
#include "FRC/SHFramerateController.h"
#include "AudioSystem/SHAudioSystem.h"
#include "Camera/SHCameraSystem.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
// Components
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
@ -42,6 +43,7 @@
#include "Assets/SHAssetManager.h"
#include "Tools/SHLogger.h"
#include "Tools/SHDebugDraw.h"
using namespace SHADE;
@ -69,6 +71,10 @@ namespace Sandbox
SHGraphicsSystem* graphicsSystem = static_cast<SHGraphicsSystem*>(SHSystemManager::GetSystem<SHGraphicsSystem>());
SHSystemManager::CreateSystem<SHAudioSystem>();
SHSystemManager::CreateSystem<SHCameraSystem>();
SHSystemManager::CreateSystem<SHDebugDrawSystem>();
// Link up SHDebugDraw
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
#ifdef SHEDITOR
SDL_Init(SDL_INIT_VIDEO);
@ -88,8 +94,10 @@ namespace Sandbox
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPreUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsFixedUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsPostUpdate>();
SHSystemManager::RegisterRoutine<SHPhysicsSystem, SHPhysicsSystem::PhysicsDebugDraw>();
SHSystemManager::RegisterRoutine<SHTransformSystem, SHTransformSystem::TransformPostPhysicsUpdate>();
SHSystemManager::RegisterRoutine<SHDebugDrawSystem, SHDebugDrawSystem::ProcessPointsRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BatcherDispatcherRoutine>();
SHSystemManager::RegisterRoutine<SHGraphicsSystem, SHGraphicsSystem::BeginRoutine>();
@ -108,13 +116,10 @@ namespace Sandbox
SHComponentManager::CreateComponentSparseSet<SHColliderComponent>();
SHComponentManager::CreateComponentSparseSet<SHTransformComponent>();
SHComponentManager::CreateComponentSparseSet<SHRenderable>();
SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
//SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
SHAssetManager::Load();
auto id = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
auto id2 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
auto id3 = SHFamilyID<SHSystem>::GetID<SHGraphicsSystem>();
SHSystemManager::RegisterRoutine<SHAudioSystem, SHAudioSystem::AudioRoutine>();
@ -126,6 +131,9 @@ namespace Sandbox
SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
SHFrameRateController::UpdateFRC();
// Link up SHDebugDraw
SHDebugDraw::Init(SHSystemManager::GetSystem<SHDebugDrawSystem>());
}
void SBApplication::Update(void)
@ -144,6 +152,13 @@ namespace Sandbox
#endif
SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
editor->PollPicking();
static bool drawColliders = false;
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::F10))
{
drawColliders = !drawColliders;
SHSystemManager::GetSystem<SHPhysicsSystem>()->SetDrawColliders(drawColliders);
}
}
// Finish all graphics jobs first
graphicsSystem->AwaitGraphicsExecution();

View File

@ -16,7 +16,10 @@
#include "Assets/SHAssetManager.h"
#include "Camera/SHCameraComponent.h"
#include "Math/SHColour.h"
#include "Resource/SHResourceManager.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
#include "Tools/SHDebugDraw.h"
using namespace SHADE;
@ -62,58 +65,20 @@ namespace Sandbox
SHResourceManager::FinaliseChanges();
// Create Materials
auto matInst = graphicsSystem->AddOrGetBaseMaterialInstance();
auto customMat = graphicsSystem->AddMaterialInstanceCopy(matInst);
customMat->SetProperty("data.color", SHVec4(0.0f, 1.0f, 1.0f, 1.0f));
customMat->SetProperty("data.textureIndex", 0);
customMat->SetProperty("data.alpha", 0.1f);
auto baseRaccoonMat = graphicsSystem->AddOrGetBaseMaterialInstance();
auto baseRaccoonMatInstant = graphicsSystem->AddMaterialInstanceCopy(baseRaccoonMat);
baseRaccoonMatInstant->SetProperty("data.color", SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
baseRaccoonMatInstant->SetProperty("data.textureIndex", 0);
baseRaccoonMatInstant->SetProperty("data.alpha", 0.1f);
// Create Stress Test Objects
static const SHVec3 TEST_OBJ_SCALE = SHVec3::One;
constexpr int NUM_ROWS = 3;
constexpr int NUM_COLS = 1;
static const SHVec3 TEST_OBJ_SPACING = { 0.1f, 0.1f, 0.1f };
static const SHVec3 TEST_OBJ_START_POS = { -(NUM_COLS / 2 * TEST_OBJ_SPACING.x) + 1.0f, -2.0f, -1.0f };
auto baseFloorMatInstant = graphicsSystem->AddMaterialInstanceCopy(baseRaccoonMat);
baseFloorMatInstant->SetProperty("data.color", SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
baseFloorMatInstant->SetProperty("data.textureIndex", 0);
baseFloorMatInstant->SetProperty("data.alpha", 0.1f);
for (int y = 0; y < NUM_ROWS; ++y)
for (int x = 0; x < NUM_COLS; ++x)
{
auto entity = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>();
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(entity);
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(entity);
auto& collider = *SHComponentManager::GetComponent_s<SHColliderComponent>(entity);
auto dummy = SHEntityManager::CreateEntity<>();
//renderable.Mesh = handles.front();
renderable.SetMesh(CUBE_MESH);
renderable.SetMaterial(customMat);
if (y == 50)
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 0.0f, 0.0f, 1.0f));
//Set initial positions
transform.SetWorldPosition(TEST_OBJ_START_POS + SHVec3{ x * TEST_OBJ_SPACING.x, y * TEST_OBJ_SPACING.y, SHMath::GenerateRandomNumber(-3.5f, -5.0f) });
//transform.SetWorldPosition({-1.0f, -1.0f, -1.0f});
transform.SetWorldRotation(SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f));
transform.SetWorldScale(TEST_OBJ_SCALE);
collider.AddBoundingBox(SHVec3::One, SHVec3::Zero);
stressTestObjects.emplace_back(entity);
}
auto raccoonSpin = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
auto& renderable = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonSpin);
auto& transform = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonSpin);
renderable.SetMesh(handles.front());
renderable.SetMaterial(customMat);
renderable.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
renderable.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
renderable.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);
transform.SetWorldPosition({ -3.0f, -1.0f, -1.0f });
transform.SetLocalScale({ 5.0f, 5.0f, 5.0f });
auto floor = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>();
auto floor = SHEntityManager::CreateEntity<SHTransformComponent,SHRenderable, SHRigidBodyComponent, SHColliderComponent>();
auto& floorRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(floor);
auto& floorTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(floor);
auto& floorRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(floor);
@ -122,13 +87,12 @@ namespace Sandbox
floorRenderable.SetMesh(CUBE_MESH);
floorRenderable.SetMaterial(graphicsSystem->GetDefaultMaterialInstance());
floorTransform.SetWorldScale({ 7.5f, 0.5f, 7.5 });
floorTransform.SetWorldScale({ 17.5f, 0.5f, 17.5f });
floorTransform.SetWorldPosition({ 0.0f, -3.0f, -5.0f });
floorRigidBody.SetType(SHRigidBodyComponent::Type::STATIC);
auto* floorBox = floorCollider.AddBoundingBox();
floorBox->SetHalfExtents(floorTransform.GetWorldScale() * 0.5f);
// Create blank entity with a script
//testObj = SHADE::SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
@ -136,17 +100,96 @@ namespace Sandbox
//testObjRenderable.Mesh = CUBE_MESH;
//testObjRenderable.SetMaterial(matInst);
//raccoon =======================================================================================================================
auto racoon = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>(MAX_EID, "Player");
auto& racoonRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(racoon);
auto& racoonTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(racoon);
auto& racoonRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(racoon);
auto& racoonCollider = *SHComponentManager::GetComponent_s<SHColliderComponent>(racoon);
racoonRenderable.SetMesh(handles.front());
racoonRenderable.SetMaterial(baseRaccoonMatInstant);
racoonTransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
racoonTransform.SetWorldPosition({ -3.0f, -2.0f, -5.0f });
racoonCollider.AddBoundingBox();
racoonCollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f,0.5f,0.0f));
racoonCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
auto racoonItemLocation = SHEntityManager::CreateEntity<SHTransformComponent>();
auto& racoonItemLocationTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(racoonItemLocation);
SHSceneManager::GetCurrentSceneGraph().SetParent(racoonItemLocation, racoon);
auto racoonCamera = SHEntityManager::CreateEntity<SHTransformComponent>();
SHSceneManager::GetCurrentSceneGraph().SetParent(racoonCamera, racoon);
//================================================================================================================================
//item ===========================================================================================================================
auto item = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>(MAX_EID, "item");
auto& itemRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(item);
auto& itemTransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(item);
auto& itemRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(item);
auto& itemCollider = *SHComponentManager::GetComponent_s<SHColliderComponent>(item);
itemRenderable.SetMesh(handles.front());
itemRenderable.SetMaterial(baseRaccoonMatInstant);
itemTransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
itemTransform.SetWorldPosition({ 0.0f, -2.0f, -5.0f });
itemCollider.AddBoundingBox();
itemCollider.AddBoundingBox(SHVec3(2.0f,2.0f,2.0f));
itemCollider.GetCollider(1).SetIsTrigger(true);
itemCollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
itemCollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
itemCollider.GetCollider(1).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
itemCollider.GetCollider(1).SetBoundingBox(SHVec3(1.0f, 1.0f, 1.0f));
itemRigidBody.SetInterpolate(false);
itemRigidBody.SetFreezeRotationX(true);
itemRigidBody.SetFreezeRotationY(true);
itemRigidBody.SetFreezeRotationZ(true);
//================================================================================================================================
//AI =============================================================================================================================
auto AI = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent, SHRigidBodyComponent, SHColliderComponent>(MAX_EID, "AI");
auto& AIRenderable = *SHComponentManager::GetComponent_s<SHRenderable>(AI);
auto& AITransform = *SHComponentManager::GetComponent_s<SHTransformComponent>(AI);
auto& AIRigidBody = *SHComponentManager::GetComponent_s<SHRigidBodyComponent>(AI);
auto& AICollider = *SHComponentManager::GetComponent_s<SHColliderComponent>(AI);
AIRenderable.SetMesh(handles.front());
AIRenderable.SetMaterial(baseRaccoonMatInstant);
AITransform.SetWorldScale({ 2.0f, 2.0f, 2.0f });
AITransform.SetWorldPosition({ -8.0f, -2.0f, 2.5f });
AICollider.AddBoundingBox();
AICollider.GetCollider(0).SetPositionOffset(SHVec3(0.0f, 0.5f, 0.0f));
AICollider.GetCollider(0).SetBoundingBox(SHVec3(0.5f, 0.5f, 0.5f));
AIRigidBody.SetInterpolate(false);
AIRigidBody.SetFreezeRotationX(true);
AIRigidBody.SetFreezeRotationY(true);
AIRigidBody.SetFreezeRotationZ(true);
//================================================================================================================================
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
scriptEngine->AddScript(raccoonSpin, "RaccoonSpin");
scriptEngine->AddScript(racoon, "PlayerController");
scriptEngine->AddScript(racoon, "PickAndThrow");
scriptEngine->AddScript(racoonCamera, "ThirdPersonCamera");
scriptEngine->AddScript(AI, "AIPrototype");
auto raccoonShowcase = SHEntityManager::CreateEntity<SHRenderable, SHTransformComponent>();
auto& renderableShowcase = *SHComponentManager::GetComponent_s<SHRenderable>(raccoonShowcase);
auto& transformShowcase = *SHComponentManager::GetComponent_s<SHTransformComponent>(raccoonShowcase);
renderableShowcase.SetMesh(handles.front());
renderableShowcase.SetMaterial(customMat);
renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(0.0f, 0.0f, 0.0f, 0.0f));
renderableShowcase.SetMaterial(baseRaccoonMatInstant);
renderableShowcase.GetModifiableMaterial()->SetProperty("data.color", SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
renderableShowcase.GetModifiableMaterial()->SetProperty("data.alpha", 1.0f);
renderableShowcase.GetModifiableMaterial()->SetProperty("data.textureIndex", 0);
@ -160,7 +203,7 @@ namespace Sandbox
SHComponentManager::RemoveComponent <SHColliderComponent>(0);
auto ambientLight = SHEntityManager::CreateEntity<SHLightComponent>();
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetColor(SHVec4(1.0f, 1.0f, 1.0f, 1.0f));
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetColor(SHColour::WHITE);
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetStrength(0.25f);
SHComponentManager::GetComponent<SHLightComponent>(ambientLight)->SetType(SH_LIGHT_TYPE::AMBIENT);
}
@ -187,6 +230,8 @@ namespace Sandbox
SHADE::SHScriptEngine* scriptEngine = static_cast<SHADE::SHScriptEngine*>(SHADE::SHSystemManager::GetSystem<SHADE::SHScriptEngine>());
scriptEngine->RemoveAllScripts(testObj);
}
SHDebugDraw::Cube(SHColour::CRIMSON, SHVec3(1.0f, 0.0f, 0.0f), SHVec3(1.0f, 1.0f, 1.0f));
}
void SBTestScene::Render()

View File

@ -33,11 +33,11 @@ namespace SHADE
struct SH_API SHMeshData : SHAssetData
{
SHMeshAssetHeader header;
std::vector<SHVec3> vertexPositions;
std::vector<SHVec3> vertexTangents;
std::vector<SHVec3> vertexNormals;
std::vector<SHVec2> vertexTexCoords;
std::vector<uint32_t> indices;
std::vector<SHVec3> VertexPositions;
std::vector<SHVec3> VertexTangents;
std::vector<SHVec3> VertexNormals;
std::vector<SHVec2> VertexTexCoords;
std::vector<uint32_t> Indices;
};
struct SH_API SHModelAsset : SHAssetData

View File

@ -10,6 +10,7 @@
*****************************************************************************/
#pragma once
#include <vulkan/vulkan.hpp>
#include "SHAssetData.h"
#include "SH_API.h"
#include <vector>
@ -17,12 +18,14 @@
namespace SHADE
{
//! Tighter control over types of shaders. Maps directly to their
//! equivalent vk::ShaderStageFlagBits.
enum class SH_SHADER_TYPE : uint8_t
{
VERTEX,
FRAGMENT,
COMPUTE,
INAVLID_TYPE
VERTEX = static_cast<uint8_t>(vk::ShaderStageFlagBits::eVertex),
FRAGMENT = static_cast<uint8_t>(vk::ShaderStageFlagBits::eFragment),
COMPUTE = static_cast<uint8_t>(vk::ShaderStageFlagBits::eCompute),
INAVLID_TYPE = std::numeric_limits<uint8_t>::max()
};
struct SH_API SHShaderAsset : SHAssetData

View File

@ -19,144 +19,145 @@
namespace SHADE
{
std::string SHShaderSourceCompiler::CompileShaderSourceToBinary(AssetPath path, SHShaderAsset const& data) noexcept
{
std::string newPath{ path.string() };
std::string SHShaderSourceCompiler::CompileShaderSourceToBinary(AssetPath path, SHShaderAsset const& data) noexcept
{
std::string newPath{ path.string() };
newPath = newPath.substr(0, newPath.find_last_of('.'));
newPath += SHADER_BUILT_IN_EXTENSION.data();
std::ofstream file{ newPath, std::ios::binary | std::ios::out | std::ios::trunc };
std::ofstream file{ newPath, std::ios::binary | std::ios::out | std::ios::trunc };
file.write(
reinterpret_cast<char const*>(& data.shaderType), sizeof(uint8_t)
);
file.write(
reinterpret_cast<char const*>(& data.shaderType), sizeof(uint8_t)
);
size_t const byteCount = sizeof(uint32_t) * data.spirvBinary.size();
size_t const byteCount = sizeof(uint32_t) * data.spirvBinary.size();
file.write(
reinterpret_cast<char const*>(&byteCount), sizeof(size_t)
);
file.write(
reinterpret_cast<char const*>(&byteCount), sizeof(size_t)
);
file.write(
reinterpret_cast<char const*>(data.spirvBinary.data()), byteCount
);
file.write(
reinterpret_cast<char const*>(data.spirvBinary.data()), byteCount
);
file.close();
file.close();
return newPath;
}
return newPath;
}
SHShaderAsset const* SHShaderSourceCompiler::CompileShaderSourceToMemory(std::string const& data, std::string const& name, SH_SHADER_TYPE type) noexcept
{
// shaderc compiler
shaderc::Compiler compiler;
shaderc::CompileOptions options;
SHShaderAsset const* SHShaderSourceCompiler::CompileShaderSourceToMemory(std::string const& data, std::string const& name, SH_SHADER_TYPE type) noexcept
{
// shaderc compiler
shaderc::Compiler compiler;
shaderc::CompileOptions options;
options.AddMacroDefinition("MY_DEFINE", "1");
options.AddMacroDefinition("MY_DEFINE", "1");
//TODO: Check if we need optimisation levels when compiling into spirv
// Set optimization levels
//if (opLevel != shaderc_optimization_level_zero)
// options.SetOptimizationLevel(opLevel);
//TODO: Check if we need optimisation levels when compiling into spirv
// Set optimization levels
//if (opLevel != shaderc_optimization_level_zero)
// options.SetOptimizationLevel(opLevel);
// Attempt to get the shaderc equivalent shader stage
shaderc_shader_kind shaderKind;
switch (type)
{
case SH_SHADER_TYPE::VERTEX:
shaderKind = shaderc_shader_kind::shaderc_glsl_vertex_shader;
break;
case SH_SHADER_TYPE::FRAGMENT:
shaderKind = shaderc_shader_kind::shaderc_glsl_fragment_shader;
break;
case SH_SHADER_TYPE::COMPUTE:
shaderKind = shaderc_shader_kind::shaderc_glsl_compute_shader;
break;
default:
shaderKind = shaderc_shader_kind::shaderc_glsl_vertex_shader;
break;
}
// Attempt to get the shaderc equivalent shader stage
shaderc_shader_kind shaderKind;
switch (type)
{
case SH_SHADER_TYPE::VERTEX:
shaderKind = shaderc_shader_kind::shaderc_glsl_vertex_shader;
break;
case SH_SHADER_TYPE::FRAGMENT:
shaderKind = shaderc_shader_kind::shaderc_glsl_fragment_shader;
break;
case SH_SHADER_TYPE::COMPUTE:
shaderKind = shaderc_shader_kind::shaderc_glsl_compute_shader;
break;
default:
shaderKind = shaderc_shader_kind::shaderc_glsl_vertex_shader;
break;
}
// Compile the shader and get the result
shaderc::SpvCompilationResult compileResult = compiler.CompileGlslToSpv(data, shaderKind, name.c_str(), options);
// Compile the shader and get the result
shaderc::SpvCompilationResult compileResult = compiler.CompileGlslToSpv(data, shaderKind, name.c_str(), options);
if (compileResult.GetCompilationStatus() != shaderc_compilation_status_success)
{
SHLOG_ERROR("Shaderc failed to compile GLSL shader to binary | " + compileResult.GetErrorMessage());
return nullptr;
}
if (compileResult.GetCompilationStatus() != shaderc_compilation_status_success)
{
SHLOG_ERROR("Shaderc failed to compile GLSL shader to binary | " + compileResult.GetErrorMessage());
return nullptr;
}
auto result = new SHShaderAsset();
result->spirvBinary.resize(compileResult.end() - compileResult.begin());
auto result = new SHShaderAsset();
result->spirvBinary.resize(compileResult.end() - compileResult.begin());
std::ranges::copy(compileResult.begin(), compileResult.end(), result->spirvBinary.data());
std::ranges::copy(compileResult.begin(), compileResult.end(), result->spirvBinary.data());
result->name = name;
result->shaderType = type;
return result;
}
return result;
}
SH_SHADER_TYPE SHShaderSourceCompiler::GetShaderTypeFromFilename(std::string name) noexcept
{
for (auto i { 0}; i < SHADER_TYPE_MAX_COUNT; ++i)
{
if (name.find(SHADER_IDENTIFIERS[i].data()) != std::string::npos)
{
return static_cast<SH_SHADER_TYPE>(i);
}
}
SH_SHADER_TYPE SHShaderSourceCompiler::GetShaderTypeFromFilename(std::string name) noexcept
{
for (auto i { 0 }; i < SHADER_TYPE_MAX_COUNT; ++i)
{
const auto& [SHADER_SUFFIX, SHADER_TYPE] = SHADER_IDENTIFIERS[i];
if (name.find(SHADER_SUFFIX.data()) != std::string::npos)
{
return SHADER_TYPE;
}
}
return SH_SHADER_TYPE::INAVLID_TYPE;
}
return SH_SHADER_TYPE::INAVLID_TYPE;
}
std::optional<AssetPath> SHShaderSourceCompiler::LoadAndCompileShader(AssetPath path) noexcept
{
auto type = GetShaderTypeFromFilename(path.filename().string());
{
auto type = GetShaderTypeFromFilename(path.filename().string());
if (type == SH_SHADER_TYPE::INAVLID_TYPE)
{
SHLOG_ERROR("Invalid filename for shaders, follow suffix in SHAssetMacros.h: {}", path.string());
return {};
}
if (type == SH_SHADER_TYPE::INAVLID_TYPE)
{
SHLOG_ERROR("Invalid filename for shaders, follow suffix in SHAssetMacros.h: {}", path.string());
return {};
}
path.make_preferred();
std::ifstream file{ path.string(), std::ios::in };
std::ifstream file{ path.string(), std::ios::in };
if (file.is_open())
{
std::stringstream stream;
if (file.is_open())
{
std::stringstream stream;
stream << file.rdbuf();
stream << file.rdbuf();
std::string const content = stream.str();
std::string const content = stream.str();
auto data = CompileShaderSourceToMemory(content, path.filename().string(), type);
auto data = CompileShaderSourceToMemory(content, path.filename().string(), type);
if (data == nullptr)
{
return{};
}
if (data == nullptr)
{
return{};
}
return CompileShaderSourceToBinary(path, *data);
}
return CompileShaderSourceToBinary(path, *data);
}
SHLOG_ERROR("Unable to open shader file: {}", path.string());
SHLOG_ERROR("Unable to open shader file: {}", path.string());
return {};
}
return {};
}
std::optional<AssetPath> SHShaderSourceCompiler::CompileShaderFromString
(std::string const& string, AssetPath path, SH_SHADER_TYPE type) noexcept
{
auto const data = CompileShaderSourceToMemory(string, path.filename().string(), type);
std::optional<AssetPath> SHShaderSourceCompiler::CompileShaderFromString
(std::string const& string, AssetPath path, SH_SHADER_TYPE type) noexcept
{
auto const data = CompileShaderSourceToMemory(string, path.filename().string(), type);
if (data == nullptr)
{
return{};
}
if (data == nullptr)
{
return{};
}
return CompileShaderSourceToBinary(path, *data);
}
return CompileShaderSourceToBinary(path, *data);
}
}

View File

@ -29,19 +29,19 @@ namespace SHADE
auto const vertexVec3Byte{ sizeof(SHVec3) * header.vertexCount };
auto const vertexVec2Byte{ sizeof(SHVec2) * header.vertexCount };
data.vertexPositions.resize(header.vertexCount);
data.vertexTangents.resize(header.vertexCount);
data.vertexNormals.resize(header.vertexCount);
data.vertexTexCoords.resize(header.vertexCount);
data.indices.resize(header.indexCount);
data.VertexPositions.resize(header.vertexCount);
data.VertexTangents.resize(header.vertexCount);
data.VertexNormals.resize(header.vertexCount);
data.VertexTexCoords.resize(header.vertexCount);
data.Indices.resize(header.indexCount);
data.header.name.resize(header.charCount);
file.read(data.header.name.data(), header.charCount);
file.read(reinterpret_cast<char*>(data.vertexPositions.data()), vertexVec3Byte);
file.read(reinterpret_cast<char*>(data.vertexTangents.data()), vertexVec3Byte);
file.read(reinterpret_cast<char*>(data.vertexNormals.data()), vertexVec3Byte);
file.read(reinterpret_cast<char*>(data.vertexTexCoords.data()), vertexVec2Byte);
file.read(reinterpret_cast<char*>(data.indices.data()), sizeof(uint32_t) * header.indexCount);
file.read(reinterpret_cast<char*>(data.VertexPositions.data()), vertexVec3Byte);
file.read(reinterpret_cast<char*>(data.VertexTangents.data()), vertexVec3Byte);
file.read(reinterpret_cast<char*>(data.VertexNormals.data()), vertexVec3Byte);
file.read(reinterpret_cast<char*>(data.VertexTexCoords.data()), vertexVec2Byte);
file.read(reinterpret_cast<char*>(data.Indices.data()), sizeof(uint32_t) * header.indexCount);
data.header.vertexCount = header.vertexCount;
data.header.indexCount = header.indexCount;

View File

@ -11,6 +11,10 @@
#pragma once
#include "SHAssetLoader.h"
#include "Assets/Asset Types/SHPrefabAsset.h"
#include "Assets/Asset Types/SHSceneAsset.h"
#include "Assets/Asset Types/SHMaterialAsset.h"
namespace SHADE
{
struct SHTextBasedLoader : SHAssetLoader

View File

@ -13,6 +13,7 @@
#include <cstdint>
#include <string>
#include <filesystem>
#include "Asset Types/SHShaderAsset.h"
// FMOD Fwd Declare
namespace FMOD
@ -117,10 +118,10 @@ constexpr std::string_view VERTEX_SHADER{ "_VS" };
constexpr std::string_view FRAGMENT_SHADER{ "_FS" };
constexpr std::string_view COMPUTER_SHADER{ "_CS" };
constexpr std::string_view SHADER_IDENTIFIERS[] = {
VERTEX_SHADER,
FRAGMENT_SHADER,
COMPUTER_SHADER
constexpr std::pair<std::string_view, SHADE::SH_SHADER_TYPE> SHADER_IDENTIFIERS[] = {
std::make_pair(VERTEX_SHADER, SHADE::SH_SHADER_TYPE::VERTEX),
std::make_pair(FRAGMENT_SHADER, SHADE::SH_SHADER_TYPE::FRAGMENT),
std::make_pair(COMPUTER_SHADER, SHADE::SH_SHADER_TYPE::COMPUTE)
};
constexpr size_t SHADER_TYPE_MAX_COUNT{ 3 };

View File

@ -153,19 +153,29 @@ namespace SHADE
****************************************************************************/
AssetID SHAssetManager::CreateNewAsset(AssetType type, AssetName name) noexcept
{
SHAssetData* data = nullptr;
std::string newPath{ ASSET_ROOT };
switch (type)
{
case AssetType::PREFAB:
newPath += PREFAB_FOLDER;
newPath += name;
newPath += PREFAB_EXTENSION;
data = new SHPrefabAsset();
break;
case AssetType::SCENE:
newPath += SCENE_FOLDER;
newPath += name;
newPath += SCENE_EXTENSION;
data = new SHSceneAsset();
break;
case AssetType::MATERIAL:
newPath += MATERIAL_FOLDER;
newPath += name;
newPath += MATERIAL_EXTENSION;
data = new SHMaterialAsset();
break;
default:
@ -193,6 +203,8 @@ namespace SHADE
)
});
assetData.emplace(id, data);
return id;
}

View File

@ -0,0 +1,68 @@
#include "SHpch.h"
#include "SHCameraArmComponent.h"
namespace SHADE
{
SHCameraArmComponent::SHCameraArmComponent()
:pitch(0.0f), yaw(0.0f), armLength(1.0f),offset(), dirty(true), lookAtCameraOrigin(true)
{
}
SHVec3 const& SHCameraArmComponent::GetOffset() const noexcept
{
return offset;
}
float SHCameraArmComponent::GetPitch() const noexcept
{
return pitch;
}
float SHCameraArmComponent::GetYaw() const noexcept
{
return yaw;
}
float SHCameraArmComponent::GetArmLength() const noexcept
{
return armLength;
}
void SHCameraArmComponent::SetPitch(float pitch) noexcept
{
this->pitch = pitch;
dirty = true;
}
void SHCameraArmComponent::SetYaw(float yaw) noexcept
{
this->yaw = yaw;
dirty = true;
}
void SHCameraArmComponent::SetArmLength(float length) noexcept
{
this->armLength = length;
dirty = true;
}
}//namespace SHADE
RTTR_REGISTRATION
{
using namespace SHADE;
using namespace rttr;
registration::class_<SHCameraArmComponent>("Camera Arm Component")
.property("Arm Pitch", &SHCameraArmComponent::GetPitch, &SHCameraArmComponent::SetPitch)
.property("Arm Yaw", &SHCameraArmComponent::GetYaw, &SHCameraArmComponent::SetYaw)
.property("Arm Length", &SHCameraArmComponent::GetArmLength, &SHCameraArmComponent::SetArmLength)
.property("Look At Camera Origin", &SHCameraArmComponent::lookAtCameraOrigin);
}

View File

@ -0,0 +1,44 @@
#pragma once
#include <rttr/registration>
#include "ECS_Base/Components/SHComponent.h"
#include "Math/SHMatrix.h"
#include "SH_API.h"
namespace SHADE
{
class SH_API SHCameraArmComponent final: public SHComponent
{
private:
float pitch;
float yaw;
float armLength;
bool dirty;
SHVec3 offset;
public:
friend class SHCameraSystem;
SHCameraArmComponent();
virtual ~SHCameraArmComponent() = default;
bool lookAtCameraOrigin;
//Getters
//SHMatrix const& GetMatrix() const noexcept;
SHVec3 const& GetOffset() const noexcept;
float GetPitch() const noexcept;
float GetYaw() const noexcept;
float GetArmLength() const noexcept;
//Setters
void SetPitch(float pitch) noexcept;
void SetYaw(float yaw) noexcept;
void SetArmLength(float length) noexcept;
protected:
};
}//namespace SHADE

View File

@ -13,7 +13,7 @@ namespace SHADE
, width(1920.0f), height(1080.0f), zNear(0.01f), zFar(10000.0f), fov(90.0f), movementSpeed(1.0f), turnSpeed(0.5f)
, perspProj(true), dirtyView(true), dirtyProj(true)
, viewMatrix(), projMatrix()
, position()
, position(), offset()
{
ComponentFamily::GetID<SHCameraComponent>();
}

View File

@ -33,7 +33,7 @@ namespace SHADE
SHVec3 position;
bool perspProj;
SHVec3 offset;
@ -41,7 +41,7 @@ namespace SHADE
friend class SHCameraSystem;
SHCameraComponent();
~SHCameraComponent();
virtual ~SHCameraComponent();
//Getters and setters.

View File

@ -1,6 +1,7 @@
#include "SHpch.h"
#include "SHCameraDirector.h"
#include "SHCameraComponent.h"
#include "SHCameraArmComponent.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "ECS_Base/SHECSMacros.h"
#include "ECS_Base/Managers/SHEntityManager.h"
@ -48,6 +49,7 @@ namespace SHADE
viewMatrix = camComponent->GetViewMatrix();
projMatrix = camComponent->GetProjMatrix();
}
}
void SHCameraDirector::SetMainCamera(SHCameraComponent& camera) noexcept

View File

@ -21,6 +21,7 @@ namespace SHADE
EntityID mainCameraEID;
EntityID transitionCameraEID;
SHMatrix GetViewMatrix() const noexcept;
SHMatrix GetProjMatrix() const noexcept;
@ -35,7 +36,7 @@ namespace SHADE
protected:
SHMatrix viewMatrix;
SHMatrix projMatrix;
};
typedef Handle<SHCameraDirector> DirectorHandle;

View File

@ -1,10 +1,12 @@
#include "SHpch.h"
#include "SHCameraSystem.h"
#include "SHCameraArmComponent.h"
#include "Math/SHMathHelpers.h"
#include "Input/SHInputManager.h"
#include "Math/Vector/SHVec2.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "Math/Transform/SHTransformComponent.h"
#include <math.h>
namespace SHADE
@ -59,6 +61,7 @@ namespace SHADE
}
UpdateCameraComponent(editorCamera);
}
void SHCameraSystem::EditorCameraUpdate::Execute(double dt) noexcept
{
@ -112,6 +115,8 @@ namespace SHADE
//std::cout << "Camera position: " << camera.position.x << " " << camera.position.y << std::endl;
system->UpdateCameraComponent(system->editorCamera);
system->DecomposeViewMatrix(camera.viewMatrix, camera.pitch, camera.yaw, camera.roll, camera.position);
}
void SHCameraSystem::Init(void)
@ -121,6 +126,9 @@ namespace SHADE
editorCamera.SetYaw(0.0f);
editorCamera.SetRoll(0.0f);
editorCamera.movementSpeed = 2.0f;
SHComponentManager::CreateComponentSparseSet<SHCameraComponent>();
SHComponentManager::CreateComponentSparseSet<SHCameraArmComponent>();
}
@ -134,6 +142,26 @@ namespace SHADE
return &editorCamera;
}
void SHCameraSystem::UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept
{
if (pivot.dirty)
{
SHVec3 offset{ 0.0f,0.0f, pivot.GetArmLength() };
offset = SHVec3::RotateX(offset, -(SHMath::DegreesToRadians(pivot.GetPitch())));
offset = SHVec3::RotateY(offset, (SHMath::DegreesToRadians(pivot.GetYaw())));
//pivot.rtMatrix = SHMatrix::RotateX(SHMath::DegreesToRadians(pivot.GetPitch()))
// * SHMatrix::RotateY(SHMath::DegreesToRadians(pivot.GetYaw()))
// * SHMatrix::Translate(SHVec3(0.0f , 0.0f, pivot.GetArmLength()));
pivot.offset = offset;
// pivot.rtMatrix = SHMatrix::Inverse(pivot.rtMatrix);
}
}
void SHCameraSystem::UpdateCameraComponent(SHCameraComponent& camera) noexcept
{
if (SHComponentManager::HasComponent<SHTransformComponent>(camera.GetEID()) == true && &camera != &editorCamera)
@ -151,6 +179,15 @@ namespace SHADE
if (camera.dirtyView)
{
camera.offset = SHVec3{ 0.0f };
if (SHComponentManager::HasComponent<SHCameraArmComponent>(camera.GetEID()))
{
auto arm = SHComponentManager::GetComponent<SHCameraArmComponent>(camera.GetEID());
camera.offset = arm->GetOffset();
if(arm->lookAtCameraOrigin)
CameraLookAt(camera, camera.position);
}
SHVec3 view, right, UP;
@ -171,9 +208,12 @@ namespace SHADE
camera.viewMatrix(2, 1) = view[1];
camera.viewMatrix(2, 2) = view[2];
camera.viewMatrix(0, 3) = -right.Dot(camera.position);
camera.viewMatrix(1, 3) = -UP.Dot(camera.position);
camera.viewMatrix(2, 3) = -view.Dot(camera.position);
camera.viewMatrix(0, 3) = -right.Dot(camera.position + camera.offset);
camera.viewMatrix(1, 3) = -UP.Dot(camera.position + camera.offset);
camera.viewMatrix(2, 3) = -view.Dot(camera.position + camera.offset);
camera.dirtyView = false;
}
@ -221,6 +261,8 @@ namespace SHADE
SHVec3 up = { 0.0f,1.0f,0.0f };
target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw));
target += camera.position;
@ -241,6 +283,13 @@ namespace SHADE
{
SHCameraSystem* system = static_cast<SHCameraSystem*>(GetSystem());
auto& dense = SHComponentManager::GetDense<SHCameraComponent>();
auto& pivotDense = SHComponentManager::GetDense<SHCameraArmComponent>();
for (auto& pivot : pivotDense)
{
system->UpdatePivotArmComponent(pivot);
}
for (auto& cam : dense)
{
system->UpdateCameraComponent(cam);
@ -274,18 +323,115 @@ namespace SHADE
}
void SHCameraSystem::ClampCameraRotation(SHCameraComponent& camera) noexcept
{
constexpr float clampVal = 85.0f;
if (camera.pitch > clampVal)
camera.SetPitch(clampVal);
if (camera.pitch < -clampVal)
camera.SetPitch(-clampVal);
if (camera.roll > clampVal)
camera.SetRoll(clampVal);
if (camera.roll < -clampVal)
camera.SetRoll(-clampVal);
if (camera.pitch > 85)
camera.SetPitch(85);
if (camera.pitch < -85)
camera.SetPitch(-85);
if (camera.roll > 85)
camera.SetRoll(85);
if (camera.roll < -85)
camera.SetRoll(-85);
while (camera.yaw > 360)
camera.yaw -= 360;
while (camera.yaw < -360)
camera.yaw += 360;
}
void SHCameraSystem::SetMainCamera(EntityID eid, size_t directorIndex) noexcept
{
if (SHComponentManager::HasComponent<SHCameraComponent>(eid) && directorIndex < directorHandleList.size())
directorHandleList[directorIndex]->SetMainCamera(*SHComponentManager::GetComponent<SHCameraComponent>(eid));
else
{
SHLOG_WARNING("Set Main Camera warning: Entity does not have camera component or director does not exist.")
}
}
void SHCameraSystem::DecomposeViewMatrix(SHMatrix const& viewMatrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept
{
float initPitch = pitch;
SHVec3 initPos = pos;
SHVec3 translate3, scale;
SHQuaternion quat;
//SHMatrix viewInverse = viewMatrix;
viewMatrix.Decompose(translate3, quat, scale);
yaw = 180+ SHMath::RadiansToDegrees(quat.ToEuler().y);
pitch = -SHMath::RadiansToDegrees(quat.ToEuler().x);
SHVec4 dotPos{ -viewMatrix(0,3),-viewMatrix(1,3), -viewMatrix(2,3), 1.0f };
SHMatrix mtx = viewMatrix;
mtx(0, 3) = 0.0f;
mtx(1, 3) = 0.0f;
mtx(2, 3) = 0.0f;
mtx.Transpose();
mtx = SHMatrix::Inverse(mtx);
SHVec4 translate = mtx* dotPos;
pos.x = translate.x;
pos.y = translate.y;
pos.z = translate.z;
}
void SHCameraSystem::SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) noexcept
{
DecomposeViewMatrix(viewMatrix, camera.pitch, camera.yaw, camera.roll, camera.position);
camera.dirtyView = true;
}
void SHCameraSystem::CameraLookAt(SHCameraComponent& camera, SHVec3 target) noexcept
{
if (camera.position == target)
{
//lets off set it abit so the view is nt fked
target.z -= 0.0001f;
}
SHVec3 forward, right, upVec;
SHVec3 up = { 0.0f,1.0f,0.0f };
////SHVec3::RotateZ(target, SHMath::DegreesToRadians(camera.roll));
//target = SHVec3::Normalise(target);
SHVec3::RotateZ(up, camera.roll);
up = SHVec3::Normalise(up);
forward = target - (camera.position + camera.offset); forward = SHVec3::Normalise(forward);
right = SHVec3::Cross(forward, up); right = SHVec3::Normalise(right);
upVec = SHVec3::Cross(forward, right);
SHMatrix viewMtx;
viewMtx = SHMatrix::Identity;
viewMtx(0, 0) = right[0];
viewMtx(0, 1) = right[1];
viewMtx(0, 2) = right[2];
viewMtx(1, 0) = upVec[0];
viewMtx(1, 1) = upVec[1];
viewMtx(1, 2) = upVec[2];
viewMtx(2, 0) = forward[0];
viewMtx(2, 1) = forward[1];
viewMtx(2, 2) = forward[2];
viewMtx(0, 3) = -right.Dot(camera.position + camera.offset);
viewMtx(1, 3) = -upVec.Dot(camera.position + camera.offset);
viewMtx(2, 3) = -forward.Dot(camera.position + camera.offset);
SetCameraViewMatrix(camera, viewMtx);
}
}

View File

@ -9,6 +9,9 @@
namespace SHADE
{
class SHCameraArmComponent;
class SH_API SHCameraSystem final : public SHSystem
{
private:
@ -19,6 +22,11 @@ namespace SHADE
SHResourceLibrary<SHCameraDirector> directorLibrary;
std::vector<DirectorHandle> directorHandleList;
void UpdateCameraComponent(SHCameraComponent& camera) noexcept;
void UpdatePivotArmComponent(SHCameraArmComponent& pivot) noexcept;
public:
SHCameraSystem(void) = default;
virtual ~SHCameraSystem(void) = default;
@ -39,7 +47,7 @@ namespace SHADE
class SH_API CameraSystemUpdate final: public SHSystemRoutine
{
public:
CameraSystemUpdate() : SHSystemRoutine("Camera System Update", false) {};
CameraSystemUpdate() : SHSystemRoutine("Camera System Update", true) {};
virtual void Execute(double dt)noexcept override final;
};
friend class CameraSystemUpdate;
@ -51,12 +59,10 @@ namespace SHADE
DirectorHandle GetDirector(size_t index) noexcept;
void ClampCameraRotation(SHCameraComponent& camera) noexcept;
void UpdateEditorCamera(double dt) noexcept;
protected:
void UpdateCameraComponent(SHCameraComponent& camera) noexcept;
void SetMainCamera(EntityID eid, size_t directorIndex) noexcept;
void DecomposeViewMatrix(SHMatrix const& matrix, float& pitch, float& yaw, float& roll, SHVec3& pos) noexcept;
void SetCameraViewMatrix(SHCameraComponent& camera, SHMatrix const& viewMatrix) noexcept;
void CameraLookAt(SHCameraComponent& camera, SHVec3 target) noexcept;
};

View File

@ -33,12 +33,18 @@ namespace SHADE
return;
}
std::vector<SHComponentRemovedEvent> eventVec;
for (uint32_t i = 0; i < componentSet.Size(); ++i)
{
SHComponent* comp = (SHComponent*) componentSet.GetElement(i, EntityHandleGenerator::GetIndex(entityID));
if (comp)
{
comp->OnDestroy();
SHComponentRemovedEvent eventData;
eventData.eid = entityID;
eventData.removedComponentType = i;
eventVec.push_back(eventData);
}
}
@ -51,8 +57,15 @@ namespace SHADE
componentSet.RemoveElements(EntityHandleGenerator::GetIndex(entityID));
for (auto& eventData : eventVec)
{
SHEventManager::BroadcastEvent<SHComponentRemovedEvent>(eventData, SH_COMPONENT_REMOVED_EVENT);
}
//entityHandle.RemoveHandle(entityID);
}

View File

@ -29,7 +29,7 @@ namespace SHADE
{
system.second->Init();
#ifdef _DEBUG
std::cout << system.first << " Init" << std::endl;
SHLOG_INFO("Initialising System {}...", system.first)
#endif
}
}

View File

@ -5,15 +5,19 @@
#include "Editor/SHImGuiHelpers.hpp"
#include <imgui.h>
#include <imgui_internal.h>
#include <misc/cpp/imgui_stdlib.h>
#include "Assets/SHAssetManager.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/IconsFontAwesome6.h"
#include "Editor/SHEditor.h"
#include "Editor/DragDrop/SHDragDrop.hpp"
#include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h"
namespace SHADE
{
SHAssetBrowser::SHAssetBrowser()
:SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder)
:SHEditorWindow("\xee\x8b\x87 Asset Browser", ImGuiWindowFlags_MenuBar), rootFolder(SHAssetManager::GetRootFolder()), prevFolder(rootFolder), currentFolder(rootFolder), assetBeingCreated(std::nullopt)
{
}
@ -53,14 +57,33 @@ namespace SHADE
flags |= ImGuiTreeNodeFlags_Selected;
if (folder == rootFolder)
flags |= ImGuiTreeNodeFlags_DefaultOpen;
bool isOpen = ImGui::TreeNodeEx(folder, flags, "%s %s", ICON_MD_FOLDER, folder->name.data());
ImGuiID folderID = ImGui::GetItemID();
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
if(ImGui::IsItemClicked())
if (ImGui::BeginPopupContextItem())
{
if (ImGui::BeginMenu("Create Asset"))
{
//TODO: Change to rttr type enum align
if (ImGui::Selectable("Material"))
{
assetBeingCreated = { folder, AssetType::MATERIAL, "New Material" };
ImGui::TreeNodeSetOpen(folderID, true);
isOpen = true;
}
ImGui::EndMenu();
}
ImGui::EndPopup();
}
if (ImGui::IsItemClicked())
{
selectedFolders.clear();
selectedFolders.push_back(folder);
}
if (isOpen)
{
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
@ -86,6 +109,9 @@ namespace SHADE
vertLineEnd.y = midPoint;
}
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 1);
if(assetBeingCreated.has_value() && std::get<0>(assetBeingCreated.value()) == folder)
DrawAssetBeingCreated();
ImGui::TreePop();
}
return nodeRect;
@ -130,7 +156,7 @@ namespace SHADE
flags |= ImGuiTreeNodeFlags_Selected;
std::string icon{};
switch(file.assetMeta->type)
switch (file.assetMeta->type)
{
case AssetType::INVALID: break;
case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break;
@ -141,24 +167,64 @@ namespace SHADE
case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break;
case AssetType::MATERIAL: break;
case AssetType::MAX_COUNT: break;
default: ;
default:;
}
ImGui::TreeNodeEx(file.assetMeta, flags, "%s %s", icon.data(), file.assetMeta->name.data());
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
if(SHDragDrop::BeginSource())
if (SHDragDrop::BeginSource())
{
auto id = file.assetMeta->id;
ImGui::Text("Moving Asset: %s [%zu]", file.name.data(), file.assetMeta->id);
SHDragDrop::SetPayload<AssetID>(SHDragDrop::DRAG_RESOURCE, &id);
SHDragDrop::EndSource();
}
if(ImGui::IsItemClicked())
if (ImGui::IsItemClicked())
{
selectedAssets.clear();
selectedAssets.push_back(file.assetMeta->id);
}
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
switch (file.assetMeta->type)
{
case AssetType::INVALID: break;
case AssetType::SHADER: icon = ICON_FA_FILE_CODE; break;
case AssetType::SHADER_BUILT_IN: icon = ICON_FA_FILE_CODE; break;
case AssetType::TEXTURE: icon = ICON_FA_IMAGES; break;
case AssetType::MESH: icon = ICON_FA_CUBES; break;
case AssetType::SCENE: icon = ICON_MD_IMAGE; break;
case AssetType::PREFAB: icon = ICON_FA_BOX_OPEN; break;
case AssetType::MATERIAL:
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
{
matInspector->OpenMaterial(file.assetMeta->id);
}
break;
case AssetType::MAX_COUNT: break;
default:;
}
}
ImGui::TreePop();
return nodeRect;
}
void SHAssetBrowser::DrawAssetBeingCreated() noexcept
{
if (!assetBeingCreated.has_value())
return;
auto& path = std::get<0>(assetBeingCreated.value());
auto& type = std::get<1>(assetBeingCreated.value());
auto& assetName = std::get<2>(assetBeingCreated.value());
if (ImGui::InputText("##newAssetname", &assetName, ImGuiInputTextFlags_EnterReturnsTrue))
{
AssetID assetId = SHAssetManager::CreateNewAsset(type, assetName);
if (auto matInspector = SHEditorWindowManager::GetEditorWindow<SHMaterialInspector>())
{
matInspector->OpenMaterial(assetId, true);
}
assetBeingCreated.reset();
}
}
}

View File

@ -10,6 +10,7 @@ namespace SHADE
class SHAssetBrowser final : public SHEditorWindow
{
public:
using AssetEntry = std::tuple<FolderPointer, AssetType, std::string>;
SHAssetBrowser();
void Init();
@ -21,11 +22,12 @@ namespace SHADE
ImRect RecursivelyDrawTree(FolderPointer folder);
void DrawCurrentFolder();
ImRect DrawFile(SHFile const& file) noexcept;
void DrawAssetBeingCreated() noexcept;
FolderPointer rootFolder, prevFolder, currentFolder;
std::optional<AssetEntry> assetBeingCreated;
std::vector<FolderPointer> selectedFolders;
std::vector<AssetID> selectedAssets;
static constexpr float tileWidth = 50.0f;
};
}

View File

@ -45,7 +45,7 @@ namespace SHADE
SHEditorWindow::Update();
isAnyNodeSelected = false;
if (Begin())
{
if (skipFrame)
@ -108,6 +108,12 @@ namespace SHADE
}
}
if(ImGui::IsWindowHovered() && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
{
ParentSelectedEntities(MAX_EID, draggingEntities);
draggingEntities.clear();
ImGui::ClearDragDrop();
}
ImGui::End();
}
@ -195,25 +201,30 @@ namespace SHADE
if (SHDragDrop::BeginSource())
{
std::string moveLabel = "Moving EID: ";
draggingEntities = editor->selectedEntities;
if (!isSelected)
editor->selectedEntities.push_back(eid);
for (int i = 0; i < static_cast<int>(editor->selectedEntities.size()); ++i)
{
moveLabel.append(std::to_string(editor->selectedEntities[i]));
if (i + 1 < static_cast<int>(editor->selectedEntities.size()))
draggingEntities.clear();
draggingEntities.push_back(eid);
}
for (int i = 0; i < static_cast<int>(draggingEntities.size()); ++i)
{
moveLabel.append(std::to_string(draggingEntities[i]));
if (i + 1 < static_cast<int>(draggingEntities.size()))
{
moveLabel.append(", ");
}
}
ImGui::Text(moveLabel.c_str());
SHDragDrop::SetPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID, &editor->selectedEntities);
SHDragDrop::SetPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID, &draggingEntities);
SHDragDrop::EndSource();
}
else if (SHDragDrop::BeginTarget()) //If Received DragDrop
{
if (const std::vector<EntityID>* eidPayload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID)) //If payload is valid
{
ParentSelectedEntities(eid);
ParentSelectedEntities(eid, draggingEntities);
draggingEntities.clear();
SHDragDrop::EndTarget();
}
}
@ -251,7 +262,7 @@ namespace SHADE
if ((currentNode->GetParent() != sceneGraph.GetRoot()) && ImGui::Selectable(std::format("{} Unparent Selected", ICON_MD_NORTH_WEST).data()))
{
ParentSelectedEntities(MAX_EID);
ParentSelectedEntities(MAX_EID, editor->selectedEntities);
}
ImGui::EndPopup();
}
@ -319,14 +330,16 @@ namespace SHADE
SHEntityManager::CreateEntity(MAX_EID, "DefaultChild", parentEID);
}
void SHHierarchyPanel::ParentSelectedEntities(EntityID parentEID) const noexcept
void SHHierarchyPanel::ParentSelectedEntities(EntityID parentEID, std::vector<EntityID> const& entities) const noexcept
{
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
auto const editor = SHSystemManager::GetSystem<SHEditor>();
//auto const editor = SHSystemManager::GetSystem<SHEditor>();
SHEntityParentCommand::EntityParentData entityParentData;
std::vector<EntityID> parentedEIDS;
for (auto const& eid : editor->selectedEntities)
for (auto const& eid : entities)
{
if(eid == parentEID)
continue;
if (sceneGraph.GetChild(eid, parentEID) == nullptr)
{
parentedEIDS.push_back(eid);

View File

@ -28,7 +28,7 @@ namespace SHADE
void DrawMenuBar() const noexcept;
ImRect RecursivelyDrawEntityNode(SHSceneNode* const);
void CreateChildEntity(EntityID parentEID) const noexcept;
void ParentSelectedEntities(EntityID parentEID) const noexcept;
void ParentSelectedEntities(EntityID parentEID, std::vector<EntityID> const& entities) const noexcept;
void SelectRangeOfEntities(EntityID beginEID, EntityID EndEID);
void SelectAllEntities();
void CopySelectedEntities();
@ -37,6 +37,8 @@ namespace SHADE
std::string filter;
bool isAnyNodeSelected = false;
EntityID scrollTo = MAX_EID;
std::vector<EntityID> draggingEntities;
};//class SHHierarchyPanel
//Might move to a different file

View File

@ -244,19 +244,23 @@ namespace SHADE
SHCollider* collider = &component->GetCollider(i);
auto cursorPos = ImGui::GetCursorPos();
//collider->IsTrigger
if (collider->GetType() == SHCollider::Type::BOX)
{
SHEditorWidgets::BeginPanel(std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger");
auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
SHEditorWidgets::DragVec3
(
"Half Extents", { "X", "Y", "Z" },
[box, transformComponent] { return (transformComponent->GetWorldScale() * 2.0f) * box->GetHalfExtents(); },
[box, transformComponent] { return (box->GetHalfExtents() * 2.0f) / transformComponent->GetWorldScale(); },
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
}
else if (collider->GetType() == SHCollider::Type::SPHERE)
{
SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
SHEditorWidgets::CheckBox("Is Trigger", [collider]() {return collider->IsTrigger(); }, [collider](bool const& value) {collider->SetIsTrigger(value); }, "Is Trigger");
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
SHEditorWidgets::DragFloat
(
@ -265,19 +269,42 @@ namespace SHADE
{
const SHVec3& TF_WORLD_SCALE = transformComponent->GetWorldScale();
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
return sphere->GetRadius() / MAX_SCALE;
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)
{
}
{
SHEditorWidgets::BeginPanel("Offset", { 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("Rotation", { "X", "Y", "Z" },
[&collider]
{
auto offset = collider->GetRotationOffset();
offset.x = SHMath::RadiansToDegrees(offset.x);
offset.y = SHMath::RadiansToDegrees(offset.y);
offset.z = SHMath::RadiansToDegrees(offset.z);
return offset;
},
[&collider](SHVec3 const& vec)
{
const SHVec3 vecInRad
{
SHMath::DegreesToRadians(vec.x)
, SHMath::DegreesToRadians(vec.y)
, SHMath::DegreesToRadians(vec.z)
};
collider->SetRotationOffset(vecInRad);
});
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()))
{
colliderToDelete = i;
@ -349,6 +376,7 @@ namespace SHADE
{
DrawContextMenu(component);
Handle<SHMesh> const& mesh = component->GetMesh();
Handle<SHMaterialInstance> const& mat = component->GetMaterial();
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Mesh", std::to_string(SHResourceManager::GetAssetID<SHMesh>(mesh).value_or(0)).data(), [component]()
{
@ -358,6 +386,20 @@ namespace SHADE
[component](AssetID const& id)
{
component->SetMesh(SHResourceManager::LoadOrGet<SHMesh>(id));
SHResourceManager::FinaliseChanges();
}, SHDragDrop::DRAG_RESOURCE);
SHEditorWidgets::DragDropReadOnlyField<AssetID>("Material", mat ? std::to_string(SHResourceManager::GetAssetID<SHMaterial>(mat->GetBaseMaterial()).value_or(0)).data() : "", [component]()
{
Handle<SHMaterialInstance> const& mat = component->GetMaterial();
if(!mat)
return static_cast<AssetID>(0);
return SHResourceManager::GetAssetID<SHMaterial>(mat->GetBaseMaterial()).value_or(0);
},
[component](AssetID const& id)
{
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
component->SetMaterial(gfxSystem->AddOrGetBaseMaterialInstance(SHResourceManager::LoadOrGet<SHMaterial>(id)));
}, SHDragDrop::DRAG_RESOURCE);
}
else

View File

@ -17,6 +17,7 @@
#include "Physics/Components/SHRigidBodyComponent.h"
#include "Physics/Components/SHColliderComponent.h"
#include "Camera/SHCameraComponent.h"
#include "Camera/SHCameraArmComponent.h"
#include "SHEditorComponentView.h"
namespace SHADE
@ -126,6 +127,9 @@ namespace SHADE
if (auto cameraComponent = SHComponentManager::GetComponent_s<SHCameraComponent>(eid))
{
DrawComponent(cameraComponent);
}if (auto cameraArmComponent = SHComponentManager::GetComponent_s<SHCameraArmComponent>(eid))
{
DrawComponent(cameraArmComponent);
}
ImGui::Separator();
// Render Scripts
@ -136,6 +140,7 @@ namespace SHADE
{
DrawAddComponentButton<SHTransformComponent>(eid);
DrawAddComponentButton<SHCameraComponent>(eid);
DrawAddComponentButton<SHCameraArmComponent>(eid);
DrawAddComponentButton<SHLightComponent>(eid);
// Components that require Transforms

View File

@ -0,0 +1,257 @@
#include "SHpch.h"
#include "Serialization/SHSerializationHelper.hpp"
#include "SHMaterialInspector.h"
#include "Editor/SHImGuiHelpers.hpp"
#include <imgui.h>
#include "Assets/SHAssetManager.h"
#include "Editor/IconsMaterialDesign.h"
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
#include "Editor/SHEditorWidgets.hpp"
#include "Resource/SHResourceManager.h"
namespace SHADE
{
SHMaterialInspector::SHMaterialInspector()
:SHEditorWindow("Material Inspector", ImGuiWindowFlags_MenuBar), isDirty(false), isNewMaterial(false), currentViewedMaterial(0)
{
}
void SHMaterialInspector::OpenMaterial(AssetID const& assetId, bool isNew) noexcept
{
//Get mat data
if(isDirty)
return;
isDirty = isNew;
isOpen = true;
SetFocusToWindow();
currentViewedMaterial = assetId;
//currentMatSpec = //Get mat spec
currentMatSpec = SHResourceManager::LoadOrGet<SHMaterialSpec>(assetId);
currentMaterial = SHResourceManager::LoadOrGet<SHMaterial>(assetId);
}
void SHMaterialInspector::Init()
{
SHEditorWindow::Init();
}
void SHMaterialInspector::Update()
{
SHEditorWindow::Update();
if (Begin())
{
if(currentViewedMaterial)
{
DrawMenuBar();
//if (SHEditorWidgets::DragDropReadOnlyField<AssetID>("Vertex Shader", std::to_string(currentMatSpec->vertexShader), [&]() {return currentMatSpec->vertexShader; }, [&](AssetID const& id) {currentMatSpec->vertexShader = id; }, SHDragDrop::DRAG_RESOURCE))
//{
// isDirty = true;
// vertShaderHandle = SHResourceManager::LoadOrGet<SHVkShaderModule>(currentMatSpec->vertexShader);
//}
//if (SHEditorWidgets::DragDropReadOnlyField<AssetID>("Fragment Shader", std::to_string(currentMatSpec->fragShader), [&]() {return currentMatSpec->fragShader; }, [&](AssetID const& id) {currentMatSpec->fragShader = id; }, SHDragDrop::DRAG_RESOURCE))
//{
// isDirty = true;
// fragShaderHandle = SHResourceManager::LoadOrGet<SHVkShaderModule>(currentMatSpec->fragShader);
//}
DrawShaderProperties(/*fragShaderHandle*/);
}
}
ImGui::End();
}
void SHMaterialInspector::Exit()
{
SHEditorWindow::Exit();
}
void SHMaterialInspector::DrawMenuBar()
{
if (ImGui::BeginMenuBar())
{
ImGui::BeginDisabled(!isDirty);
if(ImGui::Button(std::format("{} Save", ICON_MD_SAVE).data()))
{
//save
if(auto matAsset = SHAssetManager::GetData<SHMaterialAsset>(currentViewedMaterial))
{
YAML::Emitter out;
out << YAML::BeginSeq;
out << YAML::convert<SHMaterialSpec>::encode(*currentMatSpec);
out << YAML::EndSeq;
matAsset->data = out.c_str();
Handle<SHShaderBlockInterface> pipelineProperties = currentMaterial->GetShaderBlockInterface();
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
{
const std::string& PROP_NAME = pipelineProperties->GetVariableName(i);
const YAML::Node& PROP_NODE = currentMatSpec->properties[PROP_NAME.data()];
if (PROP_NODE.IsDefined())
{
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
switch (VARIABLE->type)
{
case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT:
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<float>());
break;
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<int>());
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec2>());
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec3>());
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
currentMaterial->SetProperty(VARIABLE->offset, PROP_NODE.as<SHVec4>());
break;
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
default:
continue;
break;
}
}
}
if(SHAssetManager::SaveAsset(currentViewedMaterial))
{
isDirty = false;
}
}
}
ImGui::EndDisabled();
ImGui::EndMenuBar();
}
}
void SHMaterialInspector::DrawShaderProperties(/*Handle<SHVkShaderModule> shaderModule*/)
{
/*if(!shaderModule)
return;*/
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
auto interface = gfxSystem->GetDefaultMaterialInstance()->GetBaseMaterial()->GetShaderBlockInterface();
//auto interface = shaderModule->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA);
int const varCount = static_cast<int>(interface->GetVariableCount());
for (int i = 0; i < varCount; ++i)
{
auto variable = interface->GetVariable(i);
const std::string& VAR_NAME = interface->GetVariableName(i);
if(VAR_NAME.empty())
continue;
switch (variable->type)
{
case SHShaderBlockInterface::Variable::Type::FLOAT:
isDirty |= SHEditorWidgets::DragFloat(VAR_NAME,
[&]()
{
if (currentMatSpec->properties[VAR_NAME].IsDefined())
return currentMatSpec->properties[VAR_NAME].as<float>();
else
return 0.0f;
},
[&](float const& value)
{
currentMatSpec->properties[VAR_NAME] = value;
}
);
break;
case SHShaderBlockInterface::Variable::Type::INT:
isDirty |= SHEditorWidgets::DragInt(VAR_NAME,
[&]()
{
if (currentMatSpec->properties[VAR_NAME].IsDefined())
return currentMatSpec->properties[VAR_NAME].as<int>();
else
return 0;
},
[&](int const& value)
{
currentMatSpec->properties[VAR_NAME] = value;
}
);
if(SHDragDrop::BeginTarget())
{
if(AssetID* payload = SHDragDrop::AcceptPayload<AssetID>(SHDragDrop::DRAG_RESOURCE))
{
currentMatSpec->properties[VAR_NAME] = *payload;
isDirty = true;
SHDragDrop::EndTarget();
}
}
break;
case SHShaderBlockInterface::Variable::Type::VECTOR2:
isDirty |= SHEditorWidgets::DragVec2(VAR_NAME, { "X", "Y" },
[&]()
{
if (currentMatSpec->properties[VAR_NAME].IsDefined())
return currentMatSpec->properties[VAR_NAME].as<SHVec2>();
else
return SHVec2::Zero;
},
[&](SHVec2 const& value)
{
currentMatSpec->properties[VAR_NAME] = value;
}
);
break;
case SHShaderBlockInterface::Variable::Type::VECTOR3:
isDirty |= SHEditorWidgets::DragVec3(VAR_NAME, { "X", "Y", "Z" },
[&]()
{
if (currentMatSpec->properties[VAR_NAME].IsDefined())
return currentMatSpec->properties[VAR_NAME].as<SHVec3>();
else
return SHVec3::Zero;
},
[&](SHVec3 const& value)
{
currentMatSpec->properties[VAR_NAME] = value;
}
);
break;
case SHShaderBlockInterface::Variable::Type::VECTOR4:
isDirty |= SHEditorWidgets::DragVec4(VAR_NAME, { "X", "Y", "Z", "W" },
[&]()
{
if (currentMatSpec->properties[VAR_NAME].IsDefined())
return currentMatSpec->properties[VAR_NAME].as<SHVec4>();
else
return SHVec4::Zero;
},
[&](SHVec4 const& value)
{
currentMatSpec->properties[VAR_NAME] = value;
}
);
break;
case SHShaderBlockInterface::Variable::Type::OTHER:
isDirty |= SHEditorWidgets::InputText(VAR_NAME,
[&]()
{
if (currentMatSpec->properties[VAR_NAME].IsDefined())
return currentMatSpec->properties[VAR_NAME].as<std::string>();
else
return std::string();
},
[&](std::string const& value)
{
currentMatSpec->properties[VAR_NAME] = value;
}
);
default:
continue;
break;
}
}
}
}

View File

@ -0,0 +1,33 @@
#pragma once
#include "Assets/SHAssetMacros.h"
#include "Editor/EditorWindow/SHEditorWindow.h"
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
#include "Graphics/Shaders/SHVkShaderModule.h"
#include "Resource/SHHandle.h"
namespace SHADE
{
class SHMaterialInspector final : public SHEditorWindow
{
public:
SHMaterialInspector();
~SHMaterialInspector() = default;
void Init() override;
void Update() override;
void Exit() override;
void OpenMaterial(AssetID const& assetId, bool isNew = false) noexcept;
private:
void DrawMenuBar();
void DrawShaderProperties(/*Handle<SHVkShaderModule> shaderModule*/);
bool isDirty;
bool isNewMaterial;
AssetID currentViewedMaterial;
Handle<SHMaterialSpec> currentMatSpec;
Handle<SHMaterial> currentMaterial;
Handle<SHVkShaderModule> vertShaderHandle, fragShaderHandle;
};
}

View File

@ -175,19 +175,37 @@ namespace SHADE
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
{
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
{
.previousState = editor->editorState
};
editor->editorState = SHEditor::State::PLAY;
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PLAY_EVENT);
}
ImGui::EndDisabled();
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE);
if(ImGui::SmallButton(ICON_MD_PAUSE))
{
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
{
.previousState = editor->editorState
};
editor->editorState = SHEditor::State::PAUSE;
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_PAUSE_EVENT);
}
ImGui::EndDisabled();
ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP);
if(ImGui::SmallButton(ICON_MD_STOP))
{
const SHEditorStateChangeEvent STATE_CHANGE_EVENT
{
.previousState = editor->editorState
};
editor->editorState = SHEditor::State::STOP;
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
}
ImGui::EndDisabled();
ImGui::EndMenuBar();

View File

@ -20,4 +20,10 @@ namespace SHADE
float menuBarHeight = 20.0f;
std::vector<std::filesystem::path> layoutPaths;
};//class SHEditorMenuBar
struct SHEditorStateChangeEvent
{
SHEditor::State previousState;
};
}//namespace SHADE

View File

@ -19,7 +19,7 @@ namespace SHADE
//|| Public Member Functions ||
//#==============================================================#
SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags)
: windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
:isOpen(true), isWindowHovered(false), windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
{
}
@ -68,5 +68,10 @@ namespace SHADE
void SHEditorWindow::OnPosChange()
{
}
void SHEditorWindow::SetFocusToWindow()
{
ImGui::SetWindowFocus(windowName.data());
}
}//namespace SHADE

View File

@ -34,6 +34,7 @@ namespace SHADE
virtual bool Begin();
virtual void OnResize();
virtual void OnPosChange();
virtual void SetFocusToWindow();
ImGuiWindowFlags windowFlags = 0;
ImGuiIO& io;

View File

@ -1,7 +1,8 @@
#pragma once
#include "MenuBar/SHEditorMenuBar.h" //Menu Bar
#include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel
#include "Inspector/SHEditorInspector.h" //Inspector
#include "Profiling/SHEditorProfiler.h" //Profiler
#include "ViewportWindow/SHEditorViewport.h" //Editor Viewport
#include "AssetBrowser/SHAssetBrowser.h" //Asset Browser
#include "MenuBar/SHEditorMenuBar.h" //Menu Bar
#include "HierarchyPanel/SHHierarchyPanel.h" //Hierarchy Panel
#include "Inspector/SHEditorInspector.h" //Inspector
#include "Profiling/SHEditorProfiler.h" //Profiler
#include "ViewportWindow/SHEditorViewport.h" //Editor Viewport
#include "AssetBrowser/SHAssetBrowser.h" //Asset Browser
#include "MaterialInspector/SHMaterialInspector.h" //Material Inspector

View File

@ -46,6 +46,7 @@
#include <backends/imgui_impl_vulkan.h>
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
#include "Tools/SHDebugDraw.h"
RTTR_REGISTRATION
{
@ -77,7 +78,6 @@ namespace SHADE
//#==============================================================#
void SHEditor::Init()
{
IMGUI_CHECKVERSION();
if(auto context = ImGui::CreateContext())
{
@ -93,6 +93,8 @@ namespace SHADE
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
SHEditorWindowManager::CreateEditorWindow<SHAssetBrowser>();
SHEditorWindowManager::CreateEditorWindow<SHMaterialInspector>();
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
io = &ImGui::GetIO();
@ -120,6 +122,17 @@ namespace SHADE
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")
}
@ -180,6 +193,97 @@ namespace SHADE
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()
{
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)

View File

@ -15,9 +15,10 @@
#include "ECS_Base/System/SHSystemRoutine.h"
#include "Resource/SHHandle.h"
#include "EditorWindow/SHEditorWindow.h"
#include "Tools/SHLogger.h"
#include "Gizmos/SHTransformGizmo.h"
#include "Tools/SHLog.h"
#include "Gizmos/SHTransformGizmo.h"`
#include "Events/SHEventDefines.h"
#include "Events/SHEvent.h"
//#==============================================================#
//|| Library Includes ||
@ -76,7 +77,7 @@ namespace SHADE
}
else
{
SHLOG_WARNING("Attempt to create duplicate of Editor window type")
SHLog::Warning("Attempt to create duplicate of Editor window type");
}
}
@ -194,6 +195,10 @@ namespace SHADE
void InitFonts() noexcept;
void SetUpGridLines(bool drawGrid, bool drawAxes);
SHEventHandle onEditorStateChanged(SHEventPtr eventPtr);
// Handle to command pool used for ImGui Vulkan Backend
Handle<SHVkCommandPool> imguiCommandPool;
// Handle to command buffer used for ImGui Vulkan Backend

View File

@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited.
// External Dependencies
#include <imgui.h>
#include "SHEditorWidgets.hpp"
#include "ECS_Base/Managers/SHEntityManager.h"
namespace SHADE
{
@ -156,7 +157,7 @@ namespace SHADE
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::Checkbox("#", &value);
return ImGui::Checkbox("##", &value);
}
bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered)
{
@ -164,7 +165,7 @@ namespace SHADE
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::InputInt("#", &value,
return ImGui::InputInt("##", &value,
1, 10,
ImGuiInputTextFlags_EnterReturnsTrue);
}
@ -175,7 +176,7 @@ namespace SHADE
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
const bool CHANGED = InputInt("#", signedVal);
const bool CHANGED = InputInt("##", signedVal);
if (CHANGED)
{
signedVal = std::clamp(signedVal, 0, std::numeric_limits<int>::max());
@ -189,7 +190,7 @@ namespace SHADE
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::InputFloat("#", &value,
return ImGui::InputFloat("##", &value,
0.1f, 1.0f, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
}
@ -199,7 +200,7 @@ namespace SHADE
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::InputDouble("#", &value,
return ImGui::InputDouble("##", &value,
0.1, 1.0, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
}
@ -209,7 +210,7 @@ namespace SHADE
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::InputDouble("#", &value,
return ImGui::InputDouble("##", &value,
1.0, 45.0, "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
}
@ -279,7 +280,7 @@ namespace SHADE
if (isHovered)
*isHovered = ImGui::IsItemHovered();
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)
{
value = std::string(buffer.data(), buffer.data() + TEXT_FIELD_MAX_LENGTH);
@ -287,6 +288,35 @@ namespace SHADE
return CHANGED;
}
bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered)
{
ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
SHEntity* entity = SHEntityManager::GetEntityByID(value);
std::ostringstream oss;
if (entity)
{
oss << value << ": " << entity->name;
}
std::string entityName = oss.str();
bool changed = ImGui::InputText("##", &entityName, ImGuiInputTextFlags_ReadOnly);
if (SHDragDrop::BeginTarget())
{
if (const std::vector<EntityID>* payload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID))
{
if (!payload->empty())
{
value = payload->at(0);
changed = true;
}
SHDragDrop::EndTarget();
}
}
return changed;
}
bool SHEditorUI::InputEnumCombo(const std::string& label, int& v, const std::vector<std::string>& enumNames, bool* isHovered)
{
// Clamp input value
@ -297,7 +327,7 @@ namespace SHADE
if (isHovered)
*isHovered = ImGui::IsItemHovered();
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)
{

View File

@ -308,6 +308,14 @@ namespace SHADE
/// <returns>True if the value was changed.</returns>
static bool InputTextField(const std::string& label, std::string& value, bool* isHovered = nullptr);
/// <summary>
/// Creates a drag field widget for int input.
/// </summary>
/// <param name="label">Label used to identify this widget.</param>
/// <param name="value">Reference to the variable to store the result.</param>
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
/// <returns>True if the value was changed.</returns>
static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr);
/// <summary>
/// Creates a combo box for enumeration input.
/// </summary>
/// <typeparam name="Enum">The type of enum to input.</typeparam>

View File

@ -422,12 +422,13 @@ namespace SHADE
ImGui::BeginGroup();
ImGui::PushID(label.data());
TextLabel(label);
bool const changed = ImGui::InputText("##", &text, ImGuiInputTextFlags_ReadOnly, nullptr, nullptr);
bool changed = ImGui::InputText("##", &text, ImGuiInputTextFlags_ReadOnly, nullptr, nullptr);
if(SHDragDrop::BeginTarget())
{
if(T* payload = SHDragDrop::AcceptPayload<T>(dragDropTag))
{
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), *payload, set)), false);
changed = true;
SHDragDrop::EndTarget();
}
}

View File

@ -13,4 +13,7 @@ constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 };
constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 };
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 6 };
constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 7 };
constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 8 };
constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 9 };
constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 10 };

View File

@ -64,6 +64,11 @@ namespace SHADE
return bufferUsageFlags;
}
uint32_t SHVkBuffer::GetSizeStored(void) const noexcept
{
return sizeStored;
}
/***************************************************************************/
/*!

View File

@ -102,8 +102,9 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
vk::Buffer GetVkBuffer (void) const noexcept;
vk::Buffer GetVkBuffer (void) const noexcept;
vk::BufferUsageFlags GetUsageBits(void) const noexcept;
uint32_t GetSizeStored (void) const noexcept;
template <typename T>
T GetDataFromMappedPointer(uint32_t index) const noexcept

View File

@ -282,6 +282,11 @@ namespace SHADE
}
void SHVkCommandBuffer::SetLineWidth(float lineWidth) noexcept
{
vkCommandBuffer.setLineWidth(lineWidth);
}
/***************************************************************************/
/*!

View File

@ -115,6 +115,7 @@ namespace SHADE
// Dynamic State
void SetViewportScissor (float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX = 0.0f, float vpY = 0.0f, int32_t sX = 0.0f, int32_t sY = 0.0f, float vpMinDepth = 0.0f, float vpMaxDepth = 1.0f) noexcept;
void SetLineWidth (float lineWidth) noexcept;
// Binding Commands
void BindPipeline (Handle<SHVkPipeline> const& pipelineHdl) noexcept;

View File

@ -119,6 +119,18 @@ namespace SHADE
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
{
if (&rhs == this)

View File

@ -99,6 +99,7 @@ namespace SHADE
inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; }
std::vector<Binding> const& GetBindings (void) const noexcept;
SetIndex GetSetIndex (void) const noexcept;
uint32_t GetNumDynamicOffsetsRequired (void) const noexcept;
private:
/*-----------------------------------------------------------------------------*/

View File

@ -74,11 +74,12 @@ namespace SHADE
void SHBatch::Remove(const SHRenderable* renderable)
{
// Check if we have a SubBatch with the same mesh yet
// Check if we have a SubBatch with the existing mesh yet (if changed, we use the old mesh)
Handle<SHMesh> prevSubBatchMesh = renderable->HasMeshChanged() ? renderable->GetPrevMesh() : renderable->GetMesh();
auto subBatch = std::find_if(subBatches.begin(), subBatches.end(), [&](const SHSubBatch& batch)
{
return batch.Mesh == renderable->GetMesh();
});
{
return batch.Mesh == prevSubBatchMesh;
});
// Attempt to remove if it exists
if (subBatch == subBatches.end())
@ -88,9 +89,7 @@ namespace SHADE
// Check if other renderables in subBatches contain the same material instance
bool matUnused = true;
Handle<SHMaterialInstance> matToCheck = renderable->HasMaterialChanged() ? renderable->GetPrevMaterial() : renderable->GetMaterial();
for (const auto& sb : subBatches)
{
// Check material usage

View File

@ -37,9 +37,9 @@ namespace SHADE
// Check if we have a batch with the same pipeline first
auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch)
{
return batch.GetPipeline() == PIPELINE;
});
{
return batch.GetPipeline() == PIPELINE;
});
// Create one if not found

View File

@ -79,7 +79,7 @@ namespace SHADE
SHVkDescriptorSetLayout::Binding cameraDataBinding
{
.Type = vk::DescriptorType::eUniformBufferDynamic,
.Stage = vk::ShaderStageFlagBits::eVertex,
.Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eCompute,
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA,
.DescriptorCount = 1,
};

View File

@ -0,0 +1,326 @@
/************************************************************************************//*!
\file SHDebugDrawSystem.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 16, 2022
\brief Contains the definition of functions of the SHDebugDrawSystem class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#include "SHpch.h"
#include "SHDebugDrawSystem.h"
// STL Includes
#include <algorithm>
// Project Includes
#include "Assets/Asset Types/SHModelAsset.h"
#include "../Meshes/SHPrimitiveGenerator.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "SHGraphicsSystem.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "../../SHVkUtil.h"
#include "Graphics/MiddleEnd/Interface/SHViewport.h"
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* DrawRoutine */
/*---------------------------------------------------------------------------------*/
SHDebugDrawSystem::ProcessPointsRoutine::ProcessPointsRoutine()
: SHSystemRoutine("Debug Draw", true)
{
SystemFamily::GetID<SHDebugDrawSystem>();
}
void SHDebugDrawSystem::ProcessPointsRoutine::Execute(double dt) noexcept
{
auto gfxSys = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (!gfxSys)
{
SHLOG_WARNING("[DebugDraw] Attempted to do debug draw without a graphics system.");
return;
}
// Get the system
SHDebugDrawSystem* system = static_cast<SHDebugDrawSystem*>(GetSystem());
// Get current frame index
const uint32_t FRAME_IDX = gfxSys->GetCurrentFrameIndex();
/* Non-Persistent Buffer */
// Update the buffer
system->numPoints[FRAME_IDX] = system->points.size();
const uint32_t DATA_SIZE = sizeof(PointVertex) * system->points.size();
if (DATA_SIZE > 0)
{
system->vertexBuffers[FRAME_IDX]->WriteToMemory(system->points.data(), DATA_SIZE, 0, 0);
}
// Reset for next frame
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;
}
}
/*---------------------------------------------------------------------------------*/
/* SHSystem overrides */
/*---------------------------------------------------------------------------------*/
void SHDebugDrawSystem::Init()
{
// Register function for subpass
const auto* GFX_SYSTEM = SHSystemManager::GetSystem<SHGraphicsSystem>();
auto const& RENDERERS = GFX_SYSTEM->GetDefaultViewport()->GetRenderers();
auto renderGraph = RENDERERS[SHGraphicsConstants::RenderGraphIndices::WORLD]->GetRenderGraph();
auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw");
subPass->AddExteriorDrawCalls([this, GFX_SYSTEM](Handle<SHVkCommandBuffer>& cmdBuffer)
{
// Get Current frame index
const uint32_t FRAME_IDX = GFX_SYSTEM->GetCurrentFrameIndex();
// Don't draw if no points
if (numPoints[FRAME_IDX] > 0)
{
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();
// Don't draw if no points
if (numPersistentPoints[FRAME_IDX] > 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
std::fill_n(numPoints.begin(), numPoints.size(), 0);
std::fill_n(numPersistentPoints.begin(), numPersistentPoints.size(), 0);
for (bool& cleared : persistentBuffersCleared)
cleared = true;
// Allocate buffers
// - Non-Persistent Draws
static constexpr uint32_t BUFFER_SIZE = MAX_POINTS * sizeof(PointVertex);
for (Handle<SHVkBuffer>& bufHandle : vertexBuffers)
{
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
);
}
// - 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
);
}
}
void SHDebugDrawSystem::Exit()
{
for (auto vertexBuffer : vertexBuffers)
{
if (vertexBuffer)
vertexBuffer.Free();
}
for (auto vertexBuffer : persistentVertexBuffers)
{
if (vertexBuffer)
vertexBuffer.Free();
}
}
/*---------------------------------------------------------------------------------*/
/* Draw Functions */
/*---------------------------------------------------------------------------------*/
void SHDebugDrawSystem::DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt)
{
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.");
return;
}
storage.emplace_back(PointVertex{ startPt, color });
storage.emplace_back(PointVertex{ endPt, color });
}
void SHDebugDrawSystem::drawLineSet(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList)
{
drawLineSet(storage, color, pointList.begin(), pointList.end());
}
void SHDebugDrawSystem::drawPoly(std::vector<PointVertex>& storage, const SHVec4& color, std::initializer_list<SHVec3> pointList)
{
drawPoly(storage, color, pointList.begin(), pointList.end());
}
void SHDebugDrawSystem::drawCube(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, const SHVec3& size)
{
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 };
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 TOP_LEFT_BACK = UNIT_TOP_LEFT_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_RIGHT_FRONT = UNIT_TOP_RIGHT_FRONT * size;
drawLineSet
(
storage,
color,
{
// Bottom Square
BOT_LEFT_BACK , BOT_RIGHT_BACK,
BOT_RIGHT_BACK , BOT_RIGHT_FRONT,
BOT_RIGHT_FRONT, BOT_LEFT_FRONT,
BOT_LEFT_FRONT , BOT_LEFT_BACK,
// Top Square
TOP_LEFT_BACK , TOP_RIGHT_BACK,
TOP_RIGHT_BACK , TOP_RIGHT_FRONT,
TOP_RIGHT_FRONT, TOP_LEFT_FRONT,
TOP_LEFT_FRONT , TOP_LEFT_BACK,
// Middle Lines
TOP_LEFT_BACK , BOT_LEFT_BACK,
TOP_RIGHT_BACK , BOT_RIGHT_BACK,
TOP_RIGHT_FRONT, BOT_RIGHT_FRONT,
TOP_LEFT_FRONT , BOT_LEFT_FRONT
}
);
}
void SHDebugDrawSystem::drawSphere(std::vector<PointVertex>& storage, const SHVec4& color, const SHVec3& pos, double radius)
{
if (spherePoints.empty())
{
// Generate
static const SHMeshData SPHERE = SHPrimitiveGenerator::Sphere();
for (const auto& idx : SPHERE.Indices)
{
spherePoints.emplace_back(SPHERE.VertexPositions[idx]);
}
}
drawLineSet(storage, color, spherePoints.begin(), spherePoints.end());
}
}

View File

@ -0,0 +1,253 @@
/************************************************************************************//*!
\file SHDebugDrawSystem.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 16, 2022
\brief Contains the definition of the SHDebugDrawSystem class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// STL Includes
#include <vector>
// Project Includes
#include "SH_API.h"
#include "Math/Vector/SHVec2.h"
#include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h"
#include "ECS_Base/System/SHSystem.h"
#include "ECS_Base/System/SHSystemRoutine.h"
#include "Resource/SHHandle.h"
#include "Graphics/Buffers/SHVkBuffer.h"
#include "SHGraphicsConstants.h"
#include "Math/SHColour.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHVkBuffer;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
/// <summary>
/// Manages the Debug Draw system.
/// </summary>
class SH_API SHDebugDrawSystem final : public SHSystem
{
public:
/*---------------------------------------------------------------------------------*/
/* System Routines */
/*---------------------------------------------------------------------------------*/
class SH_API ProcessPointsRoutine final : public SHSystemRoutine
{
public:
ProcessPointsRoutine();
virtual void Execute(double dt) noexcept override final;
};
/*---------------------------------------------------------------------------------*/
/* SHSystem overrides */
/*---------------------------------------------------------------------------------*/
virtual void Init() override final;
virtual void Exit() override final;
/*---------------------------------------------------------------------------------*/
/* Configuration Functions */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// Configures the line width used to draw all lines in the Debug Draw system.
/// </summary>
float LineWidth = 1.0f;
/*---------------------------------------------------------------------------------*/
/* Draw Functions */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// Renders a line between two points in world space.
/// </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 DrawLine(const SHVec4& color, const SHVec3& startPt, const SHVec3& endPt);
/// <summary>
/// Renders a triangle indicated by three points in world space.
/// </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 DrawTri(const SHVec4& color, const SHVec3& pt1, const SHVec3& pt2, const SHVec3& pt3);
/// <summary>
/// Renders a quadrilateral indicated by four points in world space.
/// </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 DrawQuad(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.
/// </summary>
/// <param name="color">Colour of the polygon.</param>
/// <param name="pointList">List of points for the polygon.</param>
void DrawPoly(const SHVec4& color, std::initializer_list<SHVec3> pointList);
/// <summary>
/// Renders a polygon indicated by the specified set of points in world space.
/// </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 DrawPoly(const SHVec4& color, IterType pointListBegin, IterType pointListEnd);
/// <summary>
/// Renders a wireframe cube centered around the position specified in world space.
/// </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 DrawCube(const SHVec4& color, const SHVec3& pos, const SHVec3& size);
/// <summary>
/// Renders a wireframe sphere centered around the position specified in world space.
/// </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 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:
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*---------------------------------------------------------------------------------*/
struct SH_API PointVertex
{
SHVec4 Position;
SHVec4 Color;
};
using TripleBuffer = std::array<Handle<SHVkBuffer>, SHGraphicsConstants::NUM_FRAME_BUFFERS>;
using TripleUInt = std::array<uint32_t , SHGraphicsConstants::NUM_FRAME_BUFFERS>;
using TripleBool = std::array<bool , SHGraphicsConstants::NUM_FRAME_BUFFERS>;
/*---------------------------------------------------------------------------------*/
/* Constants */
/*---------------------------------------------------------------------------------*/
static constexpr uint32_t MAX_POINTS = 100'000;
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
// CPU Buffers
std::vector<PointVertex> points;
std::vector<PointVertex> persistentPoints;
// GPU Buffers
TripleBuffer vertexBuffers;
TripleUInt numPoints;
TripleBuffer persistentVertexBuffers;
TripleUInt numPersistentPoints;
TripleBool persistentBuffersCleared;
// Cached Points for polygon drawing
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);
};
}
#include "SHDebugDrawSystem.hpp"

View File

@ -0,0 +1,89 @@
/************************************************************************************//*!
\file SHDebugDrawSystem.hpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 16, 2022
\brief Contains the definition of template functions the SHDebugDrawSystem
class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
#include "SHDebugDrawSystem.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Draw Functions */
/*-----------------------------------------------------------------------------------*/
template<typename IterType>
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
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;
}
const size_t POINTS_ROUNDED_COUNT = POINTS_COUNT / 2 * 2;
for (auto pointIter = pointListBegin; pointIter != (pointListBegin + POINTS_ROUNDED_COUNT); ++pointIter)
{
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 });
}
}

View File

@ -70,7 +70,17 @@ namespace SHADE
*/
/***************************************************************************/
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;
};
struct VertexBufferBindings

View File

@ -37,6 +37,10 @@ of DigiPen Institute of Technology is prohibited.
#include "Assets/Asset Types/SHTextureAsset.h"
#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h"
#include "Assets/SHAssetManager.h"
#include "Resource/SHResourceManager.h"
#include "Graphics/SHVkUtil.h"
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
namespace SHADE
{
@ -48,7 +52,11 @@ namespace SHADE
/* BACKEND BOILERPLATE */
/*-----------------------------------------------------------------------*/
// Set Up Instance
#ifdef _DEBUG
SHVkInstance::Init(true, true, true);
#else
SHVkInstance::Init(true, false, true);
#endif
// Get Physical Device and Construct Logical Device
physicalDevice = SHVkInstance::CreatePhysicalDevice(SH_PHYSICAL_DEVICE_TYPE::BEST);
@ -104,14 +112,16 @@ namespace SHADE
descPool = device->CreateDescriptorPools();
// Create generic command buffer
//transferCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
shaderModuleLibrary.ImportAllShaderSource(device);
shaderModuleLibrary.ReflectAllShaderModules();
// Load Built In Shaders
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
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 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
@ -150,67 +160,121 @@ namespace SHADE
renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
}
/*-----------------------------------------------------------------------*/
/* SCENE RENDER GRAPH RESOURCES */
/*-----------------------------------------------------------------------*/
// Initialize world render graph
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("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("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("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("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",
{
"Position",
"Entity ID",
"Light Layer Indices",
"Normals",
//"Tangents",
"Albedo",
"Depth Buffer",
"Scene"
"Scene",
"SSAO",
"SSAO Blur"
},
{}); // no predecessors
/*-----------------------------------------------------------------------*/
/* G-BUFFER SUBPASS INIT */
/*-----------------------------------------------------------------------*/
auto gBufferSubpass = gBufferNode->AddSubpass("G-Buffer Write");
gBufferSubpass->AddColorOutput("Position");
gBufferSubpass->AddColorOutput("Entity ID");
gBufferSubpass->AddColorOutput("Light Layer Indices");
gBufferSubpass->AddColorOutput("Normals");
//gBufferSubpass->AddColorOutput("Tangents");
gBufferSubpass->AddColorOutput("Albedo");
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
//// kirsch
//auto kirschShader = shaderModuleLibrary.GetShaderModule("KirschCs.glsl");
//gBufferNode->AddNodeCompute(kirschShader, { "Position", "Scene" });
/*-----------------------------------------------------------------------*/
/* SSAO PASS AND DATA INIT */
/*-----------------------------------------------------------------------*/
ssaoStorage = resourceManager.Create<SHSSAO>();
//// copy
//auto pureCopyShader = shaderModuleLibrary.GetShaderModule("PureCopyCs.glsl");
//gBufferNode->AddNodeCompute(pureCopyShader, { "Position", "Scene" });
ssaoTransferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
ssaoTransferCmdBuffer->BeginRecording();
// deferred composite
auto deferredCompositeShader = shaderModuleLibrary.GetBuiltInShaderModule("DeferredComposite_CS");
gBufferNode->AddNodeCompute(deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "Scene" });
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");
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});
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, {"G-Buffer"}); // no predecessors
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
auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass");
dummySubpass->AddInput("Scene");
/*-----------------------------------------------------------------------*/
/* GENERATE RENDER GRAPH */
/*-----------------------------------------------------------------------*/
// Generate world render graph
worldRenderGraph->Generate();
/*-----------------------------------------------------------------------*/
/* BIND RENDER GRAPH TO RENDERER */
/*-----------------------------------------------------------------------*/
// Add world renderer to default viewport
worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
worldRenderer->SetCamera(worldCamera);
worldRenderer->SetCameraDirector(cameraSystem->CreateDirector());
auto cubeVS = shaderModuleLibrary.GetBuiltInShaderModule("TestCube_VS");
auto cubeFS = shaderModuleLibrary.GetBuiltInShaderModule("TestCube_FS");
// Create default materials
defaultMaterial = AddMaterial(defaultVertShader, defaultFragShader, gBufferSubpass);
defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferSubpass);
// Create debug draw pipeline
debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass);
debugDrawDepthPipeline = createDebugDrawPipeline(debugDrawNodeDepth->GetRenderpass(), debugDrawDepthSubpass);
}
void SHGraphicsSystem::InitMiddleEnd(void) noexcept
@ -249,6 +313,7 @@ namespace SHADE
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
lightingSubSystem->Init(device, descPool);
}
#ifdef SHEDITOR
@ -354,6 +419,17 @@ namespace SHADE
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 (int vpIndex = 0; vpIndex < static_cast<int>(viewports.size()); ++vpIndex)
@ -390,8 +466,7 @@ namespace SHADE
currentCmdBuffer->BindIndexBuffer(buffer, 0);
}
// Bind the descriptor set for lights
lightingSubSystem->Run(currentCmdBuffer, frameIndex);
lightingSubSystem->BindDescSet(currentCmdBuffer, frameIndex);
// Bind textures
auto textureDescSet = texLibrary.GetTextureDescriptorSetGroup();
@ -415,7 +490,7 @@ namespace SHADE
{
auto editorSystem = SHSystemManager::GetSystem<SHEditor>();
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
renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex);
}
@ -630,10 +705,14 @@ namespace SHADE
void SHGraphicsSystem::BuildMeshBuffers()
{
transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
device->WaitIdle();
transferCmdBuffer->BeginRecording();
meshLibrary.BuildBuffers(device, transferCmdBuffer);
transferCmdBuffer->EndRecording();
graphicsQueue->SubmitCommandBuffer({ transferCmdBuffer });
device->WaitIdle();
transferCmdBuffer.Free(); transferCmdBuffer = {};
}
/*---------------------------------------------------------------------------------*/
@ -658,10 +737,19 @@ namespace SHADE
void SHGraphicsSystem::BuildTextures()
{
graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
device->WaitIdle();
texLibrary.BuildTextures
(
device, graphicsTexCmdBuffer, graphicsQueue, descPool
);
device->WaitIdle();
graphicsTexCmdBuffer.Free(); graphicsTexCmdBuffer = {};
}
Handle<SHTexture> SHGraphicsSystem::GetTextureHandle(SHTexture::Index textureId) const
{
return texLibrary.GetTextureHandle(textureId);
}
#pragma endregion ADD_REMOVE
@ -701,6 +789,7 @@ namespace SHADE
void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
{
reinterpret_cast<SHGraphicsSystem*>(system)->EndRender();
SHResourceManager::FinaliseChanges();
}
/*-----------------------------------------------------------------------------------*/
@ -718,8 +807,13 @@ namespace SHADE
if (!renderable.HasChanged())
continue;
// Remove from old material's SuperBatch
Handle<SHMaterialInstance> prevMaterial = renderable.GetPrevMaterial();
if (!renderable.GetMesh())
{
SHLOG_CRITICAL("NULL Mesh provided!");
}
// Remove from the SuperBatch it is previously in (prevMat if mat has changed)
Handle<SHMaterialInstance> prevMaterial = renderable.HasMaterialChanged() ? renderable.GetPrevMaterial() : renderable.GetMaterial();
if (prevMaterial)
{
Handle<SHSuperBatch> oldSuperBatch = prevMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
@ -808,5 +902,57 @@ namespace SHADE
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
}

View File

@ -25,13 +25,13 @@ of DigiPen Institute of Technology is prohibited.
#include "ECS_Base/System/SHSystemRoutine.h"
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
#include "Graphics/RenderGraph/SHRenderGraph.h"
#include "Graphics/MiddleEnd/Shaders/SHShaderModuleLibrary.h"
#include "SHMeshLibrary.h"
#include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h"
#include "../Textures/SHTextureLibrary.h"
#include "../Textures/SHVkSamplerCache.h"
#include "Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h"
#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h"
#include "Graphics/MiddleEnd/PostProcessing/SHSSAO.h"
namespace SHADE
{
@ -263,6 +263,21 @@ namespace SHADE
*/
/***************************************************************************/
void BuildTextures();
/***************************************************************************/
/*!
*
\brief
Retrieves the texture handle at the specified texture index.
\param textureId
Index of the texture to look for.
\returns
Handle to the texture
*/
/***************************************************************************/
Handle<SHTexture> GetTextureHandle(SHTexture::Index textureId) const;
void PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept;
void HandleResize(void) noexcept;
@ -289,10 +304,14 @@ namespace SHADE
Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
Handle<SHRenderGraphNode> GetPrimaryRenderpass() const noexcept;
//SHRenderGraph const& GetRenderGraph(void) const noexcept;
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
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(); }
/*-----------------------------------------------------------------------------*/
/* Getters */
/*-----------------------------------------------------------------------------*/
SHWindow* GetWindow() noexcept { return window; }
private:
/*-----------------------------------------------------------------------------*/
@ -313,6 +332,7 @@ namespace SHADE
Handle<SHVkDescriptorPool> descPool;
Handle<SHVkCommandPool> graphicsCmdPool;
Handle<SHVkCommandBuffer> transferCmdBuffer;
Handle<SHVkCommandBuffer> ssaoTransferCmdBuffer;
Handle<SHVkCommandBuffer> graphicsTexCmdBuffer;
SHRenderContext renderContext;
std::array<Handle<SHVkSemaphore>, 2> graphSemaphores;
@ -320,11 +340,12 @@ namespace SHADE
SHWindow* window = nullptr;
// Middle End Resources
SHResourceHub resourceManager;
SHResourceHub resourceManager;
SHMeshLibrary meshLibrary;
SHTextureLibrary texLibrary;
SHSamplerCache samplerCache;
SHMaterialInstanceCache materialInstanceCache;
// Viewports
#ifdef SHEDITOR
Handle<SHViewport> editorViewport;
@ -335,21 +356,27 @@ namespace SHADE
Handle<SHViewport> worldViewport; // Whole screen
std::vector<Handle<SHViewport>> viewports; // Additional viewports
// Debug Renderers
Handle<SHRenderer> debugWorldRenderer;
Handle<SHRenderer> debugScreenRenderer;
// Temp renderers
Handle<SHRenderer> worldRenderer;
// Temp Cameras
Handle<SHCamera> worldCamera;
Handle<SHCamera> screenCamera;
SHShaderModuleLibrary shaderModuleLibrary;
// Temp Materials
// Built-In Shaders
Handle<SHVkShaderModule> defaultVertShader;
Handle<SHVkShaderModule> defaultFragShader;
Handle<SHVkShaderModule> debugVertShader;
Handle<SHVkShaderModule> debugFragShader;
Handle<SHVkShaderModule> deferredCompositeShader;
Handle<SHVkShaderModule> ssaoShader;
Handle<SHVkShaderModule> ssaoBlurShader;
// Built-In Materials
Handle<SHMaterial> defaultMaterial;
Handle<SHVkPipeline> debugDrawPipeline;
Handle<SHVkPipeline> debugDrawDepthPipeline;
Handle<SHRenderGraph> worldRenderGraph;
@ -357,10 +384,15 @@ namespace SHADE
Handle<SHMousePickSystem> mousePickSystem;
Handle<SHPostOffscreenRenderSystem> postOffscreenRender;
Handle<SHLightingSubSystem> lightingSubSystem;
Handle<SHSSAO> ssaoStorage;
uint32_t resizeWidth;
uint32_t resizeHeight;
bool restoredFromMinimize = false;
uint32_t resizeWidth = 1;
uint32_t resizeHeight = 1;
bool restoredFromMinimize = false;
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
Handle<SHVkPipeline> createDebugDrawPipeline(Handle<SHVkRenderpass> renderPass, Handle<SHSubpass> subpass);
};
}

View File

@ -0,0 +1,77 @@
/************************************************************************************//*!
\file SHGraphicsSystemInterface.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 31, 2022
\brief Contains the definitions of the functions of the static
SHGraphicsSystemInterface class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
// Precompiled Headers
#include "SHpch.h"
// Primary Header
#include "SHGraphicsSystemInterface.h"
// Project Includes
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
#include "Graphics/Windowing/SHWindow.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Usage Functions */
/*-----------------------------------------------------------------------------------*/
uint32_t SHGraphicsSystemInterface::GetWindowWidth()
{
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (gfxSystem)
{
const auto WND = gfxSystem->GetWindow();
return WND->GetWindowSize().first;
}
SHLOG_WARNING("[SHGraphicsSystemInterface] Failed to get window width. Value of 0 returned instead.");
return 0;
}
uint32_t SHGraphicsSystemInterface::GetWindowHeight()
{
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (gfxSystem)
{
const auto WND = gfxSystem->GetWindow();
return WND->GetWindowSize().second;
}
SHLOG_WARNING("[SHGraphicsSystemInterface] Failed to get window height. Value of 0 returned instead.");
return 0;
}
bool SHGraphicsSystemInterface::IsFullscreen()
{
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (gfxSystem)
{
const auto WND = gfxSystem->GetWindow();
return WND->GetWindowData().isFullscreen;
}
SHLOG_WARNING("[SHGraphicsSystemInterface] Failed to get window fullscreen status. Value of false returned instead.");
return false;
}
void SHGraphicsSystemInterface::CloseWindow()
{
auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
if (gfxSystem)
{
auto WND = gfxSystem->GetWindow();
return WND->Close();
}
SHLOG_WARNING("[SHGraphicsSystemInterface] Failed to close window.");
}
}

View File

@ -0,0 +1,52 @@
/************************************************************************************//*!
\file SHGraphicsSystemInterface.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 31, 2022
\brief Contains the definition of the SHGraphicsSystemInterface static class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
namespace SHADE
{
/// <summary>
/// Static class that wraps up certain functions in the SHGraphicsSystem so that
/// accessing it from SHADE_Managed would not cause issues due to C++20 features.
/// </summary>
class SH_API SHGraphicsSystemInterface final
{
public:
/*---------------------------------------------------------------------------------*/
/* Constructor */
/*---------------------------------------------------------------------------------*/
SHGraphicsSystemInterface() = delete;
/*---------------------------------------------------------------------------------*/
/* Static Usage Functions */
/*---------------------------------------------------------------------------------*/
/// <summary>
/// Retrieves the current window width.
/// </summary>
/// <returns>The current window width.</returns>
static uint32_t GetWindowWidth();
/// <summary>
/// Retrieves the current window height.
/// </summary>
/// <returns>The current window height.</returns>
static uint32_t GetWindowHeight();
/// <summary>
/// Retrieves the current window fullscreen status.
/// </summary>
/// <returns>The current window fullscreen status..</returns>
static bool IsFullscreen();
/// <summary>
/// Closes the current window, and depending on the implementation, should also
/// close the application.
/// </summary>
static void CloseWindow();
};
}

View File

@ -83,13 +83,14 @@ namespace SHADE
{
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();
cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex);
@ -97,16 +98,19 @@ namespace SHADE
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::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
}
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 = vpMatrix;
cpuCameraData.viewProjectionMatrix = SHMatrix::Transpose(projMatrix * viewMatrix);
cpuCameraData.viewMatrix = SHMatrix::Transpose(viewMatrix);
cpuCameraData.projectionMatrix = SHMatrix::Transpose(projMatrix);
}
Handle<SHRenderGraph> SHRenderer::GetRenderGraph(void) const noexcept
@ -119,4 +123,9 @@ namespace SHADE
return commandBuffers[frameIndex];
}
Handle<SHCameraDirector> SHRenderer::GetCameraDirector(void) const noexcept
{
return cameraDirector;
}
}

View File

@ -46,6 +46,8 @@ namespace SHADE
{
SHVec4 cameraPosition;
SHMatrix viewProjectionMatrix;
SHMatrix viewMatrix;
SHMatrix projectionMatrix;
};
/*---------------------------------------------------------------------------------*/
@ -79,15 +81,16 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
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, SHMatrix exteriorMatrix) noexcept;
void UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept;
void UpdateCameraDataToBuffer (void) noexcept;
void SetViewProjectionMatrix (SHMatrix const& vpMatrix) noexcept;
void SetViewProjectionMatrix (SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept;
/*-----------------------------------------------------------------------------*/
/* Setters and Getters */
/*-----------------------------------------------------------------------------*/
Handle<SHRenderGraph> GetRenderGraph (void) const noexcept;
Handle<SHRenderGraph> GetRenderGraph (void) const noexcept;
Handle<SHVkCommandBuffer> GetCommandBuffer(uint32_t frameIndex) const noexcept;
Handle<SHCameraDirector> GetCameraDirector (void) const noexcept;
private:
/*-----------------------------------------------------------------------------*/

View File

@ -9,9 +9,9 @@ namespace SHADE
{
lightData.Reset();
SetType(SH_LIGHT_TYPE::DIRECTIONAL);
indexInBuffer = std::numeric_limits<uint32_t>::max();
//indexInBuffer = std::numeric_limits<uint32_t>::max();
isActive = true;
Unbind();
//Unbind();
}
@ -23,28 +23,28 @@ namespace SHADE
void SHLightComponent::SetPosition(SHVec3 const& position) noexcept
{
lightData.position = position;
MakeDirty();
//MakeDirty();
}
void SHLightComponent::SetType(SH_LIGHT_TYPE type) noexcept
{
lightData.type = type;
MakeDirty();
//MakeDirty();
}
void SHLightComponent::SetDirection(SHVec3 const& direction) noexcept
{
lightData.direction = direction;
MakeDirty();
//MakeDirty();
}
void SHLightComponent::SetColor(SHVec4 const& color) noexcept
{
lightData.color = color;
MakeDirty();
//MakeDirty();
}
void SHLightComponent::ModifyCullingMask(uint8_t layerIndex, bool value) noexcept
@ -54,7 +54,7 @@ namespace SHADE
else
lightData.cullingMask &= ~(1u << layerIndex);
MakeDirty();
//MakeDirty();
}
void SHLightComponent::SetCullingMask(uint32_t const& value) noexcept
@ -65,43 +65,43 @@ namespace SHADE
void SHLightComponent::SetAllLayers(void) noexcept
{
lightData.cullingMask = std::numeric_limits<uint32_t>::max();
MakeDirty();
//MakeDirty();
}
void SHLightComponent::ClearAllLayers(void) noexcept
{
lightData.cullingMask = 0;
MakeDirty();
//MakeDirty();
}
void SHLightComponent::MakeDirty(void) noexcept
{
dirty = true;
}
//void SHLightComponent::MakeDirty(void) noexcept
//{
// dirty = true;
//}
void SHLightComponent::ClearDirtyFlag(void) noexcept
{
dirty = false;
}
//void SHLightComponent::ClearDirtyFlag(void) noexcept
//{
// dirty = false;
//}
void SHLightComponent::Unbind(void) noexcept
{
bound = false;
MakeDirty();
}
void SHLightComponent::SetBound(uint32_t inIndexInBuffer) noexcept
{
bound = true;
indexInBuffer = inIndexInBuffer;
}
// void SHLightComponent::Unbind(void) noexcept
// {
// bound = false;
// MakeDirty();
// }
//
// void SHLightComponent::SetBound(uint32_t inIndexInBuffer) noexcept
//{
// bound = true;
// indexInBuffer = inIndexInBuffer;
// }
void SHLightComponent::SetStrength(float value) noexcept
{
lightData.strength = value;
MakeDirty();
//MakeDirty();
}
SHLightData const& SHLightComponent::GetLightData(void) const noexcept
@ -135,20 +135,20 @@ namespace SHADE
}
bool SHLightComponent::IsDirty(void) const noexcept
{
return dirty;
}
//bool SHLightComponent::IsDirty(void) const noexcept
//{
// return dirty;
//}
bool SHLightComponent::GetBound(void) const noexcept
{
return bound;
}
//bool SHLightComponent::GetBound(void) const noexcept
//{
// return bound;
//}
uint32_t SHLightComponent::GetIndexInBuffer(void) const noexcept
{
return indexInBuffer;
}
//uint32_t SHLightComponent::GetIndexInBuffer(void) const noexcept
//{
// return indexInBuffer;
//}
float SHLightComponent::GetStrength(void) const noexcept
{

View File

@ -17,13 +17,13 @@ namespace SHADE
//! 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
//! 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.
bool dirty;
////! If the light component changed some value we mark this true.
//bool dirty;
//! If the light's data is already in the buffers, this will be set to true.
bool bound;
////! If the light's data is already in the buffers, this will be set to true.
//bool bound;
public:
@ -44,10 +44,10 @@ namespace SHADE
void SetCullingMask (uint32_t const& value) noexcept;
void SetAllLayers (void) noexcept; // serialized
void ClearAllLayers (void) noexcept; // serialized
void MakeDirty (void) noexcept;
void ClearDirtyFlag (void) noexcept;
void Unbind (void) noexcept;
void SetBound (uint32_t inIndexInBuffer) noexcept;
//void MakeDirty (void) noexcept;
//void ClearDirtyFlag (void) noexcept;
//void Unbind (void) noexcept;
//void SetBound (uint32_t inIndexInBuffer) noexcept;
void SetStrength (float value) noexcept; // serialized
@ -57,8 +57,8 @@ namespace SHADE
SHVec3 const& GetDirection (void) const noexcept; // serialized
SHVec4 const& GetColor (void) const noexcept; // serialized
uint32_t const& GetCullingMask (void) const noexcept; // serialized
bool IsDirty (void) const noexcept;
bool GetBound (void) const noexcept;
//bool IsDirty (void) const noexcept;
//bool GetBound (void) const noexcept;
uint32_t GetIndexInBuffer (void) const noexcept;
float GetStrength (void) const noexcept;
RTTR_ENABLE()

View File

@ -8,6 +8,8 @@
#include "SHLightComponent.h"
#include "ECS_Base/Managers/SHComponentManager.h"
#include "SHLightComponent.h"
#include "Math/Vector/SHVec4.h"
#include "Math/SHMatrix.h"
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();
switch (lightData.type)
@ -40,8 +42,12 @@ namespace SHADE
{
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->direction = lightData.direction;
lightPtr->direction = SHVec3 (transformedDir.x, transformedDir.y, transformedDir.z);
//lightPtr->direction = lightData.direction;
lightPtr->diffuseColor = lightData.color;
lightPtr->active = lightComp->isActive;
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)
{
@ -259,10 +265,10 @@ namespace SHADE
void* writeLocation = reinterpret_cast<uint8_t*>(intermediateData.get()) + (lightDataAlignedSize * numLights);
// Write the light data to address
WriteLightToAddress(writeLocation, unboundLight);
WriteLightToAddress(writeLocation, viewMat, unboundLight);
// Set the light component to be bound to that location
unboundLight->SetBound(numLights);
//unboundLight->SetBound(numLights);
// Increase light count
++numLights;
@ -280,11 +286,11 @@ namespace SHADE
*/
/***************************************************************************/
void SHLightingSubSystem::PerTypeData::ModifyLight(SHLightComponent* lightComp) noexcept
{
void* writeLocation = reinterpret_cast<uint8_t*>(intermediateData.get()) + (lightDataAlignedSize * lightComp->GetIndexInBuffer());
WriteLightToAddress(writeLocation, lightComp);
}
//void SHLightingSubSystem::PerTypeData::ModifyLight(SHLightComponent* lightComp) noexcept
//{
// void* writeLocation = reinterpret_cast<uint8_t*>(intermediateData.get()) + (lightDataAlignedSize * lightComp->GetIndexInBuffer());
// WriteLightToAddress(writeLocation, lightComp);
//}
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
}
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);
auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
bool expanded = false;
bool rewrite = false;
if (numLightComponents > lightComps.size())
{
rewrite = true;
ResetNumLights();
}
// First we reset the number of lights. We do this every frame so that we can count how many lights we have
ResetNumLights();
numLightComponents = lightComps.size();
//bool rewrite = false;
//if (numLightComponents > lightComps.size())
//{
// rewrite = true;
// ResetNumLights();
//}
//numLightComponents = lightComps.size();
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
// 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];
}
// if there was modification to the light data
if (light.IsDirty())
//if (light.IsDirty())
{
// Write the data to the CPU
perTypeData[enumValue].ModifyLight(&light);
//perTypeData[enumValue].ModifyLight(&light);
// 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.
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] });
}
}

View File

@ -95,15 +95,15 @@ namespace SHADE
//! to the GPU that stores NUM_FRAME_BUFFERS copies.
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 MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
void InitializeData (Handle<SHVkLogicalDevice> logicalDevice, SH_LIGHT_TYPE type) noexcept;
void Expand (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
void AddLight (Handle<SHVkLogicalDevice> logicalDevice, SHLightComponent* unboundLight, bool expanded) noexcept;
void ModifyLight (SHLightComponent* lightComp) noexcept;
void AddLight (Handle<SHVkLogicalDevice> logicalDevice, SHLightComponent* unboundLight, SHMatrix const& viewMat, bool& expanded) noexcept;
//void ModifyLight (SHLightComponent* lightComp) noexcept;
void WriteToGPU (uint32_t frameIndex) 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
//! set is less than the size recorded, rewrite all light components into the its respective buffers. If its more,
//! don't do anything.
uint32_t numLightComponents;
//uint32_t numLightComponents;
/*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER FUNCTIONS */
@ -159,8 +159,10 @@ namespace SHADE
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
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 BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
};
}

View File

@ -0,0 +1,74 @@
/************************************************************************************//*!
\file SHMaterialSpec.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Nov 2, 2022
\brief Contains the function definitions of SHMaterialSpec.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#include "SHpch.h"
#include "SHMaterialSpec.h"
#include "Graphics/Shaders/SHVkShaderModule.h"
#include "Resource/SHResourceManager.h"
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Constructors */
/*-----------------------------------------------------------------------------------*/
SHMaterialSpec::SHMaterialSpec(const SHMaterial& material)
{
// Get Shader Handles
const auto& SHADERS = material.GetPipeline()->GetPipelineLayout()->GetShaderModules();
Handle<SHVkShaderModule> vShaderMod, fShaderMod;
for (const auto& shader : SHADERS)
{
const auto FLAG_BITS = shader->GetShaderStageFlagBits();
if (FLAG_BITS & vk::ShaderStageFlagBits::eVertex)
vShaderMod = shader;
else if (FLAG_BITS & vk::ShaderStageFlagBits::eFragment)
fShaderMod = shader;
}
vertexShader = SHResourceManager::GetAssetID<SHVkShaderModule>(vShaderMod).value_or(0);
fragShader = SHResourceManager::GetAssetID<SHVkShaderModule>(fShaderMod).value_or(0);
subpassName = material.GetPipeline()->GetPipelineState().GetSubpass()->GetName();
// Write Properties
Handle<SHShaderBlockInterface> pipelineProperties = material.GetShaderBlockInterface();
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
{
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
if (!VARIABLE)
break;
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
YAML::Node propNode;
switch (VARIABLE->type)
{
case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT:
propNode = material.GetProperty<float>(VARIABLE->offset);
break;
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
propNode = material.GetProperty<int>(VARIABLE->offset);
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
propNode = material.GetProperty<SHVec2>(VARIABLE->offset);
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
propNode = material.GetProperty<SHVec3>(VARIABLE->offset);
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
propNode = material.GetProperty<SHVec4>(VARIABLE->offset);
break;
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
default:
continue;
break;
}
properties[VAR_NAME.data()] = propNode;
}
}
}

View File

@ -0,0 +1,51 @@
/************************************************************************************//*!
\file SHMaterialSpec.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 31, 2022
\brief Contains the struct definition of SHMaterialSpec.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// Standard Library
#include <string>
#include <vector>
#include <utility>
// Project Includes
#include "Assets/SHAssetMacros.h"
#include <yaml-cpp/yaml.h>
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declaration */
/*-----------------------------------------------------------------------------------*/
class SHMaterial;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
/*************************************************************************************/
/*!
\brief
Describes a Material's serialized properties. A representation of a material that is
independent of GPU resources.
*/
/*************************************************************************************/
struct SHMaterialSpec
{
AssetID vertexShader;
AssetID fragShader;
std::string subpassName;
YAML::Node properties;
/*---------------------------------------------------------------------------------*/
/* Constructors */
/*---------------------------------------------------------------------------------*/
SHMaterialSpec() = default;
explicit SHMaterialSpec(const SHMaterial& material);
};
}

View File

@ -3,7 +3,7 @@
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Aug 30, 2022
\brief Contains definitions for all of the functions of the classes that deal
\brief Contains definitions for all of the functions of the classes that deal
with storage and management of vertex and index buffers of meshes.
Copyright (C) 2022 DigiPen Institute of Technology.
@ -18,50 +18,59 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHMeshData SHPrimitiveGenerator::cubeMesh;
SHMeshData SHPrimitiveGenerator::sphereMesh;
/*-----------------------------------------------------------------------------------*/
/* Primitive Generation Functions */
/*-----------------------------------------------------------------------------------*/
SHMeshData SHPrimitiveGenerator::Cube() noexcept
{
SHMeshData mesh;
mesh.vertexPositions =
mesh.VertexPositions =
{
// front
SHVec3(-0.5f, -0.5f, 0.5f),
SHVec3( 0.5f, -0.5f, 0.5f),
SHVec3( 0.5f, 0.5f, 0.5f),
SHVec3(-0.5f, 0.5f, 0.5f),
SHVec3(-0.5f, -0.5f, 0.5f),
SHVec3(0.5f, -0.5f, 0.5f),
SHVec3(0.5f, 0.5f, 0.5f),
SHVec3(-0.5f, 0.5f, 0.5f),
// back
SHVec3(-0.5f, -0.5f, -0.5f),
SHVec3(-0.5f, 0.5f, -0.5f),
SHVec3( 0.5f, 0.5f, -0.5f),
SHVec3( 0.5f, -0.5f, -0.5f),
SHVec3(-0.5f, -0.5f, -0.5f),
SHVec3(-0.5f, 0.5f, -0.5f),
SHVec3(0.5f, 0.5f, -0.5f),
SHVec3(0.5f, -0.5f, -0.5f),
// top
// top
SHVec3(-0.5f, 0.5f, -0.5f),
SHVec3(-0.5f, 0.5f, 0.5f),
SHVec3( 0.5f, 0.5f, 0.5f),
SHVec3( 0.5f, 0.5f, -0.5f),
SHVec3(0.5f, 0.5f, 0.5f),
SHVec3(0.5f, 0.5f, -0.5f),
// bottom
SHVec3(-0.5f, -0.5f, -0.5f),
SHVec3( 0.5f, -0.5f, -0.5f),
SHVec3( 0.5f, -0.5f, 0.5f),
SHVec3(-0.5f, -0.5f, 0.5f),
SHVec3(-0.5f, -0.5f, -0.5f),
SHVec3(0.5f, -0.5f, -0.5f),
SHVec3(0.5f, -0.5f, 0.5f),
SHVec3(-0.5f, -0.5f, 0.5f),
// right
SHVec3(0.5f, -0.5f, -0.5f),
SHVec3(0.5f, 0.5f, -0.5f),
SHVec3(0.5f, 0.5f, 0.5f),
SHVec3(0.5f, -0.5f, 0.5f),
SHVec3(0.5f, -0.5f, -0.5f),
SHVec3(0.5f, 0.5f, -0.5f),
SHVec3(0.5f, 0.5f, 0.5f),
SHVec3(0.5f, -0.5f, 0.5f),
// left
SHVec3(-0.5f, -0.5f, -0.5f),
SHVec3(-0.5f, -0.5f, 0.5f),
SHVec3(-0.5f, 0.5f, 0.5f),
SHVec3(-0.5f, 0.5f, -0.5f)
SHVec3(-0.5f, -0.5f, -0.5f),
SHVec3(-0.5f, -0.5f, 0.5f),
SHVec3(-0.5f, 0.5f, 0.5f),
SHVec3(-0.5f, 0.5f, -0.5f)
};
mesh.vertexTexCoords =
mesh.VertexTexCoords =
{
SHVec2(0.0f, 1.0f),
SHVec2(1.0f, 1.0f),
@ -99,7 +108,7 @@ namespace SHADE
SHVec2(0.0f, 0.0f)
};
mesh.vertexTangents =
mesh.VertexTangents =
{
// front
SHVec3(1.0f, 0.0f, 0.0f),
@ -118,7 +127,7 @@ namespace SHADE
SHVec3(1.0f, 0.0f, 0.0f),
SHVec3(1.0f, 0.0f, 0.0f),
SHVec3(1.0f, 0.0f, 0.0f),
// bottom
SHVec3(1.0f, 0.0f, 0.0f),
SHVec3(1.0f, 0.0f, 0.0f),
@ -139,7 +148,7 @@ namespace SHADE
};
mesh.vertexNormals =
mesh.VertexNormals =
{
// front
SHVec3(0.0f, 0.0f, 1.0f),
@ -178,7 +187,7 @@ namespace SHADE
SHVec3(-1.0f, 0.0f, 0.0f)
};
mesh.indices =
mesh.Indices =
{
0, 1, 2, 0, 2, 3,
4, 5, 6, 4, 6, 7,
@ -193,31 +202,113 @@ namespace SHADE
Handle<SHMesh> SHPrimitiveGenerator::Cube(SHMeshLibrary& meshLibrary) noexcept
{
static SHMeshData meshData = Cube();
return meshLibrary.AddMesh
(
static_cast<uint32_t>(meshData.vertexPositions.size()),
meshData.vertexPositions.data(),
meshData.vertexTexCoords.data(),
meshData.vertexTangents.data(),
meshData.vertexNormals.data(),
static_cast<uint32_t>(meshData.indices.size()),
meshData.indices.data()
);
if (cubeMesh.VertexPositions.empty())
cubeMesh = Cube();
return addMeshDataTo(cubeMesh, meshLibrary);
}
Handle<SHADE::SHMesh> SHPrimitiveGenerator::Cube(SHGraphicsSystem& gfxSystem) noexcept
{
static SHMeshData meshData = Cube();
if (cubeMesh.VertexPositions.empty())
cubeMesh = Cube();
return addMeshDataTo(cubeMesh, gfxSystem);
}
SHADE::SHMeshData SHPrimitiveGenerator::Sphere() noexcept
{
SHMeshData meshData;
const int LAT_SLICES = 12;
const int LONG_SLICES = 12;
float radius = 1;
for (int latNum = 0; latNum <= LAT_SLICES; ++latNum)
{
float theta = static_cast<float>(latNum * std::numbers::pi / LAT_SLICES);
float sinTheta = sin(theta);
float cosTheta = cos(theta);
for (int longNum = 0; longNum <= LONG_SLICES; ++longNum)
{
float phi = static_cast<float>(longNum * 2 * std::numbers::pi / LONG_SLICES);
float sinPhi = sin(phi);
float cosPhi = cos(phi);
const SHVec3 NORMAL = SHVec3(cosPhi * sinTheta, cosTheta, sinPhi * sinTheta);
meshData.VertexNormals.emplace_back(NORMAL);
meshData.VertexTangents.emplace_back(/* TODO */);
meshData.VertexTexCoords.emplace_back
(
1.0f - (longNum / static_cast<float>(LONG_SLICES)),
1.0f - (latNum / static_cast<float>(LAT_SLICES))
);
meshData.VertexPositions.emplace_back(radius * NORMAL.x, radius * NORMAL.y, radius * NORMAL.z);
}
}
for (int latNumber{}; latNumber < LAT_SLICES; latNumber++)
{
for (int longNumber{}; longNumber < LONG_SLICES; longNumber++)
{
const auto FIRST = (latNumber * (LONG_SLICES + 1)) + longNumber;
const auto SECOND = (FIRST + LONG_SLICES + 1);
meshData.Indices.emplace_back(FIRST);
meshData.Indices.emplace_back(SECOND);
meshData.Indices.emplace_back(FIRST + 1);
meshData.Indices.emplace_back(SECOND);
meshData.Indices.emplace_back(SECOND + 1);
meshData.Indices.emplace_back(FIRST + 1);
}
}
return meshData;
}
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::Sphere(SHMeshLibrary& meshLibrary) noexcept
{
if (sphereMesh.VertexPositions.empty())
sphereMesh = Sphere();
return addMeshDataTo(sphereMesh, meshLibrary);
}
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::Sphere(SHGraphicsSystem& gfxSystem) noexcept
{
if (sphereMesh.VertexPositions.empty())
sphereMesh = Sphere();
return addMeshDataTo(sphereMesh, gfxSystem);
}
/*-----------------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------------*/
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::addMeshDataTo(const SHMeshData& meshData, SHMeshLibrary& meshLibrary) noexcept
{
return meshLibrary.AddMesh
(
static_cast<uint32_t>(meshData.VertexPositions.size()),
meshData.VertexPositions.data(),
meshData.VertexTexCoords.data(),
meshData.VertexTangents.data(),
meshData.VertexNormals.data(),
static_cast<uint32_t>(meshData.Indices.size()),
meshData.Indices.data()
);
}
SHADE::Handle<SHADE::SHMesh> SHPrimitiveGenerator::addMeshDataTo(const SHMeshData& meshData, SHGraphicsSystem& gfxSystem) noexcept
{
return gfxSystem.AddMesh
(
static_cast<uint32_t>(meshData.vertexPositions.size()),
meshData.vertexPositions.data(),
meshData.vertexTexCoords.data(),
meshData.vertexTangents.data(),
meshData.vertexNormals.data(),
static_cast<uint32_t>(meshData.indices.size()),
meshData.indices.data()
static_cast<uint32_t>(meshData.VertexPositions.size()),
meshData.VertexPositions.data(),
meshData.VertexTexCoords.data(),
meshData.VertexTangents.data(),
meshData.VertexNormals.data(),
static_cast<uint32_t>(meshData.Indices.size()),
meshData.Indices.data()
);
}
}

View File

@ -4,9 +4,9 @@
\par email: kahwei.tng\@digipen.edu
\date Sep 18, 2022
\brief Contains the static class definition of SHPrimitiveGenerator.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
@ -30,12 +30,12 @@ namespace SHADE
/*************************************************************************************/
/*!
\brief
Static class that contains functions for generating 3D primitives.
Static class that contains functions for generating 3D primitives.
*/
/*************************************************************************************/
class SH_API SHPrimitiveGenerator
{
public:
public:
/*---------------------------------------------------------------------------------*/
/* Constructors */
/*---------------------------------------------------------------------------------*/
@ -43,7 +43,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
/* Primitive Generation Functions */
/*---------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------*/
/***********************************************************************************/
/*!
\brief
@ -53,20 +53,20 @@ namespace SHADE
SHMeshData object containing vertex data for the cube.
*/
/***********************************************************************************/
[[nodiscard]] static SHMeshData Cube() noexcept;
[[nodiscard]] static SHMeshData Cube() noexcept;
/***********************************************************************************/
/*!
\brief
Produces a cube and constructs a SHMesh using the SHMeshLibrary provided.
\param meshLibrary
Reference to the SHMeshLibrary to procude and store a cube mesh in.
Reference to the SHMeshLibrary to produce and store a cube mesh in.
\return
SHMesh object that points to the generated cube mesh in the SHMeshLibrary.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> Cube(SHMeshLibrary& meshLibrary) noexcept;
[[nodiscard]] static Handle<SHMesh> Cube(SHMeshLibrary& meshLibrary) noexcept;
/***********************************************************************************/
/*!
\brief
@ -79,12 +79,55 @@ namespace SHADE
SHMesh object that points to the generated cube mesh in the SHGraphicsSystem.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> Cube(SHGraphicsSystem& gfxSystem) noexcept;
[[nodiscard]] static Handle<SHMesh> Cube(SHGraphicsSystem& gfxSystem) noexcept;
/***********************************************************************************/
/*!
\brief
Produces a sphere and stores the data in a SHMeshData object.
private:
\return
SHMeshData object containing vertex data for the sphere.
*/
/***********************************************************************************/
[[nodiscard]] static SHMeshData Sphere() noexcept;
/***********************************************************************************/
/*!
\brief
Produces a sphere and constructs a SHMesh using the SHMeshLibrary provided.
\param meshLibrary
Reference to the SHMeshLibrary to produce and store a sphere mesh in.
\return
SHMesh object that points to the generated sphere mesh in the SHMeshLibrary.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> Sphere(SHMeshLibrary& meshLibrary) noexcept;
/***********************************************************************************/
/*!
\brief
Produces a sphere and constructs a SHMesh using the SHGraphicsSystem provided.
\param gfxSystem
Reference to the SHGraphicsSystem to produce and store a sphere mesh in.
\return
SHMesh object that points to the generated sphere mesh in the SHGraphicsSystem.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> Sphere(SHGraphicsSystem& gfxSystem) noexcept;
private:
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] static SHMeshData genCubeData() noexcept;
static Handle<SHMesh> addMeshDataTo(const SHMeshData& meshData, SHMeshLibrary& meshLibrary) noexcept;
static Handle<SHMesh> addMeshDataTo(const SHMeshData& meshData, SHGraphicsSystem& gfxSystem) noexcept;
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
static SHMeshData cubeMesh;
static SHMeshData sphereMesh;
};
}

View File

@ -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;
}
}

View File

@ -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;
};
}

View File

@ -1,139 +0,0 @@
#include "SHPch.h"
#include "SHShaderModuleLibrary.h"
#include "Graphics/Devices/SHVkLogicalDevice.h"
#include "Assets/SHAssetManager.h"
namespace SHADE
{
/***************************************************************************/
/*!
\brief
Imports all shader binaries from the source library.
\param logicalDeviceHdl
For creating shader modules.
\param sourceLib
The source library class that stores the container of shader binary data.
*/
/***************************************************************************/
//void SHShaderModuleLibrary::ImportFromSourceLibrary(Handle<SHVkLogicalDevice>& logicalDeviceHdl, SHShaderSourceLibrary const& sourceLib) noexcept
//{
// auto const& sources = sourceLib.GetSourceLibrary();
// for (auto const& source : sources)
// {
// vk::ShaderStageFlagBits shaderType{};
// switch (source.shaderType)
// {
// case SH_SHADER_TYPE::VERTEX:
// shaderType = vk::ShaderStageFlagBits::eVertex;
// break;
// case SH_SHADER_TYPE::FRAGMENT:
// shaderType = vk::ShaderStageFlagBits::eFragment;
// break;
// case SH_SHADER_TYPE::COMPUTE:
// shaderType = vk::ShaderStageFlagBits::eCompute;
// break;
// default:
// shaderType = vk::ShaderStageFlagBits::eVertex;
// break;
// }
// Handle<SHVkShaderModule> newShaderModule = logicalDeviceHdl->CreateShaderModule(source.spirvBinary, "main", shaderType, source.name);
// shaderModules.emplace(source.id, newShaderModule);
// stringToID.emplace(source.name, source.id);
// }
//}
/***************************************************************************/
/*!
\brief
Gets the shader module based on module name.
\param shaderName
\return
*/
/***************************************************************************/
//Handle<SHVkShaderModule> SHShaderModuleLibrary::GetShaderModule(std::string shaderName) const noexcept
//{
// if (stringToID.contains(shaderName))
// return shaderModules.at(stringToID.at(shaderName));
// else
// return {};
//}
vk::ShaderStageFlagBits SHShaderModuleLibrary::GetVkShaderFlag(SH_SHADER_TYPE type) noexcept
{
vk::ShaderStageFlagBits shaderType{};
switch (type)
{
case SH_SHADER_TYPE::VERTEX:
shaderType = vk::ShaderStageFlagBits::eVertex;
break;
case SH_SHADER_TYPE::FRAGMENT:
shaderType = vk::ShaderStageFlagBits::eFragment;
break;
case SH_SHADER_TYPE::COMPUTE:
shaderType = vk::ShaderStageFlagBits::eCompute;
break;
default:
shaderType = vk::ShaderStageFlagBits::eVertex;
break;
}
return shaderType;
}
Handle<SHVkShaderModule> SHShaderModuleLibrary::GetBuiltInShaderModule(std::string shaderName) const noexcept
{
if (builtInShaderModules.contains(shaderName))
return builtInShaderModules.at(shaderName);
else
return {};
}
void SHShaderModuleLibrary::ImportAllShaderSource(Handle<SHVkLogicalDevice>& logicalDeviceHdl) noexcept
{
uint32_t idCounter{ 0 };
auto const data = SHAssetManager::GetAllDataOfType(AssetType::SHADER);
for (auto const& dataPtr : data)
{
auto const shader = dynamic_cast<SHShaderAsset const*>(dataPtr);
Handle<SHVkShaderModule> newShaderModule =
logicalDeviceHdl->CreateShaderModule(shader->spirvBinary, "main", GetVkShaderFlag(shader->shaderType), shader->name);
shaderModules.emplace(idCounter++, newShaderModule);
}
auto const builtIn = SHAssetManager::GetAllDataOfType(AssetType::SHADER_BUILT_IN);
for (auto const& dataPtr : builtIn)
{
auto const shader = dynamic_cast<SHShaderAsset const*>(dataPtr);
Handle<SHVkShaderModule> newShaderModule =
logicalDeviceHdl->CreateShaderModule(shader->spirvBinary, "main", GetVkShaderFlag(shader->shaderType), shader->name);
builtInShaderModules.emplace(shader->name, newShaderModule);
}
}
void SHShaderModuleLibrary::ReflectAllShaderModules() noexcept
{
for (auto& module : shaderModules)
{
module.second->Reflect();
}
for (auto& module : builtInShaderModules)
{
module.second->Reflect();
}
}
}

View File

@ -1,44 +0,0 @@
#ifndef SH_SHADER_MODULE_LIBRARY_H
#define SH_SHADER_MODULE_LIBRARY_H
#include "Graphics/Shaders/SHVkShaderModule.h"
#include "Assets/Asset Types/SHShaderAsset.h"
namespace SHADE
{
class SHVkLogicalDevice;
/*
* The purpose of this shader module library is to be separate from the source library. The source library contains
* pure shader binary data that contains no vulkan related objects. Every time we load on unload a scene/level,
* this class and the source library class is cleared of its modules and recreated.
*/
class SHShaderModuleLibrary
{
private:
/*-----------------------------------------------------------------------*/
/* PRIVATE MEMBER VARIABLES */
/*-----------------------------------------------------------------------*/
//! Stored shader modules
std::unordered_map<uint32_t, Handle<SHVkShaderModule>> shaderModules;
std::unordered_map<std::string, Handle<SHVkShaderModule>> builtInShaderModules;
inline vk::ShaderStageFlagBits GetVkShaderFlag(SH_SHADER_TYPE type) noexcept;
public:
/*-----------------------------------------------------------------------*/
/* PUBLIC MEMBER FUNCTIONS */
/*-----------------------------------------------------------------------*/
//void ImportFromSourceLibrary(Handle<SHVkLogicalDevice>& logicalDeviceHdl, SHShaderSourceLibrary const& sourceLib) noexcept;
/*-----------------------------------------------------------------------*/
/* SETTERS AND GETTERS */
/*-----------------------------------------------------------------------*/
Handle<SHVkShaderModule> GetBuiltInShaderModule(std::string shaderName) const noexcept;
void ImportAllShaderSource(Handle<SHVkLogicalDevice>& logicalDeviceHdl) noexcept;
void ReflectAllShaderModules() noexcept;
};
}
#endif

View File

@ -129,6 +129,21 @@ namespace SHADE
/* Getter Functions */
/*-----------------------------------------------------------------------------*/
Handle<SHVkDescriptorSetGroup> GetTextureDescriptorSetGroup() const noexcept { return texDescriptors; }
/***************************************************************************/
/*!
*
\brief
Retrieves the texture handle at the specified texture index.
\param textureId
Index of the texture to look for.
\returns
Handle to the texture
*/
/***************************************************************************/
Handle<SHTexture> GetTextureHandle(SHTexture::Index textureId) const { return texOrder[textureId]; };
private:
/*-----------------------------------------------------------------------------*/

View File

@ -2,8 +2,10 @@
#define SH_PIPELINE_LAYOUT_PARAMS_H
#include "Graphics/SHVulkanIncludes.h"
#include "Graphics/SHVulkanDefines.h"
#include "Resource/SHHandle.h"
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
#include <unordered_set>
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 it for allocating descriptor sets.
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

View File

@ -47,12 +47,13 @@ namespace SHADE
/*-----------------------------------------------------------------------*/
/* CTORS AND DTORS */
/*-----------------------------------------------------------------------*/
//! For constructing a graphics pipeline
SHVkPipeline (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl,
Handle<SHVkPipelineLayout> const& inPipelineLayout,
SHVkPipelineState const* const state,
Handle<SHVkRenderpass> const& renderpassHdl,
Handle<SHSubpass> subpass) noexcept;
//! For constructing a compute pipeline
SHVkPipeline(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl,
Handle<SHVkPipelineLayout> const& inPipelineLayout) noexcept;

View File

@ -165,6 +165,28 @@ namespace SHADE
newBinding.Stage = shaderModule->GetShaderStageFlagBits();
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
// 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
@ -300,6 +322,7 @@ namespace SHADE
, vkDescriptorSetLayoutsAllocate{}
, descriptorSetLayoutsPipeline{}
, vkDescriptorSetLayoutsPipeline{}
, dynamicBufferBindings{std::move (pipelineLayoutParams.dynamicBufferBindings)}
{
for (auto& mod : shaderModules)
{

View File

@ -29,6 +29,9 @@ namespace SHADE
//! Push constant interface
SHPushConstantInterface pushConstantInterface;
//! See SHPipelineLayoutParams for details
std::unordered_set<BindingAndSetHash> dynamicBufferBindings;
//! Push constant ranges
std::vector<vk::PushConstantRange> vkPcRanges;

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