Merge branch 'main' into AudioScripting
This commit is contained in:
commit
59ef28baf1
|
@ -1,4 +1,4 @@
|
||||||
Start in Fullscreen: false
|
Start in Fullscreen: false
|
||||||
Starting Scene ID: 97158628
|
Starting Scene ID: 87244611
|
||||||
Window Size: {x: 1920, y: 1080}
|
Window Size: {x: 1920, y: 1080}
|
||||||
Window Title: SHADE Engine
|
Window Title: SHADE Engine
|
|
@ -1 +1,96 @@
|
||||||
|
7
|
||||||
|
Controller Look Horizontal
|
||||||
0
|
0
|
||||||
|
0
|
||||||
|
5
|
||||||
|
0.2
|
||||||
|
5
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
18
|
||||||
|
0
|
||||||
|
Controller Look Vertical
|
||||||
|
0
|
||||||
|
0
|
||||||
|
5
|
||||||
|
0.2
|
||||||
|
5
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
19
|
||||||
|
0
|
||||||
|
Horizontal
|
||||||
|
0
|
||||||
|
0
|
||||||
|
5
|
||||||
|
0.2
|
||||||
|
5
|
||||||
|
1
|
||||||
|
2
|
||||||
|
39
|
||||||
|
68
|
||||||
|
2
|
||||||
|
37
|
||||||
|
65
|
||||||
|
2
|
||||||
|
3
|
||||||
|
16
|
||||||
|
1
|
||||||
|
2
|
||||||
|
Jump
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1000
|
||||||
|
0.2
|
||||||
|
1000
|
||||||
|
0
|
||||||
|
1
|
||||||
|
32
|
||||||
|
0
|
||||||
|
1
|
||||||
|
10
|
||||||
|
0
|
||||||
|
Mouse Look Horizontal
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
0.2
|
||||||
|
1
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
Mouse Look Vertical
|
||||||
|
2
|
||||||
|
0
|
||||||
|
1
|
||||||
|
0.2
|
||||||
|
1
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
Vertical
|
||||||
|
0
|
||||||
|
0
|
||||||
|
5
|
||||||
|
0.2
|
||||||
|
5
|
||||||
|
1
|
||||||
|
2
|
||||||
|
38
|
||||||
|
87
|
||||||
|
2
|
||||||
|
40
|
||||||
|
83
|
||||||
|
2
|
||||||
|
0
|
||||||
|
17
|
||||||
|
1
|
||||||
|
1
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Start Maximized: true
|
||||||
|
Working Scene ID: 97161771
|
||||||
|
Window Size: {x: 1920, y: 1080}
|
||||||
|
Style: 0
|
|
@ -7,6 +7,7 @@
|
||||||
Translate: {x: 0, y: 0.304069757, z: 1.73034382}
|
Translate: {x: 0, y: 0.304069757, z: 1.73034382}
|
||||||
Rotate: {x: 0, y: 0, z: 0}
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
Scale: {x: 1, y: 1, z: 1}
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
IsActive: true
|
||||||
Camera Component:
|
Camera Component:
|
||||||
Position: {x: 0, y: 0.304069757, z: 1.73034382}
|
Position: {x: 0, y: 0.304069757, z: 1.73034382}
|
||||||
Pitch: 0
|
Pitch: 0
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
Near: 0.00999999978
|
Near: 0.00999999978
|
||||||
Far: 10000
|
Far: 10000
|
||||||
Perspective: true
|
Perspective: true
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 1
|
- EID: 1
|
||||||
Name: Raccoon
|
Name: Raccoon
|
||||||
|
@ -24,12 +26,14 @@
|
||||||
NumberOfChildren: 1
|
NumberOfChildren: 1
|
||||||
Components:
|
Components:
|
||||||
Transform Component:
|
Transform Component:
|
||||||
Translate: {x: 0, y: 0, z: 0}
|
Translate: {x: -1.86388135, y: 0.0544953719, z: 0}
|
||||||
Rotate: {x: 0, y: 0, z: 0}
|
Rotate: {x: -0, y: 0, z: -0}
|
||||||
Scale: {x: 1, y: 1, z: 1}
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
IsActive: true
|
||||||
Renderable Component:
|
Renderable Component:
|
||||||
Mesh: 149697411
|
Mesh: 149697411
|
||||||
Material: 126974645
|
Material: 126974645
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 3
|
- EID: 3
|
||||||
Name: Bag
|
Name: Bag
|
||||||
|
@ -40,9 +44,11 @@
|
||||||
Translate: {x: 0.006237939, y: -0.000393368304, z: 0}
|
Translate: {x: 0.006237939, y: -0.000393368304, z: 0}
|
||||||
Rotate: {x: -0, y: 2.79945588, z: 0}
|
Rotate: {x: -0, y: 2.79945588, z: 0}
|
||||||
Scale: {x: 1.0000881, y: 1, z: 1.0000881}
|
Scale: {x: 1.0000881, y: 1, z: 1.0000881}
|
||||||
|
IsActive: true
|
||||||
Renderable Component:
|
Renderable Component:
|
||||||
Mesh: 144838771
|
Mesh: 144838771
|
||||||
Material: 123745521
|
Material: 123745521
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 2
|
- EID: 2
|
||||||
Name: DirectionalLight
|
Name: DirectionalLight
|
||||||
|
@ -50,12 +56,13 @@
|
||||||
NumberOfChildren: 0
|
NumberOfChildren: 0
|
||||||
Components:
|
Components:
|
||||||
Light Component:
|
Light Component:
|
||||||
Position: {x: 0, y: 0, z: 0}
|
Position: {x: 3, y: 4.5, z: 7}
|
||||||
Type: Directional
|
Type: Directional
|
||||||
Direction: {x: 0, y: 0, z: 1}
|
Direction: {x: -0.298000008, y: 0.522498012, z: 0.798600018}
|
||||||
Color: {x: 1, y: 1, z: 1, w: 1}
|
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
Layer: 4294967295
|
Layer: 4294967295
|
||||||
Strength: 0
|
Strength: 0
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
- EID: 4
|
- EID: 4
|
||||||
Name: AmbientLight
|
Name: AmbientLight
|
||||||
|
@ -69,4 +76,20 @@
|
||||||
Color: {x: 1, y: 1, z: 1, w: 1}
|
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||||
Layer: 4294967295
|
Layer: 4294967295
|
||||||
Strength: 0.600000024
|
Strength: 0.600000024
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
|
- EID: 5
|
||||||
|
Name: Floor
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: 0.0810000002, z: 0}
|
||||||
|
Rotate: {x: -1.57079637, y: 0, z: 0}
|
||||||
|
Scale: {x: 50, y: 50, z: 50}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 141771688
|
||||||
|
Material: 124370424
|
||||||
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
|
@ -1,7 +1,7 @@
|
||||||
- EID: 0
|
- EID: 0
|
||||||
Name: Canvas
|
Name: Canvas
|
||||||
IsActive: true
|
IsActive: true
|
||||||
NumberOfChildren: 1
|
NumberOfChildren: 2
|
||||||
Components:
|
Components:
|
||||||
Canvas Component:
|
Canvas Component:
|
||||||
Canvas Width: 10
|
Canvas Width: 10
|
||||||
|
@ -28,6 +28,26 @@
|
||||||
Clicked Texture: 0
|
Clicked Texture: 0
|
||||||
IsActive: true
|
IsActive: true
|
||||||
Scripts: ~
|
Scripts: ~
|
||||||
|
- EID: 5
|
||||||
|
Name: Default
|
||||||
|
IsActive: true
|
||||||
|
NumberOfChildren: 0
|
||||||
|
Components:
|
||||||
|
Transform Component:
|
||||||
|
Translate: {x: 0, y: -3.9000001, z: 0}
|
||||||
|
Rotate: {x: 0, y: 0, z: 0}
|
||||||
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
|
IsActive: true
|
||||||
|
Renderable Component:
|
||||||
|
Mesh: 141771688
|
||||||
|
Material: 129340704
|
||||||
|
IsActive: true
|
||||||
|
Toggle Button Component:
|
||||||
|
Non Toggled Texture: 0
|
||||||
|
Toggled Texture: 0
|
||||||
|
Value: true
|
||||||
|
IsActive: true
|
||||||
|
Scripts: ~
|
||||||
- EID: 1
|
- EID: 1
|
||||||
Name: Camera
|
Name: Camera
|
||||||
IsActive: true
|
IsActive: true
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
Name: UI_Test
|
Name: UI_Test
|
||||||
ID: 87707373
|
ID: 87244611
|
||||||
Type: 5
|
Type: 5
|
||||||
|
|
|
@ -6,6 +6,8 @@ struct DirectionalLightStruct
|
||||||
uint isActive;
|
uint isActive;
|
||||||
uint cullingMask;
|
uint cullingMask;
|
||||||
vec4 diffuseColor;
|
vec4 diffuseColor;
|
||||||
|
mat4 pvMatrix;
|
||||||
|
uint shadowData;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AmbientLightStruct
|
struct AmbientLightStruct
|
||||||
|
@ -22,7 +24,10 @@ layout(set = 3, binding = 1, rgba32f) uniform image2D normals;
|
||||||
layout(set = 3, binding = 2, rgba8) uniform image2D albedo;
|
layout(set = 3, binding = 2, rgba8) uniform image2D albedo;
|
||||||
layout(set = 3, binding = 3, r32ui) uniform uimage2D lightLayerData;
|
layout(set = 3, binding = 3, r32ui) uniform uimage2D lightLayerData;
|
||||||
layout(set = 3, binding = 4, r8) uniform image2D ssaoBlurredImage;
|
layout(set = 3, binding = 4, r8) uniform image2D ssaoBlurredImage;
|
||||||
layout(set = 3, binding = 5, rgba8) uniform image2D targetImage;
|
layout(set = 3, binding = 5, rgba8) uniform image2D positionWorldSpace;
|
||||||
|
layout(set = 3, binding = 6, rgba8) uniform image2D targetImage;
|
||||||
|
|
||||||
|
layout (set = 4, binding = 0) uniform sampler2D shadowMaps[]; // for textures (global)
|
||||||
|
|
||||||
layout(set = 1, binding = 0) uniform LightCounts
|
layout(set = 1, binding = 0) uniform LightCounts
|
||||||
{
|
{
|
||||||
|
@ -43,6 +48,25 @@ layout(std430, set = 1, binding = 4) buffer AmbientLightData
|
||||||
AmbientLightStruct aLightData[];
|
AmbientLightStruct aLightData[];
|
||||||
} AmbLightData;
|
} AmbLightData;
|
||||||
|
|
||||||
|
float CalcShadowValue (sampler2D shadowMap, vec4 worldSpaceFragPos, mat4 lightPV)
|
||||||
|
{
|
||||||
|
vec4 fragPosLightPOV = lightPV * worldSpaceFragPos;
|
||||||
|
vec3 converted = (fragPosLightPOV.xyz / fragPosLightPOV.w) * vec3(0.5f) + vec3(0.5f);
|
||||||
|
|
||||||
|
float sampledDepth = texture(shadowMap, converted.xy).r;
|
||||||
|
|
||||||
|
if (converted.x < 0.0f || converted.x > 1.0f || converted.y < 0.0f || converted.y > 1.0f)
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
if (fragPosLightPOV.z > sampledDepth && fragPosLightPOV.w > 0.0f)
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 1.0f;
|
||||||
|
// return step (fragPosLightPOV.z, );
|
||||||
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// convenient variables
|
// convenient variables
|
||||||
|
@ -52,6 +76,9 @@ void main()
|
||||||
vec3 pixelDiffuse = imageLoad (albedo, globalThread).rgb;
|
vec3 pixelDiffuse = imageLoad (albedo, globalThread).rgb;
|
||||||
|
|
||||||
// Get position of fragment in world space
|
// Get position of fragment in world space
|
||||||
|
vec4 positionWorld = vec4 (imageLoad (positionWorldSpace, globalThread).rgb, 1.0f);
|
||||||
|
|
||||||
|
// Get position of fragment in view spacee
|
||||||
vec3 positionView = imageLoad (positions, globalThread).rgb;
|
vec3 positionView = imageLoad (positions, globalThread).rgb;
|
||||||
|
|
||||||
// normal of fragment
|
// normal of fragment
|
||||||
|
@ -62,6 +89,18 @@ void main()
|
||||||
|
|
||||||
vec3 fragColor = vec3 (0.0f);
|
vec3 fragColor = vec3 (0.0f);
|
||||||
|
|
||||||
|
vec4 shadowMapColor = vec4 (1.0f);
|
||||||
|
|
||||||
|
for (int i = 0; i < lightCounts.ambientLights; ++i)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < lightCounts.directionalLights; ++i)
|
for (int i = 0; i < lightCounts.directionalLights; ++i)
|
||||||
{
|
{
|
||||||
if ((lightLayer & DirLightData.dLightData[i].cullingMask) != 0)
|
if ((lightLayer & DirLightData.dLightData[i].cullingMask) != 0)
|
||||||
|
@ -74,16 +113,13 @@ void main()
|
||||||
|
|
||||||
// Calculate the fragment color
|
// Calculate the fragment color
|
||||||
fragColor += DirLightData.dLightData[i].diffuseColor.rgb * diffuseStrength.rrr * pixelDiffuse;
|
fragColor += DirLightData.dLightData[i].diffuseColor.rgb * diffuseStrength.rrr * pixelDiffuse;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < lightCounts.ambientLights; ++i)
|
// If the shadow map is enabled (test the bit)
|
||||||
{
|
if ((DirLightData.dLightData[i].shadowData & uint(1)) == 1)
|
||||||
if ((lightLayer & AmbLightData.aLightData[i].cullingMask) != 0)
|
{
|
||||||
{
|
// calculate shadow map here
|
||||||
// Just do some add
|
fragColor *= CalcShadowValue (shadowMaps[0], positionWorld, DirLightData.dLightData[i].pvMatrix).xxx;
|
||||||
//fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (0.5f);
|
}
|
||||||
fragColor += pixelDiffuse.rgb * AmbLightData.aLightData[i].ambientColor.rgb * vec3 (AmbLightData.aLightData[i].strength);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +128,12 @@ void main()
|
||||||
|
|
||||||
// store result into result image
|
// store result into result image
|
||||||
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor.rgb, 1.0f));
|
imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(fragColor.rgb, 1.0f));
|
||||||
//imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), vec4(ssaoVal.rrr, 1.0f));
|
|
||||||
|
// vec2 normTexCoords = vec2 (gl_GlobalInvocationID.xy) / vec2 (1024.0f);
|
||||||
|
// vec4 shadowMapVal = texture(shadowMaps[0], normTexCoords);
|
||||||
|
// if (normTexCoords.x > 1.0f || normTexCoords.y > 1.0f)
|
||||||
|
// shadowMapVal = vec4(0.0f);
|
||||||
|
|
||||||
|
// imageStore(targetImage, ivec2(gl_GlobalInvocationID.xy), shadowMapVal.xxxx);
|
||||||
|
|
||||||
}
|
}
|
Binary file not shown.
|
@ -0,0 +1,22 @@
|
||||||
|
#version 450
|
||||||
|
#extension GL_KHR_vulkan_glsl : enable
|
||||||
|
|
||||||
|
//#include "ShaderDescriptorDefinitions.glsl"
|
||||||
|
|
||||||
|
|
||||||
|
layout(location = 0) in vec3 aVertexPos;
|
||||||
|
layout(location = 4) in mat4 worldTransform;
|
||||||
|
|
||||||
|
layout(set = 1, binding = 0) uniform CameraData
|
||||||
|
{
|
||||||
|
vec4 position;
|
||||||
|
mat4 vpMat;
|
||||||
|
mat4 viewMat;
|
||||||
|
mat4 projMat;
|
||||||
|
} cameraData;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// clip space for rendering
|
||||||
|
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
|
||||||
|
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Name: ShadowMap_VS
|
||||||
|
ID: 44646107
|
||||||
|
Type: 2
|
|
@ -16,11 +16,12 @@ layout(location = 0) in struct
|
||||||
vec4 vertPos; // location 0
|
vec4 vertPos; // location 0
|
||||||
vec2 uv; // location = 1
|
vec2 uv; // location = 1
|
||||||
vec4 normal; // location = 2
|
vec4 normal; // location = 2
|
||||||
|
vec4 worldPos; // location = 3
|
||||||
|
|
||||||
} In;
|
} In;
|
||||||
|
|
||||||
// material stuff
|
// material stuff
|
||||||
layout(location = 3) flat in struct
|
layout(location = 4) flat in struct
|
||||||
{
|
{
|
||||||
int materialIndex;
|
int materialIndex;
|
||||||
uint eid;
|
uint eid;
|
||||||
|
@ -38,12 +39,14 @@ layout(location = 1) out uint outEntityID;
|
||||||
layout(location = 2) out uint lightLayerIndices;
|
layout(location = 2) out uint lightLayerIndices;
|
||||||
layout(location = 3) out vec4 normals;
|
layout(location = 3) out vec4 normals;
|
||||||
layout(location = 4) out vec4 albedo;
|
layout(location = 4) out vec4 albedo;
|
||||||
|
layout(location = 5) out vec4 worldSpacePosition;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
position = In.vertPos;
|
position = In.vertPos;
|
||||||
normals = In.normal;
|
normals = In.normal;
|
||||||
albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) * MatProp.data[In2.materialIndex].color;
|
albedo = texture(textures[nonuniformEXT(MatProp.data[In2.materialIndex].textureIndex)], In.uv) * MatProp.data[In2.materialIndex].color;
|
||||||
|
worldSpacePosition = In.worldPos;
|
||||||
|
|
||||||
outEntityID = In2.eid;
|
outEntityID = In2.eid;
|
||||||
lightLayerIndices = In2.lightLayerIndex;
|
lightLayerIndices = In2.lightLayerIndex;
|
||||||
|
|
Binary file not shown.
|
@ -17,11 +17,12 @@ layout(location = 0) out struct
|
||||||
vec4 vertPos; // location 0
|
vec4 vertPos; // location 0
|
||||||
vec2 uv; // location = 1
|
vec2 uv; // location = 1
|
||||||
vec4 normal; // location = 2
|
vec4 normal; // location = 2
|
||||||
|
vec4 worldPos; // location = 3
|
||||||
|
|
||||||
} Out;
|
} Out;
|
||||||
|
|
||||||
// material stuff
|
// material stuff
|
||||||
layout(location = 3) out struct
|
layout(location = 4) out struct
|
||||||
{
|
{
|
||||||
int materialIndex;
|
int materialIndex;
|
||||||
uint eid;
|
uint eid;
|
||||||
|
@ -49,6 +50,8 @@ void main()
|
||||||
// gBuffer position will be in view space
|
// gBuffer position will be in view space
|
||||||
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
|
||||||
|
|
||||||
|
Out.worldPos = worldTransform * vec4 (aVertexPos, 1.0f);
|
||||||
|
|
||||||
// uvs for texturing in fragment shader
|
// uvs for texturing in fragment shader
|
||||||
Out.uv = aUV;
|
Out.uv = aUV;
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -270,8 +270,12 @@ namespace SHADE
|
||||||
camera.viewMatrix(1, 3) = -UP.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.viewMatrix(2, 3) = -view.Dot(camera.position + camera.offset);
|
||||||
|
|
||||||
|
//SHVec3 target{ 0.0f,0.0f,-1.0f };
|
||||||
|
//target = SHVec3::RotateX(target, SHMath::DegreesToRadians(camera.pitch));
|
||||||
|
//target = SHVec3::RotateY(target, SHMath::DegreesToRadians(camera.yaw));
|
||||||
|
//target += camera.position;
|
||||||
|
|
||||||
|
//camera.viewMatrix = SHMatrix::Transpose(SHMatrix::LookAtLH(camera.position, target, SHVec3(0.0f, -1.0f, 0.0f)));
|
||||||
|
|
||||||
camera.dirtyView = false;
|
camera.dirtyView = false;
|
||||||
}
|
}
|
||||||
|
@ -309,7 +313,9 @@ namespace SHADE
|
||||||
camera.orthoProjMatrix(2, 3) = -n / (f-n);
|
camera.orthoProjMatrix(2, 3) = -n / (f-n);
|
||||||
camera.orthoProjMatrix(3, 3) = 1.0f;
|
camera.orthoProjMatrix(3, 3) = 1.0f;
|
||||||
|
|
||||||
//camera.orthoProjMatrix = SHMatrix::OrthographicRH(camera.GetWidth(), camera.GetHeight(), camera.GetNear(), camera.GetFar());
|
//camera.perspProjMatrix = SHMatrix::OrthographicLH(9.0f, 9.0f, 0.1f, 20.0f);
|
||||||
|
camera.orthoProjMatrix = SHMatrix::OrthographicRH(camera.GetWidth(), camera.GetHeight(), camera.GetNear(), camera.GetFar());
|
||||||
|
//camera.perspProjMatrix = SHMatrix::OrthographicLH(5.0f, 5.0f, 0.1f, 20.0f);
|
||||||
//camera.projMatrix.Transpose();
|
//camera.projMatrix.Transpose();
|
||||||
|
|
||||||
camera.dirtyProj = false;
|
camera.dirtyProj = false;
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#pragma once
|
||||||
|
#include "Camera/SHCameraComponent.h"
|
||||||
|
#include "Camera/SHCameraArmComponent.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
#include "Physics/Interface/SHRigidBodyComponent.h"
|
||||||
|
#include "UI/SHCanvasComponent.h"
|
||||||
|
#include "UI/SHButtonComponent.h"
|
||||||
|
#include "UI/SHUIComponent.h"
|
||||||
|
#include "UI/SHToggleButtonComponent.h"
|
||||||
|
#include "UI/SHSliderComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
#include "Physics/Interface/SHColliderComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
|
|
@ -239,10 +239,7 @@ namespace SHADE
|
||||||
case AssetType::TEXTURE: break;
|
case AssetType::TEXTURE: break;
|
||||||
case AssetType::MESH: break;
|
case AssetType::MESH: break;
|
||||||
case AssetType::SCENE:
|
case AssetType::SCENE:
|
||||||
if(auto editor = SHSystemManager::GetSystem<SHEditor>())
|
|
||||||
{
|
|
||||||
editor->LoadScene(asset->id);
|
editor->LoadScene(asset->id);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case AssetType::PREFAB: break;
|
case AssetType::PREFAB: break;
|
||||||
case AssetType::MATERIAL:
|
case AssetType::MATERIAL:
|
||||||
|
@ -262,6 +259,13 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("AssetID: %zu | Path: %s", asset->id, asset->path.c_str());
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: Combine Draw asset and Draw Folder recursive drawing
|
//TODO: Combine Draw asset and Draw Folder recursive drawing
|
||||||
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
const ImColor treeLineColor = ImGui::GetColorU32(ImGuiCol_CheckMark);
|
||||||
const float horizontalOffset = 0.0f;
|
const float horizontalOffset = 0.0f;
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHEditorPopups.h"
|
||||||
|
#include "Editor/SHEditor.h"
|
||||||
|
#include "misc/cpp/imgui_stdlib.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
void SHSceneSavePrompt::Draw()
|
||||||
|
{
|
||||||
|
if(Begin())
|
||||||
|
{
|
||||||
|
static std::string newSceneName{};
|
||||||
|
ImGui::Text("Enter new scene name");
|
||||||
|
ImGui::InputText("##name", &newSceneName);
|
||||||
|
ImGui::BeginDisabled(newSceneName.empty());
|
||||||
|
if (ImGui::Button("Save"))
|
||||||
|
{
|
||||||
|
editor->SaveScene(newSceneName);
|
||||||
|
newSceneName.clear();
|
||||||
|
isOpen = false;
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Cancel"))
|
||||||
|
{
|
||||||
|
isOpen = false;
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "Editor/EditorWindow/SHPopUpWindow.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHSceneSavePrompt : public SHPopUpWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHSceneSavePrompt():SHPopUpWindow("Save Scene As", true, 0, 0){}
|
||||||
|
void Draw() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -3,6 +3,11 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| Library Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| SHADE Includes ||
|
//|| SHADE Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
@ -16,14 +21,11 @@
|
||||||
#include "Tools/SHException.h"
|
#include "Tools/SHException.h"
|
||||||
#include "Editor/IconsMaterialDesign.h"
|
#include "Editor/IconsMaterialDesign.h"
|
||||||
#include "SHHierarchyPanelCommands.h"
|
#include "SHHierarchyPanelCommands.h"
|
||||||
|
#include "Common/SHAllComponents.h"
|
||||||
//#==============================================================#
|
|
||||||
//|| Library Includes ||
|
|
||||||
//#==============================================================#
|
|
||||||
#include <imgui.h>
|
|
||||||
|
|
||||||
#include "Serialization/SHSerialization.h"
|
#include "Serialization/SHSerialization.h"
|
||||||
#include "Tools/Utilities/SHClipboardUtilities.h"
|
#include "Tools/Utilities/SHClipboardUtilities.h"
|
||||||
|
#include "Tools/Utilities/SHStringUtilities.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -80,7 +82,6 @@ namespace SHADE
|
||||||
|
|
||||||
if (ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
if (ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
|
||||||
{
|
{
|
||||||
if (auto editor = SHSystemManager::GetSystem<SHEditor>())
|
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
}
|
}
|
||||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
|
||||||
|
@ -99,7 +100,6 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyReleased(ImGuiKey_V))
|
if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyReleased(ImGuiKey_V))
|
||||||
{
|
{
|
||||||
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
if (editor->selectedEntities.size() == 1)
|
if (editor->selectedEntities.size() == 1)
|
||||||
{
|
{
|
||||||
PasteEntities(editor->selectedEntities.back());
|
PasteEntities(editor->selectedEntities.back());
|
||||||
|
@ -141,16 +141,18 @@ namespace SHADE
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Private Member Functions ||
|
//|| Private Member Functions ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
void SHHierarchyPanel::DrawMenuBar() const noexcept
|
void SHHierarchyPanel::DrawMenuBar() noexcept
|
||||||
{
|
{
|
||||||
if (ImGui::BeginMenuBar())
|
if (ImGui::BeginMenuBar())
|
||||||
{
|
{
|
||||||
auto size = ImGui::GetWindowSize();
|
auto size = ImGui::GetWindowSize();
|
||||||
auto g = ImGui::GetCurrentContext();
|
auto g = ImGui::GetCurrentContext();
|
||||||
|
|
||||||
|
DrawHierarchyPanelFilter();
|
||||||
|
|
||||||
ImGui::SetCursorPosX(size.x - g->Style.FramePadding.x * 15.0f);
|
ImGui::SetCursorPosX(size.x - g->Style.FramePadding.x * 15.0f);
|
||||||
if (ImGui::SmallButton(ICON_MD_CLEAR_ALL))
|
if (ImGui::SmallButton(ICON_MD_CLEAR_ALL))
|
||||||
{
|
{
|
||||||
auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
|
@ -173,6 +175,56 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHHierarchyPanel::DrawHierarchyPanelFilter() noexcept
|
||||||
|
{
|
||||||
|
if(ImGui::InputTextWithHint("##hierarchyPanelFilter", "Filter", &filter))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if(ImGui::Button("x"))
|
||||||
|
{
|
||||||
|
filter.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHHierarchyPanel::EntityFilterCheck(SHSceneNode* entityNode) noexcept
|
||||||
|
{
|
||||||
|
if(!entityNode || filter.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
EntityID const eid = entityNode->GetEntityID();
|
||||||
|
SHEntity* entity = SHEntityManager::GetEntityByID(eid);
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
result |= SHStringUtilities::StringFindInsensitive(entity->name, filter) != std::string::npos;
|
||||||
|
|
||||||
|
if(SHStringUtilities::StringFindInsensitive(rttr::type::get<SHTransformComponent>().get_name().data(), filter) != std::string::npos)
|
||||||
|
{
|
||||||
|
result |= SHComponentManager::HasComponent<SHTransformComponent>(eid);
|
||||||
|
}
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHColliderComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHRigidBodyComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHCameraComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHCameraArmComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHRenderable>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHLightComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHTextRenderableComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHUIComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHButtonComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
//result |= SHStringUtilities::StringFindInsensitive(rttr::type::get<SHCanvasComponent>().get_name().data(), filter) != std::string::npos;
|
||||||
|
|
||||||
|
//std::vector<SHSceneNode*> const& children = entityNode->GetChildren();
|
||||||
|
|
||||||
|
//for (auto const& child : children)
|
||||||
|
//{
|
||||||
|
// result |= EntityFilterCheck(child);
|
||||||
|
//}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* const currentNode)
|
ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* const currentNode)
|
||||||
{
|
{
|
||||||
if (currentNode == nullptr)
|
if (currentNode == nullptr)
|
||||||
|
@ -189,21 +241,39 @@ namespace SHADE
|
||||||
scrollTo = MAX_EID;
|
scrollTo = MAX_EID;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto editor = SHSystemManager::GetSystem<SHEditor>();
|
auto* entity = SHEntityManager::GetEntityByID(eid);
|
||||||
|
|
||||||
const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end());
|
const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end());
|
||||||
|
|
||||||
const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow);
|
bool highlighted = false;
|
||||||
|
//if(!filter.empty())
|
||||||
//bool highlighted = false;
|
|
||||||
//if(highlighted)
|
|
||||||
//{
|
//{
|
||||||
// ImGui::PushStyleColor(ImGuiCol_Text, highlightedColor);
|
// highlighted = EntityFilterCheck(currentNode);
|
||||||
|
// if (highlighted)
|
||||||
|
// {
|
||||||
|
// ImGui::PushStyleColor(ImGuiCol_Text, highlightedColor);
|
||||||
|
//
|
||||||
|
// ImGui::SetNextItemOpen(true);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
//
|
||||||
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID());
|
const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow);
|
||||||
|
|
||||||
|
|
||||||
//Draw Node
|
//Draw Node
|
||||||
bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast<void*>(entity), nodeFlags, "%u: %s", SHEntityManager::GetEntityIndex(eid), entity->name.c_str());
|
bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast<void*>(eid), nodeFlags, "%u: %s", SHEntityManager::GetEntityIndex(eid), entity->name.c_str());
|
||||||
|
|
||||||
|
if (highlighted)
|
||||||
|
{
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
|
||||||
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax());
|
||||||
|
|
||||||
//Check For Begin Drag
|
//Check For Begin Drag
|
||||||
|
@ -336,6 +406,7 @@ namespace SHADE
|
||||||
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 2);
|
drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 2);
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodeRect;
|
return nodeRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,7 +421,6 @@ namespace SHADE
|
||||||
|
|
||||||
std::vector<EntityID> entitiesToParent = CleanUpEIDList(entities);
|
std::vector<EntityID> entitiesToParent = CleanUpEIDList(entities);
|
||||||
|
|
||||||
//auto const editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
SHEntityParentCommand::EntityParentData entityParentData;
|
SHEntityParentCommand::EntityParentData entityParentData;
|
||||||
std::vector<EntityID> parentedEIDS;
|
std::vector<EntityID> parentedEIDS;
|
||||||
for (auto const& eid : entitiesToParent)
|
for (auto const& eid : entitiesToParent)
|
||||||
|
@ -371,7 +441,7 @@ namespace SHADE
|
||||||
void SHHierarchyPanel::SelectRangeOfEntities(EntityID beginEID, EntityID endEID)
|
void SHHierarchyPanel::SelectRangeOfEntities(EntityID beginEID, EntityID endEID)
|
||||||
{
|
{
|
||||||
bool startSelecting = false; bool endSelecting = false;
|
bool startSelecting = false; bool endSelecting = false;
|
||||||
auto const editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
sceneGraph.Traverse([&](SHSceneNode* nodePtr)
|
sceneGraph.Traverse([&](SHSceneNode* nodePtr)
|
||||||
|
@ -403,7 +473,6 @@ namespace SHADE
|
||||||
|
|
||||||
void SHHierarchyPanel::SelectAllEntities()
|
void SHHierarchyPanel::SelectAllEntities()
|
||||||
{
|
{
|
||||||
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
editor->selectedEntities.clear();
|
editor->selectedEntities.clear();
|
||||||
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph();
|
||||||
sceneGraph.Traverse([&](SHSceneNode* nodePtr)
|
sceneGraph.Traverse([&](SHSceneNode* nodePtr)
|
||||||
|
@ -415,7 +484,6 @@ namespace SHADE
|
||||||
|
|
||||||
void SHHierarchyPanel::CopySelectedEntities()
|
void SHHierarchyPanel::CopySelectedEntities()
|
||||||
{
|
{
|
||||||
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
std::vector<EntityID> entitiesToCopy = CleanUpEIDList(editor->selectedEntities);
|
std::vector<EntityID> entitiesToCopy = CleanUpEIDList(editor->selectedEntities);
|
||||||
SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(entitiesToCopy));
|
SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(entitiesToCopy));
|
||||||
}
|
}
|
||||||
|
@ -428,7 +496,6 @@ namespace SHADE
|
||||||
|
|
||||||
void SHHierarchyPanel::DeleteSelectedEntities()
|
void SHHierarchyPanel::DeleteSelectedEntities()
|
||||||
{
|
{
|
||||||
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
std::vector<EntityID> entitiesToDelete = CleanUpEIDList(editor->selectedEntities);
|
std::vector<EntityID> entitiesToDelete = CleanUpEIDList(editor->selectedEntities);
|
||||||
SHCommandManager::PerformCommand(std::make_shared<SHDeleteEntitiesCommand>(entitiesToDelete));
|
SHCommandManager::PerformCommand(std::make_shared<SHDeleteEntitiesCommand>(entitiesToDelete));
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "imgui_internal.h"
|
#include "imgui_internal.h"
|
||||||
#include "ECS_Base/SHECSMacros.h"
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
#include "Editor/EditorWindow/SHEditorWindow.h"
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
#include "ECS_Base/Entity/SHEntity.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
class SHSceneNode;
|
class SHSceneNode;
|
||||||
|
@ -24,7 +26,11 @@ namespace SHADE
|
||||||
void Exit() override;
|
void Exit() override;
|
||||||
void SetScrollTo(EntityID eid);
|
void SetScrollTo(EntityID eid);
|
||||||
private:
|
private:
|
||||||
void DrawMenuBar() const noexcept;
|
void DrawMenuBar() noexcept;
|
||||||
|
void DrawHierarchyPanelFilter() noexcept;
|
||||||
|
|
||||||
|
bool EntityFilterCheck(SHSceneNode* entityNode) noexcept;
|
||||||
|
|
||||||
ImRect RecursivelyDrawEntityNode(SHSceneNode* const);
|
ImRect RecursivelyDrawEntityNode(SHSceneNode* const);
|
||||||
void CreateChildEntity(EntityID parentEID) const noexcept;
|
void CreateChildEntity(EntityID parentEID) const noexcept;
|
||||||
void ParentSelectedEntities(EntityID parentEID, std::vector<EntityID> const& entities) noexcept;
|
void ParentSelectedEntities(EntityID parentEID, std::vector<EntityID> const& entities) noexcept;
|
||||||
|
|
|
@ -0,0 +1,546 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHInputBindingsPanel.h"
|
||||||
|
#include "Input/SHInputManager.h"
|
||||||
|
#include "Editor/SHEditorWidgets.hpp"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//Vectors containing data for elements for different bindings
|
||||||
|
static std::vector<std::string> bindingRenames;
|
||||||
|
|
||||||
|
//Flags to prevent unwanted editing of bindings
|
||||||
|
static size_t positiveKeyListeningFor;
|
||||||
|
static bool positiveKeyListening;
|
||||||
|
|
||||||
|
static size_t negativeKeyListeningFor;
|
||||||
|
static bool negativeKeyListening;
|
||||||
|
|
||||||
|
static size_t positiveControllerListeningFor;
|
||||||
|
static bool positiveControllerListening;
|
||||||
|
|
||||||
|
static size_t negativeControllerListeningFor;
|
||||||
|
static bool negativeControllerListening;
|
||||||
|
|
||||||
|
//Internal Helper function
|
||||||
|
void resizeVectors(size_t newSize)
|
||||||
|
{
|
||||||
|
bindingRenames.resize(newSize);
|
||||||
|
for (auto& s : bindingRenames)
|
||||||
|
s.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Internal Helper function
|
||||||
|
std::string labelConcat(char const* label, size_t entryNumber)
|
||||||
|
{
|
||||||
|
std::string concat = label;
|
||||||
|
concat += std::to_string(entryNumber);
|
||||||
|
return concat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHInputBindingsPanel::Init()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHInputBindingsPanel::Update()
|
||||||
|
{
|
||||||
|
if (SHEditorWindow::Begin())
|
||||||
|
{
|
||||||
|
//ImGui::ShowDemoWindow();
|
||||||
|
|
||||||
|
//Binding count
|
||||||
|
ImGui::Text("Binding Count: %d", SHInputManager::CountBindings());
|
||||||
|
|
||||||
|
//Binding file name
|
||||||
|
static std::string bindingFileName;
|
||||||
|
ImGui::InputText("Binding File Path", &bindingFileName);
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text(".SHConfig will be appeneded to file name");
|
||||||
|
ImGui::Text("If no name is provided, saves to or loads from \"Assets/Bindings.SHConfig\"");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Save bindings to...
|
||||||
|
if (ImGui::Button("Save Bindings"))
|
||||||
|
{
|
||||||
|
if (bindingFileName.empty())
|
||||||
|
{
|
||||||
|
SHInputManager::SaveBindings();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string filePath = std::string(ASSET_ROOT);
|
||||||
|
filePath += "/";
|
||||||
|
filePath += bindingFileName;
|
||||||
|
filePath += ".SHConfig";
|
||||||
|
SHInputManager::SaveBindings(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Load bindings from...
|
||||||
|
if (ImGui::Button("Load Bindings"))
|
||||||
|
{
|
||||||
|
if (bindingFileName.empty())
|
||||||
|
{
|
||||||
|
SHInputManager::LoadBindings();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string filePath = std::string(ASSET_ROOT);
|
||||||
|
filePath += "/";
|
||||||
|
filePath += bindingFileName;
|
||||||
|
filePath += ".SHConfig";
|
||||||
|
SHInputManager::LoadBindings(filePath);
|
||||||
|
}
|
||||||
|
resizeVectors(SHInputManager::CountBindings());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Button to add new binding
|
||||||
|
if (ImGui::Button("Add New Binding"))
|
||||||
|
{
|
||||||
|
std::string newBindingName = "Binding" + std::to_string(SHInputManager::CountBindings());
|
||||||
|
SHInputManager::AddBinding(newBindingName);
|
||||||
|
resizeVectors(SHInputManager::CountBindings());
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Add a new binding to the list");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ensure unique label for entries
|
||||||
|
size_t entryNumber = 0;
|
||||||
|
|
||||||
|
//Listing for each binding
|
||||||
|
for (auto& binding : SHInputManager::GetBindings())
|
||||||
|
{
|
||||||
|
if (ImGui::CollapsingHeader(binding.first.c_str()))
|
||||||
|
{
|
||||||
|
//Modifiable binding name
|
||||||
|
ImGui::Text("Binding Name: %s", binding.first.c_str());
|
||||||
|
ImGui::InputText(labelConcat("##bindingModifyName", entryNumber).c_str(), &bindingRenames[entryNumber]);
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button(labelConcat("Rename##bindingRename", entryNumber).c_str()))
|
||||||
|
{
|
||||||
|
SHInputManager::RenameBinding(binding.first, bindingRenames[entryNumber]);
|
||||||
|
bindingRenames[entryNumber].clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button(labelConcat("Delete Binding##", entryNumber).c_str()))
|
||||||
|
{
|
||||||
|
SHInputManager::RemoveBinding(binding.first);
|
||||||
|
resizeVectors(SHInputManager::CountBindings());
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Delete this binding from the list");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Binding value test
|
||||||
|
ImGui::BeginDisabled();
|
||||||
|
float val = SHInputManager::GetBindingAxis(binding.first);
|
||||||
|
ImGui::SliderFloat(labelConcat("Value##", entryNumber).c_str(), &val, -1.0f, 1.0f);
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Test the current value of the binding");
|
||||||
|
ImGui::Text("For mouse movement/wheel inputs, will be multiplied by Sensitivity, with 0 being neutral (no input detected)");
|
||||||
|
ImGui::Text("Between -1 and 1 for other inputs, with 0 still being neutral (no input detected)");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
ImGui::BeginDisabled();
|
||||||
|
float rawVal = SHInputManager::GetBindingAxisRaw(binding.first);
|
||||||
|
ImGui::SliderFloat(labelConcat("Raw Value##", entryNumber).c_str(), &rawVal, -1.0f, 1.0f);
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Test the current value of the binding");
|
||||||
|
ImGui::Text("Raw value means it will be fixed among -1, 0 and 1 for non-mouse movement/wheel inputs");
|
||||||
|
ImGui::Text("No difference between this and Value for mouse movement/wheel inputs");
|
||||||
|
ImGui::Text("But for other inputs, does not consider smoothing options such as gravity and sensitivity");
|
||||||
|
ImGui::Text("If both positive and negative input is detected, returns neutral 0");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Binding Type Combo Box
|
||||||
|
int bindingType = static_cast<int>(SHInputManager::GetBindingType(binding.first));
|
||||||
|
if (ImGui::Combo(labelConcat("Input Type##", entryNumber).c_str(), &bindingType, "Keyboard / Mouse Buttons / Controller\0Mouse Horizontal\0Mouse Vertical\0Mouse Scroll Wheel"))
|
||||||
|
SHInputManager::SetBindingType(binding.first, static_cast<SHInputManager::SH_BINDINGTYPE>(bindingType));
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Which of the four types the binding uses");
|
||||||
|
ImGui::Text("Keyboard / Mouse Buttons / Controller = Keys, mouse buttons and ALL controller inputs");
|
||||||
|
ImGui::Text("Mouse Horizontal = Horizontal movement of the mouse");
|
||||||
|
ImGui::Text("Mouse Vertical = Vertical movement of the mouse");
|
||||||
|
ImGui::Text("Mouse Scroll Wheel = The scroll wheel found at the middle of most mouses");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Inversion
|
||||||
|
bool bindingInvert = SHInputManager::GetBindingInverted(binding.first);
|
||||||
|
if (ImGui::Checkbox(labelConcat("Inverted##", entryNumber).c_str(), &bindingInvert))
|
||||||
|
SHInputManager::SetBindingInverted(binding.first, bindingInvert);
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("If inverted:");
|
||||||
|
ImGui::Text("Positive inputs mean negative value of the binding");
|
||||||
|
ImGui::Text("Negative inputs mean positive value of the binding");
|
||||||
|
ImGui::Text("Mouse moving up / right means negative value of the binding");
|
||||||
|
ImGui::Text("Scrolling the mouse wheel up means negative value of the binding");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Sensitivity
|
||||||
|
double bindingSensitivity = SHInputManager::GetBindingSensitivity(binding.first);
|
||||||
|
if (ImGui::InputDouble(labelConcat("Sensitivity##", entryNumber).c_str(), &bindingSensitivity))
|
||||||
|
SHInputManager::SetBindingSensitivity(binding.first, bindingSensitivity);
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Value multiplier for mouse movement and scrolling");
|
||||||
|
ImGui::Text("For other digital inputs, serves as a rate of how fast axis value goes to maximum positive/negative");
|
||||||
|
//ImGui::Text("For other analog inputs, serves as a multiplier, but axis value magnitude will still be capped at 1");
|
||||||
|
ImGui::Text("Irrelevant for other analog inputs");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Below this section is only for KB/M type bindings
|
||||||
|
//Not relevant for mouse movement and scrolling
|
||||||
|
if (SHInputManager::GetBindingType(binding.first) == SHInputManager::SH_BINDINGTYPE::KB_MB_CONTROLLER)
|
||||||
|
{
|
||||||
|
//Dead
|
||||||
|
float bindingDead = static_cast<float>(SHInputManager::GetBindingDead(binding.first));
|
||||||
|
if (ImGui::SliderFloat(labelConcat("Deadzone##", entryNumber).c_str(), &bindingDead, 0.0f, 1.0f))
|
||||||
|
SHInputManager::SetBindingDead(binding.first, static_cast<double>(bindingDead));
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("Any positive or negative analog input with magnitude less than this will be registered as neutral");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Gravity
|
||||||
|
double bindingGravity = SHInputManager::GetBindingGravity(binding.first);
|
||||||
|
if (ImGui::InputDouble(labelConcat("Gravity##", entryNumber).c_str(), &bindingGravity))
|
||||||
|
SHInputManager::SetBindingGravity(binding.first, static_cast<double>(bindingGravity));
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("The rate at which the value moves to neutral if no input in the direction is read");
|
||||||
|
ImGui::TextColored(ImVec4{ 1.0f, 0.5f, 0.5f, 1.0f }, "Should be non-negative");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Snap
|
||||||
|
bool bindingSnap = SHInputManager::GetBindingSnap(binding.first);
|
||||||
|
if (ImGui::Checkbox(labelConcat("Snap##", entryNumber).c_str(), &bindingSnap))
|
||||||
|
SHInputManager::SetBindingSnap(binding.first, bindingSnap);
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("If no other input on the axis is present and a input is made in the opposite direction of the current value,");
|
||||||
|
ImGui::Text("the binding's value will jump to neutral 0 before resuming in the input direction");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t keycodeIndex = 0;
|
||||||
|
//Positive key codes
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Text("Positive Key Codes:");
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("When this keyboard or mouse button is held, causes the value to go positive, or negative when inverted");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
//Button to ask for inputs
|
||||||
|
if (!positiveKeyListening)
|
||||||
|
{
|
||||||
|
if (ImGui::Button(labelConcat("New##positiveKeyCode", entryNumber).c_str()))
|
||||||
|
{
|
||||||
|
positiveKeyListening = true;
|
||||||
|
positiveKeyListeningFor = entryNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (positiveKeyListeningFor == entryNumber)
|
||||||
|
{
|
||||||
|
//Listening for inputs
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.4f, 0.4f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 0.5f, 0.5f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.6f, 0.3f, 0.3f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
ImGui::Button(labelConcat("PRESS##positiveKeyCode", entryNumber).c_str());
|
||||||
|
ImGui::PopStyleColor(4);
|
||||||
|
|
||||||
|
SHInputManager::SH_KEYCODE k;
|
||||||
|
if (SHInputManager::AnyKey(&k))
|
||||||
|
{
|
||||||
|
positiveKeyListening = false;
|
||||||
|
SHInputManager::AddBindingPositiveKeyCode(binding.first, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Not listening
|
||||||
|
ImGui::BeginDisabled();
|
||||||
|
ImGui::Button(labelConcat("New##positiveKeyCode", entryNumber).c_str());
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//List and remove bindings
|
||||||
|
ImGui::Indent();
|
||||||
|
keycodeIndex = 0;
|
||||||
|
for (auto& k : binding.second.positiveKeyCodes)
|
||||||
|
{
|
||||||
|
//ImGui::Text("%d", static_cast<int>(k));
|
||||||
|
ImGui::Text(SHInputManager::GetKeyCodeName(k).c_str());
|
||||||
|
ImGui::SameLine();
|
||||||
|
std::string labelString = "X##KeyPositive";
|
||||||
|
labelString += binding.first;
|
||||||
|
|
||||||
|
//Delete button
|
||||||
|
if (ImGui::SmallButton(labelConcat(labelString.c_str(), keycodeIndex).c_str()))
|
||||||
|
{
|
||||||
|
SHInputManager::RemoveBindingPositiveKeyCode(binding.first, k);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++keycodeIndex;
|
||||||
|
}
|
||||||
|
ImGui::Unindent();
|
||||||
|
|
||||||
|
|
||||||
|
//Negative key codes
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Text("Negative Key Codes:");
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("When this keyboard or mouse button is held, causes the value to go negative, or positive when inverted");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
//Button to ask for inputs
|
||||||
|
if (!negativeKeyListening)
|
||||||
|
{
|
||||||
|
if (ImGui::Button(labelConcat("New##negativeKeyCode", entryNumber).c_str()))
|
||||||
|
{
|
||||||
|
negativeKeyListening = true;
|
||||||
|
negativeKeyListeningFor = entryNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (negativeKeyListeningFor == entryNumber)
|
||||||
|
{
|
||||||
|
//Listening for inputs
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.4f, 0.4f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 0.5f, 0.5f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.6f, 0.3f, 0.3f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
ImGui::Button(labelConcat("PRESS##negativeKeyCode", entryNumber).c_str());
|
||||||
|
ImGui::PopStyleColor(4);
|
||||||
|
|
||||||
|
SHInputManager::SH_KEYCODE k;
|
||||||
|
if (SHInputManager::AnyKey(&k))
|
||||||
|
{
|
||||||
|
negativeKeyListening = false;
|
||||||
|
SHInputManager::AddBindingNegativeKeyCode(binding.first, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Not listening
|
||||||
|
ImGui::BeginDisabled();
|
||||||
|
ImGui::Button(labelConcat("New##negativeKeyCode", entryNumber).c_str());
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//List and remove bindings
|
||||||
|
ImGui::Indent();
|
||||||
|
keycodeIndex = 0;
|
||||||
|
for (auto& k : binding.second.negativeKeyCodes)
|
||||||
|
{
|
||||||
|
//ImGui::Text("%d", static_cast<int>(k));
|
||||||
|
ImGui::Text(SHInputManager::GetKeyCodeName(k).c_str());
|
||||||
|
ImGui::SameLine();
|
||||||
|
std::string labelString = "X##KeyNegative";
|
||||||
|
labelString += binding.first;
|
||||||
|
|
||||||
|
//Delete button
|
||||||
|
if (ImGui::SmallButton(labelConcat(labelString.c_str(), keycodeIndex).c_str()))
|
||||||
|
{
|
||||||
|
SHInputManager::RemoveBindingNegativeKeyCode(binding.first, k);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++keycodeIndex;
|
||||||
|
}
|
||||||
|
ImGui::Unindent();
|
||||||
|
|
||||||
|
//Positive controller codes
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Text("Positive Controller Codes:");
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("When this controller button is held, causes the value to go positive, or negative when inverted");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
//Button to ask for inputs
|
||||||
|
if (!positiveControllerListening)
|
||||||
|
{
|
||||||
|
if (ImGui::Button(labelConcat("New##positiveControllerCode", entryNumber).c_str()))
|
||||||
|
{
|
||||||
|
positiveControllerListening = true;
|
||||||
|
positiveControllerListeningFor = entryNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (positiveControllerListeningFor == entryNumber)
|
||||||
|
{
|
||||||
|
//Listening for inputs
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.4f, 0.4f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 0.5f, 0.5f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.6f, 0.3f, 0.3f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
ImGui::Button(labelConcat("PRESS##positiveControllerCode", entryNumber).c_str());
|
||||||
|
ImGui::PopStyleColor(4);
|
||||||
|
|
||||||
|
SHInputManager::SH_CONTROLLERCODE c;
|
||||||
|
if (SHInputManager::AnyControllerInput(&c))
|
||||||
|
{
|
||||||
|
positiveControllerListening = false;
|
||||||
|
SHInputManager::AddBindingPositiveControllerCode(binding.first, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Not listening
|
||||||
|
ImGui::BeginDisabled();
|
||||||
|
ImGui::Button(labelConcat("New##positiveControllerCode", entryNumber).c_str());
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//List and remove bindings
|
||||||
|
ImGui::Indent();
|
||||||
|
keycodeIndex = 0;
|
||||||
|
for (auto& c : binding.second.positiveControllerCodes)
|
||||||
|
{
|
||||||
|
//ImGui::Text("%d", static_cast<int>(k));
|
||||||
|
ImGui::Text(SHInputManager::GetControllerCodeName(c).c_str());
|
||||||
|
ImGui::SameLine();
|
||||||
|
std::string labelString = "X##ControllerPositive";
|
||||||
|
labelString += binding.first;
|
||||||
|
|
||||||
|
//Delete button
|
||||||
|
if (ImGui::SmallButton(labelConcat(labelString.c_str(), keycodeIndex).c_str()))
|
||||||
|
{
|
||||||
|
SHInputManager::RemoveBindingPositiveControllerCode(binding.first, c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++keycodeIndex;
|
||||||
|
}
|
||||||
|
ImGui::Unindent();
|
||||||
|
|
||||||
|
//Negative controller codes
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Text("Negative Controller Codes:");
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::Text("When this controller button is pressed, causes the value to go negative, or positive when inverted");
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
//Button to ask for inputs
|
||||||
|
if (!negativeControllerListening)
|
||||||
|
{
|
||||||
|
if (ImGui::Button(labelConcat("New##negativeControllerCode", entryNumber).c_str()))
|
||||||
|
{
|
||||||
|
negativeControllerListening = true;
|
||||||
|
negativeControllerListeningFor = entryNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (negativeControllerListeningFor == entryNumber)
|
||||||
|
{
|
||||||
|
//Listening for inputs
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.4f, 0.4f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 0.5f, 0.5f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.6f, 0.3f, 0.3f, 1.0f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
ImGui::Button(labelConcat("PRESS##negativeControllerCode", entryNumber).c_str());
|
||||||
|
ImGui::PopStyleColor(4);
|
||||||
|
|
||||||
|
SHInputManager::SH_CONTROLLERCODE c;
|
||||||
|
if (SHInputManager::AnyControllerInput(&c))
|
||||||
|
{
|
||||||
|
negativeControllerListening = false;
|
||||||
|
SHInputManager::AddBindingNegativeControllerCode(binding.first, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Not listening
|
||||||
|
ImGui::BeginDisabled();
|
||||||
|
ImGui::Button(labelConcat("New##negativeControllerCode", entryNumber).c_str());
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//List and remove bindings
|
||||||
|
ImGui::Indent();
|
||||||
|
keycodeIndex = 0;
|
||||||
|
for (auto& c : binding.second.negativeControllerCodes)
|
||||||
|
{
|
||||||
|
//ImGui::Text("%d", static_cast<int>(k));
|
||||||
|
ImGui::Text(SHInputManager::GetControllerCodeName(c).c_str());
|
||||||
|
ImGui::SameLine();
|
||||||
|
std::string labelString = "X##ControllerNegative";
|
||||||
|
labelString += binding.first;
|
||||||
|
|
||||||
|
//Delete button
|
||||||
|
if (ImGui::SmallButton(labelConcat(labelString.c_str(), keycodeIndex).c_str()))
|
||||||
|
{
|
||||||
|
SHInputManager::RemoveBindingNegativeControllerCode(binding.first, c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++keycodeIndex;
|
||||||
|
}
|
||||||
|
ImGui::Unindent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++entryNumber; //Next entry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHInputBindingsPanel::Exit()
|
||||||
|
{
|
||||||
|
SHEditorWindow::Exit();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Editor/EditorWindow/SHEditorWindow.h"
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SH_API SHInputBindingsPanel final : public SHEditorWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHInputBindingsPanel() : SHEditorWindow("Input Bindings Panel", ImGuiWindowFlags_MenuBar) {}
|
||||||
|
|
||||||
|
void Init() override;
|
||||||
|
void Update() override;
|
||||||
|
void Exit() override;
|
||||||
|
};
|
||||||
|
}
|
|
@ -77,7 +77,7 @@ namespace SHADE
|
||||||
ImGui::PushID(SHFamilyID<SHComponent>::GetID<T>());
|
ImGui::PushID(SHFamilyID<SHComponent>::GetID<T>());
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
auto const& properties = componentType.get_properties();
|
auto const& properties = componentType.get_properties();
|
||||||
|
@ -234,7 +234,7 @@ namespace SHADE
|
||||||
const auto componentType = rttr::type::get<SHRigidBodyComponent>();
|
const auto componentType = rttr::type::get<SHRigidBodyComponent>();
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ namespace SHADE
|
||||||
const auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get(*component);
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
|
|
||||||
|
@ -446,7 +446,7 @@ namespace SHADE
|
||||||
const auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get(*component);
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
|
|
||||||
|
@ -478,7 +478,7 @@ namespace SHADE
|
||||||
const auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get(*component);
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
Handle<SHMesh> const& mesh = component->GetMesh();
|
Handle<SHMesh> const& mesh = component->GetMesh();
|
||||||
|
@ -536,7 +536,7 @@ namespace SHADE
|
||||||
const auto componentType = rttr::type::get(*component);
|
const auto componentType = rttr::type::get(*component);
|
||||||
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active");
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::CollapsingHeader(componentType.get_name().data()))
|
if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
DrawContextMenu(component);
|
DrawContextMenu(component);
|
||||||
Handle<SHFont> const& font = component->GetFont();
|
Handle<SHFont> const& font = component->GetFont();
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "UI/SHUIComponent.h"
|
#include "UI/SHUIComponent.h"
|
||||||
#include "UI/SHCanvasComponent.h"
|
#include "UI/SHCanvasComponent.h"
|
||||||
#include "UI/SHButtonComponent.h"
|
#include "UI/SHButtonComponent.h"
|
||||||
|
#include "UI/SHToggleButtonComponent.h"
|
||||||
#include "SHEditorComponentView.h"
|
#include "SHEditorComponentView.h"
|
||||||
#include "AudioSystem/SHAudioListenerComponent.h"
|
#include "AudioSystem/SHAudioListenerComponent.h"
|
||||||
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
|
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
|
||||||
|
@ -93,7 +94,6 @@ namespace SHADE
|
||||||
SHEditorWindow::Update();
|
SHEditorWindow::Update();
|
||||||
if (Begin())
|
if (Begin())
|
||||||
{
|
{
|
||||||
auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
if (editor && !editor->selectedEntities.empty())
|
if (editor && !editor->selectedEntities.empty())
|
||||||
{
|
{
|
||||||
EntityID const& eid = editor->selectedEntities[0];
|
EntityID const& eid = editor->selectedEntities[0];
|
||||||
|
@ -154,6 +154,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
DrawComponent(buttonComponent);
|
DrawComponent(buttonComponent);
|
||||||
}
|
}
|
||||||
|
if (auto toggleButton = SHComponentManager::GetComponent_s<SHToggleButtonComponent>(eid))
|
||||||
|
{
|
||||||
|
DrawComponent(toggleButton);
|
||||||
|
}
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
// Render Scripts
|
// Render Scripts
|
||||||
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
SHScriptEngine* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
@ -167,6 +171,7 @@ namespace SHADE
|
||||||
DrawAddComponentButton<SHLightComponent>(eid);
|
DrawAddComponentButton<SHLightComponent>(eid);
|
||||||
DrawAddComponentButton<SHCanvasComponent>(eid);
|
DrawAddComponentButton<SHCanvasComponent>(eid);
|
||||||
DrawAddComponentButton<SHButtonComponent>(eid);
|
DrawAddComponentButton<SHButtonComponent>(eid);
|
||||||
|
DrawAddComponentButton<SHToggleButtonComponent>(eid);
|
||||||
|
|
||||||
// Components that require Transforms
|
// Components that require Transforms
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
ImGui::BeginMenuBar();
|
ImGui::BeginMenuBar();
|
||||||
ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x * 0.5f - 80.f);
|
ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x * 0.5f - 80.f);
|
||||||
const auto editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
|
ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
|
||||||
if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
|
if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
|
||||||
{
|
{
|
||||||
|
@ -165,16 +165,18 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (ImGui::Selectable("New Scene"))
|
if (ImGui::Selectable("New Scene"))
|
||||||
{
|
{
|
||||||
SHSystemManager::GetSystem<SHEditor>()->NewScene();
|
editor->NewScene();
|
||||||
}
|
}
|
||||||
if (ImGui::Selectable("Save"))
|
if (ImGui::Selectable("Save"))
|
||||||
{
|
{
|
||||||
SHSystemManager::GetSystem<SHEditor>()->SaveScene();
|
editor->SaveScene();
|
||||||
}
|
}
|
||||||
|
ImGui::BeginDisabled(true);
|
||||||
if (ImGui::Selectable("Load"))
|
if (ImGui::Selectable("Load"))
|
||||||
{
|
{
|
||||||
//SHSystemManager::GetSystem<SHEditor>()->LoadScene()
|
//SHSystemManager::GetSystem<SHEditor>()->LoadScene()
|
||||||
}
|
}
|
||||||
|
ImGui::EndDisabled();
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,7 +213,7 @@ namespace SHADE
|
||||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
scriptEngine->OpenSolution();
|
scriptEngine->OpenSolution();
|
||||||
}
|
}
|
||||||
ImGui::BeginDisabled(SHSystemManager::GetSystem<SHEditor>()->editorState != SHEditor::State::STOP);
|
ImGui::BeginDisabled(editor->editorState != SHEditor::State::STOP);
|
||||||
if (ImGui::Selectable("Build Scripts - Debug"))
|
if (ImGui::Selectable("Build Scripts - Debug"))
|
||||||
{
|
{
|
||||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
@ -252,7 +254,6 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (ImGui::Selectable(style.to_string().c_str()))
|
if (ImGui::Selectable(style.to_string().c_str()))
|
||||||
{
|
{
|
||||||
if (auto editor = SHSystemManager::GetSystem<SHEditor>())
|
|
||||||
editor->SetStyle(style.convert<SHEditor::Style>());
|
editor->SetStyle(style.convert<SHEditor::Style>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
//|| SHADE Includes ||
|
//|| SHADE Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
#include "SHEditorWindow.h"
|
#include "SHEditorWindow.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Editor/SHEditor.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Library Includes ||
|
//|| Library Includes ||
|
||||||
|
@ -21,6 +23,7 @@ namespace SHADE
|
||||||
SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags)
|
SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags)
|
||||||
:isOpen(true), isWindowHovered(false), windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
|
:isOpen(true), isWindowHovered(false), windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
|
||||||
{
|
{
|
||||||
|
editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditorWindow::Init()
|
void SHEditorWindow::Init()
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
struct ImGuiIO;
|
struct ImGuiIO;
|
||||||
typedef int ImGuiWindowFlags;
|
typedef int ImGuiWindowFlags;
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
class SHEditor;
|
||||||
class SHEditorWindow
|
class SHEditorWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -38,6 +38,6 @@ namespace SHADE
|
||||||
|
|
||||||
ImGuiWindowFlags windowFlags = 0;
|
ImGuiWindowFlags windowFlags = 0;
|
||||||
ImGuiIO& io;
|
ImGuiIO& io;
|
||||||
|
SHEditor* editor;
|
||||||
};//class SHEditorWindow
|
};//class SHEditorWindow
|
||||||
}//namespace SHADE
|
}//namespace SHADE
|
||||||
|
|
|
@ -7,3 +7,4 @@
|
||||||
#include "AssetBrowser/SHAssetBrowser.h" //Asset Browser
|
#include "AssetBrowser/SHAssetBrowser.h" //Asset Browser
|
||||||
#include "MaterialInspector/SHMaterialInspector.h" //Material Inspector
|
#include "MaterialInspector/SHMaterialInspector.h" //Material Inspector
|
||||||
#include "ColliderTagPanel/SHColliderTagPanel.h" //Collider Tag Panel
|
#include "ColliderTagPanel/SHColliderTagPanel.h" //Collider Tag Panel
|
||||||
|
#include "InputBindings/SHInputBindingsPanel.h" //Input Bindings
|
|
@ -4,5 +4,7 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{};
|
SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{};
|
||||||
|
SHEditorWindowManager::PopupWindowMap SHEditorWindowManager::popupWindows{};
|
||||||
SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{};
|
SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{};
|
||||||
|
SHEditorWindowManager::EditorWindowID SHEditorWindowManager::popupWindowCount{};
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "SHEditorWindow.h"
|
#include "SHEditorWindow.h"
|
||||||
|
#include "SHPopUpWindow.h"
|
||||||
#include "Tools/Logger/SHLog.h"
|
#include "Tools/Logger/SHLog.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -16,6 +17,10 @@ namespace SHADE
|
||||||
using EditorWindowID = uint8_t;
|
using EditorWindowID = uint8_t;
|
||||||
using EditorWindowPtr = std::unique_ptr<SHEditorWindow>;
|
using EditorWindowPtr = std::unique_ptr<SHEditorWindow>;
|
||||||
using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>;
|
using EditorWindowMap = std::unordered_map<EditorWindowID, EditorWindowPtr>;
|
||||||
|
|
||||||
|
using PopupWindowPtr = std::unique_ptr<SHPopUpWindow>;
|
||||||
|
using PopupWindowMap = std::unordered_map<EditorWindowID, PopupWindowPtr>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get ID for the Editor Window Type
|
* @brief Get ID for the Editor Window Type
|
||||||
*
|
*
|
||||||
|
@ -67,10 +72,63 @@ namespace SHADE
|
||||||
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
|
return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get ID for the Popup Window Type
|
||||||
|
*
|
||||||
|
* @tparam T Type of Popup Window
|
||||||
|
* @return EditorWindowID ID of Popup Window Type
|
||||||
|
*/
|
||||||
|
template <typename T, std::enable_if_t<std::is_base_of_v<SHPopUpWindow, T>, bool> = true>
|
||||||
|
static EditorWindowID GetPopupWindowID()
|
||||||
|
{
|
||||||
|
static EditorWindowID id;
|
||||||
|
static bool idCreated = false;
|
||||||
|
if (!idCreated)
|
||||||
|
{
|
||||||
|
id = popupWindowCount++;
|
||||||
|
idCreated = true;
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create an Popup Window
|
||||||
|
*
|
||||||
|
* @tparam T Type of Popup Window to create
|
||||||
|
*/
|
||||||
|
template <typename T, std::enable_if_t<std::is_base_of_v<SHPopUpWindow, T>, bool> = true>
|
||||||
|
static void CreatePopupWindow()
|
||||||
|
{
|
||||||
|
static bool isCreated = false;
|
||||||
|
if (!isCreated)
|
||||||
|
{
|
||||||
|
popupWindows[GetPopupWindowID<T>()] = std::make_unique<T>();
|
||||||
|
isCreated = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLog::Warning("Attempt to create duplicate of Popup window type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get pointer to the Editor Window
|
||||||
|
*
|
||||||
|
* @tparam T Type of editor window to retrieve
|
||||||
|
* @return T* Pointer to the editor window
|
||||||
|
*/
|
||||||
|
template <typename T, std::enable_if_t<std::is_base_of_v<SHPopUpWindow, T>, bool> = true>
|
||||||
|
static T* GetPopupWindow()
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T*>(popupWindows[GetPopupWindowID<T>()].get());
|
||||||
|
}
|
||||||
|
|
||||||
static EditorWindowMap editorWindows;
|
static EditorWindowMap editorWindows;
|
||||||
|
static PopupWindowMap popupWindows;
|
||||||
private:
|
private:
|
||||||
// Number of windows; used for Editor Window ID Generation
|
// Number of windows; used for Editor Window ID Generation
|
||||||
static EditorWindowID windowCount;
|
static EditorWindowID windowCount;
|
||||||
|
static EditorWindowID popupWindowCount;
|
||||||
// Map of Editor Windows
|
// Map of Editor Windows
|
||||||
friend class SHEditor;
|
friend class SHEditor;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHPopUpWindow.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
#include "Editor/SHEditor.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHPopUpWindow::SHPopUpWindow(std::string_view const& name, bool modal, ImGuiPopupFlags inPopupFlags, ImGuiWindowFlags inWindowFlags)
|
||||||
|
:editor(nullptr), windowName(name), popupFlags(inPopupFlags), windowFlags(inWindowFlags), isOpen(false), isModal(modal)
|
||||||
|
{
|
||||||
|
editor = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHPopUpWindow::Begin()
|
||||||
|
{
|
||||||
|
if (isOpen)
|
||||||
|
ImGui::OpenPopup(windowName.data(), popupFlags);
|
||||||
|
|
||||||
|
return isModal ? ImGui::BeginPopupModal(windowName.data(), &isOpen, windowFlags) : ImGui::BeginPopup(windowName.data(), windowFlags);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#==============================================================#
|
||||||
|
//|| STL Includes ||
|
||||||
|
//#==============================================================#
|
||||||
|
#include <string>
|
||||||
|
#include <imgui.h>
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHEditor;
|
||||||
|
class SHPopUpWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHPopUpWindow(std::string_view const& name, bool modal, ImGuiPopupFlags inPopupFlags, ImGuiWindowFlags inWindowFlags);
|
||||||
|
virtual ~SHPopUpWindow() = default;
|
||||||
|
virtual void Draw(){};
|
||||||
|
|
||||||
|
bool isOpen;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool Begin();
|
||||||
|
|
||||||
|
SHEditor* editor;
|
||||||
|
std::string_view windowName;
|
||||||
|
ImGuiPopupFlags popupFlags;
|
||||||
|
ImGuiWindowFlags windowFlags;
|
||||||
|
bool isModal;
|
||||||
|
};
|
||||||
|
}
|
|
@ -35,7 +35,6 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
SHEditorWindow::Update();
|
SHEditorWindow::Update();
|
||||||
auto camSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
auto camSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||||
SHEditor* editor = SHSystemManager::GetSystem<SHEditor>();
|
|
||||||
|
|
||||||
if (!editor->selectedEntities.empty())
|
if (!editor->selectedEntities.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
#include "EditorWindow/SHEditorWindowManager.h"
|
#include "EditorWindow/SHEditorWindowManager.h"
|
||||||
#include "EditorWindow/SHEditorWindowIncludes.h"
|
#include "EditorWindow/SHEditorWindowIncludes.h"
|
||||||
|
|
||||||
|
#include "EditorWindow/SHPopUpWindow.h"
|
||||||
|
#include "EditorWindow/EditorPopups/SHEditorPopups.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Library Includes ||
|
//|| Library Includes ||
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
|
@ -98,15 +101,19 @@ namespace SHADE
|
||||||
|
|
||||||
//Add editor windows
|
//Add editor windows
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
|
SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
|
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
|
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
|
SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHAssetBrowser>();
|
SHEditorWindowManager::CreateEditorWindow<SHAssetBrowser>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHMaterialInspector>();
|
SHEditorWindowManager::CreateEditorWindow<SHMaterialInspector>();
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHColliderTagPanel>();
|
SHEditorWindowManager::CreateEditorWindow<SHColliderTagPanel>();
|
||||||
|
SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
|
||||||
|
SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
|
||||||
|
SHEditorWindowManager::CreateEditorWindow<SHInputBindingsPanel>();
|
||||||
|
|
||||||
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
|
||||||
|
|
||||||
|
//Add popup windows
|
||||||
|
SHEditorWindowManager::CreatePopupWindow<SHSceneSavePrompt>();
|
||||||
|
|
||||||
io = &ImGui::GetIO();
|
io = &ImGui::GetIO();
|
||||||
|
|
||||||
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
|
@ -150,7 +157,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
(void)dt;
|
(void)dt;
|
||||||
NewFrame();
|
NewFrame();
|
||||||
for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
|
for (auto const& window : SHEditorWindowManager::editorWindows | std::views::values)
|
||||||
{
|
{
|
||||||
if(window->isOpen)
|
if(window->isOpen)
|
||||||
{
|
{
|
||||||
|
@ -158,7 +165,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderSceneNamePrompt();
|
for(auto const& popupWindow : SHEditorWindowManager::popupWindows | std::views::values)
|
||||||
|
{
|
||||||
|
popupWindow->Draw();
|
||||||
|
}
|
||||||
|
|
||||||
RenderUnsavedChangesPrompt();
|
RenderUnsavedChangesPrompt();
|
||||||
//PollPicking();
|
//PollPicking();
|
||||||
|
|
||||||
|
@ -177,37 +188,6 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::RenderSceneNamePrompt() noexcept
|
|
||||||
{
|
|
||||||
if(isSceneNamePromptOpen)
|
|
||||||
{
|
|
||||||
ImGui::OpenPopup(sceneNamePromptName.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ImGui::BeginPopupModal(sceneNamePromptName.data(), &isSceneNamePromptOpen))
|
|
||||||
{
|
|
||||||
static std::string newSceneName{};
|
|
||||||
ImGui::Text("Enter new scene name");
|
|
||||||
ImGui::InputText("##name", &newSceneName);
|
|
||||||
ImGui::BeginDisabled(newSceneName.empty());
|
|
||||||
if(ImGui::Button("Save"))
|
|
||||||
{
|
|
||||||
SaveScene(newSceneName);
|
|
||||||
newSceneName.clear();
|
|
||||||
isSceneNamePromptOpen = false;
|
|
||||||
ImGui::CloseCurrentPopup();
|
|
||||||
}
|
|
||||||
ImGui::EndDisabled();
|
|
||||||
ImGui::SameLine();
|
|
||||||
if(ImGui::Button("Cancel"))
|
|
||||||
{
|
|
||||||
isSceneNamePromptOpen = false;
|
|
||||||
ImGui::CloseCurrentPopup();
|
|
||||||
}
|
|
||||||
ImGui::EndPopup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHEditor::RenderUnsavedChangesPrompt() noexcept
|
void SHEditor::RenderUnsavedChangesPrompt() noexcept
|
||||||
{
|
{
|
||||||
if(isUnsavedChangesPromptOpen)
|
if(isUnsavedChangesPromptOpen)
|
||||||
|
@ -220,12 +200,12 @@ namespace SHADE
|
||||||
ImGui::Text("You have unsaved changes!");
|
ImGui::Text("You have unsaved changes!");
|
||||||
if(ImGui::Button("Save"))
|
if(ImGui::Button("Save"))
|
||||||
{
|
{
|
||||||
isSceneNamePromptOpen = true;
|
SHEditorWindowManager::GetPopupWindow<SHSceneSavePrompt>()->isOpen = true;
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if(ImGui::Button("Cancel"))
|
if(ImGui::Button("Cancel"))
|
||||||
{
|
{
|
||||||
isUnsavedChangesPromptOpen = false;
|
SHEditorWindowManager::GetPopupWindow<SHSceneSavePrompt>()->isOpen = true;
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -489,7 +469,7 @@ namespace SHADE
|
||||||
|
|
||||||
//auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
|
//auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
|
||||||
auto renderGraph = gfxSystem->GetRenderGraph();
|
auto renderGraph = gfxSystem->GetRenderGraph();
|
||||||
auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass();
|
auto renderPass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::IMGUI_PASS.data())->GetRenderpass();
|
||||||
|
|
||||||
if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
|
if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
|
||||||
{
|
{
|
||||||
|
@ -508,7 +488,7 @@ namespace SHADE
|
||||||
|
|
||||||
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||||
|
|
||||||
renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer> cmd, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::IMGUI_PASS.data())->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle<SHVkCommandBuffer> cmd, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
cmd->BeginLabeledSegment("ImGui Draw");
|
cmd->BeginLabeledSegment("ImGui Draw");
|
||||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer());
|
||||||
|
@ -563,7 +543,7 @@ namespace SHADE
|
||||||
if (newSceneName.empty())
|
if (newSceneName.empty())
|
||||||
{
|
{
|
||||||
//Prompt for scene name
|
//Prompt for scene name
|
||||||
isSceneNamePromptOpen = true;
|
SHEditorWindowManager::GetPopupWindow<SHSceneSavePrompt>()->isOpen = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//Else We have a new name
|
//Else We have a new name
|
||||||
|
@ -644,7 +624,7 @@ namespace SHADE
|
||||||
editorState = SHEditor::State::STOP;
|
editorState = SHEditor::State::STOP;
|
||||||
SHCommandManager::SwapStacks();
|
SHCommandManager::SwapStacks();
|
||||||
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
SHEventManager::BroadcastEvent<SHEditorStateChangeEvent>(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT);
|
||||||
LoadScene(SHSceneManager::GetCurrentSceneAssetID());
|
LoadScene(editorConfig->workingSceneID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHEditor::ProcessShortcuts()
|
void SHEditor::ProcessShortcuts()
|
||||||
|
|
|
@ -37,8 +37,6 @@ namespace SHADE
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
class SHVkCommandPool;
|
class SHVkCommandPool;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SHEditor static class contains editor variables and implementation of editor functions.
|
* @brief SHEditor static class contains editor variables and implementation of editor functions.
|
||||||
*
|
*
|
||||||
|
@ -144,8 +142,6 @@ namespace SHADE
|
||||||
*/
|
*/
|
||||||
void Render();
|
void Render();
|
||||||
|
|
||||||
void RenderSceneNamePrompt() noexcept;
|
|
||||||
|
|
||||||
void RenderUnsavedChangesPrompt() noexcept;
|
void RenderUnsavedChangesPrompt() noexcept;
|
||||||
|
|
||||||
void InitLayout() noexcept;
|
void InitLayout() noexcept;
|
||||||
|
@ -156,8 +152,6 @@ namespace SHADE
|
||||||
|
|
||||||
SHEventHandle onEditorStateChanged(SHEventPtr eventPtr);
|
SHEventHandle onEditorStateChanged(SHEventPtr eventPtr);
|
||||||
|
|
||||||
bool isSceneNamePromptOpen = false;
|
|
||||||
|
|
||||||
bool isUnsavedChangesPromptOpen = false;
|
bool isUnsavedChangesPromptOpen = false;
|
||||||
|
|
||||||
static constexpr std::string_view sceneNamePromptName = "Save scene as...";
|
static constexpr std::string_view sceneNamePromptName = "Save scene as...";
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include "Command/SHCommandManager.h"
|
#include "Command/SHCommandManager.h"
|
||||||
#include "SHImGuiHelpers.hpp"
|
#include "SHImGuiHelpers.hpp"
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
|
||||||
//#==============================================================#
|
//#==============================================================#
|
||||||
//|| Library Includes ||
|
//|| Library Includes ||
|
||||||
|
@ -454,7 +456,33 @@ namespace SHADE
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
ImGui::PushID(label.data());
|
ImGui::PushID(label.data());
|
||||||
TextLabel(label);
|
TextLabel(label);
|
||||||
const bool hasChange = ImGui::InputScalar("##dragScalar", data_type, &value);
|
bool hasChange = ImGui::DragScalar("##dragScalar", data_type, &value);
|
||||||
|
if constexpr(std::is_same_v<T, uint32_t>) //EID or Resource
|
||||||
|
{
|
||||||
|
if (SHDragDrop::BeginTarget())
|
||||||
|
{
|
||||||
|
if(AssetID * payload = SHDragDrop::AcceptPayload<T>(SHDragDrop::DRAG_RESOURCE))
|
||||||
|
{
|
||||||
|
value = *payload;
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
|
||||||
|
hasChange = true;
|
||||||
|
SHDragDrop::EndTarget();
|
||||||
|
}
|
||||||
|
else if (std::vector<EntityID>* payload = SHDragDrop::AcceptPayload<std::vector<EntityID>>(SHDragDrop::DRAG_EID))
|
||||||
|
{
|
||||||
|
value = payload->back();
|
||||||
|
SHCommandManager::PerformCommand(std::reinterpret_pointer_cast<SHBaseCommand>(std::make_shared<SHCommand<T>>(get(), value, set)), false);
|
||||||
|
hasChange = true;
|
||||||
|
SHDragDrop::EndTarget();
|
||||||
|
}
|
||||||
|
if(hasChange)
|
||||||
|
{
|
||||||
|
ImGui::PopID();
|
||||||
|
ImGui::EndGroup();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
static bool startRecording = false;
|
static bool startRecording = false;
|
||||||
if (hasChange)
|
if (hasChange)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,4 +23,5 @@ constexpr SHEventIdentifier SH_SCENE_INIT_POST { 14 };
|
||||||
constexpr SHEventIdentifier SH_SCENE_EXIT_PRE { 15 };
|
constexpr SHEventIdentifier SH_SCENE_EXIT_PRE { 15 };
|
||||||
constexpr SHEventIdentifier SH_SCENE_EXIT_POST { 16 };
|
constexpr SHEventIdentifier SH_SCENE_EXIT_POST { 16 };
|
||||||
constexpr SHEventIdentifier SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT { 17 };
|
constexpr SHEventIdentifier SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT { 17 };
|
||||||
|
constexpr SHEventIdentifier SH_BUTTON_CLICK_EVENT { 18 };
|
||||||
|
|
||||||
|
|
|
@ -175,6 +175,27 @@ namespace SHADE
|
||||||
writeInfo.descImageInfos[i].sampler = sampler ? sampler->GetVkSampler() : nullptr;
|
writeInfo.descImageInfos[i].sampler = sampler ? sampler->GetVkSampler() : nullptr;
|
||||||
writeInfo.descImageInfos[i].imageLayout = layout;
|
writeInfo.descImageInfos[i].imageLayout = layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rest is not used, so it doesn't matter what's in them, we just want to pacify Vulkan
|
||||||
|
for (uint32_t i = imageViewsAndSamplers.size(); i < writeInfo.descImageInfos.size(); ++i)
|
||||||
|
{
|
||||||
|
writeInfo.descImageInfos[i].sampler = std::get<Handle<SHVkSampler>>(imageViewsAndSamplers.back())->GetVkSampler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout> const& imageViewAndSampler, uint32_t descIndex) noexcept
|
||||||
|
{
|
||||||
|
// Find the target writeDescSet
|
||||||
|
BindingAndSetHash writeHash = binding;
|
||||||
|
writeHash |= static_cast<uint64_t>(set) << 32;
|
||||||
|
auto& writeInfo = updater.writeInfos[updater.writeHashMap.at(writeHash)];
|
||||||
|
|
||||||
|
// write sampler and image view
|
||||||
|
auto& [view, sampler, layout] = imageViewAndSampler;
|
||||||
|
writeInfo.descImageInfos[descIndex].imageView = view->GetImageView();
|
||||||
|
writeInfo.descImageInfos[descIndex].sampler = sampler ? sampler->GetVkSampler() : nullptr;
|
||||||
|
writeInfo.descImageInfos[descIndex].imageLayout = layout;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHVkDescriptorSetGroup::ModifyWriteDescBuffer(uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept
|
void SHVkDescriptorSetGroup::ModifyWriteDescBuffer(uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept
|
||||||
|
@ -200,6 +221,28 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkDescriptorSetGroup::UpdateDescriptorSetImage(uint32_t set, uint32_t binding, uint32_t descArrayIndex) noexcept
|
||||||
|
{
|
||||||
|
vk::WriteDescriptorSet writeDescSet{};
|
||||||
|
|
||||||
|
// Get binding + set hash
|
||||||
|
BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding);
|
||||||
|
|
||||||
|
// to index a write for a binding
|
||||||
|
uint32_t writeInfoIndex = updater.writeHashMap[bsHash];
|
||||||
|
|
||||||
|
// Initialize info for write
|
||||||
|
writeDescSet.descriptorType = layoutsUsed[set]->GetBindings()[binding].Type;
|
||||||
|
writeDescSet.dstArrayElement = descArrayIndex;
|
||||||
|
writeDescSet.dstSet = descSets[set];
|
||||||
|
writeDescSet.dstBinding = binding;
|
||||||
|
|
||||||
|
writeDescSet.pImageInfo = updater.writeInfos[writeInfoIndex].descImageInfos.data() + descArrayIndex;
|
||||||
|
writeDescSet.descriptorCount = 1u;
|
||||||
|
|
||||||
|
device->UpdateDescriptorSet(writeDescSet);
|
||||||
|
}
|
||||||
|
|
||||||
void SHVkDescriptorSetGroup::UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept
|
void SHVkDescriptorSetGroup::UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept
|
||||||
{
|
{
|
||||||
vk::WriteDescriptorSet writeDescSet{};
|
vk::WriteDescriptorSet writeDescSet{};
|
||||||
|
|
|
@ -63,10 +63,12 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Public member functions */
|
/* Public member functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
void UpdateDescriptorSetImage (uint32_t set, uint32_t binding, uint32_t descArrayIndex) noexcept;
|
||||||
void UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept;
|
void UpdateDescriptorSetImages(uint32_t set, uint32_t binding) noexcept;
|
||||||
void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept;
|
void UpdateDescriptorSetBuffer(uint32_t set, uint32_t binding) noexcept;
|
||||||
|
|
||||||
void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> const& imageViewsAndSamplers) noexcept;
|
void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::span<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> const& imageViewsAndSamplers) noexcept;
|
||||||
|
void ModifyWriteDescImage(uint32_t set, uint32_t binding, std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout> const& imageViewAndSampler, uint32_t descIndex) noexcept;
|
||||||
void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
void ModifyWriteDescBuffer (uint32_t set, uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -183,33 +183,43 @@ namespace SHADE
|
||||||
/*if (!extensionsSupported)
|
/*if (!extensionsSupported)
|
||||||
SHUtil::ReportWarning("Some of the required extensions cannot be found on the physical device. ");*/
|
SHUtil::ReportWarning("Some of the required extensions cannot be found on the physical device. ");*/
|
||||||
|
|
||||||
vk::PhysicalDeviceFeatures features{}; // ADD MORE FEATURES HERE IF NEEDED
|
vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature
|
||||||
|
{
|
||||||
|
.shaderSampledImageArrayNonUniformIndexing = VK_TRUE,
|
||||||
|
.descriptorBindingPartiallyBound = VK_TRUE,
|
||||||
|
.descriptorBindingVariableDescriptorCount = VK_TRUE,
|
||||||
|
.runtimeDescriptorArray = VK_TRUE,
|
||||||
|
};
|
||||||
|
|
||||||
|
vk::PhysicalDeviceRobustness2FeaturesEXT robustFeatures
|
||||||
|
{
|
||||||
|
.nullDescriptor = VK_TRUE,
|
||||||
|
};
|
||||||
|
|
||||||
|
robustFeatures.pNext = &descIndexingFeature;
|
||||||
|
|
||||||
|
vk::PhysicalDeviceFeatures2 features{}; // ADD MORE FEATURES HERE IF NEEDED
|
||||||
|
|
||||||
// point and lines fill mode
|
// point and lines fill mode
|
||||||
features.fillModeNonSolid = VK_TRUE;
|
features.features.fillModeNonSolid = VK_TRUE;
|
||||||
features.samplerAnisotropy = VK_TRUE;
|
features.features.samplerAnisotropy = VK_TRUE;
|
||||||
features.multiDrawIndirect = VK_TRUE;
|
features.features.multiDrawIndirect = VK_TRUE;
|
||||||
features.independentBlend = VK_TRUE;
|
features.features.independentBlend = VK_TRUE;
|
||||||
|
features.features.wideLines = VK_TRUE;
|
||||||
|
|
||||||
// for wide lines
|
features.pNext = &robustFeatures;
|
||||||
features.wideLines = true;
|
|
||||||
|
|
||||||
vk::PhysicalDeviceDescriptorIndexingFeatures descIndexingFeature{};
|
|
||||||
descIndexingFeature.descriptorBindingVariableDescriptorCount = true;
|
|
||||||
descIndexingFeature.shaderSampledImageArrayNonUniformIndexing = true;
|
|
||||||
descIndexingFeature.runtimeDescriptorArray = true;
|
|
||||||
|
|
||||||
// Prepare to create the device
|
// Prepare to create the device
|
||||||
vk::DeviceCreateInfo deviceCreateInfo
|
vk::DeviceCreateInfo deviceCreateInfo
|
||||||
{
|
{
|
||||||
.pNext = &descIndexingFeature,
|
.pNext = &features,
|
||||||
.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size()),
|
.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size()),
|
||||||
.pQueueCreateInfos = queueCreateInfos.data(),
|
.pQueueCreateInfos = queueCreateInfos.data(),
|
||||||
.enabledLayerCount = 0, // deprecated and ignored
|
.enabledLayerCount = 0, // deprecated and ignored
|
||||||
.ppEnabledLayerNames = nullptr, // deprecated and ignored
|
.ppEnabledLayerNames = nullptr, // deprecated and ignored
|
||||||
.enabledExtensionCount = !extensionsSupported ? 0 : static_cast<uint32_t>(requiredExtensions.size()),
|
.enabledExtensionCount = !extensionsSupported ? 0 : static_cast<uint32_t>(requiredExtensions.size()),
|
||||||
.ppEnabledExtensionNames = !extensionsSupported ? nullptr : requiredExtensions.data(),
|
.ppEnabledExtensionNames = !extensionsSupported ? nullptr : requiredExtensions.data(),
|
||||||
.pEnabledFeatures = &features
|
//.pEnabledFeatures = &features
|
||||||
};
|
};
|
||||||
|
|
||||||
// Actually create the device
|
// Actually create the device
|
||||||
|
|
|
@ -10,5 +10,8 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
//! We need to get the light component and initialize the relevant variables.
|
//! We need to get the light component and initialize the relevant variables.
|
||||||
EntityID lightEntity;
|
EntityID lightEntity;
|
||||||
|
|
||||||
|
//! Generate a renderer for the light component
|
||||||
|
bool generateRenderer;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace SHADE
|
||||||
.maxAnisotropy = 1.0f,
|
.maxAnisotropy = 1.0f,
|
||||||
.minLod = params.minLod,
|
.minLod = params.minLod,
|
||||||
.maxLod = params.maxLod,
|
.maxLod = params.maxLod,
|
||||||
|
.borderColor = vk::BorderColor::eFloatOpaqueWhite
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the sampler
|
// Create the sampler
|
||||||
|
|
|
@ -551,7 +551,7 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* SHBatch - Usage Functions */
|
/* SHBatch - Usage Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
|
void SHBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline/* = true*/)
|
||||||
{
|
{
|
||||||
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
if (frameIndex >= SHGraphicsConstants::NUM_FRAME_BUFFERS)
|
||||||
{
|
{
|
||||||
|
@ -566,7 +566,10 @@ namespace SHADE
|
||||||
// Bind all required objects before drawing
|
// Bind all required objects before drawing
|
||||||
static std::array<uint32_t, 1> dynamicOffset{ 0 };
|
static std::array<uint32_t, 1> dynamicOffset{ 0 };
|
||||||
cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index));
|
cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index));
|
||||||
cmdBuffer->BindPipeline(pipeline);
|
|
||||||
|
if (bindBatchPipeline)
|
||||||
|
cmdBuffer->BindPipeline(pipeline);
|
||||||
|
|
||||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0);
|
||||||
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
|
cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0);
|
||||||
if (matPropsDescSet[frameIndex])
|
if (matPropsDescSet[frameIndex])
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace SHADE
|
||||||
void UpdateTransformBuffer(uint32_t frameIndex);
|
void UpdateTransformBuffer(uint32_t frameIndex);
|
||||||
void UpdateInstancedIntegerBuffer(uint32_t frameIndex);
|
void UpdateInstancedIntegerBuffer(uint32_t frameIndex);
|
||||||
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) ;
|
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) ;
|
||||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex);
|
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline = true);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
|
|
|
@ -107,12 +107,12 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSuperBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
void SHSuperBatch::Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline /*= true*/) noexcept
|
||||||
{
|
{
|
||||||
// Build all batches
|
// Build all batches
|
||||||
for (auto& batch : batches)
|
for (auto& batch : batches)
|
||||||
{
|
{
|
||||||
batch.Draw(cmdBuffer, frameIndex);
|
batch.Draw(cmdBuffer, frameIndex, bindBatchPipeline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace SHADE
|
||||||
void Clear() noexcept;
|
void Clear() noexcept;
|
||||||
void UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
void UpdateBuffers(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||||
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
void Build(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
||||||
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
void Draw(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, bool bindBatchPipeline = true) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
|
|
|
@ -13,6 +13,8 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsPredefinedData::predefinedLayouts;
|
std::vector<Handle<SHVkDescriptorSetLayout>> SHGraphicsPredefinedData::predefinedLayouts;
|
||||||
SHVertexInputState SHGraphicsPredefinedData::defaultVertexInputState;
|
SHVertexInputState SHGraphicsPredefinedData::defaultVertexInputState;
|
||||||
|
SHVertexInputState SHGraphicsPredefinedData::shadowMapVertexInputState;
|
||||||
|
|
||||||
std::vector<SHGraphicsPredefinedData::PerSystem> SHGraphicsPredefinedData::perSystemData;
|
std::vector<SHGraphicsPredefinedData::PerSystem> SHGraphicsPredefinedData::perSystemData;
|
||||||
|
|
||||||
//SHGraphicsPredefinedData::PerSystem SHGraphicsPredefinedData::batchingSystemData;
|
//SHGraphicsPredefinedData::PerSystem SHGraphicsPredefinedData::batchingSystemData;
|
||||||
|
@ -150,12 +152,26 @@ namespace SHADE
|
||||||
Handle<SHVkDescriptorSetLayout> fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ fontBitmapBinding, fontMatrixBinding });
|
Handle<SHVkDescriptorSetLayout> fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ fontBitmapBinding, fontMatrixBinding });
|
||||||
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, fontDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Font Data");
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, fontDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Font Data");
|
||||||
|
|
||||||
|
// descriptor binding for storing shadow maps
|
||||||
|
SHVkDescriptorSetLayout::Binding shadowMapBinding
|
||||||
|
{
|
||||||
|
.Type = vk::DescriptorType::eCombinedImageSampler,
|
||||||
|
.Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute,
|
||||||
|
.BindPoint = SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA,
|
||||||
|
.DescriptorCount = 200, // we can have up to 200 textures for now
|
||||||
|
.flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
// For global data (generic data and textures)
|
||||||
|
Handle<SHVkDescriptorSetLayout> shadowMapDescLayout = logicalDevice->CreateDescriptorSetLayout({ shadowMapBinding });
|
||||||
|
SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, shadowMapDescLayout->GetVkHandle(), "[Descriptor Set Layout] Shadow Maps");
|
||||||
|
|
||||||
predefinedLayouts.push_back(staticGlobalLayout);
|
predefinedLayouts.push_back(staticGlobalLayout);
|
||||||
predefinedLayouts.push_back(lightDataDescSetLayout);
|
predefinedLayouts.push_back(lightDataDescSetLayout);
|
||||||
predefinedLayouts.push_back(cameraDataGlobalLayout);
|
predefinedLayouts.push_back(cameraDataGlobalLayout);
|
||||||
predefinedLayouts.push_back(materialDataPerInstanceLayout);
|
predefinedLayouts.push_back(materialDataPerInstanceLayout);
|
||||||
predefinedLayouts.push_back(fontDataDescSetLayout);
|
predefinedLayouts.push_back(fontDataDescSetLayout);
|
||||||
|
predefinedLayouts.push_back(shadowMapDescLayout);
|
||||||
|
|
||||||
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts = GetPredefinedDescSetLayouts
|
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts = GetPredefinedDescSetLayouts
|
||||||
(
|
(
|
||||||
|
@ -179,7 +195,7 @@ namespace SHADE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsPredefinedData::InitDefaultVertexInputState(void) noexcept
|
void SHGraphicsPredefinedData::InitPredefinedVertexInputState(void) noexcept
|
||||||
{
|
{
|
||||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // positions at binding 0
|
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // positions at binding 0
|
||||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // UVs at binding 1
|
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_2D) }); // UVs at binding 1
|
||||||
|
@ -187,13 +203,16 @@ namespace SHADE
|
||||||
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Tangents at binding 3
|
defaultVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D) }); // Tangents at binding 3
|
||||||
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Transform at binding 4 - 7 (4 slots)
|
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }); // Transform at binding 4 - 7 (4 slots)
|
||||||
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_2D) }); // Instanced integer data at index 8
|
defaultVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::UINT32_2D) }); // Instanced integer data at index 8
|
||||||
|
|
||||||
|
shadowMapVertexInputState.AddBinding(false, false, { SHVertexAttribute(SHAttribFormat::FLOAT_3D)});
|
||||||
|
shadowMapVertexInputState.AddBinding(true, true, { SHVertexAttribute(SHAttribFormat::MAT_4D) }, 4, 4); // Transform at binding 4 - 7 (4 slots)
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsPredefinedData::Init(Handle<SHVkLogicalDevice> logicalDevice) noexcept
|
void SHGraphicsPredefinedData::Init(Handle<SHVkLogicalDevice> logicalDevice) noexcept
|
||||||
{
|
{
|
||||||
perSystemData.resize(SHUtilities::ConvertEnum(SystemType::NUM_TYPES));
|
perSystemData.resize(SHUtilities::ConvertEnum(SystemType::NUM_TYPES));
|
||||||
InitDescSetLayouts(logicalDevice);
|
InitDescSetLayouts(logicalDevice);
|
||||||
InitDefaultVertexInputState();
|
InitPredefinedVertexInputState();
|
||||||
InitDescMappings();
|
InitDescMappings();
|
||||||
InitDummyPipelineLayouts (logicalDevice);
|
InitDummyPipelineLayouts (logicalDevice);
|
||||||
}
|
}
|
||||||
|
@ -217,6 +236,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHVertexInputState const& SHGraphicsPredefinedData::GetShadowMapViState(void) noexcept
|
||||||
|
{
|
||||||
|
return shadowMapVertexInputState;
|
||||||
|
}
|
||||||
|
|
||||||
SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetSystemData(SystemType systemType) noexcept
|
SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetSystemData(SystemType systemType) noexcept
|
||||||
{
|
{
|
||||||
return perSystemData[static_cast<uint32_t>(systemType)];
|
return perSystemData[static_cast<uint32_t>(systemType)];
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace SHADE
|
||||||
CAMERA = 0x04,
|
CAMERA = 0x04,
|
||||||
MATERIALS = 0x08,
|
MATERIALS = 0x08,
|
||||||
FONT = 0x10,
|
FONT = 0x10,
|
||||||
|
SHADOW = 0x20,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SystemType
|
enum class SystemType
|
||||||
|
@ -57,6 +58,9 @@ namespace SHADE
|
||||||
//! Default vertex input state (used by everything).
|
//! Default vertex input state (used by everything).
|
||||||
static SHVertexInputState defaultVertexInputState;
|
static SHVertexInputState defaultVertexInputState;
|
||||||
|
|
||||||
|
//! vertex input state for shadow mapping
|
||||||
|
static SHVertexInputState shadowMapVertexInputState;
|
||||||
|
|
||||||
//! Predefined data for each type of system
|
//! Predefined data for each type of system
|
||||||
static std::vector<PerSystem> perSystemData;
|
static std::vector<PerSystem> perSystemData;
|
||||||
|
|
||||||
|
@ -72,7 +76,7 @@ namespace SHADE
|
||||||
static void InitDescMappings (void) noexcept;
|
static void InitDescMappings (void) noexcept;
|
||||||
static void InitDummyPipelineLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
static void InitDummyPipelineLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||||
static void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
static void InitDescSetLayouts (Handle<SHVkLogicalDevice> logicalDevice) noexcept;
|
||||||
static void InitDefaultVertexInputState (void) noexcept;
|
static void InitPredefinedVertexInputState (void) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -90,6 +94,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
static std::vector<Handle<SHVkDescriptorSetLayout>> GetPredefinedDescSetLayouts (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes types) noexcept;
|
static std::vector<Handle<SHVkDescriptorSetLayout>> GetPredefinedDescSetLayouts (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes types) noexcept;
|
||||||
static SHVertexInputState const& GetDefaultViState (void) noexcept;
|
static SHVertexInputState const& GetDefaultViState (void) noexcept;
|
||||||
|
static SHVertexInputState const& GetShadowMapViState (void) noexcept;
|
||||||
static PerSystem const& GetSystemData (SystemType systemType) noexcept;
|
static PerSystem const& GetSystemData (SystemType systemType) noexcept;
|
||||||
static SHDescriptorMappings::MapType const& GetMappings (SystemType systemType) noexcept;
|
static SHDescriptorMappings::MapType const& GetMappings (SystemType systemType) noexcept;
|
||||||
//static PerSystem const& GetBatchingSystemData(void) noexcept;
|
//static PerSystem const& GetBatchingSystemData(void) noexcept;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace SHADE
|
||||||
CAMERA,
|
CAMERA,
|
||||||
MATERIALS,
|
MATERIALS,
|
||||||
FONT,
|
FONT,
|
||||||
RENDER_GRAPH_RESOURCE,
|
|
||||||
RENDER_GRAPH_NODE_COMPUTE_RESOURCE,
|
RENDER_GRAPH_NODE_COMPUTE_RESOURCE,
|
||||||
|
RENDER_GRAPH_RESOURCE,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,9 +101,13 @@ namespace SHADE
|
||||||
// Register function for subpass
|
// Register function for subpass
|
||||||
//auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers();
|
//auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers();
|
||||||
auto renderGraph = gfxSystem->GetRenderGraph();
|
auto renderGraph = gfxSystem->GetRenderGraph();
|
||||||
auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw");
|
auto subPass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW.data())->GetSubpass("Debug Draw");
|
||||||
subPass->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
subPass->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
|
// Set line width first
|
||||||
|
cmdBuffer->SetLineWidth(LineWidth);
|
||||||
|
|
||||||
|
// Draw
|
||||||
const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
|
const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
|
||||||
cmdBuffer->BeginLabeledSegment("SHDebugDraw (No Depth Test)");
|
cmdBuffer->BeginLabeledSegment("SHDebugDraw (No Depth Test)");
|
||||||
{
|
{
|
||||||
|
@ -125,9 +129,13 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
cmdBuffer->EndLabeledSegment();
|
cmdBuffer->EndLabeledSegment();
|
||||||
});
|
});
|
||||||
auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth");
|
auto subPassWithDepth = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW_DEPTH_PASS.data())->GetSubpass("Debug Draw with Depth");
|
||||||
subPassWithDepth->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
subPassWithDepth->AddExteriorDrawCalls([this](Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHRenderer> renderer, uint32_t frameIndex)
|
||||||
{
|
{
|
||||||
|
// Set line width first
|
||||||
|
cmdBuffer->SetLineWidth(LineWidth);
|
||||||
|
|
||||||
|
// Draw
|
||||||
const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
|
const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex();
|
||||||
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Depth Tested)");
|
cmdBuffer->BeginLabeledSegment("SHDebugDraw (Depth Tested)");
|
||||||
{
|
{
|
||||||
|
@ -506,7 +514,6 @@ namespace SHADE
|
||||||
if (batch.NumPoints[frameIndex] > 0)
|
if (batch.NumPoints[frameIndex] > 0)
|
||||||
{
|
{
|
||||||
cmdBuffer->BindPipeline(batch.Pipeline);
|
cmdBuffer->BindPipeline(batch.Pipeline);
|
||||||
cmdBuffer->SetLineWidth(LineWidth);
|
|
||||||
cmdBuffer->BindVertexBuffer(0, batch.VertexBuffers[frameIndex], 0);
|
cmdBuffer->BindVertexBuffer(0, batch.VertexBuffers[frameIndex], 0);
|
||||||
cmdBuffer->DrawArrays(batch.NumPoints[frameIndex], 1, 0, 0);
|
cmdBuffer->DrawArrays(batch.NumPoints[frameIndex], 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,68 +31,91 @@ namespace SHADE
|
||||||
static constexpr uint32_t EDITOR = 0;
|
static constexpr uint32_t EDITOR = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//struct DescriptorSetIndex
|
struct RenderGraphEntityNames
|
||||||
//{
|
{
|
||||||
// /***************************************************************************/
|
/***************************************************************************/
|
||||||
// /*!
|
/*!
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for static global values like generic data, and
|
|
||||||
// texture samplers
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t STATIC_GLOBALS = 0;
|
|
||||||
// /***************************************************************************/
|
|
||||||
// /*!
|
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for dynamic global values like lights.
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t DYNAMIC_GLOBALS = 1;
|
|
||||||
// /***************************************************************************/
|
|
||||||
// /*!
|
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for high frequency changing global values like
|
|
||||||
// camera matrices.
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t HIGH_FREQUENCY_GLOBALS = 2;
|
|
||||||
// /***************************************************************************/
|
|
||||||
// /*!
|
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for per-instance/material changing values.
|
|
||||||
// */
|
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t PER_INSTANCE = 3;
|
|
||||||
// /***************************************************************************/
|
|
||||||
// /*!
|
|
||||||
// \brief
|
|
||||||
// DescriptorSet Index for render graph resources. Unlike the sets from
|
|
||||||
// 1 to 3 and 6, 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_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 and 6, 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;
|
|
||||||
|
|
||||||
// /***************************************************************************/
|
\brief
|
||||||
// /*!
|
Name of G-Buffer render graph node.
|
||||||
// \brief
|
|
||||||
// To store font data.
|
*/
|
||||||
//
|
/***************************************************************************/
|
||||||
// */
|
static constexpr std::string_view GBUFFER_PASS = "G-Buffer";
|
||||||
// /***************************************************************************/
|
|
||||||
// static constexpr uint32_t FONT_DATA = 4;
|
/***************************************************************************/
|
||||||
//};
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of shadow map render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view SHADOW_MAP_PASS = "Shadow Map Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of deferred composite render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view DEFERRED_COMPOSITE_PASS = "Deferred Comp Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of Debug Draw with Depth render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view DEBUG_DRAW_DEPTH_PASS = "Debug Draw with Depth Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of Debug Draw render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view DEBUG_DRAW = "Debug Draw Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of screen space pass render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view SCREEN_SPACE_PASS = "Screen Space Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of ImGui pass render graph node.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view IMGUI_PASS = "ImGui Pass";
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Name of deferred composite compute.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr std::string_view DEFERRED_COMPOSITE_COMPUTE = "Deferred Composite";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
struct DescriptorSetBindings
|
struct DescriptorSetBindings
|
||||||
{
|
{
|
||||||
|
@ -158,6 +181,16 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
static constexpr uint32_t FONT_MATRIX_DATA = 1;
|
static constexpr uint32_t FONT_MATRIX_DATA = 1;
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Descriptor set binding for shadow map images.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
static constexpr uint32_t SHADOW_MAP_IMAGE_SAMPLER_DATA = 0;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexBufferBindings
|
struct VertexBufferBindings
|
||||||
|
|
|
@ -44,6 +44,9 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/MiddleEnd/TextRendering/SHFreetypeInstance.h"
|
#include "Graphics/MiddleEnd/TextRendering/SHFreetypeInstance.h"
|
||||||
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h"
|
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h"
|
||||||
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
|
#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h"
|
||||||
|
#include "Events/SHEvent.h"
|
||||||
|
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
||||||
|
#include "Input/SHInputManager.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -124,6 +127,13 @@ namespace SHADE
|
||||||
|
|
||||||
SHFreetypeInstance::Init();
|
SHFreetypeInstance::Init();
|
||||||
|
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/DeferredComposite_CS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/SSAO_CS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/SSAOBlur_CS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/PureCopy_CS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_VS.glsl", false);
|
||||||
|
SHAssetManager::CompileAsset("../../Assets/Shaders/TestCube_FS.glsl", false);
|
||||||
|
|
||||||
// Load Built In Shaders
|
// Load Built In Shaders
|
||||||
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
|
static constexpr AssetID VS_DEFAULT = 39210065; defaultVertShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(VS_DEFAULT);
|
||||||
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
|
static constexpr AssetID FS_DEFAULT = 46377769; defaultFragShader = SHResourceManager::LoadOrGet<SHVkShaderModule>(FS_DEFAULT);
|
||||||
|
@ -137,6 +147,8 @@ namespace SHADE
|
||||||
static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_FS);
|
static constexpr AssetID TEXT_FS = 38024754; textFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(TEXT_FS);
|
||||||
static constexpr AssetID RENDER_SC_VS = 48082949; renderToSwapchainVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_VS);
|
static constexpr AssetID RENDER_SC_VS = 48082949; renderToSwapchainVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_VS);
|
||||||
static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_FS);
|
static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet<SHVkShaderModule>(RENDER_SC_FS);
|
||||||
|
static constexpr AssetID SHADOW_MAP_VS = 44646107; shadowMapVS = SHResourceManager::LoadOrGet<SHVkShaderModule>(SHADOW_MAP_VS);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::InitRenderGraph(void) noexcept
|
void SHGraphicsSystem::InitRenderGraph(void) noexcept
|
||||||
|
@ -169,6 +181,8 @@ namespace SHADE
|
||||||
// Create Default Viewport
|
// Create Default Viewport
|
||||||
worldViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f));
|
worldViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f));
|
||||||
|
|
||||||
|
shadowMapViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(SHLightingSubSystem::SHADOW_MAP_WIDTH), static_cast<float>(SHLightingSubSystem::SHADOW_MAP_HEIGHT), 0.0f, 1.0f));
|
||||||
|
|
||||||
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{ swapchain->GetNumImages() };
|
std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{ swapchain->GetNumImages() };
|
||||||
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
|
for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -183,22 +197,24 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
// Initialize world render graph
|
// Initialize world render graph
|
||||||
renderGraph->Init("World Render Graph", device, swapchain, &resourceManager, renderContextCmdPools);
|
renderGraph->Init("World Render Graph", device, swapchain, &resourceManager, renderContextCmdPools);
|
||||||
renderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
renderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
||||||
renderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
renderGraph->AddResource("Position World Space", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
||||||
|
renderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
||||||
//worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
//worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
|
||||||
renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second);
|
renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second);
|
||||||
renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, true, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
|
||||||
renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||||
renderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
renderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
|
||||||
renderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, windowDims.first, windowDims.second);
|
renderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second);
|
||||||
renderGraph->AddResource("SSAO", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
renderGraph->AddResource("SSAO", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
||||||
renderGraph->AddResource("SSAO Blur", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
renderGraph->AddResource("SSAO Blur", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR8Unorm);
|
||||||
renderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
|
renderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, true, windowDims.first, windowDims.second);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* MAIN NODE */
|
/* MAIN NODE */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
auto gBufferNode = renderGraph->AddNode("G-Buffer",
|
auto gBufferNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data(),
|
||||||
|
//auto gBufferNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphNodeNames::GBUFFER_PASS.data()
|
||||||
{
|
{
|
||||||
"Position",
|
"Position",
|
||||||
"Entity ID",
|
"Entity ID",
|
||||||
|
@ -207,7 +223,8 @@ namespace SHADE
|
||||||
"Albedo",
|
"Albedo",
|
||||||
"Depth Buffer",
|
"Depth Buffer",
|
||||||
"SSAO",
|
"SSAO",
|
||||||
"SSAO Blur"
|
"SSAO Blur",
|
||||||
|
"Position World Space"
|
||||||
},
|
},
|
||||||
{}); // no predecessors
|
{}); // no predecessors
|
||||||
|
|
||||||
|
@ -220,6 +237,7 @@ namespace SHADE
|
||||||
gBufferSubpass->AddColorOutput("Light Layer Indices");
|
gBufferSubpass->AddColorOutput("Light Layer Indices");
|
||||||
gBufferSubpass->AddColorOutput("Normals");
|
gBufferSubpass->AddColorOutput("Normals");
|
||||||
gBufferSubpass->AddColorOutput("Albedo");
|
gBufferSubpass->AddColorOutput("Albedo");
|
||||||
|
gBufferSubpass->AddColorOutput("Position World Space");
|
||||||
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL);
|
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL);
|
||||||
|
|
||||||
|
|
||||||
|
@ -254,53 +272,52 @@ namespace SHADE
|
||||||
// Add another pass to blur SSAO
|
// Add another pass to blur SSAO
|
||||||
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute("SSAO Blur Step", ssaoBlurShader, { "SSAO", "SSAO Blur" });
|
Handle<SHRenderGraphNodeCompute> ssaoBlurPass = gBufferNode->AddNodeCompute("SSAO Blur Step", ssaoBlurShader, { "SSAO", "SSAO Blur" });
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* SHADOW MAP PASS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
// Shadow map pass will have no resources bound at first. Lighting system will add resources to the node.
|
|
||||||
// It will initially also not have any subpasses since they will be added for each light that casts shadows.
|
|
||||||
//auto shadowMapPass = renderGraph->AddNode("Shadow Map Pass", {}, {});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* DEFERRED COMPOSITE NODE */
|
/* DEFERRED COMPOSITE NODE */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
// This pass will facilitate both lighting and shadows in 1 single pass.
|
// This pass will facilitate both lighting and shadows in 1 single pass.
|
||||||
auto deferredCompositeNode = renderGraph->AddNode("Deferred Comp Pass",
|
auto deferredCompositeNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data(),
|
||||||
{
|
{
|
||||||
"Position",
|
"Position",
|
||||||
"Light Layer Indices",
|
"Light Layer Indices",
|
||||||
"Normals",
|
"Normals",
|
||||||
"Albedo",
|
"Albedo",
|
||||||
"Scene",
|
"Scene",
|
||||||
"SSAO Blur"
|
"SSAO Blur",
|
||||||
|
"Position World Space"
|
||||||
},
|
},
|
||||||
{"G-Buffer"});
|
{ SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS .data()});
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* DEFERRED COMPOSITE SUBPASS INIT */
|
/* DEFERRED COMPOSITE SUBPASS INIT */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
deferredCompositeNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" });
|
auto deferredCompositeCompute = deferredCompositeNode->AddNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data(), deferredCompositeShader, {"Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Position World Space", "Scene"}, {}, SHLightingSubSystem::MAX_SHADOWS);
|
||||||
|
deferredCompositeCompute->AddPreComputeFunction([=](Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex)
|
||||||
|
{
|
||||||
|
lightingSubSystem->PrepareShadowMapsForRead(cmdBuffer);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* DEBUG DRAW PASS INIT */
|
/* DEBUG DRAW PASS INIT */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
// Set up Debug Draw Passes
|
// Set up Debug Draw Passes
|
||||||
// - Depth Tested
|
// - Depth Tested
|
||||||
auto debugDrawNodeDepth = renderGraph->AddNode("Debug Draw with Depth", { "Scene", "Depth Buffer" }, {"G-Buffer", "Deferred Comp Pass"});
|
auto debugDrawNodeDepth = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW_DEPTH_PASS.data(), {"Scene", "Depth Buffer"}, {SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data(), SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data()});
|
||||||
auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth", worldViewport, worldRenderer);
|
auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth", worldViewport, worldRenderer);
|
||||||
debugDrawDepthSubpass->AddColorOutput("Scene");
|
debugDrawDepthSubpass->AddColorOutput("Scene");
|
||||||
debugDrawDepthSubpass->AddDepthOutput("Depth Buffer");
|
debugDrawDepthSubpass->AddDepthOutput("Depth Buffer");
|
||||||
// - No Depth Test
|
// - No Depth Test
|
||||||
auto debugDrawNode = renderGraph->AddNode("Debug Draw", { "Scene" }, { "Debug Draw with Depth" });
|
auto debugDrawNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW.data(), {"Scene"}, {SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW_DEPTH_PASS.data()});
|
||||||
auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw", worldViewport, worldRenderer);
|
auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw", worldViewport, worldRenderer);
|
||||||
debugDrawSubpass->AddColorOutput("Scene");
|
debugDrawSubpass->AddColorOutput("Scene");
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SCREEN SPACE PASS */
|
/* SCREEN SPACE PASS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
auto screenSpaceNode = renderGraph->AddNode("Screen Space Pass", { "Scene", "Entity ID" }, {"Deferred Comp Pass", "G-Buffer", "Debug Draw" });
|
auto screenSpaceNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS.data(), {"Scene", "Entity ID"}, {SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data(), SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data(), SHGraphicsConstants::RenderGraphEntityNames::DEBUG_DRAW.data()});
|
||||||
auto uiSubpass = screenSpaceNode->AddSubpass("UI", worldViewport, screenRenderer);
|
auto uiSubpass = screenSpaceNode->AddSubpass("UI", worldViewport, screenRenderer);
|
||||||
uiSubpass->AddColorOutput("Scene");
|
uiSubpass->AddColorOutput("Scene");
|
||||||
uiSubpass->AddColorOutput("Entity ID");
|
uiSubpass->AddColorOutput("Entity ID");
|
||||||
|
@ -315,16 +332,16 @@ namespace SHADE
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
{
|
{
|
||||||
// Dummy Node to transition scene render graph resource
|
// Dummy Node to transition scene render graph resource
|
||||||
auto dummyNode = renderGraph->AddNode("Dummy Pass", { "Scene" }, { "Screen Space Pass" });
|
auto dummyNode = renderGraph->AddNode("Dummy Pass", { "Scene" }, { SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS .data()});
|
||||||
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass", {}, {});
|
auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass", {}, {});
|
||||||
dummySubpass->AddInput("Scene");
|
dummySubpass->AddInput("Scene");
|
||||||
|
|
||||||
auto imGuiNode = renderGraph->AddNode("ImGui Node", { "Present" }, {});
|
auto imGuiNode = renderGraph->AddNode(SHGraphicsConstants::RenderGraphEntityNames::IMGUI_PASS.data(), {"Present"}, {});
|
||||||
auto imGuiSubpass = imGuiNode->AddSubpass("ImGui Draw", {}, {});
|
auto imGuiSubpass = imGuiNode->AddSubpass("ImGui Draw", {}, {});
|
||||||
imGuiSubpass->AddColorOutput("Present");
|
imGuiSubpass->AddColorOutput("Present");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
renderGraph->AddRenderToSwapchainNode("Scene", "Present", { "Screen Space Pass" }, { renderToSwapchainVS, renderToSwapchainFS });
|
renderGraph->AddRenderToSwapchainNode("Scene", "Present", { SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS .data()}, {renderToSwapchainVS, renderToSwapchainFS});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -393,12 +410,16 @@ namespace SHADE
|
||||||
postOffscreenRenderSubSystem->Init(device, renderGraph->GetRenderGraphResource("Scene"), descPool);
|
postOffscreenRenderSubSystem->Init(device, renderGraph->GetRenderGraphResource("Scene"), descPool);
|
||||||
|
|
||||||
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
|
lightingSubSystem = resourceManager.Create<SHLightingSubSystem>();
|
||||||
lightingSubSystem->Init(device, descPool);
|
lightingSubSystem->Init(device, descPool, &resourceManager, samplerCache.GetSampler (device, SHVkSamplerParams
|
||||||
|
{
|
||||||
|
.addressMode = vk::SamplerAddressMode::eClampToBorder,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
textRenderingSubSystem = resourceManager.Create<SHTextRenderingSubSystem>();
|
textRenderingSubSystem = resourceManager.Create<SHTextRenderingSubSystem>();
|
||||||
|
|
||||||
// initialize the text renderer
|
// initialize the text renderer
|
||||||
auto uiNode = renderGraph->GetNode("Screen Space Pass");
|
auto uiNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SCREEN_SPACE_PASS.data());
|
||||||
textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass("UI"), descPool, textVS, textFS);
|
textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass("UI"), descPool, textVS, textFS);
|
||||||
|
|
||||||
SHGlobalDescriptorSets::SetLightingSubSystem(lightingSubSystem);
|
SHGlobalDescriptorSets::SetLightingSubSystem(lightingSubSystem);
|
||||||
|
@ -426,7 +447,7 @@ namespace SHADE
|
||||||
defaultMaterial = AddMaterial
|
defaultMaterial = AddMaterial
|
||||||
(
|
(
|
||||||
defaultVertShader, defaultFragShader,
|
defaultVertShader, defaultFragShader,
|
||||||
renderGraph->GetNode("G-Buffer")->GetSubpass("G-Buffer Write")
|
renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass("G-Buffer Write")
|
||||||
);
|
);
|
||||||
defaultMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex);
|
defaultMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex);
|
||||||
}
|
}
|
||||||
|
@ -451,6 +472,7 @@ namespace SHADE
|
||||||
InitMiddleEnd();
|
InitMiddleEnd();
|
||||||
InitSubsystems();
|
InitSubsystems();
|
||||||
InitBuiltInResources();
|
InitBuiltInResources();
|
||||||
|
InitEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHGraphicsSystem::Exit(void)
|
void SHGraphicsSystem::Exit(void)
|
||||||
|
@ -546,6 +568,15 @@ namespace SHADE
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::B))
|
||||||
|
{
|
||||||
|
auto& lightComps = SHComponentManager::GetDense<SHLightComponent>();
|
||||||
|
for (auto& comp : lightComps)
|
||||||
|
{
|
||||||
|
comp.SetEnableShadow(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
renderGraph->Begin(frameIndex);
|
renderGraph->Begin(frameIndex);
|
||||||
auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex);
|
auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex);
|
||||||
|
|
||||||
|
@ -726,16 +757,61 @@ namespace SHADE
|
||||||
renderers.erase(iter);
|
renderers.erase(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHEventHandle SHGraphicsSystem::ReceiveLightEnableShadowEvent(SHEventPtr event) noexcept
|
SHEventHandle SHGraphicsSystem::ReceiveLightEnableShadowEvent(SHEventPtr eventPtr) noexcept
|
||||||
{
|
{
|
||||||
|
// we need to wait for the device to finish using the graph first
|
||||||
|
device->WaitIdle();
|
||||||
|
|
||||||
|
auto const& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHLightEnableShadowEvent>*>(eventPtr.get())->data;
|
||||||
|
auto* lightComp = SHComponentManager::GetComponent<SHLightComponent>(EVENT_DATA->lightEntity);
|
||||||
|
std::string resourceName = "ShadowMap " + std::to_string(EVENT_DATA->lightEntity);
|
||||||
|
Handle<SHSubpass> companionSubpass = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data())->GetSubpass("G-Buffer Write");
|
||||||
|
|
||||||
|
if (EVENT_DATA->generateRenderer)
|
||||||
|
{
|
||||||
|
// Create new renderer for the light component and give it to the light component
|
||||||
|
Handle<SHRenderer> newRenderer = resourceManager.Create<SHRenderer>(device, swapchain->GetNumImages(), descPool, SHRenderer::PROJECTION_TYPE::ORTHOGRAPHIC);
|
||||||
|
lightComp->SetRenderer (newRenderer);
|
||||||
|
|
||||||
|
// assign shadow map index to light component
|
||||||
|
lightComp->SetShadowMapIndex (lightingSubSystem->GetNumShadowMaps());
|
||||||
|
}
|
||||||
|
|
||||||
// Add the shadow map resource to the graph
|
// Add the shadow map resource to the graph
|
||||||
|
renderGraph->AddResource(resourceName, {SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT}, false, SHLightingSubSystem::SHADOW_MAP_WIDTH, SHLightingSubSystem::SHADOW_MAP_HEIGHT, vk::Format::eD32Sfloat);
|
||||||
|
|
||||||
// link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer.
|
// link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer.
|
||||||
|
auto shadowMapNode = renderGraph->AddNodeAfter(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data() + resourceName, {resourceName.c_str()}, SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data());
|
||||||
|
|
||||||
// Add a subpass to render to that shadow map
|
// Add a subpass to render to that shadow map
|
||||||
|
auto newSubpass = shadowMapNode->RuntimeAddSubpass(resourceName + " Subpass", shadowMapViewport, lightComp->GetRenderer());
|
||||||
|
newSubpass->AddDepthOutput(resourceName, SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH);
|
||||||
|
|
||||||
//renderGraph->GetNode ();
|
// regenerate the node
|
||||||
return event->handle;
|
shadowMapNode->RuntimeStandaloneRegenerate();
|
||||||
|
|
||||||
|
// Create pipeline from new renderpass and subpass if it's not created yet
|
||||||
|
if (!shadowMapPipeline)
|
||||||
|
{
|
||||||
|
SHPipelineLibrary tempLibrary{};
|
||||||
|
Handle<SHRenderGraphNode> rgNode = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::SHADOW_MAP_PASS.data());
|
||||||
|
|
||||||
|
SHRasterizationState rasterState{};
|
||||||
|
rasterState.cull_mode = vk::CullModeFlagBits::eBack;
|
||||||
|
|
||||||
|
tempLibrary.Init(device);
|
||||||
|
tempLibrary.CreateGraphicsPipelines({ shadowMapVS, {} }, shadowMapNode->GetRenderpass(), newSubpass, SHGraphicsPredefinedData::GetShadowMapViState(), rasterState);
|
||||||
|
shadowMapPipeline = tempLibrary.GetGraphicsPipeline({ shadowMapVS, {} });
|
||||||
|
}
|
||||||
|
newSubpass->SetCompanionSubpass(companionSubpass, shadowMapPipeline); // set companion subpass and pipeline
|
||||||
|
|
||||||
|
// add the shadow map to the lighting system
|
||||||
|
uint32_t const NEW_SHADOW_MAP_INDEX = lightingSubSystem->AddShadowMap(renderGraph->GetRenderGraphResource(resourceName), EVENT_DATA->lightEntity);
|
||||||
|
|
||||||
|
auto nodeCompute = renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data());
|
||||||
|
nodeCompute->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, lightingSubSystem->GetViewSamplerLayout(NEW_SHADOW_MAP_INDEX), NEW_SHADOW_MAP_INDEX);
|
||||||
|
|
||||||
|
return eventPtr->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHMaterial> SHGraphicsSystem::AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass)
|
Handle<SHMaterial> SHGraphicsSystem::AddMaterial(Handle<SHVkShaderModule> vertShader, Handle<SHVkShaderModule> fragShader, Handle<SHSubpass> subpass)
|
||||||
|
@ -1047,6 +1123,7 @@ namespace SHADE
|
||||||
|
|
||||||
mousePickSubSystem->HandleResize();
|
mousePickSubSystem->HandleResize();
|
||||||
postOffscreenRenderSubSystem->HandleResize();
|
postOffscreenRenderSubSystem->HandleResize();
|
||||||
|
//lightingSubSystem->HandleResize(renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_PASS.data())->GetNodeCompute(SHGraphicsConstants::RenderGraphEntityNames::DEFERRED_COMPOSITE_COMPUTE.data()));
|
||||||
|
|
||||||
worldViewport->SetWidth(static_cast<float>(resizeWidth));
|
worldViewport->SetWidth(static_cast<float>(resizeWidth));
|
||||||
worldViewport->SetHeight(static_cast<float>(resizeHeight));
|
worldViewport->SetHeight(static_cast<float>(resizeHeight));
|
||||||
|
@ -1079,7 +1156,7 @@ namespace SHADE
|
||||||
|
|
||||||
Handle<SHRenderGraphNode> SHGraphicsSystem::GetPrimaryRenderpass() const noexcept
|
Handle<SHRenderGraphNode> SHGraphicsSystem::GetPrimaryRenderpass() const noexcept
|
||||||
{
|
{
|
||||||
return renderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data());
|
return renderGraph->GetNode(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_PASS.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkPipeline> SHGraphicsSystem::GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept
|
Handle<SHVkPipeline> SHGraphicsSystem::GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept
|
||||||
|
|
|
@ -178,7 +178,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* Light functions */
|
/* Light functions */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHEventHandle ReceiveLightEnableShadowEvent (SHEventPtr event) noexcept;
|
SHEventHandle ReceiveLightEnableShadowEvent (SHEventPtr eventPtr) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Material Functions */
|
/* Material Functions */
|
||||||
|
@ -406,10 +406,6 @@ namespace SHADE
|
||||||
SHWindow* GetWindow() noexcept { return window; }
|
SHWindow* GetWindow() noexcept { return window; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
|
||||||
/* Constants */
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
|
||||||
static constexpr std::string_view G_BUFFER_RENDER_GRAPH_NODE_NAME = "G-Buffer";
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
|
@ -446,6 +442,7 @@ namespace SHADE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Handle<SHViewport> worldViewport; // Whole screen
|
Handle<SHViewport> worldViewport; // Whole screen
|
||||||
|
Handle<SHViewport> shadowMapViewport;
|
||||||
std::vector<Handle<SHViewport>> viewports; // Additional viewports
|
std::vector<Handle<SHViewport>> viewports; // Additional viewports
|
||||||
|
|
||||||
// Renderers
|
// Renderers
|
||||||
|
@ -469,6 +466,7 @@ namespace SHADE
|
||||||
Handle<SHVkShaderModule> textFS;
|
Handle<SHVkShaderModule> textFS;
|
||||||
Handle<SHVkShaderModule> renderToSwapchainVS;
|
Handle<SHVkShaderModule> renderToSwapchainVS;
|
||||||
Handle<SHVkShaderModule> renderToSwapchainFS;
|
Handle<SHVkShaderModule> renderToSwapchainFS;
|
||||||
|
Handle<SHVkShaderModule> shadowMapVS;
|
||||||
|
|
||||||
// Fonts
|
// Fonts
|
||||||
Handle<SHFont> testFont;
|
Handle<SHFont> testFont;
|
||||||
|
@ -483,6 +481,7 @@ namespace SHADE
|
||||||
Handle<SHVkPipeline> debugDrawWireMeshDepthPipeline;
|
Handle<SHVkPipeline> debugDrawWireMeshDepthPipeline;
|
||||||
Handle<SHVkPipeline> debugDrawFilledPipeline;
|
Handle<SHVkPipeline> debugDrawFilledPipeline;
|
||||||
Handle<SHVkPipeline> debugDrawFilledDepthPipeline;
|
Handle<SHVkPipeline> debugDrawFilledDepthPipeline;
|
||||||
|
Handle<SHVkPipeline> shadowMapPipeline; // initialized only when a shadow map is needed
|
||||||
|
|
||||||
// Built-In Textures
|
// Built-In Textures
|
||||||
Handle<SHTexture> defaultTexture;
|
Handle<SHTexture> defaultTexture;
|
||||||
|
|
|
@ -122,4 +122,9 @@ namespace SHADE
|
||||||
return cameraDirector;
|
return cameraDirector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHShaderCameraData SHRenderer::GetCPUCameraData(void) const noexcept
|
||||||
|
{
|
||||||
|
return cpuCameraData;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "SHCamera.h"
|
#include "SHCamera.h"
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#include "Graphics/RenderGraph/SHRenderGraph.h"
|
|
||||||
#include "Math/SHMath.h"
|
#include "Math/SHMath.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "Graphics/Pipeline/SHPipelineType.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -93,6 +93,7 @@ namespace SHADE
|
||||||
/* Setters and Getters */
|
/* Setters and Getters */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHCameraDirector> GetCameraDirector (void) const noexcept;
|
Handle<SHCameraDirector> GetCameraDirector (void) const noexcept;
|
||||||
|
SHShaderCameraData GetCPUCameraData (void) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "SHLightComponent.h"
|
#include "SHLightComponent.h"
|
||||||
#include "Graphics/Events/SHGraphicsEvents.h"
|
#include "Graphics/Events/SHGraphicsEvents.h"
|
||||||
#include "Events/SHEventManager.hpp"
|
#include "Events/SHEventManager.hpp"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -14,6 +15,7 @@ namespace SHADE
|
||||||
//indexInBuffer = std::numeric_limits<uint32_t>::max();
|
//indexInBuffer = std::numeric_limits<uint32_t>::max();
|
||||||
isActive = true;
|
isActive = true;
|
||||||
//Unbind();
|
//Unbind();
|
||||||
|
renderer = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,11 +118,22 @@ namespace SHADE
|
||||||
// Create new event and broadcast it
|
// Create new event and broadcast it
|
||||||
SHLightEnableShadowEvent newEvent;
|
SHLightEnableShadowEvent newEvent;
|
||||||
newEvent.lightEntity = GetEID();
|
newEvent.lightEntity = GetEID();
|
||||||
|
newEvent.generateRenderer = static_cast<bool>(!renderer);
|
||||||
|
|
||||||
SHEventManager::BroadcastEvent<SHLightEnableShadowEvent>(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT);
|
SHEventManager::BroadcastEvent<SHLightEnableShadowEvent>(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHLightComponent::SetRenderer(Handle<SHRenderer> newRenderer) noexcept
|
||||||
|
{
|
||||||
|
renderer = newRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHLightComponent::SetShadowMapIndex(uint32_t index) noexcept
|
||||||
|
{
|
||||||
|
lightData.shadowMapIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
SHLightData const& SHLightComponent::GetLightData(void) const noexcept
|
SHLightData const& SHLightComponent::GetLightData(void) const noexcept
|
||||||
{
|
{
|
||||||
return lightData;
|
return lightData;
|
||||||
|
@ -172,6 +185,11 @@ namespace SHADE
|
||||||
return lightData.strength;
|
return lightData.strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHRenderer> SHLightComponent::GetRenderer(void) const noexcept
|
||||||
|
{
|
||||||
|
return renderer;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RTTR_REGISTRATION
|
RTTR_REGISTRATION
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
#include <rttr/registration>
|
#include <rttr/registration>
|
||||||
#include "ECS_Base/Components/SHComponent.h"
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
#include "SHLightData.h"
|
#include "SHLightData.h"
|
||||||
|
#include "Resource/SHHandle.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
class SHRenderer;
|
||||||
|
|
||||||
class SH_API SHLightComponent final : public SHComponent
|
class SH_API SHLightComponent final : public SHComponent
|
||||||
{
|
{
|
||||||
|
@ -14,6 +16,9 @@ namespace SHADE
|
||||||
//! GPU depends on the type of the light.
|
//! GPU depends on the type of the light.
|
||||||
SHLightData lightData;
|
SHLightData lightData;
|
||||||
|
|
||||||
|
//! Renderer to calculate light world to projection matrix
|
||||||
|
Handle<SHRenderer> renderer;
|
||||||
|
|
||||||
//! Since the lighting system is gonna be self contained and light weight, we store this
|
//! Since the lighting system is gonna be self contained and light weight, we store this
|
||||||
//! so that we only write this to the CPU buffer when this light component change, we don't
|
//! so that we only write this to the CPU buffer when this light component change, we don't
|
||||||
//! rewrite everything. However we still write to the GPU buffer when everything changes.
|
//! rewrite everything. However we still write to the GPU buffer when everything changes.
|
||||||
|
@ -49,6 +54,8 @@ namespace SHADE
|
||||||
//void SetBound (uint32_t inIndexInBuffer) noexcept;
|
//void SetBound (uint32_t inIndexInBuffer) noexcept;
|
||||||
void SetStrength (float value) noexcept; // serialized
|
void SetStrength (float value) noexcept; // serialized
|
||||||
void SetEnableShadow (bool flag) noexcept;
|
void SetEnableShadow (bool flag) noexcept;
|
||||||
|
void SetRenderer (Handle<SHRenderer> newRenderer) noexcept;
|
||||||
|
void SetShadowMapIndex (uint32_t index) noexcept;
|
||||||
|
|
||||||
|
|
||||||
SHLightData const& GetLightData (void) const noexcept;
|
SHLightData const& GetLightData (void) const noexcept;
|
||||||
|
@ -61,6 +68,7 @@ namespace SHADE
|
||||||
//bool GetBound (void) const noexcept;
|
//bool GetBound (void) const noexcept;
|
||||||
//uint32_t GetIndexInBuffer (void) const noexcept;
|
//uint32_t GetIndexInBuffer (void) const noexcept;
|
||||||
float GetStrength (void) const noexcept;
|
float GetStrength (void) const noexcept;
|
||||||
|
Handle<SHRenderer> GetRenderer (void) const noexcept;
|
||||||
RTTR_ENABLE()
|
RTTR_ENABLE()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,13 @@
|
||||||
#include "SHLightComponent.h"
|
#include "SHLightComponent.h"
|
||||||
#include "Math/Vector/SHVec4.h"
|
#include "Math/Vector/SHVec4.h"
|
||||||
#include "Math/SHMatrix.h"
|
#include "Math/SHMatrix.h"
|
||||||
|
#include "Graphics/Images/SHVkImageView.h"
|
||||||
|
#include "Graphics/MiddleEnd/Textures/SHVkSamplerCache.h"
|
||||||
|
#include "Graphics/Images/SHVkSampler.h"
|
||||||
|
#include "Graphics/Events/SHGraphicsEvents.h"
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHRenderer.h"
|
||||||
|
#include "Math/Transform/SHTransformComponent.h"
|
||||||
|
#include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -50,6 +57,19 @@ namespace SHADE
|
||||||
//lightPtr->direction = lightData.direction;
|
//lightPtr->direction = lightData.direction;
|
||||||
lightPtr->diffuseColor = lightData.color;
|
lightPtr->diffuseColor = lightData.color;
|
||||||
lightPtr->active = lightComp->isActive;
|
lightPtr->active = lightComp->isActive;
|
||||||
|
|
||||||
|
// write view projection matrix if renderer is available
|
||||||
|
auto lightRenderer = lightComp->GetRenderer();
|
||||||
|
if (lightRenderer)
|
||||||
|
{
|
||||||
|
lightPtr->pvMatrix = lightRenderer->GetCPUCameraData().viewProjectionMatrix;
|
||||||
|
|
||||||
|
// Boolean to cast shadows in first 8 bits (1 byte)
|
||||||
|
lightPtr->shadowData = lightData.castShadows;
|
||||||
|
|
||||||
|
// Next 24 bits for shadow map index
|
||||||
|
lightPtr->shadowData |= (lightData.shadowMapIndex << 8);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SH_LIGHT_TYPE::POINT:
|
case SH_LIGHT_TYPE::POINT:
|
||||||
|
@ -365,6 +385,32 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHLightingSubSystem::UpdateShadowMapDesc(void) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SHMatrix SHLightingSubSystem::GetViewMatrix(SHLightComponent* lightComp) noexcept
|
||||||
|
{
|
||||||
|
switch (lightComp->GetLightData().type)
|
||||||
|
{
|
||||||
|
case SH_LIGHT_TYPE::DIRECTIONAL:
|
||||||
|
return SHMatrix::Transpose(SHMatrix::LookAtLH(lightComp->GetLightData().position, SHVec3::Normalise (lightComp->GetLightData().direction), SHVec3(0.0f, -1.0f, 0.0f)));
|
||||||
|
//return SHMatrix::Transpose(SHMatrix::LookAtLH(/*lightComp->GetLightData().position*/SHVec3(1.27862f, 4.78952f, 4.12811f), SHVec3(-0.280564f, -0.66262f, -0.69422f), SHVec3(0.0f, -1.0f, 0.0f)));
|
||||||
|
case SH_LIGHT_TYPE::POINT:
|
||||||
|
return {};
|
||||||
|
case SH_LIGHT_TYPE::SPOT:
|
||||||
|
return {};
|
||||||
|
case SH_LIGHT_TYPE::AMBIENT:
|
||||||
|
return {};
|
||||||
|
case SH_LIGHT_TYPE::NUM_TYPES:
|
||||||
|
return {};
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -375,13 +421,15 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHLightingSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool) noexcept
|
void SHLightingSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, SHResourceHub* rh, Handle<SHVkSampler> inShadowMapSampler) noexcept
|
||||||
{
|
{
|
||||||
SHComponentManager::CreateComponentSparseSet<SHLightComponent>();
|
SHComponentManager::CreateComponentSparseSet<SHLightComponent>();
|
||||||
|
|
||||||
logicalDevice = device;
|
logicalDevice = device;
|
||||||
|
resourceHub = rh;
|
||||||
uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES);
|
uint32_t constexpr NUM_LIGHT_TYPES = SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES);
|
||||||
|
|
||||||
|
#pragma region LIGHTING
|
||||||
std::vector<uint32_t> variableSizes{ NUM_LIGHT_TYPES };
|
std::vector<uint32_t> variableSizes{ NUM_LIGHT_TYPES };
|
||||||
std::fill (variableSizes.begin(), variableSizes.end(), 1);
|
std::fill (variableSizes.begin(), variableSizes.end(), 1);
|
||||||
|
|
||||||
|
@ -418,7 +466,22 @@ namespace SHADE
|
||||||
dynamicOffsets[i].resize(NUM_LIGHT_TYPES + 1); // +1 for the count
|
dynamicOffsets[i].resize(NUM_LIGHT_TYPES + 1); // +1 for the count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region SHADOWS
|
||||||
|
//std::vector<uint32_t> shadowDescVariableSizes{ MAX_SHADOWS };
|
||||||
|
//shadowMapDescriptorSet = descPool->Allocate({SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::SHADOW)}, shadowDescVariableSizes);
|
||||||
|
|
||||||
|
//#ifdef _DEBUG
|
||||||
|
// const auto& SHADOW_MAP_DESC_SETS = shadowMapDescriptorSet->GetVkHandle();
|
||||||
|
// for (int i = 0; i < static_cast<int>(SHADOW_MAP_DESC_SETS.size()); ++i)
|
||||||
|
// SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSet, SHADOW_MAP_DESC_SETS[i], "[Descriptor Set] Shadow Map Data Frame #" + std::to_string(i));
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
shadowMapSampler = inShadowMapSampler;
|
||||||
|
shadowMaps.clear();
|
||||||
//numLightComponents = 0;
|
//numLightComponents = 0;
|
||||||
|
#pragma endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -452,6 +515,12 @@ namespace SHADE
|
||||||
|
|
||||||
for (auto& light : lightComps)
|
for (auto& light : lightComps)
|
||||||
{
|
{
|
||||||
|
if (auto renderer = light.GetRenderer())
|
||||||
|
{
|
||||||
|
//SHMatrix orthoMatrix = SHMatrix::OrthographicRH()
|
||||||
|
renderer->UpdateDataManual(frameIndex, GetViewMatrix(&light), SHMatrix::OrthographicLH(10.0f, 10.0f, 1.0f, 50.0f));
|
||||||
|
}
|
||||||
|
|
||||||
auto enumValue = SHUtilities::ConvertEnum(light.GetLightData().type);
|
auto enumValue = SHUtilities::ConvertEnum(light.GetLightData().type);
|
||||||
|
|
||||||
// First we want to make sure the light is already bound to the system. if it
|
// First we want to make sure the light is already bound to the system. if it
|
||||||
|
@ -503,7 +572,6 @@ namespace SHADE
|
||||||
// so we do it anyway. #NoteToSelf: if at any point it affects performance, do a check before computing.
|
// so we do it anyway. #NoteToSelf: if at any point it affects performance, do a check before computing.
|
||||||
ComputeDynamicOffsets();
|
ComputeDynamicOffsets();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -526,9 +594,101 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SHLightingSubSystem::AddShadowMap(Handle<SHRenderGraphResource> newShadowMap, EntityID lightEntity) noexcept
|
||||||
|
{
|
||||||
|
// Add to container of shadow maps
|
||||||
|
shadowMapIndexing.emplace(lightEntity, static_cast<uint32_t> (shadowMaps.size()));
|
||||||
|
shadowMaps.emplace_back(newShadowMap);
|
||||||
|
|
||||||
|
// Just use the image view stored in the resource
|
||||||
|
Handle<SHVkImageView> const NEW_IMAGE_VIEW = newShadowMap->GetImageView();
|
||||||
|
|
||||||
|
// Prepare to write to descriptor
|
||||||
|
shadowMapImageSamplers.emplace_back(NEW_IMAGE_VIEW, shadowMapSampler, vk::ImageLayout::eShaderReadOnlyOptimal);
|
||||||
|
|
||||||
|
// Update descriptor set
|
||||||
|
//static constexpr uint32_t SHADOW_MAP_DESC_SET_INDEX = 0;
|
||||||
|
//uint32_t const SHADOW_MAP_DESC_ARRAY_INDEX = static_cast<uint32_t>(shadowMapImageSamplers.size()) - 1u;
|
||||||
|
//shadowMapDescriptorSet->ModifyWriteDescImage
|
||||||
|
//(
|
||||||
|
// SHADOW_MAP_DESC_SET_INDEX,
|
||||||
|
// SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA,
|
||||||
|
// shadowMapImageSamplers[SHADOW_MAP_DESC_ARRAY_INDEX],
|
||||||
|
// SHADOW_MAP_DESC_ARRAY_INDEX
|
||||||
|
//);
|
||||||
|
|
||||||
|
//// TODO: Definitely can be optimized by writing a function that modifies a specific descriptor in the array
|
||||||
|
//shadowMapDescriptorSet->UpdateDescriptorSetImages
|
||||||
|
//(
|
||||||
|
// SHADOW_MAP_DESC_SET_INDEX,
|
||||||
|
// SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA
|
||||||
|
//);
|
||||||
|
|
||||||
|
// add to barriers
|
||||||
|
shadowMapMemoryBarriers.push_back (vk::ImageMemoryBarrier
|
||||||
|
{
|
||||||
|
.srcAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentWrite,
|
||||||
|
.dstAccessMask = vk::AccessFlagBits::eShaderRead,
|
||||||
|
.oldLayout = vk::ImageLayout::eDepthAttachmentOptimal,
|
||||||
|
.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal,
|
||||||
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.image = newShadowMap->GetImage()->GetVkImage(),
|
||||||
|
.subresourceRange = vk::ImageSubresourceRange
|
||||||
|
{
|
||||||
|
.aspectMask = vk::ImageAspectFlagBits::eDepth,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.levelCount = 1,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// return new index of shadow map
|
||||||
|
return static_cast<uint32_t>(shadowMapImageSamplers.size()) - 1u;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHLightingSubSystem::PrepareShadowMapsForRead(Handle<SHVkCommandBuffer> cmdBuffer) noexcept
|
||||||
|
{
|
||||||
|
// Issue barrier to transition shadow maps for reading in compute shader
|
||||||
|
cmdBuffer->PipelineBarrier(vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests, vk::PipelineStageFlagBits::eComputeShader, {}, {}, {}, shadowMapMemoryBarriers);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void SHLightingSubSystem::HandleResize(Handle<SHRenderGraphNodeCompute> compute) noexcept
|
||||||
|
//{
|
||||||
|
// uint32_t const NUM_SHADOW_MAPS = static_cast<uint32_t>(shadowMaps.size());
|
||||||
|
// for (uint32_t i = 0; i < NUM_SHADOW_MAPS; ++i)
|
||||||
|
// {
|
||||||
|
// // Just use the image view stored in the resource
|
||||||
|
// Handle<SHVkImageView> const NEW_IMAGE_VIEW = shadowMaps[i]->GetImageView();
|
||||||
|
|
||||||
|
// // set new image view
|
||||||
|
// std::get<Handle<SHVkImageView>>(shadowMapImageSamplers[i]) = NEW_IMAGE_VIEW;
|
||||||
|
|
||||||
|
// // Set image for barrier
|
||||||
|
// shadowMapMemoryBarriers[i].image = shadowMaps[i]->GetImage()->GetVkImage();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (NUM_SHADOW_MAPS > 0)
|
||||||
|
// {
|
||||||
|
// // modify descriptors in render graph node compute
|
||||||
|
// compute->ModifyWriteDescImageComputeResource (SHGraphicsConstants::DescriptorSetBindings::SHADOW_MAP_IMAGE_SAMPLER_DATA, shadowMapImageSamplers);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
Handle<SHVkDescriptorSetGroup> SHLightingSubSystem::GetLightDataDescriptorSet(void) const noexcept
|
Handle<SHVkDescriptorSetGroup> SHLightingSubSystem::GetLightDataDescriptorSet(void) const noexcept
|
||||||
{
|
{
|
||||||
return lightingDataDescSet;
|
return lightingDataDescSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout> const& SHLightingSubSystem::GetViewSamplerLayout(uint32_t index) const noexcept
|
||||||
|
{
|
||||||
|
return shadowMapImageSamplers[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SHLightingSubSystem::GetNumShadowMaps(void) const noexcept
|
||||||
|
{
|
||||||
|
return static_cast<uint32_t>(shadowMaps.size());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,13 @@
|
||||||
#include "Resource/SHHandle.h"
|
#include "Resource/SHHandle.h"
|
||||||
#include "Math/Vector/SHVec3.h"
|
#include "Math/Vector/SHVec3.h"
|
||||||
#include "Math/Vector/SHVec4.h"
|
#include "Math/Vector/SHVec4.h"
|
||||||
|
#include "Math/SHMatrix.h"
|
||||||
#include "SHLightData.h"
|
#include "SHLightData.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h"
|
||||||
|
#include "Graphics/RenderGraph/SHRenderGraphResource.h"
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -16,6 +20,10 @@ namespace SHADE
|
||||||
class SHVkBuffer;
|
class SHVkBuffer;
|
||||||
class SHLightComponent;
|
class SHLightComponent;
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
|
class SHSamplerCache;
|
||||||
|
class SHVkImageView;
|
||||||
|
class SHVkSampler;
|
||||||
|
class SHRenderGraphNodeCompute;
|
||||||
|
|
||||||
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
|
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
|
||||||
struct SHDirectionalLightData
|
struct SHDirectionalLightData
|
||||||
|
@ -34,6 +42,12 @@ namespace SHADE
|
||||||
//! Diffuse color emitted by the light
|
//! Diffuse color emitted by the light
|
||||||
alignas (16) SHVec4 diffuseColor;
|
alignas (16) SHVec4 diffuseColor;
|
||||||
|
|
||||||
|
//! Matrix for world to projection from light's perspective
|
||||||
|
SHMatrix pvMatrix;
|
||||||
|
|
||||||
|
//! Represents boolean for casting shadows in first byte and shadow map index in the other 3.
|
||||||
|
uint32_t shadowData;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
|
// Represents how the data will be interpreted in GPU. we want to copy to a container of these before passing to GPU.
|
||||||
|
@ -52,24 +66,27 @@ namespace SHADE
|
||||||
//! when a fragment is being evaluated, the shader will use the fragment's
|
//! when a fragment is being evaluated, the shader will use the fragment's
|
||||||
//! layer value to AND with the light's. If result is 1, do lighting calculations.
|
//! layer value to AND with the light's. If result is 1, do lighting calculations.
|
||||||
uint32_t cullingMask;
|
uint32_t cullingMask;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SH_API SHLightingSubSystem
|
class SH_API SHLightingSubSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using DynamicOffsetArray = std::array<std::vector<uint32_t>, static_cast<uint32_t>(SHGraphicsConstants::NUM_FRAME_BUFFERS)>;
|
using DynamicOffsetArray = std::array<std::vector<uint32_t>, static_cast<uint32_t>(SHGraphicsConstants::NUM_FRAME_BUFFERS)>;
|
||||||
|
static constexpr uint32_t MAX_SHADOWS = 200;
|
||||||
|
static constexpr uint32_t SHADOW_MAP_WIDTH = 1024;
|
||||||
|
static constexpr uint32_t SHADOW_MAP_HEIGHT = 1024;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class PerTypeData
|
class PerTypeData
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* STATIC MEMBER VARIABLES */
|
/* STATIC MEMBER VARIABLES */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
static constexpr uint32_t STARTING_NUM_LIGHTS = 50;
|
static constexpr uint32_t STARTING_NUM_LIGHTS = 50;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
|
@ -123,51 +140,90 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* STATIC MEMBER VARIABLES */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
//! logical device used for creation
|
//! logical device used for creation
|
||||||
Handle<SHVkLogicalDevice> logicalDevice;
|
Handle<SHVkLogicalDevice> logicalDevice;
|
||||||
|
|
||||||
//! The descriptor set that will hold the lighting data. Each binding will hold a buffer, NUM_FRAMES times the size required.
|
//! The descriptor set that will hold the lighting data. Each binding will hold a buffer, NUM_FRAMES times the size required.
|
||||||
Handle<SHVkDescriptorSetGroup> lightingDataDescSet;
|
Handle<SHVkDescriptorSetGroup> lightingDataDescSet;
|
||||||
|
|
||||||
//! Each type will have some data associated with it for processing
|
//! Each type will have some data associated with it for processing
|
||||||
std::array<PerTypeData, static_cast<uint32_t>(SH_LIGHT_TYPE::NUM_TYPES)> perTypeData;
|
std::array<PerTypeData, static_cast<uint32_t>(SH_LIGHT_TYPE::NUM_TYPES)> perTypeData;
|
||||||
|
|
||||||
//! Container to store dynamic offsets for binding descriptor sets
|
//! Container to store dynamic offsets for binding descriptor sets
|
||||||
DynamicOffsetArray dynamicOffsets;
|
DynamicOffsetArray dynamicOffsets;
|
||||||
|
|
||||||
//! holds the data that represents how many lights are in the scene
|
//! holds the data that represents how many lights are in the scene
|
||||||
std::array<uint32_t, static_cast<uint32_t>(SH_LIGHT_TYPE::NUM_TYPES)> lightCountsData;
|
std::array<uint32_t, static_cast<uint32_t>(SH_LIGHT_TYPE::NUM_TYPES)> lightCountsData;
|
||||||
|
|
||||||
//! GPU buffer to hold lightCountData
|
//! GPU buffer to hold lightCountData
|
||||||
Handle<SHVkBuffer> lightCountsBuffer;
|
Handle<SHVkBuffer> lightCountsBuffer;
|
||||||
|
|
||||||
//! For padding in the buffer
|
//! For padding in the buffer
|
||||||
uint32_t lightCountsAlignedSize;
|
uint32_t lightCountsAlignedSize;
|
||||||
|
|
||||||
//! Number of SHLightComponents recorded. If at the beginning of the run function the size returned by the dense
|
//! Number of SHLightComponents recorded. If at the beginning of the run function the size returned by the dense
|
||||||
//! set is less than the size recorded, rewrite all light components into the its respective buffers. If its more,
|
//! set is less than the size recorded, rewrite all light components into the its respective buffers. If its more,
|
||||||
//! don't do anything.
|
//! don't do anything.
|
||||||
//uint32_t numLightComponents;
|
//uint32_t numLightComponents;
|
||||||
|
|
||||||
|
//! Handle to sampler that all shadow map descriptors will use
|
||||||
|
Handle<SHVkSampler> shadowMapSampler;
|
||||||
|
|
||||||
|
//! For indexing shadow maps
|
||||||
|
std::unordered_map<EntityID, uint32_t> shadowMapIndexing;
|
||||||
|
|
||||||
|
//! Shadow maps for every light that casts a shadow Order here doesn't matter. We just want to store it
|
||||||
|
std::vector<Handle<SHRenderGraphResource>> shadowMaps;
|
||||||
|
|
||||||
|
//! Descriptor sets required to be given to the compute shader for shadow calculation. This will be a descriptor array.
|
||||||
|
//! It will also be preallocated.
|
||||||
|
//Handle<SHVkDescriptorSetGroup> shadowMapDescriptorSet;
|
||||||
|
|
||||||
|
//! Combined image samplers for the texture descriptors
|
||||||
|
std::vector<std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout>> shadowMapImageSamplers;
|
||||||
|
|
||||||
|
//! Barriers required to transition the resources from whatever layout they are in (probably from VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
|
||||||
|
//! to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
|
||||||
|
std::vector<vk::ImageMemoryBarrier> shadowMapMemoryBarriers;
|
||||||
|
|
||||||
|
//! Resource hub from Graphics System
|
||||||
|
SHResourceHub* resourceHub;
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER FUNCTIONS */
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void UpdateDescSet (uint32_t binding) noexcept;
|
void UpdateDescSet (uint32_t binding) noexcept;
|
||||||
void ComputeDynamicOffsets (void) noexcept;
|
void ComputeDynamicOffsets (void) noexcept;
|
||||||
void ResetNumLights (void) noexcept;
|
void ResetNumLights (void) noexcept;
|
||||||
|
void UpdateShadowMapDesc (void) noexcept;
|
||||||
|
SHMatrix GetViewMatrix (SHLightComponent* lightComp) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void Init (Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool) noexcept;
|
void Init (Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> descPool, SHResourceHub* rh, Handle<SHVkSampler> inShadowMapSampler) noexcept;
|
||||||
void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept;
|
void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept;
|
||||||
void Exit (void) noexcept;
|
void Exit (void) noexcept;
|
||||||
|
void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept;
|
||||||
|
uint32_t AddShadowMap (Handle<SHRenderGraphResource> newShadowMap, EntityID lightEntity) noexcept;
|
||||||
|
void PrepareShadowMapsForRead (Handle<SHVkCommandBuffer> cmdBuffer) noexcept;
|
||||||
|
//void HandleResize (Handle<SHRenderGraphNodeCompute> compute) noexcept;
|
||||||
|
//void RemoveShadowMap (uint32_t index) noexcept;
|
||||||
|
|
||||||
void BindDescSet (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept;
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* SETTERS AND GETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
Handle<SHVkDescriptorSetGroup> GetLightDataDescriptorSet (void) const noexcept;
|
Handle<SHVkDescriptorSetGroup> GetLightDataDescriptorSet (void) const noexcept;
|
||||||
|
std::tuple<Handle<SHVkImageView>, Handle<SHVkSampler>, vk::ImageLayout> const& GetViewSamplerLayout (uint32_t index) const noexcept;
|
||||||
|
uint32_t GetNumShadowMaps (void) const noexcept;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,23 @@
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHPipelineLibrary.h"
|
#include "SHPipelineLibrary.h"
|
||||||
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
#include "Graphics/Devices/SHVkLogicalDevice.h"
|
||||||
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
|
|
||||||
#include "Graphics/RenderGraph/SHSubpass.h"
|
#include "Graphics/RenderGraph/SHSubpass.h"
|
||||||
#include "Graphics/SHVkUtil.h"
|
#include "Graphics/SHVkUtil.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
Handle<SHVkPipeline> SHPipelineLibrary::CreateGraphicsPipelines(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass) noexcept
|
Handle<SHVkPipeline> SHPipelineLibrary::CreateGraphicsPipelines(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHVkRenderpass> renderpass, Handle<SHSubpass> subpass, SHVertexInputState const& viState/* = SHGraphicsPredefinedData::GetDefaultViState()*/, SHRasterizationState const& rasterState) noexcept
|
||||||
{
|
{
|
||||||
|
std::vector<Handle<SHVkShaderModule>> modules{};
|
||||||
|
if (vsFsPair.first)
|
||||||
|
modules.push_back(vsFsPair.first);
|
||||||
|
if (vsFsPair.second)
|
||||||
|
modules.push_back(vsFsPair.second);
|
||||||
|
|
||||||
SHPipelineLayoutParams params
|
SHPipelineLayoutParams params
|
||||||
{
|
{
|
||||||
.shaderModules = {vsFsPair.first, vsFsPair.second},
|
.shaderModules = std::move(modules),
|
||||||
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts
|
.predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,7 +26,7 @@ namespace SHADE
|
||||||
|
|
||||||
// Create the pipeline and configure the default vertex input state
|
// Create the pipeline and configure the default vertex input state
|
||||||
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass);
|
auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass);
|
||||||
newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsPredefinedData::GetDefaultViState());
|
newPipeline->GetPipelineState().SetVertexInputState(viState);
|
||||||
|
|
||||||
SHColorBlendState colorBlendState{};
|
SHColorBlendState colorBlendState{};
|
||||||
colorBlendState.logic_op_enable = VK_FALSE;
|
colorBlendState.logic_op_enable = VK_FALSE;
|
||||||
|
@ -30,6 +35,7 @@ namespace SHADE
|
||||||
auto const& subpassColorReferences = subpass->GetColorAttachmentReferences();
|
auto const& subpassColorReferences = subpass->GetColorAttachmentReferences();
|
||||||
colorBlendState.attachments.reserve(subpassColorReferences.size());
|
colorBlendState.attachments.reserve(subpassColorReferences.size());
|
||||||
|
|
||||||
|
|
||||||
for (auto& att : subpassColorReferences)
|
for (auto& att : subpassColorReferences)
|
||||||
{
|
{
|
||||||
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
|
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
|
||||||
|
@ -48,6 +54,8 @@ namespace SHADE
|
||||||
|
|
||||||
newPipeline->GetPipelineState().SetColorBlenState(colorBlendState);
|
newPipeline->GetPipelineState().SetColorBlenState(colorBlendState);
|
||||||
|
|
||||||
|
newPipeline->GetPipelineState().SetRasterizationState(rasterState);
|
||||||
|
|
||||||
// Actually construct the pipeline
|
// Actually construct the pipeline
|
||||||
newPipeline->ConstructPipeline();
|
newPipeline->ConstructPipeline();
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "Graphics/Shaders/SHVkShaderModule.h"
|
#include "Graphics/Shaders/SHVkShaderModule.h"
|
||||||
#include "Graphics/Pipeline/SHVkPipeline.h"
|
#include "Graphics/Pipeline/SHVkPipeline.h"
|
||||||
|
#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -32,7 +33,9 @@ namespace SHADE
|
||||||
Handle<SHVkPipeline> CreateGraphicsPipelines (
|
Handle<SHVkPipeline> CreateGraphicsPipelines (
|
||||||
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
|
std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair,
|
||||||
Handle<SHVkRenderpass> renderpass,
|
Handle<SHVkRenderpass> renderpass,
|
||||||
Handle<SHSubpass> subpass
|
Handle<SHSubpass> subpass,
|
||||||
|
SHVertexInputState const& viState = SHGraphicsPredefinedData::GetDefaultViState(),
|
||||||
|
SHRasterizationState const& rasterState = SHRasterizationState{}
|
||||||
) noexcept;
|
) noexcept;
|
||||||
Handle<SHVkPipeline> GetGraphicsPipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
Handle<SHVkPipeline> GetGraphicsPipeline (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
||||||
bool CheckGraphicsPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
bool CheckGraphicsPipelineExistence (std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair) noexcept;
|
||||||
|
|
|
@ -195,7 +195,7 @@ namespace SHADE
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHVertexInputState::AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs) noexcept
|
void SHVertexInputState::AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs, uint32_t fixedBinding /*= static_cast<uint32_t>(-1)*/, uint32_t fixedAttributeLocation/* = static_cast<uint32_t>(-1)*/) noexcept
|
||||||
{
|
{
|
||||||
// add a binding and get ref to it
|
// add a binding and get ref to it
|
||||||
bindings.emplace_back();
|
bindings.emplace_back();
|
||||||
|
@ -210,7 +210,7 @@ namespace SHADE
|
||||||
// Offset is 0 at first (for first element)
|
// Offset is 0 at first (for first element)
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
|
|
||||||
binding.binding = static_cast<uint32_t>(bindings.size() - 1);
|
binding.binding = (fixedBinding != static_cast<uint32_t>(-1)) ? fixedBinding : static_cast<uint32_t>(bindings.size() - 1);
|
||||||
|
|
||||||
// for every attribute passed in
|
// for every attribute passed in
|
||||||
for (auto const& attrib : inAttribs)
|
for (auto const& attrib : inAttribs)
|
||||||
|
@ -226,10 +226,11 @@ namespace SHADE
|
||||||
auto& vertexAttrib = attributes.back();
|
auto& vertexAttrib = attributes.back();
|
||||||
|
|
||||||
// The binding for that attribute description is index of the new binding created earlier in this function
|
// The binding for that attribute description is index of the new binding created earlier in this function
|
||||||
vertexAttrib.binding = static_cast<uint32_t>(bindings.size() - 1);
|
vertexAttrib.binding = (fixedBinding != static_cast<uint32_t>(-1)) ? fixedBinding : static_cast<uint32_t>(bindings.size() - 1);
|
||||||
|
|
||||||
// Attribute location. New index is simply + 1 of the previous. Starts from 0 obviously
|
//Attribute location. New index is simply + 1 of the previous. Starts from 0 obviously
|
||||||
vertexAttrib.location = static_cast<uint32_t>(attributes.size () - 1);
|
vertexAttrib.location = (fixedAttributeLocation != static_cast<uint32_t>(-1)) ? fixedAttributeLocation + i : static_cast<uint32_t>(attributes.size () - 1);
|
||||||
|
//vertexAttrib.location = static_cast<uint32_t>(attributes.size() - 1);
|
||||||
|
|
||||||
// Get the vkFormat associated with the SHAttribFormat
|
// Get the vkFormat associated with the SHAttribFormat
|
||||||
vertexAttrib.format = format;
|
vertexAttrib.format = format;
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace SHADE
|
||||||
SHVertexInputState& operator= (SHVertexInputState const& rhs) noexcept;
|
SHVertexInputState& operator= (SHVertexInputState const& rhs) noexcept;
|
||||||
SHVertexInputState& operator= (SHVertexInputState&& rhs) noexcept;
|
SHVertexInputState& operator= (SHVertexInputState&& rhs) noexcept;
|
||||||
|
|
||||||
void AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs) noexcept;
|
void AddBinding(bool instanced, bool calcOffset, std::initializer_list<SHVertexAttribute> inAttribs, uint32_t fixedBinding = static_cast<uint32_t>(-1), uint32_t fixedAttributeLocation = static_cast<uint32_t>(-1)) noexcept;
|
||||||
|
|
||||||
friend class SHVkPipelineState;
|
friend class SHVkPipelineState;
|
||||||
friend class SHVkPipeline;
|
friend class SHVkPipeline;
|
||||||
|
|
|
@ -19,69 +19,71 @@ namespace SHADE
|
||||||
|
|
||||||
for (auto& shaderModule : shaderModules)
|
for (auto& shaderModule : shaderModules)
|
||||||
{
|
{
|
||||||
// References for convenience
|
if (shaderModule)
|
||||||
auto const& reflectedData = shaderModule->GetReflectedData();
|
|
||||||
auto const& pcInfo = reflectedData.GetPushConstantInfo();
|
|
||||||
|
|
||||||
// If a push constant block exists for the shader module
|
|
||||||
if (pcInfo.memberCount != 0)
|
|
||||||
{
|
{
|
||||||
bool exists = false;
|
// References for convenience
|
||||||
|
auto const& reflectedData = shaderModule->GetReflectedData();
|
||||||
|
auto const& pcInfo = reflectedData.GetPushConstantInfo();
|
||||||
|
|
||||||
// Check if push constant block already exists
|
// If a push constant block exists for the shader module
|
||||||
for (uint32_t i = 0; i < pcInfos.size(); ++i)
|
if (pcInfo.memberCount != 0)
|
||||||
{
|
{
|
||||||
// If there is a block with the same name, member count and size
|
bool exists = false;
|
||||||
if (std::strcmp(pcInfos[i]->name, pcInfo.name) == 0 && pcInfos[i]->memberCount == pcInfo.memberCount && pcInfos[i]->size == pcInfo.size)
|
|
||||||
|
// Check if push constant block already exists
|
||||||
|
for (uint32_t i = 0; i < pcInfos.size(); ++i)
|
||||||
{
|
{
|
||||||
// We just take the existing pc range we built earlier, and allow it to be accessed in potentially other shader stages
|
// If there is a block with the same name, member count and size
|
||||||
vkPcRanges[i].stageFlags |= shaderModule->GetShaderStageFlagBits();
|
if (std::strcmp(pcInfos[i]->name, pcInfo.name) == 0 && pcInfos[i]->memberCount == pcInfo.memberCount && pcInfos[i]->size == pcInfo.size)
|
||||||
|
{
|
||||||
|
// We just take the existing pc range we built earlier, and allow it to be accessed in potentially other shader stages
|
||||||
|
vkPcRanges[i].stageFlags |= shaderModule->GetShaderStageFlagBits();
|
||||||
|
|
||||||
// Set flag and stop checking
|
// Set flag and stop checking
|
||||||
exists = true;
|
exists = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If the block doesn't exist yet
|
|
||||||
if (!exists)
|
|
||||||
{
|
|
||||||
// Loop through all member variables of the new push constant block
|
|
||||||
for (uint32_t i = 0; i < pcInfo.memberCount; ++i)
|
|
||||||
{
|
|
||||||
std::string variableName;
|
|
||||||
variableName.reserve(50);
|
|
||||||
variableName += pcInfo.name;
|
|
||||||
variableName += ".";
|
|
||||||
variableName += pcInfo.members[i].name;
|
|
||||||
|
|
||||||
// Add the variable's offset info to the interface
|
|
||||||
pushConstantInterface.AddOffset(std::move(variableName), startOffset + pcInfo.members[i].offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New push constant range
|
// If the block doesn't exist yet
|
||||||
vk::PushConstantRange newRange;
|
if (!exists)
|
||||||
|
{
|
||||||
|
// Loop through all member variables of the new push constant block
|
||||||
|
for (uint32_t i = 0; i < pcInfo.memberCount; ++i)
|
||||||
|
{
|
||||||
|
std::string variableName;
|
||||||
|
variableName.reserve(50);
|
||||||
|
variableName += pcInfo.name;
|
||||||
|
variableName += ".";
|
||||||
|
variableName += pcInfo.members[i].name;
|
||||||
|
|
||||||
// set offset and size
|
// Add the variable's offset info to the interface
|
||||||
newRange.offset = startOffset;
|
pushConstantInterface.AddOffset(std::move(variableName), startOffset + pcInfo.members[i].offset);
|
||||||
newRange.size = pcInfo.size;
|
}
|
||||||
|
|
||||||
// Stage flags will be whatever shader stage of the shader that contains the push constant block
|
// New push constant range
|
||||||
newRange.stageFlags = shaderModule->GetShaderStageFlagBits();
|
vk::PushConstantRange newRange;
|
||||||
|
|
||||||
// Add to the list foe checking later
|
// set offset and size
|
||||||
pcInfos.push_back(&pcInfo);
|
newRange.offset = startOffset;
|
||||||
|
newRange.size = pcInfo.size;
|
||||||
|
|
||||||
// For pipeline layout to consume
|
// Stage flags will be whatever shader stage of the shader that contains the push constant block
|
||||||
vkPcRanges.push_back(newRange);
|
newRange.stageFlags = shaderModule->GetShaderStageFlagBits();
|
||||||
|
|
||||||
// Next push constant block will start next to the previous push constant block
|
// Add to the list foe checking later
|
||||||
startOffset += pcInfo.size;
|
pcInfos.push_back(&pcInfo);
|
||||||
|
|
||||||
|
// For pipeline layout to consume
|
||||||
|
vkPcRanges.push_back(newRange);
|
||||||
|
|
||||||
|
// Next push constant block will start next to the previous push constant block
|
||||||
|
startOffset += pcInfo.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
stageFlags |= shaderModule->GetShaderStageFlagBits();
|
||||||
}
|
}
|
||||||
|
|
||||||
stageFlags |= shaderModule->GetShaderStageFlagBits();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// After all the sizes of the push constant blocks have been added, record the size in the interface
|
// After all the sizes of the push constant blocks have been added, record the size in the interface
|
||||||
|
@ -132,6 +134,9 @@ namespace SHADE
|
||||||
//! Now we take descriptor set info from all shaders and prepare some bindings for the descriptor set
|
//! Now we take descriptor set info from all shaders and prepare some bindings for the descriptor set
|
||||||
for (auto& shaderModule : shaderModules)
|
for (auto& shaderModule : shaderModules)
|
||||||
{
|
{
|
||||||
|
if (!shaderModule)
|
||||||
|
continue;
|
||||||
|
|
||||||
auto const& descBindingInfo = shaderModule->GetReflectedData().GetDescriptorBindingInfo();
|
auto const& descBindingInfo = shaderModule->GetReflectedData().GetDescriptorBindingInfo();
|
||||||
auto const& reflectedSets = descBindingInfo.GetReflectedSets();
|
auto const& reflectedSets = descBindingInfo.GetReflectedSets();
|
||||||
|
|
||||||
|
@ -200,10 +205,12 @@ namespace SHADE
|
||||||
newBinding.DescriptorCount = SHVkDescriptorSetLayout::Binding::VARIABLE_DESCRIPTOR_UPPER_BOUND;
|
newBinding.DescriptorCount = SHVkDescriptorSetLayout::Binding::VARIABLE_DESCRIPTOR_UPPER_BOUND;
|
||||||
|
|
||||||
// Set the flags for variable bindings
|
// Set the flags for variable bindings
|
||||||
newBinding.flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount;
|
newBinding.flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount | vk::DescriptorBindingFlagBits::ePartiallyBound;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
SHLOG_ERROR("Variable size binding is detected, but the binding is not the last binding of the set and is therefore invalid. ");
|
SHLOG_ERROR("Variable size binding is detected, but the binding is not the last binding of the set and is therefore invalid. ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setsWithBindings[CURRENT_SET].emplace_back(newBinding);
|
setsWithBindings[CURRENT_SET].emplace_back(newBinding);
|
||||||
|
@ -326,11 +333,10 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
for (auto& mod : shaderModules)
|
for (auto& mod : shaderModules)
|
||||||
{
|
{
|
||||||
mod->AddCallback([this]()
|
if (mod)
|
||||||
{
|
{
|
||||||
RecreateIfNeeded();
|
mod->AddCallback([this]() { RecreateIfNeeded(); });
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RecreateIfNeeded ();
|
RecreateIfNeeded ();
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHRenderGraph::AddResource(std::string resourceName, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
|
void SHRenderGraph::AddResource(std::string resourceName, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, bool resizeWithWindow, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
|
||||||
{
|
{
|
||||||
// If we set to
|
// If we set to
|
||||||
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
||||||
|
@ -64,7 +64,7 @@ namespace SHADE
|
||||||
format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format;
|
format = renderGraphStorage->swapchain->GetSurfaceFormatKHR().format;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resource = renderGraphStorage->resourceHub->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags);
|
auto resource = renderGraphStorage->resourceHub->Create<SHRenderGraphResource>(renderGraphStorage, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags, resizeWithWindow);
|
||||||
renderGraphStorage->graphResources->try_emplace(resourceName, resource);
|
renderGraphStorage->graphResources->try_emplace(resourceName, resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +106,9 @@ namespace SHADE
|
||||||
|
|
||||||
for (auto& affectedNode : affectedNodes)
|
for (auto& affectedNode : affectedNodes)
|
||||||
nodes[affectedNode]->CreateFramebuffer();
|
nodes[affectedNode]->CreateFramebuffer();
|
||||||
|
|
||||||
|
renderGraphStorage->graphResources->at(resourceName).Free();
|
||||||
|
renderGraphStorage->graphResources->erase (resourceName);
|
||||||
/*
|
/*
|
||||||
* IMPORTANT NOTES
|
* IMPORTANT NOTES
|
||||||
*
|
*
|
||||||
|
@ -166,68 +169,7 @@ namespace SHADE
|
||||||
|
|
||||||
for (uint32_t i = 0; auto& node : nodes)
|
for (uint32_t i = 0; auto& node : nodes)
|
||||||
{
|
{
|
||||||
// key is handle ID, value is final layout.
|
node->StandaloneConfigureAttDesc(i == nodes.size() - 1);
|
||||||
std::unordered_map<uint32_t, vk::ImageLayout> resourceAttFinalLayouts;
|
|
||||||
if (node->subpasses.empty())
|
|
||||||
{
|
|
||||||
SHLOG_ERROR("Node does not contain a subpass. Cannot configure attachment descriptions as a result. ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We first want to take all resources track their layout as undefined at the start of the node/renderpass
|
|
||||||
auto const resources = node->GetResources();
|
|
||||||
for (auto& resource : resources)
|
|
||||||
{
|
|
||||||
resource->GetInfoTracker()->TrackLayout(node, {}, vk::ImageLayout::eUndefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
// attempt to get all final layouts for all resources
|
|
||||||
for (auto& subpass : node->subpasses)
|
|
||||||
{
|
|
||||||
for (auto& color : subpass->colorReferences)
|
|
||||||
{
|
|
||||||
// If final renderpass and attachment is a COLOR_PRESENT resource, make resource transition to present after last subpass
|
|
||||||
if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)))
|
|
||||||
resourceAttFinalLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
|
|
||||||
else
|
|
||||||
resourceAttFinalLayouts[color.attachment] = color.layout;
|
|
||||||
|
|
||||||
node->attResources[color.attachment]->infoTracker->TrackLayout(node, subpass, color.layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& depth : subpass->depthReferences)
|
|
||||||
{
|
|
||||||
resourceAttFinalLayouts[depth.attachment] = depth.layout;
|
|
||||||
node->attResources[depth.attachment]->infoTracker->TrackLayout(node, subpass, depth.layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& input : subpass->inputReferences)
|
|
||||||
{
|
|
||||||
resourceAttFinalLayouts[input.attachment] = input.layout;
|
|
||||||
node->attResources[input.attachment]->infoTracker->TrackLayout(node, subpass, input.layout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j)
|
|
||||||
{
|
|
||||||
auto& att = node->attachmentDescriptions[j];
|
|
||||||
auto& resource = node->attResources[j];
|
|
||||||
|
|
||||||
// If resource is from another render graph, use the final layout it had when it was last used in that graph. This is initialized in LinkNonOwningResource.
|
|
||||||
// We also want to load the attachment, not "don't care".
|
|
||||||
if (resource->resourceTypeFlags & SHUtilities::ConvertEnum(SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED) &&
|
|
||||||
renderGraphStorage->nonOwningResourceInitialLayouts.contains(resource.GetId().Raw))
|
|
||||||
{
|
|
||||||
att.initialLayout = renderGraphStorage->nonOwningResourceInitialLayouts.at (resource.GetId().Raw);
|
|
||||||
att.loadOp = vk::AttachmentLoadOp::eLoad;
|
|
||||||
att.stencilLoadOp = vk::AttachmentLoadOp::eLoad;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
att.initialLayout = vk::ImageLayout::eUndefined;
|
|
||||||
|
|
||||||
att.finalLayout = resourceAttFinalLayouts[j];
|
|
||||||
resource->GetInfoTracker()->TrackLayout(node, {}, att.finalLayout);
|
|
||||||
}
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,6 +275,17 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraph::ReindexNodes(void) noexcept
|
||||||
|
{
|
||||||
|
nodeIndexing.clear();
|
||||||
|
uint32_t i = 0;
|
||||||
|
for (auto& node : nodes)
|
||||||
|
{
|
||||||
|
nodeIndexing.emplace (node->name, i);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -473,6 +426,65 @@ namespace SHADE
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
This function is purely used for dynamic nodes (if such a thing were to
|
||||||
|
exist in our architecture). In other words, don't use this function unless
|
||||||
|
the new node is fully standalone and does not rely or is a prereq of
|
||||||
|
other nodes.
|
||||||
|
|
||||||
|
\param nodeName
|
||||||
|
Name of new node
|
||||||
|
|
||||||
|
\param resourceInstruction
|
||||||
|
Resources for the node
|
||||||
|
|
||||||
|
\param nodeToAddAfter
|
||||||
|
The node to add the new node after.
|
||||||
|
|
||||||
|
\return
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
Handle<SHRenderGraphNode> SHRenderGraph::AddNodeAfter(std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::string nodeToAddAfter) noexcept
|
||||||
|
{
|
||||||
|
if (nodeIndexing.contains(nodeName))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Node already exists, cannot add node. ");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<SHAttachmentDescInitParams> descInitParams;
|
||||||
|
for (auto const& instruction : resourceInstruction)
|
||||||
|
{
|
||||||
|
// If the resource that the new node is requesting for exists, allow the graph to reference it
|
||||||
|
if (renderGraphStorage->graphResources->contains(instruction.resourceName))
|
||||||
|
{
|
||||||
|
descInitParams.push_back(
|
||||||
|
{
|
||||||
|
.resourceHdl = renderGraphStorage->graphResources->at(instruction.resourceName),
|
||||||
|
.dontClearOnLoad = instruction.dontClearOnLoad,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Resource doesn't exist in graph yet. Cannot create new node.");
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get target node
|
||||||
|
auto targetNode = nodes.begin() + nodeIndexing.at(nodeToAddAfter);
|
||||||
|
|
||||||
|
auto node = nodes.insert(targetNode, renderGraphStorage->resourceHub->Create<SHRenderGraphNode>(nodeName, renderGraphStorage, std::move(descInitParams), std::vector<Handle<SHRenderGraphNode>>()));
|
||||||
|
ReindexNodes ();
|
||||||
|
return *node;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void SHRenderGraph::AddRenderToSwapchainNode(std::string toSwapchainResource, std::string swapchainResource, std::initializer_list<std::string> predecessorNodes, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaderModules) noexcept
|
void SHRenderGraph::AddRenderToSwapchainNode(std::string toSwapchainResource, std::string swapchainResource, std::initializer_list<std::string> predecessorNodes, std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> shaderModules) noexcept
|
||||||
{
|
{
|
||||||
for (auto& node : predecessorNodes)
|
for (auto& node : predecessorNodes)
|
||||||
|
@ -532,10 +544,6 @@ namespace SHADE
|
||||||
ConfigureSubSystems();
|
ConfigureSubSystems();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderGraph::Regenerate(void) noexcept
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
@ -572,10 +580,13 @@ namespace SHADE
|
||||||
|
|
||||||
for (auto& node : nodes)
|
for (auto& node : nodes)
|
||||||
{
|
{
|
||||||
// bind static global data
|
if (node->renderpass)
|
||||||
SHGlobalDescriptorSets::BindStaticGlobalData(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::STATIC_DATA));
|
{
|
||||||
|
// bind static global data
|
||||||
|
SHGlobalDescriptorSets::BindStaticGlobalData(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::STATIC_DATA));
|
||||||
|
|
||||||
node->Execute(cmdBuffer, descPool, frameIndex);
|
node->Execute(cmdBuffer, descPool, frameIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdBuffer->EndLabeledSegment();
|
cmdBuffer->EndLabeledSegment();
|
||||||
|
@ -605,8 +616,11 @@ namespace SHADE
|
||||||
// resize resources
|
// resize resources
|
||||||
for (auto& [name, resource] : *renderGraphStorage->graphResources)
|
for (auto& [name, resource] : *renderGraphStorage->graphResources)
|
||||||
{
|
{
|
||||||
if (!renderGraphStorage->nonOwningResourceInitialLayouts.contains (resource.GetId().Raw))
|
if (resource->resizeWithWindow)
|
||||||
resource->HandleResize(newWidth, newHeight);
|
{
|
||||||
|
if (!renderGraphStorage->nonOwningResourceInitialLayouts.contains (resource.GetId().Raw))
|
||||||
|
resource->HandleResize(newWidth, newHeight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& node : nodes)
|
for (auto& node : nodes)
|
||||||
|
|
|
@ -55,6 +55,7 @@ namespace SHADE
|
||||||
void ConfigureRenderpasses (void) noexcept;
|
void ConfigureRenderpasses (void) noexcept;
|
||||||
void ConfigureSubSystems (void) noexcept;
|
void ConfigureSubSystems (void) noexcept;
|
||||||
void ConfigureFramebuffers (void) noexcept;
|
void ConfigureFramebuffers (void) noexcept;
|
||||||
|
void ReindexNodes (void) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
|
@ -101,6 +102,7 @@ namespace SHADE
|
||||||
(
|
(
|
||||||
std::string resourceName,
|
std::string resourceName,
|
||||||
std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags,
|
std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags,
|
||||||
|
bool resizeWithWindow = true,
|
||||||
uint32_t w = static_cast<uint32_t>(-1),
|
uint32_t w = static_cast<uint32_t>(-1),
|
||||||
uint32_t h = static_cast<uint32_t>(-1),
|
uint32_t h = static_cast<uint32_t>(-1),
|
||||||
vk::Format format = vk::Format::eB8G8R8A8Unorm,
|
vk::Format format = vk::Format::eB8G8R8A8Unorm,
|
||||||
|
@ -123,6 +125,12 @@ namespace SHADE
|
||||||
std::initializer_list<ResourceInstruction> resourceInstruction,
|
std::initializer_list<ResourceInstruction> resourceInstruction,
|
||||||
std::initializer_list<std::string> predecessorNodes
|
std::initializer_list<std::string> predecessorNodes
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
Handle<SHRenderGraphNode> AddNodeAfter
|
||||||
|
(
|
||||||
|
std::string nodeName,
|
||||||
|
std::initializer_list<ResourceInstruction> resourceInstruction,
|
||||||
|
std::string nodeToAddAfter
|
||||||
|
) noexcept;
|
||||||
|
|
||||||
void AddRenderToSwapchainNode
|
void AddRenderToSwapchainNode
|
||||||
(
|
(
|
||||||
|
@ -134,7 +142,6 @@ namespace SHADE
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
void Generate (void) noexcept;
|
void Generate (void) noexcept;
|
||||||
void Regenerate (void) noexcept;
|
|
||||||
void CheckForNodeComputes (void) noexcept;
|
void CheckForNodeComputes (void) noexcept;
|
||||||
void Execute (uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept;
|
void Execute (uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool) noexcept;
|
||||||
void Begin (uint32_t frameIndex) noexcept;
|
void Begin (uint32_t frameIndex) noexcept;
|
||||||
|
@ -165,7 +172,14 @@ namespace SHADE
|
||||||
* that manage the resources instead and can facilitate such linking of resources. Either that, or we allow only 1 render graph,
|
* that manage the resources instead and can facilitate such linking of resources. Either that, or we allow only 1 render graph,
|
||||||
* but different matrices (SHRenderer) can be used in different nodes.
|
* but different matrices (SHRenderer) can be used in different nodes.
|
||||||
* - There are also way too many hash maps created for ease of access. This definitely can be cut down.
|
* - There are also way too many hash maps created for ease of access. This definitely can be cut down.
|
||||||
* -
|
* - In hindsight there should have been a distinction between static and dynamic nodes. Static nodes are the ones that are accounted
|
||||||
|
* for in the generation of the render graph. Dynamic nodes begin with nothing at first, but allows for linking of resources and subpasses
|
||||||
|
* while the render graph is executing. The resources here should also be dynamic, which means it should never be used in anywhere else other
|
||||||
|
* than in the node that is using it. This would mean its initial layouts are always specified as undefined and final layouts specified as
|
||||||
|
* whatever the last subpass that is using that resource specifies in the node. Dynamic nodes are meant to render to resources that would later
|
||||||
|
* be used externally, as descriptors for example (the descriptors can be used in a render graph node compute for example). Dynamic nodes run as
|
||||||
|
* if they are the only nodes in the graph, because their resources are not used in other nodes and are thus not predecessors or successors of any
|
||||||
|
* other node.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,11 @@ namespace SHADE
|
||||||
renderpass.Free();
|
renderpass.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps);
|
if (!spDescs.empty())
|
||||||
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eRenderPass, renderpass->GetVkRenderpass(), "[RenderPass] " + name);
|
{
|
||||||
|
renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps);
|
||||||
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eRenderPass, renderpass->GetVkRenderpass(), "[RenderPass] " + name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -46,91 +49,105 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHRenderGraphNode::CreateFramebuffer(void) noexcept
|
void SHRenderGraphNode::CreateFramebuffer(void) noexcept
|
||||||
{
|
{
|
||||||
if (!framebuffers.empty())
|
if (renderpass)
|
||||||
{
|
{
|
||||||
for (auto fbo : framebuffers)
|
if (!framebuffers.empty())
|
||||||
{
|
{
|
||||||
if (fbo)
|
for (auto fbo : framebuffers)
|
||||||
fbo.Free();
|
{
|
||||||
}
|
if (fbo)
|
||||||
}
|
fbo.Free();
|
||||||
|
}
|
||||||
for (uint32_t i = 0; i < framebuffers.size(); ++i)
|
|
||||||
{
|
|
||||||
std::vector<Handle<SHVkImageView>> imageViews(attResources.size());
|
|
||||||
uint32_t fbWidth = std::numeric_limits<uint32_t>::max();
|
|
||||||
uint32_t fbHeight = std::numeric_limits<uint32_t>::max();
|
|
||||||
|
|
||||||
for (uint32_t j = 0; j < attResources.size(); ++j)
|
|
||||||
{
|
|
||||||
uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? i : 0;
|
|
||||||
imageViews[j] = attResources[j]->imageViews[imageViewIndex];
|
|
||||||
|
|
||||||
// We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
|
|
||||||
if (fbWidth > attResources[j]->width)
|
|
||||||
fbWidth = attResources[j]->width;
|
|
||||||
if (fbHeight > attResources[j]->height)
|
|
||||||
fbHeight = attResources[j]->height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < framebuffers.size(); ++i)
|
||||||
|
{
|
||||||
|
std::vector<Handle<SHVkImageView>> imageViews(attResources.size());
|
||||||
|
uint32_t fbWidth = std::numeric_limits<uint32_t>::max();
|
||||||
|
uint32_t fbHeight = std::numeric_limits<uint32_t>::max();
|
||||||
|
|
||||||
framebuffers[i] = graphStorage->logicalDevice->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight);
|
for (uint32_t j = 0; j < attResources.size(); ++j)
|
||||||
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eFramebuffer, framebuffers[i]->GetVkFramebuffer(), "[Framebuffer] " + name + std::to_string(i));
|
{
|
||||||
|
uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? i : 0;
|
||||||
|
imageViews[j] = attResources[j]->imageViews[imageViewIndex];
|
||||||
|
|
||||||
|
// We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
|
||||||
|
if (fbWidth > attResources[j]->width)
|
||||||
|
fbWidth = attResources[j]->width;
|
||||||
|
if (fbHeight > attResources[j]->height)
|
||||||
|
fbHeight = attResources[j]->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
framebuffers[i] = graphStorage->logicalDevice->CreateFramebuffer(renderpass, imageViews, fbWidth, fbHeight);
|
||||||
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eFramebuffer, framebuffers[i]->GetVkFramebuffer(), "[Framebuffer] " + name + std::to_string(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderGraphNode::HandleResize(void) noexcept
|
void SHRenderGraphNode::HandleResize(void) noexcept
|
||||||
{
|
{
|
||||||
renderpass->HandleResize();
|
if (renderpass)
|
||||||
|
|
||||||
for (uint32_t i = 0; i < framebuffers.size(); ++i)
|
|
||||||
{
|
{
|
||||||
std::vector<Handle<SHVkImageView>> imageViews(attResources.size());
|
renderpass->HandleResize();
|
||||||
uint32_t fbWidth = std::numeric_limits<uint32_t>::max();
|
|
||||||
uint32_t fbHeight = std::numeric_limits<uint32_t>::max();
|
|
||||||
|
|
||||||
for (uint32_t j = 0; j < attResources.size(); ++j)
|
for (uint32_t i = 0; i < framebuffers.size(); ++i)
|
||||||
{
|
{
|
||||||
uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? i : 0;
|
std::vector<Handle<SHVkImageView>> imageViews(attResources.size());
|
||||||
imageViews[j] = attResources[j]->imageViews[imageViewIndex];
|
uint32_t fbWidth = std::numeric_limits<uint32_t>::max();
|
||||||
|
uint32_t fbHeight = std::numeric_limits<uint32_t>::max();
|
||||||
|
|
||||||
// We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
|
for (uint32_t j = 0; j < attResources.size(); ++j)
|
||||||
if (fbWidth > attResources[j]->width)
|
{
|
||||||
fbWidth = attResources[j]->width;
|
uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? i : 0;
|
||||||
if (fbHeight > attResources[j]->height)
|
imageViews[j] = attResources[j]->imageViews[imageViewIndex];
|
||||||
fbHeight = attResources[j]->height;
|
|
||||||
|
// We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
|
||||||
|
if (fbWidth > attResources[j]->width)
|
||||||
|
fbWidth = attResources[j]->width;
|
||||||
|
if (fbHeight > attResources[j]->height)
|
||||||
|
fbHeight = attResources[j]->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
framebuffers[i]->HandleResize(renderpass, imageViews, fbWidth, fbHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
framebuffers[i]->HandleResize(renderpass, imageViews, fbWidth, fbHeight);
|
for (auto& subpass : subpasses)
|
||||||
}
|
{
|
||||||
|
subpass->HandleResize();
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& subpass : subpasses)
|
for (auto& nodeCompute : nodeComputes)
|
||||||
{
|
{
|
||||||
subpass->HandleResize();
|
nodeCompute->HandleResize();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& nodeCompute : nodeComputes)
|
|
||||||
{
|
|
||||||
nodeCompute->HandleResize();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderGraphNode::ConfigureSubpasses(void) noexcept
|
void SHRenderGraphNode::ConfigureSubpasses(void) noexcept
|
||||||
{
|
{
|
||||||
|
if (subpasses.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32_t numValidSubpasses = std::count_if(subpasses.begin(), subpasses.end(), [](Handle<SHSubpass> subpass) {return !subpass->HasNoAttachments();});
|
||||||
|
|
||||||
// Create subpass description and dependencies based on number of subpasses
|
// Create subpass description and dependencies based on number of subpasses
|
||||||
spDescs.resize(subpasses.size());
|
spDescs.resize(numValidSubpasses);
|
||||||
spDeps.resize(subpasses.size());
|
spDeps.resize(numValidSubpasses);
|
||||||
|
|
||||||
// Now we want to loop through all attachments in all subpasses in the node and query
|
// Now we want to loop through all attachments in all subpasses in the node and query
|
||||||
// the resources being used. For each resource we want to query the type and record it
|
// the resources being used. For each resource we want to query the type and record it
|
||||||
// in bit fields (1 bit for each subpass).
|
// in bit fields (1 bit for each subpass).
|
||||||
uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0;
|
uint32_t colorRead = 0, colorWrite = 0, depthRead = 0, depthWrite = 0, inputDependencies = 0;
|
||||||
|
|
||||||
uint32_t i = 0;
|
|
||||||
|
|
||||||
// For all subpasses (see above description about bit field for this).
|
// For all subpasses (see above description about bit field for this).
|
||||||
for (auto& subpass : subpasses)
|
for (uint32_t i = 0; auto& subpass : subpasses)
|
||||||
{
|
{
|
||||||
|
// skip if subpass is not valid
|
||||||
|
if (subpass->HasNoAttachments())
|
||||||
|
continue;
|
||||||
|
|
||||||
// Configure subpass description
|
// Configure subpass description
|
||||||
auto& desc = spDescs[i];
|
auto& desc = spDescs[i];
|
||||||
desc.pColorAttachments = subpass->colorReferences.data();
|
desc.pColorAttachments = subpass->colorReferences.data();
|
||||||
|
@ -186,8 +203,11 @@ namespace SHADE
|
||||||
|
|
||||||
// Loop through all subpasses again but this time we use the bit field to initialize
|
// Loop through all subpasses again but this time we use the bit field to initialize
|
||||||
// the dependencies.
|
// the dependencies.
|
||||||
for (i = 0; i < subpasses.size(); ++i)
|
for (uint32_t i = 0; auto & subpass : subpasses)
|
||||||
{
|
{
|
||||||
|
if (subpass->HasNoAttachments())
|
||||||
|
continue;
|
||||||
|
|
||||||
vk::PipelineStageFlags srcStage;
|
vk::PipelineStageFlags srcStage;
|
||||||
vk::PipelineStageFlags dstStage;
|
vk::PipelineStageFlags dstStage;
|
||||||
vk::AccessFlags srcAccess;
|
vk::AccessFlags srcAccess;
|
||||||
|
@ -245,6 +265,8 @@ namespace SHADE
|
||||||
|
|
||||||
// initialize input descriptors
|
// initialize input descriptors
|
||||||
subpasses[i]->CreateInputDescriptors();
|
subpasses[i]->CreateInputDescriptors();
|
||||||
|
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,6 +365,7 @@ namespace SHADE
|
||||||
, spDeps{ std::move(rhs.spDeps) }
|
, spDeps{ std::move(rhs.spDeps) }
|
||||||
, nodeComputes{ std::move(rhs.nodeComputes) }
|
, nodeComputes{ std::move(rhs.nodeComputes) }
|
||||||
, name { std::move(rhs.name) }
|
, name { std::move(rhs.name) }
|
||||||
|
, ISelfHandle<SHRenderGraphNode>{std::move(rhs)}
|
||||||
|
|
||||||
{
|
{
|
||||||
rhs.renderpass = {};
|
rhs.renderpass = {};
|
||||||
|
@ -419,7 +442,7 @@ namespace SHADE
|
||||||
return subpass;
|
return subpass;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, float numWorkGroupScale/* = 1.0f*/) noexcept
|
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, uint32_t variableDescCount/* = 0*/, float numWorkGroupScale/* = 1.0f*/) noexcept
|
||||||
{
|
{
|
||||||
// Look for the required resources in the graph
|
// Look for the required resources in the graph
|
||||||
std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{};
|
std::vector<Handle<SHRenderGraphResource>> nodeComputeResources{};
|
||||||
|
@ -435,7 +458,7 @@ namespace SHADE
|
||||||
std::vector<Handle<SHRenderGraphResource>> temp (nodeComputeResources);
|
std::vector<Handle<SHRenderGraphResource>> temp (nodeComputeResources);
|
||||||
|
|
||||||
// Create the subpass compute with the resources
|
// Create the subpass compute with the resources
|
||||||
auto nodeCompute = graphStorage->resourceHub->Create<SHRenderGraphNodeCompute>(std::move(nodeName), graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty());
|
auto nodeCompute = graphStorage->resourceHub->Create<SHRenderGraphNodeCompute>(std::move(nodeName), graphStorage, computeShaderModule, std::move(nodeComputeResources), std::move (dynamicBufferBindings), nodeComputes.empty(), variableDescCount);
|
||||||
nodeComputes.push_back(nodeCompute);
|
nodeComputes.push_back(nodeCompute);
|
||||||
|
|
||||||
for (auto& resource : temp)
|
for (auto& resource : temp)
|
||||||
|
@ -483,6 +506,68 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNode::StandaloneConfigureAttDesc(bool isLastNode) noexcept
|
||||||
|
{
|
||||||
|
// key is handle ID, value is final layout.
|
||||||
|
std::unordered_map<uint32_t, vk::ImageLayout> resourceAttFinalLayouts;
|
||||||
|
if (!subpasses.empty())
|
||||||
|
{
|
||||||
|
// We first want to take all resources track their layout as undefined at the start of the node/renderpass
|
||||||
|
for (auto& resource : attResources)
|
||||||
|
{
|
||||||
|
resource->GetInfoTracker()->TrackLayout(GetHandle(), {}, vk::ImageLayout::eUndefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
// attempt to get all final layouts for all resources
|
||||||
|
for (auto& subpass : subpasses)
|
||||||
|
{
|
||||||
|
for (auto& color : subpass->colorReferences)
|
||||||
|
{
|
||||||
|
// If final renderpass and attachment is a COLOR_PRESENT resource, make resource transition to present after last subpass
|
||||||
|
if (isLastNode && (attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)))
|
||||||
|
resourceAttFinalLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
|
||||||
|
else
|
||||||
|
resourceAttFinalLayouts[color.attachment] = color.layout;
|
||||||
|
|
||||||
|
attResources[color.attachment]->infoTracker->TrackLayout(GetHandle(), subpass, color.layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& depth : subpass->depthReferences)
|
||||||
|
{
|
||||||
|
resourceAttFinalLayouts[depth.attachment] = depth.layout;
|
||||||
|
attResources[depth.attachment]->infoTracker->TrackLayout(GetHandle(), subpass, depth.layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& input : subpass->inputReferences)
|
||||||
|
{
|
||||||
|
resourceAttFinalLayouts[input.attachment] = input.layout;
|
||||||
|
attResources[input.attachment]->infoTracker->TrackLayout(GetHandle(), subpass, input.layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t j = 0; j < attachmentDescriptions.size(); ++j)
|
||||||
|
{
|
||||||
|
auto& att = attachmentDescriptions[j];
|
||||||
|
auto& resource = attResources[j];
|
||||||
|
|
||||||
|
// If resource is from another render graph, use the final layout it had when it was last used in that graph. This is initialized in LinkNonOwningResource.
|
||||||
|
// We also want to load the attachment, not "don't care".
|
||||||
|
if (resource->resourceTypeFlags & SHUtilities::ConvertEnum(SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED) &&
|
||||||
|
graphStorage->nonOwningResourceInitialLayouts.contains(resource.GetId().Raw))
|
||||||
|
{
|
||||||
|
att.initialLayout = graphStorage->nonOwningResourceInitialLayouts.at(resource.GetId().Raw);
|
||||||
|
att.loadOp = vk::AttachmentLoadOp::eLoad;
|
||||||
|
att.stencilLoadOp = vk::AttachmentLoadOp::eLoad;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
att.initialLayout = vk::ImageLayout::eUndefined;
|
||||||
|
|
||||||
|
att.finalLayout = resourceAttFinalLayouts[j];
|
||||||
|
resource->GetInfoTracker()->TrackLayout(GetHandle(), {}, att.finalLayout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -509,14 +594,14 @@ namespace SHADE
|
||||||
// remove attachment reference
|
// remove attachment reference
|
||||||
attachmentDescriptions.erase (attachmentDescriptions.begin() + index);
|
attachmentDescriptions.erase (attachmentDescriptions.begin() + index);
|
||||||
|
|
||||||
|
// erase from mapping as well
|
||||||
|
resourceAttachmentMapping->erase(resourceHandleID);
|
||||||
|
|
||||||
// Remove footprint of attachment from all subpasses as well
|
// Remove footprint of attachment from all subpasses as well
|
||||||
for (auto it = subpasses.begin(); it != subpasses.end(); ++it)
|
for (auto it = subpasses.begin(); it != subpasses.end(); ++it)
|
||||||
{
|
{
|
||||||
// attempt to detach resource from subpass
|
// If the subpass uses the resource, just remove the subpass since the subpass will be invalid
|
||||||
(*it)->DetachResource(resourceName, index);
|
if ((*it)->UsesResource(index))
|
||||||
|
|
||||||
// If the subpass ends up having no attachments after, erase it from the node
|
|
||||||
if ((*it)->HasNoAttachments())
|
|
||||||
{
|
{
|
||||||
// erase from indexing
|
// erase from indexing
|
||||||
subpassIndexing.erase((*it)->GetName());
|
subpassIndexing.erase((*it)->GetName());
|
||||||
|
@ -530,6 +615,24 @@ namespace SHADE
|
||||||
for (uint32_t i = 0; i < subpasses.size(); ++i)
|
for (uint32_t i = 0; i < subpasses.size(); ++i)
|
||||||
subpasses[i]->SetIndex(i);
|
subpasses[i]->SetIndex(i);
|
||||||
|
|
||||||
|
// remove node computes using the resource
|
||||||
|
for (auto it = nodeComputes.begin(); it != nodeComputes.end(); ++it)
|
||||||
|
{
|
||||||
|
if ((*it)->UsesResource(resourceHandleID))
|
||||||
|
{
|
||||||
|
it = nodeComputes.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// recompute the barriers for the other computes
|
||||||
|
for (auto it = nodeComputes.begin(); it != nodeComputes.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it == nodeComputes.begin())
|
||||||
|
(*it)->SetFollowingEndRenderpass(true);
|
||||||
|
|
||||||
|
(*it)->InitializeBarriers();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -537,37 +640,40 @@ namespace SHADE
|
||||||
|
|
||||||
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
uint32_t framebufferIndex = (framebuffers.size() > 1) ? frameIndex : 0;
|
if (renderpass)
|
||||||
commandBuffer->BeginRenderpass(renderpass, framebuffers[framebufferIndex]);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < subpasses.size(); ++i)
|
|
||||||
{
|
{
|
||||||
subpasses[i]->Execute(commandBuffer, descPool, frameIndex);
|
uint32_t framebufferIndex = (framebuffers.size() > 1) ? frameIndex : 0;
|
||||||
|
commandBuffer->BeginRenderpass(renderpass, framebuffers[framebufferIndex]);
|
||||||
|
|
||||||
// Go to next subpass if not last subpass
|
for (uint32_t i = 0; i < subpasses.size(); ++i)
|
||||||
if (i != static_cast<uint32_t>(subpasses.size()) - 1u)
|
{
|
||||||
commandBuffer->NextSubpass();
|
subpasses[i]->Execute(commandBuffer, descPool, frameIndex);
|
||||||
|
|
||||||
|
// Go to next subpass if not last subpass
|
||||||
|
if (i != static_cast<uint32_t>(subpasses.size()) - 1u && !subpasses[i]->HasNoAttachments())
|
||||||
|
commandBuffer->NextSubpass();
|
||||||
|
}
|
||||||
|
|
||||||
|
commandBuffer->EndRenderpass();
|
||||||
|
|
||||||
|
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE);
|
||||||
|
|
||||||
|
// We bind these 2 descriptor sets here because they apply to all node computes
|
||||||
|
if (!nodeComputes.empty())
|
||||||
|
{
|
||||||
|
commandBuffer->ForceSetPipelineLayout(SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE).dummyPipelineLayout, SH_PIPELINE_TYPE::COMPUTE);
|
||||||
|
|
||||||
|
// bind static global data
|
||||||
|
SHGlobalDescriptorSets::BindStaticGlobalData(commandBuffer, SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::STATIC_DATA));
|
||||||
|
|
||||||
|
// bind lighting data
|
||||||
|
SHGlobalDescriptorSets::BindLightingData(commandBuffer, SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::LIGHTS), frameIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute all subpass computes
|
||||||
|
for (auto& sbCompute : nodeComputes)
|
||||||
|
sbCompute->Execute(commandBuffer, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
commandBuffer->EndRenderpass();
|
|
||||||
|
|
||||||
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE);
|
|
||||||
|
|
||||||
// We bind these 2 descriptor sets here because they apply to all node computes
|
|
||||||
if (!nodeComputes.empty())
|
|
||||||
{
|
|
||||||
commandBuffer->ForceSetPipelineLayout(SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE).dummyPipelineLayout, SH_PIPELINE_TYPE::COMPUTE);
|
|
||||||
|
|
||||||
// bind static global data
|
|
||||||
SHGlobalDescriptorSets::BindStaticGlobalData(commandBuffer, SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::STATIC_DATA));
|
|
||||||
|
|
||||||
// bind lighting data
|
|
||||||
SHGlobalDescriptorSets::BindLightingData(commandBuffer, SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::LIGHTS), frameIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute all subpass computes
|
|
||||||
for (auto& sbCompute : nodeComputes)
|
|
||||||
sbCompute->Execute(commandBuffer, frameIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SHVkPipeline> SHRenderGraphNode::GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept
|
Handle<SHVkPipeline> SHRenderGraphNode::GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept
|
||||||
|
@ -599,6 +705,77 @@ namespace SHADE
|
||||||
batcher.FinaliseBatches(graphStorage->logicalDevice, descPool, frameIndex);
|
batcher.FinaliseBatches(graphStorage->logicalDevice, descPool, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
This function simply appends to the container of VkAttachmentDescription
|
||||||
|
and attResources. It will assume the resource is used standalone in the
|
||||||
|
node and will not account for its usage in other nodes. As such its
|
||||||
|
initialLayout will always be UNDEFINED and its finalLayout will be
|
||||||
|
whatever is calculated if the node is regenerated using
|
||||||
|
StandaloneRegnerate. This function also does not affect the render graph
|
||||||
|
while its running since the 2 containers above have already been copied
|
||||||
|
to the GPU.
|
||||||
|
|
||||||
|
\param resourceName
|
||||||
|
The name of the resource for getting the resource.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHRenderGraphNode::RuntimeLinkResource(std::string resourceName) noexcept
|
||||||
|
{
|
||||||
|
// Get new resource
|
||||||
|
Handle<SHRenderGraphResource> newResource = graphStorage->graphResources->at(resourceName);
|
||||||
|
|
||||||
|
// append new resource to container
|
||||||
|
attResources.push_back(newResource);
|
||||||
|
|
||||||
|
attachmentDescriptions.push_back(vk::AttachmentDescription
|
||||||
|
{
|
||||||
|
.format = newResource->GetResourceFormat(),
|
||||||
|
.samples = vk::SampleCountFlagBits::e1,
|
||||||
|
.loadOp = vk::AttachmentLoadOp::eClear,
|
||||||
|
.storeOp = vk::AttachmentStoreOp::eStore,
|
||||||
|
.stencilLoadOp = vk::AttachmentLoadOp::eClear,
|
||||||
|
.stencilStoreOp = vk::AttachmentStoreOp::eStore,
|
||||||
|
});
|
||||||
|
|
||||||
|
resourceAttachmentMapping->try_emplace(newResource.GetId().Raw, attachmentDescriptions.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHSubpass> SHRenderGraphNode::RuntimeAddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept
|
||||||
|
{
|
||||||
|
return AddSubpass(std::move (subpassName), viewport, renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
USE WITH CAUTION because the function does not reevaluate resource
|
||||||
|
layouts in attachment descriptions. All resources here will start at
|
||||||
|
UNDEFINED and end at whatever the last subpass using the attachment
|
||||||
|
specifies. It will also not support render graph node computes given its
|
||||||
|
complexity if it has to be accounted for.
|
||||||
|
|
||||||
|
IN SHORT, IT GENERATES A RENDERPASS AS IF ITS THE ONLY NODE
|
||||||
|
IN THE RENDER GRAPH. SEE NOTES IN SHRenderGraph.h
|
||||||
|
|
||||||
|
This function is mainly meant for nodes that are dynamic (in hindsight,
|
||||||
|
there really should have been a distinction between static and dynamic
|
||||||
|
nodes).
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHRenderGraphNode::RuntimeStandaloneRegenerate(void) noexcept
|
||||||
|
{
|
||||||
|
StandaloneConfigureAttDesc(false);
|
||||||
|
ConfigureSubpasses();
|
||||||
|
CreateRenderpass();
|
||||||
|
CreateFramebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -633,4 +810,15 @@ namespace SHADE
|
||||||
return attResources;
|
return attResources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHRenderGraphNodeCompute> SHRenderGraphNode::GetNodeCompute(std::string nodeComputeName) const noexcept
|
||||||
|
{
|
||||||
|
for (auto nc : nodeComputes)
|
||||||
|
{
|
||||||
|
if (nc->name == nodeComputeName)
|
||||||
|
return nc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -93,6 +93,9 @@ namespace SHADE
|
||||||
void CreateFramebuffer(void) noexcept;
|
void CreateFramebuffer(void) noexcept;
|
||||||
void HandleResize (void) noexcept;
|
void HandleResize (void) noexcept;
|
||||||
void ConfigureSubpasses (void) noexcept;
|
void ConfigureSubpasses (void) noexcept;
|
||||||
|
bool DetachResource(std::string const& resourceName, uint64_t resourceHandleID) noexcept;
|
||||||
|
void AddDummySubpassIfNeeded(void) noexcept;
|
||||||
|
void StandaloneConfigureAttDesc (bool isLastNode) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -105,15 +108,17 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
Handle<SHSubpass> AddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept;
|
Handle<SHSubpass> AddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept;
|
||||||
Handle<SHRenderGraphNodeCompute> AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept;
|
Handle<SHRenderGraphNodeCompute> AddNodeCompute(std::string nodeName, Handle<SHVkShaderModule> computeShaderModule, std::initializer_list<std::string> resources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings = {}, uint32_t variableDescCount = 0, float numWorkGroupScale = 1.0f) noexcept;
|
||||||
void AddDummySubpassIfNeeded (void) noexcept;
|
|
||||||
bool DetachResource (std::string const& resourceName, uint64_t resourceHandleID) noexcept;
|
|
||||||
|
|
||||||
// TODO: RemoveSubpass()
|
void Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
||||||
void Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
Handle<SHVkPipeline> GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept;
|
||||||
Handle<SHVkPipeline> GetOrCreatePipeline(std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>> const& vsFsPair, Handle<SHSubpass> subpass) noexcept;
|
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
||||||
void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
|
|
||||||
|
// Runtime functions that don't affect the renderpass
|
||||||
|
void RuntimeLinkResource(std::string resourceName) noexcept;
|
||||||
|
Handle<SHSubpass> RuntimeAddSubpass(std::string subpassName, Handle<SHViewport> viewport, Handle<SHRenderer> renderer) noexcept;
|
||||||
|
void RuntimeStandaloneRegenerate (void) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
|
@ -122,6 +127,7 @@ namespace SHADE
|
||||||
Handle<SHSubpass> GetSubpass(std::string_view subpassName) const noexcept;
|
Handle<SHSubpass> GetSubpass(std::string_view subpassName) const noexcept;
|
||||||
Handle<SHRenderGraphResource> GetResource (uint32_t resourceIndex) const noexcept;
|
Handle<SHRenderGraphResource> GetResource (uint32_t resourceIndex) const noexcept;
|
||||||
std::vector<Handle<SHRenderGraphResource>> const& GetResources (void) const noexcept;
|
std::vector<Handle<SHRenderGraphResource>> const& GetResources (void) const noexcept;
|
||||||
|
Handle<SHRenderGraphNodeCompute> GetNodeCompute (std::string nodeComputeName) const noexcept;
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,56 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale/* = 1.0f*/) noexcept
|
|
||||||
|
bool SHRenderGraphNodeCompute::UsesResource(uint64_t resourceHandleID) const noexcept
|
||||||
|
{
|
||||||
|
for (auto& resource : resources)
|
||||||
|
{
|
||||||
|
if (resource.GetId().Raw == resourceHandleID)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::InitializeBarriers(void) noexcept
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; auto & barriers : memoryBarriers)
|
||||||
|
{
|
||||||
|
barriers.clear();
|
||||||
|
|
||||||
|
for (auto& resource : resources)
|
||||||
|
{
|
||||||
|
vk::AccessFlags srcAccessMask = (followingEndRenderpass) ? vk::AccessFlagBits::eInputAttachmentRead : (vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite);
|
||||||
|
barriers.push_back(vk::ImageMemoryBarrier
|
||||||
|
{
|
||||||
|
.srcAccessMask = srcAccessMask,
|
||||||
|
.dstAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite,
|
||||||
|
.oldLayout = vk::ImageLayout::eGeneral,
|
||||||
|
.newLayout = vk::ImageLayout::eGeneral,
|
||||||
|
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||||
|
.image = resource->GetImage((resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? i : 0)->GetVkImage(),
|
||||||
|
.subresourceRange = vk::ImageSubresourceRange
|
||||||
|
{
|
||||||
|
.aspectMask = resource->imageAspectFlags,
|
||||||
|
.baseMipLevel = 0,
|
||||||
|
.levelCount = resource->mipLevels,
|
||||||
|
.baseArrayLayer = 0,
|
||||||
|
.layerCount = 1,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::SetFollowingEndRenderpass(uint32_t flag) noexcept
|
||||||
|
{
|
||||||
|
followingEndRenderpass = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHRenderGraphNodeCompute::SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, uint32_t variableDescCount, float inNumWorkGroupScale/* = 1.0f*/) noexcept
|
||||||
: computePipeline{}
|
: computePipeline{}
|
||||||
, pipelineLayout{}
|
, pipelineLayout{}
|
||||||
, resources{}
|
, resources{}
|
||||||
|
@ -68,10 +117,12 @@ namespace SHADE
|
||||||
// check if all layouts are there
|
// check if all layouts are there
|
||||||
if (layouts.size() == descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE) + 1)
|
if (layouts.size() == descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE) + 1)
|
||||||
{
|
{
|
||||||
|
Handle<SHVkDescriptorSetLayout> computeResourceLayout = {};
|
||||||
|
computeResourceLayout = layouts[descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE)];
|
||||||
|
|
||||||
// create compute resources
|
// create compute resources
|
||||||
computeResource = graphStorage->resourceHub->Create<ComputeResource>();
|
computeResource = graphStorage->resourceHub->Create<ComputeResource>();
|
||||||
auto computeResourceLayout = layouts[descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE)];
|
computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, {variableDescCount});
|
||||||
computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 });
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
for (auto set : computeResource->descSet->GetVkHandle())
|
for (auto set : computeResource->descSet->GetVkHandle())
|
||||||
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] " + name + " Resources");
|
SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] " + name + " Resources");
|
||||||
|
@ -91,6 +142,11 @@ namespace SHADE
|
||||||
|
|
||||||
void SHRenderGraphNodeCompute::Execute(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
void SHRenderGraphNodeCompute::Execute(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
|
||||||
{
|
{
|
||||||
|
for (auto& fn : preComputeFunctions)
|
||||||
|
{
|
||||||
|
fn (cmdBuffer, frameIndex);
|
||||||
|
}
|
||||||
|
|
||||||
// bind the compute pipeline
|
// bind the compute pipeline
|
||||||
cmdBuffer->BindPipeline(computePipeline);
|
cmdBuffer->BindPipeline(computePipeline);
|
||||||
|
|
||||||
|
@ -157,35 +213,7 @@ namespace SHADE
|
||||||
groupSizeX = maxWidth / workGroupSizeX;
|
groupSizeX = maxWidth / workGroupSizeX;
|
||||||
groupSizeY = maxHeight / workGroupSizeY;
|
groupSizeY = maxHeight / workGroupSizeY;
|
||||||
|
|
||||||
for (uint32_t i = 0; auto& barriers : memoryBarriers)
|
InitializeBarriers();
|
||||||
{
|
|
||||||
barriers.clear();
|
|
||||||
|
|
||||||
for (auto& resource : resources)
|
|
||||||
{
|
|
||||||
vk::AccessFlags srcAccessMask = (followingEndRenderpass) ? vk::AccessFlagBits::eInputAttachmentRead : (vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite);
|
|
||||||
barriers.push_back(vk::ImageMemoryBarrier
|
|
||||||
{
|
|
||||||
.srcAccessMask = srcAccessMask,
|
|
||||||
.dstAccessMask = vk::AccessFlagBits::eShaderRead | vk::AccessFlagBits::eShaderWrite,
|
|
||||||
.oldLayout = vk::ImageLayout::eGeneral,
|
|
||||||
.newLayout = vk::ImageLayout::eGeneral,
|
|
||||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
|
||||||
.image = resource->GetImage((resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? i : 0)->GetVkImage(),
|
|
||||||
.subresourceRange = vk::ImageSubresourceRange
|
|
||||||
{
|
|
||||||
.aspectMask = resource->imageAspectFlags,
|
|
||||||
.baseMipLevel = 0,
|
|
||||||
.levelCount = resource->mipLevels,
|
|
||||||
.baseArrayLayer = 0,
|
|
||||||
.layerCount = 1,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRenderGraphNodeCompute::SetDynamicOffsets(std::span<uint32_t> perFrameSizes) noexcept
|
void SHRenderGraphNodeCompute::SetDynamicOffsets(std::span<uint32_t> perFrameSizes) noexcept
|
||||||
|
@ -219,4 +247,17 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::ModifyWriteDescImageComputeResource(uint32_t binding, SHVkDescriptorSetGroup::viewSamplerLayout const& viewSamplerLayout, uint32_t descArrayIndex) noexcept
|
||||||
|
{
|
||||||
|
static constexpr uint32_t COMPUTE_RESOURCE_SET_INDEX = 0;
|
||||||
|
computeResource->descSet->ModifyWriteDescImage(COMPUTE_RESOURCE_SET_INDEX, binding, viewSamplerLayout, descArrayIndex);
|
||||||
|
computeResource->descSet->UpdateDescriptorSetImage(COMPUTE_RESOURCE_SET_INDEX, binding, descArrayIndex);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNodeCompute::AddPreComputeFunction(PreComputeFunction const& fn) noexcept
|
||||||
|
{
|
||||||
|
preComputeFunctions.push_back(fn);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,10 @@ namespace SHADE
|
||||||
|
|
||||||
class SHRenderGraphNodeCompute
|
class SHRenderGraphNodeCompute
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
using PreComputeFunction = std::function<void(Handle<SHVkCommandBuffer>, uint32_t)>;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Binding of set SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE
|
// Binding of set SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE
|
||||||
struct ComputeResource
|
struct ComputeResource
|
||||||
|
@ -73,8 +77,23 @@ namespace SHADE
|
||||||
//! Name of this node
|
//! Name of this node
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
|
std::vector<PreComputeFunction> preComputeFunctions;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
bool UsesResource (uint64_t resourceHandleID) const noexcept;
|
||||||
|
void InitializeBarriers (void) noexcept;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE SETTERS AND GETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
void SetFollowingEndRenderpass (uint32_t flag) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, float inNumWorkGroupScale = 1.0f) noexcept;
|
SHRenderGraphNodeCompute(std::string nodeName, Handle<SHRenderGraphStorage> graphStorage, Handle<SHVkShaderModule> computeShaderModule, std::vector<Handle<SHRenderGraphResource>>&& subpassComputeResources, std::unordered_set<BindingAndSetHash>&& dynamicBufferBindings, bool followingEndRP, uint32_t variableDescCount, float inNumWorkGroupScale = 1.0f) noexcept;
|
||||||
|
|
||||||
void Execute (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
void Execute (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;
|
||||||
void HandleResize (void) noexcept;
|
void HandleResize (void) noexcept;
|
||||||
|
@ -84,7 +103,9 @@ namespace SHADE
|
||||||
|
|
||||||
void ModifyWriteDescBufferComputeResource (uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
void ModifyWriteDescBufferComputeResource (uint32_t binding, std::span<Handle<SHVkBuffer>> const& buffers, uint32_t offset, uint32_t range) noexcept;
|
||||||
void ModifyWriteDescImageComputeResource(uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept;
|
void ModifyWriteDescImageComputeResource(uint32_t binding, std::span<SHVkDescriptorSetGroup::viewSamplerLayout> const& viewSamplerLayouts) noexcept;
|
||||||
|
void ModifyWriteDescImageComputeResource(uint32_t binding, SHVkDescriptorSetGroup::viewSamplerLayout const& viewSamplerLayout, uint32_t descArrayIndex) noexcept;
|
||||||
|
|
||||||
|
void AddPreComputeFunction (PreComputeFunction const& fn) noexcept;
|
||||||
|
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
friend class SHRenderGraphNode;
|
friend class SHRenderGraphNode;
|
||||||
|
|
|
@ -78,7 +78,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHRenderGraphResource::SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
|
SHRenderGraphResource::SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags, bool inResizeWithWindow) noexcept
|
||||||
: graphStorage{renderGraphStorage}
|
: graphStorage{renderGraphStorage}
|
||||||
, resourceTypeFlags{ }
|
, resourceTypeFlags{ }
|
||||||
, resourceFormat{ format }
|
, resourceFormat{ format }
|
||||||
|
@ -88,6 +88,7 @@ namespace SHADE
|
||||||
, height{ h }
|
, height{ h }
|
||||||
, mipLevels{ levels }
|
, mipLevels{ levels }
|
||||||
, resourceName{ name }
|
, resourceName{ name }
|
||||||
|
, resizeWithWindow { inResizeWithWindow }
|
||||||
{
|
{
|
||||||
// If the resource type is an arbitrary image and not swapchain image
|
// If the resource type is an arbitrary image and not swapchain image
|
||||||
if (typeFlags.size() == 1 && *typeFlags.begin() == SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)
|
if (typeFlags.size() == 1 && *typeFlags.begin() == SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)
|
||||||
|
@ -210,6 +211,7 @@ namespace SHADE
|
||||||
, imageAspectFlags{ rhs.imageAspectFlags }
|
, imageAspectFlags{ rhs.imageAspectFlags }
|
||||||
, graphStorage{rhs.graphStorage}
|
, graphStorage{rhs.graphStorage}
|
||||||
, infoTracker {std::move (rhs.infoTracker)}
|
, infoTracker {std::move (rhs.infoTracker)}
|
||||||
|
, resizeWithWindow{rhs.resizeWithWindow}
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -242,7 +244,8 @@ namespace SHADE
|
||||||
mipLevels = rhs.mipLevels;
|
mipLevels = rhs.mipLevels;
|
||||||
imageAspectFlags = rhs.imageAspectFlags;
|
imageAspectFlags = rhs.imageAspectFlags;
|
||||||
graphStorage = rhs.graphStorage;
|
graphStorage = rhs.graphStorage;
|
||||||
infoTracker = std::move(infoTracker);
|
infoTracker = std::move(rhs.infoTracker);
|
||||||
|
resizeWithWindow = rhs.resizeWithWindow;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,11 +96,14 @@ namespace SHADE
|
||||||
//! For tracking resource states in stages of the render graphs
|
//! For tracking resource states in stages of the render graphs
|
||||||
Handle<InfoTracker> infoTracker;
|
Handle<InfoTracker> infoTracker;
|
||||||
|
|
||||||
|
//! Whether or not to resize (recreate vulkan image) when window resizes
|
||||||
|
bool resizeWithWindow;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
|
SHRenderGraphResource(Handle<SHRenderGraphStorage> renderGraphStorage, std::string const& name, std::initializer_list<SH_RENDER_GRAPH_RESOURCE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags, bool inResizeWithWindow) noexcept;
|
||||||
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
|
SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
|
||||||
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
|
SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
|
||||||
~SHRenderGraphResource(void) noexcept;
|
~SHRenderGraphResource(void) noexcept;
|
||||||
|
|
|
@ -77,6 +77,7 @@ namespace SHADE
|
||||||
, name { rhs.name }
|
, name { rhs.name }
|
||||||
, viewport {rhs.viewport}
|
, viewport {rhs.viewport}
|
||||||
, renderer {rhs.renderer}
|
, renderer {rhs.renderer}
|
||||||
|
, companionSubpass {rhs.companionSubpass}
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -113,6 +114,7 @@ namespace SHADE
|
||||||
name = std::move(rhs.name);
|
name = std::move(rhs.name);
|
||||||
renderer = rhs.renderer;
|
renderer = rhs.renderer;
|
||||||
viewport = rhs.viewport;
|
viewport = rhs.viewport;
|
||||||
|
companionSubpass = rhs.companionSubpass;
|
||||||
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -162,7 +164,7 @@ namespace SHADE
|
||||||
switch (attachmentDescriptionType)
|
switch (attachmentDescriptionType)
|
||||||
{
|
{
|
||||||
case SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH:
|
case SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH:
|
||||||
imageLayout = vk::ImageLayout::eDepthAttachmentOptimal;
|
imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
|
||||||
break;
|
break;
|
||||||
case SH_RENDER_GRAPH_RESOURCE_FLAGS::STENCIL:
|
case SH_RENDER_GRAPH_RESOURCE_FLAGS::STENCIL:
|
||||||
imageLayout = vk::ImageLayout::eStencilAttachmentOptimal;
|
imageLayout = vk::ImageLayout::eStencilAttachmentOptimal;
|
||||||
|
@ -211,25 +213,38 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
commandBuffer->BeginLabeledSegment(name);
|
commandBuffer->BeginLabeledSegment(name);
|
||||||
|
|
||||||
// Ensure correct transforms are provided
|
if (!HasNoAttachments())
|
||||||
superBatch->UpdateBuffers(frameIndex, descPool);
|
|
||||||
|
|
||||||
if (viewport)
|
|
||||||
{
|
{
|
||||||
// set viewport and scissor
|
// Ensure correct transforms are provided
|
||||||
uint32_t w = static_cast<uint32_t>(viewport->GetWidth());
|
superBatch->UpdateBuffers(frameIndex, descPool);
|
||||||
uint32_t h = static_cast<uint32_t>(viewport->GetHeight());
|
|
||||||
commandBuffer->SetViewportScissor(static_cast<float>(w), static_cast<float>(h), w, h);
|
if (viewport)
|
||||||
|
{
|
||||||
|
// set viewport and scissor
|
||||||
|
uint32_t w = static_cast<uint32_t>(viewport->GetWidth());
|
||||||
|
uint32_t h = static_cast<uint32_t>(viewport->GetHeight());
|
||||||
|
commandBuffer->SetViewportScissor(static_cast<float>(w), static_cast<float>(h), w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
||||||
|
|
||||||
|
if (renderer)
|
||||||
|
renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex);
|
||||||
|
|
||||||
|
// If companion subpass is not a valid handle, render super batch normally
|
||||||
|
if (!companionSubpass.companion)
|
||||||
|
{
|
||||||
|
// Draw all the batches
|
||||||
|
superBatch->Draw(commandBuffer, frameIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if not bind pipeline for companion and and execute draw command
|
||||||
|
commandBuffer->BindPipeline(companionSubpass.pipeline);
|
||||||
|
companionSubpass.companion->superBatch->Draw(commandBuffer, frameIndex, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
|
|
||||||
|
|
||||||
if (renderer)
|
|
||||||
renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex);
|
|
||||||
|
|
||||||
// Draw all the batches
|
|
||||||
superBatch->Draw(commandBuffer, frameIndex);
|
|
||||||
|
|
||||||
// Draw all the exterior draw calls
|
// Draw all the exterior draw calls
|
||||||
for (auto& drawCall : exteriorDrawCalls)
|
for (auto& drawCall : exteriorDrawCalls)
|
||||||
{
|
{
|
||||||
|
@ -265,43 +280,27 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHSubpass::DetachResource(std::string const& resourceName, uint32_t attachmentIndex) noexcept
|
bool SHSubpass::UsesResource(uint32_t attachmentIndex) noexcept
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < colorReferences.size(); ++i)
|
for (uint32_t i = 0; i < colorReferences.size(); ++i)
|
||||||
{
|
{
|
||||||
if (colorReferences[i].attachment == attachmentIndex)
|
if (colorReferences[i].attachment == attachmentIndex)
|
||||||
{
|
return true;
|
||||||
colorReferences.erase (colorReferences.begin() + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < depthReferences.size(); ++i)
|
for (uint32_t i = 0; i < depthReferences.size(); ++i)
|
||||||
{
|
{
|
||||||
if (depthReferences[i].attachment == attachmentIndex)
|
if (depthReferences[i].attachment == attachmentIndex)
|
||||||
{
|
return true;
|
||||||
depthReferences.erase(depthReferences.begin() + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < inputReferences.size(); ++i)
|
for (uint32_t i = 0; i < inputReferences.size(); ++i)
|
||||||
{
|
{
|
||||||
if (inputReferences[i].attachment == attachmentIndex)
|
if (inputReferences[i].attachment == attachmentIndex)
|
||||||
{
|
return true;
|
||||||
inputReferences.erase(inputReferences.begin() + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < inputNames.size(); ++i)
|
return false;
|
||||||
{
|
|
||||||
if (inputNames[i] == resourceName)
|
|
||||||
{
|
|
||||||
inputNames.erase(inputNames.begin() + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SHSubpass::HasNoAttachments(void) const noexcept
|
bool SHSubpass::HasNoAttachments(void) const noexcept
|
||||||
|
@ -458,6 +457,12 @@ namespace SHADE
|
||||||
subpassIndex = index;
|
subpassIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHSubpass::SetCompanionSubpass(Handle<SHSubpass> companion, Handle<SHVkPipeline> pipeline) noexcept
|
||||||
|
{
|
||||||
|
companionSubpass.companion = companion;
|
||||||
|
companionSubpass.pipeline = pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,23 @@ namespace SHADE
|
||||||
class SHVkSampler;
|
class SHVkSampler;
|
||||||
class SHRenderer;
|
class SHRenderer;
|
||||||
class SHViewport;
|
class SHViewport;
|
||||||
|
class SHVkPipeline;
|
||||||
|
|
||||||
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
|
class SH_API SHSubpass : public ISelfHandle<SHSubpass>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using ExteriorDrawCallFunction = std::function<void(Handle<SHVkCommandBuffer>, Handle<SHRenderer>, uint32_t)>;
|
using ExteriorDrawCallFunction = std::function<void(Handle<SHVkCommandBuffer>, Handle<SHRenderer>, uint32_t)>;
|
||||||
|
|
||||||
|
// Allows for subpasses to run using a companions data
|
||||||
|
struct CompanionSubpass
|
||||||
|
{
|
||||||
|
// subpass whose data will be borrowed to draw
|
||||||
|
Handle<SHSubpass> companion;
|
||||||
|
|
||||||
|
// Pipeline that will be used for all the draw calls from all batches of the companion subpass
|
||||||
|
Handle<SHVkPipeline> pipeline;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
|
@ -94,6 +105,15 @@ namespace SHADE
|
||||||
// For identifying subpasses
|
// For identifying subpasses
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
|
//! Optional component to a companion subpass. If the subpass handle of this object
|
||||||
|
//! is valid, the subpass will be drawn using this companion's data.
|
||||||
|
CompanionSubpass companionSubpass;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
bool UsesResource(uint32_t attachmentIndex) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -119,7 +139,6 @@ namespace SHADE
|
||||||
void Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
void Execute(Handle<SHVkCommandBuffer> commandBuffer, Handle<SHVkDescriptorPool> descPool, uint32_t frameIndex) noexcept;
|
||||||
void HandleResize (void) noexcept;
|
void HandleResize (void) noexcept;
|
||||||
void BindInputDescriptorSets (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) const noexcept;
|
void BindInputDescriptorSets (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t setIndex, uint32_t frameIndex) const noexcept;
|
||||||
void DetachResource (std::string const& resourceName, uint32_t attachmentIndex) noexcept;
|
|
||||||
bool HasNoAttachments (void) const noexcept;
|
bool HasNoAttachments (void) const noexcept;
|
||||||
|
|
||||||
void Init(SHResourceHub& resourceManager) noexcept;
|
void Init(SHResourceHub& resourceManager) noexcept;
|
||||||
|
@ -128,19 +147,24 @@ namespace SHADE
|
||||||
void CreateInputDescriptors (void) noexcept;
|
void CreateInputDescriptors (void) noexcept;
|
||||||
void UpdateWriteDescriptors (void) noexcept;
|
void UpdateWriteDescriptors (void) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* GETTERS AND SETTERS */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
private:
|
private:
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE GETTERS AND SETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
void SetIndex (uint32_t index) noexcept;
|
void SetIndex (uint32_t index) noexcept;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Handle<SHRenderGraphNode> const& GetParentNode(void) const noexcept;
|
/*-----------------------------------------------------------------------*/
|
||||||
SHSubPassIndex GetIndex() const noexcept;
|
/* PUBLIC SETTERS AND GETTERS */
|
||||||
Handle<SHSuperBatch> GetSuperBatch(void) const noexcept;
|
/*-----------------------------------------------------------------------*/
|
||||||
|
void SetCompanionSubpass (Handle<SHSubpass> companion, Handle<SHVkPipeline> pipeline) noexcept;
|
||||||
|
|
||||||
|
Handle<SHRenderGraphNode> const& GetParentNode(void) const noexcept;
|
||||||
|
SHSubPassIndex GetIndex() const noexcept;
|
||||||
|
Handle<SHSuperBatch> GetSuperBatch(void) const noexcept;
|
||||||
std::vector<vk::AttachmentReference> const& GetColorAttachmentReferences (void) const noexcept;
|
std::vector<vk::AttachmentReference> const& GetColorAttachmentReferences (void) const noexcept;
|
||||||
vk::Format GetFormatFromAttachmentReference (uint32_t attachmentReference) const noexcept;
|
vk::Format GetFormatFromAttachmentReference (uint32_t attachmentReference) const noexcept;
|
||||||
const std::string& GetName() const;
|
const std::string& GetName() const;
|
||||||
|
|
||||||
friend class SHRenderGraphNode;
|
friend class SHRenderGraphNode;
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
|
|
|
@ -100,6 +100,475 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string SHInputManager::GetKeyCodeName(SH_KEYCODE k) noexcept
|
||||||
|
{
|
||||||
|
int kInt = static_cast<int>(k);
|
||||||
|
//Numbers
|
||||||
|
if (kInt >= static_cast<int>(SH_KEYCODE::NUMBER_0) && kInt <= static_cast<int>(SH_KEYCODE::NUMBER_9))
|
||||||
|
{
|
||||||
|
return std::to_string(kInt - 48);
|
||||||
|
}
|
||||||
|
//Letters
|
||||||
|
if (kInt >= static_cast<int>(SH_KEYCODE::A) && kInt <= static_cast<int>(SH_KEYCODE::Z))
|
||||||
|
{
|
||||||
|
return std::string(1, static_cast<char>(kInt));
|
||||||
|
}
|
||||||
|
//Numpads
|
||||||
|
if (kInt >= static_cast<int>(SH_KEYCODE::NUMPAD_0) && kInt <= static_cast<int>(SH_KEYCODE::NUMPAD_9))
|
||||||
|
{
|
||||||
|
return "Numpad " + std::to_string(kInt - 96);
|
||||||
|
}
|
||||||
|
//Function keys
|
||||||
|
if (kInt >= static_cast<int>(SH_KEYCODE::F1) && kInt <= static_cast<int>(SH_KEYCODE::F24))
|
||||||
|
{
|
||||||
|
return "F" + std::to_string(kInt - 111);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Other keys
|
||||||
|
switch (k)
|
||||||
|
{
|
||||||
|
case SH_KEYCODE::LMB:
|
||||||
|
return "Left Mouse Button";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::RMB:
|
||||||
|
return "Right Mouse Button";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::CANCEL:
|
||||||
|
return "Cancel";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::MMB:
|
||||||
|
return "Middle Mouse Button";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::XMB1:
|
||||||
|
return "X1 Mouse Button";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::XMB2:
|
||||||
|
return "X2 Mouse Button";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::BACKSPACE:
|
||||||
|
return "Backspace";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::TAB:
|
||||||
|
return "Tab";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::CLEAR:
|
||||||
|
return "Clear";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::ENTER:
|
||||||
|
return "Enter";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::SHIFT:
|
||||||
|
return "Shift";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::CTRL:
|
||||||
|
return "Ctrl";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::ALT:
|
||||||
|
return "Alt";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::PAUSE:
|
||||||
|
return "Pause";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::CAPS_LOCK:
|
||||||
|
return "Caps Lock";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::IME_KANA:
|
||||||
|
return "IME Kana / Hangul Mode";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::IME_ON:
|
||||||
|
return "IME On";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::IME_JUNJA:
|
||||||
|
return "IME Junja Mode";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::IME_FINAL:
|
||||||
|
return "IME Final Mode";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::IME_HANJA:
|
||||||
|
return "IME Kanji / Hanja Mode";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::IME_OFF:
|
||||||
|
return "IME Off";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::ESCAPE:
|
||||||
|
return "Esc";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::IME_CONVERT:
|
||||||
|
return "IME Convert";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::IME_NONCONVERT:
|
||||||
|
return "IME Nonconvert";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::IME_ACCEPT:
|
||||||
|
return "IME Accept";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::IME_MODECHANGE:
|
||||||
|
return "IME Mode Change Request";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::SPACE:
|
||||||
|
return "Spacebar";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::PAGE_UP:
|
||||||
|
return "Page Up";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::PAGE_DOWN:
|
||||||
|
return "Page Down";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::END:
|
||||||
|
return "End";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::HOME:
|
||||||
|
return "Home";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::LEFT_ARROW:
|
||||||
|
return "Left Arrow";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::UP_ARROW:
|
||||||
|
return "Up Arrow";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::RIGHT_ARROW:
|
||||||
|
return "Right Arrow";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::DOWN_ARROW:
|
||||||
|
return "Down Arrow";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::SELECT:
|
||||||
|
return "Select";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::PRINT:
|
||||||
|
return "Print";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::EXECUTE:
|
||||||
|
return "Execute";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::PRINT_SCREEN:
|
||||||
|
return "Print Screen";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::INSERT:
|
||||||
|
return "Insert";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::DEL:
|
||||||
|
return "Delete";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::HELP:
|
||||||
|
return "Help";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::LEFT_WINDOWS:
|
||||||
|
return "Left Windows";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::RIGHT_WINDOWS:
|
||||||
|
return "Right Windows";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::APPS:
|
||||||
|
return "Applications";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::SLEEP:
|
||||||
|
return "Sleep";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::MULTIPLY:
|
||||||
|
return "Numpad *";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::ADD:
|
||||||
|
return "Numpad +";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::SEPARATOR:
|
||||||
|
return "Separator";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::SUBTRACT:
|
||||||
|
return "Numpad -";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::DECIMAL:
|
||||||
|
return "Numpad .";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::DIVIDE:
|
||||||
|
return "Numpad /";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::NUM_LOCK:
|
||||||
|
return "Num Lock";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::SCROLL_LOCK:
|
||||||
|
return "Scroll Lock";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_PC98_NUMPAD_EQUAL:
|
||||||
|
return "OEM PC98 Numpad Equal / Fujitsu Dictionary";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_FUJITSU_UNREGISTER:
|
||||||
|
return "OEM Fujitsu Unregister";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_FUJITSU_REGISTER:
|
||||||
|
return "OEM Fujitsu Register";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_FUJITSU_LEFT_THUMB:
|
||||||
|
return "OEM Fujitsu Left Thumb";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_FUJITSU_RIGHT_THUMB:
|
||||||
|
return "OEM Fujitsu Right Thumb";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::LEFT_SHIFT:
|
||||||
|
return "Left Shift";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::RIGHT_SHIFT:
|
||||||
|
return "Right Shift";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::LEFT_CTRL:
|
||||||
|
return "Left Ctrl";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::RIGHT_CTRL:
|
||||||
|
return "Right Ctrl";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::LEFT_ALT:
|
||||||
|
return "Left Alt";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::RIGHT_ALT:
|
||||||
|
return "Right Alt";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::BROWSER_BACK:
|
||||||
|
return "Browser Back";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::BROWSER_FORWARD:
|
||||||
|
return "Browser Forward";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::BROWSER_REFRESH:
|
||||||
|
return "Browser Refresh";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::BROWSER_STOP:
|
||||||
|
return "Browser Stop";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::BROWSER_SEARCH:
|
||||||
|
return "Browser Search";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::BROWSER_FAVOURITES:
|
||||||
|
return "Browser Favourites";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::BROWSER_HOME:
|
||||||
|
return "Browser Start and Home";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::VOLUME_MUTE:
|
||||||
|
return "Volume Mute";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::VOLUME_DOWN:
|
||||||
|
return "Volume Down";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::VOLUME_UP:
|
||||||
|
return "Volume Up";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::MEDIA_NEXT_TRACK:
|
||||||
|
return "Media Next Track";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::MEDIA_PREVIOUS_TRACK:
|
||||||
|
return "Media Previous Track";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::MEDIA_STOP:
|
||||||
|
return "Media Stop";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::MEDIA_PLAY_PAUSE:
|
||||||
|
return "Media Play/Pause";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::LAUNCH_MAIL:
|
||||||
|
return "Launch Mail";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::LAUNCH_MEDIA_SELECT:
|
||||||
|
return "Select Media";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::LAUNCH_APP_1:
|
||||||
|
return "Launch App 1";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::LAUNCH_APP_2:
|
||||||
|
return "Launch App 2";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_1:
|
||||||
|
return "; or :";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_PLUS:
|
||||||
|
return "= or +";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_COMMA:
|
||||||
|
return ", or <";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_MINUS:
|
||||||
|
return "- or _";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_PERIOD:
|
||||||
|
return ". or >";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_2:
|
||||||
|
return "/ or ?";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_3:
|
||||||
|
return "` or ~";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_4:
|
||||||
|
return "[ or {";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_5:
|
||||||
|
return "\\ or |";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_6:
|
||||||
|
return "] or }";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_7:
|
||||||
|
return "\' or \"";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_8:
|
||||||
|
return "OEM 8";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_AX:
|
||||||
|
return "OEM AX";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_102:
|
||||||
|
return "< or > or \\ or |";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_ICO_HELP:
|
||||||
|
return "ICO Help";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_ICO_00:
|
||||||
|
return "ICO 00";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::IME_PROCESS:
|
||||||
|
return "IME Process";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_ICO_CLEAR:
|
||||||
|
return "ICO Clear";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::PACKET:
|
||||||
|
return "Packet";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_RESET:
|
||||||
|
return "OEM Reset";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_JUMP:
|
||||||
|
return "OEM Jump";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_PA1:
|
||||||
|
return "OEM PA1";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_PA2:
|
||||||
|
return "OEM PA2";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_PA3:
|
||||||
|
return "OEM PA3";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_WSCTRL:
|
||||||
|
return "OEM WSCTRL";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_CUSEL:
|
||||||
|
return "OEM CuSel";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_ATTN:
|
||||||
|
return "OEM Attn";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_FINISH:
|
||||||
|
return "OEM Finish";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_COPY:
|
||||||
|
return "OEM Copy";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_AUTO:
|
||||||
|
return "OEM Auto";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_ENLW:
|
||||||
|
return "OEM ENLW";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_BACKTAB:
|
||||||
|
return "OEM Backtab";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::ATTN:
|
||||||
|
return "Attn";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::CRSEL:
|
||||||
|
return "CrSel";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::EXSEL:
|
||||||
|
return "ExSel";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::EREOF:
|
||||||
|
return "Erase EOF";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::PLAY:
|
||||||
|
return "Play";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::ZOOM:
|
||||||
|
return "Zoom";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::NONAME:
|
||||||
|
return "No Name Key";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::PA_1:
|
||||||
|
return "PA1";
|
||||||
|
break;
|
||||||
|
case SH_KEYCODE::OEM_CLEAR:
|
||||||
|
return "OEM Clear";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SHInputManager::GetControllerCodeName(SH_CONTROLLERCODE c) noexcept
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case SH_CONTROLLERCODE::DPAD_UP:
|
||||||
|
return "D-Pad Up";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::DPAD_DOWN:
|
||||||
|
return "D-Pad Down";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::DPAD_LEFT:
|
||||||
|
return "D-Pad Left";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::DPAD_RIGHT:
|
||||||
|
return "D-Pad Right";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::START:
|
||||||
|
return "Start Button";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::BACK:
|
||||||
|
return "Back Button";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::LEFT_THUMBSTICK:
|
||||||
|
return "Left Thumbstick Button";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::RIGHT_THUMBSTICK:
|
||||||
|
return "Right Thumbstick Button";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::LEFT_SHOULDER:
|
||||||
|
return "Left Shoulder Button";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::RIGHT_SHOULDER:
|
||||||
|
return "Right Shoulder Button";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::A:
|
||||||
|
return "A Button";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::B:
|
||||||
|
return "B Button";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::X:
|
||||||
|
return "X Button";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::Y:
|
||||||
|
return "Y Button";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::LEFT_TRIGGER:
|
||||||
|
return "Left Trigger";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::RIGHT_TRIGGER:
|
||||||
|
return "Right Trigger";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::LEFT_THUMBSTICK_X:
|
||||||
|
return "Left Thumbstick Horizontal";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::LEFT_THUMBSTICK_Y:
|
||||||
|
return "Left Thumbstick Vertical";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::RIGHT_THUMBSTICK_X:
|
||||||
|
return "Right Thumbstick Horizontal";
|
||||||
|
break;
|
||||||
|
case SH_CONTROLLERCODE::RIGHT_THUMBSTICK_Y:
|
||||||
|
return "Right Thumbstick Vertical";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//The Binding File format presently goes as such:
|
//The Binding File format presently goes as such:
|
||||||
/*
|
/*
|
||||||
* Binding count
|
* Binding count
|
||||||
|
@ -680,7 +1149,7 @@ namespace SHADE
|
||||||
digitalInput = true;
|
digitalInput = true;
|
||||||
}
|
}
|
||||||
if (std::abs(newValue) > std::abs(largestMagnitude))
|
if (std::abs(newValue) > std::abs(largestMagnitude))
|
||||||
largestMagnitude = newValue * data.sensitivity * (data.inverted ? -1.0 : 1.0);
|
largestMagnitude = newValue * (data.inverted ? -1.0 : 1.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,7 +1165,7 @@ namespace SHADE
|
||||||
digitalInput = true;
|
digitalInput = true;
|
||||||
}
|
}
|
||||||
if (std::abs(newValue) > std::abs(largestMagnitude))
|
if (std::abs(newValue) > std::abs(largestMagnitude))
|
||||||
largestMagnitude = -newValue * data.sensitivity * (data.inverted ? -1.0 : 1.0);
|
largestMagnitude = -newValue * (data.inverted ? -1.0 : 1.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,21 +1209,23 @@ namespace SHADE
|
||||||
if (data.value > 1.0) data.value = 1.0;
|
if (data.value > 1.0) data.value = 1.0;
|
||||||
else if (data.value < -1.0) data.value = -1.0;
|
else if (data.value < -1.0) data.value = -1.0;
|
||||||
}
|
}
|
||||||
//If analog input was in,
|
//If analog input was in, raw value taken
|
||||||
//sensitivity is instead used as a multiplier
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
data.value = largestMagnitude * data.sensitivity;
|
data.value = largestMagnitude;
|
||||||
if (data.value > 1.0) data.value = 1.0;
|
if (data.value > 1.0) data.value = 1.0;
|
||||||
else if (data.value < -1.0) data.value = -1.0;
|
else if (data.value < -1.0) data.value = -1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.snap) //Snapping
|
if (data.snap) //Snapping
|
||||||
{
|
{
|
||||||
if (data.value > 0.0 && data.negativeInputHeld)
|
if (digitalInput) //Only for digital inputs
|
||||||
data.value = 0.0;
|
{
|
||||||
if (data.value < 0.0 && data.positiveInputHeld)
|
if (data.value > 0.0 && data.negativeInputHeld)
|
||||||
data.value = 0.0;
|
data.value = 0.0;
|
||||||
|
if (data.value < 0.0 && data.positiveInputHeld)
|
||||||
|
data.value = 0.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -936,11 +1407,11 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
else if (bindings[bindingName].positiveInputHeld)
|
else if (GetBindingAxis(bindingName, cNum) > 0.0)
|
||||||
{
|
{
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
else if (bindings[bindingName].negativeInputHeld)
|
else if (GetBindingAxis(bindingName, cNum) < 0.0)
|
||||||
{
|
{
|
||||||
return -1.0;
|
return -1.0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -363,6 +363,7 @@ namespace SHADE
|
||||||
|
|
||||||
//Speed in units per second that the axis will move toward target value for digital
|
//Speed in units per second that the axis will move toward target value for digital
|
||||||
//For mouse movement / scrolling, serves as multiplier
|
//For mouse movement / scrolling, serves as multiplier
|
||||||
|
//Irrelevant for other analog inputs
|
||||||
double sensitivity = 1.0;
|
double sensitivity = 1.0;
|
||||||
|
|
||||||
//If enabled, axis value will reset to zero when pressing a button
|
//If enabled, axis value will reset to zero when pressing a button
|
||||||
|
@ -415,6 +416,12 @@ namespace SHADE
|
||||||
return controllerInUse;
|
return controllerInUse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Get the name of key code
|
||||||
|
static std::string GetKeyCodeName(SH_KEYCODE const keyCode) noexcept;
|
||||||
|
|
||||||
|
//Get the name of controller code
|
||||||
|
static std::string GetControllerCodeName(SH_CONTROLLERCODE const controllerCode) noexcept;
|
||||||
|
|
||||||
//For testing purposes
|
//For testing purposes
|
||||||
//static void PrintCurrentState() noexcept;
|
//static void PrintCurrentState() noexcept;
|
||||||
|
|
||||||
|
@ -738,6 +745,16 @@ namespace SHADE
|
||||||
return bindings.erase(bindingName);
|
return bindings.erase(bindingName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Rename a binding
|
||||||
|
static inline void RenameBinding(std::string const& oldBindingName, std::string const& newBindingName) noexcept
|
||||||
|
{
|
||||||
|
//https://stackoverflow.com/a/44883472
|
||||||
|
//https://en.cppreference.com/w/cpp/container/map/extract
|
||||||
|
auto nodeHandler = bindings.extract(oldBindingName);
|
||||||
|
nodeHandler.key() = newBindingName;
|
||||||
|
bindings.insert(std::move(nodeHandler));
|
||||||
|
}
|
||||||
|
|
||||||
//Clears all bindings from the list
|
//Clears all bindings from the list
|
||||||
static inline void ClearBindings() noexcept
|
static inline void ClearBindings() noexcept
|
||||||
{
|
{
|
||||||
|
@ -809,7 +826,7 @@ namespace SHADE
|
||||||
//Get the sensitivity of the binding
|
//Get the sensitivity of the binding
|
||||||
//Serves as a multiplier for mouse movement/scrolling
|
//Serves as a multiplier for mouse movement/scrolling
|
||||||
//For other digital inputs, serves as a rate of how fast axis value goes to maximum positive/negative
|
//For other digital inputs, serves as a rate of how fast axis value goes to maximum positive/negative
|
||||||
//For other analog inputs, serves as a multiplier, but axis value magnitude will still be capped at 1
|
//Irrelevant for other analog inputs
|
||||||
static inline double GetBindingSensitivity(std::string const& bindingName)
|
static inline double GetBindingSensitivity(std::string const& bindingName)
|
||||||
{
|
{
|
||||||
return bindings[bindingName].sensitivity;
|
return bindings[bindingName].sensitivity;
|
||||||
|
@ -818,7 +835,7 @@ namespace SHADE
|
||||||
//Set the sensitivity of the binding
|
//Set the sensitivity of the binding
|
||||||
//Serves as a multiplier for mouse movement/scrolling
|
//Serves as a multiplier for mouse movement/scrolling
|
||||||
//For other digital inputs, serves as a rate of how fast axis value goes to maximum positive/negative
|
//For other digital inputs, serves as a rate of how fast axis value goes to maximum positive/negative
|
||||||
//For other analog inputs, serves as a multiplier, but axis value magnitude will still be capped at 1
|
//Irrelevant for other analog inputs
|
||||||
static inline void SetBindingSensitivity(std::string const& bindingName, double const newValue)
|
static inline void SetBindingSensitivity(std::string const& bindingName, double const newValue)
|
||||||
{
|
{
|
||||||
bindings[bindingName].sensitivity = newValue;
|
bindings[bindingName].sensitivity = newValue;
|
||||||
|
@ -984,8 +1001,6 @@ namespace SHADE
|
||||||
|
|
||||||
//Get the axis value of binding, between -1 and 1 for non-mouse movement/wheel
|
//Get the axis value of binding, between -1 and 1 for non-mouse movement/wheel
|
||||||
//For mouse movement/wheel, it won't be between -1 and 1. It will also be multiplied by sensitivity
|
//For mouse movement/wheel, it won't be between -1 and 1. It will also be multiplied by sensitivity
|
||||||
//To avoid interference between mouse movement/wheel and keyboard/mouse/controller input,
|
|
||||||
//Set mouseXBound, mouseYBound and mouseScrollBound to false
|
|
||||||
//controllerNumber is not used
|
//controllerNumber is not used
|
||||||
static double GetBindingAxis(std::string const& bindingName, size_t controllerNumber = 0) noexcept;
|
static double GetBindingAxis(std::string const& bindingName, size_t controllerNumber = 0) noexcept;
|
||||||
|
|
||||||
|
|
|
@ -11,15 +11,8 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include "Assets/Asset Types/SHSceneAsset.h"
|
#include "Assets/Asset Types/SHSceneAsset.h"
|
||||||
#include "Camera/SHCameraComponent.h"
|
#include "Common/SHAllComponents.h"
|
||||||
#include "Camera/SHCameraArmComponent.h"
|
|
||||||
#include "Math/Transform/SHTransformComponent.h"
|
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
|
||||||
#include "Physics/Interface/SHRigidBodyComponent.h"
|
|
||||||
#include "UI/SHCanvasComponent.h"
|
|
||||||
#include "UI/SHButtonComponent.h"
|
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Graphics/MiddleEnd/Lights/SHLightComponent.h"
|
|
||||||
#include "Scripting/SHScriptEngine.h"
|
#include "Scripting/SHScriptEngine.h"
|
||||||
#include "Tools/FileIO/SHFileIO.h"
|
#include "Tools/FileIO/SHFileIO.h"
|
||||||
|
|
||||||
|
@ -208,6 +201,7 @@ namespace SHADE
|
||||||
|
|
||||||
AddComponentToComponentNode<SHCanvasComponent>(components, eid);
|
AddComponentToComponentNode<SHCanvasComponent>(components, eid);
|
||||||
AddComponentToComponentNode<SHButtonComponent>(components, eid);
|
AddComponentToComponentNode<SHButtonComponent>(components, eid);
|
||||||
|
AddComponentToComponentNode<SHToggleButtonComponent>(components, eid);
|
||||||
|
|
||||||
AddComponentToComponentNode<SHTextRenderableComponent>(components, eid);
|
AddComponentToComponentNode<SHTextRenderableComponent>(components, eid);
|
||||||
|
|
||||||
|
@ -265,6 +259,7 @@ namespace SHADE
|
||||||
|
|
||||||
AddComponentID<SHCanvasComponent>(componentIDList, componentsNode);
|
AddComponentID<SHCanvasComponent>(componentIDList, componentsNode);
|
||||||
AddComponentID<SHButtonComponent>(componentIDList, componentsNode);
|
AddComponentID<SHButtonComponent>(componentIDList, componentsNode);
|
||||||
|
AddComponentID<SHToggleButtonComponent>(componentIDList, componentsNode);
|
||||||
AddComponentID<SHTextRenderableComponent>(componentIDList, componentsNode);
|
AddComponentID<SHTextRenderableComponent>(componentIDList, componentsNode);
|
||||||
|
|
||||||
return componentIDList;
|
return componentIDList;
|
||||||
|
@ -346,6 +341,7 @@ namespace SHADE
|
||||||
|
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHCanvasComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHCanvasComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHButtonComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHButtonComponent>(componentsNode, eid);
|
||||||
|
SHSerializationHelper::InitializeComponentFromNode<SHToggleButtonComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHTextRenderableComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHTextRenderableComponent>(componentsNode, eid);
|
||||||
SHSerializationHelper::InitializeComponentFromNode<SHLightComponent>(componentsNode, eid);
|
SHSerializationHelper::InitializeComponentFromNode<SHLightComponent>(componentsNode, eid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
#include "Graphics/MiddleEnd/Interface/SHRenderable.h"
|
||||||
|
#include "Physics/Interface/SHColliderComponent.h"
|
||||||
|
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
|
||||||
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
#include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h"
|
||||||
#include "Math/Geometry/SHBox.h"
|
#include "Math/Geometry/SHBox.h"
|
||||||
#include "Math/Geometry/SHSphere.h"
|
#include "Math/Geometry/SHSphere.h"
|
||||||
|
@ -11,8 +13,6 @@
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
#include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h"
|
||||||
#include "SHSerializationTools.h"
|
#include "SHSerializationTools.h"
|
||||||
#include "Physics/Interface/SHColliderComponent.h"
|
|
||||||
#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h"
|
|
||||||
#include "Graphics/MiddleEnd/TextRendering/SHFont.h"
|
#include "Graphics/MiddleEnd/TextRendering/SHFont.h"
|
||||||
#include "Physics/Collision/SHCollisionTagMatrix.h"
|
#include "Physics/Collision/SHCollisionTagMatrix.h"
|
||||||
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ namespace SHADE
|
||||||
/// <param name="color"></param>
|
/// <param name="color"></param>
|
||||||
/// <param name="color">Colour to draw with.</param>
|
/// <param name="color">Colour to draw with.</param>
|
||||||
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
|
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
|
||||||
void WireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color = SHColour::WHITE, bool depthTested = false);
|
static void WireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color = SHColour::WHITE, bool depthTested = false);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Persistent Draw Function Class "Folder" */
|
/* Persistent Draw Function Class "Folder" */
|
||||||
|
@ -388,7 +388,7 @@ namespace SHADE
|
||||||
/// <param name="color"></param>
|
/// <param name="color"></param>
|
||||||
/// <param name="color">Colour to draw with.</param>
|
/// <param name="color">Colour to draw with.</param>
|
||||||
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
|
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
|
||||||
void WireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color = SHColour::WHITE, bool depthTested = false);
|
static void WireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color = SHColour::WHITE, bool depthTested = false);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clears any persistent drawn debug primitives.
|
/// Clears any persistent drawn debug primitives.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -13,6 +13,7 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include <SHpch.h>
|
#include <SHpch.h>
|
||||||
// Primary Header
|
// Primary Header
|
||||||
#include "SHStringUtilities.h"
|
#include "SHStringUtilities.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -51,4 +52,11 @@ namespace SHADE
|
||||||
return std::system_category().message(errorCode);
|
return std::system_category().message(errorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t SHStringUtilities::StringFindInsensitive(std::string str, std::string search, size_t pos)
|
||||||
|
{
|
||||||
|
std::transform(str.begin(), str.end(), str.begin(), [](char c) {return static_cast<char>(std::tolower(c)); });
|
||||||
|
std::transform(search.begin(), search.end(), search.begin(), [](char c) {return static_cast<char>(std::tolower(c)); });
|
||||||
|
return str.find(search, pos);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -16,66 +16,68 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contains useful functions for operating on strings.
|
||||||
|
/// </summary>
|
||||||
|
class SHStringUtilities
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Utility Functions */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains useful functions for operating on strings.
|
/// Splits a string separated by a specified delimiter into a vector of strings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class SHStringUtilities
|
/// <typeparam name="T">Internal type of each element in the string.</typeparam>
|
||||||
{
|
/// <param name="str">Read only reference to the string to split.</param>
|
||||||
public:
|
/// <param name="delim">Read only reference to the delimiter.</param>
|
||||||
/*-----------------------------------------------------------------------------*/
|
/// <returns>Vector of strings that have been split.</returns>
|
||||||
/* Utility Functions */
|
template<typename T>
|
||||||
/*-----------------------------------------------------------------------------*/
|
static std::vector<std::basic_string<T>> Split(const std::basic_string<T>& str, const T& delim);
|
||||||
|
/// <summary>
|
||||||
|
/// Splits a string separated by a specified delimiter into a vector of strings.
|
||||||
|
/// Overload of Split<T>() to allow for string literals to be accepted.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str">Read only reference to the string to split.</param>
|
||||||
|
/// <param name="delim">Read only reference to the delimiter.</param>
|
||||||
|
/// <returns>Vector of strings that have been split.</returns>
|
||||||
|
static std::vector<std::string> Split(const std::string& str, const char& delim);
|
||||||
|
/// <summary>
|
||||||
|
/// Splits a string separated by a specified delimiter into a vector of strings.
|
||||||
|
/// Overload of Split<T>() to allow for wide string literals to be accepted.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str">Read only reference to the string to split.</param>
|
||||||
|
/// <param name="delim">Read only reference to the delimiter.</param>
|
||||||
|
/// <returns>Vector of strings that have been split.</returns>
|
||||||
|
static std::vector<std::wstring> Split(const std::wstring& str, const wchar_t& delim);
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a wstring to a string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="wstr">wstring to convert.</param>
|
||||||
|
/// <returns>The converted wstring in string form.</returns>
|
||||||
|
static std::string WstrToStr(const std::wstring& wstr);
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a string to a wstring.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str">string to convert.</param>
|
||||||
|
/// <returns>The converted string in wstring form.</returns>
|
||||||
|
static std::wstring StrToWstr(const std::string& str);
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the error message associated with a Win32 error code.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="errorCode">Win32 error code to decode.</param>
|
||||||
|
/// <returns>String that represents the Win32 error.</returns>
|
||||||
|
static std::string GetWin32ErrorMessage(unsigned long errorCode);
|
||||||
|
|
||||||
/// <summary>
|
static size_t StringFindInsensitive(std::string str, std::string search, size_t pos = 0);
|
||||||
/// Splits a string separated by a specified delimiter into a vector of strings.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">Internal type of each element in the string.</typeparam>
|
|
||||||
/// <param name="str">Read only reference to the string to split.</param>
|
|
||||||
/// <param name="delim">Read only reference to the delimiter.</param>
|
|
||||||
/// <returns>Vector of strings that have been split.</returns>
|
|
||||||
template<typename T>
|
|
||||||
static std::vector<std::basic_string<T>> Split(const std::basic_string<T>& str, const T& delim);
|
|
||||||
/// <summary>
|
|
||||||
/// Splits a string separated by a specified delimiter into a vector of strings.
|
|
||||||
/// Overload of Split<T>() to allow for string literals to be accepted.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="str">Read only reference to the string to split.</param>
|
|
||||||
/// <param name="delim">Read only reference to the delimiter.</param>
|
|
||||||
/// <returns>Vector of strings that have been split.</returns>
|
|
||||||
static std::vector<std::string> Split(const std::string& str, const char& delim);
|
|
||||||
/// <summary>
|
|
||||||
/// Splits a string separated by a specified delimiter into a vector of strings.
|
|
||||||
/// Overload of Split<T>() to allow for wide string literals to be accepted.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="str">Read only reference to the string to split.</param>
|
|
||||||
/// <param name="delim">Read only reference to the delimiter.</param>
|
|
||||||
/// <returns>Vector of strings that have been split.</returns>
|
|
||||||
static std::vector<std::wstring> Split(const std::wstring& str, const wchar_t& delim);
|
|
||||||
/// <summary>
|
|
||||||
/// Converts a wstring to a string.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="wstr">wstring to convert.</param>
|
|
||||||
/// <returns>The converted wstring in string form.</returns>
|
|
||||||
static std::string WstrToStr(const std::wstring& wstr);
|
|
||||||
/// <summary>
|
|
||||||
/// Converts a string to a wstring.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="str">string to convert.</param>
|
|
||||||
/// <returns>The converted string in wstring form.</returns>
|
|
||||||
static std::wstring StrToWstr(const std::string& str);
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieves the error message associated with a Win32 error code.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="errorCode">Win32 error code to decode.</param>
|
|
||||||
/// <returns>String that represents the Win32 error.</returns>
|
|
||||||
static std::string GetWin32ErrorMessage(unsigned long errorCode);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
/* Constructors/Destructors */
|
/* Constructors/Destructors */
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
SHStringUtilities() = delete;
|
SHStringUtilities() = delete;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "SHStringUtilities.hpp"
|
#include "SHStringUtilities.hpp"
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include "ECS_Base/SHECSMacros.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHButtonClickEvent
|
||||||
|
{
|
||||||
|
EntityID EID;
|
||||||
|
// value of the toggle button, default to false if its a button and not a toggle button
|
||||||
|
bool value{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
SHButtonComponent::SHButtonComponent()
|
SHButtonComponent::SHButtonComponent()
|
||||||
:size(1.0f), offset(0.0f), isHovered(false), isClicked(false),
|
:size(1.0f), isHovered(false), isClicked(false),
|
||||||
defaultTexture(0), hoveredTexture(0), clickedTexture(0)
|
defaultTexture(0), hoveredTexture(0), clickedTexture(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ namespace SHADE
|
||||||
virtual ~SHButtonComponent() = default;
|
virtual ~SHButtonComponent() = default;
|
||||||
|
|
||||||
SHVec2 size;
|
SHVec2 size;
|
||||||
SHVec2 offset;
|
|
||||||
|
|
||||||
AssetID GetClickedTexture() const noexcept;
|
AssetID GetClickedTexture() const noexcept;
|
||||||
AssetID GetDefaultTexture() const noexcept;
|
AssetID GetDefaultTexture() const noexcept;
|
||||||
|
@ -33,8 +32,10 @@ namespace SHADE
|
||||||
|
|
||||||
friend class SHUISystem;
|
friend class SHUISystem;
|
||||||
private:
|
private:
|
||||||
|
//Set to true when mouse is hovering over the button.
|
||||||
bool isHovered;
|
bool isHovered;
|
||||||
|
//This is set to true when the mouse clicks down, and set back to false when mouse releases.
|
||||||
|
//The event for the button click will be broadcasted when mouse release.
|
||||||
bool isClicked;
|
bool isClicked;
|
||||||
AssetID defaultTexture;
|
AssetID defaultTexture;
|
||||||
AssetID hoveredTexture;
|
AssetID hoveredTexture;
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHSliderComponent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHSliderComponent::SHSliderComponent()
|
||||||
|
:size(1.0f), isHovered(false), isClicked(false), value(0.0f)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float SHSliderComponent::GetValue() const noexcept
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSliderComponent::SetValue(float value) noexcept
|
||||||
|
{
|
||||||
|
this->value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RTTR_REGISTRATION
|
||||||
|
{
|
||||||
|
using namespace SHADE;
|
||||||
|
using namespace rttr;
|
||||||
|
|
||||||
|
registration::class_<SHSliderComponent>("Slider Component")
|
||||||
|
.property("Slider Value", &SHSliderComponent::GetValue, &SHSliderComponent::SetValue)
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <rttr/registration>
|
||||||
|
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
#include "Math/Vector/SHVec3.h"
|
||||||
|
#include "Math/Vector/SHVec2.h"
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
class SH_API SHSliderComponent final: public SHComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHSliderComponent();
|
||||||
|
virtual ~SHSliderComponent() = default;
|
||||||
|
|
||||||
|
SHVec2 size;
|
||||||
|
|
||||||
|
|
||||||
|
float GetValue() const noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
void SetValue(float value) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
friend class SHUISystem;
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool isHovered;
|
||||||
|
bool isClicked;
|
||||||
|
|
||||||
|
float value;
|
||||||
|
|
||||||
|
RTTR_ENABLE()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHToggleButtonComponent.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHToggleButtonComponent::SHToggleButtonComponent()
|
||||||
|
:size(1.0f), isHovered(false), isClicked(false), value(false),
|
||||||
|
defaultTexture(0), toggledTexture(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetID SHToggleButtonComponent::GetDefaultTexture() const noexcept
|
||||||
|
{
|
||||||
|
return defaultTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetID SHToggleButtonComponent::GetToggledTexture() const noexcept
|
||||||
|
{
|
||||||
|
return toggledTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHToggleButtonComponent::GetValue() const noexcept
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHToggleButtonComponent::SetDefaultTexture(AssetID texture) noexcept
|
||||||
|
{
|
||||||
|
defaultTexture = texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHToggleButtonComponent::SetToggledTexture(AssetID texture) noexcept
|
||||||
|
{
|
||||||
|
toggledTexture = texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHToggleButtonComponent::SetValue(bool value) noexcept
|
||||||
|
{
|
||||||
|
this->value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RTTR_REGISTRATION
|
||||||
|
{
|
||||||
|
using namespace SHADE;
|
||||||
|
using namespace rttr;
|
||||||
|
|
||||||
|
registration::class_<SHToggleButtonComponent>("Toggle Button Component")
|
||||||
|
.property("Non Toggled Texture", &SHToggleButtonComponent::GetDefaultTexture, &SHToggleButtonComponent::SetDefaultTexture)
|
||||||
|
.property("Toggled Texture", &SHToggleButtonComponent::GetToggledTexture, &SHToggleButtonComponent::SetToggledTexture)
|
||||||
|
.property("Value", &SHToggleButtonComponent::GetValue, &SHToggleButtonComponent::SetValue)
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <rttr/registration>
|
||||||
|
|
||||||
|
#include "SH_API.h"
|
||||||
|
#include "ECS_Base/Components/SHComponent.h"
|
||||||
|
#include "Math/Vector/SHVec3.h"
|
||||||
|
#include "Math/Vector/SHVec2.h"
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
class SH_API SHToggleButtonComponent final: public SHComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHToggleButtonComponent();
|
||||||
|
virtual ~SHToggleButtonComponent() = default;
|
||||||
|
|
||||||
|
SHVec2 size;
|
||||||
|
|
||||||
|
AssetID GetToggledTexture() const noexcept;
|
||||||
|
AssetID GetDefaultTexture() const noexcept;
|
||||||
|
bool GetValue() const noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
void SetDefaultTexture(AssetID texture) noexcept;
|
||||||
|
void SetToggledTexture(AssetID texture) noexcept;
|
||||||
|
void SetValue(bool value) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
friend class SHUISystem;
|
||||||
|
private:
|
||||||
|
|
||||||
|
//Set to true when mouse is hovering over the button.
|
||||||
|
bool isHovered;
|
||||||
|
//This is set to true when the mouse clicks down, and set back to false when mouse releases.
|
||||||
|
//The event for the button click will be broadcasted when mouse release.
|
||||||
|
bool isClicked;
|
||||||
|
bool value;
|
||||||
|
AssetID defaultTexture;
|
||||||
|
AssetID toggledTexture;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RTTR_ENABLE()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -9,7 +9,15 @@
|
||||||
#include "Editor/EditorWindow/ViewportWindow/SHEditorViewport.h"
|
#include "Editor/EditorWindow/ViewportWindow/SHEditorViewport.h"
|
||||||
#include "Editor/SHEditor.h"
|
#include "Editor/SHEditor.h"
|
||||||
#include "Resource/SHResourceManager.h"
|
#include "Resource/SHResourceManager.h"
|
||||||
|
#include "Assets/SHAssetManager.h"
|
||||||
#include "Input/SHInputManager.h"
|
#include "Input/SHInputManager.h"
|
||||||
|
#include "SHUIComponent.h"
|
||||||
|
#include "SHButtonComponent.h"
|
||||||
|
#include "SHToggleButtonComponent.h"
|
||||||
|
#include "SHSliderComponent.h"
|
||||||
|
#include "SHCanvasComponent.h"
|
||||||
|
#include "Events/SHEventManager.hpp"
|
||||||
|
#include "Events/SHButtonClickEvent.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -103,7 +111,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(comp.GetEID());
|
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(comp.GetEID());
|
||||||
if (canvasComp != nullptr)
|
if (canvasComp != nullptr)
|
||||||
comp.localToCanvasMatrix = canvasComp->GetMatrix()* transform->GetTRS();
|
comp.localToCanvasMatrix = transform->GetTRS() * canvasComp->GetMatrix();
|
||||||
else
|
else
|
||||||
comp.localToCanvasMatrix = transform->GetTRS();
|
comp.localToCanvasMatrix = transform->GetTRS();
|
||||||
}
|
}
|
||||||
|
@ -139,77 +147,235 @@ namespace SHADE
|
||||||
|
|
||||||
void SHUISystem::UpdateButtonComponent(SHButtonComponent& comp) noexcept
|
void SHUISystem::UpdateButtonComponent(SHButtonComponent& comp) noexcept
|
||||||
{
|
{
|
||||||
if (!SHComponentManager::HasComponent<SHTransformComponent>(comp.GetEID()) || !SHComponentManager::HasComponent<SHUIComponent>(comp.GetEID()))
|
if (!SHComponentManager::HasComponent<SHUIComponent>(comp.GetEID()))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||||
|
auto uiComp = SHComponentManager::GetComponent<SHUIComponent>(comp.GetEID());
|
||||||
|
//auto canvasComp = SHComponentManager::GetComponent_s<SHCanvasComponent>(uiComp->canvasID);
|
||||||
|
|
||||||
|
SHVec4 topExtent4 = SHMatrix::Translate(-comp.size.x * 0.5f, comp.size.y * 0.5f, 0.0f) * uiComp->GetMatrix() * SHVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
SHVec4 btmExtent4 = SHMatrix::Translate(comp.size.x * 0.5f, -comp.size.y * 0.5f, 0.0f) * uiComp->GetMatrix() * SHVec4(0.0f,0.0f, 0.0f,1.0f);
|
||||||
|
|
||||||
|
|
||||||
|
SHVec2 topExtent{ topExtent4.x,topExtent4.y };
|
||||||
|
SHVec2 btmExtent{ btmExtent4.x,btmExtent4.y };
|
||||||
|
|
||||||
|
|
||||||
|
SHVec2 mousePos;
|
||||||
|
SHVec2 windowSize;
|
||||||
|
#ifdef SHEDITOR
|
||||||
|
windowSize = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>()->beginContentRegionAvailable;
|
||||||
|
mousePos = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>()->viewportMousePos;
|
||||||
|
//mousePos.y = windowSize.y - mousePos.y;
|
||||||
|
//SHLOG_INFO("mouse pos: {}, {}", mousePos.x, mousePos.y)
|
||||||
|
mousePos /= windowSize;
|
||||||
|
//SHLOG_INFO("mouse pos normalized: {}, {}", mousePos.x, mousePos.y)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
SHInputManager::GetMouseScreenPosition(&x, &y);
|
||||||
|
mousePos.x = x;
|
||||||
|
mousePos.y = y;
|
||||||
|
auto ws = SHSystemManager::GetSystem<SHGraphicsSystem>()->GetWindow()->GetWindowSize();
|
||||||
|
windowSize = { ws.first,ws.second };
|
||||||
|
mousePos /= windowSize;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SHVec2 camSize{ cameraSystem->GetCameraWidthHeight(0)};
|
||||||
|
//SHLOG_INFO("TopExtent: {}, {}", topExtent.x, topExtent.y)
|
||||||
|
|
||||||
|
topExtent = CanvasToScreenPoint(topExtent,true);
|
||||||
|
btmExtent = CanvasToScreenPoint(btmExtent,true);
|
||||||
|
//SHLOG_INFO("TopExtent: {}, {} Btm Extent: {}, {}", topExtent.x, topExtent.y, btmExtent.x, btmExtent.y)
|
||||||
|
|
||||||
|
|
||||||
|
//comp.isClicked = false;
|
||||||
|
if (mousePos.x >= topExtent.x && mousePos.x <= btmExtent.x
|
||||||
|
&& mousePos.y >= topExtent.y && mousePos.y <= btmExtent.y)
|
||||||
|
{
|
||||||
|
comp.isHovered = true;
|
||||||
|
#ifdef SHEDITOR
|
||||||
|
//if (SHSystemManager::GetSystem<SHEditor>()->editorState == SHEditor::State::PLAY)
|
||||||
|
{
|
||||||
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::LMB))
|
||||||
|
{
|
||||||
|
comp.isClicked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::LMB))
|
||||||
|
{
|
||||||
|
comp.isClicked = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//SHLOG_INFO("HOVERED")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
comp.isHovered = false;
|
||||||
|
//SHLOG_INFO("NOT HOVERED")
|
||||||
|
}
|
||||||
|
if (comp.isClicked && SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::LMB))
|
||||||
|
{
|
||||||
|
comp.isClicked = false;
|
||||||
|
SHButtonClickEvent clickEvent;
|
||||||
|
clickEvent.EID = comp.GetEID();
|
||||||
|
SHEventManager::BroadcastEvent(clickEvent, SH_BUTTON_CLICK_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SHComponentManager::HasComponent<SHRenderable>(comp.GetEID()))
|
||||||
|
{
|
||||||
|
auto renderable = SHComponentManager::GetComponent_s<SHRenderable>(comp.GetEID());
|
||||||
|
//auto texture = SHResourceManager::Get<SHTexture>(comp.GetDefaultTexture());
|
||||||
|
|
||||||
|
auto material = renderable->GetModifiableMaterial();
|
||||||
|
if(!comp.isHovered && !comp.isClicked)
|
||||||
|
if (comp.GetDefaultTexture() != 0 && SHAssetManager::GetType(comp.GetDefaultTexture()) == AssetType::TEXTURE)
|
||||||
|
{
|
||||||
|
material->SetProperty("data.textureIndex", comp.GetDefaultTexture());
|
||||||
|
//SHLOG_INFO("SETTING DEFAULT TEXTURE")
|
||||||
|
}
|
||||||
|
else if (comp.isClicked)
|
||||||
|
{
|
||||||
|
if (comp.GetClickedTexture() != 0 && SHAssetManager::GetType(comp.GetClickedTexture()) == AssetType::TEXTURE)
|
||||||
|
{
|
||||||
|
material->SetProperty("data.textureIndex", comp.GetClickedTexture());
|
||||||
|
//SHLOG_INFO("SETTING CLICKED TEXTURE")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (comp.GetHoveredTexture() != 0 && SHAssetManager::GetType(comp.GetHoveredTexture()) == AssetType::TEXTURE)
|
||||||
|
{
|
||||||
|
material->SetProperty("data.textureIndex", comp.GetHoveredTexture());
|
||||||
|
//SHLOG_INFO("SETTING HOVERED TEXTURE")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHUISystem::UpdateToggleButtonComponent(SHToggleButtonComponent& comp) noexcept
|
||||||
|
{
|
||||||
|
if (!SHComponentManager::HasComponent<SHUIComponent>(comp.GetEID()))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||||
auto uiComp = SHComponentManager::GetComponent<SHUIComponent>(comp.GetEID());
|
auto uiComp = SHComponentManager::GetComponent<SHUIComponent>(comp.GetEID());
|
||||||
|
|
||||||
SHVec4 topExtent4 = uiComp->GetMatrix() * SHVec4(-comp.size.x * 0.5f, comp.size.y * 0.5f , 0.0f,1.0f);
|
SHVec4 topExtent4 = SHMatrix::Translate(-comp.size.x * 0.5f, comp.size.y * 0.5f, 0.0f) * uiComp->GetMatrix() * SHVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
SHVec4 btmExtent4 = uiComp->GetMatrix() * SHVec4(comp.size.x * 0.5f , -comp.size.y * 0.5f , 0.0f, 1.0f);
|
SHVec4 btmExtent4 = SHMatrix::Translate(comp.size.x * 0.5f, -comp.size.y * 0.5f, 0.0f) * uiComp->GetMatrix() * SHVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
SHVec2 topExtent{ topExtent4.x,-topExtent4.y };
|
|
||||||
SHVec2 btmExtent{ btmExtent4.x,-btmExtent4.y };
|
|
||||||
|
|
||||||
|
|
||||||
|
SHVec2 topExtent{ topExtent4.x,topExtent4.y };
|
||||||
|
SHVec2 btmExtent{ btmExtent4.x,btmExtent4.y };
|
||||||
|
|
||||||
SHVec2 windowSize;
|
|
||||||
SHVec2 mousePos;
|
SHVec2 mousePos;
|
||||||
|
SHVec2 windowSize;
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
|
windowSize = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>()->beginContentRegionAvailable;
|
||||||
windowSize = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>()->windowSize;
|
|
||||||
mousePos = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>()->viewportMousePos;
|
mousePos = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>()->viewportMousePos;
|
||||||
|
//mousePos.y = windowSize.y - mousePos.y;
|
||||||
|
//SHLOG_INFO("mouse pos: {}, {}", mousePos.x, mousePos.y)
|
||||||
|
mousePos /= windowSize;
|
||||||
|
//SHLOG_INFO("mouse pos normalized: {}, {}", mousePos.x, mousePos.y)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
SHInputManager::GetMouseScreenPosition(&x, &y);
|
||||||
|
mousePos.x = x;
|
||||||
|
mousePos.y = y;
|
||||||
|
auto ws = SHSystemManager::GetSystem<SHGraphicsSystem>()->GetWindow()->GetWindowSize();
|
||||||
|
windowSize = { ws.first,ws.second };
|
||||||
|
mousePos /= windowSize;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
SHVec2 camSize{ cameraSystem->GetCameraWidthHeight(0) };
|
||||||
|
|
||||||
|
|
||||||
SHVec2 camSize{ cameraSystem->GetCameraWidthHeight(0).x , cameraSystem->GetCameraWidthHeight(0).y };
|
|
||||||
|
|
||||||
topExtent += camSize * 0.5f;
|
topExtent = CanvasToScreenPoint(topExtent,true);
|
||||||
btmExtent += camSize * 0.5f;
|
btmExtent = CanvasToScreenPoint(btmExtent, true);
|
||||||
|
|
||||||
//Convert everything to using ratios
|
|
||||||
topExtent /= camSize;
|
|
||||||
btmExtent /= camSize;
|
|
||||||
|
|
||||||
mousePos /= windowSize;
|
|
||||||
|
|
||||||
//SHLOG_INFO("mousePos: {} , {}", mousePos.x, mousePos.y);
|
|
||||||
comp.isClicked = false;
|
comp.isClicked = false;
|
||||||
if (mousePos.x >= topExtent.x && mousePos.x <= btmExtent.x
|
if (mousePos.x >= topExtent.x && mousePos.x <= btmExtent.x
|
||||||
&& mousePos.y >= topExtent.y && mousePos.y <= btmExtent.y)
|
&& mousePos.y >= topExtent.y && mousePos.y <= btmExtent.y)
|
||||||
{
|
{
|
||||||
comp.isHovered = true;
|
comp.isHovered = true;
|
||||||
if (SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::LMB))
|
#ifdef SHEDITOR
|
||||||
|
if (SHSystemManager::GetSystem<SHEditor>()->editorState == SHEditor::State::PLAY)
|
||||||
|
{
|
||||||
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::LMB))
|
||||||
|
{
|
||||||
|
comp.isClicked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (SHInputManager::GetKeyDown(SHInputManager::SH_KEYCODE::LMB))
|
||||||
{
|
{
|
||||||
comp.isClicked = true;
|
comp.isClicked = true;
|
||||||
}
|
}
|
||||||
//SHLOG_INFO("BUTTON HOVERED");
|
#endif
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
comp.isHovered = false;
|
comp.isHovered = false;
|
||||||
|
|
||||||
//SHLOG_INFO("BUTTON NOT HOVERED")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (comp.isClicked && SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::LMB))
|
||||||
|
{
|
||||||
|
comp.isClicked = false;
|
||||||
|
comp.value = !comp.value;
|
||||||
|
SHButtonClickEvent clickEvent;
|
||||||
|
clickEvent.EID = comp.GetEID();
|
||||||
|
clickEvent.value = comp.value;
|
||||||
|
SHEventManager::BroadcastEvent(clickEvent, SH_BUTTON_CLICK_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
if (SHComponentManager::HasComponent<SHRenderable>(comp.GetEID()))
|
if (SHComponentManager::HasComponent<SHRenderable>(comp.GetEID()))
|
||||||
{
|
{
|
||||||
//auto renderable = SHComponentManager::GetComponent_s<SHRenderable>(comp.GetEID());
|
auto renderable = SHComponentManager::GetComponent_s<SHRenderable>(comp.GetEID());
|
||||||
//auto texture = SHResourceManager::Get<SHTexture>(comp.GetDefaultTexture());
|
//auto texture = SHResourceManager::Get<SHTexture>(comp.GetDefaultTexture());
|
||||||
|
|
||||||
//auto material = renderable->GetModifiableMaterial();
|
auto material = renderable->GetModifiableMaterial();
|
||||||
//material->SetProperty("texture", comp.GetDefaultTexture());
|
if (comp.GetValue() == false)
|
||||||
|
{
|
||||||
|
if (comp.GetDefaultTexture()!= 0 && SHAssetManager::GetType(comp.GetDefaultTexture()) == AssetType::TEXTURE)
|
||||||
|
{
|
||||||
|
material->SetProperty("data.textureIndex", comp.GetDefaultTexture());
|
||||||
|
//SHLOG_INFO("SETTING DEFAULT TEXTURE")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (comp.GetToggledTexture() != 0 && SHAssetManager::GetType(comp.GetToggledTexture()) == AssetType::TEXTURE)
|
||||||
|
{
|
||||||
|
material->SetProperty("data.textureIndex", comp.GetToggledTexture());
|
||||||
|
//SHLOG_INFO("SETTING DEFAULT TEXTURE")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHUISystem::UpdateButtonsRoutine::Execute(double dt) noexcept
|
void SHUISystem::UpdateButtonsRoutine::Execute(double dt) noexcept
|
||||||
{
|
{
|
||||||
SHUISystem* system = (SHUISystem*)GetSystem();
|
SHUISystem* system = (SHUISystem*)GetSystem();
|
||||||
|
@ -219,6 +385,34 @@ namespace SHADE
|
||||||
if (SHSceneManager::CheckNodeAndComponentsActive<SHButtonComponent>(comp.GetEID()))
|
if (SHSceneManager::CheckNodeAndComponentsActive<SHButtonComponent>(comp.GetEID()))
|
||||||
system->UpdateButtonComponent(comp);
|
system->UpdateButtonComponent(comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& toggleButtonDense = SHComponentManager::GetDense<SHToggleButtonComponent>();
|
||||||
|
for (auto& comp : toggleButtonDense)
|
||||||
|
{
|
||||||
|
if (SHSceneManager::CheckNodeAndComponentsActive<SHToggleButtonComponent>(comp.GetEID()))
|
||||||
|
system->UpdateToggleButtonComponent(comp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHVec2 SHUISystem::CanvasToScreenPoint(SHVec2& const canvasPoint, bool normalized) noexcept
|
||||||
|
{
|
||||||
|
SHVec2 result{canvasPoint};
|
||||||
|
|
||||||
|
auto cameraSystem = SHSystemManager::GetSystem<SHCameraSystem>();
|
||||||
|
|
||||||
|
SHVec2 camSize{ cameraSystem->GetCameraWidthHeight(0) };
|
||||||
|
//camSize.y *= -1.0f;
|
||||||
|
|
||||||
|
result.y *= -1.0f;
|
||||||
|
result += camSize * 0.5f;
|
||||||
|
|
||||||
|
if (normalized)
|
||||||
|
return result / camSize;
|
||||||
|
else
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}//end namespace
|
}//end namespace
|
||||||
|
|
|
@ -3,14 +3,20 @@
|
||||||
#include "SH_API.h"
|
#include "SH_API.h"
|
||||||
#include "ECS_Base/System/SHSystem.h"
|
#include "ECS_Base/System/SHSystem.h"
|
||||||
#include "ECS_Base/System/SHSystemRoutine.h"
|
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||||
#include "SHUIComponent.h"
|
|
||||||
#include "SHButtonComponent.h"
|
|
||||||
#include "SHCanvasComponent.h"
|
|
||||||
#include "Scene/SHSceneGraph.h"
|
#include "Scene/SHSceneGraph.h"
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
|
#include "Math/Vector/SHVec2.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class SHButtonComponent;
|
||||||
|
class SHUIComponent;
|
||||||
|
class SHToggleButtonComponent;
|
||||||
|
class SHSliderComponent;
|
||||||
|
class SHCanvasComponent;
|
||||||
|
|
||||||
class SH_API SHUISystem final: public SHSystem
|
class SH_API SHUISystem final: public SHSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -64,8 +70,12 @@ namespace SHADE
|
||||||
private:
|
private:
|
||||||
void UpdateUIComponent(SHUIComponent& comp) noexcept;
|
void UpdateUIComponent(SHUIComponent& comp) noexcept;
|
||||||
void UpdateButtonComponent(SHButtonComponent& comp) noexcept;
|
void UpdateButtonComponent(SHButtonComponent& comp) noexcept;
|
||||||
|
void UpdateToggleButtonComponent(SHToggleButtonComponent& comp) noexcept;
|
||||||
void UpdateCanvasComponent(SHCanvasComponent& comp) noexcept;
|
void UpdateCanvasComponent(SHCanvasComponent& comp) noexcept;
|
||||||
|
|
||||||
|
SHVec2 CanvasToScreenPoint(SHVec2& const canvasPoint, bool normalized) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue