diff --git a/Assets/Scenes/MainGame.shade b/Assets/Scenes/MainGame.shade index 29cfdda0..49602e78 100644 --- a/Assets/Scenes/MainGame.shade +++ b/Assets/Scenes/MainGame.shade @@ -474,6 +474,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 10, y: 0.0500000007, z: 18} Friction: 0.400000006 @@ -511,6 +512,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.200000003, z: 0.25} Friction: 0.400000006 @@ -519,6 +521,7 @@ Position Offset: {x: 0, y: 2.0999999, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.899999976, z: 0.25} Friction: 0.400000006 @@ -527,6 +530,7 @@ Position Offset: {x: 0, y: 0.449999988, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -535,6 +539,7 @@ Position Offset: {x: -0.449999988, y: 1.10000002, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -561,6 +566,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1.10000002, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -569,6 +575,7 @@ Position Offset: {x: 0.449999988, y: 1.10000002, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.25, y: 2.20000005, z: 1.10000002} Friction: 0.400000006 @@ -595,6 +602,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -621,6 +629,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -647,6 +656,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -673,6 +683,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -699,6 +710,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -725,6 +737,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1.10000002, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -733,6 +746,7 @@ Position Offset: {x: 0.449999988, y: 1.10000002, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.25, y: 2.20000005, z: 1.10000002} Friction: 0.400000006 @@ -759,6 +773,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -785,6 +800,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -811,6 +827,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -837,6 +854,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.150000006, z: 0.25} Friction: 0.400000006 @@ -845,6 +863,7 @@ Position Offset: {x: 0, y: 2.125, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -853,6 +872,7 @@ Position Offset: {x: -0.455000013, y: 1.10000002, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -897,6 +917,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.800000012, y: 2, z: 0.0350000001} Friction: 0.400000006 @@ -923,6 +944,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -949,6 +971,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1.10000002, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -957,6 +980,7 @@ Position Offset: {x: 0.449999988, y: 1.10000002, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.25, y: 2.20000005, z: 1.10000002} Friction: 0.400000006 @@ -983,6 +1007,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -1009,6 +1034,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -1035,6 +1061,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -1061,6 +1088,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -1087,6 +1115,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -1113,6 +1142,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.150000006, z: 0.25} Friction: 0.400000006 @@ -1121,6 +1151,7 @@ Position Offset: {x: 0, y: 2.125, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -1129,6 +1160,7 @@ Position Offset: {x: -0.455000013, y: 1.10000002, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -1173,6 +1205,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.800000012, y: 2, z: 0.0350000001} Friction: 0.400000006 @@ -1199,6 +1232,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -1225,6 +1259,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -1251,6 +1286,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -1277,6 +1313,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -1303,6 +1340,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -1351,6 +1389,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1377,6 +1416,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1403,6 +1443,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1429,6 +1470,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1455,6 +1497,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1492,6 +1535,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1518,6 +1562,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1544,6 +1589,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1570,6 +1616,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1596,6 +1643,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1633,6 +1681,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1659,6 +1708,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1685,6 +1735,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1711,6 +1762,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1737,6 +1789,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1774,6 +1827,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1800,6 +1854,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1826,6 +1881,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1852,6 +1908,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1878,6 +1935,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1915,6 +1973,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1941,6 +2000,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1967,6 +2027,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -1993,6 +2054,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -2019,6 +2081,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -2171,6 +2234,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -2197,6 +2261,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -2234,6 +2299,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -2260,6 +2326,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.0500000007, z: 2} Friction: 0.400000006 @@ -2297,6 +2364,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1.10000002, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -2305,6 +2373,7 @@ Position Offset: {x: 0.449999988, y: 1.10000002, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.25, y: 2.20000005, z: 1.10000002} Friction: 0.400000006 @@ -2331,6 +2400,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1.10000002, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -2339,6 +2409,7 @@ Position Offset: {x: 0.449999988, y: 1.10000002, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.25, y: 2.20000005, z: 1.10000002} Friction: 0.400000006 @@ -2365,6 +2436,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.200000003, z: 0.25} Friction: 0.400000006 @@ -2373,6 +2445,7 @@ Position Offset: {x: 0, y: 2.0999999, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 0.899999976, z: 0.25} Friction: 0.400000006 @@ -2381,6 +2454,7 @@ Position Offset: {x: 0, y: 0.449999988, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -2389,6 +2463,7 @@ Position Offset: {x: -0.949999988, y: 1.10000002, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -2415,6 +2490,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -2441,6 +2517,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 2, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -2467,6 +2544,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -2493,6 +2571,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 2.20000005, z: 0.25} Friction: 0.400000006 @@ -2519,6 +2598,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.400000006, y: 0.439999998, z: 0.400000006} Friction: 0.400000006 @@ -2527,6 +2607,7 @@ Position Offset: {x: 0, y: 0.219999999, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0399999991, y: 1, z: 0.400000006} Friction: 0.400000006 @@ -2575,6 +2656,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -2601,6 +2683,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -2627,6 +2710,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -2653,6 +2737,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -2661,6 +2746,7 @@ Position Offset: {x: 0, y: 0.0250000004, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -2669,6 +2755,7 @@ Position Offset: {x: 0, y: 1.17499995, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -2677,6 +2764,7 @@ Position Offset: {x: 0, y: 0.600000024, z: 0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -2685,6 +2773,7 @@ Position Offset: {x: 0, y: 0.600000024, z: -0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -2711,6 +2800,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.970000029, y: 0.0250000004, z: 0.870000005} Friction: 0.400000006 @@ -2719,6 +2809,7 @@ Position Offset: {x: -0.310000002, y: -0.219999999, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0450000018, y: 0.349999994, z: 0.870000005} Friction: 0.400000006 @@ -2727,6 +2818,7 @@ Position Offset: {x: 0.147, y: -0.0700000003, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0450000018, y: 0.349999994, z: 0.870000005} Friction: 0.400000006 @@ -2735,6 +2827,7 @@ Position Offset: {x: -0.757000029, y: -0.0700000003, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.959999979, y: 0.349999994, z: 0.0450000018} Friction: 0.400000006 @@ -2743,6 +2836,7 @@ Position Offset: {x: -0.310000002, y: -0.0700000003, z: -0.425000012} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.959999979, y: 0.349999994, z: 0.0450000018} Friction: 0.400000006 @@ -2769,6 +2863,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.970000029, y: 0.0250000004, z: 0.870000005} Friction: 0.400000006 @@ -2777,6 +2872,7 @@ Position Offset: {x: -0.310000002, y: -0.219999999, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0450000018, y: 0.349999994, z: 0.870000005} Friction: 0.400000006 @@ -2785,6 +2881,7 @@ Position Offset: {x: 0.147, y: -0.0700000003, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0450000018, y: 0.349999994, z: 0.870000005} Friction: 0.400000006 @@ -2793,6 +2890,7 @@ Position Offset: {x: -0.757000029, y: -0.0700000003, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.959999979, y: 0.349999994, z: 0.0450000018} Friction: 0.400000006 @@ -2801,6 +2899,7 @@ Position Offset: {x: -0.310000002, y: -0.0700000003, z: -0.425000012} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.959999979, y: 0.349999994, z: 0.0450000018} Friction: 0.400000006 @@ -2827,6 +2926,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.970000029, y: 0.0250000004, z: 0.870000005} Friction: 0.400000006 @@ -2835,6 +2935,7 @@ Position Offset: {x: -0.310000002, y: -0.219999999, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0450000018, y: 0.349999994, z: 0.870000005} Friction: 0.400000006 @@ -2843,6 +2944,7 @@ Position Offset: {x: 0.147, y: -0.0700000003, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0450000018, y: 0.349999994, z: 0.870000005} Friction: 0.400000006 @@ -2851,6 +2953,7 @@ Position Offset: {x: -0.757000029, y: -0.0700000003, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.959999979, y: 0.349999994, z: 0.0450000018} Friction: 0.400000006 @@ -2859,6 +2962,7 @@ Position Offset: {x: -0.310000002, y: -0.0700000003, z: -0.425000012} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.959999979, y: 0.349999994, z: 0.0450000018} Friction: 0.400000006 @@ -2885,6 +2989,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -2911,6 +3016,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 0.725000024, z: 0.850000024} Friction: 0.400000006 @@ -2952,6 +3058,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.800000012, y: 0.0500000007, z: 0.800000012} Friction: 0.400000006 @@ -2978,6 +3085,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -2986,6 +3094,7 @@ Position Offset: {x: 0, y: 0.0250000004, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -2994,6 +3103,7 @@ Position Offset: {x: 0, y: 0.860000014, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -3002,6 +3112,7 @@ Position Offset: {x: 0, y: 0.600000024, z: 0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -3010,6 +3121,7 @@ Position Offset: {x: 0, y: 0.600000024, z: -0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -3018,6 +3130,7 @@ Position Offset: {x: -0.444999993, y: 0.600000024, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.300000012, z: 1} Friction: 0.400000006 @@ -3026,6 +3139,7 @@ Position Offset: {x: 0.444999993, y: 1.04999995, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.300000012, z: 0.100000001} Friction: 0.400000006 @@ -3034,6 +3148,7 @@ Position Offset: {x: 0, y: 1.04999995, z: 0.444999993} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.300000012, z: 0.100000001} Friction: 0.400000006 @@ -3042,6 +3157,7 @@ Position Offset: {x: 0, y: 1.04999995, z: -0.444999993} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.300000012, z: 0.100000001} Friction: 0.400000006 @@ -3068,6 +3184,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 1.07500005, z: 0.925000012} Friction: 0.400000006 @@ -3094,6 +3211,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -3102,6 +3220,7 @@ Position Offset: {x: 0, y: 0.0250000004, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -3110,6 +3229,7 @@ Position Offset: {x: 0, y: 0.860000014, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -3118,6 +3238,7 @@ Position Offset: {x: 0, y: 0.600000024, z: 0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -3126,6 +3247,7 @@ Position Offset: {x: 0, y: 0.600000024, z: -0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -3134,6 +3256,7 @@ Position Offset: {x: -0.444999993, y: 0.600000024, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.300000012, z: 1} Friction: 0.400000006 @@ -3142,6 +3265,7 @@ Position Offset: {x: 0.444999993, y: 1.04999995, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.300000012, z: 0.100000001} Friction: 0.400000006 @@ -3150,6 +3274,7 @@ Position Offset: {x: 0, y: 1.04999995, z: 0.444999993} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.300000012, z: 0.100000001} Friction: 0.400000006 @@ -3158,6 +3283,7 @@ Position Offset: {x: 0, y: 1.04999995, z: -0.444999993} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.300000012, z: 0.100000001} Friction: 0.400000006 @@ -3184,6 +3310,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 1.07500005, z: 0.925000012} Friction: 0.400000006 @@ -3210,6 +3337,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -3236,6 +3364,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.400000006, y: 1.29999995, z: 1} Friction: 0.400000006 @@ -3244,6 +3373,7 @@ Position Offset: {x: 0, y: 0.699999988, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.600000024, y: 1.70000005, z: 0.0700000003} Friction: 0.400000006 @@ -3252,6 +3382,7 @@ Position Offset: {x: 0, y: 0.850000024, z: -0.5} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.600000024, y: 1.70000005, z: 0.0700000003} Friction: 0.400000006 @@ -3278,6 +3409,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.300000012, y: 0.800000012, z: 0.300000012} Friction: 0.400000006 @@ -3315,6 +3447,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.699999988, y: 0.0500000007, z: 1.20000005} Friction: 0.400000006 @@ -3323,6 +3456,7 @@ Position Offset: {x: 0, y: 0.77700001, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 0.800000012, z: 0.0500000007} Friction: 0.400000006 @@ -3331,6 +3465,7 @@ Position Offset: {x: -0.449999988, y: 0.400000006, z: -0.850000024} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 0.800000012, z: 0.0500000007} Friction: 0.400000006 @@ -3339,6 +3474,7 @@ Position Offset: {x: -0.449999988, y: 0.400000006, z: 0.850000024} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 0.800000012, z: 0.0500000007} Friction: 0.400000006 @@ -3347,6 +3483,7 @@ Position Offset: {x: 0.449999988, y: 0.400000006, z: 0.850000024} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 0.800000012, z: 0.0500000007} Friction: 0.400000006 @@ -3373,6 +3510,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.400000006, y: 0.439999998, z: 0.400000006} Friction: 0.400000006 @@ -3381,6 +3519,7 @@ Position Offset: {x: 0, y: 0.219999999, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0399999991, y: 1, z: 0.400000006} Friction: 0.400000006 @@ -3407,6 +3546,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.400000006, y: 0.439999998, z: 0.400000006} Friction: 0.400000006 @@ -3415,6 +3555,7 @@ Position Offset: {x: 0, y: 0.219999999, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0399999991, y: 1, z: 0.400000006} Friction: 0.400000006 @@ -3441,6 +3582,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.400000006, y: 0.439999998, z: 0.400000006} Friction: 0.400000006 @@ -3449,6 +3591,7 @@ Position Offset: {x: 0, y: 0.219999999, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0399999991, y: 1, z: 0.400000006} Friction: 0.400000006 @@ -3475,6 +3618,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.400000006, y: 0.439999998, z: 0.400000006} Friction: 0.400000006 @@ -3483,6 +3627,7 @@ Position Offset: {x: 0, y: 0.219999999, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0399999991, y: 1, z: 0.400000006} Friction: 0.400000006 @@ -3520,6 +3665,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -3528,6 +3674,7 @@ Position Offset: {x: 0, y: 0.0250000004, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -3536,6 +3683,7 @@ Position Offset: {x: 0, y: 1.17499995, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -3544,6 +3692,7 @@ Position Offset: {x: 0, y: 0.600000024, z: 0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -3552,6 +3701,7 @@ Position Offset: {x: 0, y: 0.600000024, z: -0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -3578,6 +3728,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -3586,6 +3737,7 @@ Position Offset: {x: 0, y: 0.0250000004, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -3594,6 +3746,7 @@ Position Offset: {x: 0, y: 1.17499995, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -3602,6 +3755,7 @@ Position Offset: {x: 0, y: 0.600000024, z: 0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -3610,6 +3764,7 @@ Position Offset: {x: 0, y: 0.600000024, z: -0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -3636,6 +3791,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -3644,6 +3800,7 @@ Position Offset: {x: 0, y: 0.0250000004, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -3652,6 +3809,7 @@ Position Offset: {x: 0, y: 0.860000014, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -3660,6 +3818,7 @@ Position Offset: {x: 0, y: 0.600000024, z: 0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -3668,6 +3827,7 @@ Position Offset: {x: 0, y: 0.600000024, z: -0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -3676,6 +3836,7 @@ Position Offset: {x: -0.444999993, y: 0.600000024, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.300000012, z: 1} Friction: 0.400000006 @@ -3684,6 +3845,7 @@ Position Offset: {x: 0.444999993, y: 1.04999995, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.300000012, z: 0.100000001} Friction: 0.400000006 @@ -3692,6 +3854,7 @@ Position Offset: {x: 0, y: 1.04999995, z: 0.444999993} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.300000012, z: 0.100000001} Friction: 0.400000006 @@ -3700,6 +3863,7 @@ Position Offset: {x: 0, y: 1.04999995, z: -0.444999993} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.300000012, z: 0.100000001} Friction: 0.400000006 @@ -3726,6 +3890,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 1.07500005, z: 0.462500006} Friction: 0.400000006 @@ -3752,6 +3917,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 1.07500005, z: 0.462500006} Friction: 0.400000006 @@ -3778,6 +3944,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -3786,6 +3953,7 @@ Position Offset: {x: 0, y: 0.0250000004, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -3794,6 +3962,7 @@ Position Offset: {x: 0, y: 1.17499995, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -3802,6 +3971,7 @@ Position Offset: {x: 0, y: 0.600000024, z: 0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -3810,6 +3980,7 @@ Position Offset: {x: 0, y: 0.600000024, z: -0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -3836,6 +4007,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.970000029, y: 0.0250000004, z: 0.870000005} Friction: 0.400000006 @@ -3844,6 +4016,7 @@ Position Offset: {x: -0.310000002, y: -0.519999981, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0450000018, y: 0.699999988, z: 0.870000005} Friction: 0.400000006 @@ -3852,6 +4025,7 @@ Position Offset: {x: 0.147, y: -0.170000002, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0450000018, y: 0.699999988, z: 0.870000005} Friction: 0.400000006 @@ -3860,6 +4034,7 @@ Position Offset: {x: -0.757000029, y: -0.170000002, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.959999979, y: 0.699999988, z: 0.0450000018} Friction: 0.400000006 @@ -3868,6 +4043,7 @@ Position Offset: {x: -0.310000002, y: -0.170000002, z: -0.425000012} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.959999979, y: 0.699999988, z: 0.0450000018} Friction: 0.400000006 @@ -3894,6 +4070,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.970000029, y: 0.0250000004, z: 0.870000005} Friction: 0.400000006 @@ -3902,6 +4079,7 @@ Position Offset: {x: -0.310000002, y: -0.219999999, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0450000018, y: 0.349999994, z: 0.870000005} Friction: 0.400000006 @@ -3910,6 +4088,7 @@ Position Offset: {x: 0.147, y: -0.0700000003, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0450000018, y: 0.349999994, z: 0.870000005} Friction: 0.400000006 @@ -3918,6 +4097,7 @@ Position Offset: {x: -0.757000029, y: -0.0700000003, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.959999979, y: 0.349999994, z: 0.0450000018} Friction: 0.400000006 @@ -3926,6 +4106,7 @@ Position Offset: {x: -0.310000002, y: -0.0700000003, z: -0.425000012} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.959999979, y: 0.349999994, z: 0.0450000018} Friction: 0.400000006 @@ -3952,6 +4133,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -3960,6 +4142,7 @@ Position Offset: {x: 0, y: 0.0250000004, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -3968,6 +4151,7 @@ Position Offset: {x: 0, y: 1.17499995, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -3976,6 +4160,7 @@ Position Offset: {x: 0, y: 0.600000024, z: 0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -3984,6 +4169,7 @@ Position Offset: {x: 0, y: 0.600000024, z: -0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -4010,6 +4196,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -4036,6 +4223,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -4062,6 +4250,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -4088,6 +4277,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -4114,6 +4304,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -4140,6 +4331,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 0.725000024, z: 0.850000024} Friction: 0.400000006 @@ -4181,6 +4373,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.800000012, y: 0.0500000007, z: 0.800000012} Friction: 0.400000006 @@ -4207,6 +4400,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -4233,6 +4427,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 0.725000024, z: 0.850000024} Friction: 0.400000006 @@ -4274,6 +4469,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.800000012, y: 0.0500000007, z: 0.800000012} Friction: 0.400000006 @@ -4300,6 +4496,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -4308,6 +4505,7 @@ Position Offset: {x: 0, y: 0.0250000004, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -4316,6 +4514,7 @@ Position Offset: {x: 0, y: 1.17499995, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -4324,6 +4523,7 @@ Position Offset: {x: 0, y: 0.600000024, z: 0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -4332,6 +4532,7 @@ Position Offset: {x: 0, y: 0.600000024, z: -0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -4358,6 +4559,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -4366,6 +4568,7 @@ Position Offset: {x: 0, y: 0.0250000004, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -4374,6 +4577,7 @@ Position Offset: {x: 0, y: 1.17499995, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -4382,6 +4586,7 @@ Position Offset: {x: 0, y: 0.600000024, z: 0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -4390,6 +4595,7 @@ Position Offset: {x: 0, y: 0.600000024, z: -0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -4416,6 +4622,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -4424,6 +4631,7 @@ Position Offset: {x: 0, y: 0.0250000004, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -4432,6 +4640,7 @@ Position Offset: {x: 0, y: 1.17499995, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -4440,6 +4649,7 @@ Position Offset: {x: 0, y: 0.600000024, z: 0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -4448,6 +4658,7 @@ Position Offset: {x: 0, y: 0.600000024, z: -0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -4474,6 +4685,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -4482,6 +4694,7 @@ Position Offset: {x: 0, y: 0.0250000004, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.0500000007, z: 1} Friction: 0.400000006 @@ -4490,6 +4703,7 @@ Position Offset: {x: 0, y: 1.17499995, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -4498,6 +4712,7 @@ Position Offset: {x: 0, y: 0.600000024, z: 0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.20000005, z: 0.0500000007} Friction: 0.400000006 @@ -4506,6 +4721,7 @@ Position Offset: {x: 0, y: 0.600000024, z: -0.474999994} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 1.20000005, z: 1} Friction: 0.400000006 @@ -4532,6 +4748,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.970000029, y: 0.0250000004, z: 0.870000005} Friction: 0.400000006 @@ -4540,6 +4757,7 @@ Position Offset: {x: -0.310000002, y: -0.519999981, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0450000018, y: 0.699999988, z: 0.870000005} Friction: 0.400000006 @@ -4548,6 +4766,7 @@ Position Offset: {x: 0.147, y: -0.170000002, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0450000018, y: 0.699999988, z: 0.870000005} Friction: 0.400000006 @@ -4556,6 +4775,7 @@ Position Offset: {x: -0.757000029, y: -0.170000002, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.959999979, y: 0.699999988, z: 0.0450000018} Friction: 0.400000006 @@ -4564,6 +4784,7 @@ Position Offset: {x: -0.310000002, y: -0.170000002, z: -0.425000012} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.959999979, y: 0.699999988, z: 0.0450000018} Friction: 0.400000006 @@ -4590,6 +4811,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.970000029, y: 0.0250000004, z: 0.870000005} Friction: 0.400000006 @@ -4598,6 +4820,7 @@ Position Offset: {x: -0.310000002, y: -0.219999999, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0450000018, y: 0.349999994, z: 0.870000005} Friction: 0.400000006 @@ -4606,6 +4829,7 @@ Position Offset: {x: 0.147, y: -0.0700000003, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0450000018, y: 0.349999994, z: 0.870000005} Friction: 0.400000006 @@ -4614,6 +4838,7 @@ Position Offset: {x: -0.757000029, y: -0.0700000003, z: 0.00499999989} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.959999979, y: 0.349999994, z: 0.0450000018} Friction: 0.400000006 @@ -4622,6 +4847,7 @@ Position Offset: {x: -0.310000002, y: -0.0700000003, z: -0.425000012} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.959999979, y: 0.349999994, z: 0.0450000018} Friction: 0.400000006 @@ -4648,6 +4874,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.300000012, y: 0.800000012, z: 0.300000012} Friction: 0.400000006 @@ -4685,6 +4912,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1.20000005, y: 0.100000001, z: 2.20000005} Friction: 0.400000006 @@ -4711,6 +4939,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1.20000005, y: 0.100000001, z: 2.20000005} Friction: 0.400000006 @@ -4737,6 +4966,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.100000001, z: 1.89999998} Friction: 0.400000006 @@ -4763,6 +4993,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.899999976, y: 0.100000001, z: 1.89999998} Friction: 0.400000006 @@ -4789,6 +5020,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.100000001} Friction: 0.400000006 @@ -4797,6 +5029,7 @@ Position Offset: {x: 0, y: 0.5, z: -0.954999983} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.100000001} Friction: 0.400000006 @@ -4823,6 +5056,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.100000001} Friction: 0.400000006 @@ -4831,6 +5065,7 @@ Position Offset: {x: 0, y: 0.5, z: -0.954999983} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.100000001} Friction: 0.400000006 @@ -4857,6 +5092,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.400000006, y: 0.439999998, z: 0.400000006} Friction: 0.400000006 @@ -4865,6 +5101,7 @@ Position Offset: {x: 0, y: 0.219999999, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0399999991, y: 1, z: 0.400000006} Friction: 0.400000006 @@ -4902,6 +5139,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1.20000005, y: 0.100000001, z: 2.20000005} Friction: 0.400000006 @@ -4928,6 +5166,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1.20000005, y: 0.100000001, z: 2.20000005} Friction: 0.400000006 @@ -4954,6 +5193,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.100000001, z: 1.89999998} Friction: 0.400000006 @@ -4980,6 +5220,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.899999976, y: 0.100000001, z: 1.89999998} Friction: 0.400000006 @@ -5006,6 +5247,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.100000001} Friction: 0.400000006 @@ -5014,6 +5256,7 @@ Position Offset: {x: 0, y: 0.5, z: -0.954999983} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.100000001} Friction: 0.400000006 @@ -5040,6 +5283,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.100000001} Friction: 0.400000006 @@ -5048,6 +5292,7 @@ Position Offset: {x: 0, y: 0.5, z: -0.954999983} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.100000001} Friction: 0.400000006 @@ -5085,6 +5330,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1.20000005, y: 0.100000001, z: 2.20000005} Friction: 0.400000006 @@ -5111,6 +5357,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1.20000005, y: 0.100000001, z: 2.20000005} Friction: 0.400000006 @@ -5137,6 +5384,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.100000001, z: 1.89999998} Friction: 0.400000006 @@ -5163,6 +5411,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.899999976, y: 0.100000001, z: 1.89999998} Friction: 0.400000006 @@ -5189,6 +5438,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.100000001} Friction: 0.400000006 @@ -5197,6 +5447,7 @@ Position Offset: {x: 0, y: 0.5, z: -0.954999983} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.100000001} Friction: 0.400000006 @@ -5223,6 +5474,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.100000001} Friction: 0.400000006 @@ -5231,6 +5483,7 @@ Position Offset: {x: 0, y: 0.5, z: -0.954999983} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.100000001} Friction: 0.400000006 @@ -5257,6 +5510,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.699999988, y: 0.0500000007, z: 1.20000005} Friction: 0.400000006 @@ -5265,6 +5519,7 @@ Position Offset: {x: 0, y: 0.77700001, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 0.800000012, z: 0.0500000007} Friction: 0.400000006 @@ -5273,6 +5528,7 @@ Position Offset: {x: -0.25, y: 0.400000006, z: -0.550000012} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 0.800000012, z: 0.0500000007} Friction: 0.400000006 @@ -5281,6 +5537,7 @@ Position Offset: {x: -0.25, y: 0.400000006, z: 0.550000012} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 0.800000012, z: 0.0500000007} Friction: 0.400000006 @@ -5289,6 +5546,7 @@ Position Offset: {x: 0.25, y: 0.400000006, z: 0.550000012} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0500000007, y: 0.800000012, z: 0.0500000007} Friction: 0.400000006 @@ -5315,6 +5573,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.400000006, y: 0.439999998, z: 0.400000006} Friction: 0.400000006 @@ -5323,6 +5582,7 @@ Position Offset: {x: 0, y: 0.219999999, z: 0} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.0399999991, y: 1, z: 0.400000006} Friction: 0.400000006 @@ -5360,6 +5620,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1.20000005, y: 0.100000001, z: 2.20000005} Friction: 0.400000006 @@ -5386,6 +5647,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1.20000005, y: 0.100000001, z: 2.20000005} Friction: 0.400000006 @@ -5412,6 +5674,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 0.100000001, z: 1.89999998} Friction: 0.400000006 @@ -5438,6 +5701,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.100000001} Friction: 0.400000006 @@ -5446,6 +5710,7 @@ Position Offset: {x: 0, y: 0.5, z: -0.954999983} Rotation Offset: {x: 0, y: 0, z: 0} - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.100000001} Friction: 0.400000006 @@ -8235,6 +8500,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.300000012, y: 0.300000012, z: 0.300000012} Friction: 0.400000006 @@ -8279,6 +8545,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.300000012, y: 0.300000012, z: 0.300000012} Friction: 0.400000006 @@ -8323,6 +8590,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.300000012, y: 0.300000012, z: 0.300000012} Friction: 0.400000006 @@ -8367,6 +8635,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.5, y: 0.150000006, z: 0.5} Friction: 0.400000006 @@ -8411,6 +8680,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.5, y: 0.150000006, z: 0.5} Friction: 0.400000006 @@ -8455,6 +8725,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.5, y: 0.150000006, z: 0.5} Friction: 0.400000006 @@ -8499,6 +8770,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.200000003, y: 0.200000003, z: 0.200000003} Friction: 0.400000006 @@ -8543,6 +8815,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.200000003, y: 0.200000003, z: 0.200000003} Friction: 0.400000006 @@ -8587,6 +8860,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.200000003, y: 0.200000003, z: 0.200000003} Friction: 0.400000006 @@ -8633,6 +8907,7 @@ Collider Component: Colliders: - Is Trigger: true + Collision Tag: 1 Type: Box Half Extents: {x: 1.79999995, y: 1, z: 1} Friction: 0.400000006 @@ -8671,6 +8946,7 @@ Collider Component: Colliders: - Is Trigger: true + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1, z: 0.200000003} Friction: 0.400000006 @@ -8773,6 +9049,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.400000006, y: 0.5, z: 0.300000012} Friction: 0.400000006 @@ -8916,6 +9193,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.200000003, y: 0.100000001, z: 0.200000003} Friction: 0.400000006 @@ -8960,6 +9238,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.0500000007, z: 0.150000006} Friction: 0.400000006 @@ -9000,6 +9279,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.0500000007, z: 0.200000003} Friction: 0.400000006 @@ -9040,6 +9320,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.0500000007, z: 0.150000006} Friction: 0.400000006 @@ -9080,6 +9361,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.0500000007, z: 0.150000006} Friction: 0.400000006 @@ -9120,6 +9402,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.200000003, y: 0.100000001, z: 0.200000003} Friction: 0.400000006 @@ -9164,6 +9447,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.0500000007, z: 0.150000006} Friction: 0.400000006 @@ -9204,6 +9488,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.0500000007, z: 0.200000003} Friction: 0.400000006 @@ -9244,6 +9529,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.0500000007, z: 0.150000006} Friction: 0.400000006 @@ -9284,6 +9570,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.0500000007, z: 0.150000006} Friction: 0.400000006 @@ -9324,6 +9611,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.200000003, y: 0.100000001, z: 0.200000003} Friction: 0.400000006 @@ -9368,6 +9656,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.0500000007, z: 0.150000006} Friction: 0.400000006 @@ -9408,6 +9697,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.0500000007, z: 0.200000003} Friction: 0.400000006 @@ -9448,6 +9738,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.0500000007, z: 0.150000006} Friction: 0.400000006 @@ -9488,6 +9779,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 0.100000001, y: 0.0500000007, z: 0.150000006} Friction: 0.400000006 @@ -9611,6 +9903,7 @@ Collider Component: Colliders: - Is Trigger: false + Collision Tag: 1 Type: Box Half Extents: {x: 1, y: 1.79999995, z: 0.400000006} Friction: 0.400000006 diff --git a/Assets/Shaders/DebugDrawMesh_VS.glsl b/Assets/Shaders/DebugDrawMesh_VS.glsl index 2f035261..1f3b43ac 100644 --- a/Assets/Shaders/DebugDrawMesh_VS.glsl +++ b/Assets/Shaders/DebugDrawMesh_VS.glsl @@ -11,13 +11,12 @@ layout(location = 0) out struct vec4 Color; } Out; -layout(set = 2, binding = 0) uniform CameraData +layout(set = 1, binding = 0) uniform CameraData { vec4 position; mat4 vpMat; mat4 viewMat; - mat4 perspectiveMat; - mat4 orthoMat; + mat4 projMat; } cameraData; void main() diff --git a/Assets/Shaders/DebugDrawMesh_VS.shshaderb b/Assets/Shaders/DebugDrawMesh_VS.shshaderb index 442cd789..c00e88f8 100644 Binary files a/Assets/Shaders/DebugDrawMesh_VS.shshaderb and b/Assets/Shaders/DebugDrawMesh_VS.shshaderb differ diff --git a/Assets/Shaders/DebugDraw_VS.glsl b/Assets/Shaders/DebugDraw_VS.glsl index 42a48c01..dbfa7645 100644 --- a/Assets/Shaders/DebugDraw_VS.glsl +++ b/Assets/Shaders/DebugDraw_VS.glsl @@ -10,13 +10,12 @@ layout(location = 0) out struct vec4 vertColor; // location 0 } Out; -layout(set = 2, binding = 0) uniform CameraData +layout(set = 1, binding = 0) uniform CameraData { vec4 position; mat4 vpMat; mat4 viewMat; - mat4 perspectiveMat; - mat4 orthoMat; + mat4 projMat; } cameraData; void main() diff --git a/Assets/Shaders/DebugDraw_VS.shshaderb b/Assets/Shaders/DebugDraw_VS.shshaderb index 9f5f7766..3ce6c312 100644 Binary files a/Assets/Shaders/DebugDraw_VS.shshaderb and b/Assets/Shaders/DebugDraw_VS.shshaderb differ diff --git a/Assets/Shaders/DeferredComposite_CS.glsl b/Assets/Shaders/DeferredComposite_CS.glsl index 5af585ba..0a8085b1 100644 --- a/Assets/Shaders/DeferredComposite_CS.glsl +++ b/Assets/Shaders/DeferredComposite_CS.glsl @@ -17,12 +17,12 @@ struct AmbientLightStruct }; layout(local_size_x = 16, local_size_y = 16) in; -layout(set = 4, binding = 0, rgba32f) uniform image2D positions; -layout(set = 4, binding = 1, rgba32f) uniform image2D normals; -layout(set = 4, binding = 2, rgba8) uniform image2D albedo; -layout(set = 4, binding = 3, r32ui) uniform uimage2D lightLayerData; -layout(set = 4, binding = 4, r8) uniform image2D ssaoBlurredImage; -layout(set = 4, binding = 5, rgba8) uniform image2D targetImage; +layout(set = 3, binding = 0, rgba32f) uniform image2D positions; +layout(set = 3, binding = 1, rgba32f) uniform image2D normals; +layout(set = 3, binding = 2, rgba8) uniform image2D albedo; +layout(set = 3, binding = 3, r32ui) uniform uimage2D lightLayerData; +layout(set = 3, binding = 4, r8) uniform image2D ssaoBlurredImage; +layout(set = 3, binding = 5, rgba8) uniform image2D targetImage; layout(set = 1, binding = 0) uniform LightCounts { diff --git a/Assets/Shaders/DeferredComposite_CS.shshaderb b/Assets/Shaders/DeferredComposite_CS.shshaderb index 172a6a32..cabce080 100644 Binary files a/Assets/Shaders/DeferredComposite_CS.shshaderb and b/Assets/Shaders/DeferredComposite_CS.shshaderb differ diff --git a/Assets/Shaders/Kirsch_CS.glsl b/Assets/Shaders/Kirsch_CS.glsl index 3dec174d..8c60525a 100644 --- a/Assets/Shaders/Kirsch_CS.glsl +++ b/Assets/Shaders/Kirsch_CS.glsl @@ -50,8 +50,8 @@ #define NUM_MASKS 8 layout(local_size_x = 16, local_size_y = 16) in; -layout(set = 4, binding = 0, rgba8) uniform image2D inputImage; -layout(set = 4, binding = 1, rgba8) uniform image2D resultImage; +layout(set = 3, binding = 0, rgba8) uniform image2D inputImage; +layout(set = 3, binding = 1, rgba8) uniform image2D resultImage; const float kirsch[8][3][3] = { { diff --git a/Assets/Shaders/Normals_FS.glsl b/Assets/Shaders/Normals_FS.glsl index ba260d82..78b0a027 100644 --- a/Assets/Shaders/Normals_FS.glsl +++ b/Assets/Shaders/Normals_FS.glsl @@ -28,7 +28,7 @@ layout(location = 3) flat in struct } In2; layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global) -layout (std430, set = 3, binding = 0) buffer MaterialProperties // For materials +layout (std430, set = 2, binding = 0) buffer MaterialProperties // For materials { MatPropData data[]; } MatProp; diff --git a/Assets/Shaders/Normals_FS.shshaderb b/Assets/Shaders/Normals_FS.shshaderb index 7595ece9..7f72d16f 100644 Binary files a/Assets/Shaders/Normals_FS.shshaderb and b/Assets/Shaders/Normals_FS.shshaderb differ diff --git a/Assets/Shaders/PureCopy_CS.glsl b/Assets/Shaders/PureCopy_CS.glsl index 89da6dd9..6f396199 100644 --- a/Assets/Shaders/PureCopy_CS.glsl +++ b/Assets/Shaders/PureCopy_CS.glsl @@ -46,8 +46,8 @@ layout(local_size_x = 16, local_size_y = 16) in; -layout(set = 4, binding = 0, rgba8) uniform image2D inputImage; -layout(set = 4, binding = 1, rgba8) uniform image2D targetImage; +layout(set = 3, binding = 0, rgba8) uniform image2D inputImage; +layout(set = 3, binding = 1, rgba8) uniform image2D targetImage; void main() diff --git a/Assets/Shaders/PureCopy_CS.shshaderb b/Assets/Shaders/PureCopy_CS.shshaderb index 30a629f5..15821430 100644 Binary files a/Assets/Shaders/PureCopy_CS.shshaderb and b/Assets/Shaders/PureCopy_CS.shshaderb differ diff --git a/Assets/Shaders/SSAOBlur_CS.glsl b/Assets/Shaders/SSAOBlur_CS.glsl index 64066525..4519689d 100644 --- a/Assets/Shaders/SSAOBlur_CS.glsl +++ b/Assets/Shaders/SSAOBlur_CS.glsl @@ -5,8 +5,8 @@ #define SHM_WIDTH BLUR_WIDTH + 16 - 1 layout(local_size_x = 16, local_size_y = 16) in; -layout(set = 4, binding = 0, r8) uniform image2D ssaoImage; -layout(set = 4, binding = 1, r8) uniform image2D ssaoBlurImage; +layout(set = 3, binding = 0, r8) uniform image2D ssaoImage; +layout(set = 3, binding = 1, r8) uniform image2D ssaoBlurImage; float GetSSAOValue(ivec2 uv, ivec2 imageSize) diff --git a/Assets/Shaders/SSAOBlur_CS.shshaderb b/Assets/Shaders/SSAOBlur_CS.shshaderb index e25b57ba..5d40b45f 100644 Binary files a/Assets/Shaders/SSAOBlur_CS.shshaderb and b/Assets/Shaders/SSAOBlur_CS.shshaderb differ diff --git a/Assets/Shaders/SSAO_CS.glsl b/Assets/Shaders/SSAO_CS.glsl index 627c59d1..42ab220c 100644 --- a/Assets/Shaders/SSAO_CS.glsl +++ b/Assets/Shaders/SSAO_CS.glsl @@ -1,5 +1,7 @@ #version 450 +#pragma vscode_glsllint_stage : comp + const uint NUM_SAMPLES = 64; const uint NUM_ROTATIONS = 16; const int ROTATION_KERNEL_W = 4; @@ -10,19 +12,19 @@ const float RADIUS = 0.2f; const float BIAS = 0.0025f; layout(local_size_x = 16, local_size_y = 16) in; -layout(set = 4, binding = 0, rgba32f) uniform image2D positions; -layout(set = 4, binding = 1, rgba32f) uniform image2D normals; -layout(set = 4, binding = 2, rgba32f) uniform image2D outputImage; +layout(set = 3, binding = 0, rgba32f) uniform image2D positions; +layout(set = 3, binding = 1, rgba32f) uniform image2D normals; +layout(set = 3, binding = 2, rgba32f) uniform image2D outputImage; // SSAO data -layout(std430, set = 5, binding = 0) buffer SSAOData +layout(std430, set = 4, binding = 0) buffer SSAOData { vec4 samples[NUM_SAMPLES]; } ssaoData; -layout (set = 5, binding = 1) uniform sampler2D noiseTexture; +layout (set = 4, binding = 1) uniform sampler2D noiseTexture; layout(set = 2, binding = 0) uniform CameraData { diff --git a/Assets/Shaders/SSAO_CS.shshaderb b/Assets/Shaders/SSAO_CS.shshaderb index a9154e10..36e627d6 100644 Binary files a/Assets/Shaders/SSAO_CS.shshaderb and b/Assets/Shaders/SSAO_CS.shshaderb differ diff --git a/Assets/Shaders/TestCube_FS.glsl b/Assets/Shaders/TestCube_FS.glsl index d6f88687..b6a1eab6 100644 --- a/Assets/Shaders/TestCube_FS.glsl +++ b/Assets/Shaders/TestCube_FS.glsl @@ -28,7 +28,7 @@ layout(location = 3) flat in struct } In2; layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global) -layout (std430, set = 3, binding = 0) buffer MaterialProperties // For materials +layout (std430, set = 2, binding = 0) buffer MaterialProperties // For materials { MatPropData data[]; } MatProp; diff --git a/Assets/Shaders/TestCube_FS.shshaderb b/Assets/Shaders/TestCube_FS.shshaderb index bcf5bf5e..abd90cf7 100644 Binary files a/Assets/Shaders/TestCube_FS.shshaderb and b/Assets/Shaders/TestCube_FS.shshaderb differ diff --git a/Assets/Shaders/TestCube_Tile_FS.glsl b/Assets/Shaders/TestCube_Tile_FS.glsl index 84403a7c..c01d9365 100644 --- a/Assets/Shaders/TestCube_Tile_FS.glsl +++ b/Assets/Shaders/TestCube_Tile_FS.glsl @@ -26,7 +26,7 @@ layout(location = 3) flat in struct } In2; layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global) -layout (std430, set = 3, binding = 0) buffer MaterialProperties // For materials +layout (std430, set = 2, binding = 0) buffer MaterialProperties // For materials { MatPropData data[]; } MatProp; diff --git a/Assets/Shaders/TestCube_Tile_FS.shshaderb b/Assets/Shaders/TestCube_Tile_FS.shshaderb index c7444c7d..836a25d4 100644 Binary files a/Assets/Shaders/TestCube_Tile_FS.shshaderb and b/Assets/Shaders/TestCube_Tile_FS.shshaderb differ diff --git a/Assets/Shaders/TestCube_Tile_VS.glsl b/Assets/Shaders/TestCube_Tile_VS.glsl index 31a448fe..d3a1a0de 100644 --- a/Assets/Shaders/TestCube_Tile_VS.glsl +++ b/Assets/Shaders/TestCube_Tile_VS.glsl @@ -34,16 +34,15 @@ layout(location = 3) out struct } Out2; -layout(set = 2, binding = 0) uniform CameraData +layout(set = 1, binding = 0) uniform CameraData { vec4 position; mat4 vpMat; mat4 viewMat; - mat4 perspectiveMat; - mat4 orthoMat; + mat4 projMat; } cameraData; -layout (std430, set = 3, binding = 0) buffer MaterialProperties // For materials +layout (std430, set = 2, binding = 0) buffer MaterialProperties // For materials { MatPropData data[]; } MatProp; diff --git a/Assets/Shaders/TestCube_Tile_VS.shshaderb b/Assets/Shaders/TestCube_Tile_VS.shshaderb index 9f836656..c7749607 100644 Binary files a/Assets/Shaders/TestCube_Tile_VS.shshaderb and b/Assets/Shaders/TestCube_Tile_VS.shshaderb differ diff --git a/Assets/Shaders/TestCube_VS.glsl b/Assets/Shaders/TestCube_VS.glsl index 774bc580..554ce379 100644 --- a/Assets/Shaders/TestCube_VS.glsl +++ b/Assets/Shaders/TestCube_VS.glsl @@ -29,13 +29,12 @@ layout(location = 3) out struct } Out2; -layout(set = 2, binding = 0) uniform CameraData +layout(set = 1, binding = 0) uniform CameraData { vec4 position; mat4 vpMat; mat4 viewMat; - mat4 perspectiveMat; - mat4 orthoMat; + mat4 projMat; } cameraData; void main() diff --git a/Assets/Shaders/TestCube_VS.shshaderb b/Assets/Shaders/TestCube_VS.shshaderb index 28c4655b..a1138f75 100644 Binary files a/Assets/Shaders/TestCube_VS.shshaderb and b/Assets/Shaders/TestCube_VS.shshaderb differ diff --git a/Assets/Shaders/Text_FS.glsl b/Assets/Shaders/Text_FS.glsl index fdf32583..36bdb8eb 100644 --- a/Assets/Shaders/Text_FS.glsl +++ b/Assets/Shaders/Text_FS.glsl @@ -28,7 +28,7 @@ layout(location = 3) flat in struct -layout(set = 4, binding = 0) uniform sampler2D fontBitmap; +layout(set = 2, binding = 0) uniform sampler2D fontBitmap; layout(location = 0) out vec4 color; layout(location = 1) out uint outEntityID; diff --git a/Assets/Shaders/Text_FS.shshaderb b/Assets/Shaders/Text_FS.shshaderb index d9b47d6e..024073a8 100644 Binary files a/Assets/Shaders/Text_FS.shshaderb and b/Assets/Shaders/Text_FS.shshaderb differ diff --git a/Assets/Shaders/Text_VS.glsl b/Assets/Shaders/Text_VS.glsl index 3501a13d..1e05dd25 100644 --- a/Assets/Shaders/Text_VS.glsl +++ b/Assets/Shaders/Text_VS.glsl @@ -25,13 +25,12 @@ layout(location = 3) out struct } Out2; // Camera data -layout(set = 2, binding = 0) uniform CameraData +layout(set = 1, binding = 0) uniform CameraData { vec4 position; mat4 vpMat; mat4 viewMat; - mat4 perspectiveMat; - mat4 orthoMat; + mat4 projMat; } cameraData; // push constants @@ -44,7 +43,7 @@ layout(std140, push_constant) uniform TestPushConstant } testPushConstant; // Descriptor sets -layout(std430, set = 4, binding = 1) buffer GlyphTransforms +layout(std430, set = 2, binding = 1) buffer GlyphTransforms { mat4 matrices[]; } glyphTransforms; @@ -96,6 +95,6 @@ void main() Out2.textColor = testPushConstant.textColor; // transform the vertex position to font space - gl_Position = cameraData.orthoMat * localModel * vec4(vertexPos, 1.0f); + gl_Position = cameraData.projMat * localModel * vec4(vertexPos, 1.0f); // gl_Position = vec4(vertexPos, 1.0f); } \ No newline at end of file diff --git a/Assets/Shaders/Text_VS.shshaderb b/Assets/Shaders/Text_VS.shshaderb index 25eff84a..527b3db7 100644 Binary files a/Assets/Shaders/Text_VS.shshaderb and b/Assets/Shaders/Text_VS.shshaderb differ diff --git a/Assets/Shaders/ToSwapchain_FS.glsl b/Assets/Shaders/ToSwapchain_FS.glsl index a68fa0c7..3cf1752f 100644 --- a/Assets/Shaders/ToSwapchain_FS.glsl +++ b/Assets/Shaders/ToSwapchain_FS.glsl @@ -3,7 +3,7 @@ #extension GL_ARB_shading_language_420pack : enable #extension GL_EXT_nonuniform_qualifier : require -layout (input_attachment_index = 0, set = 4, binding = 0) uniform subpassInput sceneTexture; +layout (input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput sceneTexture; layout(location = 0) out vec4 fragColor; diff --git a/Assets/Shaders/ToSwapchain_FS.shshaderb b/Assets/Shaders/ToSwapchain_FS.shshaderb index b10a9d6c..0bee0ac6 100644 Binary files a/Assets/Shaders/ToSwapchain_FS.shshaderb and b/Assets/Shaders/ToSwapchain_FS.shshaderb differ diff --git a/Assets/Shaders/UI_FS.glsl b/Assets/Shaders/UI_FS.glsl index 093cc9c6..0c4c526c 100644 --- a/Assets/Shaders/UI_FS.glsl +++ b/Assets/Shaders/UI_FS.glsl @@ -28,7 +28,7 @@ layout(location = 3) flat in struct } In2; layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global) -layout (std430, set = 3, binding = 0) buffer MaterialProperties // For materials +layout (std430, set = 2, binding = 0) buffer MaterialProperties // For materials { MatPropData data[]; } MatProp; diff --git a/Assets/Shaders/UI_FS.shshaderb b/Assets/Shaders/UI_FS.shshaderb index fcb72b6e..703040e1 100644 Binary files a/Assets/Shaders/UI_FS.shshaderb and b/Assets/Shaders/UI_FS.shshaderb differ diff --git a/Assets/Shaders/UI_VS.glsl b/Assets/Shaders/UI_VS.glsl index c4393b98..8856ca77 100644 --- a/Assets/Shaders/UI_VS.glsl +++ b/Assets/Shaders/UI_VS.glsl @@ -29,13 +29,12 @@ layout(location = 3) out struct } Out2; -layout(set = 2, binding = 0) uniform CameraData +layout(set = 1, binding = 0) uniform CameraData { vec4 position; mat4 vpMat; mat4 viewMat; - mat4 perspectiveMat; - mat4 orthoMat; + mat4 projMat; } cameraData; void main() @@ -60,7 +59,7 @@ void main() Out.normal.rgb = normalize (Out.normal.rgb); // clip space for rendering - gl_Position = cameraData.orthoMat * worldTransform * vec4 (aVertexPos, 1.0f); + gl_Position = cameraData.projMat * worldTransform * vec4 (aVertexPos, 1.0f); gl_Position.z += 0.1f; // HAX // gl_Position = vec4 (aVertexPos, 1.0f); } \ No newline at end of file diff --git a/Assets/Shaders/UI_VS.shshaderb b/Assets/Shaders/UI_VS.shshaderb index a1f1a8b7..79d39a82 100644 Binary files a/Assets/Shaders/UI_VS.shshaderb and b/Assets/Shaders/UI_VS.shshaderb differ diff --git a/Dependencies.bat b/Dependencies.bat index ba411815..460a1d87 100644 --- a/Dependencies.bat +++ b/Dependencies.bat @@ -20,10 +20,11 @@ echo "M - SDL" echo "N - dotnet" echo "O - tinyddsloader" echo "P - fmod" +echo "Q - vswhere" echo --------------------------------------------------- echo. -choice /C ABCDEFGHIJKLMNOP /T 10 /D A +choice /C ABCDEFGHIJKLMNOPQ /T 10 /D A set _e=%ERRORLEVEL% if %_e%==1 goto VMA @@ -42,6 +43,7 @@ if %_e%==13 goto SDL if %_e%==14 goto dotnet if %_e%==15 goto tinyddsloader if %_e%==16 goto fmod +if %_e%==17 goto vswhere :VMA echo -----------------------VMA---------------------------- @@ -155,6 +157,13 @@ if %_e%==15 (goto :done) else (goto :fmod) echo --------------------fmod------------------------- rmdir "Dependencies/fmod" /S /Q git clone https://github.com/SHADE-DP/FMOD.git "Dependencies/fmod" +if %_e%==16 (goto :done) else (goto :vswhere) + +:vswhere +echo -----------------------vswhere---------------------------- +rmdir "Dependencies/vswhere" /S /Q +mkdir "Dependencies/vswhere" +powershell -Command "& {wget https://github.com/microsoft/vswhere/releases/download/3.1.1/vswhere.exe -OutFile "Dependencies/vswhere/vswhere.exe"}" :done echo DONE! diff --git a/Dependencies.lua b/Dependencies.lua index fe75c3f4..2694fe35 100644 --- a/Dependencies.lua +++ b/Dependencies.lua @@ -16,4 +16,5 @@ IncludeDir["SDL"] = "%{wks.location}\\Dependencies\\SDL" IncludeDir["VULKAN"] = "$(VULKAN_SDK)" IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet" IncludeDir["tinyddsloader"] = "%{wks.location}\\Dependencies\\tinyddsloader" -IncludeDir["fmod"] = "%{wks.location}\\Dependencies\\fmod" \ No newline at end of file +IncludeDir["fmod"] = "%{wks.location}\\Dependencies\\fmod" +IncludeDir["vswhere"] = "%{wks.location}\\Dependencies\\vswhere" \ No newline at end of file diff --git a/SHADE_Engine/premake5.lua b/SHADE_Engine/premake5.lua index 7fb7291d..17ca5be8 100644 --- a/SHADE_Engine/premake5.lua +++ b/SHADE_Engine/premake5.lua @@ -124,7 +124,8 @@ project "SHADE_Engine" "xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Debug\\ModelCompiler.exe\" \"$(OutDir)\"", "xcopy /r /y /q \"%{IncludeDir.FontCompiler}\\bin\\Debug\\FontCompiler.exe\" \"$(OutDir)\"", "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodL.dll\" \"$(OutDir)\"", - "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudioL.dll\" \"$(OutDir)\"" + "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudioL.dll\" \"$(OutDir)\"", + "xcopy /r /y /q \"%{IncludeDir.vswhere}\\vswhere.exe\" \"$(OutDir)\"" } filter "configurations:Release" @@ -134,7 +135,8 @@ project "SHADE_Engine" "xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Release\\ModelCompiler.exe\" \"$(OutDir)\"", "xcopy /r /y /q \"%{IncludeDir.FontCompiler}\\bin\\Release\\FontCompiler.exe\" \"$(OutDir)\"", "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"", - "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\"" + "xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\"", + "xcopy /r /y /q \"%{IncludeDir.vswhere}\\vswhere.exe\" \"$(OutDir)\"" } filter "configurations:Publish" diff --git a/SHADE_Engine/src/Camera/SHCameraComponent.cpp b/SHADE_Engine/src/Camera/SHCameraComponent.cpp index 7fc71db1..8b2f50d9 100644 --- a/SHADE_Engine/src/Camera/SHCameraComponent.cpp +++ b/SHADE_Engine/src/Camera/SHCameraComponent.cpp @@ -226,7 +226,7 @@ namespace SHADE const SHMatrix& SHCameraComponent::GetPerspectiveMatrix() const noexcept { - return orthoProjMatrix; + return perspProjMatrix; } //void SHCameraComponent::SetMainCamera(size_t directorCameraIndex) noexcept diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp index 66b3c962..bd39b38e 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -14,6 +14,8 @@ #include "Editor/DragDrop/SHDragDrop.hpp" #include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h" #include "Editor/EditorWindow/SHEditorWindowManager.h" +#include "Scripting/SHVSUtilities.h" +#include "Scripting/SHScriptEngine.h" namespace SHADE { @@ -249,6 +251,12 @@ namespace SHADE matInspector->OpenMaterial(asset->id); } break; + case AssetType::SCRIPT: + if(auto scriptEngine = SHSystemManager::GetSystem()) + { + scriptEngine->OpenFile(asset->path); + } + break; case AssetType::MAX_COUNT: break; default:; } diff --git a/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp index 9dbb9542..537cfc55 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp @@ -196,10 +196,12 @@ namespace SHADE if (!fragShader) return; + auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); + // Get interface for the shader combination auto interface = fragShader->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface ( - SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + mappings.at(SHPredefinedDescriptorTypes::MATERIALS), SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA ); if (!interface) diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index a08f0f75..31b527f3 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -121,6 +121,11 @@ namespace SHADE auto* scriptEngine = static_cast(SHSystemManager::GetSystem()); scriptEngine->GenerateScriptsCsProjFile(); } + if (ImGui::Selectable("Open Visual Studio Project")) + { + auto* scriptEngine = static_cast(SHSystemManager::GetSystem()); + scriptEngine->OpenSolution(); + } ImGui::BeginDisabled(SHSystemManager::GetSystem()->editorState != SHEditor::State::STOP); if (ImGui::Selectable("Build Scripts - Debug")) { diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 6466533f..93b42418 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -501,10 +501,7 @@ namespace SHADE imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); //auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers(); - auto const& renderers = gfxSystem->GetEditorViewport()->GetRenderers(); - - SHASSERT(!renderers.empty(), "No Renderers available") - auto renderGraph = renderers[SHGraphicsConstants::RenderGraphIndices::EDITOR]->GetRenderGraph(); + auto renderGraph = gfxSystem->GetRenderGraph(); auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass(); if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false) @@ -524,7 +521,7 @@ namespace SHADE ImGui_ImplVulkan_DestroyFontUploadObjects(); - renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle& cmd, uint32_t frameIndex) + renderGraph->GetNode("ImGui Node")->GetSubpass("ImGui Draw")->AddExteriorDrawCalls([](Handle cmd, Handle renderer, uint32_t frameIndex) { cmd->BeginLabeledSegment("ImGui Draw"); ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->GetVkCommandBuffer()); diff --git a/SHADE_Engine/src/Events/SHEventDefines.h b/SHADE_Engine/src/Events/SHEventDefines.h index 2a45da1b..f8e452c1 100644 --- a/SHADE_Engine/src/Events/SHEventDefines.h +++ b/SHADE_Engine/src/Events/SHEventDefines.h @@ -5,23 +5,24 @@ typedef uint32_t SHEventIdentifier; typedef uint32_t SHEventHandle; //Add your event identifiers here: -constexpr SHEventIdentifier SH_EXAMPLE_EVENT { 0 }; -constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT { 1 }; -constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 }; -constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 }; -constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 }; -constexpr SHEventIdentifier SH_SCENE_INIT_PRE { 5 }; -constexpr SHEventIdentifier SH_SCENE_INIT_POST { 6 }; -constexpr SHEventIdentifier SH_SCENE_EXIT_PRE { 7 }; -constexpr SHEventIdentifier SH_SCENE_EXIT_POST { 8 }; -constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 9 }; -constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 10 }; -constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 11 }; -constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 12 }; -constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 13 }; -constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_DRAW_EVENT { 14 }; -constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 15 }; -constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 16 }; -constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 17 }; +constexpr SHEventIdentifier SH_EXAMPLE_EVENT { 0 }; +constexpr SHEventIdentifier SH_ENTITY_DESTROYED_EVENT { 1 }; +constexpr SHEventIdentifier SH_ENTITY_CREATION_EVENT { 2 }; +constexpr SHEventIdentifier SH_COMPONENT_ADDED_EVENT { 3 }; +constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 }; +constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 }; +constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 6 }; +constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 7 }; +constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 8 }; +constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 9 }; +constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 10 }; +constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 11 }; +constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 12 }; +constexpr SHEventIdentifier SH_SCENE_INIT_PRE { 13 }; +constexpr SHEventIdentifier SH_SCENE_INIT_POST { 14 }; +constexpr SHEventIdentifier SH_SCENE_EXIT_PRE { 15 }; +constexpr SHEventIdentifier SH_SCENE_EXIT_POST { 16 }; +constexpr SHEventIdentifier SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT { 17 }; +constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_DRAW_EVENT { 18 }; diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp index 05fd4288..37b89883 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.cpp @@ -367,7 +367,7 @@ namespace SHADE } } - void SHVkCommandBuffer::BindDescriptorSet(Handle descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span dynamicOffsets) + void SHVkCommandBuffer::BindDescriptorSet(Handle descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span const dynamicOffsets) { uint32_t bindPointIndex = static_cast(bindPoint); vkCommandBuffer.bindDescriptorSets(SHVkUtil::GetPipelineBindPointFromType(bindPoint), bindPointData[bindPointIndex].boundPipelineLayoutHdl->GetVkPipelineLayout(), firstSet, descSetGroup->GetVkHandle(), dynamicOffsets); diff --git a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h index fc348487..c6a17d2a 100644 --- a/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h +++ b/SHADE_Engine/src/Graphics/Commands/SHVkCommandBuffer.h @@ -125,7 +125,7 @@ namespace SHADE void BindPipeline (Handle const& pipelineHdl) noexcept; void BindVertexBuffer (uint32_t bindingPoint, Handle const& buffer, vk::DeviceSize offset) noexcept; void BindIndexBuffer (Handle const& buffer, uint32_t startingIndex) const noexcept; - void BindDescriptorSet (Handle descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span dynamicOffsets); + void BindDescriptorSet (Handle descSetGroup, SH_PIPELINE_TYPE bindPoint, uint32_t firstSet, std::span const dynamicOffsets); // Draw Commands void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept; diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp index adb51586..e77234ca 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp @@ -53,7 +53,6 @@ namespace SHADE for (uint32_t i = 0; i < layouts.size(); ++i) { vkLayouts[i] = layouts[i]->GetVkHandle(); - setIndexing.emplace(layouts[i]->GetSetIndex(), i); } // Check for variable descriptor count @@ -87,7 +86,7 @@ namespace SHADE for (auto& binding : bindings) { BindingAndSetHash writeHash = binding.BindPoint; - writeHash |= static_cast(layouts[i]->GetSetIndex()) << 32; + writeHash |= static_cast(i) << 32; // new write for the binding updater.writeInfos.emplace_back(); @@ -208,16 +207,13 @@ namespace SHADE // Get binding + set hash BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding); - // to index a set - uint32_t setIndex = setIndexing[set]; - // to index a write for a binding uint32_t writeInfoIndex = updater.writeHashMap[bsHash]; // Initialize info for write - writeDescSet.descriptorType = layoutsUsed[setIndex]->GetBindings()[binding].Type; + writeDescSet.descriptorType = layoutsUsed[set]->GetBindings()[binding].Type; writeDescSet.dstArrayElement = 0; - writeDescSet.dstSet = descSets[setIndex]; + writeDescSet.dstSet = descSets[set]; writeDescSet.dstBinding = binding; writeDescSet.pImageInfo = updater.writeInfos[writeInfoIndex].descImageInfos.data(); @@ -233,16 +229,13 @@ namespace SHADE // Get binding + set hash BindingAndSetHash bsHash = SHVkUtil::GenBindingSetHash(set, binding); - // to index a set - uint32_t setIndex = setIndexing[set]; - // to index a write for a binding uint32_t writeInfoIndex = updater.writeHashMap[bsHash]; // Initialize info for write - writeDescSet.descriptorType = layoutsUsed[setIndex]->GetBindings()[binding].Type; + writeDescSet.descriptorType = layoutsUsed[set]->GetBindings()[binding].Type; writeDescSet.dstArrayElement = 0; - writeDescSet.dstSet = descSets[setIndex]; + writeDescSet.dstSet = descSets[set]; writeDescSet.dstBinding = binding; writeDescSet.pBufferInfo = updater.writeInfos[writeInfoIndex].descBufferInfos.data(); diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h index 3f42afcc..a228bc66 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.h @@ -21,7 +21,6 @@ namespace SHADE class SHVkImageView; class SHVkBuffer; - /*---------------------------------------------------------------------------------*/ /* Type Definitions */ /*---------------------------------------------------------------------------------*/ @@ -91,10 +90,10 @@ namespace SHADE //! Descriptor pool to allocate descriptor sets Handle descPool; - //! Sometimes when we pass in a layout, the set of the layout used in the - //! shader cannot be used to index into descSets. This is to mitigate that issue - //! when we update descriptor sets. - std::unordered_map setIndexing; + ////! Sometimes when we pass in a layout, the set of the layout used in the + ////! shader cannot be used to index into descSets. This is to mitigate that issue + ////! when we update descriptor sets. + //std::unordered_map setIndexing; //! Descriptor sets std::vector descSets; diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp index 4be8cc9e..9b921411 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp @@ -5,146 +5,138 @@ namespace SHADE { - /*---------------------------------------------------------------------------------*/ - /* Constructor/Destructor */ - /*---------------------------------------------------------------------------------*/ - SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle device, SetIndex set, const std::vector& bindings, bool genImmutableSamplers/* = false*/) - : device { device } - , layoutDesc { bindings } - , setIndex {set} + /*---------------------------------------------------------------------------------*/ + /* Constructor/Destructor */ + /*---------------------------------------------------------------------------------*/ + SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle device, const std::vector& bindings, bool genImmutableSamplers/* = false*/) + : device{ device } + , layoutDesc{ bindings } , immutableSampler{} + { + // Check if auto-binding point calculation configuration is valid + bool autoCalc = false; + for (const auto& binding : bindings) { - // Check if auto-binding point calculation configuration is valid - bool autoCalc = false; - for (const auto& binding : bindings) - { - if (binding.BindPoint == Binding::AUTO_CALC_BINDING) - { - autoCalc = true; - } - else if (autoCalc) - { - throw std::invalid_argument("For auto calculation of bindings, all bindings must be set to AUTO_CALC_BINDING!"); - } - } - - vk::Sampler tempVkSampler = nullptr; - if (genImmutableSamplers) - { - // Create sampler - immutableSampler = device->CreateSampler( - { - .minFilter = vk::Filter::eLinear, - .magFilter = vk::Filter::eLinear, - .addressMode = vk::SamplerAddressMode::eRepeat, - .mipmapMode = vk::SamplerMipmapMode::eLinear, - .minLod = -1000, - .maxLod = 1000 - } - ); - - tempVkSampler = immutableSampler->GetVkSampler(); - } - - - // Fill up VK bindings with auto calculated bind points if needed - std::vector layoutBindings; - layoutBindings.reserve(bindings.size()); - int bindCount = 0; - for (const auto& binding : bindings) - { - const uint32_t CURR_BIND_POINT = autoCalc ? bindCount : binding.BindPoint; - const vk::DescriptorSetLayoutBinding VK_BINDING = - { - .binding = CURR_BIND_POINT, - .descriptorType = binding.Type, - .descriptorCount = binding.DescriptorCount, - .stageFlags = binding.Stage, - .pImmutableSamplers = genImmutableSamplers ? &tempVkSampler : nullptr, - }; - layoutBindings.emplace_back(VK_BINDING); - - // Save for future reference - layoutDesc[bindCount++].BindPoint = CURR_BIND_POINT; - } - - // TODO: Check layout support with physical device - - // Prepare binding flags - std::vector combinedBindings(bindings.size()); - for (uint32_t i = 0; i < bindings.size(); ++i) - combinedBindings[i] = bindings[i].flags; - - const vk::DescriptorSetLayoutBindingFlagsCreateInfo BINDING_FLAGS_CREATE_INFO - { - .bindingCount = static_cast(bindings.size()), // Number of flags = number of bindings - .pBindingFlags = combinedBindings.data(), // address to flags - }; - - // Create the layout - const vk::DescriptorSetLayoutCreateInfo DESC_SET_LAYOUT_CREATE_INFO - { - .pNext = &BINDING_FLAGS_CREATE_INFO, - .flags = {}, - .bindingCount = static_cast(layoutBindings.size()), - .pBindings = layoutBindings.data(), - }; - setLayout = device->GetVkLogicalDevice().createDescriptorSetLayout(DESC_SET_LAYOUT_CREATE_INFO); - } - - SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept - : device {rhs.device} - , setLayout {rhs.setLayout} - , layoutDesc{std::move (rhs.layoutDesc)} - , setIndex{ rhs.setIndex } - , immutableSampler{ rhs.immutableSampler } - { - rhs.setLayout = VK_NULL_HANDLE; - } - - SHVkDescriptorSetLayout::~SHVkDescriptorSetLayout() noexcept - { - // Destroy layout - if (setLayout) - device->GetVkLogicalDevice().destroyDescriptorSetLayout(setLayout); - } - - std::vector const& SHVkDescriptorSetLayout::GetBindings(void) const noexcept - { - return layoutDesc; - } - - SetIndex SHVkDescriptorSetLayout::GetSetIndex(void) const noexcept - { - return setIndex; - } - - uint32_t SHVkDescriptorSetLayout::GetNumDynamicOffsetsRequired(void) const noexcept - { - uint32_t numDynamicBindings = 0; - for (auto& binding : layoutDesc) + if (binding.BindPoint == Binding::AUTO_CALC_BINDING) { - if (binding.Type == vk::DescriptorType::eUniformBufferDynamic || binding.Type == vk::DescriptorType::eStorageBufferDynamic) - ++numDynamicBindings; + autoCalc = true; + } + else if (autoCalc) + { + throw std::invalid_argument("For auto calculation of bindings, all bindings must be set to AUTO_CALC_BINDING!"); } - - return numDynamicBindings; } - SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept + vk::Sampler tempVkSampler = nullptr; + if (genImmutableSamplers) { - if (&rhs == this) - return *this; + // Create sampler + immutableSampler = device->CreateSampler( + { + .minFilter = vk::Filter::eLinear, + .magFilter = vk::Filter::eLinear, + .addressMode = vk::SamplerAddressMode::eRepeat, + .mipmapMode = vk::SamplerMipmapMode::eLinear, + .minLod = -1000, + .maxLod = 1000 + } + ); - device = rhs.device; - setLayout = rhs.setLayout; - layoutDesc = std::move(rhs.layoutDesc); - setIndex = rhs.setIndex; - immutableSampler = rhs.immutableSampler; - - rhs.setLayout = VK_NULL_HANDLE; - - return *this; + tempVkSampler = immutableSampler->GetVkSampler(); } + + // Fill up VK bindings with auto calculated bind points if needed + std::vector layoutBindings; + layoutBindings.reserve(bindings.size()); + int bindCount = 0; + for (const auto& binding : bindings) + { + const uint32_t CURR_BIND_POINT = autoCalc ? bindCount : binding.BindPoint; + const vk::DescriptorSetLayoutBinding VK_BINDING = + { + .binding = CURR_BIND_POINT, + .descriptorType = binding.Type, + .descriptorCount = binding.DescriptorCount, + .stageFlags = binding.Stage, + .pImmutableSamplers = genImmutableSamplers ? &tempVkSampler : nullptr, + }; + layoutBindings.emplace_back(VK_BINDING); + + // Save for future reference + layoutDesc[bindCount++].BindPoint = CURR_BIND_POINT; + } + + // TODO: Check layout support with physical device + + // Prepare binding flags + std::vector combinedBindings(bindings.size()); + for (uint32_t i = 0; i < bindings.size(); ++i) + combinedBindings[i] = bindings[i].flags; + + const vk::DescriptorSetLayoutBindingFlagsCreateInfo BINDING_FLAGS_CREATE_INFO + { + .bindingCount = static_cast(bindings.size()), // Number of flags = number of bindings + .pBindingFlags = combinedBindings.data(), // address to flags + }; + + // Create the layout + const vk::DescriptorSetLayoutCreateInfo DESC_SET_LAYOUT_CREATE_INFO + { + .pNext = &BINDING_FLAGS_CREATE_INFO, + .flags = {}, + .bindingCount = static_cast(layoutBindings.size()), + .pBindings = layoutBindings.data(), + }; + setLayout = device->GetVkLogicalDevice().createDescriptorSetLayout(DESC_SET_LAYOUT_CREATE_INFO); + } + + SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept + : device{ rhs.device } + , setLayout{ rhs.setLayout } + , layoutDesc{ std::move(rhs.layoutDesc) } + , immutableSampler{ rhs.immutableSampler } + { + rhs.setLayout = VK_NULL_HANDLE; + } + + SHVkDescriptorSetLayout::~SHVkDescriptorSetLayout() noexcept + { + // Destroy layout + if (setLayout) + device->GetVkLogicalDevice().destroyDescriptorSetLayout(setLayout); + } + + std::vector const& SHVkDescriptorSetLayout::GetBindings(void) const noexcept + { + return layoutDesc; + } + + uint32_t SHVkDescriptorSetLayout::GetNumDynamicOffsetsRequired(void) const noexcept + { + uint32_t numDynamicBindings = 0; + for (auto& binding : layoutDesc) + { + if (binding.Type == vk::DescriptorType::eUniformBufferDynamic || binding.Type == vk::DescriptorType::eStorageBufferDynamic) + ++numDynamicBindings; + } + + return numDynamicBindings; + } + + SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept + { + if (&rhs == this) + return *this; + + device = rhs.device; + setLayout = rhs.setLayout; + layoutDesc = std::move(rhs.layoutDesc); + immutableSampler = rhs.immutableSampler; + + rhs.setLayout = VK_NULL_HANDLE; + + return *this; + } + } diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h index caa3c057..f0e1fe4e 100644 --- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h +++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h @@ -6,109 +6,107 @@ namespace SHADE { - /*---------------------------------------------------------------------------------*/ - /* Forward Declarations */ - /*---------------------------------------------------------------------------------*/ - class SHVkLogicalDevice; - class SHVkSampler; + /*---------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*---------------------------------------------------------------------------------*/ + class SHVkLogicalDevice; + class SHVkSampler; - /*---------------------------------------------------------------------------------*/ - /* Type Definitions */ - /*---------------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + /// + /// RAII wrapper object for a Vulkan Descriptor Set Layout object. + /// + class SHVkDescriptorSetLayout + { + public: + /*-----------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------*/ /// - /// RAII wrapper object for a Vulkan Descriptor Set Layout object. + /// Object that describes how a descriptor binding in a DescriptorSetLayout is + /// structured. /// - class SHVkDescriptorSetLayout + struct Binding { - public: - /*-----------------------------------------------------------------------------*/ - /* Type Definitions */ - /*-----------------------------------------------------------------------------*/ - /// - /// Object that describes how a descriptor binding in a DescriptorSetLayout is - /// structured. - /// - struct Binding - { - /*-------------------------------------------------------------------------*/ - /* Constants */ - /*-------------------------------------------------------------------------*/ - /// - /// If set for the "BindPoint", binding points are automatically calculated. - /// - static constexpr uint32_t AUTO_CALC_BINDING = std::numeric_limits::max(); + /*-------------------------------------------------------------------------*/ + /* Constants */ + /*-------------------------------------------------------------------------*/ + /// + /// If set for the "BindPoint", binding points are automatically calculated. + /// + static constexpr uint32_t AUTO_CALC_BINDING = std::numeric_limits::max(); - /// - /// For use in Binding DescriptorCount. - /// - static constexpr uint32_t VARIABLE_DESCRIPTOR_UPPER_BOUND = 2000; - /*-------------------------------------------------------------------------*/ - /* Data Members */ - /*-------------------------------------------------------------------------*/ - /// - /// Type of element for the descriptor. - /// - vk::DescriptorType Type = {}; - /// - /// Shader stage that this binding is for. - /// - vk::ShaderStageFlags Stage = {}; - /// - /// Binding point for the Descriptor within the Descriptor Set. - /// - uint32_t BindPoint = AUTO_CALC_BINDING; - /// - /// Number of elements in the binding. When VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT - /// is used in VkDescriptorBindingFlagBits, this value represents the upper bound. - /// - uint32_t DescriptorCount = 1; + /// + /// For use in Binding DescriptorCount. + /// + static constexpr uint32_t VARIABLE_DESCRIPTOR_UPPER_BOUND = 2000; + /*-------------------------------------------------------------------------*/ + /* Data Members */ + /*-------------------------------------------------------------------------*/ + /// + /// Type of element for the descriptor. + /// + vk::DescriptorType Type = {}; + /// + /// Shader stage that this binding is for. + /// + vk::ShaderStageFlags Stage = {}; + /// + /// Binding point for the Descriptor within the Descriptor Set. + /// + uint32_t BindPoint = AUTO_CALC_BINDING; + /// + /// Number of elements in the binding. When VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT + /// is used in VkDescriptorBindingFlagBits, this value represents the upper bound. + /// + uint32_t DescriptorCount = 1; - vk::DescriptorBindingFlags flags = {}; - }; - - /*-----------------------------------------------------------------------------*/ - /* Constructor/Destructors */ - /*-----------------------------------------------------------------------------*/ - SHVkDescriptorSetLayout() = delete; - /// - /// Constructs a DescriptorSetLayout with the specified properties and device. - /// - /// - /// - SHVkDescriptorSetLayout(Handle device, SetIndex setIndex, const std::vector& bindings, bool genImmutableSamplers = false); - SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete; - SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept; - /// - /// Destructor which will unload and deallocate all resources for this Set. - /// - ~SHVkDescriptorSetLayout() noexcept; - - /*-----------------------------------------------------------------------------*/ - /* Overloaded Operators */ - /*-----------------------------------------------------------------------------*/ - SHVkDescriptorSetLayout& operator=(const SHVkDescriptorSetLayout&) = delete; - SHVkDescriptorSetLayout& operator=(SHVkDescriptorSetLayout&& rhs) noexcept; - - /*-----------------------------------------------------------------------------*/ - /* Getter Functions */ - /*-----------------------------------------------------------------------------*/ - /// - /// Retrieves the handle to the Vulkan Descriptor Set Layout handle. - /// - /// Handle to the Vulkan Descriptor Set Layout handle. - inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; } - std::vector const& GetBindings (void) const noexcept; - SetIndex GetSetIndex (void) const noexcept; - uint32_t GetNumDynamicOffsetsRequired (void) const noexcept; - - private: - /*-----------------------------------------------------------------------------*/ - /* Data Members */ - /*-----------------------------------------------------------------------------*/ - Handle device; - vk::DescriptorSetLayout setLayout; - std::vector layoutDesc; // Stores description of the layout - SetIndex setIndex; // Index of the set - Handle immutableSampler; + vk::DescriptorBindingFlags flags = {}; }; + + /*-----------------------------------------------------------------------------*/ + /* Constructor/Destructors */ + /*-----------------------------------------------------------------------------*/ + SHVkDescriptorSetLayout() = delete; + /// + /// Constructs a DescriptorSetLayout with the specified properties and device. + /// + /// + /// + SHVkDescriptorSetLayout(Handle device, const std::vector& bindings, bool genImmutableSamplers = false); + SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete; + SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept; + /// + /// Destructor which will unload and deallocate all resources for this Set. + /// + ~SHVkDescriptorSetLayout() noexcept; + + /*-----------------------------------------------------------------------------*/ + /* Overloaded Operators */ + /*-----------------------------------------------------------------------------*/ + SHVkDescriptorSetLayout& operator=(const SHVkDescriptorSetLayout&) = delete; + SHVkDescriptorSetLayout& operator=(SHVkDescriptorSetLayout&& rhs) noexcept; + + /*-----------------------------------------------------------------------------*/ + /* Getter Functions */ + /*-----------------------------------------------------------------------------*/ + /// + /// Retrieves the handle to the Vulkan Descriptor Set Layout handle. + /// + /// Handle to the Vulkan Descriptor Set Layout handle. + inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; } + std::vector const& GetBindings(void) const noexcept; + uint32_t GetNumDynamicOffsetsRequired(void) const noexcept; + + private: + /*-----------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------*/ + Handle device; + vk::DescriptorSetLayout setLayout; + std::vector layoutDesc; // Stores description of the layout + Handle immutableSampler; + }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp index 95cf2e91..6a6e385f 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp @@ -561,9 +561,9 @@ namespace SHADE } - Handle SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector const& bindings, bool genImmutableSamplers/* = false*/) noexcept + Handle SHVkLogicalDevice::CreateDescriptorSetLayout(std::vector const& bindings, bool genImmutableSamplers/* = false*/) noexcept { - return SHVkInstance::GetResourceManager().Create (GetHandle(), setIndex, bindings, genImmutableSamplers); + return SHVkInstance::GetResourceManager().Create (GetHandle(), bindings, genImmutableSamplers); } Handle SHVkLogicalDevice::CreateDescriptorPools(const SHVkDescriptorPool::Config& config /*= {}*/) noexcept diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h index ed09b482..6e3bb0ce 100644 --- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h +++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h @@ -190,7 +190,7 @@ namespace SHADE Handle CreateRenderpass (std::span const vkDescriptions, std::vector const& subpasses) noexcept; Handle CreateRenderpass (std::span const vkDescriptions, std::span const spDescs, std::span const spDeps) noexcept; Handle CreateFramebuffer (Handle const& renderpassHdl, std::vector> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept; - Handle CreateDescriptorSetLayout (SetIndex setIndex, std::vector const& bindings, bool genImmutableSamplers = false) noexcept; + Handle CreateDescriptorSetLayout (std::vector const& bindings, bool genImmutableSamplers = false) noexcept; Handle CreateDescriptorPools (const SHVkDescriptorPool::Config& config = {}) noexcept; Handle CreateDescriptorSetGroup(Handle pool, std::vector> const& layouts, diff --git a/SHADE_Engine/src/Graphics/Events/SHGraphicsEvents.h b/SHADE_Engine/src/Graphics/Events/SHGraphicsEvents.h new file mode 100644 index 00000000..ab120a1f --- /dev/null +++ b/SHADE_Engine/src/Graphics/Events/SHGraphicsEvents.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include +#include "ECS_Base/SHECSMacros.h" + +namespace SHADE +{ + struct SHLightEnableShadowEvent + { + //! We need to get the light component and initialize the relevant variables. + EntityID lightEntity; + }; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 211c50b7..7e4069f6 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -25,7 +25,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "ECS_Base/Managers/SHComponentManager.h" #include "Math/Transform/SHTransformComponent.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" #include "Graphics/Descriptors/SHVkDescriptorPool.h" #include "Scene/SHSceneManager.h" #include "UI/SHUIComponent.h" @@ -411,11 +411,12 @@ namespace SHADE instancedIntegerData.reserve(numTotalElements); instancedIntegerData.clear(); + auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); // - Material Properties Data const Handle SHADER_INFO = pipeline->GetPipelineLayout()->GetShaderBlockInterface ( - SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + descMappings.at(SHPredefinedDescriptorTypes::MATERIALS), SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, vk::ShaderStageFlagBits::eFragment ); @@ -570,11 +571,14 @@ namespace SHADE cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0); if (matPropsDescSet[frameIndex]) { + auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); + cmdBuffer->BindDescriptorSet ( matPropsDescSet[frameIndex], SH_PIPELINE_TYPE::GRAPHICS, - SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + //SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + descMappings.at(SHPredefinedDescriptorTypes::MATERIALS), dynamicOffset ); } @@ -582,6 +586,31 @@ namespace SHADE cmdBuffer->EndLabeledSegment(); } + /*-----------------------------------------------------------------------------------*/ + /* SHBatch - Getter Functions */ + /*-----------------------------------------------------------------------------------*/ + Handle SHBatch::GetTransformBuffer(uint32_t frameIndex) const noexcept + { + if (frameIndex >= transformDataBuffer.size()) + { + SHLOG_WARNING("[SHBatch] Attempted to retrieve a transform buffer of an invalid index."); + return {}; + } + + return transformDataBuffer[frameIndex]; + } + + Handle SHBatch::GetMDIBuffer(uint32_t frameIndex) const noexcept + { + if (frameIndex >= drawDataBuffer.size()) + { + SHLOG_WARNING("[SHBatch] Attempted to retrieve a MDI draw data buffer of an invalid index."); + return {}; + } + + return drawDataBuffer[frameIndex]; + } + /*---------------------------------------------------------------------------------*/ /* SHBatch - Helper Functions */ /*---------------------------------------------------------------------------------*/ @@ -607,7 +636,7 @@ namespace SHADE { matPropsDescSet[frameIndex] = descPool->Allocate ( - { SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE] }, + SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::MATERIALS), { 0 } ); #ifdef _DEBUG @@ -618,17 +647,20 @@ namespace SHADE } #endif } + + static constexpr uint32_t MATERIAL_DESC_SET_INDEX = 0; + std::array, 1> bufferList = { matPropsBuffer[frameIndex] }; matPropsDescSet[frameIndex]->ModifyWriteDescBuffer ( - SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + MATERIAL_DESC_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, bufferList, 0, static_cast(matPropsDataSize) ); matPropsDescSet[frameIndex]->UpdateDescriptorSetBuffer ( - SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + MATERIAL_DESC_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA ); } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h index dd4d33fd..d4ce068e 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.h @@ -94,6 +94,8 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ Handle GetPipeline() const noexcept { return pipeline; }; bool IsEmpty() const noexcept { return subBatches.empty(); } + Handle GetTransformBuffer(uint32_t frameIndex) const noexcept; + Handle GetMDIBuffer(uint32_t frameIndex) const noexcept; private: /*-----------------------------------------------------------------------------*/ @@ -122,7 +124,7 @@ namespace SHADE std::unique_ptr matPropsData; Byte matPropsDataSize = 0; Byte singleMatPropAlignedSize = 0; - Byte singleMatPropSize = 0; + Byte singleMatPropSize = 0; bool isCPUBuffersDirty = true; // GPU Buffers TripleBuffer drawDataBuffer; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h index 9877e04e..75bd1829 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.h @@ -54,7 +54,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ void Add(const SHRenderable* renderable) noexcept; void Remove(const SHRenderable* renderable) noexcept; - void Clear() noexcept; + void Clear() noexcept; void UpdateBuffers(uint32_t frameIndex, Handle descPool); void Build(Handle device, Handle descPool, uint32_t frameIndex) noexcept; void Draw(Handle cmdBuffer, uint32_t frameIndex) noexcept; @@ -63,6 +63,7 @@ namespace SHADE /* Getter Functions */ /*-----------------------------------------------------------------------------*/ Handle GetSubpass() const noexcept { return subpass; }; + const std::vector& GetBatches() const noexcept { return batches; } private: /*-----------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHDescriptorMappings.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHDescriptorMappings.cpp new file mode 100644 index 00000000..075f0e06 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHDescriptorMappings.cpp @@ -0,0 +1,17 @@ +#include "SHpch.h" +#include "SHDescriptorMappings.h" + +namespace SHADE +{ + void SHDescriptorMappings::AddMappings(std::initializer_list> inMappings) noexcept + { + for (auto& map : inMappings) + mappings.emplace(map); + } + + SHDescriptorMappings::MapType const& SHDescriptorMappings::GetMappings(void) const noexcept + { + return mappings; + } + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHDescriptorMappings.h b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHDescriptorMappings.h new file mode 100644 index 00000000..3e94a87a --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHDescriptorMappings.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include "Graphics/MiddleEnd/GlobalData/SHPredefinedDescriptorTypes.h" + +namespace SHADE +{ + class SHDescriptorMappings + { + public: + using MapType = std::unordered_map; + + private: + //! To map an enum value from descriptor set types to set indices + MapType mappings; + + public: + /*-----------------------------------------------------------------------*/ + /* PUBLIC MEMBER FUNCTIONS */ + /*-----------------------------------------------------------------------*/ + void AddMappings (std::initializer_list> inMappings) noexcept; + + /*-----------------------------------------------------------------------*/ + /* SETTERS AND GETTERS */ + /*-----------------------------------------------------------------------*/ + MapType const& GetMappings (void) const noexcept; + }; + +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.cpp new file mode 100644 index 00000000..fd94968e --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.cpp @@ -0,0 +1,51 @@ +#include "SHpch.h" +#include "SHGlobalDescriptorSets.h" +#include "Graphics/MiddleEnd/Lights/SHLightingSubSystem.h" +#include "Graphics/Commands/SHVkCommandBuffer.h" + +namespace SHADE +{ + + Handle SHGlobalDescriptorSets::staticGlobalDataDescriptorSet; + Handle SHGlobalDescriptorSets::lightingSubSystem; + + //void SHGlobalDescriptorSets::BindLightingData(Handle cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t firstSet) noexcept + //{ + // // Bind descriptor set for light data + // cmdBuffer->BindDescriptorSet(SHGlobalDescriptorSets::GetLightDescriptorSet(), SH_PIPELINE_TYPE::COMPUTE, descMappings[SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::LIGHTS], const std::span{ TEX_DYNAMIC_OFFSET.data(), 1 }); + //} + + void SHGlobalDescriptorSets::BindLightingData(Handle cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex, uint32_t frameIndex) noexcept + { + lightingSubSystem->BindDescSet(cmdBuffer, setIndex, frameIndex); + } + + void SHGlobalDescriptorSets::BindStaticGlobalData(Handle cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex) noexcept + { + // Bind descriptor set for static global data + static std::array TEX_DYNAMIC_OFFSET{ 0 }; + cmdBuffer->BindDescriptorSet(staticGlobalDataDescriptorSet, pipelineType, setIndex, std::span{ TEX_DYNAMIC_OFFSET.data(), 1 }); + } + + /***************************************************************************/ + /*! + + \brief + Sets the Handle to descriptor set for lights. + + \param lightDescSet + The handle to set to. + + */ + /***************************************************************************/ + void SHGlobalDescriptorSets::SetLightingSubSystem(Handle system) noexcept + { + lightingSubSystem = system; + } + + void SHGlobalDescriptorSets::SetStaticGlobalDataDescriptorSet(Handle staticGlobalDescSet) noexcept + { + staticGlobalDataDescriptorSet = staticGlobalDescSet; + } + +} \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h new file mode 100644 index 00000000..2e2dca7d --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h @@ -0,0 +1,36 @@ +#pragma once + +#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" +#include "Resource/SHHandle.h" +#include "Graphics/Pipeline/SHPipelineType.h" + +namespace SHADE +{ + class SHLightingSubSystem; + class SHVkCommandBuffer; + + // This class is mainly for descriptors that are truly global, meaning they only come from 1 place and they are shared between many systems + class SHGlobalDescriptorSets + { + private: + + //! Static global descriptor sets for miscellaneous data and textures + static Handle staticGlobalDataDescriptorSet; + + //! Lighting sub system required to get information to bind descriptor sets for light data + static Handle lightingSubSystem; + + public: + /*-----------------------------------------------------------------------*/ + /* PUBLIC MEMBER FUNCTIONS */ + /*-----------------------------------------------------------------------*/ + static void BindLightingData (Handle cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex, uint32_t frameIndex) noexcept; + static void BindStaticGlobalData (Handle cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex) noexcept; + + /*-----------------------------------------------------------------------*/ + /* SETTERS AND GETTERS */ + /*-----------------------------------------------------------------------*/ + static void SetLightingSubSystem (Handle system) noexcept; + static void SetStaticGlobalDataDescriptorSet (Handle staticGlobalDescSet) noexcept; + }; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp deleted file mode 100644 index 87234a6b..00000000 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.cpp +++ /dev/null @@ -1,143 +0,0 @@ -#include "SHpch.h" -#include "SHGraphicsGlobalData.h" -#include "Graphics/Devices/SHVkLogicalDevice.h" -#include "Graphics/Pipeline/SHPipelineState.h" -#include "Graphics/Pipeline/SHVkPipelineLayout.h" -#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" -#include "Graphics/MiddleEnd/Lights/SHLightData.h" -#include "Tools/Utilities/SHUtilities.h" - -namespace SHADE -{ - /*-----------------------------------------------------------------------------------*/ - /* Static Definitions */ - /*-----------------------------------------------------------------------------------*/ - std::vector> SHGraphicsGlobalData::globalDescSetLayouts; - SHVertexInputState SHGraphicsGlobalData::defaultVertexInputState; - Handle SHGraphicsGlobalData::dummyPipelineLayout; - - void SHGraphicsGlobalData::InitHighFrequencyGlobalData(void) noexcept - { - - } - - /*-----------------------------------------------------------------------------------*/ - /* Function Definitions */ - /*-----------------------------------------------------------------------------------*/ - void SHGraphicsGlobalData::InitDescSetLayouts(Handle logicalDevice) noexcept - { - SHVkDescriptorSetLayout::Binding genericDataBinding - { - .Type = vk::DescriptorType::eUniformBufferDynamic, - .Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute, - .BindPoint = SHGraphicsConstants::DescriptorSetBindings::GENERIC_DATA, - .DescriptorCount = 1, - }; - - SHVkDescriptorSetLayout::Binding texturesBinding - { - .Type = vk::DescriptorType::eCombinedImageSampler, - .Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute, - .BindPoint = SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA, - .DescriptorCount = 2000, // we can have up to 2000 textures for now - .flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount, - }; - - // For global data (generic data and textures) - Handle staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, { genericDataBinding, texturesBinding }); - SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, staticGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Static Globals"); - - - std::vector lightBindings{}; - - // This is the binding we use to count the lights (binding 0) - lightBindings.push_back(SHVkDescriptorSetLayout::Binding - { - .Type = vk::DescriptorType::eUniformBufferDynamic, - .Stage = vk::ShaderStageFlagBits::eCompute, - .BindPoint = 0, - .DescriptorCount = 1, - - }); - - for (uint32_t i = 1; i <= SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES); ++i) - { - lightBindings.push_back (SHVkDescriptorSetLayout::Binding - { - .Type = vk::DescriptorType::eStorageBufferDynamic, - .Stage = vk::ShaderStageFlagBits::eCompute, - .BindPoint = i, - .DescriptorCount = 1, - }); - } - - // For Dynamic global data (lights) - Handle dynamicGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, lightBindings); - SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, dynamicGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Dynamic Globals"); - - // For High frequency global data (camera) - SHVkDescriptorSetLayout::Binding cameraDataBinding - { - .Type = vk::DescriptorType::eUniformBufferDynamic, - .Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eCompute, - .BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, - .DescriptorCount = 1, - }; - Handle cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, { cameraDataBinding }); - SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, cameraDataGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] High Frequency Globals"); - - // For per instance data (transforms, materials, etc.) - SHVkDescriptorSetLayout::Binding materialDataBinding - { - .Type = vk::DescriptorType::eStorageBufferDynamic, - .Stage = vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eVertex, - .BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, - .DescriptorCount = 1, - }; - Handle materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, { materialDataBinding }); - SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, materialDataPerInstanceLayout->GetVkHandle(), "[Descriptor Set Layout] Material Globals"); - - - - globalDescSetLayouts.push_back(staticGlobalLayout); - globalDescSetLayouts.push_back(dynamicGlobalLayout); - globalDescSetLayouts.push_back(cameraDataGlobalLayout); - globalDescSetLayouts.push_back(materialDataPerInstanceLayout); - - - dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{globalDescSetLayouts}); - } - - void SHGraphicsGlobalData::InitDefaultVertexInputState(void) noexcept - { - 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_3D) }); // Normals at binding 2 - 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::UINT32_2D) }); // Instanced integer data at index 8 - } - - void SHGraphicsGlobalData::Init(Handle logicalDevice) noexcept - { - InitDescSetLayouts(logicalDevice); - InitDefaultVertexInputState(); - } - - std::vector> const& SHGraphicsGlobalData::GetDescSetLayouts(void) noexcept - { - return globalDescSetLayouts; - } - - - SHVertexInputState const& SHGraphicsGlobalData::GetDefaultViState(void) noexcept - { - return defaultVertexInputState; - } - - Handle SHGraphicsGlobalData::GetDummyPipelineLayout(void) noexcept - { - return dummyPipelineLayout; - } - -} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h deleted file mode 100644 index 439acba5..00000000 --- a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "SH_API.h" -#include "Graphics/Pipeline/SHPipelineState.h" -#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" - -namespace SHADE -{ - class SHVkLogicalDevice; - class SHVkDescriptorSetLayout; - class SHVkDescriptorSetGroup; - class SHVkPipelineLayout; - - class SH_API SHGraphicsGlobalData - { - private: - //! Global descriptor set layouts. Used to allocate descriptor sets - static std::vector> globalDescSetLayouts; - - //! Default vertex input state (used by everything). - static SHVertexInputState defaultVertexInputState; - - //! Since we want to bind global data but can't do so without a pipeline layout, - //! we create a dummy pipeline layout to use it for binding. - static Handle dummyPipelineLayout; - - static void InitHighFrequencyGlobalData (void) noexcept; - static void InitDescSetLayouts (Handle logicalDevice) noexcept; - static void InitDefaultVertexInputState (void) noexcept; - - public: - /*-----------------------------------------------------------------------*/ - /* Constructors */ - /*-----------------------------------------------------------------------*/ - SHGraphicsGlobalData() = delete; - - /*-----------------------------------------------------------------------*/ - /* PUBLIC MEMBER FUNCTIONS */ - /*-----------------------------------------------------------------------*/ - static void Init (Handle logicalDevice) noexcept; - - /*-----------------------------------------------------------------------*/ - /* SETTERS AND GETTERS */ - /*-----------------------------------------------------------------------*/ - static std::vector> const& GetDescSetLayouts (void) noexcept; - static SHVertexInputState const& GetDefaultViState (void) noexcept; - static Handle GetDummyPipelineLayout (void) noexcept; - }; -} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp new file mode 100644 index 00000000..ffe29b36 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.cpp @@ -0,0 +1,256 @@ +#include "SHpch.h" +#include "SHGraphicsPredefinedData.h" +#include "Graphics/Devices/SHVkLogicalDevice.h" +#include "Graphics/Pipeline/SHPipelineState.h" +#include "Graphics/Pipeline/SHVkPipelineLayout.h" +#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" +#include "Graphics/MiddleEnd/Lights/SHLightData.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Definitions */ + /*-----------------------------------------------------------------------------------*/ + std::vector> SHGraphicsPredefinedData::predefinedLayouts; + SHVertexInputState SHGraphicsPredefinedData::defaultVertexInputState; + std::vector SHGraphicsPredefinedData::perSystemData; + + //SHGraphicsPredefinedData::PerSystem SHGraphicsPredefinedData::batchingSystemData; + //SHGraphicsPredefinedData::PerSystem SHGraphicsPredefinedData::textSystemData; + //SHGraphicsPredefinedData::PerSystem SHGraphicsPredefinedData::renderGraphNodeComputeData; + + void SHGraphicsPredefinedData::InitDescMappings(void) noexcept + { + + perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descMappings.AddMappings + ({ + {SHPredefinedDescriptorTypes::STATIC_DATA, 0}, + {SHPredefinedDescriptorTypes::CAMERA, 1}, + {SHPredefinedDescriptorTypes::MATERIALS, 2}, + }); + + perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].descMappings.AddMappings + ({ + {SHPredefinedDescriptorTypes::STATIC_DATA, 0}, + {SHPredefinedDescriptorTypes::CAMERA, 1}, + {SHPredefinedDescriptorTypes::FONT, 2}, + }); + + perSystemData[SHUtilities::ConvertEnum(SystemType::RENDER_GRAPH_NODE_COMPUTE)].descMappings.AddMappings + ({ + {SHPredefinedDescriptorTypes::STATIC_DATA, 0}, + {SHPredefinedDescriptorTypes::LIGHTS, 1}, + {SHPredefinedDescriptorTypes::CAMERA, 2}, + {SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE, 3}, + {SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE, 4}, + }); + } + + void SHGraphicsPredefinedData::InitDummyPipelineLayouts(Handle logicalDevice) noexcept + { + perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{ perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts }); + perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{ perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].descSetLayouts }); + perSystemData[SHUtilities::ConvertEnum(SystemType::RENDER_GRAPH_NODE_COMPUTE)].dummyPipelineLayout = logicalDevice->CreatePipelineLayoutDummy(SHPipelineLayoutParamsDummy{ perSystemData[SHUtilities::ConvertEnum(SystemType::RENDER_GRAPH_NODE_COMPUTE)].descSetLayouts }); + } + + /*-----------------------------------------------------------------------------------*/ + /* Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + void SHGraphicsPredefinedData::InitDescSetLayouts(Handle logicalDevice) noexcept + { + SHVkDescriptorSetLayout::Binding genericDataBinding + { + .Type = vk::DescriptorType::eUniformBufferDynamic, + .Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute, + .BindPoint = SHGraphicsConstants::DescriptorSetBindings::GENERIC_DATA, + .DescriptorCount = 1, + }; + + SHVkDescriptorSetLayout::Binding texturesBinding + { + .Type = vk::DescriptorType::eCombinedImageSampler, + .Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eCompute, + .BindPoint = SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA, + .DescriptorCount = 2000, // we can have up to 2000 textures for now + .flags = vk::DescriptorBindingFlagBits::eVariableDescriptorCount, + }; + + // For global data (generic data and textures) + Handle staticGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ genericDataBinding, texturesBinding }); + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, staticGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] Static Globals"); + + + std::vector lightBindings{}; + + // This is the binding we use to count the lights (binding 0) + lightBindings.push_back(SHVkDescriptorSetLayout::Binding + { + .Type = vk::DescriptorType::eUniformBufferDynamic, + .Stage = vk::ShaderStageFlagBits::eCompute, + .BindPoint = 0, + .DescriptorCount = 1, + + }); + + for (uint32_t i = 1; i <= SHUtilities::ConvertEnum(SH_LIGHT_TYPE::NUM_TYPES); ++i) + { + lightBindings.push_back (SHVkDescriptorSetLayout::Binding + { + .Type = vk::DescriptorType::eStorageBufferDynamic, + .Stage = vk::ShaderStageFlagBits::eCompute, + .BindPoint = i, + .DescriptorCount = 1, + }); + } + + // For Dynamic global data (lights) + Handle lightDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout(lightBindings); + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, lightDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Dynamic Globals"); + + // For High frequency global data (camera) + SHVkDescriptorSetLayout::Binding cameraDataBinding + { + .Type = vk::DescriptorType::eUniformBufferDynamic, + .Stage = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eCompute, + .BindPoint = SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, + .DescriptorCount = 1, + }; + Handle cameraDataGlobalLayout = logicalDevice->CreateDescriptorSetLayout({ cameraDataBinding }); + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, cameraDataGlobalLayout->GetVkHandle(), "[Descriptor Set Layout] High Frequency Globals"); + + // For per instance data (transforms, materials, etc.) + SHVkDescriptorSetLayout::Binding materialDataBinding + { + .Type = vk::DescriptorType::eStorageBufferDynamic, + .Stage = vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eVertex, + .BindPoint = SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, + .DescriptorCount = 1, + }; + Handle materialDataPerInstanceLayout = logicalDevice->CreateDescriptorSetLayout({ materialDataBinding }); + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, materialDataPerInstanceLayout->GetVkHandle(), "[Descriptor Set Layout] Material Globals"); + + // font bitmap data (texture) + SHVkDescriptorSetLayout::Binding fontBitmapBinding + { + .Type = vk::DescriptorType::eCombinedImageSampler, + .Stage = vk::ShaderStageFlagBits::eFragment, + .BindPoint = SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA, + .DescriptorCount = 1, + }; + + // font data in the form of matrices + SHVkDescriptorSetLayout::Binding fontMatrixBinding + { + .Type = vk::DescriptorType::eStorageBuffer, + .Stage = vk::ShaderStageFlagBits::eVertex, + .BindPoint = SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA, + .DescriptorCount = 1, + }; + + Handle fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ fontBitmapBinding, fontMatrixBinding }); + SET_VK_OBJ_NAME(logicalDevice, vk::ObjectType::eDescriptorSetLayout, fontDataDescSetLayout->GetVkHandle(), "[Descriptor Set Layout] Font Data"); + + + predefinedLayouts.push_back(staticGlobalLayout); + predefinedLayouts.push_back(lightDataDescSetLayout); + predefinedLayouts.push_back(cameraDataGlobalLayout); + predefinedLayouts.push_back(materialDataPerInstanceLayout); + predefinedLayouts.push_back(fontDataDescSetLayout); + + perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descSetLayouts = GetPredefinedDescSetLayouts + ( + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA | + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA | + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::MATERIALS + ); + + perSystemData[SHUtilities::ConvertEnum(SystemType::TEXT_RENDERING)].descSetLayouts = GetPredefinedDescSetLayouts + ( + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA | + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA | + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::FONT + ); + + perSystemData[SHUtilities::ConvertEnum(SystemType::RENDER_GRAPH_NODE_COMPUTE)].descSetLayouts = GetPredefinedDescSetLayouts + ( + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA | + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA | + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::LIGHTS + ); + } + + void SHGraphicsPredefinedData::InitDefaultVertexInputState(void) noexcept + { + 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_3D) }); // Normals at binding 2 + 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::UINT32_2D) }); // Instanced integer data at index 8 + } + + void SHGraphicsPredefinedData::Init(Handle logicalDevice) noexcept + { + perSystemData.resize(SHUtilities::ConvertEnum(SystemType::NUM_TYPES)); + InitDescSetLayouts(logicalDevice); + InitDefaultVertexInputState(); + InitDescMappings(); + InitDummyPipelineLayouts (logicalDevice); + } + + std::vector> SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes types) noexcept + { + std::vector> layoutsFound; + for (uint8_t i = 0; i < numPredefinedDescSetLayoutTypes; ++i) + { + auto result = types & static_cast(static_cast(1) << i); + if (static_cast(result)) + layoutsFound.push_back(predefinedLayouts[i]); + } + + return layoutsFound; + } + + SHVertexInputState const& SHGraphicsPredefinedData::GetDefaultViState(void) noexcept + { + return defaultVertexInputState; + } + + + SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetSystemData(SystemType systemType) noexcept + { + return perSystemData[static_cast(systemType)]; + } + + SHDescriptorMappings::MapType const& SHGraphicsPredefinedData::GetMappings(SystemType systemType) noexcept + { + return perSystemData[static_cast(systemType)].descMappings.GetMappings(); + } + + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes operator|(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept + { + return static_cast(static_cast(lhs) | static_cast(rhs)); + } + + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes operator&(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept + { + return static_cast(static_cast(lhs) & static_cast(rhs)); + + } + + //SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetBatchingSystemData(void) noexcept + //{ + // return batchingSystemData; + //} + + //SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetTextSystemData(void) noexcept + //{ + // return textSystemData; + //} + + //SHGraphicsPredefinedData::PerSystem const& SHGraphicsPredefinedData::GetRenderGraphNodeComputeData(void) noexcept + //{ + // return renderGraphNodeComputeData; + //} + +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h new file mode 100644 index 00000000..11bfc469 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h @@ -0,0 +1,102 @@ +#pragma once + +#include "SH_API.h" +#include "Graphics/Pipeline/SHPipelineState.h" +#include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" +#include "Graphics/MiddleEnd/GlobalData/SHDescriptorMappings.h" +#include "Tools/Utilities/SHUtilities.h" +#include "Tools/SHEnumWrapper.h" +#include + +namespace SHADE +{ + class SHVkLogicalDevice; + class SHVkDescriptorSetLayout; + class SHVkDescriptorSetGroup; + class SHVkPipelineLayout; + + class SH_API SHGraphicsPredefinedData + { + public: + static constexpr uint8_t numPredefinedDescSetLayoutTypes = 64; + + // This enum is mainly to initialize a bit field to retrieve bit fields from SHPRedefinedData + enum class PredefinedDescSetLayoutTypes : uint64_t + { + STATIC_DATA = 0x01, + LIGHTS = 0x02, + CAMERA = 0x04, + MATERIALS = 0x08, + FONT = 0x10, + }; + + enum class SystemType + { + BATCHING = 0, + TEXT_RENDERING, + RENDER_GRAPH_NODE_COMPUTE, + NUM_TYPES + }; + + struct PerSystem + { + //! vector of descriptor set layouts used by a system + std::vector> descSetLayouts; + + //! pipeline layout used for binding descriptor sets in the system + Handle dummyPipelineLayout; + + //! Descriptor type mappings for the system + SHDescriptorMappings descMappings; + }; + + private: + //! Global descriptor set layouts. Used to allocate descriptor sets + static std::vector> predefinedLayouts; + + //! Default vertex input state (used by everything). + static SHVertexInputState defaultVertexInputState; + + //! Predefined data for each type of system + static std::vector perSystemData; + + ////! predefined data for the batching system + //static PerSystem batchingSystemData; + + ////! predefined data for the text system + //static PerSystem textSystemData; + + ////! predefined data for the render graph node computes + //static PerSystem renderGraphNodeComputeData; + + static void InitDescMappings (void) noexcept; + static void InitDummyPipelineLayouts (Handle logicalDevice) noexcept; + static void InitDescSetLayouts (Handle logicalDevice) noexcept; + static void InitDefaultVertexInputState (void) noexcept; + + public: + /*-----------------------------------------------------------------------*/ + /* Constructors */ + /*-----------------------------------------------------------------------*/ + SHGraphicsPredefinedData() = delete; + + /*-----------------------------------------------------------------------*/ + /* PUBLIC MEMBER FUNCTIONS */ + /*-----------------------------------------------------------------------*/ + static void Init (Handle logicalDevice) noexcept; + + /*-----------------------------------------------------------------------*/ + /* SETTERS AND GETTERS */ + /*-----------------------------------------------------------------------*/ + static std::vector> GetPredefinedDescSetLayouts (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes types) noexcept; + static SHVertexInputState const& GetDefaultViState (void) noexcept; + static PerSystem const& GetSystemData (SystemType systemType) noexcept; + static SHDescriptorMappings::MapType const& GetMappings (SystemType systemType) noexcept; + //static PerSystem const& GetBatchingSystemData(void) noexcept; + //static PerSystem const& GetTextSystemData(void) noexcept; + //static PerSystem const& GetRenderGraphNodeComputeData(void) noexcept; + + }; + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes operator| (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept; + SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes operator& (SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes lhs, SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes rhs) noexcept; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHPredefinedDescriptorTypes.h b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHPredefinedDescriptorTypes.h new file mode 100644 index 00000000..931101f4 --- /dev/null +++ b/SHADE_Engine/src/Graphics/MiddleEnd/GlobalData/SHPredefinedDescriptorTypes.h @@ -0,0 +1,19 @@ +#pragma once + +namespace SHADE +{ + // This enum is different from PredefinedDescSetLayoutTypes in that it is used to initialize a hash table to + // with the values here as keys and set indices as values. It is worth noting that some values here + // are not in the above table. This is because those values don't have predefined descriptor set layouts. + // Their layouts and set indices are instead created through introspection in the pipeline layout. + enum class SHPredefinedDescriptorTypes + { + STATIC_DATA, + LIGHTS, + CAMERA, + MATERIALS, + FONT, + RENDER_GRAPH_RESOURCE, + RENDER_GRAPH_NODE_COMPUTE_RESOURCE, + }; +} diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp index d77fbeb0..b57249de 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHDebugDrawSystem.cpp @@ -99,10 +99,10 @@ namespace SHADE createMeshBatches(); // Register function for subpass - auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers(); - auto renderGraph = RENDERERS[SHGraphicsConstants::RenderGraphIndices::WORLD]->GetRenderGraph(); + //auto const& RENDERERS = gfxSystem->GetDefaultViewport()->GetRenderers(); + auto renderGraph = gfxSystem->GetRenderGraph(); auto subPass = renderGraph->GetNode("Debug Draw")->GetSubpass("Debug Draw"); - subPass->AddExteriorDrawCalls([this](Handle& cmdBuffer, uint32_t frameIndex) + subPass->AddExteriorDrawCalls([this](Handle cmdBuffer, Handle renderer, uint32_t frameIndex) { const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex(); cmdBuffer->BeginLabeledSegment("SHDebugDraw (No Depth Test)"); @@ -126,7 +126,7 @@ namespace SHADE cmdBuffer->EndLabeledSegment(); }); auto subPassWithDepth = renderGraph->GetNode("Debug Draw with Depth")->GetSubpass("Debug Draw with Depth"); - subPassWithDepth->AddExteriorDrawCalls([this](Handle& cmdBuffer, uint32_t frameIndex) + subPassWithDepth->AddExteriorDrawCalls([this](Handle cmdBuffer, Handle renderer, uint32_t frameIndex) { const uint32_t FRAME_IDX = gfxSystem->GetCurrentFrameIndex(); cmdBuffer->BeginLabeledSegment("SHDebugDraw (Depth Tested)"); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h index e6051841..c889a321 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h @@ -31,68 +31,68 @@ namespace SHADE static constexpr uint32_t EDITOR = 0; }; - struct DescriptorSetIndex - { - /***************************************************************************/ - /*! - \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; + //struct DescriptorSetIndex + //{ + // /***************************************************************************/ + // /*! + // \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 - To store font data. - - */ - /***************************************************************************/ - static constexpr uint32_t FONT_DATA = 4; - }; + // /***************************************************************************/ + // /*! + // \brief + // To store font data. + // + // */ + // /***************************************************************************/ + // static constexpr uint32_t FONT_DATA = 4; + //}; struct DescriptorSetBindings { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index 9a599a07..b1256921 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -19,7 +19,6 @@ of DigiPen Institute of Technology is prohibited. #include "Camera/SHCameraSystem.h" #include "Editor/SHEditor.h" #include "ECS_Base/Managers/SHSystemManager.h" -//#include "SHRenderer.h" #include "Graphics/Windowing/SHWindow.h" #include "Graphics/MiddleEnd/PerFrame/SHPerFrameData.h" #include "Graphics/MiddleEnd/Interface/SHViewport.h" @@ -31,7 +30,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Batching/SHSuperBatch.h" #include "SHGraphicsConstants.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Images/SHVkSampler.h" #include "Assets/Asset Types/SHTextureAsset.h" @@ -44,6 +43,7 @@ of DigiPen Institute of Technology is prohibited. #include "../Meshes/SHPrimitiveGenerator.h" #include "Graphics/MiddleEnd/TextRendering/SHFreetypeInstance.h" #include "Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h" +#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h" namespace SHADE { @@ -139,7 +139,7 @@ namespace SHADE static constexpr AssetID RENDER_SC_FS = 36869006; renderToSwapchainFS = SHResourceManager::LoadOrGet(RENDER_SC_FS); } - void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept + void SHGraphicsSystem::InitRenderGraph(void) noexcept { /*-----------------------------------------------------------------------*/ /* MIDDLE END SETUP @@ -153,82 +153,82 @@ namespace SHADE auto windowDims = window->GetWindowSize(); auto cameraSystem = SHSystemManager::GetSystem(); - - // Set Up Cameras - screenCamera = resourceManager.Create(); - screenCamera->SetLookAt(SHVec3(0.0f, 0.0f, -1.0f), SHVec3(0.0f, 0.0f, 1.0f), SHVec3(0.0f, 1.0f, 0.0f)); - screenCamera->SetOrthographic(static_cast(windowDims.first), static_cast(windowDims.second), 0.01f, 100.0f); - - worldCamera = resourceManager.Create(); - worldCamera->SetLookAt(SHVec3(0.0f, 0.0f, 0.0f), SHVec3(0.0f, 0.0f, -2.0f), SHVec3(0.0f, 1.0f, 0.0f)); - worldCamera->SetPerspective(90.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 100.0f); - worldCameraDirector = cameraSystem->CreateDirector(); + /*-----------------------------------------------------------------------*/ + /* PREPARE RENDERERS */ + /*-----------------------------------------------------------------------*/ + // Add world renderer to default viewport + worldRenderer = AddRenderer(SHRenderer::PROJECTION_TYPE::PERSPECTIVE); + worldRenderer->SetCameraDirector(worldCameraDirector); + + // Add screen renderer to default viewport + screenRenderer = AddRenderer(SHRenderer::PROJECTION_TYPE::ORTHOGRAPHIC); + screenRenderer->SetCameraDirector(worldCameraDirector); + // Create Default Viewport worldViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast(window->GetWindowSize().first), static_cast(window->GetWindowSize().second), 0.0f, 1.0f)); - // Get render graph from default viewport world renderer - worldRenderGraph = resourceManager.Create(); - std::vector> renderContextCmdPools{ swapchain->GetNumImages() }; for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) { renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0]; } + // Get render graph from default viewport world renderer + renderGraph = resourceManager.Create(); + /*-----------------------------------------------------------------------*/ /* WORLD RENDER GRAPH RESOURCES */ /*-----------------------------------------------------------------------*/ // Initialize world render graph - worldRenderGraph->Init("World Render Graph", device, swapchain, &resourceManager); - worldRenderGraph->AddResource("Position", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); - worldRenderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); + 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("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); //worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); - worldRenderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, windowDims.first, windowDims.second); - worldRenderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); - worldRenderGraph->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); - worldRenderGraph->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); - worldRenderGraph->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); - worldRenderGraph->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); - worldRenderGraph->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("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("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, 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("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("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("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 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("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); /*-----------------------------------------------------------------------*/ /* MAIN NODE */ /*-----------------------------------------------------------------------*/ - auto gBufferNode = worldRenderGraph->AddNode("G-Buffer", + auto gBufferNode = renderGraph->AddNode("G-Buffer", { - "Position", - "Entity ID", + "Position", + "Entity ID", "Light Layer Indices", "Normals", - //"Tangents", "Albedo", - "Depth Buffer", - "Scene", + "Depth Buffer", "SSAO", "SSAO Blur" - }, + }, {}); // no predecessors /*-----------------------------------------------------------------------*/ /* G-BUFFER SUBPASS INIT */ /*-----------------------------------------------------------------------*/ - auto gBufferSubpass = gBufferNode->AddSubpass("G-Buffer Write"); + auto gBufferSubpass = gBufferNode->AddSubpass("G-Buffer Write", worldViewport, worldRenderer); gBufferSubpass->AddColorOutput("Position"); gBufferSubpass->AddColorOutput("Entity ID"); gBufferSubpass->AddColorOutput("Light Layer Indices"); gBufferSubpass->AddColorOutput("Normals"); - //gBufferSubpass->AddColorOutput("Tangents"); gBufferSubpass->AddColorOutput("Albedo"); gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL); + /*-----------------------------------------------------------------------*/ /* SSAO PASS AND DATA INIT */ /*-----------------------------------------------------------------------*/ ssaoStorage = resourceManager.Create(); + // command buffer operation to transfer data for ssao ssaoTransferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); SET_VK_OBJ_NAME(device, vk::ObjectType::eCommandBuffer, ssaoTransferCmdBuffer->GetVkCommandBuffer(), "[Command Buffer] SSAO Pass (Graphics)"); ssaoTransferCmdBuffer->BeginRecording(); @@ -237,95 +237,102 @@ namespace SHADE ssaoTransferCmdBuffer->EndRecording(); graphicsQueue->SubmitCommandBuffer({ ssaoTransferCmdBuffer }); - // Set up Debug Draw Passes - // - Depth Tested - auto debugDrawNodeDepth = worldRenderGraph->AddNode("Debug Draw with Depth", { "Scene", "Depth Buffer" }, {"G-Buffer"}); - auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth"); - debugDrawDepthSubpass->AddColorOutput("Scene"); - debugDrawDepthSubpass->AddDepthOutput("Depth Buffer"); - // - No Depth Test - auto debugDrawNode = worldRenderGraph->AddNode("Debug Draw", { "Scene" }, { "Debug Draw with Depth" }); - auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw"); - debugDrawSubpass->AddColorOutput("Scene"); + // wait for command buffer to finish executing graphicsQueue->WaitIdle(); - ssaoStorage->PrepareRotationVectorsVkData(device); + // Add the pass to generate an image with just SSAO data Handle ssaoPass = gBufferNode->AddNodeCompute("SSAO", ssaoShader, { "Position", "Normals", "SSAO" }); auto ssaoDataBuffer = ssaoStorage->GetBuffer(); - ssaoPass->ModifyWriteDescBufferComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored()); + ssaoPass->ModifyWriteDescBufferComputeResource(SHSSAO::DESC_SET_BUFFER_BINDING, { &ssaoDataBuffer, 1 }, 0, ssaoStorage->GetBuffer()->GetSizeStored()); auto viewSamplerLayout = ssaoStorage->GetViewSamplerLayout(); - ssaoPass->ModifyWriteDescImageComputeResource(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, SHSSAO::DESC_SET_IMAGE_BINDING, {&viewSamplerLayout, 1}); + ssaoPass->ModifyWriteDescImageComputeResource(SHSSAO::DESC_SET_IMAGE_BINDING, { &viewSamplerLayout, 1 }); + ssaoPass->SetRenderer(worldRenderer); + + // Add another pass to blur SSAO + Handle 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", {}, {}); - Handle ssaoBlurPass = gBufferNode->AddNodeCompute("SSAO Blur Step", ssaoBlurShader, {"SSAO", "SSAO Blur"}); + + /*-----------------------------------------------------------------------*/ + /* DEFERRED COMPOSITE NODE */ + /*-----------------------------------------------------------------------*/ + // This pass will facilitate both lighting and shadows in 1 single pass. + auto deferredCompositeNode = renderGraph->AddNode("Deferred Comp Pass", + { + "Position", + "Light Layer Indices", + "Normals", + "Albedo", + "Scene", + "SSAO Blur" + }, + {"G-Buffer"}); /*-----------------------------------------------------------------------*/ /* DEFERRED COMPOSITE SUBPASS INIT */ /*-----------------------------------------------------------------------*/ - gBufferNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, {"Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene"}); - - { - //// Dummy Node to transition scene render graph resource - //auto dummyNode = worldRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Debug Draw" }); // no predecessors - //auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass"); - //dummySubpass->AddInput("Scene"); - } + deferredCompositeNode->AddNodeCompute("Deferred Composite", deferredCompositeShader, { "Position", "Normals", "Albedo", "Light Layer Indices", "SSAO Blur", "Scene" }); /*-----------------------------------------------------------------------*/ - /* GENERATE WORLD RENDER GRAPH */ + /* DEBUG DRAW PASS INIT */ /*-----------------------------------------------------------------------*/ - // Generate world render graph - worldRenderGraph->Generate(); - + // Set up Debug Draw Passes + // - Depth Tested + auto debugDrawNodeDepth = renderGraph->AddNode("Debug Draw with Depth", { "Scene", "Depth Buffer" }, {"G-Buffer", "Deferred Comp Pass"}); + auto debugDrawDepthSubpass = debugDrawNodeDepth->AddSubpass("Debug Draw with Depth", worldViewport, worldRenderer); + debugDrawDepthSubpass->AddColorOutput("Scene"); + debugDrawDepthSubpass->AddDepthOutput("Depth Buffer"); + // - No Depth Test + auto debugDrawNode = renderGraph->AddNode("Debug Draw", { "Scene" }, { "Debug Draw with Depth" }); + auto debugDrawSubpass = debugDrawNode->AddSubpass("Debug Draw", worldViewport, worldRenderer); + debugDrawSubpass->AddColorOutput("Scene"); /*-----------------------------------------------------------------------*/ - /* SCREEN RENDER GRAPH */ + /* SCREEN SPACE PASS */ /*-----------------------------------------------------------------------*/ - // Initialize screen render graph - screenRenderGraph = resourceManager.Create(); - screenRenderGraph->Init("Screen Render Graph", device, swapchain, &resourceManager); - screenRenderGraph->LinkNonOwningResource(worldRenderGraph, "Scene"); - screenRenderGraph->LinkNonOwningResource(worldRenderGraph, "Entity ID"); - screenRenderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); - - auto screenSpaceNode = screenRenderGraph->AddNode("Screen Space Pass", { "Scene", "Entity ID"}, {}); - auto uiSubpass = screenSpaceNode->AddSubpass("UI"); + auto screenSpaceNode = renderGraph->AddNode("Screen Space Pass", { "Scene", "Entity ID" }, {"Deferred Comp Pass", "G-Buffer", "Debug Draw" }); + auto uiSubpass = screenSpaceNode->AddSubpass("UI", worldViewport, screenRenderer); uiSubpass->AddColorOutput("Scene"); uiSubpass->AddColorOutput("Entity ID"); - uiSubpass->AddExteriorDrawCalls([=](Handle& cmdBuffer, uint32_t frameIndex) + uiSubpass->AddExteriorDrawCalls([=](Handle cmdBuffer, Handle renderer, uint32_t frameIndex) { - textRenderingSubSystem->Render(cmdBuffer, frameIndex); + textRenderingSubSystem->Render(cmdBuffer, renderer, frameIndex); }); + /*-----------------------------------------------------------------------*/ + /* RENDER TO SWAPCHAIN IMAGE FOR PRESENT PASS */ + /*-----------------------------------------------------------------------*/ #ifdef SHEDITOR { // Dummy Node to transition scene render graph resource - auto dummyNode = screenRenderGraph->AddNode("Dummy Pass", { "Scene" }, { "Screen Space Pass" }); // no predecessors - auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass"); + auto dummyNode = renderGraph->AddNode("Dummy Pass", { "Scene" }, { "Screen Space Pass" }); + auto dummySubpass = dummyNode->AddSubpass("Dummy Subpass", {}, {}); dummySubpass->AddInput("Scene"); - } + auto imGuiNode = renderGraph->AddNode("ImGui Node", { "Present" }, {}); + auto imGuiSubpass = imGuiNode->AddSubpass("ImGui Draw", {}, {}); + imGuiSubpass->AddColorOutput("Present"); + } #else - screenRenderGraph->AddRenderToSwapchainNode("Scene", "Present", {"Screen Space Pass"}, {renderToSwapchainVS, renderToSwapchainFS}); + renderGraph->AddRenderToSwapchainNode("Scene", "Present", { "Screen Space Pass" }, { renderToSwapchainVS, renderToSwapchainFS }); #endif - screenRenderGraph->Generate(); /*-----------------------------------------------------------------------*/ - /* BIND RENDER GRAPH TO RENDERER */ + /* GENERATE RENDER GRAPH */ /*-----------------------------------------------------------------------*/ - // Add world renderer to default viewport - worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph); - worldRenderer->SetCamera(worldCamera); - worldRenderer->SetCameraDirector(worldCameraDirector); - - // Add screen renderer to default viewport - screenRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], screenRenderGraph); - screenRenderer->SetCamera(screenCamera); - screenRenderer->SetCameraDirector(worldCameraDirector); + // Generate render graph + renderGraph->Generate(); // Create debug draw pipeline debugDrawPipeline = createDebugDrawPipeline(debugDrawNode->GetRenderpass(), debugDrawSubpass, false, false, false); @@ -356,13 +363,10 @@ namespace SHADE void SHGraphicsSystem::InitMiddleEnd(void) noexcept { - SHGraphicsGlobalData::Init(device); + SHGraphicsPredefinedData::Init(device); - InitSceneRenderGraph(); + InitRenderGraph(); -#ifdef SHEDITOR - InitEditorRenderGraph(); -#endif // Create Semaphore for (auto& semaHandle : graphSemaphores) @@ -374,7 +378,7 @@ namespace SHADE void SHGraphicsSystem::InitSubsystems(void) noexcept { - mousePickSystem = resourceManager.Create(); + mousePickSubSystem = resourceManager.Create(); std::vector> cmdPools; cmdPools.reserve(swapchain->GetNumImages()); @@ -382,11 +386,11 @@ namespace SHADE cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]); // Mouse picking system for the editor (Will still run with editor disabled) - mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID")); + mousePickSubSystem->Init(device, cmdPools, renderGraph->GetRenderGraphResource("Entity ID")); // Register the post offscreen render to the system - postOffscreenRender = resourceManager.Create(); - postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool); + postOffscreenRenderSubSystem = resourceManager.Create(); + postOffscreenRenderSubSystem->Init(device, renderGraph->GetRenderGraphResource("Scene"), descPool); lightingSubSystem = resourceManager.Create(); lightingSubSystem->Init(device, descPool); @@ -394,11 +398,10 @@ namespace SHADE textRenderingSubSystem = resourceManager.Create(); // initialize the text renderer - auto uiNode = screenRenderGraph->GetNode("Screen Space Pass"); - textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass("UI"), descPool, textVS, textFS, [=](Handle cmdBuffer, uint32_t frameIndex) - { - screenRenderer->BindDescSet(cmdBuffer, frameIndex); - }); + auto uiNode = renderGraph->GetNode("Screen Space Pass"); + textRenderingSubSystem->Init(device, uiNode->GetRenderpass(), uiNode->GetSubpass("UI"), descPool, textVS, textFS); + + SHGlobalDescriptorSets::SetLightingSubSystem(lightingSubSystem); } @@ -422,42 +425,21 @@ namespace SHADE defaultMaterial = AddMaterial ( defaultVertShader, defaultFragShader, - worldRenderGraph->GetNode("G-Buffer")->GetSubpass("G-Buffer Write") + renderGraph->GetNode("G-Buffer")->GetSubpass("G-Buffer Write") ); defaultMaterial->SetProperty("data.textureIndex", defaultTexture->TextureArrayIndex); } -#ifdef SHEDITOR - void SHGraphicsSystem::InitEditorRenderGraph(void) noexcept + + void SHGraphicsSystem::InitEvents(void) noexcept { - auto windowDims = window->GetWindowSize(); - - // Create Default Viewport - editorViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast(windowDims.first), static_cast(windowDims.second), 0.0f, 1.0f)); - - // Get render graph from viewport editor renderer - editorRenderGraph = resourceManager.Create(); - - std::vector> renderContextCmdPools{ swapchain->GetNumImages() }; - for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) - renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0]; - - editorRenderGraph->Init("Editor Render Graph", device, swapchain, &resourceManager); - editorRenderGraph->AddResource("Present", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second); - - - auto imguiNode = editorRenderGraph->AddNode("ImGui Node", { "Present"}, {}); - auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw"); - imguiSubpass->AddColorOutput("Present"); - - // Generate world render graph - editorRenderGraph->Generate(); - - // Add world renderer to default viewport - editorRenderer = editorViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], editorRenderGraph); - editorRenderer->SetCamera(worldCamera); + std::shared_ptr> thisReceiver + { + std::make_shared>(this, &SHGraphicsSystem::ReceiveLightEnableShadowEvent) + }; + ReceiverPtr receiver = std::dynamic_pointer_cast(thisReceiver); + SHEventManager::SubscribeTo(SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT, receiver); } -#endif /*---------------------------------------------------------------------------------*/ /* Constructor/Destructors */ @@ -544,99 +526,52 @@ namespace SHADE textRenderingSubSystem->Run(frameIndex); - // For every viewport - for (int vpIndex = 0; vpIndex < static_cast(viewports.size()); ++vpIndex) + + for (auto renderer : renderers) { - auto& renderers = viewports[vpIndex]->GetRenderers(); - - // For every renderer - for (int renIndex = 0; renIndex < static_cast(renderers.size()); ++renIndex) - { - /*-----------------------------------------------------------------------*/ - /* Renderer start */ - /*-----------------------------------------------------------------------*/ - // get command buffer of the renderer in the current frame - auto currentCmdBuffer = renderers[renIndex]->GetCommandBuffer(frameIndex); - - // Begin recording the command buffer - currentCmdBuffer->BeginRecording(); - - // set viewport and scissor - uint32_t w = static_cast(viewports[vpIndex]->GetWidth()); - uint32_t h = static_cast(viewports[vpIndex]->GetHeight()); - currentCmdBuffer->SetViewportScissor (static_cast(w), static_cast(h), w, h); - - // Force set the pipeline layout - currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout(), SH_PIPELINE_TYPE::GRAPHICS); - currentCmdBuffer->ForceSetPipelineLayout(SHGraphicsGlobalData::GetDummyPipelineLayout(), SH_PIPELINE_TYPE::COMPUTE); - - // Bind all the buffers required for meshes - for (auto& [buffer, bindingPoint] : MESH_DATA) - { - if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eVertexBuffer) - currentCmdBuffer->BindVertexBuffer(bindingPoint, buffer, 0); - else if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eIndexBuffer) - currentCmdBuffer->BindIndexBuffer(buffer, 0); - } - - lightingSubSystem->BindDescSet(currentCmdBuffer, frameIndex); - - // Bind textures - auto textureDescSet = texLibrary.GetTextureDescriptorSetGroup(); - if (textureDescSet) - { - std::array texDynamicOffset {0}; - currentCmdBuffer->BindDescriptorSet - ( - textureDescSet, - SH_PIPELINE_TYPE::GRAPHICS, - 0, - texDynamicOffset - ); - } - - // bind camera data - //renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); - #ifdef SHEDITOR - if (renderers[renIndex] == worldRenderer) - { - auto editorSystem = SHSystemManager::GetSystem(); - if (editorSystem->editorState != SHEditor::State::PLAY) - worldRenderer->UpdateDataAndBind(currentCmdBuffer, frameIndex, cameraSystem->GetEditorCamera()->GetViewMatrix(), cameraSystem->GetEditorCamera()->GetProjMatrix(), cameraSystem->GetEditorCamera()->GetOrthoMatrix()); - else - renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); - } + if (renderer == worldRenderer) + { + auto editorSystem = SHSystemManager::GetSystem(); + if (editorSystem->editorState != SHEditor::State::PLAY) + worldRenderer->UpdateDataManual(frameIndex, cameraSystem->GetEditorCamera()->GetViewMatrix(), cameraSystem->GetEditorCamera()->GetProjMatrix()); else - renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); -#else - renderers[renIndex]->UpdateDataAndBind(currentCmdBuffer, frameIndex); -#endif - - // Draw the scene - renderers[renIndex]->Draw(frameIndex, descPool); - - // End the command buffer recording - currentCmdBuffer->EndRecording(); - /*-----------------------------------------------------------------------*/ - /* Renderer end */ - /*-----------------------------------------------------------------------*/ - - // submit a command buffer from the current render graph and make it wait for the previous render graph before submitting it to GPU. - graphicsQueue->SubmitCommandBuffer - ( - { currentCmdBuffer }, - { (vpIndex == viewports.size() - 1 && renIndex == renderers.size() - 1) ? frameData.semRenderFinishHdl : graphSemaphores[!semIndex] }, - { (vpIndex == 0 && renIndex == 0) ? frameData.semImgAvailableHdl : graphSemaphores[semIndex] }, - { vk::PipelineStageFlagBits::eColorAttachmentOutput }, - { (vpIndex == viewports.size() - 1 && renIndex == renderers.size() - 1) ? frameData.fenceHdl : Handle{} } - ); - - semIndex = !semIndex; + renderer->UpdateData(frameIndex); } + else + renderer->UpdateData(frameIndex); +#else + renderers[renIndex]->UpdateDataAndBind(frameIndex); +#endif } + + renderGraph->Begin(frameIndex); + auto cmdBuffer = renderGraph->GetCommandBuffer(frameIndex); + + // Bind all the buffers required for meshes + for (auto& [buffer, bindingPoint] : MESH_DATA) + { + if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eVertexBuffer) + cmdBuffer->BindVertexBuffer(bindingPoint, buffer, 0); + else if (buffer->GetUsageBits() & vk::BufferUsageFlagBits::eIndexBuffer) + cmdBuffer->BindIndexBuffer(buffer, 0); + } + + renderGraph->Execute(frameIndex, descPool); + renderGraph->End(frameIndex); + + graphicsQueue->SubmitCommandBuffer + ( + { renderGraph->GetCommandBuffer(frameIndex) }, + { frameData.semRenderFinishHdl }, + { frameData.semImgAvailableHdl }, + { vk::PipelineStageFlagBits::eColorAttachmentOutput }, + { frameData.fenceHdl } + ); + } + /***************************************************************************/ /*! @@ -674,12 +609,8 @@ namespace SHADE // #BackEndTest: For for the fence initialized by queue submit renderContext.WaitForFence(); - // Finalise all batches - for (auto vp : viewports) - for (auto renderer : vp->GetRenderers()) - { - renderer->GetRenderGraph()->FinaliseBatch(renderContext.GetCurrentFrame(), descPool); - } + // finalize batches for render graph + renderGraph->FinaliseBatch(renderContext.GetCurrentFrame(), descPool); // #BackEndTest: Acquire the next image in the swapchain available renderContext.AcquireNextIamge(); @@ -720,7 +651,7 @@ namespace SHADE const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame(); auto& currFrameData = renderContext.GetCurrentFrameData(); - mousePickSystem->Run(graphicsQueue, CURR_FRAME_IDX); + mousePickSubSystem->Run(graphicsQueue, CURR_FRAME_IDX); // #BackEndTest: queues an image for presentation if (auto result = graphicsQueue->Present(swapchain, { currFrameData.semRenderFinishHdl }, CURR_FRAME_IDX); result != vk::Result::eSuccess) @@ -760,6 +691,52 @@ namespace SHADE viewports.erase(iter); } + /*---------------------------------------------------------------------------------*/ + /* Renderer Registration Functions */ + /*---------------------------------------------------------------------------------*/ + Handle SHGraphicsSystem::AddRenderer(SHRenderer::PROJECTION_TYPE projectionType) + { + std::vector> renderContextCmdPools{ swapchain->GetNumImages() }; + for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i) + { + renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0]; + } + + // Create the renderer + auto renderer = resourceManager.Create(device, swapchain->GetNumImages(), descPool, projectionType); + + // Store + renderers.emplace_back(renderer); + + // Return + return renderer; + } + void SHGraphicsSystem::RemoveRenderer(Handle renderer) + { + auto iter = std::find(renderers.begin(), renderers.end(), renderer); + if (iter == renderers.end()) + { + SHLOG_WARNING("Attempted to remove a Renderer that does not belong to a viewport!"); + return; + } + + // Remove it + iter->Free(); + renderers.erase(iter); + } + + SHEventHandle SHGraphicsSystem::ReceiveLightEnableShadowEvent(SHEventPtr event) noexcept + { + // Add the shadow map resource to the graph + + // link resource to node. This means linking the resource and regenerating the node's renderpass and framebuffer. + + // Add a subpass to render to that shadow map + + //renderGraph->GetNode (); + return event->handle; + } + Handle SHGraphicsSystem::AddMaterial(Handle vertShader, Handle fragShader, Handle subpass) { // Retrieve pipeline from pipeline storage or create if unavailable @@ -883,6 +860,8 @@ namespace SHADE ); device->WaitIdle(); graphicsTexCmdBuffer.Free(); graphicsTexCmdBuffer = {}; + SHGlobalDescriptorSets::SetStaticGlobalDataDescriptorSet(texLibrary.GetTextureDescriptorSetGroup()); + } Handle SHGraphicsSystem::GetTextureHandle(SHTexture::Index textureId) const @@ -900,7 +879,7 @@ namespace SHADE void SHGraphicsSystem::BuildFonts(void) noexcept { - fontLibrary.BuildFonts(device, graphicsQueue, graphicsCmdPool, descPool, textRenderingSubSystem->GetFontDataDescSetLayout(), resourceManager); + fontLibrary.BuildFonts(device, graphicsQueue, graphicsCmdPool, descPool, SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::FONT)[0], resourceManager); } #pragma endregion ADD_REMOVE @@ -1044,6 +1023,10 @@ namespace SHADE graphSemaphores[0].Free(); graphSemaphores[1].Free(); + for (auto& semaHandle : graphSemaphores) + semaHandle = device->CreateSemaphore(); + + auto windowDims = window->GetWindowSize(); // Resize the swapchain @@ -1051,23 +1034,21 @@ namespace SHADE renderContext.HandleResize(); - worldRenderGraph->HandleResize(resizeWidth, resizeHeight); + renderGraph->HandleResize(resizeWidth, resizeHeight); #ifdef SHEDITOR - editorRenderGraph->HandleResize(windowDims.first, windowDims.second); + // NOTE: These 2 lines are actually not necessary because the editor viewport is not even used for + // setting dynamic viewport or scissor state. ImGUI takes care of that for us. + //editorViewport->SetWidth(windowDims.first); + //editorViewport->SetHeight(windowDims.second); #endif - screenRenderGraph->HandleResize(resizeWidth, resizeHeight); - - mousePickSystem->HandleResize(); - postOffscreenRender->HandleResize(); + mousePickSubSystem->HandleResize(); + postOffscreenRenderSubSystem->HandleResize(); worldViewport->SetWidth(static_cast(resizeWidth)); worldViewport->SetHeight(static_cast(resizeHeight)); - //worldCamera->SetPerspective(90.0f, static_cast(resizeWidth), static_cast(resizeHeight), 0.0f, 100.0f); - //screenCamera->SetOrthographic(static_cast(resizeWidth), static_cast(resizeHeight), 0.01f, 100.0f); - auto cameraSystem = SHSystemManager::GetSystem(); #ifdef SHEDITOR cameraSystem->GetEditorCamera()->SetWidth(static_cast(resizeWidth)); @@ -1076,8 +1057,6 @@ namespace SHADE #endif - for (auto& semaHandle : graphSemaphores) - semaHandle = device->CreateSemaphore(); } void SHGraphicsSystem::AwaitGraphicsExecution() @@ -1091,9 +1070,14 @@ namespace SHADE } + Handle SHGraphicsSystem::GetRenderGraph(void) const noexcept + { + return renderGraph; + } + Handle SHGraphicsSystem::GetPrimaryRenderpass() const noexcept { - return worldRenderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data()); + return renderGraph->GetNode(G_BUFFER_RENDER_GRAPH_NODE_NAME.data()); } Handle SHGraphicsSystem::GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept @@ -1126,7 +1110,7 @@ namespace SHADE device, SHPipelineLayoutParams { .shaderModules = { (instanced ? debugMeshVertShader : debugVertShader) , debugFragShader }, - .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() + .predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts } ); auto pipeline = resourceManager.Create(device, pipelineLayout, nullptr, renderPass, subpass); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h index 75b48c9b..40148e05 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h @@ -34,6 +34,8 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/MiddleEnd/PostProcessing/SHSSAO.h" #include "Camera/SHCameraDirector.h" #include "Graphics/MiddleEnd/TextRendering/SHFontLibrary.h" +#include "Graphics/MiddleEnd/Interface/SHRenderer.h" +#include "Graphics/Events/SHGraphicsEvents.h" namespace SHADE { @@ -49,9 +51,7 @@ namespace SHADE class SHVkImage; class SHVkFramebuffer; class SHVkCommandBuffer; - class SHRenderer; class SHViewport; - class SHCamera; class SHVkShaderModule; class SHMaterial; class SHMaterialInstance; @@ -99,14 +99,11 @@ namespace SHADE { private: void InitBoilerplate (void) noexcept; - void InitSceneRenderGraph (void) noexcept; + void InitRenderGraph (void) noexcept; void InitMiddleEnd (void) noexcept; void InitSubsystems (void) noexcept; void InitBuiltInResources (void); - -#ifdef SHEDITOR - void InitEditorRenderGraph (void) noexcept; -#endif + void InitEvents (void) noexcept; public: class SH_API BeginRoutine final : public SHSystemRoutine @@ -171,6 +168,17 @@ namespace SHADE Handle AddViewport(const vk::Viewport& viewport); void RemoveViewport(Handle viewport); + /*-----------------------------------------------------------------------------*/ + /* Renderers Registration Functions */ + /*-----------------------------------------------------------------------------*/ + Handle AddRenderer(SHRenderer::PROJECTION_TYPE projectionType); + void RemoveRenderer(Handle renderer); + + /*-----------------------------------------------------------------------*/ + /* Light functions */ + /*-----------------------------------------------------------------------*/ + SHEventHandle ReceiveLightEnableShadowEvent (SHEventPtr event) noexcept; + /*-----------------------------------------------------------------------------*/ /* Material Functions */ /*-----------------------------------------------------------------------------*/ @@ -382,8 +390,9 @@ namespace SHADE #ifdef SHEDITOR Handle GetEditorViewport () const {return editorViewport;}; #endif - Handle GetMousePickSystem(void) const noexcept {return mousePickSystem;}; - Handle GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;}; + Handle GetMousePickSystem(void) const noexcept {return mousePickSubSystem;}; + Handle GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRenderSubSystem;}; + Handle GetRenderGraph (void) const noexcept; Handle GetPrimaryRenderpass() const noexcept; Handle GetDebugDrawPipeline(DebugDrawPipelineType type) const noexcept; uint32_t GetCurrentFrameIndex(void) const noexcept { return renderContext.GetCurrentFrame(); } @@ -441,10 +450,8 @@ namespace SHADE // Renderers Handle worldRenderer; Handle screenRenderer; + std::vector> renderers; - // Temp Cameras - Handle worldCamera; - Handle screenCamera; DirectorHandle worldCameraDirector; @@ -483,15 +490,15 @@ namespace SHADE std::array, MAX_PRIMITIVE_TYPES> primitiveMeshes; // Render Graphs - Handle worldRenderGraph; - Handle screenRenderGraph; + Handle renderGraph; + //Handle screenRenderGraph; #ifdef SHEDITOR - Handle editorRenderGraph; + //Handle editorRenderGraph; #endif // Sub systems - Handle mousePickSystem; - Handle postOffscreenRender; + Handle mousePickSubSystem; + Handle postOffscreenRenderSubSystem; Handle lightingSubSystem; Handle textRenderingSubSystem; Handle ssaoStorage; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp index 1a007b95..3e944a5f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp @@ -9,6 +9,8 @@ #include "ECS_Base/Managers/SHSystemManager.h" #include "SHGraphicsSystem.h" #include "SHMaterialInstance.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" + namespace SHADE { @@ -95,9 +97,11 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ Handle SHMaterial::GetShaderBlockInterface() const noexcept { + auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); return pipeline->GetPipelineLayout()->GetShaderBlockInterface ( - SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + mappings.at (SHPredefinedDescriptorTypes::MATERIALS), + //SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, vk::ShaderStageFlagBits::eFragment ); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp index 7526538f..1506cf71 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp @@ -16,6 +16,7 @@ of DigiPen Institute of Technology is prohibited. #include "SHMaterial.h" #include "Graphics/Pipeline/SHVkPipeline.h" #include "Tools/Logger/SHLogger.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" namespace SHADE { @@ -78,11 +79,12 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ Handle SHMaterialInstance::getShaderBlockInterface() const noexcept { - return baseMaterial->GetPipeline()->GetPipelineLayout()->GetShaderBlockInterface - ( - SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, - SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, - vk::ShaderStageFlagBits::eFragment - ); + return baseMaterial->GetPipeline()->GetPipelineLayout()->GetShaderBlockInterface + ( + SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING).at(SHPredefinedDescriptorTypes::MATERIALS), + //SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, + SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, + vk::ShaderStageFlagBits::eFragment + ); } } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp index 8b41a979..dd3b4366 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp @@ -56,7 +56,7 @@ namespace SHADE }; // Create descriptor set layout - offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }, false); + offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout({ imageBinding }, false); // Create descriptor set offscreenRenderDescSet = descriptorPool->Allocate({ offscreenRenderDescSetLayout }, { 1 }); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp index e47055df..f1d4dc7f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp @@ -14,7 +14,6 @@ of DigiPen Institute of Technology is prohibited. #include "SHRenderer.h" #include "Graphics/Devices/SHVkLogicalDevice.h" -#include "SHViewport.h" #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Framebuffer/SHVkFramebuffer.h" #include "SHMaterial.h" @@ -22,22 +21,22 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Buffers/SHVkBuffer.h" #include "Camera/SHCameraDirector.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" namespace SHADE { /*-----------------------------------------------------------------------------------*/ /* Constructor/Destructors */ /*-----------------------------------------------------------------------------------*/ - SHRenderer::SHRenderer(Handle logicalDevice, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle viewport, Handle renderGraph) - : viewport { viewport } - , renderGraph { renderGraph } + SHRenderer::SHRenderer(Handle logicalDevice, uint32_t numFrames, Handle descriptorPool, PROJECTION_TYPE type) + : projectionType{type} { - commandBuffers.resize(static_cast(numFrames)); + //commandBuffers.resize(static_cast(numFrames)); - for (uint32_t i = 0; i < commandBuffers.size(); ++i) - commandBuffers[i] = cmdPools[i]->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); + //for (uint32_t i = 0; i < commandBuffers.size(); ++i) + // commandBuffers[i] = cmdPools[i]->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); - cameraDescriptorSet = descriptorPool->Allocate({ cameraDescLayout }, { 1 }); + cameraDescriptorSet = descriptorPool->Allocate(SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::CAMERA), { 1 }); #ifdef _DEBUG const auto& CAM_DESC_SETS = cameraDescriptorSet->GetVkHandle(); @@ -51,25 +50,16 @@ namespace SHADE std::array cameraBufferArray{cameraBuffer}; - cameraDescriptorSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, std::span>{ cameraBufferArray.data(), cameraBufferArray.size()}, 0, sizeof (SHShaderCameraData)); + // We use index 0 because the descriptor set is standalone created from a single desc set layout. What the driver sees is that this set is at index 0 during updating. + static constexpr uint8_t SET_0 = 0; - cameraDescriptorSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA); + cameraDescriptorSet->ModifyWriteDescBuffer(SET_0, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA, std::span>{ cameraBufferArray.data(), cameraBufferArray.size()}, 0, sizeof (SHShaderCameraData)); + + cameraDescriptorSet->UpdateDescriptorSetBuffer(SET_0, SHGraphicsConstants::DescriptorSetBindings::CAMERA_DATA); } SHRenderer::~SHRenderer(void) { - //for (auto& cmdBuffer : commandBuffers) - //{ - // cmdBuffer.Free(); - //} - } - - /*-----------------------------------------------------------------------------------*/ - /* Camera Registration */ - /*-----------------------------------------------------------------------------------*/ - void SHRenderer::SetCamera(Handle _camera) - { - camera = _camera; } void SHRenderer::SetCameraDirector(Handle director) noexcept @@ -77,63 +67,55 @@ namespace SHADE cameraDirector = director; } - /*-----------------------------------------------------------------------------------*/ - /* Drawing Functions */ - /*-----------------------------------------------------------------------------------*/ - void SHRenderer::Draw(uint32_t frameIndex, Handle descPool) noexcept + void SHRenderer::UpdateData(uint32_t frameIndex) noexcept { - renderGraph->Execute(frameIndex, commandBuffers[frameIndex], descPool); - } - - void SHRenderer::UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex) noexcept - { - if (camera && cameraDirector) + if (cameraDirector) { - //UpdateDataAndBind(cmdBuffer, frameIndex, SHMatrix::Transpose(cameraDirector->GetVPMatrix())); - UpdateDataAndBind(cmdBuffer, frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetProjMatrix(), cameraDirector->GetOrthoMatrix()); + switch (projectionType) + { + case PROJECTION_TYPE::DEFAULT: + UpdateDataManual(frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetProjMatrix()); + break; + case PROJECTION_TYPE::PERSPECTIVE: + UpdateDataManual(frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetPerspectiveMatrix()); + break; + case PROJECTION_TYPE::ORTHOGRAPHIC: + UpdateDataManual(frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetOrthoMatrix()); + break; + default: + UpdateDataManual(frameIndex, cameraDirector->GetViewMatrix(), cameraDirector->GetProjMatrix()); + break; + } } } - void SHRenderer::UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept + void SHRenderer::UpdateDataManual(uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept { - SetViewProjectionMatrix(viewMatrix, projMatrix, orthoMatrix); + SetViewProjectionMatrix(viewMatrix, projMatrix); - //cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix(); cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex); - BindDescSet(cmdBuffer, frameIndex); + //BindDescSet(cmdBuffer, frameIndex); } - void SHRenderer::BindDescSet(Handle cmdBuffer, uint32_t frameIndex) noexcept + void SHRenderer::BindDescriptorSet(Handle cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex, uint32_t frameIndex) noexcept { std::array dynamicOffsets{ frameIndex * cameraDataAlignedSize }; - cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); - cmdBuffer->BindDescriptorSet(cameraDescriptorSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 }); + cmdBuffer->BindDescriptorSet(cameraDescriptorSet, pipelineType, setIndex, std::span{ dynamicOffsets.data(), 1 }); } - void SHRenderer::UpdateCameraDataToBuffer(void) noexcept + void SHRenderer::SetViewProjectionMatrix(SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept { - } - - void SHRenderer::SetViewProjectionMatrix(SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept - { - //cpuCameraData.viewProjectionMatrix = camera->GetViewMatrix() * camera->GetProjectionMatrix(); cpuCameraData.viewProjectionMatrix = SHMatrix::Transpose(projMatrix * viewMatrix); cpuCameraData.viewMatrix = SHMatrix::Transpose(viewMatrix); cpuCameraData.projectionMatrix = SHMatrix::Transpose(projMatrix); - cpuCameraData.orthoMatrix = SHMatrix::Transpose (orthoMatrix); } - Handle SHRenderer::GetRenderGraph(void) const noexcept - { - return renderGraph; - } - - Handle SHRenderer::GetCommandBuffer(uint32_t frameIndex) const noexcept - { - return commandBuffers[frameIndex]; - } + //Handle SHRenderer::GetCommandBuffer(uint32_t frameIndex) const noexcept + //{ + // return commandBuffers[frameIndex]; + //} Handle SHRenderer::GetCameraDirector(void) const noexcept { diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h index 83291700..baf76187 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.h @@ -32,12 +32,11 @@ namespace SHADE class SHVkFramebuffer; class SHMaterial; class SHVkLogicalDevice; - class SHViewport; class SHVkImageView; class SHVkCommandBuffer; class SHCamera; class SHVkDescriptorSetGroup; - class SHGraphicsGlobalData; + class SHGraphicsPredefinedData; class SHVkDescriptorPool; class SHVkBuffer; class SHCameraDirector; @@ -48,7 +47,6 @@ namespace SHADE SHMatrix viewProjectionMatrix; SHMatrix viewMatrix; SHMatrix projectionMatrix; - SHMatrix orthoMatrix; }; /*---------------------------------------------------------------------------------*/ @@ -64,35 +62,36 @@ namespace SHADE /***********************************************************************************/ class SHRenderer { - public: + enum class PROJECTION_TYPE + { + DEFAULT, + PERSPECTIVE, + ORTHOGRAPHIC + }; + /*-----------------------------------------------------------------------------*/ /* Constructor/Destructors */ /*-----------------------------------------------------------------------------*/ - SHRenderer(Handle logicalDevice, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle viewport, Handle renderGraph); + SHRenderer(Handle logicalDevice, uint32_t numFrames, Handle descriptorPool, PROJECTION_TYPE type); ~SHRenderer(void); /*-----------------------------------------------------------------------------*/ /* Camera Registration */ /*-----------------------------------------------------------------------------*/ - void SetCamera(Handle _camera); void SetCameraDirector (Handle director) noexcept; /*-----------------------------------------------------------------------------*/ /* Drawing Functions */ /*-----------------------------------------------------------------------------*/ - void Draw(uint32_t frameIndex, Handle descPool) noexcept; - void UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex) noexcept; - void UpdateDataAndBind(Handle cmdBuffer, uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept; - void BindDescSet (Handle cmdBuffer, uint32_t frameIndex) noexcept; - void UpdateCameraDataToBuffer (void) noexcept; - void SetViewProjectionMatrix (SHMatrix const& viewMatrix, SHMatrix const& projMatrix, SHMatrix const& orthoMatrix) noexcept; + void UpdateData(uint32_t frameIndex) noexcept; + void UpdateDataManual(uint32_t frameIndex, SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept; + void BindDescriptorSet (Handle cmdBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex, uint32_t frameIndex) noexcept; + void SetViewProjectionMatrix (SHMatrix const& viewMatrix, SHMatrix const& projMatrix) noexcept; /*-----------------------------------------------------------------------------*/ /* Setters and Getters */ /*-----------------------------------------------------------------------------*/ - Handle GetRenderGraph (void) const noexcept; - Handle GetCommandBuffer(uint32_t frameIndex) const noexcept; Handle GetCameraDirector (void) const noexcept; private: @@ -102,9 +101,6 @@ namespace SHADE //! Vulkan UBOs need to be aligned, this is pad SHShaderCameraData struct uint32_t cameraDataAlignedSize; - Handle viewport; - Handle camera; - Handle renderGraph; Handle cameraDescriptorSet; Handle cameraBuffer; @@ -114,10 +110,10 @@ namespace SHADE // GPU. SHShaderCameraData cpuCameraData; - //! Command buffers for the render graph - std::vector> commandBuffers; - + ////! Command buffers for the render graph + //std::vector> commandBuffers; + PROJECTION_TYPE projectionType; }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp index 7bd0049f..078261a5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp @@ -46,34 +46,6 @@ namespace SHADE ); } - /*---------------------------------------------------------------------------------*/ - /* Renderer Registration Functions */ - /*---------------------------------------------------------------------------------*/ - Handle SHViewport::AddRenderer(SHResourceHub& resourceManager, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph) - { - // Create the renderer - auto renderer = resourceManager.Create(device, numFrames, cmdPools, descriptorPool, cameraDescLayout, GetHandle(), renderGraph); - - // Store - renderers.emplace_back(renderer); - - // Return - return renderer; - } - void SHViewport::RemoveRenderer(Handle renderer) - { - auto iter = std::find(renderers.begin(), renderers.end(), renderer); - if (iter == renderers.end()) - { - SHLOG_WARNING("Attempted to remove a Renderer that does not belong to a viewport!"); - return; - } - - // Remove it - iter->Free(); - renderers.erase(iter); - } - void SHViewport::SetWidth(float w) noexcept { viewport.width = w; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h index 26c0a6bd..60bd6e95 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h @@ -56,11 +56,11 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ void SetUp(Handle commandBuffer); - /*-----------------------------------------------------------------------------*/ - /* Renderers Registration Functions */ - /*-----------------------------------------------------------------------------*/ - Handle AddRenderer(SHResourceHub& resourceManager, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph); - void RemoveRenderer(Handle renderer); + ///*-----------------------------------------------------------------------------*/ + ///* Renderers Registration Functions */ + ///*-----------------------------------------------------------------------------*/ + //Handle AddRenderer(SHResourceHub& resourceManager, uint32_t numFrames, std::vector>& cmdPools, Handle descriptorPool, Handle cameraDescLayout, Handle renderGraph); + //void RemoveRenderer(Handle renderer); /*-----------------------------------------------------------------------------*/ /* Setters */ @@ -79,7 +79,7 @@ namespace SHADE float GetHeight() const { return viewport.height; } float GetMinDepth() const { return viewport.minDepth; } float GetMaxDepth() const { return viewport.maxDepth; } - std::vector>& GetRenderers() { return renderers; } + //std::vector>& GetRenderers() { return renderers; } private: @@ -88,7 +88,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ Handle device; vk::Viewport viewport; - std::vector> renderers; + //std::vector> renderers; }; } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp index 2ea6bc8b..362b0e8f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.cpp @@ -1,5 +1,7 @@ #include "SHpch.h" #include "SHLightComponent.h" +#include "Graphics/Events/SHGraphicsEvents.h" +#include "Events/SHEventManager.hpp" namespace SHADE { @@ -104,6 +106,21 @@ namespace SHADE //MakeDirty(); } + void SHLightComponent::SetEnableShadow(bool flag) noexcept + { + lightData.castShadows = flag; + + // If the flag is true + if (flag && lightData.shadowMapIndex == SHLightData::INVALID_SHADOW_MAP_INDEX) + { + // Create new event and broadcast it + SHLightEnableShadowEvent newEvent; + newEvent.lightEntity = GetEID(); + + SHEventManager::BroadcastEvent(newEvent, SH_GRAPHICS_LIGHT_ENABLE_SHADOW_EVENT); + } + } + SHLightData const& SHLightComponent::GetLightData(void) const noexcept { return lightData; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h index 6b35559c..1d636595 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightComponent.h @@ -25,7 +25,6 @@ namespace SHADE ////! If the light's data is already in the buffers, this will be set to true. //bool bound; - public: /*-----------------------------------------------------------------------*/ /* LIFECYCLE FUNCTIONS */ @@ -49,6 +48,7 @@ namespace SHADE //void Unbind (void) noexcept; //void SetBound (uint32_t inIndexInBuffer) noexcept; void SetStrength (float value) noexcept; // serialized + void SetEnableShadow (bool flag) noexcept; SHLightData const& GetLightData (void) const noexcept; @@ -59,7 +59,7 @@ namespace SHADE uint32_t const& GetCullingMask (void) const noexcept; // serialized //bool IsDirty (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; RTTR_ENABLE() }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.cpp index 8e8f0783..f51fdfa7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.cpp @@ -16,6 +16,12 @@ namespace SHADE // Diffuse color set to 1 color = SHVec4::One; + + // light will default not cast shadows + castShadows = false; + + // shadow map index is invalid. + shadowMapIndex = INVALID_SHADOW_MAP_INDEX; } } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.h index e9a02c1a..4d62700d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightData.h @@ -26,6 +26,8 @@ namespace SHADE /***************************************************************************/ struct SHLightData { + static constexpr uint32_t INVALID_SHADOW_MAP_INDEX = std::numeric_limits::max(); + //! position of the light SHVec3 position; @@ -46,6 +48,13 @@ namespace SHADE //! Strength of the light float strength; + //! Whether or not the light will cast a shadow. More technically, whether or + //! not the light will result in the addition of a depth map into the render graph + //! to be used for shadow mapping calculations. + bool castShadows; + + //! Index of the shadow map when it gets placed in the descriptor array of textures (that are all shadow maps). + uint32_t shadowMapIndex; void Reset (void) noexcept; //! TODO: diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp index 3d5a5773..ddacf3a7 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.cpp @@ -1,6 +1,6 @@ #include "SHpch.h" #include "SHLightingSubSystem.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" #include "Tools/Utilities/SHUtilities.h" #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Buffers/SHVkBuffer.h" @@ -320,15 +320,16 @@ namespace SHADE void SHLightingSubSystem::UpdateDescSet(uint32_t binding) noexcept { auto buffer = perTypeData[binding].GetDataBuffer(); + static constexpr uint32_t LIGHTING_DATA_SET_INDEX = 0; // We bind the buffer with the correct desc set binding - lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, + lightingDataDescSet->ModifyWriteDescBuffer(LIGHTING_DATA_SET_INDEX, binding + 1, // we want to +1 here because the first binding is reserved for count { &buffer, 1 }, 0, perTypeData[binding].GetDataSize() * perTypeData[binding].GetMaxLights()); - lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, binding + 1); // +1 here, same reason. see above + lightingDataDescSet->UpdateDescriptorSetBuffer(LIGHTING_DATA_SET_INDEX, binding + 1); // +1 here, same reason. see above } /***************************************************************************/ @@ -385,7 +386,7 @@ namespace SHADE std::fill (variableSizes.begin(), variableSizes.end(), 1); // Create the descriptor set - lightingDataDescSet = descPool->Allocate({ SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS] }, variableSizes); + lightingDataDescSet = descPool->Allocate({ SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::LIGHTS) }, variableSizes); #ifdef _DEBUG const auto& CAM_DESC_SETS = lightingDataDescSet->GetVkHandle(); for (int i = 0; i < static_cast(CAM_DESC_SETS.size()); ++i) @@ -408,8 +409,9 @@ namespace SHADE // Create the GPU buffer to hold light count lightCountsBuffer = logicalDevice->CreateBuffer(lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, nullptr, lightCountsAlignedSize * SHGraphicsConstants::NUM_FRAME_BUFFERS, vk::BufferUsageFlagBits::eUniformBuffer, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, "Light Count Data"); - lightingDataDescSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT, {&lightCountsBuffer, 1}, 0, sizeof (uint32_t) * NUM_LIGHT_TYPES); - lightingDataDescSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT); + static constexpr uint32_t LIGHTING_DATA_SET_INDEX = 0; + lightingDataDescSet->ModifyWriteDescBuffer(LIGHTING_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT, { &lightCountsBuffer, 1 }, 0, sizeof(uint32_t) * NUM_LIGHT_TYPES); + lightingDataDescSet->UpdateDescriptorSetBuffer(LIGHTING_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::LIGHTING_COUNT); for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) { @@ -517,11 +519,16 @@ namespace SHADE } - void SHLightingSubSystem::BindDescSet(Handle cmdBuffer, uint32_t frameIndex) noexcept + void SHLightingSubSystem::BindDescSet(Handle cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept { //Bind descriptor set(We bind at an offset because the buffer holds NUM_FRAME_BUFFERS sets of data). - cmdBuffer->BindDescriptorSet(lightingDataDescSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::DYNAMIC_GLOBALS, { dynamicOffsets[frameIndex] }); + cmdBuffer->BindDescriptorSet(lightingDataDescSet, SH_PIPELINE_TYPE::COMPUTE, setIndex, { dynamicOffsets[frameIndex] }); } + Handle SHLightingSubSystem::GetLightDataDescriptorSet(void) const noexcept + { + return lightingDataDescSet; + } + } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h index ae6caead..fa103136 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Lights/SHLightingSubSystem.h @@ -4,6 +4,7 @@ #include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec4.h" #include "SHLightData.h" +#include #include "Graphics/MiddleEnd/Interface/SHGraphicsConstants.h" namespace SHADE @@ -57,8 +58,11 @@ namespace SHADE class SH_API SHLightingSubSystem { - private: + public: + using DynamicOffsetArray = std::array, static_cast(SHGraphicsConstants::NUM_FRAME_BUFFERS)>; + + private: class PerTypeData { private: @@ -130,7 +134,7 @@ namespace SHADE std::array(SH_LIGHT_TYPE::NUM_TYPES)> perTypeData; //! Container to store dynamic offsets for binding descriptor sets - std::array, static_cast(SHGraphicsConstants::NUM_FRAME_BUFFERS)> dynamicOffsets; + DynamicOffsetArray dynamicOffsets; //! holds the data that represents how many lights are in the scene std::array(SH_LIGHT_TYPE::NUM_TYPES)> lightCountsData; @@ -162,7 +166,8 @@ namespace SHADE void Run (SHMatrix const& viewMat, uint32_t frameIndex) noexcept; void Exit (void) noexcept; - void BindDescSet (Handle cmdBuffer, uint32_t frameIndex) noexcept; + void BindDescSet (Handle cmdBuffer, uint32_t setIndex, uint32_t frameIndex) noexcept; + Handle GetLightDataDescriptorSet (void) const noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp index 05bd8813..baf09a2d 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.cpp @@ -1,7 +1,7 @@ #include "SHpch.h" #include "SHPipelineLibrary.h" #include "Graphics/Devices/SHVkLogicalDevice.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" #include "Graphics/RenderGraph/SHSubpass.h" #include "Graphics/SHVkUtil.h" @@ -13,7 +13,7 @@ namespace SHADE SHPipelineLayoutParams params { .shaderModules = {vsFsPair.first, vsFsPair.second}, - .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() + .predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING).descSetLayouts }; // Create the pipeline layout @@ -21,7 +21,7 @@ namespace SHADE // Create the pipeline and configure the default vertex input state auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass); - newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsGlobalData::GetDefaultViState()); + newPipeline->GetPipelineState().SetVertexInputState(SHGraphicsPredefinedData::GetDefaultViState()); SHColorBlendState colorBlendState{}; colorBlendState.logic_op_enable = VK_FALSE; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h index aeb023c5..5085f21f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h @@ -10,7 +10,7 @@ namespace SHADE class SHVkDescriptorSetLayouts; class SHVkPipeline; class SHSubpass; - class SHGraphicsGlobalData; + class SHGraphicsPredefinedData; // Pipeline library is a PURELY MIDDLE END SYSTEM. It is responsible for only creating pipelines from shaders and caching // them so that they don't need to be recreated again. diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.cpp index 3dd54ca5..b6ec5f83 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.cpp @@ -1,7 +1,7 @@ #include "SHpch.h" #include "SHFont.h" #include "Graphics/Devices/SHVkLogicalDevice.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Buffers/SHVkBuffer.h" #include "Graphics/Images/SHVkSampler.h" @@ -121,17 +121,23 @@ namespace SHADE descSet = descPool->Allocate({ layout }, { 1 }); auto viewLayoutSampler = std::make_tuple(bitmapDataImageView, sampler, vk::ImageLayout::eShaderReadOnlyOptimal); - descSet->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA, {&viewLayoutSampler, 1}); + static constexpr uint32_t FONT_DATA_SET_INDEX = 0; + descSet->ModifyWriteDescImage(FONT_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA, {&viewLayoutSampler, 1}); - descSet->ModifyWriteDescBuffer(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, + descSet->ModifyWriteDescBuffer(FONT_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA, { &matrixDataBuffer, 1 }, 0, fontAsset.glyphTransformations.size() * sizeof(SHMatrix)); // Bind image and buffer to desc set. - descSet->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA); - descSet->UpdateDescriptorSetBuffer(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA); + descSet->UpdateDescriptorSetImages(FONT_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA); + descSet->UpdateDescriptorSetBuffer(FONT_DATA_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA); } + void SHFont::BindDescriptorSet(Handle commandBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex) noexcept + { + commandBuffer->BindDescriptorSet(descSet, SH_PIPELINE_TYPE::GRAPHICS, setIndex, {}); + } + std::unordered_map SHFont::GetUnicodeIndexing(void) const noexcept { return unicodeIndexing; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.h b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.h index 1439281a..b3731af9 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHFont.h @@ -3,6 +3,7 @@ #include "Resource/SHHandle.h" #include "msdf-atlas-gen/msdf-atlas-gen.h" #include "Assets/Asset Types/SHFontAsset.h" +#include "Graphics/Pipeline/SHPipelineType.h" namespace SHADE { @@ -57,6 +58,7 @@ namespace SHADE SHFont (Handle inLogicalDeviceHdl, SHFontAsset const& asset) noexcept; void TransferToGPU (Handle commandBuffer) noexcept; void DoPostTransfer (Handle descPool, Handle layout) noexcept; + void BindDescriptorSet (Handle commandBuffer, SH_PIPELINE_TYPE pipelineType, uint32_t setIndex) noexcept; /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.cpp index 6748311e..ffd5ac96 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.cpp @@ -6,11 +6,13 @@ #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/MiddleEnd/TextRendering/SHFont.h" #include "Graphics/Buffers/SHVkBuffer.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" #include "Graphics/Pipeline/SHVkPipeline.h" #include "Graphics/SHVkUtil.h" #include "Graphics/RenderGraph/SHSubpass.h" #include "Math/Transform/SHTransformComponent.h" +#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h" +#include "Graphics/MiddleEnd/Interface/SHRenderer.h" namespace SHADE { @@ -91,19 +93,17 @@ namespace SHADE } - void SHTextRenderingSubSystem::Init(Handle device, Handle compatibleRenderpass, Handle subpass, Handle descPool, Handle textVS, Handle textFS, std::function, uint32_t)> const& bindFunction) noexcept + void SHTextRenderingSubSystem::Init(Handle device, Handle compatibleRenderpass, Handle subpass, Handle descPool, Handle textVS, Handle textFS) noexcept { SHComponentManager::CreateComponentSparseSet(); - cameraDescSetBind = bindFunction; - logicalDevice = device; // prepare pipeline layout params SHPipelineLayoutParams plParams { .shaderModules = {textVS, textFS}, - .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts() + .predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::TEXT_RENDERING).descSetLayouts }; pipelineLayout = logicalDevice->CreatePipelineLayout(plParams); @@ -157,24 +157,6 @@ namespace SHADE // Construct pipeline pipeline->ConstructPipeline(); - SHVkDescriptorSetLayout::Binding fontBitmapBinding - { - .Type = vk::DescriptorType::eCombinedImageSampler, - .Stage = vk::ShaderStageFlagBits::eFragment, - .BindPoint = SHGraphicsConstants::DescriptorSetBindings::FONT_BITMAP_DATA, - .DescriptorCount = 1, - }; - - SHVkDescriptorSetLayout::Binding fontMatrixBinding - { - .Type = vk::DescriptorType::eStorageBuffer, - .Stage = vk::ShaderStageFlagBits::eVertex, - .BindPoint = SHGraphicsConstants::DescriptorSetBindings::FONT_MATRIX_DATA, - .DescriptorCount = 1, - }; - - fontDataDescSetLayout = logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, { fontBitmapBinding, fontMatrixBinding }); - } void SHTextRenderingSubSystem::Run(uint32_t frameIndex) noexcept @@ -192,9 +174,14 @@ namespace SHADE } } - void SHTextRenderingSubSystem::Render(Handle cmdBuffer, uint32_t frameIndex) noexcept + void SHTextRenderingSubSystem::Render(Handle cmdBuffer, Handle renderer, uint32_t frameIndex) noexcept { auto& textRendererComps = SHComponentManager::GetDense(); + auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::TEXT_RENDERING); + uint32_t fontSetIndex = mappings.at(SHPredefinedDescriptorTypes::FONT); + uint32_t staticGlobalSetIndex = mappings.at(SHPredefinedDescriptorTypes::STATIC_DATA); + uint32_t cameraSetIndex = mappings.at(SHPredefinedDescriptorTypes::CAMERA); + for (auto& comp : textRendererComps) { auto* transform = SHComponentManager::GetComponent(comp.GetEID()); @@ -205,15 +192,19 @@ namespace SHADE // bind the pipeline cmdBuffer->BindPipeline(pipeline); + // Bind global data + SHGlobalDescriptorSets::BindStaticGlobalData(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, staticGlobalSetIndex); + + // Bind camera data + renderer->BindDescriptorSet(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, cameraSetIndex, frameIndex); + + // bind descriptors for font (matrices) + fontHandle->BindDescriptorSet(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, fontSetIndex); + // bind VBO (position and indices) cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::CALCULATED_GLYPH_POSITION, comp.charPositionDataBuffer, 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::GLYPH_INDEX, comp.indexingDataBuffer, 0); - cameraDescSetBind(cmdBuffer, frameIndex); - - // bind descriptors for font (matrices) - cmdBuffer->BindDescriptorSet(fontHandle->GetDescriptorSet(), SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::FONT_DATA, {}); - cmdBuffer->SetPushConstantVariable("TestPushConstant.worldTransform", transform->GetTRS(), SH_PIPELINE_TYPE::GRAPHICS); cmdBuffer->SetPushConstantVariable("TestPushConstant.eid", comp.GetEID(), SH_PIPELINE_TYPE::GRAPHICS); cmdBuffer->SetPushConstantVariable("TestPushConstant.textColor", SHVec3 (1.0f, 1.0f, 1.0f), SH_PIPELINE_TYPE::GRAPHICS); @@ -223,9 +214,7 @@ namespace SHADE // call draw call cmdBuffer->DrawArrays(4, comp.text.size(), 0, 0); //glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, static_cast(textComp.lastRenderedCharacterIndex) + 1); - } - } } @@ -234,9 +223,9 @@ namespace SHADE } - Handle SHTextRenderingSubSystem::GetFontDataDescSetLayout(void) const noexcept - { - return fontDataDescSetLayout; - } + //Handle SHTextRenderingSubSystem::GetFontDataDescSetLayout(void) const noexcept + //{ + // return fontDataDescSetLayout; + //} } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h index 05ab01da..c91e7794 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/TextRendering/SHTextRenderingSubSystem.h @@ -20,6 +20,7 @@ namespace SHADE class SHVkRenderpass; class SHSubpass; class SHVkShaderModule; + class SHRenderer; class SHTextRenderingSubSystem { @@ -41,24 +42,20 @@ namespace SHADE Handle pipelineLayout; //! Descriptor set for font data access in shaders - Handle fontDataDescSetLayout; - - //! Super temporary. Global descriptor set needs to be revamped along with - //! entire graphics system. - std::function, uint32_t)> cameraDescSetBind; + //Handle fontDataDescSetLayout; private: void RecomputePositions(SHTextRenderableComponent& textComp) noexcept; public: - void Init(Handle device, Handle compatibleRenderpass, Handle subpass, Handle descPool, Handle textVS, Handle textFS, std::function, uint32_t)> const& bindFunction) noexcept; + void Init(Handle device, Handle compatibleRenderpass, Handle subpass, Handle descPool, Handle textVS, Handle textFS) noexcept; void Run(uint32_t frameIndex) noexcept; - void Render (Handle cmdBuffer, uint32_t frameIndex) noexcept; + void Render (Handle cmdBuffer, Handle renderer, uint32_t frameIndex) noexcept; void Exit(void) noexcept; - Handle GetFontDataDescSetLayout (void) const noexcept; + //Handle GetFontDataDescSetLayout (void) const noexcept; }; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp index dfb3f3b9..0578e7a2 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Textures/SHTextureLibrary.cpp @@ -24,7 +24,7 @@ of DigiPen Institute of Technology is prohibited. #include "Graphics/Descriptors/SHVkDescriptorSetGroup.h" #include "Graphics/Images/SHVkImage.h" #include "Graphics/Images/SHVkImageView.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" #include "Assets/Asset Types/SHTextureAsset.h" namespace SHADE @@ -168,22 +168,23 @@ namespace SHADE } texDescriptors = descPool->Allocate ( - { SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS] }, + { SHGraphicsPredefinedData::GetPredefinedDescSetLayouts(SHGraphicsPredefinedData::PredefinedDescSetLayoutTypes::STATIC_DATA) }, { static_cast(texOrder.size()) } ); #ifdef _DEBUG for (auto set : texDescriptors->GetVkHandle()) SET_VK_OBJ_NAME(device, vk::ObjectType::eDescriptorSet, set, "[Descriptor Set] Static Globals"); #endif + static constexpr uint32_t TEX_DESCRIPTOR_SET_INDEX = 0; texDescriptors->ModifyWriteDescImage ( - SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, + TEX_DESCRIPTOR_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA, combinedImageSamplers ); texDescriptors->UpdateDescriptorSetImages ( - SHGraphicsConstants::DescriptorSetIndex::STATIC_GLOBALS, + TEX_DESCRIPTOR_SET_INDEX, SHGraphicsConstants::DescriptorSetBindings::IMAGE_AND_SAMPLERS_DATA ); } diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h index 010bed0e..3288d196 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h +++ b/SHADE_Engine/src/Graphics/Pipeline/SHPipelineLayoutParams.h @@ -25,7 +25,7 @@ namespace SHADE //! used just for textures or lights for example). In that case, we still //! want to use the layout to initialize the pipeline layout but we do not //! want to use it for allocating descriptor sets. - std::vector> const& globalDescSetLayouts = {}; + std::vector> const& predefinedDescSetLayouts = {}; //! Since both SPIRV-Reflect and GLSL don't provide ways to describe UBOs or //! SSBOs as dynamic, we need to do it ourselves. This will store bindings diff --git a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp index 0333aa09..c2d83052 100644 --- a/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp +++ b/SHADE_Engine/src/Graphics/Pipeline/SHVkPipelineLayout.cpp @@ -220,7 +220,7 @@ namespace SHADE // 1 descriptor set layout for every descriptor set detected. for (auto const& set : setsWithBindings) { - auto newDescriptorSetLayout = logicalDeviceHdl->CreateDescriptorSetLayout(set.first, set.second); + auto newDescriptorSetLayout = logicalDeviceHdl->CreateDescriptorSetLayout(set.second); descriptorSetLayoutsAllocate.push_back(newDescriptorSetLayout); } @@ -317,7 +317,7 @@ namespace SHADE , logicalDeviceHdl {inLogicalDeviceHdl} , pushConstantInterface{} , vkPcRanges{} - , descriptorSetLayoutsGlobal{pipelineLayoutParams.globalDescSetLayouts } // do a copy, some other pipeline layout might need this + , descriptorSetLayoutsGlobal{pipelineLayoutParams.predefinedDescSetLayouts } // do a copy, some other pipeline layout might need this , descriptorSetLayoutsAllocate{} , vkDescriptorSetLayoutsAllocate{} , descriptorSetLayoutsPipeline{} diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp index 2ffd6d13..74371a64 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp @@ -12,8 +12,10 @@ #include "SHRenderGraphStorage.h" #include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h" #include "Tools/Utilities/SHUtilities.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" #include "Graphics/RenderGraph/SHRenderToSwapchainImageSystem.h" +#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h" + namespace SHADE { @@ -66,6 +68,56 @@ namespace SHADE renderGraphStorage->graphResources->try_emplace(resourceName, resource); } + + void SHRenderGraph::RemoveResource(std::string resourceName) noexcept + { + // 1. Check if nodes are using said attachment and remove if they are + // - Check subpasses while at it and remove as well if used as attachment + // 2. Regenerate graph + // - Delete all vulkan objects first as well and clear the necessary containers + + if (!renderGraphStorage->graphResources->contains(resourceName)) + return; + + renderGraphStorage->logicalDevice->WaitIdle(); + + uint64_t handleID = renderGraphStorage->graphResources->at (resourceName).GetId().Raw; + + // Record nodes that will be affected + std::vector affectedNodes{}; + + // Detach resource from all nodes if applicable + for (uint32_t i = 0; i < nodes.size(); ++i) + { + if (nodes[i]->DetachResource(resourceName, handleID)) + affectedNodes.emplace_back(i); + } + + // Up to this point the nodes and subpasses should have no trace of the deleted resource. Attachment + // descriptions and subpass indices should also have been reconfigured at this point. However, this + // means that the subpass descriptions and subpass dependencies need to be reconfigured. + + // configure subpass dependencies and descriptions. + for (auto& affectedNode : affectedNodes) + nodes[affectedNode]->ConfigureSubpasses(); + + for (auto& affectedNode : affectedNodes) + nodes[affectedNode]->CreateRenderpass(); + + for (auto& affectedNode : affectedNodes) + nodes[affectedNode]->CreateFramebuffer(); + /* + * IMPORTANT NOTES + * + * This remove resource function would be more complete if it accounted for renderpass compatibility by + * recreating the graphics pipelines stored in render graph nodes. However due to time constraints, this is left out. As such, + * pipelines that are recreated with a certain renderpass and subpass will assumed to be compatible when used in different subpasses. + * + * This function also recreates renderpasses and framebuffers so it does not account for removing of resources that are used in nodes whose + * renderpasses and framebuffers are used externally in systems like Editor with ImGui. + */ + } + void SHRenderGraph::LinkNonOwningResource(Handle resourceOrigin, std::string resourceName) noexcept { // resource to link @@ -234,140 +286,12 @@ namespace SHADE */ /***************************************************************************/ - void SHRenderGraph::ConfigureSubpasses(void) noexcept + void SHRenderGraph::ConfigureAllSubpasses(void) noexcept { // For all nodes for (auto& node : nodes) { - // Create subpass description and dependencies based on number of subpasses - node->spDescs.resize(node->subpasses.size()); - node->spDeps.resize(node->subpasses.size()); - - // 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 - // in bit fields (1 bit for each subpass). - 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 (auto& subpass : node->subpasses) - { - // Configure subpass description - auto& desc = node->spDescs[i]; - desc.pColorAttachments = subpass->colorReferences.data(); - desc.colorAttachmentCount = static_cast(subpass->colorReferences.size()); - desc.pInputAttachments = subpass->inputReferences.data(); - desc.inputAttachmentCount = static_cast(subpass->inputReferences.size()); - desc.pDepthStencilAttachment = subpass->depthReferences.data(); - desc.pipelineBindPoint = vk::PipelineBindPoint::eGraphics; // TODO: Just graphics for now. See if its possible to allow user defined params. - - // Get reference to subpass description - auto& dep = node->spDeps[i]; - - // Configure subpass index for dependencies - dep.srcSubpass = (i == 0) ? VK_SUBPASS_EXTERNAL : i - 1; - dep.dstSubpass = i; - - // First we want to see if the subpass has color, depth or input attachments and set bit field accordingly - if (subpass->colorReferences.size()) - { - colorRead |= (1 << i); - colorWrite |= (1 << i); - } - - // Same thing for depth - if (subpass->depthReferences.size()) - { - depthRead |= (1 << i); - depthWrite |= (1 << i); - } - if (subpass->inputReferences.size()) - inputDependencies |= (1 << i); - - // Input attachments can be any type, so we need to check what type it is - for (auto& inputAtt : subpass->inputReferences) - { - auto resource = node->attResources[inputAtt.attachment]; - if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT)) - { - if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR) || - resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) - colorRead |= (1 << i); - else if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL)) - depthRead |= (1 << i); - } - else - { - SHLOG_ERROR("While configuring subpass, an input reference was detected but the resource to be used is not marked as SH_ATT_DESC_TYPE_FLAGS::INPUT. "); - } - } - - ++i; - } - - // Loop through all subpasses again but this time we use the bit field to initialize - // the dependencies. - for (i = 0; i < node->subpasses.size(); ++i) - { - vk::PipelineStageFlags srcStage; - vk::PipelineStageFlags dstStage; - vk::AccessFlags srcAccess; - vk::AccessFlags dstAccess; - auto& dep = node->spDeps[i]; - - if (colorRead & (1 << i)) - { - srcStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; - dstStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; - srcAccess |= vk::AccessFlagBits::eColorAttachmentWrite; - dstAccess |= vk::AccessFlagBits::eColorAttachmentRead; - } - if (colorWrite & (1 << i)) - { - srcStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; - dstStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; - srcAccess |= vk::AccessFlagBits::eColorAttachmentWrite; - dstAccess |= vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead; - } - if (depthRead & (1 << i)) - { - srcStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests; - dstStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests; - srcAccess |= vk::AccessFlagBits::eDepthStencilAttachmentWrite; - dstAccess |= vk::AccessFlagBits::eDepthStencilAttachmentRead; - } - if (depthWrite & (1 << i)) - { - srcStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests; - dstStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests; - srcAccess |= vk::AccessFlagBits::eDepthStencilAttachmentWrite; - dstAccess |= vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite; - } - if (inputDependencies & (1 << i)) - { - dstStage |= vk::PipelineStageFlagBits::eFragmentShader; - dstAccess |= vk::AccessFlagBits::eInputAttachmentRead; - } - - //// If subpass of first renderpass, stage flag should be bottom of pipe - //if (&node == &nodes.front() && i == 0) - // srcStage = vk::PipelineStageFlagBits::eBottomOfPipe; - - //// If subpass of last renderpass, stage flag should be bottom of pipe - //if (&node == &nodes.back() && i == node->subpasses.size() - 1) - // dstStage = vk::PipelineStageFlagBits::eTopOfPipe; - - dep.srcStageMask = srcStage; - dep.dstStageMask = dstStage; - dep.srcAccessMask = srcAccess; - dep.dstAccessMask = dstAccess; - - dep.srcStageMask = srcStage; - - // initialize input descriptors - node->subpasses[i]->CreateInputDescriptors(); - } + node->ConfigureSubpasses(); } } @@ -424,7 +348,7 @@ namespace SHADE */ /***************************************************************************/ - void SHRenderGraph::Init(std::string graphName, Handle logicalDevice, Handle swapchain, SHResourceHub* resourceHub) noexcept + void SHRenderGraph::Init(std::string graphName, Handle logicalDevice, Handle swapchain, SHResourceHub* resourceHub, std::vector>& cmdPools) noexcept { //resourceHub = std::make_shared(); @@ -437,6 +361,11 @@ namespace SHADE renderGraphStorage->resourceHub = resourceHub; renderGraphStorage->descriptorPool = logicalDevice->CreateDescriptorPools(); + commandBuffers.resize(static_cast(swapchain->GetNumImages())); + + for (uint32_t i = 0; i < commandBuffers.size(); ++i) + commandBuffers[i] = cmdPools[i]->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); + name = std::move(graphName); } @@ -555,17 +484,24 @@ namespace SHADE if (renderGraphStorage->graphResources->contains(toSwapchainResource) && renderGraphStorage->graphResources->contains(swapchainResource)) { auto newNode = AddNode("Render To Present", { ResourceInstruction (toSwapchainResource.c_str()), ResourceInstruction(swapchainResource.c_str()) }, predecessorNodes); - auto newSubpass = newNode->AddSubpass("Render"); + auto newSubpass = newNode->AddSubpass("Render", {}, {}); newSubpass->AddColorOutput(swapchainResource); newSubpass->AddInput(toSwapchainResource); renderToSwapchainImageSystem = renderGraphStorage->resourceHub->Create (newNode, newSubpass, shaderModules); - newSubpass->AddExteriorDrawCalls([=](Handle& cmdBuffer, uint32_t frameIndex) + newSubpass->AddExteriorDrawCalls([=](Handle cmdBuffer, Handle renderer, uint32_t frameIndex) { cmdBuffer->BindPipeline(renderToSwapchainImageSystem->GetPipeline()); - - newSubpass->BindDescriptorInputDescriptorSets (cmdBuffer, frameIndex); + + // If we are rendering to present image, the width and height will be the dimensions of that image. So we need to set viewport scissor. + auto resource = renderGraphStorage->graphResources->at(swapchainResource); + uint32_t w = static_cast(resource->GetWidth()); + uint32_t h = static_cast(resource->GetHeight()); + cmdBuffer->SetViewportScissor(static_cast(w), static_cast(h), w, h); + + static constexpr uint32_t INPUT_IMAGE_SET_INDEX = 0; + newSubpass->BindInputDescriptorSets (cmdBuffer, INPUT_IMAGE_SET_INDEX, frameIndex); // draw a quad. cmdBuffer->DrawArrays(4, 1, 0, 0); @@ -590,12 +526,17 @@ namespace SHADE { CheckForNodeComputes(); ConfigureAttachmentDescriptions(); - ConfigureSubpasses(); + ConfigureAllSubpasses(); ConfigureRenderpasses(); ConfigureFramebuffers(); ConfigureSubSystems(); } + void SHRenderGraph::Regenerate(void) noexcept + { + + } + /***************************************************************************/ /*! @@ -616,14 +557,41 @@ namespace SHADE // TODO: The graph scope buffers were meant to bind vertex buffers and index buffers for meshes. Find a // better way to manage these - void SHRenderGraph::Execute(uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept + void SHRenderGraph::Execute(uint32_t frameIndex, Handle descPool) noexcept { + auto cmdBuffer = commandBuffers[frameIndex]; cmdBuffer->BeginLabeledSegment(name); + + auto batchingSystemData = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING); + + // Force bind pipeline layout + cmdBuffer->ForceSetPipelineLayout(batchingSystemData.dummyPipelineLayout, SH_PIPELINE_TYPE::GRAPHICS); + cmdBuffer->ForceSetPipelineLayout(batchingSystemData.dummyPipelineLayout, SH_PIPELINE_TYPE::COMPUTE); + + auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); + for (auto& node : nodes) + { + // bind static global data + SHGlobalDescriptorSets::BindStaticGlobalData(cmdBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::STATIC_DATA)); + node->Execute(cmdBuffer, descPool, frameIndex); + } + cmdBuffer->EndLabeledSegment(); } + void SHRenderGraph::Begin(uint32_t frameIndex) noexcept + { + commandBuffers[frameIndex]->BeginRecording(); + + } + + void SHRenderGraph::End(uint32_t frameIndex) noexcept + { + commandBuffers[frameIndex]->EndRecording(); + } + void SHRenderGraph::FinaliseBatch(uint32_t frameIndex, Handle descPool) { for (auto& node : nodes) @@ -670,4 +638,9 @@ namespace SHADE return {}; } + Handle SHRenderGraph::GetCommandBuffer(uint32_t frameIndex) const noexcept + { + return commandBuffers[frameIndex]; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h index 0a9ed376..c7fe221b 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h @@ -29,7 +29,7 @@ namespace SHADE class SHVkCommandPool; class SHVkCommandBuffer; class SHRenderGraphNode; - class SHGraphicsGlobalData; + class SHGraphicsPredefinedData; class SHVkDescriptorPool; class SHRenderGraphStorage; class SHRenderToSwapchainImageSystem; @@ -51,7 +51,7 @@ namespace SHADE /* PRIVATE MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ void ConfigureAttachmentDescriptions (void) noexcept; - void ConfigureSubpasses (void) noexcept; + void ConfigureAllSubpasses (void) noexcept; void ConfigureRenderpasses (void) noexcept; void ConfigureSubSystems (void) noexcept; void ConfigureFramebuffers (void) noexcept; @@ -74,6 +74,9 @@ namespace SHADE //! For rendering onto the swapchain Handle renderToSwapchainImageSystem; + //! Command buffer to issue rendering commands + std::vector> commandBuffers; + public: /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ @@ -86,24 +89,66 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - void Init (std::string graphName, Handle logicalDevice, Handle swapchain, SHResourceHub* resourceHub) noexcept; - void AddResource(std::string resourceName, std::initializer_list typeFlags, uint32_t w = static_cast(-1), uint32_t h = static_cast(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {}); - void LinkNonOwningResource (Handle resourceOrigin, std::string resourceName) noexcept; - Handle AddNode (std::string nodeName, std::initializer_list resourceInstruction, std::initializer_list predecessorNodes) noexcept; - void AddRenderToSwapchainNode (std::string toSwapchainResource, std::string swapchainResource, std::initializer_list predecessorNodes, std::pair, Handle> shaderModules) noexcept; + void Init + ( + std::string graphName, + Handle logicalDevice, + Handle swapchain, SHResourceHub* resourceHub, + std::vector>& cmdPools + ) noexcept; + + void AddResource + ( + std::string resourceName, + std::initializer_list typeFlags, + uint32_t w = static_cast(-1), + uint32_t h = static_cast(-1), + vk::Format format = vk::Format::eB8G8R8A8Unorm, + uint8_t levels = 1, + vk::ImageUsageFlagBits usageFlags = {}, + vk::ImageCreateFlagBits createFlags = {} + ); + + void RemoveResource (std::string resourceName) noexcept; + + void LinkNonOwningResource + ( + Handle resourceOrigin, + std::string resourceName + ) noexcept; + + Handle AddNode + ( + std::string nodeName, + std::initializer_list resourceInstruction, + std::initializer_list predecessorNodes + ) noexcept; + + void AddRenderToSwapchainNode + ( + std::string toSwapchainResource, + std::string swapchainResource, + std::initializer_list predecessorNodes, + std::pair, + Handle> shaderModules + ) noexcept; void Generate (void) noexcept; + void Regenerate (void) noexcept; void CheckForNodeComputes (void) noexcept; - void Execute (uint32_t frameIndex, Handle cmdBuffer, Handle descPool) noexcept; + void Execute (uint32_t frameIndex, Handle descPool) noexcept; + void Begin (uint32_t frameIndex) noexcept; + void End (uint32_t frameIndex) noexcept; void FinaliseBatch (uint32_t frameIndex, Handle descPool); void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept; /*-----------------------------------------------------------------------*/ /* SETTERS AND GETTERS */ /*-----------------------------------------------------------------------*/ - Handle GetNode (std::string const& nodeName) const noexcept; - std::vector> const& GetNodes (void) const noexcept; - Handle GetRenderGraphResource (std::string const& resourceName) const noexcept; + Handle GetNode (std::string const& nodeName) const noexcept; + std::vector> const& GetNodes (void) const noexcept; + Handle GetRenderGraphResource (std::string const& resourceName) const noexcept; + Handle GetCommandBuffer (uint32_t frameIndex) const noexcept; }; } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp index 0f9379fe..3c412645 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp @@ -9,6 +9,8 @@ #include "SHRenderGraphStorage.h" #include "Graphics/RenderGraph/SHRenderGraphNodeCompute.h" #include "Graphics/SHVkUtil.h" +#include "Graphics/MiddleEnd/GlobalData/SHGlobalDescriptorSets.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" namespace SHADE { @@ -24,6 +26,12 @@ namespace SHADE /***************************************************************************/ void SHRenderGraphNode::CreateRenderpass(void) noexcept { + if (renderpass) + { + if (renderpass) + renderpass.Free(); + } + renderpass = graphStorage->logicalDevice->CreateRenderpass(attachmentDescriptions, spDescs, spDeps); SET_VK_OBJ_NAME(graphStorage->logicalDevice, vk::ObjectType::eRenderPass, renderpass->GetVkRenderpass(), "[RenderPass] " + name); } @@ -38,6 +46,15 @@ namespace SHADE /***************************************************************************/ void SHRenderGraphNode::CreateFramebuffer(void) noexcept { + if (!framebuffers.empty()) + { + for (auto fbo : framebuffers) + { + if (fbo) + fbo.Free(); + } + } + for (uint32_t i = 0; i < framebuffers.size(); ++i) { std::vector> imageViews(attResources.size()); @@ -98,6 +115,139 @@ namespace SHADE } } + void SHRenderGraphNode::ConfigureSubpasses(void) noexcept + { + // Create subpass description and dependencies based on number of subpasses + spDescs.resize(subpasses.size()); + spDeps.resize(subpasses.size()); + + // 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 + // in bit fields (1 bit for each subpass). + 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 (auto& subpass : subpasses) + { + // Configure subpass description + auto& desc = spDescs[i]; + desc.pColorAttachments = subpass->colorReferences.data(); + desc.colorAttachmentCount = static_cast(subpass->colorReferences.size()); + desc.pInputAttachments = subpass->inputReferences.data(); + desc.inputAttachmentCount = static_cast(subpass->inputReferences.size()); + desc.pDepthStencilAttachment = subpass->depthReferences.data(); + desc.pipelineBindPoint = vk::PipelineBindPoint::eGraphics; // TODO: Just graphics for now. See if its possible to allow user defined params. + + // Get reference to subpass description + auto& dep = spDeps[i]; + + // Configure subpass index for dependencies + dep.srcSubpass = (i == 0) ? VK_SUBPASS_EXTERNAL : i - 1; + dep.dstSubpass = i; + + // First we want to see if the subpass has color, depth or input attachments and set bit field accordingly + if (subpass->colorReferences.size()) + { + colorRead |= (1 << i); + colorWrite |= (1 << i); + } + + // Same thing for depth + if (subpass->depthReferences.size()) + { + depthRead |= (1 << i); + depthWrite |= (1 << i); + } + if (subpass->inputReferences.size()) + inputDependencies |= (1 << i); + + // Input attachments can be any type, so we need to check what type it is + for (auto& inputAtt : subpass->inputReferences) + { + auto resource = attResources[inputAtt.attachment]; + if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT)) + { + if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR) || + resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) + colorRead |= (1 << i); + else if (resource->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL)) + depthRead |= (1 << i); + } + else + { + SHLOG_ERROR("While configuring subpass, an input reference was detected but the resource to be used is not marked as SH_ATT_DESC_TYPE_FLAGS::INPUT. "); + } + } + + ++i; + } + + // Loop through all subpasses again but this time we use the bit field to initialize + // the dependencies. + for (i = 0; i < subpasses.size(); ++i) + { + vk::PipelineStageFlags srcStage; + vk::PipelineStageFlags dstStage; + vk::AccessFlags srcAccess; + vk::AccessFlags dstAccess; + auto& dep = spDeps[i]; + + if (colorRead & (1 << i)) + { + srcStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; + dstStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; + srcAccess |= vk::AccessFlagBits::eColorAttachmentWrite; + dstAccess |= vk::AccessFlagBits::eColorAttachmentRead; + } + if (colorWrite & (1 << i)) + { + srcStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; + dstStage |= vk::PipelineStageFlagBits::eColorAttachmentOutput; + srcAccess |= vk::AccessFlagBits::eColorAttachmentWrite; + dstAccess |= vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead; + } + if (depthRead & (1 << i)) + { + srcStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests; + dstStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests; + srcAccess |= vk::AccessFlagBits::eDepthStencilAttachmentWrite; + dstAccess |= vk::AccessFlagBits::eDepthStencilAttachmentRead; + } + if (depthWrite & (1 << i)) + { + srcStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests; + dstStage |= vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests; + srcAccess |= vk::AccessFlagBits::eDepthStencilAttachmentWrite; + dstAccess |= vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite; + } + if (inputDependencies & (1 << i)) + { + dstStage |= vk::PipelineStageFlagBits::eFragmentShader; + dstAccess |= vk::AccessFlagBits::eInputAttachmentRead; + } + + //// If subpass of first renderpass, stage flag should be bottom of pipe + //if (&node == &nodes.front() && i == 0) + // srcStage = vk::PipelineStageFlagBits::eBottomOfPipe; + + //// If subpass of last renderpass, stage flag should be bottom of pipe + //if (&node == &nodes.back() && i == subpasses.size() - 1) + // dstStage = vk::PipelineStageFlagBits::eTopOfPipe; + + dep.srcStageMask = srcStage; + dep.dstStageMask = dstStage; + dep.srcAccessMask = srcAccess; + dep.dstAccessMask = dstAccess; + + dep.srcStageMask = srcStage; + + // initialize input descriptors + subpasses[i]->CreateInputDescriptors(); + } + } + /***************************************************************************/ /*! @@ -238,7 +388,7 @@ namespace SHADE */ /***************************************************************************/ - Handle SHRenderGraphNode::AddSubpass(std::string subpassName) noexcept + Handle SHRenderGraphNode::AddSubpass(std::string subpassName, Handle viewport, Handle renderer) noexcept { // if subpass already exists, don't add. if (subpassIndexing.contains(subpassName)) @@ -253,6 +403,8 @@ namespace SHADE graphStorage->resourceHub->Create ( subpassName, + viewport, + renderer, graphStorage, GetHandle(), static_cast(subpasses.size()), resourceAttachmentMapping.get() ) @@ -318,7 +470,7 @@ namespace SHADE } // insert them all for a subpass to transition them. This subpass is the last subpass - auto dummySubpass = AddSubpass("dummy"); + auto dummySubpass = AddSubpass("dummy", {}, {}); for (auto& resource : resourcesInvolved) { dummySubpass->AddGeneralInput(resource); @@ -331,7 +483,59 @@ namespace SHADE } } - void SHRenderGraphNode::Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept + /***************************************************************************/ + /*! + + \brief + For detaching attachments from the node. The node would need to be + rebuilt but it won't be done in this function. This function just removes + any footprint of the resource in the class. + + \param resourceHandleID + The handle ID of the resource. + + */ + /***************************************************************************/ + bool SHRenderGraphNode::DetachResource(std::string const& resourceName, uint64_t resourceHandleID) noexcept + { + if (resourceAttachmentMapping->contains(resourceHandleID)) + { + // Get attachment index in the node's attachment container + auto index = resourceAttachmentMapping->at(resourceHandleID); + + // remove attachment from the list of attachments + attResources.erase (attResources.begin() + index); + + // remove attachment reference + attachmentDescriptions.erase (attachmentDescriptions.begin() + index); + + // Remove footprint of attachment from all subpasses as well + for (auto it = subpasses.begin(); it != subpasses.end(); ++it) + { + // attempt to detach resource from subpass + (*it)->DetachResource(resourceName, index); + + // If the subpass ends up having no attachments after, erase it from the node + if ((*it)->HasNoAttachments()) + { + // erase from indexing + subpassIndexing.erase((*it)->GetName()); + + // erase from container of subpasses. + it = subpasses.erase(it); + } + } + + // give existing subpasses new indices + for (uint32_t i = 0; i < subpasses.size(); ++i) + subpasses[i]->SetIndex(i); + + return true; + } + return false; + } + + void SHRenderGraphNode::Execute(Handle commandBuffer, Handle descPool, uint32_t frameIndex) noexcept { uint32_t framebufferIndex = (framebuffers.size() > 1) ? frameIndex : 0; commandBuffer->BeginRenderpass(renderpass, framebuffers[framebufferIndex]); @@ -347,12 +551,23 @@ namespace SHADE 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 SHRenderGraphNode::GetOrCreatePipeline(std::pair, Handle> const& vsFsPair, Handle subpass) noexcept diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h index 775d64f7..a581d21c 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h @@ -19,9 +19,11 @@ namespace SHADE class SHVkLogicalDevice; class SHVkRenderpass; class SHVkDescriptorPool; - class SHGraphicsGlobalData; + class SHGraphicsPredefinedData; class SHRenderGraphStorage; class SHRenderGraphNodeCompute; + class SHRenderer; + class SHViewport; class SH_API SHRenderGraphNode : public ISelfHandle { @@ -53,7 +55,7 @@ namespace SHADE //! Vector of subpasses std::vector> subpasses; - //! Descriptions to pass to renderpass for renderpass creation. We want to keep this here because + //! Descriptions to pass to renderpass for renderpass creation. std::vector spDescs; //! Subpass dependencies for renderpass creation @@ -90,6 +92,7 @@ namespace SHADE void CreateRenderpass(void) noexcept; void CreateFramebuffer(void) noexcept; void HandleResize (void) noexcept; + void ConfigureSubpasses (void) noexcept; public: /*-----------------------------------------------------------------------*/ @@ -102,12 +105,13 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* PUBLIC MEMBER FUNCTIONS */ /*-----------------------------------------------------------------------*/ - Handle AddSubpass(std::string subpassName) noexcept; + Handle AddSubpass(std::string subpassName, Handle viewport, Handle renderer) noexcept; Handle AddNodeCompute(std::string nodeName, Handle computeShaderModule, std::initializer_list resources, std::unordered_set&& dynamicBufferBindings = {}, float numWorkGroupScale = 1.0f) noexcept; void AddDummySubpassIfNeeded (void) noexcept; + bool DetachResource (std::string const& resourceName, uint64_t resourceHandleID) noexcept; // TODO: RemoveSubpass() - void Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; + void Execute(Handle commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; Handle GetOrCreatePipeline(std::pair, Handle> const& vsFsPair, Handle subpass) noexcept; void FinaliseBatch(uint32_t frameIndex, Handle descPool); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp index 2f8fd968..cfc8443c 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.cpp @@ -6,10 +6,11 @@ #include "Graphics/Descriptors/SHVkDescriptorSetLayout.h" #include "Graphics/Devices/SHVkLogicalDevice.h" #include "Graphics/Pipeline/SHVkPipelineLayout.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" #include "SHRenderGraphStorage.h" #include "SHRenderGraphResource.h" #include "Graphics/Commands/SHVkCommandBuffer.h" +#include "Graphics/MiddleEnd/Interface/SHRenderer.h" namespace SHADE { @@ -23,11 +24,12 @@ namespace SHADE , numWorkGroupScale {std::clamp(inNumWorkGroupScale, 0.0f, 1.0f)} , computeResource{} , name { std::move(nodeName) } + , renderer{ } { SHPipelineLayoutParams pipelineLayoutParams { .shaderModules = {computeShaderModule}, - .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts(), + .predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE).descSetLayouts, .dynamicBufferBindings = std::move(dynamicBufferBindings), }; @@ -45,10 +47,13 @@ namespace SHADE // save the resources resources = std::move (subpassComputeResources); + auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE); + auto const& layouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline(); - //Get the descriptor set layouts required to allocate. We only want the ones for allocate because - //global descriptors are already bound in the main system. - auto const& graphResourceLayout = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline()[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE]; + + //Get the descriptor set layouts required to allocate. We only want the ones for allocate because + //global descriptors are already bound in the main system. + auto const& graphResourceLayout = layouts[descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE)]; // Allocate descriptor sets to hold the images for reading (STORAGE_IMAGE) for (uint32_t i = 0; i < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++i) @@ -60,14 +65,12 @@ namespace SHADE #endif } - - auto const& layouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline(); - - if (layouts.size() == SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE + 1) + // check if all layouts are there + if (layouts.size() == descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE) + 1) { // create compute resources computeResource = graphStorage->resourceHub->Create(); - auto computeResourceLayout = layouts[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE]; + auto computeResourceLayout = layouts[descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE)]; computeResource->descSet = graphStorage->descriptorPool->Allocate({ computeResourceLayout }, { 1 }); #ifdef _DEBUG for (auto set : computeResource->descSet->GetVkHandle()) @@ -91,14 +94,22 @@ namespace SHADE // bind the compute pipeline cmdBuffer->BindPipeline(computePipeline); - // bind descriptor sets - cmdBuffer->BindDescriptorSet(graphResourceDescSets[frameIndex], SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, {}); + auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE); + + // bind render graph resource + cmdBuffer->BindDescriptorSet(graphResourceDescSets[frameIndex], SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE), {}); + + // bind compute resource if (computeResource) { - cmdBuffer->BindDescriptorSet(computeResource->descSet, SH_PIPELINE_TYPE::COMPUTE, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_NODE_COMPUTE_RESOURCE, computeResource->dynamicOffsets[frameIndex]); + cmdBuffer->BindDescriptorSet(computeResource->descSet, SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_NODE_COMPUTE_RESOURCE), computeResource->dynamicOffsets[frameIndex]); } + // bind camera data + if (renderer) + renderer->BindDescriptorSet (cmdBuffer, SH_PIPELINE_TYPE::COMPUTE, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex); + // dispatch compute cmdBuffer->ComputeDispatch(groupSizeX, groupSizeY, 1); @@ -109,8 +120,14 @@ namespace SHADE void SHRenderGraphNodeCompute::HandleResize(void) noexcept { + // We need to get from mappings because we want the introspected layout from the vector of layouts (of which the first few are predefined) + uint32_t RENDER_GRAPH_RESOURCE_SET_INDEX = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::RENDER_GRAPH_NODE_COMPUTE).at (SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE); + + // Since the descriptor set is standalone, the index we want to use is not the one in the shaders, it should always be 0. + uint32_t RENDER_GRAPH_RESOURCE_UPDATE_SET_INDEX = 0; + // Get the layout for the render graph resource. We can index it this way because the container returned is a container of layouts that includes the global ones - auto pipelineDescSetLayouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline()[SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE]; + auto pipelineDescSetLayouts = computePipeline->GetPipelineLayout()->GetDescriptorSetLayoutsPipeline()[RENDER_GRAPH_RESOURCE_SET_INDEX]; // everything below here needs resizing for (uint32_t frameIndex = 0; frameIndex < SHGraphicsConstants::NUM_FRAME_BUFFERS; ++frameIndex) @@ -123,8 +140,8 @@ namespace SHADE uint32_t imageIndex = (resources[i]->resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) ? frameIndex : 0; SHVkDescriptorSetGroup::viewSamplerLayout vsl = std::make_tuple(resources[i]->GetImageView(imageIndex), Handle{}, vk::ImageLayout::eGeneral); - graphResourceDescSets[frameIndex]->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, { &vsl, 1 }); - graphResourceDescSets[frameIndex]->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint); + graphResourceDescSets[frameIndex]->ModifyWriteDescImage(RENDER_GRAPH_RESOURCE_UPDATE_SET_INDEX, binding.BindPoint, { &vsl, 1 }); + graphResourceDescSets[frameIndex]->UpdateDescriptorSetImages(RENDER_GRAPH_RESOURCE_UPDATE_SET_INDEX, binding.BindPoint); ++i; } } @@ -181,16 +198,24 @@ namespace SHADE } } - void SHRenderGraphNodeCompute::ModifyWriteDescBufferComputeResource(uint32_t set, uint32_t binding, std::span> const& buffers, uint32_t offset, uint32_t range) noexcept + void SHRenderGraphNodeCompute::SetRenderer(Handle inRenderer) noexcept { - computeResource->descSet->ModifyWriteDescBuffer(set, binding, buffers, offset, range); - computeResource->descSet->UpdateDescriptorSetBuffer(set, binding); + renderer = inRenderer; } - void SHRenderGraphNodeCompute::ModifyWriteDescImageComputeResource(uint32_t set, uint32_t binding, std::span const& viewSamplerLayouts) noexcept + void SHRenderGraphNodeCompute::ModifyWriteDescBufferComputeResource(uint32_t binding, std::span> const& buffers, uint32_t offset, uint32_t range) noexcept { - computeResource->descSet->ModifyWriteDescImage(set, binding, viewSamplerLayouts); - computeResource->descSet->UpdateDescriptorSetImages(set, binding); + static constexpr uint32_t COMPUTE_RESOURCE_SET_INDEX = 0; + + computeResource->descSet->ModifyWriteDescBuffer(COMPUTE_RESOURCE_SET_INDEX, binding, buffers, offset, range); + computeResource->descSet->UpdateDescriptorSetBuffer(COMPUTE_RESOURCE_SET_INDEX, binding); + } + + void SHRenderGraphNodeCompute::ModifyWriteDescImageComputeResource(uint32_t binding, std::span const& viewSamplerLayouts) noexcept + { + static constexpr uint32_t COMPUTE_RESOURCE_SET_INDEX = 0; + computeResource->descSet->ModifyWriteDescImage(COMPUTE_RESOURCE_SET_INDEX, binding, viewSamplerLayouts); + computeResource->descSet->UpdateDescriptorSetImages(COMPUTE_RESOURCE_SET_INDEX, binding); } diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h index 580f018c..dc3ca886 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNodeCompute.h @@ -7,6 +7,7 @@ #include #include #include +#include "Resource/SHHandle.h" namespace SHADE { @@ -19,6 +20,7 @@ namespace SHADE class SHVkShaderModule; class SHVkCommandBuffer; class SHVkBuffer; + class SHRenderer; class SHRenderGraphNodeCompute @@ -53,6 +55,9 @@ namespace SHADE //! vector of resources needed by the subpass compute std::vector> resources; + //! For binding optional camera data to the post compute + Handle renderer; + //! X dimension work group size. Should scale with resource size. uint32_t groupSizeX; @@ -75,9 +80,10 @@ namespace SHADE void HandleResize (void) noexcept; void SetDynamicOffsets (std::span perFrameSizes) noexcept; + void SetRenderer (Handle inRenderer) noexcept; - void ModifyWriteDescBufferComputeResource (uint32_t set, uint32_t binding, std::span> const& buffers, uint32_t offset, uint32_t range) noexcept; - void ModifyWriteDescImageComputeResource(uint32_t set, uint32_t binding, std::span const& viewSamplerLayouts) noexcept; + void ModifyWriteDescBufferComputeResource (uint32_t binding, std::span> const& buffers, uint32_t offset, uint32_t range) noexcept; + void ModifyWriteDescImageComputeResource(uint32_t binding, std::span const& viewSamplerLayouts) noexcept; friend class SHRenderGraph; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp index ce7e1622..5a34fa04 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp @@ -262,11 +262,13 @@ namespace SHADE void SHRenderGraphResource::HandleResize(uint32_t newWidth, uint32_t newHeight) noexcept { - width = newWidth; - height = newHeight; if ((resourceTypeFlags & static_cast(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) == 0) { + width = newWidth; + height = newHeight; + + // prepare image view details SHImageViewDetails viewDetails { @@ -287,6 +289,9 @@ namespace SHADE } else { + width = graphStorage->swapchain->GetWidth(); + height = graphStorage->swapchain->GetHeight(); + // Prepare image view details SHImageViewDetails viewDetails { diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h index d02d8d39..b0cd40bc 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphStorage.h @@ -7,7 +7,7 @@ namespace SHADE { class SHVkLogicalDevice; class SHVkSwapchain; - class SHGraphicsGlobalData; + class SHGraphicsPredefinedData; class SHVkDescriptorPool; class SHRenderGraphResource; diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderToSwapchainImageSystem.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderToSwapchainImageSystem.cpp index 770217ee..80260b7b 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderToSwapchainImageSystem.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderToSwapchainImageSystem.cpp @@ -1,7 +1,7 @@ #include "SHpch.h" #include "SHRenderToSwapchainImageSystem.h" #include "Graphics/Devices/SHVkLogicalDevice.h" -#include "Graphics/MiddleEnd/GlobalData/SHGraphicsGlobalData.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" #include "Graphics/RenderGraph/SHRenderGraphNode.h" #include "Graphics/RenderGraph/SHSubpass.h" #include "Graphics/SHVkUtil.h" @@ -24,7 +24,7 @@ namespace SHADE auto pipelineLayout = logicalDevice->CreatePipelineLayout(SHPipelineLayoutParams { .shaderModules = {shaderModules.first, shaderModules.second}, - .globalDescSetLayouts = SHGraphicsGlobalData::GetDescSetLayouts(), + .predefinedDescSetLayouts = {} }); pipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderGraphNode->GetRenderpass(), subpass); diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp index c1d53632..3d2b1699 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp @@ -11,6 +11,9 @@ #include "Graphics/Swapchain/SHVkSwapchain.h" #include "Graphics/Images/SHVkSampler.h" #include "SHRenderGraphResource.h" +#include "Graphics/MiddleEnd/Interface/SHViewport.h" +#include "Graphics/MiddleEnd/Interface/SHRenderer.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" namespace SHADE { @@ -30,7 +33,7 @@ namespace SHADE */ /***************************************************************************/ - SHSubpass::SHSubpass(const std::string& name, Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping) noexcept + SHSubpass::SHSubpass(const std::string& name, Handle inViewport, Handle inRenderer, Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping) noexcept : resourceAttachmentMapping{ mapping } , parentNode{ parent } , subpassIndex{ index } @@ -41,6 +44,8 @@ namespace SHADE , name { name } , graphStorage{ renderGraphStorage } , inputImageDescriptorSets{} + , viewport {inViewport} + , renderer {inRenderer} { } @@ -63,7 +68,6 @@ namespace SHADE , depthReferences{ std::move(rhs.depthReferences) } , inputReferences{ std::move(rhs.inputReferences) } , resourceAttachmentMapping{ rhs.resourceAttachmentMapping } - , descriptorSetLayout{ rhs.descriptorSetLayout } , exteriorDrawCalls{ std::move(rhs.exteriorDrawCalls) } , graphStorage{ rhs.graphStorage } , inputNames{ std::move(rhs.inputNames) } @@ -71,6 +75,8 @@ namespace SHADE , inputDescriptorLayout{ rhs.inputDescriptorLayout } , inputSamplers{ rhs.inputSamplers } , name { rhs.name } + , viewport {rhs.viewport} + , renderer {rhs.renderer} { } @@ -98,7 +104,6 @@ namespace SHADE depthReferences = std::move(rhs.depthReferences); inputReferences = std::move(rhs.inputReferences); resourceAttachmentMapping = std::move(rhs.resourceAttachmentMapping); - descriptorSetLayout = rhs.descriptorSetLayout; exteriorDrawCalls = std::move(rhs.exteriorDrawCalls); graphStorage = rhs.graphStorage; inputNames = std::move(rhs.inputNames); @@ -106,6 +111,9 @@ namespace SHADE inputDescriptorLayout = rhs.inputDescriptorLayout; inputSamplers = rhs.inputSamplers; name = std::move(rhs.name); + renderer = rhs.renderer; + viewport = rhs.viewport; + return *this; } @@ -199,21 +207,33 @@ namespace SHADE inputReferences.push_back({ resourceAttachmentMapping->at(graphStorage->graphResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eGeneral }); } - void SHSubpass::Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept + void SHSubpass::Execute(Handle commandBuffer, Handle descPool, uint32_t frameIndex) noexcept { commandBuffer->BeginLabeledSegment(name); - // Ensure correct transforms are provided superBatch->UpdateBuffers(frameIndex, descPool); + if (viewport) + { + // set viewport and scissor + uint32_t w = static_cast(viewport->GetWidth()); + uint32_t h = static_cast(viewport->GetHeight()); + commandBuffer->SetViewportScissor(static_cast(w), static_cast(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); + // Draw all the batches superBatch->Draw(commandBuffer, frameIndex); // Draw all the exterior draw calls for (auto& drawCall : exteriorDrawCalls) { - drawCall(commandBuffer, frameIndex); + drawCall(commandBuffer, renderer, frameIndex); } commandBuffer->EndLabeledSegment(); } @@ -223,15 +243,73 @@ namespace SHADE UpdateWriteDescriptors(); } - void SHSubpass::BindDescriptorInputDescriptorSets(Handle cmdBuffer, uint32_t frameIndex) const noexcept + void SHSubpass::BindInputDescriptorSets(Handle cmdBuffer, uint32_t setIndex, uint32_t frameIndex) const noexcept { if (!inputImageDescriptorSets.empty()) { - cmdBuffer->BindDescriptorSet(inputImageDescriptorSets[frameIndex], SH_PIPELINE_TYPE::GRAPHICS, SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, { }); + cmdBuffer->BindDescriptorSet(inputImageDescriptorSets[frameIndex], SH_PIPELINE_TYPE::GRAPHICS, setIndex, { }); } } - void SHSubpass::AddExteriorDrawCalls(std::function&, uint32_t)> const& newDrawCall) noexcept + /***************************************************************************/ + /*! + + \brief + Removes all footprints of a resource in the subpass. + + \param resourceName + Name of resource. + + \param attachmentIndex + index of attachment. + + */ + /***************************************************************************/ + void SHSubpass::DetachResource(std::string const& resourceName, uint32_t attachmentIndex) noexcept + { + for (uint32_t i = 0; i < colorReferences.size(); ++i) + { + if (colorReferences[i].attachment == attachmentIndex) + { + colorReferences.erase (colorReferences.begin() + i); + break; + } + } + + for (uint32_t i = 0; i < depthReferences.size(); ++i) + { + if (depthReferences[i].attachment == attachmentIndex) + { + depthReferences.erase(depthReferences.begin() + i); + break; + } + } + + for (uint32_t i = 0; i < inputReferences.size(); ++i) + { + if (inputReferences[i].attachment == attachmentIndex) + { + inputReferences.erase(inputReferences.begin() + i); + break; + } + } + + for (uint32_t i = 0; i < inputNames.size(); ++i) + { + if (inputNames[i] == resourceName) + { + inputNames.erase(inputNames.begin() + i); + break; + } + } + } + + bool SHSubpass::HasNoAttachments(void) const noexcept + { + return colorReferences.empty() && depthReferences.empty() && inputReferences.empty(); + } + + void SHSubpass::AddExteriorDrawCalls(ExteriorDrawCallFunction const& newDrawCall) noexcept { exteriorDrawCalls.push_back(newDrawCall); } @@ -247,6 +325,21 @@ namespace SHADE if (inputNames.empty()) return; + for (auto& set : inputImageDescriptorSets) + { + if (set) + set.Free(); + } + + if (inputDescriptorLayout) + inputDescriptorLayout.Free(); + + for (auto& sampler : inputSamplers) + { + if (sampler) + sampler.Free(); + } + inputImageDescriptorSets.resize(SHGraphicsConstants::NUM_FRAME_BUFFERS); std::vector bindings{}; @@ -266,7 +359,7 @@ namespace SHADE } // We build a new descriptor set layout to store our images - inputDescriptorLayout = graphStorage->logicalDevice->CreateDescriptorSetLayout(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, bindings); + inputDescriptorLayout = graphStorage->logicalDevice->CreateDescriptorSetLayout(bindings); // we store a sampler if its an input attachment. if it is storage image, no need sampler, store an empty handle. for (uint32_t i = 0; i < bindings.size(); ++i) @@ -334,66 +427,36 @@ namespace SHADE // Update descriptor sets auto args = std::make_tuple(resource->GetImageView(viewIndex), inputSamplers[i], descriptorLayout); - group->ModifyWriteDescImage(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint, std::span{&args, 1}); - group->UpdateDescriptorSetImages(SHGraphicsConstants::DescriptorSetIndex::RENDERGRAPH_RESOURCE, binding.BindPoint); + + + // Since the descriptor set is standalone, the index we want to use is not the one in the shaders, it should always be 0. + uint32_t RENDER_GRAPH_RESOURCE_SET_INDEX = 0; + + group->ModifyWriteDescImage(RENDER_GRAPH_RESOURCE_SET_INDEX, binding.BindPoint, std::span{&args, 1}); + group->UpdateDescriptorSetImages(RENDER_GRAPH_RESOURCE_SET_INDEX, binding.BindPoint); } ++i; } } - //void SHSubpass::InitComputeBarriers(void) noexcept - //{ - // std::unordered_set handleBarriers{}; - - // // we will have swapchainNumImages vectors of vector of barriers - // subpassComputeBarriers.resize(graphStorage->swapchain->GetNumImages()); - - // for (auto sbCompute : subpassComputes) - // { - // // for every resource the subpass compute is using - // for (auto resource : sbCompute->resources) - // { - // // Get the resource handle - // uint64_t resourceRaw = resource.GetId().Raw; - - // // if the barrier is not registered - // if (!handleBarriers.contains(resourceRaw)) - // { - // // If the resource is a swapchain image - // bool isSwapchainImage = (resource->resourceTypeFlags & static_cast(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)); - // for (uint32_t i = 0; i < graphStorage->swapchain->GetNumImages(); ++i) - // { - // // if swapchain image, we want the index of the swapchain image, if not take base image - // uint32_t imageIndex = isSwapchainImage ? i : 0; - - // // Prepare image barrier - // vk::ImageMemoryBarrier imageBarrier - // { - // .oldLayout = colorReferences[resourceAttachmentMapping->at(resource.GetId().Raw)].layout, - // .newLayout = vk::ImageLayout::eGeneral, - // .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - // .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - // .image = resource->GetImage(imageIndex)->GetVkImage(), - // .subresourceRange = - // { - // .aspectMask = resource->imageAspectFlags, - // .levelCount = resource->GetMipLevels(), - // .baseArrayLayer = 0, - // .layerCount = 1 - // } - // }; - - // // push the barrier - // subpassComputeBarriers[i].push_back(imageBarrier); - // } - - // // Image transition registered - // handleBarriers.emplace(resourceRaw); - // } - // } - // } - //} + /***************************************************************************/ + /*! + + \brief + This function is mainly used for the purposes of giving a subpass a new + index in the case another subpass in the node gets deleted, and subpasses + need to be re-indexed. + + \param index + New index of the subpass. + + */ + /***************************************************************************/ + void SHSubpass::SetIndex(uint32_t index) noexcept + { + subpassIndex = index; + } /***************************************************************************/ /*! diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h index 69b8fd56..6c582aa6 100644 --- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h +++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h @@ -19,15 +19,28 @@ namespace SHADE class SHRenderGraphStorage; class SHVkShaderModule; class SHVkSampler; + class SHRenderer; + class SHViewport; class SH_API SHSubpass : public ISelfHandle { + public: + using ExteriorDrawCallFunction = std::function, Handle, uint32_t)>; + private: /*---------------------------------------------------------------------*/ /* PRIVATE MEMBER VARIABLES */ /*---------------------------------------------------------------------*/ Handle graphStorage; + //! Viewport to specify what part of the screen we want to draw on. This + //! will be used in vkCmdSetViewport/Scissor. + Handle viewport; + + //! Renderer used during the subpass execution. This dictates what matrix gets + //! passed to the shaders. + Handle renderer; + //! The index of the subpass in the render graph uint32_t subpassIndex; @@ -37,9 +50,6 @@ namespace SHADE //! Handle superBatch; - //! Descriptor set layout to hold attachments - Handle descriptorSetLayout; - //! Color attachments std::vector colorReferences; @@ -79,8 +89,9 @@ namespace SHADE //! after we draw everything from the batch. Because of this, these draw calls //! are always the last things drawn, so DO NOT USE THIS FUNCTIONALITY FOR ANYTHING //! COMPLEX. - std::vector&, uint32_t)>> exteriorDrawCalls; - /// For identifying subpasses + std::vector exteriorDrawCalls; + + // For identifying subpasses std::string name; @@ -88,7 +99,7 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* CTORS AND DTORS */ /*-----------------------------------------------------------------------*/ - SHSubpass(const std::string& name, Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping) noexcept; + SHSubpass(const std::string& name, Handle inViewport, Handle inRenderer, Handle renderGraphStorage, Handle const& parent, uint32_t index, std::unordered_map const* mapping) noexcept; SHSubpass(SHSubpass&& rhs) noexcept; SHSubpass& operator=(SHSubpass&& rhs) noexcept; @@ -102,12 +113,14 @@ namespace SHADE void AddGeneralDepthOutput(std::string resourceToReference) noexcept; void AddInput(std::string resourceToReference) noexcept; void AddGeneralInput (std::string resourceToReference) noexcept; - void AddExteriorDrawCalls(std::function&, uint32_t)> const& newDrawCall) noexcept; + void AddExteriorDrawCalls(ExteriorDrawCallFunction const& newDrawCall) noexcept; // Runtime functions - void Execute(Handle& commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; + void Execute(Handle commandBuffer, Handle descPool, uint32_t frameIndex) noexcept; void HandleResize (void) noexcept; - void BindDescriptorInputDescriptorSets (Handle cmdBuffer, uint32_t frameIndex) const noexcept; + void BindInputDescriptorSets (Handle cmdBuffer, uint32_t setIndex, uint32_t frameIndex) const noexcept; + void DetachResource (std::string const& resourceName, uint32_t attachmentIndex) noexcept; + bool HasNoAttachments (void) const noexcept; void Init(SHResourceHub& resourceManager) noexcept; @@ -118,6 +131,10 @@ namespace SHADE /*-----------------------------------------------------------------------*/ /* GETTERS AND SETTERS */ /*-----------------------------------------------------------------------*/ + private: + void SetIndex (uint32_t index) noexcept; + + public: Handle const& GetParentNode(void) const noexcept; SHSubPassIndex GetIndex() const noexcept; Handle GetSuperBatch(void) const noexcept; diff --git a/SHADE_Engine/src/Graphics/Swapchain/SHVkSwapchain.cpp b/SHADE_Engine/src/Graphics/Swapchain/SHVkSwapchain.cpp index 40f917a0..eab4a03d 100644 --- a/SHADE_Engine/src/Graphics/Swapchain/SHVkSwapchain.cpp +++ b/SHADE_Engine/src/Graphics/Swapchain/SHVkSwapchain.cpp @@ -347,4 +347,14 @@ namespace SHADE return vkDepthFormat; } + uint32_t SHVkSwapchain::GetWidth(void) const noexcept + { + return width; + } + + uint32_t SHVkSwapchain::GetHeight(void) const noexcept + { + return height; + } + } \ No newline at end of file diff --git a/SHADE_Engine/src/Graphics/Swapchain/SHVkSwapchain.h b/SHADE_Engine/src/Graphics/Swapchain/SHVkSwapchain.h index 384665d3..f3f51423 100644 --- a/SHADE_Engine/src/Graphics/Swapchain/SHVkSwapchain.h +++ b/SHADE_Engine/src/Graphics/Swapchain/SHVkSwapchain.h @@ -101,6 +101,8 @@ namespace SHADE vk::SwapchainKHR const& GetVkSwapchain (void) const noexcept; vk::SurfaceFormatKHR GetSurfaceFormatKHR (void) const noexcept; vk::Format GetDepthFormat (void) const noexcept; + uint32_t GetWidth (void) const noexcept; + uint32_t GetHeight (void) const noexcept; }; } diff --git a/SHADE_Engine/src/Input/SHInputManager.cpp b/SHADE_Engine/src/Input/SHInputManager.cpp index 4849a772..cec78648 100644 --- a/SHADE_Engine/src/Input/SHInputManager.cpp +++ b/SHADE_Engine/src/Input/SHInputManager.cpp @@ -105,12 +105,12 @@ namespace SHADE //Write to lastKeys memcpy(keysLast, keys, sizeof(keys)); - //Poll + //Poll KB/M unsigned char keyboardState[MAX_KEYS] = {}; SecureZeroMemory(keyboardState, sizeof(keyboardState)); //if (GetKeyboardState(keyboardState) == false) return; bool keyboardStateGot = GetKeyboardState(keyboardState); - SHASSERT(keyboardStateGot, "SHInputManager:GetKeyboardState() failed ({})", GetLastError()); + SHASSERT(keyboardStateGot, "SHInputManager::GetKeyboardState() failed ({})", GetLastError()); keyCount = 0; keyToggleCount = 0; for (size_t i = 0; i < MAX_KEYS; ++i) @@ -159,7 +159,7 @@ namespace SHADE } } - //Mouse Positioning///////////////////////////////////// + //Mouse Positioning///////////////////////////////////////////////////////// //https://stackoverflow.com/a/6423739 //Set last positioning @@ -181,7 +181,7 @@ namespace SHADE mouseWheelVerticalDelta = mouseWheelVerticalDeltaPoll; mouseWheelVerticalDeltaPoll = 0; - //Controllers////////////////////////////////////////////////////////////// + //Controllers/////////////////////////////////////////////////////////////// controllersConnectedCount = 0; @@ -447,6 +447,200 @@ namespace SHADE } } } + + //Bindings////////////////////////////////////////////////////////////////// + for (auto& binding : bindings) + { + SHLogicalBindingData& data = binding.second; + + //Set last value + data.positiveInputHeldLast = data.positiveInputHeld; + data.negativeInputHeldLast = data.negativeInputHeld; + + //Reset held values + data.positiveInputHeld = false; + data.negativeInputHeld = false; + + if (data.bindingType == SHInputManager::SH_BINDINGTYPE::MOUSE_X) + { + double velX = 0.0; + GetMouseVelocity(&velX, nullptr); + if (data.value > 0.0) data.positiveInputHeld = true; + else if (data.value < 0.0) data.negativeInputHeld = true; + data.value = velX * data.sensitivity * (data.inverted ? -1.0 : 1.0); + } + else if (data.bindingType == SHInputManager::SH_BINDINGTYPE::MOUSE_Y) + { + double velY = 0.0; + GetMouseVelocity(nullptr, &velY); + if (data.value > 0.0) data.positiveInputHeld = true; + else if (data.value < 0.0) data.negativeInputHeld = true; + data.value = velY * data.sensitivity * (data.inverted ? -1.0 : 1.0); + } + else if (data.bindingType == SHInputManager::SH_BINDINGTYPE::MOUSE_SCROLL) + { + if (mouseWheelVerticalDelta > 0.0) data.positiveInputHeld = true; + else if (mouseWheelVerticalDelta < 0.0) data.negativeInputHeld = true; + data.value = mouseWheelVerticalDelta * data.sensitivity * (data.inverted ? -1.0 : 1.0); + } + else if (data.bindingType == SHInputManager::SH_BINDINGTYPE::KB_MB_CONTROLLER) + { + //Prioritise the largest magnitude + double largestMagnitude = 0.0; + + //If digital input was in, use sensitivity + bool digitalInput = false; + + //Over keycodes + for (SH_KEYCODE k : data.positiveKeyCodes) + { + if (GetKey(k)) + { + if (std::abs(1.0) > std::abs(largestMagnitude)) largestMagnitude = 1.0 * (data.inverted ? -1.0 : 1.0); + digitalInput = true; + data.positiveInputHeld = true; + } + } + for (SH_KEYCODE k : data.negativeKeyCodes) + { + if (GetKey(k)) + { + if (std::abs(-1.0) > std::abs(largestMagnitude)) largestMagnitude = -1.0 * (data.inverted ? -1.0 : 1.0); + digitalInput = true; + data.negativeInputHeld = true; + } + } + + //Over controllerCodes + for (SH_CONTROLLERCODE c : data.positiveControllerCodes) + { + double newValue = 0.0; + GetControllerInput(c, &newValue); + if (std::abs(newValue) > std::abs(data.dead)) + { + data.positiveInputHeld = true; + if (static_cast(c) < NUM_CONTROLLER_BUTTON) + { + digitalInput = true; + } + if (std::abs(newValue) > std::abs(largestMagnitude)) + largestMagnitude = newValue * data.sensitivity * (data.inverted ? -1.0 : 1.0); + } + } + + for (SH_CONTROLLERCODE c : data.negativeControllerCodes) + { + double newValue = 0.0; + GetControllerInput(c, &newValue); + if (std::abs(newValue) > std::abs(data.dead)) + { + data.negativeInputHeld = true; + if (static_cast(c) < NUM_CONTROLLER_BUTTON) + { + digitalInput = true; + } + if (std::abs(newValue) > std::abs(largestMagnitude)) + largestMagnitude = -newValue * data.sensitivity * (data.inverted ? -1.0 : 1.0); + } + } + + //If both positive and negative inputs read, do not modify value + if (data.positiveInputHeld && data.negativeInputHeld) + { + data.value = data.value; + } + else + { + //If no data received, use gravity + if (!data.positiveInputHeld && !data.negativeInputHeld) + { + if (data.value > 0.0) + { + data.value -= data.gravity * dt; + if (data.value < 0.0) data.value = 0.0; + } + if (data.value < 0.0) + { + data.value += data.gravity * dt; + if (data.value > 0.0) data.value = 0.0; + } + } + else //Either positive OR negative input was read + { + //If digital input was in, + //sensitivity is used as a rate at which the axis value is changed + if (digitalInput) + { + //If the input is opposite the current value, gravity works + //with the sensitivity + if (data.value > 0.0 && largestMagnitude < 0.0) + data.value -= data.gravity * dt; + if (data.value < 0.0 && largestMagnitude > 0.0) + data.value += data.gravity * dt; + + //Moved by sensitivity + data.value += data.sensitivity * largestMagnitude * dt; + + if (data.value > 1.0) data.value = 1.0; + else if (data.value < -1.0) data.value = -1.0; + } + //If analog input was in, + //sensitivity is instead used as a multiplier + else + { + data.value = largestMagnitude * data.sensitivity; + 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.value > 0.0 && data.negativeInputHeld) + data.value = 0.0; + if (data.value < 0.0 && data.positiveInputHeld) + data.value = 0.0; + } + } + } + } + + //Binding timings + + //Positivie bindings + if (data.positiveInputHeld) //Input is down + { + if (!data.positiveInputHeldLast) //Input was just pressed + { + data.positiveHeldTime = 0.0; //Reset timer + } + data.positiveHeldTime += dt; //Tick up + } + else //Input is up + { + if (data.positiveInputHeldLast) //Input was just released + { + data.positiveReleasedTime = 0.0; //Reset timer + } + data.positiveReleasedTime += dt; //Tick up + } + + if (data.negativeInputHeld) //Input is down + { + if (!data.negativeInputHeldLast) //Input was just pressed + { + data.negativeHeldTime = 0.0; //Reset timer + } + data.negativeHeldTime += dt; //Tick up + } + else //Input is up + { + if (data.negativeInputHeldLast) //Input was just released + { + data.negativeReleasedTime = 0.0; //Reset timer + } + data.negativeReleasedTime += dt; //Tick up + } + } } bool SHInputManager::AnyKeyDown(SH_KEYCODE* firstDetected) noexcept @@ -574,40 +768,34 @@ namespace SHADE return false; } - //Only get of largest magnitude - double SHInputManager::GetBindingAxis(std::string bindingName, size_t cNum) noexcept + double SHInputManager::GetBindingAxis(std::string const& bindingName, size_t cNum) noexcept { - //Over keycodes, prioritise positive - for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes) - { - if (GetKey(k)) return 1.0; - } - for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes) - { - if (GetKey(k)) return -1.0; - } - - double largestMagnitude = 0.0; - - //Over controllerCodes - for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes) - { - double newValue = 0.0; - if (GetControllerInput(c, &newValue, nullptr, nullptr, cNum)) - if (std::abs(newValue) > std::abs(largestMagnitude)) largestMagnitude = newValue; - } - for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes) - { - double newValue = 0.0; - if (GetControllerInput(c, &newValue, nullptr, nullptr, cNum)) - if (std::abs(newValue) > std::abs(largestMagnitude)) largestMagnitude = -newValue; - } - - return largestMagnitude; + return bindings[bindingName].value; } - bool SHInputManager::GetBindingPositiveButton(std::string bindingName, size_t cNum) noexcept + double SHInputManager::GetBindingAxisRaw(std::string const& bindingName, size_t cNum) noexcept { + //Neutral if both positive and negative held + if (bindings[bindingName].positiveInputHeld && bindings[bindingName].negativeInputHeld) + { + return 0.0; + } + else if (bindings[bindingName].positiveInputHeld) + { + return 1.0; + } + else if (bindings[bindingName].negativeInputHeld) + { + return -1.0; + } + + //No input means neutral + return 0.0; + } + + bool SHInputManager::GetBindingPositiveButton(std::string const& bindingName, size_t cNum) noexcept + { + /* if (cNum >= XUSER_MAX_COUNT) return false; //Over keycodes @@ -622,11 +810,13 @@ namespace SHADE if (GetControllerInput(c, nullptr, nullptr, nullptr, cNum)) return true; } - return false; + return false;*/ + return bindings[bindingName].positiveInputHeld; } - bool SHInputManager::GetBindingNegativeButton(std::string bindingName, size_t cNum) noexcept + bool SHInputManager::GetBindingNegativeButton(std::string const& bindingName, size_t cNum) noexcept { + /* if (cNum >= XUSER_MAX_COUNT) return false; //Over keycodes @@ -641,11 +831,13 @@ namespace SHADE if (GetControllerInput(c, nullptr, nullptr, nullptr, cNum)) return true; } - return false; + return false;*/ + return bindings[bindingName].negativeInputHeld; } - bool SHInputManager::GetBindingPositiveButtonDown(std::string bindingName, size_t cNum) noexcept + bool SHInputManager::GetBindingPositiveButtonDown(std::string const& bindingName, size_t cNum) noexcept { + /* if (cNum >= XUSER_MAX_COUNT) return false; //Over keycodes @@ -660,11 +852,13 @@ namespace SHADE if (GetControllerInputDown(c, nullptr, cNum)) return true; } - return false; + return false;*/ + return (bindings[bindingName].positiveInputHeld && !bindings[bindingName].positiveInputHeldLast); } - bool SHInputManager::GetBindingNegativeButtonDown(std::string bindingName, size_t cNum) noexcept + bool SHInputManager::GetBindingNegativeButtonDown(std::string const& bindingName, size_t cNum) noexcept { + /* if (cNum >= XUSER_MAX_COUNT) return false; //Over keycodes @@ -679,11 +873,13 @@ namespace SHADE if (GetControllerInputDown(c, nullptr, cNum)) return true; } - return false; + return false;*/ + return (bindings[bindingName].negativeInputHeld && !bindings[bindingName].negativeInputHeldLast); } - bool SHInputManager::GetBindingPositiveButtonUp(std::string bindingName, size_t cNum) noexcept + bool SHInputManager::GetBindingPositiveButtonUp(std::string const& bindingName, size_t cNum) noexcept { + /* if (cNum >= XUSER_MAX_COUNT) return false; //Over keycodes @@ -698,11 +894,13 @@ namespace SHADE if (GetControllerInputUp(c, nullptr, cNum)) return true; } - return false; + return false;*/ + return (!bindings[bindingName].positiveInputHeld && bindings[bindingName].positiveInputHeldLast); } - bool SHInputManager::GetBindingNegativeButtonUp(std::string bindingName, size_t cNum) noexcept + bool SHInputManager::GetBindingNegativeButtonUp(std::string const& bindingName, size_t cNum) noexcept { + /* if (cNum >= XUSER_MAX_COUNT) return false; //Over keycodes @@ -717,107 +915,7 @@ namespace SHADE if (GetControllerInputUp(c, nullptr, cNum)) return true; } - return false; + return false;*/ + return (!bindings[bindingName].positiveInputHeld && bindings[bindingName].positiveInputHeldLast); } - - //Fetches longest hold time - double SHInputManager::GetBindingPositiveHeldTime(std::string bindingName, size_t cNum) noexcept - { - if (cNum >= XUSER_MAX_COUNT) return 0.0; - - double maxHeldTime = 0.0; - - //Over keycodes - for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes) - { - if (GetKeyHeldTime(k) > maxHeldTime) maxHeldTime = GetKeyHeldTime(k); - } - - //Over controller buttons - for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes) - { - if (GetControllerInputHeldTime(c, cNum) > maxHeldTime) maxHeldTime = GetControllerInputHeldTime(c); - } - - return maxHeldTime; - } - - double SHInputManager::GetBindingNegativeHeldTime(std::string bindingName, size_t cNum) noexcept - { - if (cNum >= XUSER_MAX_COUNT) return 0.0; - - double maxHeldTime = 0.0; - - //Over keycodes - for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes) - { - if (GetKeyHeldTime(k) > maxHeldTime) maxHeldTime = GetKeyHeldTime(k); - } - - //Over controller buttons - for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes) - { - if (GetControllerInputHeldTime(c, cNum) > maxHeldTime) maxHeldTime = GetControllerInputHeldTime(c); - } - - return maxHeldTime; - } - - //Fetches shortest release time - double SHInputManager::GetBindingPositiveReleasedTime(std::string bindingName, size_t cNum) noexcept - { - if (cNum >= XUSER_MAX_COUNT) return 0.0; - - double minReleaseTime = _HUGE_ENUF; - - //Over keycodes - for (SH_KEYCODE k : bindings[bindingName].positiveKeyCodes) - { - if (GetKeyReleasedTime(k) < minReleaseTime) minReleaseTime = GetKeyReleasedTime(k); - } - - //Over controller buttons - for (SH_CONTROLLERCODE c : bindings[bindingName].positiveControllerCodes) - { - if (GetControllerInputReleasedTime(c, cNum) < minReleaseTime) minReleaseTime = GetControllerInputReleasedTime(c); - } - - return minReleaseTime; - } - - double SHInputManager::GetBindingNegativeReleasedTime(std::string bindingName, size_t cNum) noexcept - { - if (cNum >= XUSER_MAX_COUNT) return 0.0; - - double minReleaseTime = _HUGE_ENUF; - - //Over keycodes - for (SH_KEYCODE k : bindings[bindingName].negativeKeyCodes) - { - if (GetKeyReleasedTime(k) < minReleaseTime) minReleaseTime = GetKeyReleasedTime(k); - } - - //Over controller buttons - for (SH_CONTROLLERCODE c : bindings[bindingName].negativeControllerCodes) - { - if (GetControllerInputReleasedTime(c, cNum) < minReleaseTime) minReleaseTime = GetControllerInputReleasedTime(c); - } - - return minReleaseTime; - } - - //Only for mouse movement - //Get largest delta - double SHInputManager::GetBindingMouseVelocity(std::string bindingName, size_t cNum) noexcept - { - if (cNum >= XUSER_MAX_COUNT) return 0.0; - - //Mouse velocity - double velX = 0.0; - double velY = 0.0; - GetMouseVelocity(&velX, &velY); - - return bindings[bindingName].mouseXPositiveMultiplier * velX + bindings[bindingName].mouseYPositiveMultiplier * velY; - } - } //namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Input/SHInputManager.h b/SHADE_Engine/src/Input/SHInputManager.h index 04e5871d..3f708124 100644 --- a/SHADE_Engine/src/Input/SHInputManager.h +++ b/SHADE_Engine/src/Input/SHInputManager.h @@ -300,12 +300,28 @@ namespace SHADE RIGHT_THUMBSTICK_Y }; + //BINDING TYPES/////////////////////////////////////////////////////////// + enum class SH_BINDINGTYPE + { + KB_MB_CONTROLLER, + MOUSE_X, + MOUSE_Y, + MOUSE_SCROLL + }; + private: /*------------------------------------------------------------------------*/ /* Struct for logical bindings */ /*------------------------------------------------------------------------*/ struct SH_API SHLogicalBindingData { + + + //BINDINGS//////////////////////////////////////////////////////////////// + + //The type of the binding + SH_BINDINGTYPE bindingType = SH_BINDINGTYPE::KB_MB_CONTROLLER; + //Key codes mapped to positive std::set positiveKeyCodes; @@ -318,9 +334,51 @@ namespace SHADE //Controller Codes mapped to negative std::set negativeControllerCodes; - //Mouse movement mapped to axes? - double mouseXPositiveMultiplier; - double mouseYPositiveMultiplier; + //VALUES////////////////////////////////////////////////////////////////// + + //The current value of the axis binding + double value = 0.0; + + bool positiveInputHeld = false; + bool negativeInputHeld = false; + + bool positiveInputHeldLast = false; + bool negativeInputHeldLast = false; + + //Whether the input is inverted, + //If so, positive bindings will make the value negative, + // negative bindings will make the value positive, + // moving the mouse up will make the value negative, + // scrolling the mousewheel up will make the value negative, + bool inverted = false; + + //When no input is present, how fast does the value fall back to neutral? + //Best to be non-negative + double gravity = 1.0; + + //How far the user needs to move an analog stick before application + //registers the movement + double dead = 0.2; + + //Speed in units per second that the axis will move toward target value for digital + //For mouse movement / scrolling, serves as multiplier + double sensitivity = 1.0; + + //If enabled, axis value will reset to zero when pressing a button + //that corresponds in the opposite direction + bool snap = false; + + //How long the positive binding has been held for + double positiveHeldTime = 0.0; + + //How long the positive binding has been released for + double positiveReleasedTime = 0.0; + + //How long the negative binding has been held for + double negativeHeldTime = 0.0; + + //How long the negative binding has been released for + double negativeReleasedTime = 0.0; }; public: @@ -350,6 +408,12 @@ namespace SHADE mouseWheelVerticalDeltaPoll += GET_WHEEL_DELTA_WPARAM(wParam); } + //Get if controller or KB/M is presently being used + static inline bool GetControllerInUse() noexcept + { + return controllerInUse; + } + //For testing purposes //static void PrintCurrentState() noexcept; @@ -484,7 +548,7 @@ namespace SHADE } /*------------------------------------------------------------------------*/ - /* Input state accessors (KB & M) */ + /* Input state accessors (Controller) */ /*------------------------------------------------------------------------*/ //How many controller inputs of any kind are being used now @@ -621,168 +685,347 @@ namespace SHADE /* Binding Functions */ /*------------------------------------------------------------------------*/ - //Add a new binding to the map - static inline void BindingsAdd(std::string newBindingName) noexcept + //Get a read-only map of the bindings + static inline std::map const& GetBindings() noexcept { - bindings.insert({ newBindingName, SHLogicalBindingData() }); + return bindings; } - //Remove a binding from the map - //Returns 1 if found and removed, 0 if not found - static inline size_t BindingsRemove(std::string targetBindingName) noexcept + //Add a new binding to the map with settings + //Binding type is between four different types, + //KB_MB_CONTROLLER Binding is connected to the keyboard, mouse and controller buttons and its analog inputs + //MOUSE_X Binding is connected to horizontal movement of the mouse + //MOUSE_Y Binding is connected to the vertical movement of the mouse + //MOUSE_SCROLL Binding is connected to the scrolling of the mouse wheel + //Inverted is whether positive inputs result in a negative value and vice-versa + //Snap is if inputting in the opposite direction results in the value snapping to 0 before continuing in the direction + //Sensitivity is how fast the value moves with input + //Dead is how much analogue input magnitude on a scale of 0 to 1 is required before being registered + //Gravity is how fast the value moves to neutral without input + static inline void AddBinding(std::string const& newBindingName, + SH_BINDINGTYPE const bindingType = SH_BINDINGTYPE::KB_MB_CONTROLLER, + bool const inverted = false, + bool const snap = false, + double const sensitivity = 1.0, + double const dead = 0.2, + double const gravity = 1.0) noexcept { - return bindings.erase(targetBindingName); + bindings.insert({ newBindingName, SHLogicalBindingData() }); + bindings[newBindingName].bindingType = bindingType; + bindings[newBindingName].inverted = inverted; + bindings[newBindingName].snap = snap; + bindings[newBindingName].sensitivity = sensitivity; + bindings[newBindingName].dead = dead; + bindings[newBindingName].gravity = gravity; + } + + //Remove a binding and all its associated inputs from the list + //Returns 1 if found and removed, 0 if not found + static inline size_t RemoveBinding(std::string const& bindingName) noexcept + { + return bindings.erase(bindingName); } //Clears all bindings from the list - static inline void BindingsClear() noexcept + static inline void ClearBindings() noexcept { bindings.clear(); } //Get the number of bindings present - static inline size_t BindingsCount() noexcept + static inline size_t CountBindings() noexcept { return bindings.size(); } + //BINDING VALUES//////////////////////////////////////////////////////////// + + //Get whether the binding is inverted or not + //If inverted, positive inputs subtract the value of the binding + // negative inputs add to the value of the binding + // Moving mouse up / right will be negative + // Scrolling the mouse wheel up will be negative + static inline bool GetBindingInverted(std::string const& bindingName) + { + return bindings[bindingName].inverted; + } + + //Set whether the binding is inverted or not + //If inverted, positive inputs subtract the value of the binding + // negative inputs add to the value of the binding + // Moving mouse up / right will be negative + // Scrolling the mouse wheel up will be negative + static inline void SetBindingInverted(std::string const& bindingName, bool const newValue) + { + bindings[bindingName].inverted = newValue; + } + + //Gets the gravity of the binding + //The rate at which the value moves to neutral if no input in the direction is read + //Should be non-negative + //Irrelevant for mouse movement and scrolling + static inline double GetBindingGravity(std::string const& bindingName) + { + return bindings[bindingName].gravity; + } + + //Sets the gravity of the binding + //The rate at which the value moves to neutral if no input in the direction is read + //Should be non-negative + //Irrelevant for mouse movement and scrolling + static inline void SetBindingGravity(std::string const& bindingName, double const newValue) + { + bindings[bindingName].gravity = newValue; + } + + //Get the dead zone of the binding on a scale of 0 to 1, + //Any positive or negative analog input with magnitude less than this will be registered as neutral + //Irrelvant for digital inputs, mouse movement and scrolling + static inline double GetBindingDead(std::string const& bindingName) + { + return bindings[bindingName].dead; + } + + //Get the dead zone of the binding on a scale of 0 to 1, + //Any positive or negative analog input with magnitude less than this will be registered as neutral + //Irrelvant for digital inputs, mouse movement and scrolling + static inline void SetBindingDead(std::string const& bindingName, double const newValue) + { + bindings[bindingName].dead = newValue; + } + + //Get the sensitivity of the binding + //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 analog inputs, serves as a multiplier, but axis value magnitude will still be capped at 1 + static inline double GetBindingSensitivity(std::string const& bindingName) + { + return bindings[bindingName].sensitivity; + } + + //Set the sensitivity of the binding + //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 analog inputs, serves as a multiplier, but axis value magnitude will still be capped at 1 + static inline void SetBindingSensitivity(std::string const& bindingName, double const newValue) + { + bindings[bindingName].sensitivity = newValue; + } + + //Gets the snap of the binding + //If no other input on the axis is present and a input is made in the opposite direction of the current value, + //the binding's value will jump to neutral 0 before resuming in the input direction + //Irrelevant for mouse movement and scrolling + static inline bool GetBindingSnap(std::string const& bindingName) + { + return bindings[bindingName].snap; + } + + //Sets the snap of the binding + //If no other input on the axis is present and a input is made in the opposite direction of the current value, + //the binding's value will jump to neutral 0 before resuming in the input direction + //Irrelevant for mouse movement and scrolling + static inline void SetBindingSnap(std::string const& bindingName, bool const newValue) + { + bindings[bindingName].snap = newValue; + } + + //BINDING TYPE////////////////////////////////////////////////////////////// + + //Get the type of the binding + //There are four types: + //KB_MB_CONTROLLER Binding is connected to the keyboard, mouse and controller buttons and its analog inputs + //MOUSE_X Binding is connected to horizontal movement of the mouse + //MOUSE_Y Binding is connected to the vertical movement of the mouse + //MOUSE_SCROLL Binding is connected to the scrolling of the mouse wheel + static inline SH_BINDINGTYPE GetBindingType(std::string const& bindingName) + { + return bindings[bindingName].bindingType; + } + + //Set the type of the binding + //There are four types: + //KB_MB_CONTROLLER Binding is connected to the keyboard, mouse and controller buttons and its analog inputs + //MOUSE_X Binding is connected to horizontal movement of the mouse + //MOUSE_Y Binding is connected to the vertical movement of the mouse + //MOUSE_SCROLL Binding is connected to the scrolling of the mouse wheel + static inline void SetBindingType(std::string const& bindingName, SH_BINDINGTYPE const newType) + { + bindings[bindingName].bindingType = newType; + } + + //POSITIVE KEYCODES///////////////////////////////////////////////////////// + //Check positive keycodes to binding - static inline std::set const& BindingsGetPositiveKeyCodes(std::string bindingName) noexcept + static inline std::set const& GetBindingPositiveKeyCodes(std::string const& bindingName) noexcept { return bindings[bindingName].positiveKeyCodes; } //Add positive SH_KEYCODE to binding - static inline void BindingsAddPositiveKeyCode(std::string targetBindingName, + static inline void AddBindingPositiveKeyCode(std::string const& bindingName, SH_KEYCODE toAdd) noexcept { - bindings[targetBindingName].positiveKeyCodes.insert(toAdd); + bindings[bindingName].positiveKeyCodes.insert(toAdd); } //Remove positive SH_KEYCODE from binding //If toRemove found and removed, returns 1. Otherwise, 0. - static inline size_t BindingsRemovePositiveKeyCode(std::string targetBindingName, + static inline size_t RemoveBindingPositiveKeyCode(std::string const& bindingName, SH_KEYCODE toRemove) noexcept { - return bindings[targetBindingName].positiveKeyCodes.erase(toRemove); + return bindings[bindingName].positiveKeyCodes.erase(toRemove); } + //Clear all positive SH_KEYCODEs from binding + static inline void ClearBindingPositiveKeyCodes(std::string const& bindingName) noexcept + { + bindings[bindingName].positiveKeyCodes.clear(); + } + + //NEGATIVE KEYCODES///////////////////////////////////////////////////////// + //Check negative keycodes to binding - static inline std::set const& BindingsGetNegativeKeyCodes(std::string bindingName) noexcept + static inline std::set const& GetBindingNegativeKeyCodes(std::string const& bindingName) noexcept { return bindings[bindingName].negativeKeyCodes; } //Add negative SH_KEYCODE to binding - static inline void BindingsAddNegativeKeyCode(std::string targetBindingName, + static inline void AddBindingNegativeKeyCode(std::string const& bindingName, SH_KEYCODE toAdd) noexcept { - bindings[targetBindingName].negativeKeyCodes.insert(toAdd); + bindings[bindingName].negativeKeyCodes.insert(toAdd); } //Remove negative SH_KEYCODE from binding //If toRemove found and removed, returns 1. Otherwise, 0. - static inline size_t BindingsRemoveNegativeKeyCode(std::string targetBindingName, + static inline size_t RemoveBindingNegativeKeyCode(std::string const& bindingName, SH_KEYCODE toRemove) noexcept { - return bindings[targetBindingName].negativeKeyCodes.erase(toRemove); + return bindings[bindingName].negativeKeyCodes.erase(toRemove); } + //Clear all negative SH_KEYCODEs from binding + static inline void ClearBindingNegativeKeyCodes(std::string const& bindingName) noexcept + { + bindings[bindingName].negativeKeyCodes.clear(); + } + + //POSITIVE CONTROLLERCODES////////////////////////////////////////////////// + //Check positive controllercodes to binding - static inline std::set const& BindingsGetPositiveControllerCodes(std::string bindingName) noexcept + static inline std::set const& GetBindingPositiveControllerCodes(std::string const& bindingName) noexcept { return bindings[bindingName].positiveControllerCodes; } //Add positive SH_CONTROLLERCODE to binding - static inline void BindingsAddPositiveControllerCode(std::string targetBindingName, + static inline void AddBindingPositiveControllerCode(std::string const& bindingName, SH_CONTROLLERCODE toAdd) noexcept { - bindings[targetBindingName].positiveControllerCodes.insert(toAdd); + bindings[bindingName].positiveControllerCodes.insert(toAdd); } //Remove positive SH_CONTROLLERCODE from binding //If toRemove found and removed, returns 1. Otherwise, 0. - static inline size_t BindingsRemovePositiveControllerCode(std::string targetBindingName, + static inline size_t RemoveBindingPositiveControllerCode(std::string const& bindingName, SH_CONTROLLERCODE toRemove) noexcept { - return bindings[targetBindingName].positiveControllerCodes.erase(toRemove); + return bindings[bindingName].positiveControllerCodes.erase(toRemove); } + //Clear all positive SH_CONTROLLERCODEs from binding + static inline void ClearBindingPositiveControllerCodes(std::string const& bindingName) noexcept + { + bindings[bindingName].positiveControllerCodes.clear(); + } + + //NEGATIVE CONTROLLERCODES////////////////////////////////////////////////// + //Check negative controllercodes to binding - static inline std::set const& BindingsGetNegativeControllerCodes(std::string bindingName) noexcept + static inline std::set const& GetBindingNegativeControllerCodes(std::string const& bindingName) noexcept { return bindings[bindingName].negativeControllerCodes; } //Add negative SH_CONTROLLERCODE to binding - static inline void BindingsAddNegativeControllerCode(std::string targetBindingName, + static inline void AddBindingNegativeControllerCode(std::string const& bindingName, SH_CONTROLLERCODE toAdd) noexcept { - bindings[targetBindingName].negativeControllerCodes.insert(toAdd); + bindings[bindingName].negativeControllerCodes.insert(toAdd); } //Remove negative SH_CONTROLLERCODE from binding //If toRemove found and removed, returns 1. Otherwise, 0. - static inline size_t BindingsRemoveNegativeControllerCode(std::string targetBindingName, + static inline size_t RemoveBindingNegativeControllerCode(std::string const& bindingName, SH_CONTROLLERCODE toRemove) noexcept { - return bindings[targetBindingName].negativeControllerCodes.erase(toRemove); + return bindings[bindingName].negativeControllerCodes.erase(toRemove); } - //Mouse movement bindings - - static inline double const BindingsGetMouseXPositiveMultiplier(std::string bindingName) noexcept + //Clear all negative SH_CONTROLLERCODEs from binding + static inline void ClearBindingNegativeControllerCodes(std::string const& bindingName) noexcept { - return bindings[bindingName].mouseXPositiveMultiplier; + bindings[bindingName].negativeControllerCodes.clear(); } - static inline void BindingsSetMouseXPositiveMultiplier(std::string bindingName, double newValue) noexcept - { - bindings[bindingName].mouseXPositiveMultiplier = newValue; - } + //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 + //To avoid interference between mouse movement/wheel and keyboard/mouse/controller input, + //Set mouseXBound, mouseYBound and mouseScrollBound to false + //controllerNumber is not used + static double GetBindingAxis(std::string const& bindingName, size_t controllerNumber = 0) noexcept; - static inline double const BindingsGetMouseYPositiveMultiplier(std::string bindingName) noexcept - { - return bindings[bindingName].mouseXPositiveMultiplier; - } - - static inline void BindingsSetMouseYPositiveMultiplier(std::string bindingName, double newValue) noexcept - { - bindings[bindingName].mouseXPositiveMultiplier = newValue; - } - - //Get the axis value of binding, between -1 and 1 - static double GetBindingAxis(std::string bindingName, size_t controllerNumber = 0) noexcept; + //Get the axis value of binding, which will be fixed among -1, 0 and 1 for non-mouse movement/wheel + //No difference between this and GetBindingAxis for mouse movement/wheel + //But for other inputs, does not consider smoothing options such as gravity and sensitivity + //If both positive and negative input is detected, returns neutral 0 + //controllerNumber is not used + static double GetBindingAxisRaw(std::string const& bindingName, size_t controllerNumber = 0) noexcept; //Whether binding is being held or not - //Does not work for mouse movement - static bool GetBindingPositiveButton(std::string bindingName, size_t controllerNumber = 0) noexcept; - static bool GetBindingNegativeButton(std::string bindingName, size_t controllerNumber = 0) noexcept; + //Does not work for mouse movement or wheel + static bool GetBindingPositiveButton(std::string const& bindingName, size_t controllerNumber = 0) noexcept; + static bool GetBindingNegativeButton(std::string const& bindingName, size_t controllerNumber = 0) noexcept; //Whether binding is pressed down IN THIS FRAME ONLY - //Does not work for mouse movement - static bool GetBindingPositiveButtonDown(std::string bindingName, size_t controllerNumber = 0) noexcept; - static bool GetBindingNegativeButtonDown(std::string bindingName, size_t controllerNumber = 0) noexcept; + //Does not work for mouse movement or wheel + static bool GetBindingPositiveButtonDown(std::string const& bindingName, size_t controllerNumber = 0) noexcept; + static bool GetBindingNegativeButtonDown(std::string const& bindingName, size_t controllerNumber = 0) noexcept; //Whether binding is released IN THIS FRAME ONLY - //Does not work for mouse movement - static bool GetBindingPositiveButtonUp(std::string bindingName, size_t controllerNumber = 0) noexcept; - static bool GetBindingNegativeButtonUp(std::string bindingName, size_t controllerNumber = 0) noexcept; + //Does not work for mouse movement or wheel + static bool GetBindingPositiveButtonUp(std::string const& bindingName, size_t controllerNumber = 0) noexcept; + static bool GetBindingNegativeButtonUp(std::string const& bindingName, size_t controllerNumber = 0) noexcept; //Binding times - //Does not work for mouse movement - static double GetBindingPositiveHeldTime(std::string bindingName, size_t controllerNumber = 0) noexcept; - static double GetBindingNegativeHeldTime(std::string bindingName, size_t controllerNumber = 0) noexcept; + //Gets how long the binding has been considered positive + //Does not work for mouse movement or wheel + static inline double GetBindingPositiveHeldTime(std::string const& bindingName, size_t controllerNumber = 0) noexcept + { + return bindings[bindingName].positiveHeldTime; + } + //Gets how long the binding has been considered negative + //Does not work for mouse movement or wheel + static inline double GetBindingNegativeHeldTime(std::string const& bindingName, size_t controllerNumber = 0) noexcept + { + return bindings[bindingName].negativeHeldTime; + } - //Does not work for mouse movement - static double GetBindingPositiveReleasedTime(std::string bindingName, size_t controllerNumber = 0) noexcept; - static double GetBindingNegativeReleasedTime(std::string bindingName, size_t controllerNumber = 0) noexcept; - - //Binding mouse velocity - //Only for mouse movement - static double GetBindingMouseVelocity(std::string bindingName, size_t controllerNumber = 0) noexcept; + //Gets how long the binding has been not considered positive + //Does not work for mouse movement or wheel + static inline double GetBindingPositiveReleasedTime(std::string const& bindingName, size_t controllerNumber = 0) noexcept + { + return bindings[bindingName].positiveReleasedTime; + } + //Gets how long the binding has been not considered negative + //Does not work for mouse movement or wheel + static inline double GetBindingNegativeReleasedTime(std::string const& bindingName, size_t controllerNumber = 0) noexcept + { + return bindings[bindingName].negativeReleasedTime; + } /*------------------------------------------------------------------------*/ /* Other Functions */ diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp index 3746d1d0..96f1539d 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.cpp +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.cpp @@ -28,8 +28,9 @@ of DigiPen Institute of Technology is prohibited. #include "Physics/System/SHPhysicsSystem.h" #include "Physics/SHPhysicsEvents.h" #include "Scene/SHSceneEvents.h" - #include "Assets/SHAssetMacros.h" +#include "Tools/Utilities/SHExecUtilities.h" +#include "SHVSUtilities.h" namespace SHADE { @@ -189,12 +190,9 @@ namespace SHADE oss << "[ScriptEngine] Building " << (debug ? " debug " : "") << "Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!"; SHLOG_INFO(oss.str()); oss.str(""); - const bool BUILD_SUCCESS = execProcess - ( - L"C:\\Windows\\system32\\cmd.exe", - L"/K \"" + generateBuildCommand(debug) + L" & exit\"" - ) == 0; - if (BUILD_SUCCESS) + const auto BUILD_SUCCESS = SHExecUtilties::ExecBlockingProcess(L"C:\\Program Files\\dotnet\\dotnet.exe", generateBuildCommand(debug), false, false); + SHLOG_WARNING("Build Output: {}", SHStringUtilities::WstrToStr(BUILD_SUCCESS.StdOutput)); + if (BUILD_SUCCESS.Code == 0) { // Copy to built dll to the working directory and replace if (!copyFile("./tmp/SHADE_Scripting.dll", "SHADE_Scripting.dll", std::filesystem::copy_options::overwrite_existing)) @@ -238,7 +236,7 @@ namespace SHADE LoadScriptAssembly(); } - return BUILD_SUCCESS; + return BUILD_SUCCESS.Code == 0; } void SHScriptEngine::GenerateScriptsCsProjFile(const std::filesystem::path& path) const @@ -306,6 +304,16 @@ namespace SHADE file.close(); } + void SHScriptEngine::OpenSolution() + { + SHVSUtilties::OpenProject(CSPROJ_PATH); + } + + void SHScriptEngine::OpenFile(const std::filesystem::path& path) + { + SHVSUtilties::OpenFile(CSPROJ_PATH, path); + } + /*-----------------------------------------------------------------------------------*/ /* Event Handler Functions */ /*-----------------------------------------------------------------------------------*/ @@ -610,64 +618,12 @@ namespace SHADE } } - DWORD SHScriptEngine::execProcess(const std::wstring& path, const std::wstring& args) - { - STARTUPINFOW startInfo; - PROCESS_INFORMATION procInfo; - ZeroMemory(&startInfo, sizeof(startInfo)); - ZeroMemory(&procInfo, sizeof(procInfo)); - startInfo.cb = sizeof(startInfo); - - std::wstring argsWstr = args; - - // Start Process - const auto SUCCESS = CreateProcess - ( - path.data(), argsWstr.data(), - nullptr, nullptr, false, NULL, nullptr, nullptr, - &startInfo, &procInfo - ); - - // Error Check - if (!SUCCESS) - { - auto err = GetLastError(); - std::ostringstream oss; - oss << "[ScriptEngine] Failed to launch process. Error code: " << std::hex << err - << " (" << SHStringUtilities::GetWin32ErrorMessage(err) << ")"; - throw std::runtime_error(oss.str()); - } - - // Wait for execution to end - DWORD status; - while (true) - { - const auto EXEC_SUCCESS = GetExitCodeProcess(procInfo.hProcess, &status); - if (!EXEC_SUCCESS) - { - auto err = GetLastError(); - std::ostringstream oss; - oss << "[ScriptEngine] Failed to query process. Error code: " << std::hex << err - << " (" << SHStringUtilities::GetWin32ErrorMessage(err) << ")"; - throw std::runtime_error(oss.str()); - } - - // Break only if process ends - if (status != STILL_ACTIVE) - { - CloseHandle(procInfo.hProcess); - CloseHandle(procInfo.hThread); - return status; - } - } - } - std::wstring SHScriptEngine::generateBuildCommand(bool debug) { std::wostringstream oss; - oss << "dotnet build \"" << SHStringUtilities::StrToWstr(CSPROJ_PATH) << "\" -c "; + oss << " build \"" << SHStringUtilities::StrToWstr(std::filesystem::absolute(CSPROJ_PATH).string()) << "\" -c "; oss << debug ? "Debug" : "Release"; - oss << " -o \"./tmp/\" -fl -flp:LogFile=build.log;Verbosity=quiet -r \"win-x64\""; + oss << " -o \"./tmp/\" -r \"win-x64\""; return oss.str(); } } diff --git a/SHADE_Engine/src/Scripting/SHScriptEngine.h b/SHADE_Engine/src/Scripting/SHScriptEngine.h index 1a38a678..9710f5c5 100644 --- a/SHADE_Engine/src/Scripting/SHScriptEngine.h +++ b/SHADE_Engine/src/Scripting/SHScriptEngine.h @@ -1,5 +1,5 @@ /************************************************************************************//*! -\file ScriptEngine.h +\file SHScriptEngine.h \author Tng Kah Wei, kahwei.tng, 390009620 \par email: kahwei.tng\@digipen.edu \date Sep 17, 2021 @@ -217,6 +217,15 @@ namespace SHADE /// /// File path to the generated file. void GenerateScriptsCsProjFile(const std::filesystem::path& path = CSPROJ_PATH) const; + /// + /// Opens the script solution in Visual Studio. + /// + void OpenSolution(); + /// + /// Opens the file in Visual Studio. + /// + /// + void OpenFile(const std::filesystem::path& path); private: /*-----------------------------------------------------------------------------*/ @@ -320,7 +329,6 @@ namespace SHADE /// True if the file exists static bool fileExists(const std::filesystem::path& filePath); static bool copyFile(const std::filesystem::path& from, const std::filesystem::path& to, const std::filesystem::copy_options options) noexcept; - static DWORD execProcess(const std::wstring& path, const std::wstring& args); static std::wstring generateBuildCommand(bool debug); }; } diff --git a/SHADE_Engine/src/Scripting/SHVSUtilities.cpp b/SHADE_Engine/src/Scripting/SHVSUtilities.cpp new file mode 100644 index 00000000..17435d6f --- /dev/null +++ b/SHADE_Engine/src/Scripting/SHVSUtilities.cpp @@ -0,0 +1,127 @@ +/************************************************************************************//*! +\file SHVSUtilities.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Dec 21, 2022 +\brief Contains the implementation for SHVSUtilities static class. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include +// Primary Header +#include "SHVSUtilities.h" +// Project Headers +#include "Tools/Utilities/SHExecUtilities.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Data Members */ + /*-----------------------------------------------------------------------------------*/ + std::filesystem::path SHVSUtilties::devEnvPath; + HANDLE SHVSUtilties::devEnvInst = nullptr; + + /*-----------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHVSUtilties::OpenProject(const std::filesystem::path& projPath) + try + { + // Check if there is an instance + bool devEnvActive = false; + if (devEnvInst) + { + + DWORD status; + const auto GET_CODE_STATUS = GetExitCodeProcess(devEnvInst, &status); + devEnvActive = GET_CODE_STATUS && status == STILL_ACTIVE; + } + + // Reuse the existing instance if there is one + if (devEnvActive) + { + // No need to reopen one + return; + } + else + { + if (devEnvPath.empty()) + { + devEnvPath = SHVSUtilties::getDevEnvPath(); + } + + auto absProjPath = std::filesystem::canonical(projPath); + auto pi = SHExecUtilties::ExecProcess(devEnvPath.generic_wstring(), L" " + absProjPath.generic_wstring()); + // Cache the process handle + devEnvInst = pi.hProcess; + } + } + catch (std::exception& e) + { + SHLOG_ERROR("{}", e.what()); + SHLOG_ERROR("[SHVSUtilities] Failed to launch Visual Studio."); + } + + void SHVSUtilties::OpenFile(const std::filesystem::path& projPath, const std::filesystem::path& path) + try + { + // Check if there is an instance + bool devEnvActive = false; + if (devEnvInst) + { + + DWORD status; + const auto GET_CODE_STATUS = GetExitCodeProcess(devEnvInst, &status); + devEnvActive = GET_CODE_STATUS && status == STILL_ACTIVE; + } + + auto absPath = std::filesystem::canonical(path); + + // Reuse the existing instance if there is one + if (devEnvActive) + { + // Edit the file only + SHExecUtilties::ExecProcess(devEnvPath.generic_wstring(), L" /Edit " + absPath.generic_wstring()); + } + else + { + if (devEnvPath.empty()) + { + devEnvPath = SHVSUtilties::getDevEnvPath(); + } + + auto absProjPath = std::filesystem::canonical(projPath); + auto pi = SHExecUtilties::ExecProcess(devEnvPath.generic_wstring(), absProjPath.generic_wstring() + L" " + absPath.generic_wstring()); + // Cache the process handle + devEnvInst = pi.hProcess; + } + } + catch (std::exception& e) + { + SHLOG_ERROR("{}", e.what()); + SHLOG_ERROR("[SHVSUtilities] Failed to launch Visual Studio."); + } + + /*-----------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------------*/ + std::filesystem::path SHVSUtilties::getDevEnvPath() + { +#ifdef _PUBLISH + return {}; // Don't do anything if it's a published build +#else + static constexpr int EXCESS_CHARS_COUNT = 2; + + const auto RESULT = SHExecUtilties::ExecBlockingPowerShellCommand(L"./vswhere -version \"[15.0,19.0]\" -requires Microsoft.NetCore.Component.DevelopmentTools -find Common7\\\\IDE\\\\devenv.exe | Select-Object -first 1", true, true); + if (RESULT.StdOutput.size() < EXCESS_CHARS_COUNT) + { + SHLOG_ERROR("[SHVSUtilities] Unable to get path to Visual Studio installation. SHVSUtilities will not work."); + return {}; + } + return RESULT.StdOutput.substr(0, RESULT.StdOutput.size() - EXCESS_CHARS_COUNT); +#endif + } +} diff --git a/SHADE_Engine/src/Scripting/SHVSUtilities.h b/SHADE_Engine/src/Scripting/SHVSUtilities.h new file mode 100644 index 00000000..8e702dfd --- /dev/null +++ b/SHADE_Engine/src/Scripting/SHVSUtilities.h @@ -0,0 +1,61 @@ +/************************************************************************************//*! +\file SHVSUtilties.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Dec 21, 2022 +\brief Contains the interface for SHVSUtilties class. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ + +// STL Includes +#include +// External Dependencies +#include + +namespace SHADE +{ + /// + /// Static class containing functions for working with Visual Studio installation and + /// running instances. + /// + class SH_API SHVSUtilties final + { + public: + /*---------------------------------------------------------------------------------*/ + /* Usage Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Opens the project at the specified path with a new or existing instance of Visual + /// Studio if it exists. + /// + /// Path to the project file to open. + static void OpenProject(const std::filesystem::path& projPath); + /// + /// Opens the file at the specified path with a new or existing instance of Visual + /// Studio if it exists. + /// + /// Path to the project file to open. + /// Path to the file to open. + static void OpenFile(const std::filesystem::path& projPath, const std::filesystem::path& path); + + private: + /*---------------------------------------------------------------------------------*/ + /* Constructors/Destructors */ + /*---------------------------------------------------------------------------------*/ + SHVSUtilties() = delete; + + /*---------------------------------------------------------------------------------*/ + /* Static Data Members */ + /*---------------------------------------------------------------------------------*/ + static std::filesystem::path devEnvPath; + static HANDLE devEnvInst; + + /*---------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*---------------------------------------------------------------------------------*/ + static std::filesystem::path getDevEnvPath(); + }; +} diff --git a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp index b560acae..9a82577a 100644 --- a/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp +++ b/SHADE_Engine/src/Serialization/SHSerializationHelper.hpp @@ -10,6 +10,7 @@ #include "ECS_Base/Managers/SHComponentManager.h" #include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h" #include "Tools/Logger/SHLog.h" +#include "Graphics/MiddleEnd/GlobalData/SHGraphicsPredefinedData.h" namespace SHADE @@ -264,7 +265,8 @@ namespace SHADE if(spec.properties.IsDefined()) { auto fragShader = SHResourceManager::LoadOrGet(spec.fragShader); - auto interface = fragShader->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA); + auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); + auto interface = fragShader->GetReflectedData().GetDescriptorBindingInfo().GetShaderBlockInterface(mappings.at(SHPredefinedDescriptorTypes::MATERIALS), SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA); int const varCount = static_cast(interface->GetVariableCount()); for (int i = 0; i < varCount; ++i) diff --git a/SHADE_Engine/src/Tools/SHEnumWrapper.h b/SHADE_Engine/src/Tools/SHEnumWrapper.h new file mode 100644 index 00000000..07c92fab --- /dev/null +++ b/SHADE_Engine/src/Tools/SHEnumWrapper.h @@ -0,0 +1,67 @@ +#pragma once + +#include + +//namespace SHADE +//{ +// template +// class SHEnumWrapper +// { +// public: +// using UnderlyingType = typename std::underlying_type_t; +// +// private: +// UnderlyingType mask; +// +// public: +// +// constexpr SHEnumWrapper(void) noexcept +// : mask{ 0 } +// { +// +// }; +// +// constexpr SHEnumWrapper(BitType bit) noexcept +// : mask{ static_cast(bit) } +// { +// +// }; +// +// constexpr SHEnumWrapper(SHEnumWrapper const& rhs) noexcept = default; +// constexpr SHEnumWrapper& operator= (SHEnumWrapper const& rhs) noexcept = default; +// +// constexpr explicit SHEnumWrapper(UnderlyingType flags) noexcept +// : mask{ flags } +// { +// +// }; +// +// constexpr SHEnumWrapper operator| (SHEnumWrapper const& rhs) const noexcept +// { +// return static_cast> (mask | rhs.mask); +// }; +// +// constexpr SHEnumWrapper operator& (SHEnumWrapper const& rhs) const noexcept +// { +// return static_cast> (mask & rhs.mask); +// }; +// +// constexpr operator UnderlyingType() const noexcept +// { +// return mask; +// }; +// }; +// +// template>> +// inline BitType operator|(const BitType& left, const BitType& right) +// { +// return static_cast(static_cast(left) | static_cast(right)); +// } +// +// template>> +// inline BitType operator&(const BitType& left, const BitType& right) +// { +// return static_cast(static_cast(left) & static_cast(right)); +// } +// +//} diff --git a/SHADE_Engine/src/Tools/Utilities/SHExecUtilities.cpp b/SHADE_Engine/src/Tools/Utilities/SHExecUtilities.cpp new file mode 100644 index 00000000..4a5a963c --- /dev/null +++ b/SHADE_Engine/src/Tools/Utilities/SHExecUtilities.cpp @@ -0,0 +1,215 @@ +/************************************************************************************//*! +\file SHExecUtilities.cpp +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Dec 21, 2022 +\brief Contains the implementation for SHExecUtilities static class. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ +// Precompiled Headers +#include +// Primary Header +#include "SHExecUtilities.h" +// Project Includes +#include "SHStringUtilities.h" +#include "SHFileUtilties.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Process Execution Functions */ + /*-----------------------------------------------------------------------------------*/ + PROCESS_INFORMATION SHExecUtilties::ExecProcess(const std::wstring& path, const std::wstring& args) + { + return execProcess(path, args, nullptr, nullptr); + } + + ExecResult SHExecUtilties::ExecBlockingProcess(const std::wstring& path, const std::wstring& args, bool output, bool errorOutput) + { + // Create pipes for stdout and stderr if specified + HANDLE stdoutReadPipe = nullptr; + HANDLE stdoutWritePipe = nullptr; + HANDLE stderrReadPipe = nullptr; + HANDLE stderrWritePipe = nullptr; + if (output) + { + std::tie(stdoutReadPipe, stdoutWritePipe) = createIoPipes(); + } + if (errorOutput) + { + std::tie(stderrReadPipe, stderrWritePipe) = createIoPipes(); + } + + PROCESS_INFORMATION procInfo = execProcess(path, args, stdoutWritePipe, stderrWritePipe); + + // Wait for execution to end + ExecResult result; + while (true) + { + const auto EXEC_SUCCESS = GetExitCodeProcess(procInfo.hProcess, &result.Code); + if (!EXEC_SUCCESS) + { + auto err = GetLastError(); + std::ostringstream oss; + oss << "[SHExecUtilties] Failed to query process. Error code: " << std::hex << err + << " (" << SHStringUtilities::GetWin32ErrorMessage(err) << ")"; + throw std::runtime_error(oss.str()); + } + + // Break only if process ends + if (result.Code != STILL_ACTIVE) + { + // Get stdout/stderror output + if (stdoutReadPipe) + { + readPipeData(stdoutReadPipe, stdoutWritePipe, result.StdOutput); + } + if (stderrReadPipe) + { + readPipeData(stderrReadPipe, stderrWritePipe, result.StdErrOutput); + } + + // Close the process and threads for that process + CloseHandle(procInfo.hProcess); + CloseHandle(procInfo.hThread); + + // Return results + return result; + } + } + } + + /*-----------------------------------------------------------------------------------*/ + /* Command Execution Functions */ + /*-----------------------------------------------------------------------------------*/ + PROCESS_INFORMATION SHExecUtilties::ExecCommand(const std::wstring& command) + { + return ExecProcess + ( + L"C:\\Windows\\system32\\cmd.exe", + L"/K \"" + command + L" & exit\"" + ); + } + + ExecResult SHExecUtilties::ExecBlockingCommand(const std::wstring& command, bool output, bool errorOutput) + { + return ExecBlockingProcess + ( + L"C:\\Windows\\system32\\cmd.exe", + L"/K \"" + command + L" & exit\"", + output, + errorOutput + ); + } + + PROCESS_INFORMATION SHExecUtilties::ExecPowerShellCommand(const std::wstring& command) + { + return ExecProcess + ( + L"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", + L"-Command \"& {" + command + L"} \"" + ); + } + + ExecResult SHExecUtilties::ExecBlockingPowerShellCommand(const std::wstring& command, bool output, bool errorOutput) + { + return ExecBlockingProcess + ( + L"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", + L"-Command \"& { cd \"" + SHFileUtilities::GetExecDir().generic_wstring() + L"\";" + command + L"} \"", + output, + errorOutput + ); + } + + PROCESS_INFORMATION SHExecUtilties::execProcess(const std::wstring& path, const std::wstring& args, HANDLE outputWritePipe, HANDLE errorOutputWritePipe) + { + STARTUPINFOW startInfo; + PROCESS_INFORMATION procInfo; + ZeroMemory(&startInfo, sizeof(startInfo)); + ZeroMemory(&procInfo, sizeof(procInfo)); + startInfo.cb = sizeof(startInfo); + if (outputWritePipe) + { + startInfo.hStdOutput = outputWritePipe; + startInfo.dwFlags |= STARTF_USESTDHANDLES; + startInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + } + if (errorOutputWritePipe) + { + startInfo.hStdError = errorOutputWritePipe; + startInfo.dwFlags |= STARTF_USESTDHANDLES; + startInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + } + + std::wstring argsWstr = args; + + // Start Process + const auto SUCCESS = CreateProcess + ( + path.data(), argsWstr.data(), + nullptr, nullptr, true, NULL, nullptr, nullptr, + &startInfo, &procInfo + ); + + // Error Check + if (!SUCCESS) + { + auto err = GetLastError(); + std::ostringstream oss; + oss << "[SHExecUtilties] Failed to launch process. Error code: " << std::hex << err + << " (" << SHStringUtilities::GetWin32ErrorMessage(err) << ")"; + throw std::runtime_error(oss.str()); + } + + return procInfo; + } + + std::pair SHExecUtilties::createIoPipes() + { + SECURITY_ATTRIBUTES saAttr; + saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); + saAttr.bInheritHandle = true; + saAttr.lpSecurityDescriptor = nullptr; + + // First: Read | Second: Write + std::pair output = { nullptr, nullptr }; + if (CreatePipe(&output.first, &output.second, &saAttr, 0)) + { + if (!SetHandleInformation(output.first, HANDLE_FLAG_INHERIT, 0)) + { + SHLOG_ERROR("[SHExecUtilities] Failed to initialize pipe for process IO."); + CloseHandle(output.first); + CloseHandle(output.second); + output = { nullptr, nullptr }; + } + } + else + { + SHLOG_ERROR("[SHExecUtilities] Failed to create pipe for process IO."); + } + + return output; + } + + void SHExecUtilties::readPipeData(HANDLE readPipe, HANDLE writePipe, std::wstring& output) + { + CloseHandle(writePipe); + + LARGE_INTEGER stdoutSize = {}; + while (true) + { + std::array buffer{}; + DWORD bytesRead = 0; + const auto RESULT = ReadFile(readPipe, buffer.data(), buffer.size(), &bytesRead, nullptr); + if (!RESULT || bytesRead <= 0) + break; + output.insert(output.end(), buffer.data(), buffer.data() + bytesRead); + } + + CloseHandle(readPipe); + } +} diff --git a/SHADE_Engine/src/Tools/Utilities/SHExecUtilities.h b/SHADE_Engine/src/Tools/Utilities/SHExecUtilities.h new file mode 100644 index 00000000..718fc45b --- /dev/null +++ b/SHADE_Engine/src/Tools/Utilities/SHExecUtilities.h @@ -0,0 +1,142 @@ +/************************************************************************************//*! +\file SHExecUtilties.h +\author Tng Kah Wei, kahwei.tng, 390009620 +\par email: kahwei.tng\@digipen.edu +\date Dec 21, 2022 +\brief Contains the interface for SHExecUtilities class. + +Copyright (C) 2022 DigiPen Institute of Technology. +Reproduction or disclosure of this file or its contents without the prior written consent +of DigiPen Institute of Technology is prohibited. +*//*************************************************************************************/ + +// STL Includes +#include +// External Dependencies +#include + +namespace SHADE +{ + /// + /// Stores the result of an execution of a process. + /// + struct SH_API ExecResult final + { + /// + /// Exit code of the process. + /// + DWORD Code; + /// + /// Stored text output from the process. + /// + std::wstring StdOutput; + /// + /// Stored error text output from the process. + /// + std::wstring StdErrOutput; + }; + + /// + /// Static class containing functions for executing external processes or commands. + /// + class SH_API SHExecUtilties final + { + public: + /*---------------------------------------------------------------------------------*/ + /* Process Execution Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Executes a process at the specified path with the specified arguments. This call + /// does not wait for the process to finish executing. + /// + /// Path to the processs to start. + /// Arguments to pass to the process. + /// Information about the started process. + /// + /// Thrown if failed to start the process. + /// + static PROCESS_INFORMATION ExecProcess(const std::wstring& path, const std::wstring& args); + /// + /// Executes a process at the specified path with the specified arguments and waits + /// for that process to finish executing. + /// + /// Path to the processs to start. + /// Arguments to pass to the process. + /// If true, stdout will be routed to return. + /// If true, outstderr will be routed to return. + /// Information about the process's execution. + /// + /// Thrown if failed to start the process. + /// + static ExecResult ExecBlockingProcess(const std::wstring& path, const std::wstring& args, bool output = false, bool errorOutput = false); + + /*---------------------------------------------------------------------------------*/ + /* Command Execution Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Executes a specified command in cmd. + /// This call does not wait for the command to finish executing. + /// + /// Command to execute. + /// + /// Information about the started cmd process that executes the command. + /// + /// + /// Thrown if failed to start the process. + /// + static PROCESS_INFORMATION ExecCommand(const std::wstring& command); + /// + /// Executes a specified command in cmd and waits for that process to finish + /// executing. + /// + /// Command to execute. + /// If true, stdout will be routed to return. + /// If true, outstderr will be routed to return. + /// Information about the process's execution. + /// + /// Thrown if failed to start the process. + /// + static ExecResult ExecBlockingCommand(const std::wstring& command, bool output = false, bool errorOutput = false); + + /*---------------------------------------------------------------------------------*/ + /* PowerShell Execution Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Executes a specified command in PowerShell. + /// This call does not wait for the command to finish executing. + /// + /// Command to execute. + /// + /// Information about the started cmd process that executes the command. + /// + /// + /// Thrown if failed to start the process. + /// + static PROCESS_INFORMATION ExecPowerShellCommand(const std::wstring& command); + /// + /// Executes a specified command in PowerShell and waits for that process to finish + /// executing. + /// + /// Command to execute. + /// If true, stdout will be routed to return. + /// If true, outstderr will be routed to return. + /// Information about the process's execution. + /// + /// Thrown if failed to start the process. + /// + static ExecResult ExecBlockingPowerShellCommand(const std::wstring& command, bool output, bool errorOutput); + + private: + /*---------------------------------------------------------------------------------*/ + /* Constructors/Destructors */ + /*---------------------------------------------------------------------------------*/ + SHExecUtilties() = delete; + + /*---------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*---------------------------------------------------------------------------------*/ + static PROCESS_INFORMATION execProcess(const std::wstring& path, const std::wstring& args, HANDLE outputWritePipe, HANDLE errorOutputWritePipe); + static std::pair createIoPipes(); + static void readPipeData(HANDLE readPipe, HANDLE writePipe, std::wstring& output); + }; +} diff --git a/SHADE_Engine/src/Tools/Utilities/SHFileUtilties.cpp b/SHADE_Engine/src/Tools/Utilities/SHFileUtilties.cpp index 0e75b16a..63e7d26e 100644 --- a/SHADE_Engine/src/Tools/Utilities/SHFileUtilties.cpp +++ b/SHADE_Engine/src/Tools/Utilities/SHFileUtilties.cpp @@ -22,9 +22,21 @@ namespace SHADE { void SHFileUtilities::SetWorkDirToExecDir() { - TCHAR currentExecFilePath[MAX_PATH] = { '\0' }; - GetModuleFileName(nullptr, currentExecFilePath, MAX_PATH); - PathRemoveFileSpec(currentExecFilePath); - std::filesystem::current_path(currentExecFilePath); + std::filesystem::current_path(GetExecDir()); + } + + std::filesystem::path SHFileUtilities::GetExecDir() + { + TCHAR currentExecFilePath[MAX_PATH] = { '\0' }; + GetModuleFileName(nullptr, currentExecFilePath, MAX_PATH); + PathRemoveFileSpec(currentExecFilePath); + return std::filesystem::path(currentExecFilePath); + } + + std::filesystem::path SHFileUtilities::GetExecPath() + { + TCHAR currentExecFilePath[MAX_PATH] = { '\0' }; + GetModuleFileName(nullptr, currentExecFilePath, MAX_PATH); + return std::filesystem::path(currentExecFilePath); } } diff --git a/SHADE_Engine/src/Tools/Utilities/SHFileUtilties.h b/SHADE_Engine/src/Tools/Utilities/SHFileUtilties.h index b9ba164b..fdbee34e 100644 --- a/SHADE_Engine/src/Tools/Utilities/SHFileUtilties.h +++ b/SHADE_Engine/src/Tools/Utilities/SHFileUtilties.h @@ -15,24 +15,29 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { - /*!************************************************************************************ - - \class SHFileUtilities - - \brief - Static class that contains functions for working with files and directories. - - **************************************************************************************/ + /// + /// Static class that contains functions for working with files and directories. + /// class SH_API SHFileUtilities { public: - /*!********************************************************************************** - - \brief - Sets the application's current working directory to the application executable's - directory. - - ************************************************************************************/ + /*---------------------------------------------------------------------------------*/ + /* Executable Directory Functions */ + /*---------------------------------------------------------------------------------*/ + /// + /// Sets the application's current working directory to the application executable's + /// directory. + /// static void SetWorkDirToExecDir(); + /// + /// Retrieves the file path to the executable's directory. + /// + /// File path to the executable's directory. + static std::filesystem::path GetExecDir(); + /// + /// Retrieves the file path to the executable. + /// + /// File path to the executable. + static std::filesystem::path GetExecPath(); }; } diff --git a/SHADE_Engine/src/Tools/Utilities/SHStringUtilities.cpp b/SHADE_Engine/src/Tools/Utilities/SHStringUtilities.cpp index b1e4aa92..b9698071 100644 --- a/SHADE_Engine/src/Tools/Utilities/SHStringUtilities.cpp +++ b/SHADE_Engine/src/Tools/Utilities/SHStringUtilities.cpp @@ -26,27 +26,29 @@ namespace SHADE std::vector SHStringUtilities::Split(const std::wstring& str, const wchar_t& delim) { return Split(str, delim); - } - std::string SHStringUtilities::WstrToStr(const std::wstring& wstr) - { - static std::vector buffer; - const int STR_SIZE = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast(wstr.size()), nullptr, 0, nullptr, nullptr) + 1 /* Null Terminator */; - buffer.resize(STR_SIZE); - WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast(wstr.size()), buffer.data(), MAX_PATH, nullptr, nullptr); - return std::string(buffer.data()); - } - std::wstring SHStringUtilities::StrToWstr(const std::string& str) - { - static std::vector buffer; - const int WSTR_SIZE = MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast(str.size()), nullptr, 0) + 1 /* Null Terminator */; - buffer.resize(WSTR_SIZE); - MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast(str.size()), buffer.data(), WSTR_SIZE); - return std::wstring(buffer.data()); - } + } + std::string SHStringUtilities::WstrToStr(const std::wstring& wstr) + { + static std::vector buffer; + buffer.clear(); + const int STR_SIZE = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast(wstr.size()), nullptr, 0, nullptr, nullptr) + 1 /* Null Terminator */; + buffer.resize(STR_SIZE, '\0'); + WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast(wstr.size()), buffer.data(), MAX_PATH, nullptr, nullptr); + return std::string(buffer.data()); + } + std::wstring SHStringUtilities::StrToWstr(const std::string& str) + { + static std::vector buffer; + buffer.clear(); + const int WSTR_SIZE = MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast(str.size()), nullptr, 0) + 1 /* Null Terminator */; + buffer.resize(WSTR_SIZE, '\0'); + MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast(str.size()), buffer.data(), WSTR_SIZE); + return std::wstring(buffer.data()); + } - std::string SHStringUtilities::GetWin32ErrorMessage(unsigned long errorCode) - { - return std::system_category().message(errorCode); - } + std::string SHStringUtilities::GetWin32ErrorMessage(unsigned long errorCode) + { + return std::system_category().message(errorCode); + } } \ No newline at end of file diff --git a/SHADE_Managed/src/Engine/Application.cxx b/SHADE_Managed/src/Engine/Application.cxx index c19bafa6..06ad632f 100644 --- a/SHADE_Managed/src/Engine/Application.cxx +++ b/SHADE_Managed/src/Engine/Application.cxx @@ -44,6 +44,10 @@ namespace SHADE return false; } + bool Application::IsEditor::get() + { + return SHSystemManager::GetSystem() != nullptr; + } int Application::WindowWidth::get() { return SHGraphicsSystemInterface::GetWindowWidth(); @@ -66,6 +70,9 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ void Application::Quit() { - SHGraphicsSystemInterface::CloseWindow(); + if (!IsEditor) + { + SHGraphicsSystemInterface::CloseWindow(); + } } } diff --git a/SHADE_Managed/src/Engine/Application.hxx b/SHADE_Managed/src/Engine/Application.hxx index 8629cf75..4467ec3b 100644 --- a/SHADE_Managed/src/Engine/Application.hxx +++ b/SHADE_Managed/src/Engine/Application.hxx @@ -43,6 +43,13 @@ namespace SHADE bool get(); } /// + /// True if the engine is running in the editor. + /// + static property bool IsEditor + { + bool get(); + } + /// /// Retrieves the designated width of the current window. /// static property int WindowWidth @@ -71,6 +78,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ /// /// Marks the application to stop at the end of the current frame. + /// If running in the editor, this function does nothing. /// static void Quit(); };