Merge branch 'main' into SP3-16-Math
This commit is contained in:
commit
ec3470c443
|
@ -353,4 +353,9 @@ MigrationBackup/
|
||||||
# Ionide (cross platform F# VS Code tools) working folder
|
# Ionide (cross platform F# VS Code tools) working folder
|
||||||
.ionide/
|
.ionide/
|
||||||
|
|
||||||
|
# Generated Files
|
||||||
[Dd]ependencies/
|
[Dd]ependencies/
|
||||||
|
*.vcxproj
|
||||||
|
*.vcxproj.filters
|
||||||
|
*.sln
|
||||||
|
*.csproj
|
||||||
|
|
|
@ -8,34 +8,36 @@ echo "A - All"
|
||||||
echo "B - VMA"
|
echo "B - VMA"
|
||||||
echo "C - msdf"
|
echo "C - msdf"
|
||||||
echo "D - assimp"
|
echo "D - assimp"
|
||||||
echo "E - ktx"
|
echo "E - spdlog"
|
||||||
echo "F - spdlog"
|
echo "F - reactphysics3d"
|
||||||
echo "G - reactphysics3d"
|
echo "G - imgui"
|
||||||
echo "H - imgui"
|
echo "H - imguizmo"
|
||||||
echo "I - imguizmo"
|
echo "I - imnodes"
|
||||||
echo "J - imnodes"
|
echo "J - tracy"
|
||||||
echo "K - tracy"
|
echo "K - RTTR"
|
||||||
echo "L - RTTR"
|
echo "L - yamlcpp"
|
||||||
echo "M - yamlcpp"
|
echo "M - SDL"
|
||||||
|
echo "N - dotnet"
|
||||||
echo ---------------------------------------------------
|
echo ---------------------------------------------------
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
choice /C ABCDEFGHIJKLM /T 10 /D A
|
choice /C ABCDEFGHIJKLMN /T 10 /D A
|
||||||
set _e=%ERRORLEVEL%
|
set _e=%ERRORLEVEL%
|
||||||
|
|
||||||
if %_e%==1 goto VMA
|
if %_e%==1 goto VMA
|
||||||
if %_e%==2 goto VMA
|
if %_e%==2 goto VMA
|
||||||
if %_e%==3 goto MSDF
|
if %_e%==3 goto MSDF
|
||||||
if %_e%==4 goto assimp
|
if %_e%==4 goto assimp
|
||||||
if %_e%==5 goto ktx
|
if %_e%==5 goto spdlog
|
||||||
if %_e%==6 goto spdlog
|
if %_e%==6 goto reactphysics3d
|
||||||
if %_e%==7 goto reactphysics3d
|
if %_e%==7 goto imgui
|
||||||
if %_e%==8 goto imgui
|
if %_e%==8 goto imguizmo
|
||||||
if %_e%==9 goto imguizmo
|
if %_e%==9 goto imnodes
|
||||||
if %_e%==10 goto imnodes
|
if %_e%==10 goto tracy
|
||||||
if %_e%==11 goto tracy
|
if %_e%==11 goto RTTR
|
||||||
if %_e%==12 goto RTTR
|
if %_e%==12 goto yamlcpp
|
||||||
if %_e%==13 goto yamlcpp
|
if %_e%==13 goto SDL
|
||||||
|
if %_e%==14 goto dotnet
|
||||||
|
|
||||||
:VMA
|
:VMA
|
||||||
echo -----------------------VMA----------------------------
|
echo -----------------------VMA----------------------------
|
||||||
|
@ -53,60 +55,87 @@ if %_e%==3 (goto :done) else (goto :assimp)
|
||||||
echo -----------------------assimp----------------------------
|
echo -----------------------assimp----------------------------
|
||||||
rmdir "Dependencies/assimp" /S /Q
|
rmdir "Dependencies/assimp" /S /Q
|
||||||
git clone https://github.com/SHADE-DP/assimp.git "Dependencies/assimp"
|
git clone https://github.com/SHADE-DP/assimp.git "Dependencies/assimp"
|
||||||
if %_e%==4 (goto :done) else (goto :ktx)
|
if %_e%==4 (goto :done) else (goto :spdlog)
|
||||||
|
|
||||||
:ktx
|
@REM :ktx
|
||||||
rmdir "Dependencies/ktx" /S /Q
|
@REM rmdir "Dependencies/ktx" /S /Q
|
||||||
echo -----------------------ktx----------------------------
|
@REM echo -----------------------ktx----------------------------
|
||||||
git clone https://github.com/SHADE-DP/ktx.git "Dependencies/ktx"
|
@REM git clone https://github.com/SHADE-DP/ktx.git "Dependencies/ktx"
|
||||||
if %_e%==5 (goto :done) else (goto :spdlog)
|
@REM if %_e%==5 (goto :done) else (goto :spdlog)
|
||||||
|
|
||||||
:spdlog
|
:spdlog
|
||||||
echo -----------------------spdlog----------------------------
|
echo -----------------------spdlog----------------------------
|
||||||
rmdir "Dependencies/spdlog" /S /Q
|
rmdir "Dependencies/spdlog" /S /Q
|
||||||
git clone https://github.com/SHADE-DP/spdlog.git "Dependencies/spdlog"
|
git clone https://github.com/SHADE-DP/spdlog.git "Dependencies/spdlog"
|
||||||
if %_e%==6 (goto :done) else (goto :reactphysics3d)
|
if %_e%==5 (goto :done) else (goto :reactphysics3d)
|
||||||
|
|
||||||
:reactphysics3d
|
:reactphysics3d
|
||||||
echo -----------------------reactphysics3d----------------------------
|
echo -----------------------reactphysics3d----------------------------
|
||||||
rmdir "Dependencies/reactphysics3d" /S /Q
|
rmdir "Dependencies/reactphysics3d" /S /Q
|
||||||
git clone https://github.com/SHADE-DP/reactphysics3d.git "Dependencies/reactphysics3d"
|
git clone https://github.com/SHADE-DP/reactphysics3d.git "Dependencies/reactphysics3d"
|
||||||
if %_e%==7 (goto :done) else (goto :imgui)
|
if %_e%==6 (goto :done) else (goto :imgui)
|
||||||
|
|
||||||
:imgui
|
:imgui
|
||||||
echo -----------------------imgui----------------------------
|
echo -----------------------imgui----------------------------
|
||||||
rmdir "Dependencies/imgui" /S /Q
|
rmdir "Dependencies/imgui" /S /Q
|
||||||
git clone https://github.com/SHADE-DP/imgui.git "Dependencies/imgui"
|
git clone https://github.com/SHADE-DP/imgui.git "Dependencies/imgui"
|
||||||
if %_e%==8 (goto :done) else (goto :imguizmo)
|
if %_e%==7 (goto :done) else (goto :imguizmo)
|
||||||
|
|
||||||
:imguizmo
|
:imguizmo
|
||||||
echo -----------------------imguizmo----------------------------
|
echo -----------------------imguizmo----------------------------
|
||||||
rmdir "Dependencies/imguizmo" /S /Q
|
rmdir "Dependencies/imguizmo" /S /Q
|
||||||
git clone https://github.com/SHADE-DP/ImGuizmo.git "Dependencies/imguizmo"
|
git clone https://github.com/SHADE-DP/ImGuizmo.git "Dependencies/imguizmo"
|
||||||
if %_e%==9 (goto :done) else (goto :imnodes)
|
if %_e%==8 (goto :done) else (goto :imnodes)
|
||||||
|
|
||||||
:imnodes
|
:imnodes
|
||||||
echo -----------------------imnodes----------------------------
|
echo -----------------------imnodes----------------------------
|
||||||
rmdir "Dependencies/imnodes" /S /Q
|
rmdir "Dependencies/imnodes" /S /Q
|
||||||
git clone https://github.com/SHADE-DP/imnodes.git "Dependencies/imnodes"
|
git clone https://github.com/SHADE-DP/imnodes.git "Dependencies/imnodes"
|
||||||
if %_e%==10 (goto :done) else (goto :tracy)
|
if %_e%==9 (goto :done) else (goto :tracy)
|
||||||
|
|
||||||
:tracy
|
:tracy
|
||||||
echo -----------------------tracy----------------------------
|
echo -----------------------tracy----------------------------
|
||||||
rmdir "Dependencies/tracy" /S /Q
|
rmdir "Dependencies/tracy" /S /Q
|
||||||
git clone https://github.com/SHADE-DP/tracy.git "Dependencies/tracy"
|
git clone https://github.com/SHADE-DP/tracy.git "Dependencies/tracy"
|
||||||
if %_e%==11 (goto :done) else (goto :RTTR)
|
if %_e%==10 (goto :done) else (goto :RTTR)
|
||||||
|
|
||||||
:RTTR
|
:RTTR
|
||||||
echo -----------------------RTTR----------------------------
|
echo -----------------------RTTR----------------------------
|
||||||
rmdir "Dependencies/RTTR" /S /Q
|
rmdir "Dependencies/RTTR" /S /Q
|
||||||
git clone https://github.com/SHADE-DP/RTTR.git "Dependencies/RTTR"
|
git clone https://github.com/SHADE-DP/RTTR.git "Dependencies/RTTR"
|
||||||
if %_e%==12 (goto :done) else (goto :yamlcpp)
|
if %_e%==11 (goto :done) else (goto :yamlcpp)
|
||||||
|
|
||||||
:yamlcpp
|
:yamlcpp
|
||||||
echo -----------------------yamlcpp----------------------------
|
echo -----------------------yamlcpp----------------------------
|
||||||
rmdir "Dependencies/yamlcpp" /S /Q
|
rmdir "Dependencies/yamlcpp" /S /Q
|
||||||
git clone https://github.com/SHADE-DP/yaml-cpp.git "Dependencies/yamlcpp"
|
git clone https://github.com/SHADE-DP/yaml-cpp.git "Dependencies/yamlcpp"
|
||||||
|
if %_e%==12 (goto :done) else (goto :SDL)
|
||||||
|
|
||||||
|
:SDL
|
||||||
|
echo -----------------------SDL----------------------------
|
||||||
|
rmdir "Dependencies/SDL" /S /Q
|
||||||
|
mkdir "Dependencies/SDL/include"
|
||||||
|
mkdir "Dependencies/SDL/lib"
|
||||||
|
powershell -Command "& {wget https://github.com/libsdl-org/SDL/releases/download/release-2.24.0/SDL2-devel-2.24.0-VC.zip -OutFile "Dependencies/SDL/SDL.zip"}"
|
||||||
|
powershell -Command "& {Expand-Archive -LiteralPath Dependencies/SDL/SDL.zip -DestinationPath Dependencies/SDL/tmp}"
|
||||||
|
robocopy "Dependencies/SDL/tmp/SDL2-2.24.0/lib/x64" "Dependencies/SDL/lib/" /ns /nfl /ndl /nc /njh
|
||||||
|
robocopy "Dependencies/SDL/tmp/SDL2-2.24.0/include/" "Dependencies/SDL/include/" /ns /nfl /ndl /nc /njh
|
||||||
|
rmdir "Dependencies/SDL/tmp/" /s /q
|
||||||
|
powershell -Command "& {Remove-Item "Dependencies/SDL/SDL.zip"}"
|
||||||
|
if %_e%==13 (goto :done) else (goto :dotnet)
|
||||||
|
|
||||||
|
:dotnet
|
||||||
|
echo -----------------------dotnet----------------------------
|
||||||
|
rmdir "Dependencies/dotnet" /S /Q
|
||||||
|
mkdir "Dependencies/dotnet/include"
|
||||||
|
mkdir "Dependencies/dotnet/bin"
|
||||||
|
powershell -Command "& {wget https://raw.githubusercontent.com/dotnet/runtime/main/src/coreclr/hosts/inc/coreclrhost.h -OutFile "Dependencies/dotnet/include/coreclrhost.h"}"
|
||||||
|
powershell -Command "& {wget https://download.visualstudio.microsoft.com/download/pr/8686fa48-b378-424e-908b-afbd66d6e120/2d75d5c3574fb5d917c5a3cd3f624287/dotnet-sdk-6.0.400-win-x64.zip -OutFile "Dependencies/dotnet/dotnet.zip"}"
|
||||||
|
powershell -Command "& {Expand-Archive -LiteralPath Dependencies/dotnet/dotnet.zip -DestinationPath Dependencies/dotnet/tmp}"
|
||||||
|
robocopy "Dependencies/dotnet/tmp/shared/Microsoft.NETCore.App/6.0.8/" "Dependencies/dotnet/bin/" *.dll /ns /nfl /ndl /nc /njh
|
||||||
|
rmdir "Dependencies/dotnet/tmp/" /s /q
|
||||||
|
del "Dependencies/dotnet/dotnet.zip"
|
||||||
|
powershell -Command "& {Remove-Item "Dependencies/dotnet/dotnet.zip"}"
|
||||||
|
|
||||||
:done
|
:done
|
||||||
echo DONE!
|
echo DONE!
|
||||||
|
|
|
@ -10,6 +10,7 @@ IncludeDir["tracy"] = "%{wks.location}/Dependencies/tracy"
|
||||||
IncludeDir["VMA"] = "%{wks.location}/Dependencies/VMA"
|
IncludeDir["VMA"] = "%{wks.location}/Dependencies/VMA"
|
||||||
IncludeDir["yamlcpp"] = "%{wks.location}/Dependencies/yamlcpp/include"
|
IncludeDir["yamlcpp"] = "%{wks.location}/Dependencies/yamlcpp/include"
|
||||||
IncludeDir["RTTR"] = "%{wks.location}/Dependencies/RTTR"
|
IncludeDir["RTTR"] = "%{wks.location}/Dependencies/RTTR"
|
||||||
IncludeDir["ktx"] = "%{wks.location}/Dependencies/ktx"
|
|
||||||
IncludeDir["reactphysics3d"] = "%{wks.location}/Dependencies/reactphysics3d"
|
IncludeDir["reactphysics3d"] = "%{wks.location}/Dependencies/reactphysics3d"
|
||||||
|
IncludeDir["SDL"] = "%{wks.location}/Dependencies/SDL"
|
||||||
IncludeDir["VULKAN"] = "$(VULKAN_SDK)"
|
IncludeDir["VULKAN"] = "$(VULKAN_SDK)"
|
||||||
|
IncludeDir["dotnet"] = "%{wks.location}/Dependencies/dotnet"
|
||||||
|
|
Binary file not shown.
87
SHADE.sln
87
SHADE.sln
|
@ -1,87 +0,0 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio Version 16
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SHADE_Application", "SHADE_Application\SHADE_Application.vcxproj", "{BDC70008-29DE-FE9D-7255-8ABFDEAACF25}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dependencies", "Dependencies", "{53E47842-3FC8-3998-A828-34EB942B241A}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ImGui", "Dependencies\imgui\ImGui.vcxproj", "{C0FF640D-2C14-8DBE-F595-301E616989EF}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "freetype", "Dependencies\msdf\msdfgen\freetype\freetype.vcxproj", "{89895BD8-7556-B6E3-9E6F-A48B8A9BEB71}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msdf-atlas-gen", "Dependencies\msdf\msdf-atlas-gen.vcxproj", "{38BD587B-248B-4C81-0D1F-BDA7F98B28E6}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msdfgen", "Dependencies\msdf\msdfgen\msdfgen.vcxproj", "{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reactphysics3d", "Dependencies\reactphysics3d\reactphysics3d.vcxproj", "{2ECAB41A-1A98-A820-032C-1947EF988485}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spdlog", "Dependencies\spdlog\spdlog.vcxproj", "{8EAD431C-7A4F-6EF2-630A-82464F4BF542}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml-cpp", "Dependencies\yamlcpp\yaml-cpp.vcxproj", "{88F1A057-74BE-FB62-9DD7-E90A890331F1}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SHADE_Engine", "SHADE_Engine\SHADE_Engine.vcxproj", "{3F92E998-2BF5-783D-D47A-B1F3C0BC44C0}"
|
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
|
||||||
{88F1A057-74BE-FB62-9DD7-E90A890331F1} = {88F1A057-74BE-FB62-9DD7-E90A890331F1}
|
|
||||||
{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA} = {8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA}
|
|
||||||
{38BD587B-248B-4C81-0D1F-BDA7F98B28E6} = {38BD587B-248B-4C81-0D1F-BDA7F98B28E6}
|
|
||||||
{2ECAB41A-1A98-A820-032C-1947EF988485} = {2ECAB41A-1A98-A820-032C-1947EF988485}
|
|
||||||
{C0FF640D-2C14-8DBE-F595-301E616989EF} = {C0FF640D-2C14-8DBE-F595-301E616989EF}
|
|
||||||
{8EAD431C-7A4F-6EF2-630A-82464F4BF542} = {8EAD431C-7A4F-6EF2-630A-82464F4BF542}
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|x64 = Debug|x64
|
|
||||||
Release|x64 = Release|x64
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{BDC70008-29DE-FE9D-7255-8ABFDEAACF25}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{BDC70008-29DE-FE9D-7255-8ABFDEAACF25}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{BDC70008-29DE-FE9D-7255-8ABFDEAACF25}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{BDC70008-29DE-FE9D-7255-8ABFDEAACF25}.Release|x64.Build.0 = Release|x64
|
|
||||||
{C0FF640D-2C14-8DBE-F595-301E616989EF}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{C0FF640D-2C14-8DBE-F595-301E616989EF}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{C0FF640D-2C14-8DBE-F595-301E616989EF}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{C0FF640D-2C14-8DBE-F595-301E616989EF}.Release|x64.Build.0 = Release|x64
|
|
||||||
{89895BD8-7556-B6E3-9E6F-A48B8A9BEB71}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{89895BD8-7556-B6E3-9E6F-A48B8A9BEB71}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{89895BD8-7556-B6E3-9E6F-A48B8A9BEB71}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{89895BD8-7556-B6E3-9E6F-A48B8A9BEB71}.Release|x64.Build.0 = Release|x64
|
|
||||||
{38BD587B-248B-4C81-0D1F-BDA7F98B28E6}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{38BD587B-248B-4C81-0D1F-BDA7F98B28E6}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{38BD587B-248B-4C81-0D1F-BDA7F98B28E6}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{38BD587B-248B-4C81-0D1F-BDA7F98B28E6}.Release|x64.Build.0 = Release|x64
|
|
||||||
{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA}.Release|x64.Build.0 = Release|x64
|
|
||||||
{2ECAB41A-1A98-A820-032C-1947EF988485}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{2ECAB41A-1A98-A820-032C-1947EF988485}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{2ECAB41A-1A98-A820-032C-1947EF988485}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{2ECAB41A-1A98-A820-032C-1947EF988485}.Release|x64.Build.0 = Release|x64
|
|
||||||
{8EAD431C-7A4F-6EF2-630A-82464F4BF542}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{8EAD431C-7A4F-6EF2-630A-82464F4BF542}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{8EAD431C-7A4F-6EF2-630A-82464F4BF542}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{8EAD431C-7A4F-6EF2-630A-82464F4BF542}.Release|x64.Build.0 = Release|x64
|
|
||||||
{88F1A057-74BE-FB62-9DD7-E90A890331F1}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{88F1A057-74BE-FB62-9DD7-E90A890331F1}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{88F1A057-74BE-FB62-9DD7-E90A890331F1}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{88F1A057-74BE-FB62-9DD7-E90A890331F1}.Release|x64.Build.0 = Release|x64
|
|
||||||
{3F92E998-2BF5-783D-D47A-B1F3C0BC44C0}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{3F92E998-2BF5-783D-D47A-B1F3C0BC44C0}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{3F92E998-2BF5-783D-D47A-B1F3C0BC44C0}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{3F92E998-2BF5-783D-D47A-B1F3C0BC44C0}.Release|x64.Build.0 = Release|x64
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(NestedProjects) = preSolution
|
|
||||||
{C0FF640D-2C14-8DBE-F595-301E616989EF} = {53E47842-3FC8-3998-A828-34EB942B241A}
|
|
||||||
{89895BD8-7556-B6E3-9E6F-A48B8A9BEB71} = {53E47842-3FC8-3998-A828-34EB942B241A}
|
|
||||||
{38BD587B-248B-4C81-0D1F-BDA7F98B28E6} = {53E47842-3FC8-3998-A828-34EB942B241A}
|
|
||||||
{8900D8DD-F5DF-5679-FEF7-E14F6A56BDDA} = {53E47842-3FC8-3998-A828-34EB942B241A}
|
|
||||||
{2ECAB41A-1A98-A820-032C-1947EF988485} = {53E47842-3FC8-3998-A828-34EB942B241A}
|
|
||||||
{8EAD431C-7A4F-6EF2-630A-82464F4BF542} = {53E47842-3FC8-3998-A828-34EB942B241A}
|
|
||||||
{88F1A057-74BE-FB62-9DD7-E90A890331F1} = {53E47842-3FC8-3998-A828-34EB942B241A}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
|
@ -1,30 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<Filter Include="Application">
|
|
||||||
<UniqueIdentifier>{D9DE78AF-4594-F1A4-CE88-EB7B3A3DE8A8}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Scenes">
|
|
||||||
<UniqueIdentifier>{86EEB3D0-7290-DEA6-5B4B-F2FA478C65F7}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="src\Application\SBApplication.h">
|
|
||||||
<Filter>Application</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="src\SBpch.h" />
|
|
||||||
<ClInclude Include="src\Scenes\SBTestScene.h">
|
|
||||||
<Filter>Scenes</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="src\Application\SBApplication.cpp">
|
|
||||||
<Filter>Application</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="src\SBpch.cpp" />
|
|
||||||
<ClCompile Include="src\Scenes\SBTestScene.cpp">
|
|
||||||
<Filter>Scenes</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="src\WinMain.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
|
@ -1,9 +1,9 @@
|
||||||
project "SHADE_Application"
|
project "SHADE_Application"
|
||||||
kind "WindowedApp"
|
kind "WindowedApp"
|
||||||
language "C++"
|
language "C++"
|
||||||
cppdialect "C++latest"
|
cppdialect "C++20"
|
||||||
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
|
targetdir (outputdir)
|
||||||
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
|
objdir (interdir)
|
||||||
systemversion "latest"
|
systemversion "latest"
|
||||||
pchheader "SBpch.h"
|
pchheader "SBpch.h"
|
||||||
pchsource "%{prj.location}/src/SBpch.cpp"
|
pchsource "%{prj.location}/src/SBpch.cpp"
|
||||||
|
@ -14,6 +14,7 @@ project "SHADE_Application"
|
||||||
files
|
files
|
||||||
{
|
{
|
||||||
"%{prj.location}/src/**.h",
|
"%{prj.location}/src/**.h",
|
||||||
|
"%{prj.location}/src/**.hpp",
|
||||||
"%{prj.location}/src/**.c",
|
"%{prj.location}/src/**.c",
|
||||||
"%{prj.location}/src/**.cpp",
|
"%{prj.location}/src/**.cpp",
|
||||||
"%{prj.location}/src/**.glsl",
|
"%{prj.location}/src/**.glsl",
|
||||||
|
@ -21,11 +22,22 @@ project "SHADE_Application"
|
||||||
|
|
||||||
includedirs
|
includedirs
|
||||||
{
|
{
|
||||||
"%{IncludeDir.spdlog}/include",
|
|
||||||
"../SHADE_Engine/src",
|
"../SHADE_Engine/src",
|
||||||
"src"
|
"src",
|
||||||
|
"%{IncludeDir.dotnet}/include",
|
||||||
|
"%{IncludeDir.SDL}/include",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
externalincludedirs
|
||||||
|
{
|
||||||
|
"%{IncludeDir.spdlog}/include",
|
||||||
|
"%{IncludeDir.VULKAN}/include",
|
||||||
|
"%{IncludeDir.VMA}/include",
|
||||||
|
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect"
|
||||||
|
}
|
||||||
|
|
||||||
|
externalwarnings "Off"
|
||||||
|
|
||||||
flags
|
flags
|
||||||
{
|
{
|
||||||
"MultiProcessorCompile"
|
"MultiProcessorCompile"
|
||||||
|
@ -33,11 +45,26 @@ project "SHADE_Application"
|
||||||
|
|
||||||
links
|
links
|
||||||
{
|
{
|
||||||
"SHADE_Engine"
|
"SHADE_Engine",
|
||||||
|
"SHADE_Managed",
|
||||||
|
"SDL2.lib",
|
||||||
|
"SDL2main.lib"
|
||||||
}
|
}
|
||||||
|
|
||||||
postbuildcommands
|
libdirs
|
||||||
{
|
{
|
||||||
|
"%{IncludeDir.spdlog}/lib",
|
||||||
|
"%{IncludeDir.SDL}/lib",
|
||||||
|
}
|
||||||
|
|
||||||
|
defines
|
||||||
|
{
|
||||||
|
"NOMINMAX"
|
||||||
|
}
|
||||||
|
|
||||||
|
disablewarnings
|
||||||
|
{
|
||||||
|
"4251"
|
||||||
}
|
}
|
||||||
|
|
||||||
warnings 'Extra'
|
warnings 'Extra'
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
#include "SBpch.h"
|
#include "SBpch.h"
|
||||||
#include "SBApplication.h"
|
#include "SBApplication.h"
|
||||||
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
|
|
||||||
|
#define SHEDITOR
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
#include "Editor/SHEditor.h"
|
//#include "Editor/SHEditor.h"
|
||||||
#include "Scenes/SBEditorScene.h"
|
//#include "Scenes/SBEditorScene.h"
|
||||||
#endif // SHEDITOR
|
#endif // SHEDITOR
|
||||||
|
|
||||||
#include "Math/SHMath.h"
|
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLogger.h"
|
||||||
|
#include "Tools/SHFileUtilties.h"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <ratio>
|
#include <ratio>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
|
||||||
namespace Sandbox
|
namespace Sandbox
|
||||||
{
|
{
|
||||||
|
@ -24,32 +29,56 @@ namespace Sandbox
|
||||||
_In_ INT nCmdShow
|
_In_ INT nCmdShow
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Set working directory
|
||||||
|
SHADE::SHFileUtilities::SetWorkDirToExecDir();
|
||||||
|
|
||||||
SHADE::SHQuaternion aroundZ20{ SHADE::SHVec3::UnitZ, SHADE::SHMath::DegreesToRadians(20.0f) };
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
SHLOG_INFO("Angle is {}", SHADE::SHMath::RadiansToDegrees(aroundZ20.GetAngle()))
|
|
||||||
|
|
||||||
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
window.Create(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
||||||
|
SHADE::SHSystemManager::CreateSystem<SHADE::SHGraphicsSystem>();
|
||||||
|
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
||||||
|
SHADE::SHSystemManager::RegisterRoutine<SHADE::SHGraphicsSystem, SHADE::SHGraphicsSystem::SHGraphicsSystemRoutine>(1);
|
||||||
|
|
||||||
|
|
||||||
|
graphicsSystem->SetWindow(&window);
|
||||||
|
SDL_CreateWindowFrom(window.GetHWND());
|
||||||
|
|
||||||
|
SHADE::SHSystemManager::Init();
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
|
//SHADE::SHEditor::Initialize(window.GetHWND());
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Set up scripting
|
||||||
|
SHADE::SHScriptEngine::Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBApplication::Update(void)
|
void SBApplication::Update(void)
|
||||||
{
|
{
|
||||||
|
SHADE::SHGraphicsSystem* graphicsSystem = static_cast<SHADE::SHGraphicsSystem*>(SHADE::SHSystemManager::GetSystem<SHADE::SHGraphicsSystem>());
|
||||||
|
|
||||||
//TODO: Change true to window is open
|
//TODO: Change true to window is open
|
||||||
while (!window.WindowShouldClose())
|
while (!window.WindowShouldClose())
|
||||||
{
|
{
|
||||||
#ifdef SHEDITOR
|
//#ifdef SHEDITOR
|
||||||
#else
|
//SHADE::SHEditor::PreRender();
|
||||||
#endif
|
//#endif
|
||||||
}
|
graphicsSystem->BeginRender();
|
||||||
|
graphicsSystem->Run(1.0f);
|
||||||
|
//#ifdef SHEDITOR
|
||||||
|
//SHADE::SHEditor::PreRender();
|
||||||
|
//SHADE::SHEditor::Update();
|
||||||
|
//SHADE::SHEditor::Render();
|
||||||
|
//#endif
|
||||||
|
graphicsSystem->EndRender();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SBApplication::Exit(void)
|
void SBApplication::Exit(void)
|
||||||
{
|
{
|
||||||
|
SHADE::SHScriptEngine::Exit();
|
||||||
|
SHADE::SHSystemManager::Exit();
|
||||||
|
SDL_DestroyWindow(sdlWindow);
|
||||||
#ifdef SHEDITOR
|
#ifdef SHEDITOR
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef SB_APPLICATION_H
|
#ifndef SB_APPLICATION_H
|
||||||
#define SB_APPLICATION_H
|
#define SB_APPLICATION_H
|
||||||
#include <Graphics/Windowing/SHWindow.h>
|
#include <Graphics/Windowing/SHWindow.h>
|
||||||
|
#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
|
||||||
|
#include <SDL_video.h>
|
||||||
//using namespace SHADE;
|
//using namespace SHADE;
|
||||||
|
|
||||||
namespace Sandbox
|
namespace Sandbox
|
||||||
|
@ -9,6 +11,7 @@ namespace Sandbox
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SHADE::SHWindow window;
|
SHADE::SHWindow window;
|
||||||
|
SDL_Window* sdlWindow;
|
||||||
//SHAppConfig config;
|
//SHAppConfig config;
|
||||||
public:
|
public:
|
||||||
SBApplication() = default;
|
SBApplication() = default;
|
||||||
|
|
|
@ -26,15 +26,15 @@ INT WINAPI wWinMain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const SHADE::SHLogger::Config LOGGER_CONFIG{ .directoryPath = "./logs/" };
|
const SHADE::SHLogger::Config LOGGER_CONFIG{ .directoryPath = "./logs/" };
|
||||||
SHADE::SHLogger::Initialise(LOGGER_CONFIG);
|
auto logger = SHADE::SHLogger::Initialise(LOGGER_CONFIG);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#ifndef SHEDITOR
|
#ifndef SHEDITOR
|
||||||
//ShowWindow(::GetConsoleWindow(), SW_HIDE);
|
//ShowWindow(::GetConsoleWindow(), SW_HIDE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SHLOG_INFO("sup")
|
SHLOG_REGISTER(logger)
|
||||||
|
|
||||||
SHADE::SHEngine::Run<Sandbox::SBApplication>(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
SHADE::SHEngine::Run<Sandbox::SBApplication>(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
||||||
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
project "SHADE_Engine"
|
project "SHADE_Engine"
|
||||||
kind "StaticLib"
|
kind "SharedLib"
|
||||||
language "C++"
|
language "C++"
|
||||||
cppdialect "C++latest"
|
cppdialect "C++20"
|
||||||
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
|
targetdir (outputdir)
|
||||||
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
|
objdir (interdir)
|
||||||
systemversion "latest"
|
systemversion "latest"
|
||||||
pchheader "SHpch.h"
|
pchheader "SHpch.h"
|
||||||
pchsource "%{prj.location}/src/SHpch.cpp"
|
pchsource "%{prj.location}/src/SHpch.cpp"
|
||||||
|
@ -12,16 +12,20 @@ project "SHADE_Engine"
|
||||||
files
|
files
|
||||||
{
|
{
|
||||||
"%{prj.location}/src/**.h",
|
"%{prj.location}/src/**.h",
|
||||||
|
"%{prj.location}/src/**.hpp",
|
||||||
"%{prj.location}/src/**.c",
|
"%{prj.location}/src/**.c",
|
||||||
"%{prj.location}/src/**.cpp",
|
"%{prj.location}/src/**.cpp",
|
||||||
"%{prj.location}/src/**.glsl",
|
"%{prj.location}/src/**.glsl"
|
||||||
"%{wks.location}/Dependencies/stb_image/**.cpp"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
includedirs
|
includedirs
|
||||||
{
|
{
|
||||||
"%{prj.location}/src",
|
"%{prj.location}/src",
|
||||||
"%{IncludeDir.assimp}/include",
|
}
|
||||||
|
|
||||||
|
externalincludedirs
|
||||||
|
{
|
||||||
|
"%{IncludeDir.assimp}/include",
|
||||||
"%{IncludeDir.imgui}",
|
"%{IncludeDir.imgui}",
|
||||||
"%{IncludeDir.imguizmo}",
|
"%{IncludeDir.imguizmo}",
|
||||||
"%{IncludeDir.imnodes}",
|
"%{IncludeDir.imnodes}",
|
||||||
|
@ -31,13 +35,16 @@ project "SHADE_Engine"
|
||||||
"%{IncludeDir.tracy}",
|
"%{IncludeDir.tracy}",
|
||||||
"%{IncludeDir.VMA}/include",
|
"%{IncludeDir.VMA}/include",
|
||||||
"%{IncludeDir.yamlcpp}",
|
"%{IncludeDir.yamlcpp}",
|
||||||
"%{IncludeDir.ktx}/include",
|
"%{IncludeDir.SDL}/include",
|
||||||
"%{IncludeDir.RTTR}/include",
|
"%{IncludeDir.RTTR}/include",
|
||||||
"%{IncludeDir.reactphysics3d}/include",
|
"%{IncludeDir.reactphysics3d}/include",
|
||||||
"%{IncludeDir.VULKAN}/include",
|
"%{IncludeDir.VULKAN}/include",
|
||||||
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect"
|
"%{IncludeDir.VULKAN}/Source/SPIRV-Reflect",
|
||||||
|
"%{IncludeDir.dotnet}/include",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
externalwarnings "Off"
|
||||||
|
|
||||||
libdirs
|
libdirs
|
||||||
{
|
{
|
||||||
"%{prj.location}/libs",
|
"%{prj.location}/libs",
|
||||||
|
@ -45,8 +52,8 @@ project "SHADE_Engine"
|
||||||
"%{IncludeDir.assimp}/lib/Debug",
|
"%{IncludeDir.assimp}/lib/Debug",
|
||||||
"%{IncludeDir.assimp}/lib/Release",
|
"%{IncludeDir.assimp}/lib/Release",
|
||||||
"%{IncludeDir.RTTR}/lib",
|
"%{IncludeDir.RTTR}/lib",
|
||||||
"%{IncludeDir.ktx}/lib/Debug",
|
"%{IncludeDir.SDL}/lib",
|
||||||
"%{IncludeDir.ktx}/lib/Release",
|
"%{IncludeDir.spdlog}/lib"
|
||||||
}
|
}
|
||||||
|
|
||||||
links
|
links
|
||||||
|
@ -56,9 +63,16 @@ project "SHADE_Engine"
|
||||||
"msdf-atlas-gen",
|
"msdf-atlas-gen",
|
||||||
"reactphysics3d",
|
"reactphysics3d",
|
||||||
"imgui",
|
"imgui",
|
||||||
"spdlog",
|
|
||||||
"vulkan-1.lib",
|
"vulkan-1.lib",
|
||||||
"shaderc_shared.lib"
|
"SDL2.lib",
|
||||||
|
"SDL2main.lib",
|
||||||
|
"shaderc_shared.lib",
|
||||||
|
"shlwapi.lib"
|
||||||
|
}
|
||||||
|
|
||||||
|
disablewarnings
|
||||||
|
{
|
||||||
|
"4251"
|
||||||
}
|
}
|
||||||
|
|
||||||
defines
|
defines
|
||||||
|
@ -66,7 +80,8 @@ project "SHADE_Engine"
|
||||||
"_LIB",
|
"_LIB",
|
||||||
"_GLFW_INCLUDE_NONE",
|
"_GLFW_INCLUDE_NONE",
|
||||||
"MSDFGEN_USE_CPP11",
|
"MSDFGEN_USE_CPP11",
|
||||||
"NOMINMAX"
|
"NOMINMAX",
|
||||||
|
"SH_API_EXPORT"
|
||||||
}
|
}
|
||||||
|
|
||||||
flags
|
flags
|
||||||
|
@ -81,7 +96,13 @@ project "SHADE_Engine"
|
||||||
"msdf-atlas-gen",
|
"msdf-atlas-gen",
|
||||||
"reactphysics3d",
|
"reactphysics3d",
|
||||||
"imgui",
|
"imgui",
|
||||||
"spdlog",
|
}
|
||||||
|
|
||||||
|
postbuildcommands
|
||||||
|
{
|
||||||
|
"xcopy /s /r /y /q \"%{IncludeDir.spdlog}/bin\" \"$(OutDir)\"",
|
||||||
|
"xcopy /r /y /q \"%{IncludeDir.SDL}/lib/SDL2.dll\" \"$(OutDir)\"",
|
||||||
|
"xcopy /s /r /y /q \"%{IncludeDir.dotnet}/bin\" \"$(OutDir)\""
|
||||||
}
|
}
|
||||||
|
|
||||||
warnings 'Extra'
|
warnings 'Extra'
|
||||||
|
@ -89,11 +110,11 @@ project "SHADE_Engine"
|
||||||
filter "configurations:Debug"
|
filter "configurations:Debug"
|
||||||
symbols "On"
|
symbols "On"
|
||||||
defines {"_DEBUG"}
|
defines {"_DEBUG"}
|
||||||
links{"assimp-vc142-mtd.lib", "ktxd.lib", "librttr_core_d.lib"}
|
links{"assimp-vc142-mtd.lib", "librttr_core_d.lib", "spdlogd.lib"}
|
||||||
--links{"fmodstudioL_vc.lib", "fmodL_vc.lib"}
|
--links{"fmodstudioL_vc.lib", "fmodL_vc.lib"}
|
||||||
|
|
||||||
filter "configurations:Release"
|
filter "configurations:Release"
|
||||||
optimize "On"
|
optimize "On"
|
||||||
defines{"_RELEASE"}
|
defines{"_RELEASE"}
|
||||||
links{"assimp-vc142-mt.lib", "ktx.lib", "librttr_core.lib"}
|
links{"assimp-vc142-mt.lib", "librttr_core.lib", "spdlog.lib"}
|
||||||
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
--links{"fmodstudio_vc.lib", "fmod_vc.lib"}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHCommonTypes.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 8, 2022
|
||||||
|
\brief Contains the definitions of type alias for commonly used units for
|
||||||
|
clarity and convenience.
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Type used to mark a value that is supposed to represent a size in bytes.
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
using Byte = size_t;
|
||||||
|
}
|
|
@ -9,18 +9,18 @@
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef SH_COMPONENT_H
|
#pragma once
|
||||||
#define SH_COMPONENT_H
|
|
||||||
|
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "../SHECSMacros.h"
|
#include "../SHECSMacros.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
class SHComponentManager;
|
class SHComponentManager;
|
||||||
|
|
||||||
class SHComponent
|
class SH_API SHComponent
|
||||||
{
|
{
|
||||||
friend SHComponentManager;
|
friend SHComponentManager;
|
||||||
|
|
||||||
|
@ -118,4 +118,3 @@ namespace SHADE
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHComponentGroup.h"
|
#include "SHComponentGroup.h"
|
||||||
#include "../System/SHComponentManager.h"
|
#include "../Managers/SHComponentManager.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
|
|
@ -12,9 +12,7 @@
|
||||||
consent of DigiPen Institute of Technology is prohibited.
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef SH_COMPONENT_GROUP
|
|
||||||
#define SH_COMPONENT_GROUP
|
|
||||||
|
|
||||||
#include "../SHECSMacros.h"
|
#include "../SHECSMacros.h"
|
||||||
#include "../General/SHFamily.h"
|
#include "../General/SHFamily.h"
|
||||||
|
@ -180,6 +178,3 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHEntity.h"
|
#include "SHEntity.h"
|
||||||
#include "../System/SHEntityManager.h"
|
#include "../Managers/SHEntityManager.h"
|
||||||
//#include "Scene/SHSceneGraph.h"
|
//#include "Scene/SHSceneGraph.h"
|
||||||
#include "../System/SHComponentManager.h"
|
#include "../Managers/SHComponentManager.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ namespace SHADE
|
||||||
//SHEntityManager::RemoveEntity(this->entityID);
|
//SHEntityManager::RemoveEntity(this->entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityID SHEntity::GetEID() noexcept
|
EntityID SHEntity::GetEID() const noexcept
|
||||||
{
|
{
|
||||||
return this->entityID;
|
return this->entityID;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,10 @@ namespace SHADE
|
||||||
SHComponentManager::SetActive(entityID, active);
|
SHComponentManager::SetActive(entityID, active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SHEntity::GetActive(void) const noexcept
|
||||||
|
{
|
||||||
|
return isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHEntity::SetParent(SHEntity* newParent) noexcept
|
void SHEntity::SetParent(SHEntity* newParent) noexcept
|
||||||
|
@ -53,20 +57,20 @@ namespace SHADE
|
||||||
//TODO
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
SHEntity* SHEntity::GetParent() noexcept
|
SHEntity* SHEntity::GetParent()const noexcept
|
||||||
{
|
{
|
||||||
//TODO
|
//TODO
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<SHEntity*>const& SHEntity::GetChildren() noexcept
|
std::vector<SHEntity*>const& SHEntity::GetChildren()const noexcept
|
||||||
{
|
{
|
||||||
//TODO
|
//TODO
|
||||||
return std::vector<SHEntity*>{};
|
return std::vector<SHEntity*>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<EntityID>const& SHEntity::GetChildrenID() noexcept
|
std::vector<EntityID>const& SHEntity::GetChildrenID()const noexcept
|
||||||
{
|
{
|
||||||
return std::vector<EntityID>{};
|
return std::vector<EntityID>{};
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,13 @@
|
||||||
consent of DigiPen Institute of Technology is prohibited.
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
#ifndef SH_ENTITY_H
|
#pragma once
|
||||||
#define SH_ENTITY_H
|
|
||||||
|
|
||||||
#include "../SHECSMacros.h"
|
#include "../SHECSMacros.h"
|
||||||
#include "../Components/SHComponent.h"
|
#include "../Components/SHComponent.h"
|
||||||
#include "../System/SHComponentManager.h"
|
#include "../Managers/SHComponentManager.h"
|
||||||
//#include "../../Scene/SHSceneNode.h"
|
//#include "../../Scene/SHSceneNode.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ namespace SHADE
|
||||||
class SHComponentManager;
|
class SHComponentManager;
|
||||||
class SHEntityManager;
|
class SHEntityManager;
|
||||||
|
|
||||||
class SHEntity
|
class SH_API SHEntity
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ namespace SHADE
|
||||||
* Returns nullptr if the entity does not have such Component.
|
* Returns nullptr if the entity does not have such Component.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::enable_if_t<std::is_base_of_v<SHComponent, T>, T*> GetComponent() noexcept
|
std::enable_if_t<std::is_base_of_v<SHComponent, T>, T*> GetComponent()const noexcept
|
||||||
{
|
{
|
||||||
|
|
||||||
return SHComponentManager::GetComponent_s<T>(entityID);
|
return SHComponentManager::GetComponent_s<T>(entityID);
|
||||||
|
@ -77,7 +77,7 @@ namespace SHADE
|
||||||
* \return uint32_t
|
* \return uint32_t
|
||||||
* The entityID of this Entity object.
|
* The entityID of this Entity object.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
EntityID GetEID() noexcept;
|
EntityID GetEID() const noexcept;
|
||||||
|
|
||||||
/*!*************************************************************************
|
/*!*************************************************************************
|
||||||
* \brief Set the Active object
|
* \brief Set the Active object
|
||||||
|
@ -91,6 +91,7 @@ namespace SHADE
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
virtual void SetActive(bool active) noexcept;
|
virtual void SetActive(bool active) noexcept;
|
||||||
|
|
||||||
|
bool GetActive(void)const noexcept;
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -124,7 +125,7 @@ namespace SHADE
|
||||||
* Returns a pointer to the parent entity.
|
* Returns a pointer to the parent entity.
|
||||||
* Returns a nullptr if the parent node is the root node.
|
* Returns a nullptr if the parent node is the root node.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
SHEntity* GetParent() noexcept;
|
SHEntity* GetParent()const noexcept;
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -133,7 +134,7 @@ namespace SHADE
|
||||||
* \return
|
* \return
|
||||||
* Return a vector of SHEntity pointers of the children belonging to this entity.
|
* Return a vector of SHEntity pointers of the children belonging to this entity.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
std::vector<SHEntity*>const& GetChildren() noexcept;
|
std::vector<SHEntity*>const& GetChildren()const noexcept;
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* \brief
|
* \brief
|
||||||
|
@ -141,11 +142,13 @@ namespace SHADE
|
||||||
* \return
|
* \return
|
||||||
* return a vector of EntityID of the children belonging to this entity.
|
* return a vector of EntityID of the children belonging to this entity.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
std::vector<EntityID>const& GetChildrenID() noexcept;
|
std::vector<EntityID>const& GetChildrenID()const noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
//Name of the entity. This name is non-unique and only used for the editor.
|
||||||
std::string name;
|
std::string name;
|
||||||
bool isActive;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -156,8 +159,10 @@ namespace SHADE
|
||||||
EntityID entityID;
|
EntityID entityID;
|
||||||
|
|
||||||
|
|
||||||
|
//Entity active state. This should only be set using the SetActive function which will
|
||||||
|
//set the active state of all components of this entity.
|
||||||
|
bool isActive;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ECS_Base/Entity/SHEntity.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHEntityCreationEvent
|
||||||
|
{
|
||||||
|
EntityID eid;
|
||||||
|
std::vector<ComponentTypeID> componentTypeIDs;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ECS_Base/Entity/SHEntity.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHEntityDestroyedEvent
|
||||||
|
{
|
||||||
|
EntityID eid;
|
||||||
|
};
|
||||||
|
}
|
|
@ -11,8 +11,7 @@
|
||||||
consent of DigiPen Institute of Technology is prohibited.
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
#ifndef SH_FAMILY_H
|
#pragma once
|
||||||
#define SH_FAMILY_H
|
|
||||||
|
|
||||||
#include "../SHECSMacros.h"
|
#include "../SHECSMacros.h"
|
||||||
|
|
||||||
|
@ -82,7 +81,3 @@ namespace SHADE
|
||||||
ComponentTypeID SHFamilyID<BaseClass>::currentID = 0;
|
ComponentTypeID SHFamilyID<BaseClass>::currentID = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -11,8 +11,7 @@
|
||||||
or disclosure of this file or its contents without the prior written
|
or disclosure of this file or its contents without the prior written
|
||||||
consent of DigiPen Institute of Technology is prohibited.
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
#ifndef SH_HANDLE_GENERATOR_H
|
#pragma once
|
||||||
#define SH_HANDLE_GENERATOR_H
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -300,6 +299,3 @@ namespace SHADE
|
||||||
typedef SHHandleGenerator<EntityID, EntityIndex> EntityHandleGenerator;
|
typedef SHHandleGenerator<EntityID, EntityIndex> EntityHandleGenerator;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -10,8 +10,7 @@
|
||||||
consent of DigiPen Institute of Technology is prohibited.
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
#ifndef SH_SPARSE_BASE_H
|
#pragma once
|
||||||
#define SH_SPARSE_BASE_H
|
|
||||||
|
|
||||||
#include "../SHECSMacros.h"
|
#include "../SHECSMacros.h"
|
||||||
|
|
||||||
|
@ -45,6 +44,3 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -9,8 +9,7 @@
|
||||||
or disclosure of this file or its contents without the prior written
|
or disclosure of this file or its contents without the prior written
|
||||||
consent of DigiPen Institute of Technology is prohibited.
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
#ifndef SH_SPARSE_SET_H
|
#pragma once
|
||||||
#define SH_SPARSE_SET_H
|
|
||||||
|
|
||||||
#include "../SHECSMacros.h"
|
#include "../SHECSMacros.h"
|
||||||
#include "../General/SHSparseBase.h"
|
#include "../General/SHSparseBase.h"
|
||||||
|
@ -352,5 +351,3 @@ namespace SHADE
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -10,8 +10,7 @@
|
||||||
consent of DigiPen Institute of Technology is prohibited.
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
#ifndef SH_SPARSE_SET_CONTAINER_H
|
#pragma once
|
||||||
#define SH_SPARSE_SET_CONTAINER_H
|
|
||||||
|
|
||||||
#include "SHSparseSet.h"
|
#include "SHSparseSet.h"
|
||||||
#include "SHFamily.h"
|
#include "SHFamily.h"
|
||||||
|
@ -243,6 +242,3 @@ namespace SHADE
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -12,20 +12,22 @@
|
||||||
consent of DigiPen Institute of Technology is prohibited.
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
#ifndef SH_ENGINE_H
|
#pragma once
|
||||||
#define SH_ENGINE_H
|
|
||||||
|
|
||||||
#include "../General/SHSparseSetContainer.h"
|
#include "../General/SHSparseSetContainer.h"
|
||||||
#include "../Components/SHComponent.h"
|
#include "../Components/SHComponent.h"
|
||||||
#include "../Components/SHComponentGroup.h"
|
#include "../Components/SHComponentGroup.h"
|
||||||
//#include "Scene/SHSceneNode.h"
|
//#include "Scene/SHSceneNode.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
class SHComponentManager
|
typedef SHFamilyID<SHComponent> ComponentFamily;
|
||||||
|
|
||||||
|
class SH_API SHComponentManager
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -38,6 +40,8 @@ namespace SHADE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* \brief
|
* \brief
|
||||||
* This is called by the SHSceneNode friend class to change the parent
|
* This is called by the SHSceneNode friend class to change the parent
|
||||||
|
@ -225,7 +229,7 @@ namespace SHADE
|
||||||
* \return
|
* \return
|
||||||
* none
|
* none
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void AddComponent(EntityID entityID, uint32_t componentTypeID) noexcept
|
static void AddComponent(EntityID entityID, ComponentTypeID componentTypeID) noexcept
|
||||||
{
|
{
|
||||||
componentSet.GetSparseSet_ID(componentTypeID)->Add(EntityHandleGenerator::GetIndex(entityID));
|
componentSet.GetSparseSet_ID(componentTypeID)->Add(EntityHandleGenerator::GetIndex(entityID));
|
||||||
|
|
||||||
|
@ -277,7 +281,7 @@ namespace SHADE
|
||||||
* \return bool
|
* \return bool
|
||||||
* True if the entity has a component of specified type.
|
* True if the entity has a component of specified type.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static bool HasComponent_ID(EntityID entityID, uint32_t componentTypeID) noexcept;
|
static bool HasComponent_ID(EntityID entityID, ComponentTypeID componentTypeID) noexcept;
|
||||||
|
|
||||||
|
|
||||||
/*!*************************************************************************
|
/*!*************************************************************************
|
||||||
|
@ -362,7 +366,7 @@ namespace SHADE
|
||||||
* \return
|
* \return
|
||||||
*
|
*
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void SwapInDenseByIndexHash_ID(EntityIndex index, EntityID hash, uint32_t componentTypeID) noexcept;
|
static void SwapInDenseByIndexHash_ID(EntityIndex index, EntityID hash, ComponentTypeID componentTypeID) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -385,7 +389,7 @@ namespace SHADE
|
||||||
* \return
|
* \return
|
||||||
* The number of components in the component sparse set.
|
* The number of components in the component sparse set.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static EntityIndex ComponentCount_ID(uint32_t componentTypeID)
|
static EntityIndex ComponentCount_ID(ComponentTypeID componentTypeID)
|
||||||
{
|
{
|
||||||
return componentSet.GetSparseSet_ID(componentTypeID)->Count();
|
return componentSet.GetSparseSet_ID(componentTypeID)->Count();
|
||||||
}
|
}
|
||||||
|
@ -402,9 +406,9 @@ namespace SHADE
|
||||||
static void SetActive(EntityID entityID, bool active) noexcept;
|
static void SetActive(EntityID entityID, bool active) noexcept;
|
||||||
|
|
||||||
template<typename... T>
|
template<typename... T>
|
||||||
static std::enable_if_t<(... && std::is_base_of_v<SHComponent, T>), uint32_t> CreateComponentGroup(uint32_t numOwningComponents)
|
static std::enable_if_t<(... && std::is_base_of_v<SHComponent, T>), uint32_t> CreateComponentGroup(ComponentTypeID numOwningComponents)
|
||||||
{
|
{
|
||||||
std::vector<uint32_t> templateIDs{ (SHFamilyID<SHComponent>::GetID<T>())... };
|
std::vector<ComponentTypeID> templateIDs{ (ComponentFamily::GetID<T>())... };
|
||||||
|
|
||||||
for (auto& g : componentGroups)
|
for (auto& g : componentGroups)
|
||||||
{
|
{
|
||||||
|
@ -421,11 +425,11 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
SHComponentGroup grp;
|
SHComponentGroup grp;
|
||||||
for (uint32_t i = 0; i < numOwningComponents; ++i)
|
for (ComponentTypeID i = 0; i < numOwningComponents; ++i)
|
||||||
{
|
{
|
||||||
grp.ownedComponentTypes.push_back(templateIDs[i]);
|
grp.ownedComponentTypes.push_back(templateIDs[i]);
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < templateIDs.size(); ++i)
|
for (ComponentTypeID i = 0; i < templateIDs.size(); ++i)
|
||||||
{
|
{
|
||||||
grp.componentTypeIDs.push_back(templateIDs[i]);
|
grp.componentTypeIDs.push_back(templateIDs[i]);
|
||||||
}
|
}
|
||||||
|
@ -472,6 +476,3 @@ namespace SHADE
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -52,63 +52,20 @@ namespace SHADE
|
||||||
return entityHandle.GetIndex(entityID);
|
return entityHandle.GetIndex(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityID SHEntityManager::CreateEntity(std::vector<uint32_t>const& componentTypeIDs, std::string const& name,EntityID parentEID)
|
|
||||||
{
|
|
||||||
EntityID eID = entityHandle.GetNewHandle();
|
|
||||||
EntityIndex eIndex = entityHandle.GetIndex(eID);
|
|
||||||
if (eIndex > entityVec.size())
|
|
||||||
{
|
|
||||||
assert("FATAL ERROR: EntityIndex out of range in Entity Creation");
|
|
||||||
}
|
|
||||||
else if (eIndex == entityVec.size())
|
|
||||||
{
|
|
||||||
entityVec.emplace_back(std::make_unique<SHEntity>());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!entityVec[eIndex])
|
|
||||||
{
|
|
||||||
//There is still an entity stored there.Something went wrong
|
|
||||||
assert("FATAL ERROR: Entity Creation error. Entity Index Conflict");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Reset it to a newly constructed entity
|
|
||||||
entityVec[eIndex].reset(new SHEntity());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
entityVec[eIndex]->entityID = eID;
|
|
||||||
entityVec[eIndex]->name = name;
|
|
||||||
for (auto& id : componentTypeIDs)
|
|
||||||
{
|
|
||||||
SHComponentManager::AddComponent(eID, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//(SHComponentManager::AddComponent<ComponentTypes>(eID), ...);
|
|
||||||
/*if (entityHandle.IsValid(parentEID) == false)
|
|
||||||
{
|
|
||||||
entityVec[eIndex]->sceneNode.ConnectToRoot();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entityVec[eIndex]->SetParent(parentEID);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
//TODO Link to Scene graph.
|
|
||||||
|
|
||||||
return eID;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityID SHEntityManager::CreateEntity(std::vector<uint32_t>const& componentTypeIDs, EntityID desiredEID, std::string const& name, EntityID parentEID)
|
EntityID SHEntityManager::CreateEntity(std::vector<uint32_t>const& componentTypeIDs, EntityID desiredEID, std::string const& name, EntityID parentEID)
|
||||||
{
|
{
|
||||||
EntityID eID ;
|
EntityID eID;
|
||||||
|
if (desiredEID == MAX_EID)
|
||||||
if (entityHandle.ClaimHandle(desiredEID) == true)
|
{
|
||||||
eID = desiredEID;
|
|
||||||
else
|
|
||||||
eID = entityHandle.GetNewHandle();
|
eID = entityHandle.GetNewHandle();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (entityHandle.ClaimHandle(desiredEID) == true)
|
||||||
|
eID = desiredEID;
|
||||||
|
else
|
||||||
|
eID = entityHandle.GetNewHandle();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EntityIndex eIndex = entityHandle.GetIndex(eID);
|
EntityIndex eIndex = entityHandle.GetIndex(eID);
|
||||||
|
@ -146,6 +103,10 @@ namespace SHADE
|
||||||
SHComponentManager::AddComponent(eID, id);
|
SHComponentManager::AddComponent(eID, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//set up event stuff
|
||||||
|
SHEntityCreationEvent event{ eID,componentTypeIDs };
|
||||||
|
SHEventManager::BroadcastEvent<SHEntityCreationEvent>(event, SH_ENTITY_CREATION_EVENT);
|
||||||
|
|
||||||
//(SHComponentManager::AddComponent<ComponentTypes>(eID), ...);
|
//(SHComponentManager::AddComponent<ComponentTypes>(eID), ...);
|
||||||
|
|
||||||
//if (entityHandle.IsValid(parentEID) == false)
|
//if (entityHandle.IsValid(parentEID) == false)
|
||||||
|
@ -196,6 +157,12 @@ namespace SHADE
|
||||||
entityHandle.RemoveHandle(eID);
|
entityHandle.RemoveHandle(eID);
|
||||||
|
|
||||||
entityVec[eIndex].reset(nullptr);
|
entityVec[eIndex].reset(nullptr);
|
||||||
|
|
||||||
|
|
||||||
|
SHEntityDestroyedEvent event{eID};
|
||||||
|
SHEventManager::BroadcastEvent<SHEntityDestroyedEvent>(event, SH_ENTITY_DESTROYED_EVENT);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -12,9 +12,7 @@
|
||||||
or disclosure of this file or its contents without the prior written
|
or disclosure of this file or its contents without the prior written
|
||||||
consent of DigiPen Institute of Technology is prohibited.
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
#pragma once
|
||||||
#ifndef SH_ENTITY_MANAGER_H
|
|
||||||
#define SH_ENTITY_MANAGER_H
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -22,11 +20,15 @@
|
||||||
#include "../Components/SHComponent.h"
|
#include "../Components/SHComponent.h"
|
||||||
#include "../General/SHHandleGenerator.h"
|
#include "../General/SHHandleGenerator.h"
|
||||||
#include "../SHECSMacros.h"
|
#include "../SHECSMacros.h"
|
||||||
|
#include "ECS_Base/Events/SHEntityCreationEvent.h"
|
||||||
|
#include "ECS_Base/Events/SHEntityDestroyedEvent.h"
|
||||||
|
#include "Events/SHEventManager.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
class SHEntityManager
|
class SH_API SHEntityManager
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static std::vector<std::unique_ptr<SHEntity>> entityVec;
|
static std::vector<std::unique_ptr<SHEntity>> entityVec;
|
||||||
|
@ -81,55 +83,21 @@ namespace SHADE
|
||||||
* EntityID of the new Entity
|
* EntityID of the new Entity
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
template<typename ...ComponentTypes>
|
template<typename ...ComponentTypes>
|
||||||
static std::enable_if_t<(... && std::is_base_of_v<SHComponent, ComponentTypes>), EntityID> CreateEntity(std::string const& name = "Default", EntityID parentEID = MAX_EID)
|
static std::enable_if_t<(... && std::is_base_of_v<SHComponent, ComponentTypes>), EntityID> CreateEntity(EntityID desiredEID = MAX_EID, std::string const& name = "Default", EntityID parentEID = MAX_EID)
|
||||||
{
|
|
||||||
EntityID eID = entityHandle.GetNewHandle();
|
|
||||||
EntityIndex eIndex = entityHandle.GetIndex(eID);
|
|
||||||
if (eIndex > entityVec.size())
|
|
||||||
{
|
|
||||||
assert("FATAL ERROR: EntityIndex out of range in Entity Creation");
|
|
||||||
}
|
|
||||||
else if (eIndex == entityVec.size())
|
|
||||||
{
|
|
||||||
entityVec.emplace_back(std::make_unique<SHEntity>());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!entityVec[eIndex])
|
|
||||||
{
|
|
||||||
//There is still an entity stored there.Something went wrong
|
|
||||||
assert("FATAL ERROR: Entity Creation error. Entity Index Conflict");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Reset it to a newly constructed entity
|
|
||||||
entityVec[eIndex].reset(new SHEntity());
|
|
||||||
}
|
|
||||||
entityVec[eIndex]->entityID = eID;
|
|
||||||
entityVec[eIndex]->name = name;
|
|
||||||
(SHComponentManager::AddComponent<ComponentTypes>(eID),...);
|
|
||||||
|
|
||||||
/*if (entityHandle.IsValid(parentEID) == false)
|
|
||||||
{
|
|
||||||
entityVec[eIndex]->sceneNode.ConnectToRoot();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entityVec[eIndex]->SetParent(parentEID);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//TODO Link up with Scene graph
|
|
||||||
|
|
||||||
return eID;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ...ComponentTypes>
|
|
||||||
static std::enable_if_t<(... && std::is_base_of_v<SHComponent, ComponentTypes>), EntityID> CreateEntity(EntityID desiredEID, std::string const& name = "Default", EntityID parentEID = MAX_EID)
|
|
||||||
{
|
{
|
||||||
EntityID eID;
|
EntityID eID;
|
||||||
if (entityHandle.ClaimHandle(desiredEID) == true)
|
if (desiredEID == MAX_EID)
|
||||||
eID = desiredEID;
|
{
|
||||||
else
|
|
||||||
eID = entityHandle.GetNewHandle();
|
eID = entityHandle.GetNewHandle();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (entityHandle.ClaimHandle(desiredEID) == true)
|
||||||
|
eID = desiredEID;
|
||||||
|
else
|
||||||
|
eID = entityHandle.GetNewHandle();
|
||||||
|
}
|
||||||
|
|
||||||
EntityIndex eIndex = entityHandle.GetIndex(eID);
|
EntityIndex eIndex = entityHandle.GetIndex(eID);
|
||||||
if (eIndex > entityVec.size())
|
if (eIndex > entityVec.size())
|
||||||
{
|
{
|
||||||
|
@ -160,6 +128,14 @@ namespace SHADE
|
||||||
entityVec[eIndex]->name = name;
|
entityVec[eIndex]->name = name;
|
||||||
(SHComponentManager::AddComponent<ComponentTypes>(eID), ...);
|
(SHComponentManager::AddComponent<ComponentTypes>(eID), ...);
|
||||||
|
|
||||||
|
//set up event stuff
|
||||||
|
std::vector<ComponentTypeID> typeIDVec;
|
||||||
|
(typeIDVec.push_back(ComponentFamily::GetID<ComponentTypes>()), ...);
|
||||||
|
|
||||||
|
SHEntityCreationEvent event{ eID,typeIDVec };
|
||||||
|
SHEventManager::BroadcastEvent<SHEntityCreationEvent>(event, SH_ENTITY_CREATION_EVENT);
|
||||||
|
|
||||||
|
|
||||||
/*if (entityHandle.IsValid(parentEID) == false)
|
/*if (entityHandle.IsValid(parentEID) == false)
|
||||||
{
|
{
|
||||||
entityVec[eIndex]->sceneNode.ConnectToRoot();
|
entityVec[eIndex]->sceneNode.ConnectToRoot();
|
||||||
|
@ -179,21 +155,6 @@ namespace SHADE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* \brief
|
|
||||||
* Create Entity using a vector of ComponentTypeIDs.
|
|
||||||
* \param componentTypeIDs
|
|
||||||
* Vector of ComponentTypeIDs. This assumes that CreateSparseSet is called
|
|
||||||
* for these ComponentTypes.
|
|
||||||
* \param name
|
|
||||||
* Name of the Entity (this is not unique)
|
|
||||||
* \param parentEID
|
|
||||||
* The entity ID of the parent. This does not call UpdateHierarchy hence
|
|
||||||
* the parent of the entity is not updated until UpdateHierarchy is called.
|
|
||||||
* \return
|
|
||||||
* EntityID of the new Entity
|
|
||||||
***************************************************************************/
|
|
||||||
static EntityID CreateEntity(std::vector<ComponentTypeID>const& componentTypeIDs,std::string const& name = "Default", EntityID parentEID = MAX_EID);
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* \brief
|
* \brief
|
||||||
|
@ -209,7 +170,7 @@ namespace SHADE
|
||||||
* \return
|
* \return
|
||||||
* EntityID of the new Entity
|
* EntityID of the new Entity
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static EntityID CreateEntity(std::vector<ComponentTypeID>const& componentTypeIDs, EntityID desiredEID, std::string const& name = "Default", EntityID parentEID = MAX_EID);
|
static EntityID CreateEntity(std::vector<ComponentTypeID>const& componentTypeIDs, EntityID desiredEID = MAX_EID, std::string const& name = "Default", EntityID parentEID = MAX_EID);
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* \brief
|
* \brief
|
||||||
|
@ -247,7 +208,3 @@ namespace SHADE
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* \file SHSystemManager.cpp
|
||||||
|
* \author Daniel Chua Yee Chen
|
||||||
|
* \brief Implementation for the SHSystemManager class.
|
||||||
|
* SHSystemManager is the interface class where users of the engine create
|
||||||
|
* the systems that gives the components their functionality. This also
|
||||||
|
* ensures that the Init and Exit functions are ran at the appropriate time
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 DigiPen Institute of Technology. Reproduction
|
||||||
|
or disclosure of this file or its contents without the prior written
|
||||||
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
|
*********************************************************************/
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHSystemManager.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <ratio>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHSystemManager::SystemContainer SHSystemManager::systemContainer;
|
||||||
|
SHSystemManager::SystemRoutineContainer SHSystemManager::systemRoutineContainer;
|
||||||
|
|
||||||
|
void SHSystemManager::Init() noexcept
|
||||||
|
{
|
||||||
|
for (auto& system : systemContainer)
|
||||||
|
{
|
||||||
|
system.second->Init();
|
||||||
|
#ifdef _DEBUG
|
||||||
|
std::cout << system.first << " Init" << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHSystemManager::RunRoutines(bool editorPause, double deltaTime) noexcept
|
||||||
|
{
|
||||||
|
for (auto& routine : systemRoutineContainer)
|
||||||
|
{
|
||||||
|
if (editorPause == true)
|
||||||
|
{
|
||||||
|
if (routine.get()->IsRunInEditorPause)
|
||||||
|
{
|
||||||
|
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
|
||||||
|
routine.get()->Execute(deltaTime);
|
||||||
|
std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
|
||||||
|
routine.get()->stats.executionTime = std::chrono::duration<double, std::milli>(end - start).count();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
|
||||||
|
routine.get()->Execute(deltaTime);
|
||||||
|
std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now();
|
||||||
|
routine.get()->stats.executionTime = std::chrono::duration<double, std::milli>(end - start).count();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHSystemManager::Exit() noexcept
|
||||||
|
{
|
||||||
|
systemRoutineContainer.clear();
|
||||||
|
|
||||||
|
for (SystemContainer::reverse_iterator it = systemContainer.rbegin(); it != systemContainer.rend(); ++it)
|
||||||
|
{
|
||||||
|
(*it).second->Exit();
|
||||||
|
//delete system.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
systemContainer.clear();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -10,29 +10,33 @@
|
||||||
consent of DigiPen Institute of Technology is prohibited.
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef SH_SYSTEM_MANAGER_H
|
|
||||||
#define SH_SYSTEM_MANAGER_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <climits>
|
||||||
#include "../System/SHSystem.h"
|
#include "../System/SHSystem.h"
|
||||||
|
#include "../General/SHFamily.h"
|
||||||
|
#include "../System/SHSystemRoutine.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
class SHSystemManager
|
|
||||||
|
typedef SHFamilyID<SHSystem> SystemFamily;
|
||||||
|
|
||||||
|
class SH_API SHSystemManager
|
||||||
{
|
{
|
||||||
//type definition for the container we use to store our system
|
//type definition for the container we use to store our system
|
||||||
using SystemContainer = std::unordered_map<std::string, std::unique_ptr<SHSystem>>;
|
using SystemContainer = std::map<SystemID, std::unique_ptr<SHSystem>>;
|
||||||
|
using SystemRoutineContainer = std::vector<std::unique_ptr<SHSystemRoutine>>;
|
||||||
private:
|
private:
|
||||||
static SystemContainer systemContainer;
|
static SystemContainer systemContainer;
|
||||||
|
static SystemRoutineContainer systemRoutineContainer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!*************************************************************************
|
/*!*************************************************************************
|
||||||
|
@ -52,15 +56,21 @@ namespace SHADE
|
||||||
* none
|
* none
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static std::enable_if_t<std::is_base_of_v<SHSystem, T>, void> CreateSystem(std::string const& name)
|
static std::enable_if_t<std::is_base_of_v<SHSystem, T>, SystemID> CreateSystem()
|
||||||
{
|
{
|
||||||
if (systemContainer.find(name) != systemContainer.end())
|
SystemTypeID typeID = SystemFamily::GetID<T>();
|
||||||
|
|
||||||
|
SystemVersionID version = 0;
|
||||||
|
SystemID id = ((SystemID)version << sizeof(SystemVersionID) * CHAR_BIT) + typeID;
|
||||||
|
while (systemContainer.find(id) != systemContainer.end())
|
||||||
{
|
{
|
||||||
assert("System Creation Error: System with the same name already exist.");
|
++version;
|
||||||
|
id = ((SystemID)version << sizeof(SystemVersionID) * CHAR_BIT) + typeID;
|
||||||
}
|
}
|
||||||
|
systemContainer.emplace(id, std::make_unique<T>());
|
||||||
|
systemContainer[id].get()->systemID = id;
|
||||||
|
|
||||||
systemContainer.emplace(name, std::make_unique<T>());
|
return id;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +82,21 @@ namespace SHADE
|
||||||
* \return
|
* \return
|
||||||
* Base System pointer.
|
* Base System pointer.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static SHSystem* GetSystem(std::string name);
|
template<typename T>
|
||||||
|
static std::enable_if_t<std::is_base_of_v<SHSystem, T>, T*> GetSystem(SystemVersionID version = 0)
|
||||||
|
{
|
||||||
|
SystemTypeID typeID = SystemFamily::GetID<T>();
|
||||||
|
|
||||||
|
SystemID id = ((SystemID)version << sizeof(SystemVersionID) * CHAR_BIT) + typeID;
|
||||||
|
|
||||||
|
if (systemContainer.find(id) == systemContainer.end())
|
||||||
|
{
|
||||||
|
std::cout << "System Manager error: System Version " << version << " does not exit." << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (T*)systemContainer.find(id)->second.get();
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* \brief
|
* \brief
|
||||||
|
@ -82,6 +106,20 @@ namespace SHADE
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void Init() noexcept;
|
static void Init() noexcept;
|
||||||
|
|
||||||
|
static void RunRoutines(bool editorPause, double deltaTime) noexcept;
|
||||||
|
|
||||||
|
template<typename SystemType, typename RoutineType>
|
||||||
|
static void RegisterRoutine(SystemVersionID version = 0) noexcept
|
||||||
|
{
|
||||||
|
SHSystem* system = GetSystem<SystemType>(version);
|
||||||
|
if (system == nullptr)
|
||||||
|
return;
|
||||||
|
systemRoutineContainer.emplace_back(std::make_unique<RoutineType>());
|
||||||
|
systemRoutineContainer.back().get()->system = system;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* \brief
|
* \brief
|
||||||
* Call the Exit function of all systems.
|
* Call the Exit function of all systems.
|
||||||
|
@ -96,7 +134,3 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -9,6 +9,10 @@
|
||||||
typedef uint32_t EntityID;
|
typedef uint32_t EntityID;
|
||||||
typedef uint16_t EntityIndex;
|
typedef uint16_t EntityIndex;
|
||||||
typedef uint32_t ComponentTypeID;
|
typedef uint32_t ComponentTypeID;
|
||||||
|
typedef uint32_t SystemTypeID;
|
||||||
|
typedef uint32_t SystemVersionID;
|
||||||
|
typedef uint64_t SystemID;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const EntityIndex MAX_EID = 51000;
|
const EntityIndex MAX_EID = 51000;
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHFixedSystemRoutine.h"
|
||||||
|
#include "../SHECSMacros.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
void SHFixedSystemRoutine::Execute(double dt) noexcept
|
||||||
|
{
|
||||||
|
accumulatedTime += dt;
|
||||||
|
int counter = 0;
|
||||||
|
while (accumulatedTime >= fixedTimeStep)
|
||||||
|
{
|
||||||
|
++counter;
|
||||||
|
accumulatedTime -= fixedTimeStep;
|
||||||
|
FixedExecute(fixedTimeStep);
|
||||||
|
}
|
||||||
|
stats.numSteps = counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include "SHSystemRoutine.h"
|
||||||
|
#define DEFAULT_FIXED_STEP 1.0/60.0
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHFixedSystemRoutine: public SHSystemRoutine
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double accumulatedTime;
|
||||||
|
double fixedTimeStep;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SHFixedSystemRoutine(double timeStep = DEFAULT_FIXED_STEP, std::string routineName = "Default Fixed Routine Name", bool editorPause = false)
|
||||||
|
:SHSystemRoutine(routineName, editorPause), accumulatedTime(0.0), fixedTimeStep(timeStep){}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
~SHFixedSystemRoutine() = default;
|
||||||
|
|
||||||
|
virtual void Execute(double dt) noexcept;
|
||||||
|
|
||||||
|
virtual void FixedExecute(double dt) noexcept {};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHRoutineStats
|
||||||
|
{
|
||||||
|
SHRoutineStats(std::string name)
|
||||||
|
:name(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
std::string name;
|
||||||
|
double executionTime;
|
||||||
|
int numSteps{1};
|
||||||
|
|
||||||
|
//friend std::ostream& operator<<(std::ostream& os, const SHRoutineStats& stats);
|
||||||
|
};
|
||||||
|
|
||||||
|
//std::ostream& operator<<(std::ostream& os, const SHRoutineStats& stats)
|
||||||
|
//{
|
||||||
|
// os << stats.name << ": Execution Time: " << stats.executionTime << " Number of steps: " << stats.numSteps << std::endl;
|
||||||
|
// return os;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -8,13 +8,20 @@
|
||||||
consent of DigiPen Institute of Technology is prohibited.
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
#ifndef SH_SYSTEM_H
|
#pragma once
|
||||||
#define SH_SYSTEM_H
|
|
||||||
|
#include "../SHECSMacros.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class SHSystemManager;
|
||||||
|
|
||||||
class SHSystem
|
class SHSystem
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
SystemID systemID;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*!*************************************************************************
|
/*!*************************************************************************
|
||||||
* \brief
|
* \brief
|
||||||
|
@ -22,6 +29,9 @@ namespace SHADE
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
SHSystem()= default;
|
SHSystem()= default;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!*************************************************************************
|
/*!*************************************************************************
|
||||||
* \brief
|
* \brief
|
||||||
|
@ -35,13 +45,13 @@ namespace SHADE
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
virtual void Init() = 0;
|
virtual void Init() = 0;
|
||||||
|
|
||||||
/*!*************************************************************************
|
///*!*************************************************************************
|
||||||
* \brief
|
// * \brief
|
||||||
* Pure virtual Run function. Derived class must implement this
|
// * Pure virtual Run function. Derived class must implement this
|
||||||
* \param dt
|
// * \param dt
|
||||||
* Delta time
|
// * Delta time
|
||||||
***************************************************************************/
|
//***************************************************************************/
|
||||||
virtual void Run(float dt) = 0;
|
//virtual void Run(float dt) = 0;
|
||||||
|
|
||||||
/*!*************************************************************************
|
/*!*************************************************************************
|
||||||
* \brief
|
* \brief
|
||||||
|
@ -49,7 +59,14 @@ namespace SHADE
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
virtual void Exit() = 0;
|
virtual void Exit() = 0;
|
||||||
|
|
||||||
};
|
friend class SHSystemManager;
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
inline SystemID GetSystemID(void) const noexcept { return systemID; }
|
||||||
|
inline SystemVersionID GetSystemVersion(void) const noexcept { return static_cast<SystemVersionID>(systemID >> sizeof(SystemVersionID) * CHAR_BIT); }
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,57 +0,0 @@
|
||||||
/*********************************************************************
|
|
||||||
* \file SHSystemManager.cpp
|
|
||||||
* \author Daniel Chua Yee Chen
|
|
||||||
* \brief Implementation for the SHSystemManager class.
|
|
||||||
* SHSystemManager is the interface class where users of the engine create
|
|
||||||
* the systems that gives the components their functionality. This also
|
|
||||||
* ensures that the Init and Exit functions are ran at the appropriate time
|
|
||||||
*
|
|
||||||
* \copyright Copyright (c) 2021 DigiPen Institute of Technology. Reproduction
|
|
||||||
or disclosure of this file or its contents without the prior written
|
|
||||||
consent of DigiPen Institute of Technology is prohibited.
|
|
||||||
*********************************************************************/
|
|
||||||
#include "SHpch.h"
|
|
||||||
#include "SHSystemManager.h"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace SHADE
|
|
||||||
{
|
|
||||||
SHSystemManager::SystemContainer SHSystemManager::systemContainer;
|
|
||||||
|
|
||||||
|
|
||||||
SHSystem* SHSystemManager::GetSystem(std::string name)
|
|
||||||
{
|
|
||||||
if (systemContainer.find(name) == systemContainer.end())
|
|
||||||
{
|
|
||||||
assert("Get System Error: No system with such name exist.");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return systemContainer.find(name)->second.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHSystemManager::Init() noexcept
|
|
||||||
{
|
|
||||||
for (auto& system : systemContainer)
|
|
||||||
{
|
|
||||||
system.second->Init();
|
|
||||||
#ifdef _DEBUG
|
|
||||||
std::cout << system.first << " Init" << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHSystemManager::Exit() noexcept
|
|
||||||
{
|
|
||||||
for (auto& system : systemContainer)
|
|
||||||
{
|
|
||||||
system.second->Exit();
|
|
||||||
//delete system.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
systemContainer.clear();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHSystemRoutine.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
SHSystem* SHSystemRoutine::GetSystem() const noexcept
|
||||||
|
{
|
||||||
|
return system;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string const SHSystemRoutine::GetName()const noexcept
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHRoutineStats const& SHSystemRoutine::GetStats()const noexcept
|
||||||
|
{
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../SHECSMacros.h"
|
||||||
|
#include "SHRoutineStats.h"
|
||||||
|
#include "SHSystem.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
class SHSystemManager;
|
||||||
|
|
||||||
|
|
||||||
|
class SHSystemRoutine
|
||||||
|
{
|
||||||
|
friend class SHSystemManager;
|
||||||
|
protected:
|
||||||
|
|
||||||
|
SHSystemRoutine(std::string routineName = "Default Routine Name", bool editorPause = false)
|
||||||
|
:system(nullptr), name(routineName), stats(routineName),IsRunInEditorPause(editorPause){};
|
||||||
|
|
||||||
|
|
||||||
|
SHSystem* system;
|
||||||
|
std::string name;
|
||||||
|
SHRoutineStats stats;
|
||||||
|
|
||||||
|
//Whether or not this routine should run when the editor is still in pause
|
||||||
|
bool IsRunInEditorPause;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
~SHSystemRoutine() = default;
|
||||||
|
|
||||||
|
|
||||||
|
SHSystem* GetSystem()const noexcept;
|
||||||
|
std::string const GetName() const noexcept;
|
||||||
|
SHRoutineStats const& GetStats()const noexcept;
|
||||||
|
|
||||||
|
virtual void Execute(double dt) noexcept {};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,181 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHECSUnitTest.h"
|
||||||
|
#include "../Managers/SHComponentManager.h"
|
||||||
|
#include "../Managers/SHEntityManager.h"
|
||||||
|
#include "../Managers/SHSystemManager.h"
|
||||||
|
#include "SHTestComponents.h"
|
||||||
|
#include "SHTestSystems.h"
|
||||||
|
#include "Tools/SHLogger.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
void SHECSUnitTest::TestAll(void) noexcept
|
||||||
|
{
|
||||||
|
TestBasicEntityCreate();
|
||||||
|
TestEntityCreateTemplate();
|
||||||
|
TestEntityDestroy();
|
||||||
|
TestSystemRoutine();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHECSUnitTest::TestBasicEntityCreate(void) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHComponent_A>();
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHComponent_B>();
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHComponent_C>();
|
||||||
|
|
||||||
|
SHLOG_INFO("Test for add and remove component")
|
||||||
|
|
||||||
|
EntityID id1 = SHEntityManager::CreateEntity();
|
||||||
|
EntityID id2 = SHEntityManager::CreateEntity();
|
||||||
|
EntityID id3 = SHEntityManager::CreateEntity();
|
||||||
|
|
||||||
|
|
||||||
|
SHComponentManager::AddComponent<SHComponent_A>(id1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHECSUnitTest::TestEntityCreateTemplate(void) noexcept
|
||||||
|
{
|
||||||
|
std::cout << "\nTest2" << std::endl;
|
||||||
|
//Test entity Creation.
|
||||||
|
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHComponent_A>();
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHComponent_B>();
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHComponent_C>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 10000; ++i)
|
||||||
|
{
|
||||||
|
switch (i % 3)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
SHEntityManager::CreateEntity<SHComponent_A, SHComponent_B>();
|
||||||
|
}break;
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
SHEntityManager::CreateEntity<SHComponent_A, SHComponent_C>();
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
SHEntityManager::CreateEntity<SHComponent_A>();
|
||||||
|
}break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto& denseA = SHComponentManager::GetDense<SHComponent_A>();
|
||||||
|
auto& denseB = SHComponentManager::GetDense<SHComponent_B>();
|
||||||
|
auto& denseC = SHComponentManager::GetDense<SHComponent_C>();
|
||||||
|
|
||||||
|
std::cout << "Test Entity Creation" << std::endl;
|
||||||
|
std::cout << "dense A size: " << denseA.size() << ((denseA.size() == 10000) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "dense B size: " << denseB.size() << ((denseB.size() == 3334) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "dense C size: " << denseC.size() << ((denseC.size() == 3333) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "Number of entities: " << SHEntityManager::GetEntityCount() << (SHEntityManager::GetEntityCount() == 10000 ? " Success" : " Failure") << std::endl;
|
||||||
|
|
||||||
|
SHEntityManager::DestroyAllEntity();
|
||||||
|
std::cout << std::endl << "Test Destroy All Entity" << std::endl;
|
||||||
|
std::cout << "dense A size: " << denseA.size() << ((denseA.size() == 0) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "dense B size: " << denseB.size() << ((denseB.size() == 0) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "dense C size: " << denseC.size() << ((denseC.size() == 0) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "Number of entities: " << SHEntityManager::GetEntityCount() << (SHEntityManager::GetEntityCount() == 0 ? " Success" : " Failure") << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHECSUnitTest::TestEntityDestroy(void) noexcept
|
||||||
|
{
|
||||||
|
std::cout << "\nTest3" << std::endl;
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHComponent_A>();
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHComponent_B>();
|
||||||
|
SHComponentManager::CreateComponentSparseSet<SHComponent_C>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 10000; ++i)
|
||||||
|
{
|
||||||
|
switch (i % 3)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
SHEntityManager::CreateEntity<SHComponent_A, SHComponent_B>();
|
||||||
|
}break;
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
SHEntityManager::CreateEntity<SHComponent_A, SHComponent_C>();
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
SHEntityManager::CreateEntity<SHComponent_A>();
|
||||||
|
}break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SHEntityManager::DestroyEntity(5000);
|
||||||
|
SHEntityManager::DestroyEntity(5001);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
auto& denseA = SHComponentManager::GetDense<SHComponent_A>();
|
||||||
|
auto& denseB = SHComponentManager::GetDense<SHComponent_B>();
|
||||||
|
auto& denseC = SHComponentManager::GetDense<SHComponent_C>();
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << "Test Entity Deletion" << std::endl;
|
||||||
|
std::cout << "dense A size: " << denseA.size() << ((denseA.size() == 9998) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "dense B size: " << denseB.size() << ((denseB.size() == 3333) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "dense C size: " << denseC.size() << ((denseC.size() == 3333) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "Number of entities: " << SHEntityManager::GetEntityCount() << (SHEntityManager::GetEntityCount() == 9998 ? " Success" : " Failure") << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << std::endl << "Test Entity Recreation" << std::endl;
|
||||||
|
EntityID id = SHEntityManager::CreateEntity<SHComponent_C>();
|
||||||
|
std::cout << "dense A size: " << denseA.size() << ((denseA.size() == 9998) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "dense B size: " << denseB.size() << ((denseB.size() == 3333) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "dense C size: " << denseC.size() << ((denseC.size() == 3334) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "Entity ID: " << id << " EntityIndex: " << EntityHandleGenerator::GetIndex(id) << (EntityHandleGenerator::GetIndex(id) == 5001 ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "Number of entities: " << SHEntityManager::GetEntityCount() << (SHEntityManager::GetEntityCount() == 9999 ? " Success" : " Failure") << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
SHEntityManager::DestroyAllEntity();
|
||||||
|
std::cout << std::endl << "Check Destroy All Entity" << std::endl;
|
||||||
|
std::cout << "dense A size: " << denseA.size() << ((denseA.size() == 0) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "dense B size: " << denseB.size() << ((denseB.size() == 0) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "dense C size: " << denseC.size() << ((denseC.size() == 0) ? " Success" : " Failure") << std::endl;
|
||||||
|
std::cout << "Number of entities: " << SHEntityManager::GetEntityCount() << (SHEntityManager::GetEntityCount() == 0 ? " Success" : " Failure") << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHECSUnitTest::TestSystemRoutine(void) noexcept
|
||||||
|
{
|
||||||
|
SHSystemManager::CreateSystem<SHTestSystem>();
|
||||||
|
SHSystemManager::CreateSystem<SHTestSystem>();
|
||||||
|
|
||||||
|
|
||||||
|
SHSystemManager::RegisterRoutine<SHTestSystem, SHTestSystem::SHTestRoutine>(1);
|
||||||
|
|
||||||
|
SHSystemManager::RunRoutines(false, 1.0 / 120.0);
|
||||||
|
|
||||||
|
SHSystemManager::Exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHECSUnitTest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHECSUnitTest() = delete;
|
||||||
|
~SHECSUnitTest() = delete;
|
||||||
|
|
||||||
|
static void TestBasicEntityCreate(void) noexcept;
|
||||||
|
static void TestEntityCreateTemplate(void) noexcept;
|
||||||
|
static void TestEntityDestroy(void) noexcept;
|
||||||
|
static void TestSystemRoutine(void) noexcept;
|
||||||
|
|
||||||
|
static void TestAll(void) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Components/SHComponent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
class SHComponent_A :public SHComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int value{};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SHComponent_B :public SHComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
float x{};
|
||||||
|
float y{};
|
||||||
|
float z{};
|
||||||
|
};
|
||||||
|
|
||||||
|
class SHComponent_C :public SHComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string value{};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "../System/SHSystem.h"
|
||||||
|
#include "../System/SHSystemRoutine.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
class SHTestSystem : public SHSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHTestSystem() {};
|
||||||
|
~SHTestSystem() {};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::string test{ "Test system" };
|
||||||
|
|
||||||
|
void Init() {};
|
||||||
|
void Exit() {};
|
||||||
|
|
||||||
|
class SHTestRoutine : public SHSystemRoutine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHTestRoutine()
|
||||||
|
:SHSystemRoutine("Test System Routine", false) {}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void Execute(double dt) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
std::cout << GetName() << " System Version: " << GetSystem()->GetSystemVersion() << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHEvent.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Event class declaration
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2022 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior written consent
|
||||||
|
* of Digipen Institute of Technology is prohibited.
|
||||||
|
******************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SHEventDefines.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHEvent
|
||||||
|
{
|
||||||
|
SHEventIdentifier type;
|
||||||
|
SHEventHandle handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct SHEventSpec : SHEvent
|
||||||
|
{
|
||||||
|
SHEventSpec(SHEventIdentifier t, SHEventHandle e, T* dp)
|
||||||
|
:SHEvent{ t, e }, data{ dp } {}
|
||||||
|
|
||||||
|
std::shared_ptr<const T> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
using SHEventPtr = std::shared_ptr<SHEvent>;
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
#pragma once
|
||||||
|
#include "SHpch.h"
|
||||||
|
|
||||||
|
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 };
|
|
@ -0,0 +1,101 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHEventManager.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Function Implmentations for SHEventManager
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited
|
||||||
|
******************************************************************************/
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHEventManager.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
std::unordered_map<SHEventIdentifier, ResponseVec> SHEventManager::packageReceiverRegistry;
|
||||||
|
|
||||||
|
SHEventHandle SHEventManager::handleCounter{ 0 };
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param ListenerConstPtr - Const pointer to listener that sent event.
|
||||||
|
* \param EventType - Templated type for every type of event
|
||||||
|
|
||||||
|
* \brief Receives event from the listeners.
|
||||||
|
****************************************************************************/
|
||||||
|
void SHEventManager::CatchEvent(SHEventPtr event)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Do something with the event
|
||||||
|
|
||||||
|
Broadcast(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param ResponseFunction - function pointer from receiver to be passed
|
||||||
|
* into event manager to be called when events are broadcasted.
|
||||||
|
* \param SHEventIdentifier - package type that corresponding subscriber is
|
||||||
|
* subscribing to.
|
||||||
|
|
||||||
|
* \brief Links a function pointer from a subscriber to a particular
|
||||||
|
* package type
|
||||||
|
****************************************************************************/
|
||||||
|
void SHEventManager::SubscribeTo(SHEventIdentifier pkgType, ReceiverPtr receiver)
|
||||||
|
{
|
||||||
|
RegisterReceiverToType(pkgType, receiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void SHEventManager::BroadcastEvent(T data, SHEventIdentifier eventType)
|
||||||
|
{
|
||||||
|
std::shared_ptr<const T> data = std::make_shared<T>(data);
|
||||||
|
|
||||||
|
CatchEvent(
|
||||||
|
reinterpret_cast<SHEventPtr>
|
||||||
|
(
|
||||||
|
std::make_shared<SHEventSpec<T>>(eventType, handleCounter++, data)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param ReceiverPtr - Pointer to receiver
|
||||||
|
* \param ListenerConstPtr - Const pointer to listener that receiver is
|
||||||
|
* subscribing to.
|
||||||
|
|
||||||
|
* \brief Registers receiver as a subscriber to listener in the registry.
|
||||||
|
****************************************************************************/
|
||||||
|
void SHEventManager::RegisterReceiverToType(
|
||||||
|
SHEventIdentifier pkgType, ReceiverPtr receiver)
|
||||||
|
{
|
||||||
|
if (packageReceiverRegistry.contains(pkgType))
|
||||||
|
{
|
||||||
|
packageReceiverRegistry[pkgType].emplace_back(receiver);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packageReceiverRegistry.emplace(pkgType, std::vector{ receiver });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param ListenerConstPtr - Const pointer to listener that sent event.
|
||||||
|
* \param EventType - Event data
|
||||||
|
|
||||||
|
* \brief Broadcast event to all receivers that are subscribed to this
|
||||||
|
* listener.
|
||||||
|
****************************************************************************/
|
||||||
|
void SHEventManager::Broadcast(SHEventPtr event)
|
||||||
|
{
|
||||||
|
ResponseVec& receivers{ packageReceiverRegistry[event->type] };
|
||||||
|
for (auto& receiver : receivers)
|
||||||
|
{
|
||||||
|
receiver->Receive(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
//auto& funcs{ ackageReceiverRegistry[event.GetType()] };
|
||||||
|
//for (auto func : funcs)
|
||||||
|
//{
|
||||||
|
// func(event.GetData());
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHEventManager.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Class declaration for event manager.
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2022 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior written consent
|
||||||
|
* of Digipen Institute of Technology is prohibited.
|
||||||
|
******************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SHEvent.h"
|
||||||
|
#include "SHEventReceiver.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
INSTRUCTIONS FOR USE:
|
||||||
|
On broadcaster side:
|
||||||
|
1. Create a struct/class to contain the data that you would need to send
|
||||||
|
in the event.
|
||||||
|
2. Create unique event identifier in SHEventDefines.h, follow the example
|
||||||
|
provided.
|
||||||
|
3. When ready to send the event, call
|
||||||
|
SHEventManager::BroadcastEvent<ExampleClass>(exampleClass, EVENT_IDENTIFIER);
|
||||||
|
|
||||||
|
NOTE: If your custom struct to contain data requires a deep copy, please
|
||||||
|
overload the assignment operator accordingly. It is fine to send
|
||||||
|
a single object of a basic type such as int/float.
|
||||||
|
|
||||||
|
Headers required: SHEventManager.h
|
||||||
|
|
||||||
|
On Receiver side:
|
||||||
|
1. Create a function with the signature:
|
||||||
|
SHEventHandle FunctionName(SHEventPtr);
|
||||||
|
|
||||||
|
2. In the init function of the class, copy the below in and replace the
|
||||||
|
necessary:
|
||||||
|
|
||||||
|
std::shared_ptr<SHEventReceiverSpec<ReceiverClass>> thisReceiver{
|
||||||
|
std::make_shared<SHEventReceiverSpec<ReceiverClass>>(this, &ReceiverClass::ReceiveFunction)
|
||||||
|
};
|
||||||
|
ReceiverPtr receiver = std::dynamic_pointer_cast<SHEventReceiver>(thisReceiver);
|
||||||
|
SHEventManager::SubscribeTo(EVENT_IDENTIFIER, receiver);
|
||||||
|
|
||||||
|
ReceiverClass is the class that the receiver is in. E.g., SHPhysicsSystem
|
||||||
|
|
||||||
|
3. Note: The EventIdentifier should match all that is defined in
|
||||||
|
SHEventDefines.h so check there. When the receiver catches the event, it
|
||||||
|
needs to know the struct that the broadcaster is using to cast the event
|
||||||
|
ptr as such:
|
||||||
|
|
||||||
|
reinterpret_cast<std::shared_ptr<SHEventSpec<CustomClass>>>(event)
|
||||||
|
|
||||||
|
4. Inside the new ptr should be a shared pointer of const CustomClass type.
|
||||||
|
|
||||||
|
Headers required: SHEventManager.h, SHEventReceiver.h
|
||||||
|
|
||||||
|
If you have any questions/suggestions for improvement lmk.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//using ResponseFunction = std::function<SHEventHandle(SHEventPtr)>;
|
||||||
|
using ReceiverPtr = std::shared_ptr<SHEventReceiver>;
|
||||||
|
using ResponseVec = std::vector<ReceiverPtr>;
|
||||||
|
|
||||||
|
using EventManagerListener = std::function<void(SHEvent)>;
|
||||||
|
|
||||||
|
|
||||||
|
class SHEventManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param ListenerConstPtr - Const pointer to listener that sent event.
|
||||||
|
* \param EventType - Templated type for every type of event
|
||||||
|
|
||||||
|
* \brief Receives event from the listeners.
|
||||||
|
****************************************************************************/
|
||||||
|
static void CatchEvent(SHEventPtr);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param ResponseFunction - function pointer from receiver to be passed
|
||||||
|
* into event manager to be called when events are broadcasted.
|
||||||
|
* \param SHPackageType - package type that corresponding subscriber is
|
||||||
|
* subscribing to.
|
||||||
|
|
||||||
|
* \brief Links a function pointer from a subscriber to a particular
|
||||||
|
* package type
|
||||||
|
****************************************************************************/
|
||||||
|
static void SubscribeTo(SHEventIdentifier, ReceiverPtr);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static void BroadcastEvent(T data, SHEventIdentifier eventType);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Registry for broadcasters and subscribers
|
||||||
|
static std::unordered_map<SHEventIdentifier, ResponseVec> packageReceiverRegistry;
|
||||||
|
|
||||||
|
static SHEventHandle handleCounter;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param ListenerConstPtr - Const pointer to listener that sent event.
|
||||||
|
* \param EventType - Event data
|
||||||
|
|
||||||
|
* \brief Broadcast event to all receivers that are subscribed to this
|
||||||
|
* listener.
|
||||||
|
****************************************************************************/
|
||||||
|
static void Broadcast(SHEventPtr event);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* \param ReceiverPtr - Pointer to receiver
|
||||||
|
* \param ListenerConstPtr - Const pointer to listener that receiver is
|
||||||
|
* subscribing to.
|
||||||
|
|
||||||
|
* \brief Registers receiver as a subscriber to listener in the registry.
|
||||||
|
****************************************************************************/
|
||||||
|
static void RegisterReceiverToType(SHEventIdentifier, ReceiverPtr);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "SHEvent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHEventReceiver
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
public:
|
||||||
|
virtual void Receive(SHEventPtr) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class SHEventReceiverSpec : public SHEventReceiver
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T* object;
|
||||||
|
SHEventHandle(T::*callback)(SHEventPtr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
SHEventReceiverSpec(T* obj, void(T::* cb)(SHEventPtr))
|
||||||
|
:SHEventReceiver(), object{ obj }, callback{ cb }
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Receive(SHEventPtr evt) override
|
||||||
|
{
|
||||||
|
(object->*callback)(evt);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* \file SHFramerateController.cpp
|
||||||
|
* \author Ryan Wang Nian Jing
|
||||||
|
* \brief Definition for functions of the framerate controller
|
||||||
|
* Handles changing of scenes and manages loop (timestep, etc.)
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2022 DigiPen Institute of Technology. Reproduction
|
||||||
|
or disclosure of this file or its contents without the prior written
|
||||||
|
consent of DigiPen Institute of Technology is prohibited.
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <cassert>
|
||||||
|
#include <SHpch.h>
|
||||||
|
#include "SHFramerateController.h"
|
||||||
|
#include "../Tools/SHLogger.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
//Init statics
|
||||||
|
double SHFramerateController::fixedTimestep = 0.01;
|
||||||
|
SHScene* SHFramerateController::previousScene = nullptr;
|
||||||
|
SHScene* SHFramerateController::currentScene = nullptr;
|
||||||
|
SHScene* SHFramerateController::nextScene = nullptr;
|
||||||
|
bool SHFramerateController::toRestart = false;
|
||||||
|
bool SHFramerateController::toQuit = false;
|
||||||
|
|
||||||
|
//Scene manager loop
|
||||||
|
void SHFramerateController::Run(SHScene* firstScene)
|
||||||
|
{
|
||||||
|
if (firstScene == nullptr)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Do not pass a nullptr as the firstScene");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set quit and restart flags to false
|
||||||
|
toQuit = false;
|
||||||
|
toRestart = false;
|
||||||
|
|
||||||
|
//Set the first scene to run
|
||||||
|
previousScene = firstScene;
|
||||||
|
currentScene = firstScene;
|
||||||
|
nextScene = firstScene;
|
||||||
|
|
||||||
|
while (!toQuit)
|
||||||
|
{
|
||||||
|
if (toRestart)
|
||||||
|
{
|
||||||
|
//Restart current scene
|
||||||
|
currentScene = previousScene;
|
||||||
|
nextScene = previousScene;
|
||||||
|
toRestart = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Move to a new scene
|
||||||
|
currentScene->Load();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Call init function of current scene
|
||||||
|
currentScene->Init();
|
||||||
|
|
||||||
|
//Have an initial value
|
||||||
|
//This frame time will fluctuate
|
||||||
|
//SHOULD be larger than the fixed timestep
|
||||||
|
//TODO this might need to be changed
|
||||||
|
double variableLastFrameTime = fixedTimestep;
|
||||||
|
|
||||||
|
//Time accumulator for meshing between fixed and variable timesteps
|
||||||
|
double accumulator = 0.0;
|
||||||
|
|
||||||
|
//Start state loop
|
||||||
|
while (currentScene == nextScene && !toQuit && !toRestart)
|
||||||
|
{
|
||||||
|
//Use of new STL timing functions
|
||||||
|
//https://en.cppreference.com/w/cpp/chrono
|
||||||
|
std::chrono::duration<double> deltaTime;
|
||||||
|
|
||||||
|
auto startTime = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
//Whittle down the accumulator by continuously simulating
|
||||||
|
for (; accumulator > fixedTimestep; accumulator -= fixedTimestep)
|
||||||
|
{
|
||||||
|
MSG msg;
|
||||||
|
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||||
|
{
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO change to double
|
||||||
|
currentScene->Update((float)fixedTimestep);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Interpolation
|
||||||
|
//Manage the alpha value well
|
||||||
|
//https://randomascii.wordpress.com/2012/02/13/dont-store-that-in-a-float/
|
||||||
|
//Key points:
|
||||||
|
//1) Any time you add or subtract floats of widely varying
|
||||||
|
// magnitudes, you need to watch for loss of precision
|
||||||
|
//2) Sometimes using double instead of float is the correct
|
||||||
|
// solution, but often a more stable algorithm is more important
|
||||||
|
//3) calcT() should probably use double (to give sufficient
|
||||||
|
// precision after many hours of gameplay)
|
||||||
|
|
||||||
|
//TODO awaiting approval to use this
|
||||||
|
//double alpha = accumulator / fixedTimestep;
|
||||||
|
|
||||||
|
//assert alpha does not go out of range
|
||||||
|
|
||||||
|
currentScene->Render();
|
||||||
|
|
||||||
|
auto endTime = std::chrono::high_resolution_clock::now();
|
||||||
|
deltaTime = endTime - startTime;
|
||||||
|
variableLastFrameTime = deltaTime.count();
|
||||||
|
|
||||||
|
//Increase accumulator
|
||||||
|
accumulator += variableLastFrameTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Free once out of scene loop
|
||||||
|
currentScene->Free();
|
||||||
|
|
||||||
|
//Check if not to restart state
|
||||||
|
//If so, unload
|
||||||
|
if (!toRestart) currentScene->Unload();
|
||||||
|
|
||||||
|
//Shift forward scenes
|
||||||
|
previousScene = currentScene;
|
||||||
|
currentScene = nextScene;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*********************************************************************
|
||||||
|
* \file SHFramerateController.h
|
||||||
|
* \author Ryan Wang Nian Jing
|
||||||
|
* \brief Declaration for the framerate controller
|
||||||
|
* Handles changing of scenes and manages loop (timestep, etc.)
|
||||||
|
*
|
||||||
|
* \copyright 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.
|
||||||
|
*********************************************************************/
|
||||||
|
|
||||||
|
#ifndef SH_FRAMERATECONTROLLER_H
|
||||||
|
#define SH_FRAMERATECONTROLLER_H
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Scene/SHScene.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHFramerateController
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
//scene pointers
|
||||||
|
static SHScene* previousScene;
|
||||||
|
static SHScene* currentScene;
|
||||||
|
static SHScene* nextScene;
|
||||||
|
|
||||||
|
//Flags
|
||||||
|
//Whether the flag has been raised for the game to be quit
|
||||||
|
static bool toQuit;
|
||||||
|
|
||||||
|
//Whether the flag has been raised for the current scene to restart
|
||||||
|
static bool toRestart;
|
||||||
|
|
||||||
|
public:
|
||||||
|
//Fixed timestep value for physics. Default at 1/100th of a second.
|
||||||
|
//Should be lower than the variable refresh rate
|
||||||
|
static double fixedTimestep;
|
||||||
|
|
||||||
|
//Scene Manager Loop
|
||||||
|
//This loop is vital to the game because it runs for as long as the game
|
||||||
|
//runs. Before entering, initialise vital systems for game. After exiting,
|
||||||
|
//free these vital systems before finishing the main() function and
|
||||||
|
//terminating the game
|
||||||
|
//Parameter of firstScene is what scene the game should start with
|
||||||
|
static void Run(SHScene* firstScene);
|
||||||
|
|
||||||
|
//Set the flag to restart the current game scene
|
||||||
|
static inline void RestartScene() { toRestart = true; }
|
||||||
|
|
||||||
|
//Set the flag to halt running of the scene manager and quit the game
|
||||||
|
static inline void QuitGame() { toQuit = true; }
|
||||||
|
|
||||||
|
//Set the next scene to be excuted
|
||||||
|
//This will tell the scene manager to
|
||||||
|
//halt execution of the current scene and prepare
|
||||||
|
//execution of the next
|
||||||
|
static inline void SetNextScene(SHScene* const next) { nextScene = next; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -33,6 +33,8 @@ namespace SHADE
|
||||||
};
|
};
|
||||||
cmdBufferHdl->GetVkCommandBuffer().copyBuffer(stagingBuffer, vkBuffer, 1, ©Region);
|
cmdBufferHdl->GetVkCommandBuffer().copyBuffer(stagingBuffer, vkBuffer, 1, ©Region);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Need to destroy staging buffer. Obviously not here but after the command has finished executing.
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::Buffer SHVkBuffer::GetVkBuffer(void) const noexcept
|
vk::Buffer SHVkBuffer::GetVkBuffer(void) const noexcept
|
||||||
|
|
|
@ -48,7 +48,6 @@ namespace SHADE
|
||||||
vk::BufferUsageFlags bufferUsageFlags;
|
vk::BufferUsageFlags bufferUsageFlags;
|
||||||
|
|
||||||
//! Reference to the allocator
|
//! Reference to the allocator
|
||||||
//VmaAllocator const& vmaAllocator;
|
|
||||||
std::reference_wrapper<VmaAllocator const> vmaAllocator;
|
std::reference_wrapper<VmaAllocator const> vmaAllocator;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -76,7 +76,10 @@ namespace SHADE
|
||||||
// Check if command buffer is ready to record.
|
// Check if command buffer is ready to record.
|
||||||
if (cmdBufferState != SH_CMD_BUFFER_STATE::INITIAL)
|
if (cmdBufferState != SH_CMD_BUFFER_STATE::INITIAL)
|
||||||
{
|
{
|
||||||
SHLOG_ERROR("Command buffer not in initial state, cannot begin recording. ");
|
SHLOG_ERROR("Command buffer not in initial state, cannot begin recording. Command buffer could be: \n"
|
||||||
|
"- corrupted and in invalid state\n"
|
||||||
|
"- in executable state\n"
|
||||||
|
"- in pending state\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +185,9 @@ namespace SHADE
|
||||||
|
|
||||||
// Check if render area is optimal
|
// Check if render area is optimal
|
||||||
if (!IsRenderAreaOptimal(renderpassHdl, framebufferExtent, renderPassInfo.renderArea))
|
if (!IsRenderAreaOptimal(renderpassHdl, framebufferExtent, renderPassInfo.renderArea))
|
||||||
|
{
|
||||||
SHLOG_ERROR("Render area in renderpass begin info is not optimal. See Vulkan vkGetRenderAreaGranularity for details.");
|
SHLOG_ERROR("Render area in renderpass begin info is not optimal. See Vulkan vkGetRenderAreaGranularity for details.");
|
||||||
|
}
|
||||||
|
|
||||||
// Begin the render pass
|
// Begin the render pass
|
||||||
vkCommandBuffer.beginRenderPass (&renderPassInfo, vk::SubpassContents::eInline);
|
vkCommandBuffer.beginRenderPass (&renderPassInfo, vk::SubpassContents::eInline);
|
||||||
|
@ -202,6 +207,11 @@ namespace SHADE
|
||||||
vkCommandBuffer.endRenderPass();
|
vkCommandBuffer.endRenderPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::NextSubpass(void) noexcept
|
||||||
|
{
|
||||||
|
vkCommandBuffer.nextSubpass(commandBufferType == SH_CMD_BUFFER_TYPE::PRIMARY ? vk::SubpassContents::eInline : vk::SubpassContents::eSecondaryCommandBuffers);
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -406,6 +416,41 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::PipelineBarrier (
|
||||||
|
vk::PipelineStageFlags srcStage,
|
||||||
|
vk::PipelineStageFlags dstStage,
|
||||||
|
vk::DependencyFlags deps,
|
||||||
|
std::vector<vk::MemoryBarrier> const& memoryBarriers,
|
||||||
|
std::vector<vk::BufferMemoryBarrier> const& bufferMemoryBarriers,
|
||||||
|
std::vector<vk::ImageMemoryBarrier> const& imageMemoryBarriers
|
||||||
|
) const noexcept
|
||||||
|
{
|
||||||
|
vkCommandBuffer.pipelineBarrier (
|
||||||
|
srcStage,
|
||||||
|
dstStage,
|
||||||
|
deps,
|
||||||
|
memoryBarriers,
|
||||||
|
bufferMemoryBarriers,
|
||||||
|
imageMemoryBarriers
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHVkCommandBuffer::IsReadyToSubmit(void) const noexcept
|
||||||
|
{
|
||||||
|
return cmdBufferState == SH_CMD_BUFFER_STATE::EXECUTABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHVkCommandBuffer::HandlePostSubmit(void) noexcept
|
||||||
|
{
|
||||||
|
SetState(SH_CMD_BUFFER_STATE::PENDING);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void SHVkCommandBuffer::PipelineBarrier(vk::PipelineStageFlags ) const noexcept
|
||||||
|
//{
|
||||||
|
// //vkCommandBuffer.pipelineBarrier()
|
||||||
|
//}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -463,9 +508,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
vk::Extent2D granularity = parentPool->GetLogicalDevice()->GetVkLogicalDevice().getRenderAreaGranularity(renderpassHdl->GetVkRenderpass());
|
vk::Extent2D granularity = parentPool->GetLogicalDevice()->GetVkLogicalDevice().getRenderAreaGranularity(renderpassHdl->GetVkRenderpass());
|
||||||
|
|
||||||
return (renderArea.offset.x % granularity.width == 0 && renderArea.offset.y % granularity.height == 0 &&
|
return (renderArea.offset.x % granularity.width == 0 && renderArea.offset.y % granularity.height == 0 && (renderArea.extent.width % granularity.width || renderArea.offset.x + renderArea.extent.width == framebufferExtent.width) && (renderArea.extent.height % granularity.height || renderArea.offset.y + renderArea.extent.height == framebufferExtent.height));
|
||||||
(renderArea.extent.width % granularity.width || renderArea.offset.x + renderArea.extent.width == framebufferExtent.width) &&
|
|
||||||
(renderArea.extent.height % granularity.height || renderArea.offset.y + renderArea.extent.height == framebufferExtent.height));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -529,6 +572,7 @@ namespace SHADE
|
||||||
, usageFlags{}
|
, usageFlags{}
|
||||||
, commandBufferCount{ 0 }
|
, commandBufferCount{ 0 }
|
||||||
, parentPool{commandPool}
|
, parentPool{commandPool}
|
||||||
|
, pushConstantData{}
|
||||||
|
|
||||||
{
|
{
|
||||||
vk::CommandBufferAllocateInfo allocateInfo{};
|
vk::CommandBufferAllocateInfo allocateInfo{};
|
||||||
|
|
|
@ -96,11 +96,12 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
|
|
||||||
// Begins and Ends
|
// Begins, Ends and Nexts
|
||||||
void BeginRecording (void) noexcept;
|
void BeginRecording (void) noexcept;
|
||||||
void EndRecording (void) noexcept;
|
void EndRecording (void) noexcept;
|
||||||
void BeginRenderpass (Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> const& framebufferHdl, vk::Offset2D offset = {0, 0}, vk::Extent2D extent = {0, 0}) noexcept;
|
void BeginRenderpass (Handle<SHVkRenderpass> const& renderpassHdl, Handle<SHVkFramebuffer> const& framebufferHdl, vk::Offset2D offset = {0, 0}, vk::Extent2D extent = {0, 0}) noexcept;
|
||||||
void EndRenderpass (void) noexcept;
|
void EndRenderpass (void) noexcept;
|
||||||
|
void NextSubpass (void) noexcept;
|
||||||
|
|
||||||
// Dynamic State
|
// Dynamic State
|
||||||
void SetviewportScissor (float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX = 0.0f, float vpY = 0.0f, int32_t sX = 0.0f, int32_t sY = 0.0f, float vpMinDepth = 0.0f, float vpMaxDepth = 1.0f) noexcept;
|
void SetviewportScissor (float vpWidth, float vpHeight, uint32_t sWidth, uint32_t sHeight, float vpX = 0.0f, float vpY = 0.0f, int32_t sX = 0.0f, int32_t sY = 0.0f, float vpMinDepth = 0.0f, float vpMaxDepth = 1.0f) noexcept;
|
||||||
|
@ -114,6 +115,19 @@ namespace SHADE
|
||||||
void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept;
|
void DrawArrays (uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) const noexcept;
|
||||||
void DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept;
|
void DrawIndexed (uint32_t indexCount, uint32_t firstIndex, uint32_t vertexOffset) const noexcept;
|
||||||
|
|
||||||
|
// memory barriers
|
||||||
|
void PipelineBarrier (
|
||||||
|
vk::PipelineStageFlags srcStage,
|
||||||
|
vk::PipelineStageFlags dstStage,
|
||||||
|
vk::DependencyFlags deps,
|
||||||
|
std::vector<vk::MemoryBarrier> const& memoryBarriers,
|
||||||
|
std::vector<vk::BufferMemoryBarrier> const& bufferMemoryBarriers,
|
||||||
|
std::vector<vk::ImageMemoryBarrier> const& imageMemoryBarriers
|
||||||
|
) const noexcept;
|
||||||
|
|
||||||
|
bool IsReadyToSubmit (void) const noexcept;
|
||||||
|
void HandlePostSubmit (void) noexcept;
|
||||||
|
|
||||||
// Push Constant variable setting
|
// Push Constant variable setting
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void SetPushConstantVariable(std::string variableName, T const& data) noexcept
|
void SetPushConstantVariable(std::string variableName, T const& data) noexcept
|
||||||
|
|
|
@ -150,20 +150,19 @@ namespace SHADE
|
||||||
logicalDeviceHdl->GetVkLogicalDevice().resetCommandPool(vkCommandPool, vk::CommandPoolResetFlagBits::eReleaseResources);
|
logicalDeviceHdl->GetVkLogicalDevice().resetCommandPool(vkCommandPool, vk::CommandPoolResetFlagBits::eReleaseResources);
|
||||||
for (auto& primary : primaries)
|
for (auto& primary : primaries)
|
||||||
{
|
{
|
||||||
if (primary->GetState() != SH_CMD_BUFFER_STATE::PENDING)
|
// #NoteToSelf: Since there is no way to set the state of a command buffer back to initial, we just hard set it to initial. Ditto for secondaries.
|
||||||
primary->SetState(SH_CMD_BUFFER_STATE::INITIAL);
|
//if (primary->GetState() != SH_CMD_BUFFER_STATE::PENDING)
|
||||||
else
|
primary->SetState(SH_CMD_BUFFER_STATE::INITIAL);
|
||||||
SHLOG_ERROR("Primary command buffer in pending state, could not reset. ");
|
|
||||||
|
|
||||||
// From the spec: Any primary command buffer allocated from another VkCommandPool that is in the recording or
|
// From the spec: Any primary command buffer allocated from another VkCommandPool that is in the recording or
|
||||||
// executable state and has a secondary command buffer allocated from commandPool recorded into it,
|
// executable state and has a secondary command buffer allocated from commandPool recorded into it,
|
||||||
// becomes invalid. TODO: Might want to check and throw exception for these conditions after making sure this actually happens using validation layers.
|
// becomes invalid. TODO: Might want to check and throw exception for these conditions after making sure this actually happens using validation layers.
|
||||||
}
|
}
|
||||||
for (auto& secondary : secondaries)
|
for (auto& secondary : secondaries)
|
||||||
{
|
{
|
||||||
if (secondary->GetState() != SH_CMD_BUFFER_STATE::PENDING)
|
//if (secondary->GetState() != SH_CMD_BUFFER_STATE::PENDING)
|
||||||
secondary->SetState(SH_CMD_BUFFER_STATE::INITIAL);
|
secondary->SetState(SH_CMD_BUFFER_STATE::INITIAL);
|
||||||
else
|
|
||||||
SHLOG_ERROR("Secondary command buffer in pending state, could not reset. ");
|
|
||||||
|
|
||||||
// TODO: Ditto from TODO in primary check
|
// TODO: Ditto from TODO in primary check
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVulkanDebugUtil::ReportVkWarning(vk::Result vkResult, std::string_view message, std::source_location const& location /*= std::source_location::current()*/) noexcept
|
void SHVulkanDebugUtil::ReportVkWarning(vk::Result vkResult, std::string_view message) noexcept
|
||||||
{
|
{
|
||||||
//std::cout << location.file_name() << ": " << location.function_name() << "|" << location.line() << "|" <<
|
//std::cout << location.file_name() << ": " << location.function_name() << "|" << location.line() << "|" <<
|
||||||
// location.column() << "|: Warning: " << SHDebugUtil::VkResultToString(vkResult) << " | " << message << std::endl;
|
// location.column() << "|: Warning: " << SHDebugUtil::VkResultToString(vkResult) << " | " << message << std::endl;
|
||||||
|
@ -88,7 +88,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHVulkanDebugUtil::ReportVkError(vk::Result vkResult, std::string_view message, std::source_location const& location /*= std::source_location::current()*/) noexcept
|
void SHVulkanDebugUtil::ReportVkError(vk::Result vkResult, std::string_view message) noexcept
|
||||||
{
|
{
|
||||||
std::string toLogger = "Vulkan Warning: " + std::string(SHVulkanDebugUtil::VkResultToString(vkResult)) + " | " + std::string(message);
|
std::string toLogger = "Vulkan Warning: " + std::string(SHVulkanDebugUtil::VkResultToString(vkResult)) + " | " + std::string(message);
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHVulkanDebugUtil::ReportVkSuccess(std::string_view message, std::source_location const& location /*= std::source_location::current()*/) noexcept
|
void SHVulkanDebugUtil::ReportVkSuccess(std::string_view message) noexcept
|
||||||
{
|
{
|
||||||
SHLOGV_INFO(message);
|
SHLOGV_INFO(message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,9 @@ namespace SHADE
|
||||||
public:
|
public:
|
||||||
static VKAPI_ATTR VkBool32 VKAPI_CALL GenericDebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageSeverityFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData);
|
static VKAPI_ATTR VkBool32 VKAPI_CALL GenericDebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageSeverityFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData);
|
||||||
|
|
||||||
static void ReportVkWarning(vk::Result vkResult, std::string_view message, std::source_location const& location = std::source_location::current()) noexcept;
|
static void ReportVkWarning(vk::Result vkResult, std::string_view message) noexcept;
|
||||||
static void ReportVkError(vk::Result vkResult, std::string_view message, std::source_location const& location = std::source_location::current()) noexcept;
|
static void ReportVkError(vk::Result vkResult, std::string_view message) noexcept;
|
||||||
static void ReportVkSuccess(std::string_view message, std::source_location const& location = std::source_location::current()) noexcept;
|
static void ReportVkSuccess(std::string_view message) noexcept;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHDescriptorSetUpdater.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
SHDescriptorWriteInfo::SHDescriptorWriteInfo(SHDescriptorWriteInfo&& rhs) noexcept
|
||||||
|
: descImageInfos{ std::move(rhs.descImageInfos) }
|
||||||
|
, descBufferInfos{ std::move(rhs.descBufferInfos) }
|
||||||
|
, descTexelBufferInfos{std::move (rhs.descTexelBufferInfos)}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SHDescriptorWriteInfo::SHDescriptorWriteInfo(void) noexcept
|
||||||
|
: descImageInfos{}
|
||||||
|
, descBufferInfos{}
|
||||||
|
, descTexelBufferInfos{}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Links the write infos to the vulkan write descriptor sets.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHDescriptorSetUpdater::LinkInfoToWriteDescSet(void) noexcept
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < writeInfos.size(); ++i)
|
||||||
|
{
|
||||||
|
writeDescSets[i].pImageInfo = writeInfos[i].descImageInfos.data();
|
||||||
|
writeDescSets[i].pBufferInfo = writeInfos[i].descBufferInfos.data();
|
||||||
|
writeDescSets[i].pTexelBufferView = writeInfos[i].descTexelBufferInfos.data();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHDescriptorWriteInfo& SHDescriptorWriteInfo::operator=(SHDescriptorWriteInfo&& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (&rhs == this)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
descImageInfos = std::move(rhs.descImageInfos);
|
||||||
|
descBufferInfos = std::move(rhs.descBufferInfos);
|
||||||
|
descTexelBufferInfos = std::move(rhs.descTexelBufferInfos);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHDescriptorSetUpdater::SHDescriptorSetUpdater(SHDescriptorSetUpdater&& rhs) noexcept
|
||||||
|
: writeInfos{ std::move(rhs.writeInfos) }
|
||||||
|
, writeHashMap {std::move (rhs.writeHashMap)}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SHDescriptorSetUpdater::SHDescriptorSetUpdater(void) noexcept
|
||||||
|
: writeInfos{}
|
||||||
|
, writeHashMap{}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<vk::WriteDescriptorSet> const& SHDescriptorSetUpdater::GetWriteDescriptorSets(void) const noexcept
|
||||||
|
{
|
||||||
|
return writeDescSets;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHDescriptorSetUpdater& SHDescriptorSetUpdater::operator=(SHDescriptorSetUpdater&& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (&rhs == this)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
writeInfos = std::move (rhs.writeInfos);
|
||||||
|
writeHashMap = std::move (rhs.writeHashMap);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
|
#include "Graphics/Shaders/SHShaderReflected.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
// Vulkan doesn't use all of the information when looking at a writeDescriptorSet. It all
|
||||||
|
// depends on the descriptor type. This struct plays it safe by having members that would
|
||||||
|
// accommodate all types of descriptors.
|
||||||
|
class SHDescriptorWriteInfo
|
||||||
|
{
|
||||||
|
//! When we want to update a descriptor that is an image, it goes in here
|
||||||
|
std::vector<vk::DescriptorImageInfo> descImageInfos;
|
||||||
|
|
||||||
|
//! When we want to update a descriptor that is a buffer, it goes in here
|
||||||
|
std::vector<vk::DescriptorBufferInfo> descBufferInfos;
|
||||||
|
|
||||||
|
//! When we want to update a descriptor that is an texel buffer, it goes in here
|
||||||
|
std::vector<vk::BufferView> descTexelBufferInfos;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SHDescriptorWriteInfo (void) noexcept;
|
||||||
|
SHDescriptorWriteInfo (SHDescriptorWriteInfo&& rhs) noexcept;
|
||||||
|
SHDescriptorWriteInfo& operator= (SHDescriptorWriteInfo&& rhs) noexcept;
|
||||||
|
|
||||||
|
friend class SHVkDescriptorSetGroup;
|
||||||
|
friend class SHDescriptorSetUpdater;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SHDescriptorSetUpdater
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
//! When we want to update descriptor sets, this will get passed into vkUpdateDescriptorSets.
|
||||||
|
//! Each write will correspond to a binding from a set. If the binding is a variable
|
||||||
|
//! sized binding, pImageInfo (e.g.) will point to an array of vk::DescriptorImageInfo.
|
||||||
|
std::vector<SHDescriptorWriteInfo> writeInfos;
|
||||||
|
|
||||||
|
//! When we want to update a write, we need to use this to identify the index of the write.
|
||||||
|
std::unordered_map<BindingAndSetHash, uint32_t> writeHashMap;
|
||||||
|
|
||||||
|
//! We keep this here because we want this to be immediately passable to vkUpdateDescriptorSets
|
||||||
|
std::vector<vk::WriteDescriptorSet> writeDescSets;
|
||||||
|
|
||||||
|
void LinkInfoToWriteDescSet(void) noexcept;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SHDescriptorSetUpdater (void) noexcept;
|
||||||
|
SHDescriptorSetUpdater(SHDescriptorSetUpdater&& rhs) noexcept;
|
||||||
|
SHDescriptorSetUpdater& operator= (SHDescriptorSetUpdater&& rhs) noexcept;
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::vector<vk::WriteDescriptorSet> const& GetWriteDescriptorSets (void) const noexcept;
|
||||||
|
|
||||||
|
friend class SHVkDescriptorSetGroup;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -7,32 +7,52 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Constructor/Destructor */
|
/* Constructor/Destructor */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
SHVkDescriptorPool::SHVkDescriptorPool(Handle<SHVkLogicalDevice> device, const Config& config)
|
SHVkDescriptorPool::SHVkDescriptorPool(Handle<SHVkLogicalDevice> device, const Config& config)
|
||||||
: device { device }
|
: device{ device }
|
||||||
|
{
|
||||||
|
// Create the Pool
|
||||||
|
const vk::DescriptorPoolCreateInfo POOL_CREATE_INFO
|
||||||
{
|
{
|
||||||
// Create the Pool
|
.flags = config.Flags,
|
||||||
const vk::DescriptorPoolCreateInfo POOL_CREATE_INFO
|
.maxSets = config.MaxSets,
|
||||||
{
|
.poolSizeCount = static_cast<uint32_t>(config.Limits.size()),
|
||||||
.flags = config.Flags,
|
.pPoolSizes = config.Limits.data()
|
||||||
.maxSets = config.MaxSets,
|
};
|
||||||
.poolSizeCount = static_cast<uint32_t>(config.Limits.size()),
|
pool = device->GetVkLogicalDevice().createDescriptorPool(POOL_CREATE_INFO);
|
||||||
.pPoolSizes = config.Limits.data()
|
}
|
||||||
};
|
|
||||||
pool = device->GetVkLogicalDevice().createDescriptorPool(POOL_CREATE_INFO);
|
|
||||||
}
|
|
||||||
|
|
||||||
SHVkDescriptorPool::~SHVkDescriptorPool() noexcept
|
SHVkDescriptorPool::SHVkDescriptorPool(SHVkDescriptorPool&& rhs) noexcept
|
||||||
{
|
: device{ rhs.device }
|
||||||
if (pool)
|
, pool{ rhs.pool }
|
||||||
device->GetVkLogicalDevice().destroyDescriptorPool(pool);
|
{
|
||||||
}
|
rhs.pool = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Handle<SHVkDescriptorSetGroup>> SHVkDescriptorPool::Allocate(const std::vector<Handle<SHVkDescriptorSetLayout>>& layouts, std::vector<uint32_t> const& variableDescCounts)
|
SHVkDescriptorPool::~SHVkDescriptorPool() noexcept
|
||||||
{
|
{
|
||||||
SHVkInstance::GetResourceManager().Create<SHVkDescriptorSetGroup>(device, GetHandle(), layouts, variableDescCounts);
|
if (pool)
|
||||||
return {};
|
device->GetVkLogicalDevice().destroyDescriptorPool(pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHVkDescriptorPool& SHVkDescriptorPool::operator=(SHVkDescriptorPool&& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (&rhs == this)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
device = rhs.device;
|
||||||
|
pool = rhs.pool;
|
||||||
|
|
||||||
|
rhs.pool = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Handle<SHVkDescriptorSetGroup>> SHVkDescriptorPool::Allocate(const std::vector<Handle<SHVkDescriptorSetLayout>>& layouts, std::vector<uint32_t> const& variableDescCounts)
|
||||||
|
{
|
||||||
|
SHVkInstance::GetResourceManager().Create<SHVkDescriptorSetGroup>(device, GetHandle(), layouts, variableDescCounts);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ namespace SHADE
|
||||||
/// </param>
|
/// </param>
|
||||||
SHVkDescriptorPool(Handle<SHVkLogicalDevice> device, const Config& config = {});
|
SHVkDescriptorPool(Handle<SHVkLogicalDevice> device, const Config& config = {});
|
||||||
SHVkDescriptorPool(const SHVkDescriptorPool&) = delete;
|
SHVkDescriptorPool(const SHVkDescriptorPool&) = delete;
|
||||||
SHVkDescriptorPool(SHVkDescriptorPool&& rhs) noexcept = default;
|
SHVkDescriptorPool(SHVkDescriptorPool&& rhs) noexcept;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Destructor which will unload and deallocate all resources for this Pool.
|
/// Destructor which will unload and deallocate all resources for this Pool.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -75,7 +75,7 @@ namespace SHADE
|
||||||
/* Overloaded Operators */
|
/* Overloaded Operators */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
SHVkDescriptorPool& operator=(const SHVkDescriptorPool&) = delete;
|
SHVkDescriptorPool& operator=(const SHVkDescriptorPool&) = delete;
|
||||||
SHVkDescriptorPool& operator=(SHVkDescriptorPool&& rhs) noexcept = default;
|
SHVkDescriptorPool& operator=(SHVkDescriptorPool&& rhs) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
|
|
|
@ -42,9 +42,11 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
// Create the layout for each concurrent frame
|
// Create the layout for each concurrent frame
|
||||||
std::vector<vk::DescriptorSetLayout> vkLayouts{ layouts.size() };
|
std::vector<vk::DescriptorSetLayout> vkLayouts{ layouts.size() };
|
||||||
for (auto& layout : layouts)
|
|
||||||
|
//for (auto& layout : layouts)
|
||||||
|
for (uint32_t i = 0; i < layouts.size(); ++i)
|
||||||
{
|
{
|
||||||
vkLayouts.push_back(layout->GetVkHandle());
|
vkLayouts.push_back(layouts[i]->GetVkHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for variable descriptor count
|
// Check for variable descriptor count
|
||||||
|
@ -67,6 +69,66 @@ namespace SHADE
|
||||||
|
|
||||||
// allocate descriptor sets
|
// allocate descriptor sets
|
||||||
descSets = device->GetVkLogicalDevice().allocateDescriptorSets(DESC_SET_LAYOUT_CREATE_INFO);
|
descSets = device->GetVkLogicalDevice().allocateDescriptorSets(DESC_SET_LAYOUT_CREATE_INFO);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Now we want to prepare the write descriptor sets for writing later.
|
||||||
|
for (uint32_t i = 0; i < layouts.size(); ++i)
|
||||||
|
{
|
||||||
|
auto const& bindings = layouts[i]->GetBindings();
|
||||||
|
for (auto& binding : bindings)
|
||||||
|
{
|
||||||
|
BindingAndSetHash writeHash = binding.BindPoint;
|
||||||
|
writeHash |= static_cast<uint64_t>(i) << 32;
|
||||||
|
|
||||||
|
// new write for the binding
|
||||||
|
updater.writeInfos.emplace_back();
|
||||||
|
updater.writeHashMap.try_emplace(writeHash, updater.writeInfos.size() - 1);
|
||||||
|
auto& writeInfo = updater.writeInfos.back();
|
||||||
|
|
||||||
|
updater.writeDescSets.emplace_back();
|
||||||
|
auto& writeDescSet = updater.writeDescSets.back();
|
||||||
|
|
||||||
|
// Initialize info for write
|
||||||
|
writeDescSet.descriptorType = binding.Type;
|
||||||
|
writeDescSet.dstArrayElement = 0;
|
||||||
|
writeDescSet.dstSet = descSets[i];
|
||||||
|
writeDescSet.dstBinding = binding.BindPoint;
|
||||||
|
|
||||||
|
// Descriptor count for the write descriptor set. Usually this is set to 1, but if binding is variable sized, set to info passed in
|
||||||
|
uint32_t descriptorCount = (binding.flags & vk::DescriptorBindingFlagBits::eVariableDescriptorCount) ? variableDescCounts[i] : 1;
|
||||||
|
writeDescSet.descriptorCount = descriptorCount;
|
||||||
|
|
||||||
|
switch (binding.Type)
|
||||||
|
{
|
||||||
|
//case vk::DescriptorType::eSampler:
|
||||||
|
//case vk::DescriptorType::eSampledImage:
|
||||||
|
case vk::DescriptorType::eCombinedImageSampler:
|
||||||
|
writeInfo.descImageInfos.resize(descriptorCount);
|
||||||
|
break;
|
||||||
|
//case vk::DescriptorType::eStorageImage:
|
||||||
|
// break;
|
||||||
|
case vk::DescriptorType::eUniformTexelBuffer:
|
||||||
|
case vk::DescriptorType::eStorageTexelBuffer:
|
||||||
|
case vk::DescriptorType::eUniformBuffer:
|
||||||
|
case vk::DescriptorType::eStorageBuffer:
|
||||||
|
writeInfo.descImageInfos.resize (descriptorCount);
|
||||||
|
break;
|
||||||
|
//case vk::DescriptorType::eUniformBufferDynamic:
|
||||||
|
// break;
|
||||||
|
//case vk::DescriptorType::eStorageBufferDynamic:
|
||||||
|
// break;
|
||||||
|
//case vk::DescriptorType::eInputAttachment:
|
||||||
|
// break;
|
||||||
|
//case vk::DescriptorType::eInlineUniformBlock:
|
||||||
|
// break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Link all the writeDescSet data for vkUpdateDescriptorSets to write to the linked descriptors
|
||||||
|
updater.LinkInfoToWriteDescSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -82,4 +144,45 @@ namespace SHADE
|
||||||
if (!descSets.empty())
|
if (!descSets.empty())
|
||||||
device->GetVkLogicalDevice().freeDescriptorSets(descPool->GetVkHandle(), descSets);
|
device->GetVkLogicalDevice().freeDescriptorSets(descPool->GetVkHandle(), descSets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Modifies a descriptor write info. #NoteToSelf: This function does NOT
|
||||||
|
need to modify the writeDescSets. Those are already linked before.
|
||||||
|
|
||||||
|
\param imageViewsAndSamplers
|
||||||
|
Image and view samplers
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHVkDescriptorSetGroup::ModifyWriteDescImage(uint32_t set, uint32_t binding, std::vector<std::pair<vk::ImageView, vk::Sampler>> const& imageViewsAndSamplers) noexcept
|
||||||
|
{
|
||||||
|
// Find the target writeDescSet
|
||||||
|
BindingAndSetHash writeHash = binding;
|
||||||
|
writeHash |= static_cast<uint64_t>(set) << 32;
|
||||||
|
auto& writeInfo = updater.writeInfos[updater.writeHashMap.at(writeHash)];
|
||||||
|
|
||||||
|
if (imageViewsAndSamplers.size() > writeInfo.descImageInfos.size())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Attempting write too many descriptors into descriptor set. Failed to write to vk::WriteDescriptorSet. ");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < imageViewsAndSamplers.size(); ++i)
|
||||||
|
{
|
||||||
|
// write sampler and image view
|
||||||
|
auto& ivs = imageViewsAndSamplers[i];
|
||||||
|
writeInfo.descImageInfos[i].imageView = ivs.first;
|
||||||
|
writeInfo.descImageInfos[i].sampler = ivs.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHVkDescriptorSetGroup::UpdateDescriptorSet(void) noexcept
|
||||||
|
{
|
||||||
|
device->UpdateDescriptorSets(updater.GetWriteDescriptorSets());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,71 +1,89 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Project Includes
|
// Project Includes
|
||||||
#include "Graphics/SHVulkanIncludes.h"
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
#include "Resource/Handle.h"
|
#include "Resource/Handle.h"
|
||||||
|
#include "Graphics/Shaders/SHShaderReflected.h"
|
||||||
|
#include "SHDescriptorSetUpdater.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Forward Declarations */
|
/* Forward Declarations */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
class SHVkLogicalDevice;
|
class SHVkLogicalDevice;
|
||||||
class SHVkDescriptorPool;
|
class SHVkDescriptorPool;
|
||||||
class SHVkDescriptorSetLayout;
|
class SHVkDescriptorSetLayout;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
/* Type Definitions */
|
/*---------------------------------------------------------------------------------*/
|
||||||
/*---------------------------------------------------------------------------------*/
|
/* Type Definitions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
class SHVkDescriptorSetGroup
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Constructor/Destructors */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
/// Constructs a Descriptor Set with the specified layout using the specified
|
||||||
|
/// pool meant for use with the specified surface. This Set will be created with
|
||||||
|
/// multiple Vulkan Descriptor Set objects based on the max number of concurrent
|
||||||
|
/// frames for the specified surface.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class SHVkDescriptorSetGroup
|
/// <param name="device">Vulkan logical device used to create the Set.</param>
|
||||||
{
|
/// <param name="pool">Descriptor Pool used to create the Set.</param>
|
||||||
public:
|
/// <param name="layout">Descriptor Set Layout to create the Set with.</param>
|
||||||
/*-----------------------------------------------------------------------------*/
|
SHVkDescriptorSetGroup(Handle<SHVkLogicalDevice> deviceHdl, Handle<SHVkDescriptorPool> pool,
|
||||||
/* Constructor/Destructors */
|
std::vector<Handle<SHVkDescriptorSetLayout>> const& layouts,
|
||||||
/*-----------------------------------------------------------------------------*/
|
std::vector<uint32_t> const& variableDescCounts);
|
||||||
/// <summary>
|
SHVkDescriptorSetGroup(const SHVkDescriptorSetGroup&) = delete;
|
||||||
/// Constructs a Descriptor Set with the specified layout using the specified
|
SHVkDescriptorSetGroup(SHVkDescriptorSetGroup&& rhs) noexcept = default;
|
||||||
/// pool meant for use with the specified surface. This Set will be created with
|
/// <summary>
|
||||||
/// multiple Vulkan Descriptor Set objects based on the max number of concurrent
|
/// Destructor which will unload and deallocate all resources for this Descriptor Set.
|
||||||
/// frames for the specified surface.
|
/// </summary>
|
||||||
/// </summary>
|
~SHVkDescriptorSetGroup() noexcept;
|
||||||
/// <param name="device">Vulkan logical device used to create the Set.</param>
|
|
||||||
/// <param name="pool">Descriptor Pool used to create the Set.</param>
|
|
||||||
/// <param name="layout">Descriptor Set Layout to create the Set with.</param>
|
|
||||||
SHVkDescriptorSetGroup(Handle<SHVkLogicalDevice> deviceHdl, Handle<SHVkDescriptorPool> pool,
|
|
||||||
std::vector<Handle<SHVkDescriptorSetLayout>> const& layouts,
|
|
||||||
std::vector<uint32_t> const& variableDescCounts);
|
|
||||||
SHVkDescriptorSetGroup(const SHVkDescriptorSetGroup&) = delete;
|
|
||||||
SHVkDescriptorSetGroup(SHVkDescriptorSetGroup&& rhs) noexcept = default;
|
|
||||||
/// <summary>
|
|
||||||
/// Destructor which will unload and deallocate all resources for this Descriptor Set.
|
|
||||||
/// </summary>
|
|
||||||
~SHVkDescriptorSetGroup() noexcept;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Overloaded Operators */
|
/* Overloaded Operators */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
SHVkDescriptorSetGroup& operator=(const SHVkDescriptorSetGroup&) = delete;
|
SHVkDescriptorSetGroup& operator=(const SHVkDescriptorSetGroup&) = delete;
|
||||||
SHVkDescriptorSetGroup& operator=(SHVkDescriptorSetGroup&& rhs) noexcept = default;
|
SHVkDescriptorSetGroup& operator=(SHVkDescriptorSetGroup&& rhs) noexcept = default;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getter Functions */
|
/* Descriptor set writing */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/// <summary>
|
void ModifyWriteDescImage (uint32_t set, uint32_t binding, std::vector<std::pair<vk::ImageView, vk::Sampler>> const& imageViewsAndSamplers) noexcept;
|
||||||
/// Retrieves the handle to the Vulkan Descriptor Set handle.
|
void UpdateDescriptorSet (void) noexcept;
|
||||||
/// </summary>
|
|
||||||
/// <returns>Handle to the Vulkan Descriptor Set.</returns>
|
|
||||||
[[nodiscard]]
|
|
||||||
inline const std::vector<vk::DescriptorSet>& GetVkHandle() { return descSets; }
|
|
||||||
|
|
||||||
private:
|
/*-----------------------------------------------------------------------------*/
|
||||||
/*-----------------------------------------------------------------------------*/
|
/* Getter Functions */
|
||||||
/* Data Members */
|
/*-----------------------------------------------------------------------------*/
|
||||||
/*-----------------------------------------------------------------------------*/
|
/// <summary>
|
||||||
Handle<SHVkLogicalDevice> device;
|
/// Retrieves the handle to the Vulkan Descriptor Set handle.
|
||||||
Handle<SHVkDescriptorPool> descPool;
|
/// </summary>
|
||||||
std::vector<vk::DescriptorSet> descSets;
|
/// <returns>Handle to the Vulkan Descriptor Set.</returns>
|
||||||
};
|
[[nodiscard]]
|
||||||
|
inline const std::vector<vk::DescriptorSet>& GetVkHandle() { return descSets; }
|
||||||
|
private:
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
//! Device required to allocate descriptor sets
|
||||||
|
Handle<SHVkLogicalDevice> device;
|
||||||
|
|
||||||
|
//! Descriptor pool to allocate descriptor sets
|
||||||
|
Handle<SHVkDescriptorPool> descPool;
|
||||||
|
|
||||||
|
//! Descriptor sets
|
||||||
|
std::vector<vk::DescriptorSet> descSets;
|
||||||
|
|
||||||
|
//! for updating descriptor sets. We want to cache this so that we don't create the
|
||||||
|
//! write structs at runtime.
|
||||||
|
SHDescriptorSetUpdater updater;
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,11 @@ namespace SHADE
|
||||||
device->GetVkLogicalDevice().destroyDescriptorSetLayout(setLayout);
|
device->GetVkLogicalDevice().destroyDescriptorSetLayout(setLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<SHVkDescriptorSetLayout::Binding> const& SHVkDescriptorSetLayout::GetBindings(void) const noexcept
|
||||||
|
{
|
||||||
|
return layoutDesc;
|
||||||
|
}
|
||||||
|
|
||||||
SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept
|
SHVkDescriptorSetLayout& SHVkDescriptorSetLayout::operator=(SHVkDescriptorSetLayout&& rhs) noexcept
|
||||||
{
|
{
|
||||||
if (&rhs == this)
|
if (&rhs == this)
|
||||||
|
|
|
@ -96,6 +96,7 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Handle to the Vulkan Descriptor Set Layout handle.</returns>
|
/// <returns>Handle to the Vulkan Descriptor Set Layout handle.</returns>
|
||||||
inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; }
|
inline const vk::DescriptorSetLayout& GetVkHandle() const { return setLayout; }
|
||||||
|
std::vector<Binding> const& GetBindings (void) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -418,7 +418,12 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) const noexcept
|
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) const noexcept
|
||||||
{
|
{
|
||||||
return SHVkInstance::GetResourceManager().Create<SHVkImage>(std::cref(vmaAllocator), w, h, levels, format, usage, create);
|
return SHVkInstance::GetResourceManager().Create<SHVkImage>(&vmaAllocator, w, h, levels, format, usage, create);
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHVkImage> SHVkLogicalDevice::CreateImage(SHImageCreateParams const& imageDetails, unsigned char* data, uint32_t dataSize, std::span<uint32_t> inMipOffsets, VmaMemoryUsage memUsage, VmaAllocationCreateFlags allocFlags) noexcept
|
||||||
|
{
|
||||||
|
return SHVkInstance::GetResourceManager().Create<SHVkImage>(&vmaAllocator, imageDetails, data, dataSize, inMipOffsets, memUsage, allocFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -509,6 +514,12 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle<SHVkDescriptorPool> SHVkLogicalDevice::CreateDescriptorPools(const SHVkDescriptorPool::Config& config /*= {}*/) noexcept
|
||||||
|
{
|
||||||
|
return SHVkInstance::GetResourceManager().Create <SHVkDescriptorPool>(GetHandle(), config);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -541,6 +552,22 @@ namespace SHADE
|
||||||
return SHVkInstance::GetResourceManager().Create<SHVkSemaphore>(GetHandle());
|
return SHVkInstance::GetResourceManager().Create<SHVkSemaphore>(GetHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Writes to descriptor sets.
|
||||||
|
|
||||||
|
\param writeDescSets
|
||||||
|
Descriptor sets to write to.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHVkLogicalDevice::UpdateDescriptorSets(std::vector<vk::WriteDescriptorSet> const& writeDescSets) noexcept
|
||||||
|
{
|
||||||
|
vkLogicalDevice.updateDescriptorSets(writeDescSets, {});
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,9 @@
|
||||||
#include "Graphics/Pipeline/SHPipelineState.h"
|
#include "Graphics/Pipeline/SHPipelineState.h"
|
||||||
#include "Graphics/Pipeline/SHPipelineType.h"
|
#include "Graphics/Pipeline/SHPipelineType.h"
|
||||||
#include "vk_mem_alloc.h"
|
#include "vk_mem_alloc.h"
|
||||||
//#include "Graphics/DescriptorSets/SHDescriptorPool.h"
|
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
|
||||||
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
|
||||||
|
#include "Graphics/Images/SHVkImage.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -29,7 +30,6 @@ namespace SHADE
|
||||||
class SHVkSurface;
|
class SHVkSurface;
|
||||||
class SHVkSwapchain;
|
class SHVkSwapchain;
|
||||||
class SHVkBuffer;
|
class SHVkBuffer;
|
||||||
class SHVkImage;
|
|
||||||
class SHVkFence;
|
class SHVkFence;
|
||||||
class SHVkSemaphore;
|
class SHVkSemaphore;
|
||||||
class SHVkShaderModule;
|
class SHVkShaderModule;
|
||||||
|
@ -38,6 +38,7 @@ namespace SHADE
|
||||||
class SHVkFramebuffer;
|
class SHVkFramebuffer;
|
||||||
class SHVkImageView;
|
class SHVkImageView;
|
||||||
class SHShaderBlockInterface;
|
class SHShaderBlockInterface;
|
||||||
|
class SHVkDescriptorSetGroup;
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
@ -138,14 +139,23 @@ namespace SHADE
|
||||||
) const noexcept;
|
) const noexcept;
|
||||||
|
|
||||||
Handle<SHVkImage> CreateImage (
|
Handle<SHVkImage> CreateImage (
|
||||||
uint32_t w,
|
uint32_t w,
|
||||||
uint32_t h,
|
uint32_t h,
|
||||||
uint8_t levels,
|
uint8_t levels,
|
||||||
vk::Format format,
|
vk::Format format,
|
||||||
vk::ImageUsageFlags usage,
|
vk::ImageUsageFlags usage,
|
||||||
vk::ImageCreateFlags create
|
vk::ImageCreateFlags create
|
||||||
) const noexcept;
|
) const noexcept;
|
||||||
|
|
||||||
|
Handle<SHVkImage> CreateImage (
|
||||||
|
SHImageCreateParams const& imageDetails,
|
||||||
|
unsigned char* data,
|
||||||
|
uint32_t dataSize,
|
||||||
|
std::span<uint32_t> inMipOffsets,
|
||||||
|
VmaMemoryUsage memUsage,
|
||||||
|
VmaAllocationCreateFlags allocFlags
|
||||||
|
) noexcept;
|
||||||
|
|
||||||
Handle<SHVkShaderModule> CreateShaderModule (
|
Handle<SHVkShaderModule> CreateShaderModule (
|
||||||
std::vector<uint32_t> const& binaryData,
|
std::vector<uint32_t> const& binaryData,
|
||||||
std::string entryPoint,
|
std::string entryPoint,
|
||||||
|
@ -165,10 +175,13 @@ namespace SHADE
|
||||||
Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::span<vk::SubpassDescription> const spDescs, std::span<vk::SubpassDependency> const spDeps) noexcept;
|
Handle<SHVkRenderpass> CreateRenderpass (std::span<vk::AttachmentDescription> const vkDescriptions, std::span<vk::SubpassDescription> const spDescs, std::span<vk::SubpassDependency> const spDeps) noexcept;
|
||||||
Handle<SHVkFramebuffer> CreateFramebuffer (Handle<SHVkRenderpass> const& renderpassHdl, std::vector<Handle<SHVkImageView>> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept;
|
Handle<SHVkFramebuffer> CreateFramebuffer (Handle<SHVkRenderpass> const& renderpassHdl, std::vector<Handle<SHVkImageView>> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept;
|
||||||
Handle<SHVkDescriptorSetLayout> CreateDescriptorSetLayout (std::vector<SHVkDescriptorSetLayout::Binding> const& bindings) noexcept;
|
Handle<SHVkDescriptorSetLayout> CreateDescriptorSetLayout (std::vector<SHVkDescriptorSetLayout::Binding> const& bindings) noexcept;
|
||||||
|
Handle<SHVkDescriptorPool> CreateDescriptorPools (const SHVkDescriptorPool::Config& config = {}) noexcept;
|
||||||
Handle<SHVkPipelineLayout> CreatePipelineLayout (SHPipelineLayoutParams& pipelineLayoutParams) noexcept;
|
Handle<SHVkPipelineLayout> CreatePipelineLayout (SHPipelineLayoutParams& pipelineLayoutParams) noexcept;
|
||||||
Handle<SHVkFence> CreateFence (void) const noexcept;
|
Handle<SHVkFence> CreateFence (void) const noexcept;
|
||||||
Handle<SHVkSemaphore> CreateSemaphore (void) const noexcept;
|
Handle<SHVkSemaphore> CreateSemaphore (void) const noexcept;
|
||||||
|
|
||||||
|
void UpdateDescriptorSets (std::vector<vk::WriteDescriptorSet> const& writeDescSets) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* SETTERS AND GETTERS */
|
/* SETTERS AND GETTERS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
|
@ -180,10 +180,10 @@ namespace SHADE
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHLOG_ERROR("Successfully queried Physical Devices:");
|
SHLOG_TRACE("Successfully queried Physical Devices:");
|
||||||
for (auto const& device : physicalDevices)
|
for (auto const& device : physicalDevices)
|
||||||
{
|
{
|
||||||
SHLOG_ERROR(std::string_view (std::string("\t-") + GetDeviceTypeName(device.getProperties().deviceType) + device.getProperties().deviceName.operator std::string()));
|
SHLOG_TRACE(std::string_view (std::string("\t-") + GetDeviceTypeName(device.getProperties().deviceType) + device.getProperties().deviceName.operator std::string()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,14 +5,88 @@
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLogger.h"
|
||||||
#include "SHVkImageView.h"
|
#include "SHVkImageView.h"
|
||||||
#include "Graphics/Instance/SHVkInstance.h"
|
#include "Graphics/Instance/SHVkInstance.h"
|
||||||
|
#include "Graphics/Buffers/SHVkBuffer.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
If an image is a GPU only resource, we need to prep a staging buffer
|
||||||
|
to use for transferring data to the GPU. #NoteToSelf: I don't really
|
||||||
|
like this because its duplicate code. Should try to find a way to utilize
|
||||||
|
the logical device for this.
|
||||||
|
|
||||||
|
\param data
|
||||||
|
Data to transfer.
|
||||||
|
|
||||||
|
\param srcSize
|
||||||
|
Size in bytes of the data.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHVkImage::PrepStagingBuffer(void* data, uint32_t srcSize) noexcept
|
||||||
|
{
|
||||||
|
// For creation of buffer
|
||||||
|
vk::BufferCreateInfo bufferInfo{};
|
||||||
|
|
||||||
|
// size stored same as GPU buffer
|
||||||
|
bufferInfo.size = srcSize;
|
||||||
|
|
||||||
|
// We just want to set the transfer bit
|
||||||
|
bufferInfo.usage = vk::BufferUsageFlagBits::eTransferSrc;
|
||||||
|
|
||||||
|
// sharing mode exclusive
|
||||||
|
bufferInfo.sharingMode = vk::SharingMode::eExclusive;
|
||||||
|
|
||||||
|
// Set to auto detect bits
|
||||||
|
VmaAllocationCreateInfo allocCreateInfo{};
|
||||||
|
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
|
||||||
|
|
||||||
|
// We want to just write all at once. Using random access bit could make this slow
|
||||||
|
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
|
||||||
|
|
||||||
|
// parameters of a vmaAllocation retrieved via vmaGetAllocationInfo
|
||||||
|
VmaAllocationInfo allocInfo;
|
||||||
|
|
||||||
|
// results of allocation
|
||||||
|
VmaAllocation stagingAlloc;
|
||||||
|
|
||||||
|
// To get around VMA's usage for C version of vulkan, create a temp first...,
|
||||||
|
VkBuffer tempBuffer{};
|
||||||
|
|
||||||
|
// Create the buffer...
|
||||||
|
vmaCreateBuffer(*vmaAllocator,
|
||||||
|
&bufferInfo.operator VkBufferCreateInfo & (), // TODO: Verify if this works (can use renderdoc to check buffer variables?)
|
||||||
|
&allocCreateInfo,
|
||||||
|
&tempBuffer, &stagingAlloc, &allocInfo);
|
||||||
|
|
||||||
|
// then assign it to the hpp version
|
||||||
|
stagingBuffer = tempBuffer;
|
||||||
|
|
||||||
|
// Just map, copy then unmap
|
||||||
|
void* stagingBufferMappedPtr = nullptr;
|
||||||
|
vmaMapMemory(*vmaAllocator, stagingAlloc, &stagingBufferMappedPtr);
|
||||||
|
|
||||||
|
if (stagingBufferMappedPtr)
|
||||||
|
std::memcpy(static_cast<uint8_t*>(stagingBufferMappedPtr), static_cast<uint8_t*>(data), srcSize);
|
||||||
|
|
||||||
|
const VkDeviceSize offsets = 0;
|
||||||
|
const VkDeviceSize sizes = srcSize;
|
||||||
|
vmaFlushAllocations(*vmaAllocator, 1, &stagingAlloc, &offsets, &sizes);
|
||||||
|
|
||||||
|
vmaUnmapMemory(*vmaAllocator, stagingAlloc);
|
||||||
|
}
|
||||||
|
|
||||||
SHVkImage::SHVkImage(
|
SHVkImage::SHVkImage(
|
||||||
VmaAllocator const& vmaAllocator,
|
VmaAllocator const* allocator,
|
||||||
SHImageCreateParams const& imageDetails,
|
SHImageCreateParams const& imageDetails,
|
||||||
VmaMemoryUsage memUsage,
|
unsigned char* data,
|
||||||
VmaAllocationCreateFlags allocFlags
|
uint32_t dataSize,
|
||||||
|
std::span<uint32_t> inMipOffsets,
|
||||||
|
VmaMemoryUsage memUsage,
|
||||||
|
VmaAllocationCreateFlags allocFlags
|
||||||
) noexcept
|
) noexcept
|
||||||
: imageType { imageDetails.imageType }
|
: imageType { imageDetails.imageType }
|
||||||
, width{ imageDetails.width }
|
, width{ imageDetails.width }
|
||||||
|
@ -23,12 +97,14 @@ namespace SHADE
|
||||||
, imageFormat{ imageDetails.imageFormat }
|
, imageFormat{ imageDetails.imageFormat }
|
||||||
, usageFlags{}
|
, usageFlags{}
|
||||||
, createFlags{}
|
, createFlags{}
|
||||||
|
, vmaAllocator{allocator}
|
||||||
|
, mipOffsets { inMipOffsets }
|
||||||
|
, boundToCoherent{false}
|
||||||
|
, randomAccessOptimized {false}
|
||||||
|
, mappedPtr{nullptr}
|
||||||
{
|
{
|
||||||
for (auto& bit : imageDetails.usageBits)
|
usageFlags = imageDetails.usageFlags;
|
||||||
usageFlags |= bit;
|
createFlags = imageDetails.createFlags;
|
||||||
|
|
||||||
for (auto& bit : imageDetails.createBits)
|
|
||||||
createFlags |= bit;
|
|
||||||
|
|
||||||
// If marked as 2D array compatible, image type MUST be 3D
|
// If marked as 2D array compatible, image type MUST be 3D
|
||||||
if (createFlags & vk::ImageCreateFlagBits::e2DArrayCompatible)
|
if (createFlags & vk::ImageCreateFlagBits::e2DArrayCompatible)
|
||||||
|
@ -64,58 +140,52 @@ namespace SHADE
|
||||||
VmaAllocationInfo allocInfo{};
|
VmaAllocationInfo allocInfo{};
|
||||||
|
|
||||||
VkImage tempImage;
|
VkImage tempImage;
|
||||||
vmaCreateImage(vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo&(), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo&(), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
||||||
|
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
SHVulkanDebugUtil::ReportVkError(vk::Result(result), "Failed to create vulkan image. ");
|
||||||
|
else
|
||||||
|
SHVulkanDebugUtil::ReportVkSuccess("Successfully created image. ");
|
||||||
|
|
||||||
vkImage = tempImage;
|
vkImage = tempImage;
|
||||||
|
|
||||||
//if (allocFlags & )
|
// At this point the image and device memory have been created.
|
||||||
|
|
||||||
|
if (allocFlags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)
|
||||||
|
randomAccessOptimized = true;
|
||||||
|
|
||||||
|
// TODO: This constructor can only create a GPU only resource for now. Due to time constraint, I was trying to create a ctor
|
||||||
|
// fast to finish up the ImGUI backend. In the future, there definitely needs to be more versatility to the constructor.
|
||||||
|
|
||||||
|
// Get the memory property flags
|
||||||
|
VkMemoryPropertyFlags memPropFlags;
|
||||||
|
vmaGetAllocationMemoryProperties(*vmaAllocator, alloc, &memPropFlags);
|
||||||
|
|
||||||
|
// mainly host visible. Can be cached (need to flush/invalidate), uncached (always coherent) and coherent (virtual).
|
||||||
|
//if (memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
|
||||||
|
//{
|
||||||
|
// // If memory is marked to be coherent between CPU and GPU (no need flush/invalidate) (TODO: Verify if VMA_ALLOCATION_CREATE_MAPPED_BIT is used when VMA_MEMORY_USAGE_AUTO is set)
|
||||||
|
// // TODO: also verify that coherent bit = pointer is already mapped
|
||||||
|
// if (memPropFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
|
||||||
|
// {
|
||||||
|
// boundToCoherent = true;
|
||||||
|
// mappedPtr = allocInfo.pMappedData;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// mappedPtr = nullptr;
|
||||||
|
|
||||||
|
// if (data)
|
||||||
|
// MapWriteUnmap(data, srcSize, 0, 0);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// We can prep first so that we can do transfers later via 1 cmd buffer recording
|
||||||
|
PrepStagingBuffer(data, dataSize);
|
||||||
|
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
SHVkImage::SHVkImage(VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief
|
|
||||||
This is mainly used for images that aren't created internally because
|
|
||||||
they cannot be created in the traditional way (e.g. swapchain images).
|
|
||||||
|
|
||||||
\param inVkImage
|
|
||||||
Image already created outside
|
|
||||||
|
|
||||||
\param width
|
|
||||||
Width of the image
|
|
||||||
|
|
||||||
\param height
|
|
||||||
Height of the image
|
|
||||||
|
|
||||||
\param depth
|
|
||||||
Depth of the image
|
|
||||||
|
|
||||||
\param levels
|
|
||||||
Number of levels in the image
|
|
||||||
|
|
||||||
\param arrayLayers
|
|
||||||
if the image is an array, this value will be > 1.
|
|
||||||
|
|
||||||
\param imageFormat
|
|
||||||
Format of the image
|
|
||||||
|
|
||||||
*/
|
|
||||||
/***************************************************************************/
|
|
||||||
SHVkImage::SHVkImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t arrayLayers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept
|
|
||||||
: vkImage (inVkImage)
|
|
||||||
, width{ inWidth }
|
|
||||||
, height{ inHeight }
|
|
||||||
, depth{ inDepth }
|
|
||||||
, mipLevelCount{ levels }
|
|
||||||
, layerCount{ arrayLayers }
|
|
||||||
, imageFormat{ format }
|
|
||||||
, usageFlags{flags}
|
|
||||||
, alloc{}
|
|
||||||
, imageType{type}
|
|
||||||
, createFlags{}
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SHVkImage::SHVkImage(VmaAllocator const& vmaAllocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept
|
|
||||||
: width {w}
|
: width {w}
|
||||||
, height{h}
|
, height{h}
|
||||||
, depth {1}
|
, depth {1}
|
||||||
|
@ -124,6 +194,7 @@ namespace SHADE
|
||||||
, imageFormat{format}
|
, imageFormat{format}
|
||||||
, usageFlags{usage}
|
, usageFlags{usage}
|
||||||
, createFlags {create}
|
, createFlags {create}
|
||||||
|
, vmaAllocator {allocator}
|
||||||
{
|
{
|
||||||
vk::ImageCreateInfo imageCreateInfo{};
|
vk::ImageCreateInfo imageCreateInfo{};
|
||||||
imageCreateInfo.imageType = vk::ImageType::e2D;
|
imageCreateInfo.imageType = vk::ImageType::e2D;
|
||||||
|
@ -149,7 +220,7 @@ namespace SHADE
|
||||||
VmaAllocationInfo allocInfo{};
|
VmaAllocationInfo allocInfo{};
|
||||||
|
|
||||||
VkImage tempImage;
|
VkImage tempImage;
|
||||||
auto result = vmaCreateImage(vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
auto result = vmaCreateImage(*vmaAllocator, &imageCreateInfo.operator VkImageCreateInfo & (), &allocCreateInfo, &tempImage, &alloc, &allocInfo);
|
||||||
vkImage = tempImage;
|
vkImage = tempImage;
|
||||||
|
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
|
@ -163,6 +234,86 @@ namespace SHADE
|
||||||
return SHVkInstance::GetResourceManager().Create<SHVkImageView>(inLogicalDeviceHdl, parent, createParams);
|
return SHVkInstance::GetResourceManager().Create<SHVkImageView>(inLogicalDeviceHdl, parent, createParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHVkImage::TransferToDeviceResource(Handle<SHVkCommandBuffer> const& cmdBufferHdl) noexcept
|
||||||
|
{
|
||||||
|
// prepare copy regions
|
||||||
|
std::vector<vk::BufferImageCopy> copyRegions{mipOffsets.size()};
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < mipOffsets.size(); ++i)
|
||||||
|
{
|
||||||
|
copyRegions[i].bufferOffset = mipOffsets[i];
|
||||||
|
copyRegions[i].bufferRowLength = 0; // for padding
|
||||||
|
copyRegions[i].bufferImageHeight = 0; // for padding
|
||||||
|
copyRegions[i].imageSubresource.aspectMask = vk::ImageAspectFlagBits::eColor; // TODO: Need to change this to base it off image format.
|
||||||
|
copyRegions[i].imageSubresource.mipLevel = i;
|
||||||
|
copyRegions[i].imageSubresource.baseArrayLayer = 0; // TODO: Array textures not supported yet
|
||||||
|
copyRegions[i].imageSubresource.layerCount = layerCount;
|
||||||
|
copyRegions[i].imageOffset = vk::Offset3D{ 0,0,0 };
|
||||||
|
copyRegions[i].imageExtent = vk::Extent3D{ width >> i, height >> i, 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Does not perform any image transitions but prepares a barrier for image
|
||||||
|
transitioning. Pipeline barrier will be issued outside this call after
|
||||||
|
this preparation function, or at least, it should be.
|
||||||
|
|
||||||
|
\param oldLayout
|
||||||
|
Old layout of the image.
|
||||||
|
|
||||||
|
\param newLayout
|
||||||
|
new layout of the image to transition to.
|
||||||
|
|
||||||
|
\param barrier
|
||||||
|
Barrier to modify to prepare the image for transitioning.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHVkImage::PrepareImageTransition(vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept
|
||||||
|
{
|
||||||
|
barrier.oldLayout = oldLayout;
|
||||||
|
barrier.newLayout = newLayout;
|
||||||
|
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||||
|
barrier.image = vkImage;
|
||||||
|
barrier.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor; // TODO: Need to change this to base it off image format.
|
||||||
|
barrier.subresourceRange.baseMipLevel = 0;
|
||||||
|
barrier.subresourceRange.levelCount = mipLevelCount;
|
||||||
|
barrier.subresourceRange.baseArrayLayer = 0;
|
||||||
|
barrier.subresourceRange.layerCount = layerCount;
|
||||||
|
|
||||||
|
vk::PipelineStageFlagBits srcStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||||
|
vk::PipelineStageFlagBits dstStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||||
|
|
||||||
|
if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal)
|
||||||
|
{
|
||||||
|
srcStage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||||
|
dstStage = vk::PipelineStageFlagBits::eTransfer;
|
||||||
|
|
||||||
|
barrier.srcAccessMask = vk::AccessFlagBits::eNone;
|
||||||
|
barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
|
||||||
|
}
|
||||||
|
else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal)
|
||||||
|
{
|
||||||
|
srcStage = vk::PipelineStageFlagBits::eTransfer;
|
||||||
|
|
||||||
|
// TODO, what if we want to access in compute shader
|
||||||
|
dstStage = vk::PipelineStageFlagBits::eFragmentShader;
|
||||||
|
|
||||||
|
barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
|
||||||
|
barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Image layouts are invalid. ");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept
|
void SHVkImage::LinkWithExteriorImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t layers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept
|
||||||
{
|
{
|
||||||
vkImage = inVkImage;
|
vkImage = inVkImage;
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
class SHVkLogicalDevice;
|
class SHVkLogicalDevice;
|
||||||
class SHVkImageView;
|
class SHVkImageView;
|
||||||
|
class SHVkCommandBuffer;
|
||||||
|
|
||||||
struct SHImageCreateParams
|
struct SHImageCreateParams
|
||||||
{
|
{
|
||||||
|
@ -35,10 +36,10 @@ namespace SHADE
|
||||||
vk::Format imageFormat;
|
vk::Format imageFormat;
|
||||||
|
|
||||||
//! Image usage bits
|
//! Image usage bits
|
||||||
std::span<vk::ImageUsageFlagBits> usageBits;
|
vk::ImageUsageFlags usageFlags;
|
||||||
|
|
||||||
//! Image create flags
|
//! Image create flags
|
||||||
std::span<vk::ImageCreateFlagBits> createBits;
|
vk::ImageCreateFlags createFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SHVkImage
|
class SHVkImage
|
||||||
|
@ -47,6 +48,12 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
//! Pointer to the vma allocator. #NoteToSelf: Not super proud of this being a pointer.
|
||||||
|
//! The only reason why this is a pointer is because a reference_wrapper cannot be default constructed.
|
||||||
|
//! And the reason why we want a default constructor is because sometimes we don't want to create images
|
||||||
|
//! but merely link them from outside (swapchain images)
|
||||||
|
VmaAllocator const* vmaAllocator;
|
||||||
|
|
||||||
//! 1D, 2D or 3D
|
//! 1D, 2D or 3D
|
||||||
vk::ImageType imageType = vk::ImageType::e2D;
|
vk::ImageType imageType = vk::ImageType::e2D;
|
||||||
|
|
||||||
|
@ -80,22 +87,46 @@ namespace SHADE
|
||||||
//! allocation object containing details of an allocation
|
//! allocation object containing details of an allocation
|
||||||
VmaAllocation alloc{};
|
VmaAllocation alloc{};
|
||||||
|
|
||||||
|
//! Whether or not this image is HOST_VISIBLE and random access optimized
|
||||||
|
bool randomAccessOptimized;
|
||||||
|
|
||||||
|
//! Whether or not the memory the image is bound to is memory coherent (updates on CPU can be seen on GPU without flushing cache)
|
||||||
|
bool boundToCoherent;
|
||||||
|
|
||||||
|
//! Persistently mapped pointer if applicable (will be void if image is
|
||||||
|
//! not created with the correct flags). Note that this is only used for
|
||||||
|
//! persistent mapping. One time updates do not use this pointer.
|
||||||
|
void* mappedPtr;
|
||||||
|
|
||||||
|
//! Staging buffer for images purely in the GPU
|
||||||
|
vk::Buffer stagingBuffer;
|
||||||
|
|
||||||
|
//! Mipmap offsets for initializing the vk::BufferImageCopy during transfer to GPU resource
|
||||||
|
std::span<uint32_t> mipOffsets;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PRIVATE MEMBER FUNCTIONS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
void PrepStagingBuffer(void* data, uint32_t srcSize) noexcept;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTOR AND DTOR */
|
/* CTOR AND DTOR */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
SHVkImage(void) noexcept = default;
|
SHVkImage(void) noexcept = default;
|
||||||
|
|
||||||
// TODO: Might need to add flags to parameters
|
|
||||||
SHVkImage(
|
SHVkImage(
|
||||||
VmaAllocator const& vmaAllocator,
|
VmaAllocator const* allocator,
|
||||||
SHImageCreateParams const& imageDetails,
|
SHImageCreateParams const& imageDetails,
|
||||||
VmaMemoryUsage memUsage,
|
unsigned char* data,
|
||||||
VmaAllocationCreateFlags allocFlags
|
uint32_t dataSize,
|
||||||
|
std::span<uint32_t> inMipOffsets,
|
||||||
|
VmaMemoryUsage memUsage,
|
||||||
|
VmaAllocationCreateFlags allocFlags
|
||||||
) noexcept;
|
) noexcept;
|
||||||
|
|
||||||
SHVkImage(vk::Image inVkImage, vk::ImageType type, uint32_t inWidth, uint32_t inHeight, uint32_t inDepth, uint32_t arrayLayers, uint8_t levels, vk::Format format, vk::ImageUsageFlags flags) noexcept;
|
SHVkImage(VmaAllocator const* allocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept;
|
||||||
SHVkImage(VmaAllocator const& vmaAllocator, uint32_t w, uint32_t h, uint8_t levels, vk::Format format, vk::ImageUsageFlags usage, vk::ImageCreateFlags create) noexcept;
|
|
||||||
|
|
||||||
SHVkImage(SHVkImage&& rhs) noexcept = default;
|
SHVkImage(SHVkImage&& rhs) noexcept = default;
|
||||||
SHVkImage& operator=(SHVkImage && rhs) noexcept = default;
|
SHVkImage& operator=(SHVkImage && rhs) noexcept = default;
|
||||||
|
@ -103,7 +134,9 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
Handle<SHVkImageView> CreateImageView(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept;
|
Handle<SHVkImageView> CreateImageView (Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, Handle<SHVkImage> const& parent, SHImageViewDetails const& createParams) const noexcept;
|
||||||
|
void TransferToDeviceResource (Handle<SHVkCommandBuffer> const& cmdBufferHdl) noexcept;
|
||||||
|
void PrepareImageTransition (vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageMemoryBarrier& barrier) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* GETTERS AND SETTERS */
|
/* GETTERS AND SETTERS */
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHVkSampler.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
struct SHVkSamplerParams
|
||||||
|
{
|
||||||
|
vk::Filter minFilter;
|
||||||
|
vk::Filter maxFilter;
|
||||||
|
//vk::Filter maxFilter;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SHVkSampler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
//! The vulkan sampler handler
|
||||||
|
vk::Sampler vkSampler;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SHVkSampler () noexcept;
|
||||||
|
SHVkSampler (SHVkSampler&& rhs) noexcept;
|
||||||
|
SHVkSampler&& operator=(SHVkSampler&& rhs) noexcept;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -22,14 +22,12 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*---------------------------------------------------------------------------------*/
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Constructor/Destructors */
|
/* Constructor/Destructors */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
SHGraphicsSystem::SHGraphicsSystem(SHWindow& window)
|
void SHGraphicsSystem::Init(void)
|
||||||
{
|
{
|
||||||
// Save the SHWindow
|
|
||||||
this->window = &window;
|
|
||||||
|
|
||||||
// Set Up Instance
|
// Set Up Instance
|
||||||
SHVkInstance::Init(true, true, true);
|
SHVkInstance::Init(true, true, true);
|
||||||
|
|
||||||
|
@ -39,10 +37,10 @@ namespace SHADE
|
||||||
device = SHVkInstance::CreateLogicalDevice({ SHQueueParams(SH_Q_FAM::GRAPHICS, SH_QUEUE_SELECT::DEDICATED), SHQueueParams(SH_Q_FAM::TRANSFER, SH_QUEUE_SELECT::DEDICATED) }, physicalDevice);
|
device = SHVkInstance::CreateLogicalDevice({ SHQueueParams(SH_Q_FAM::GRAPHICS, SH_QUEUE_SELECT::DEDICATED), SHQueueParams(SH_Q_FAM::TRANSFER, SH_QUEUE_SELECT::DEDICATED) }, physicalDevice);
|
||||||
|
|
||||||
// Construct surface
|
// Construct surface
|
||||||
surface = device->CreateSurface(window.GetHWND());
|
surface = device->CreateSurface(window->GetHWND());
|
||||||
|
|
||||||
// Construct Swapchain
|
// Construct Swapchain
|
||||||
auto windowDims = window.GetWindowSize();
|
auto windowDims = window->GetWindowSize();
|
||||||
swapchain = device->CreateSwapchain(surface, windowDims.first, windowDims.second, SHSwapchainParams
|
swapchain = device->CreateSwapchain(surface, windowDims.first, windowDims.second, SHSwapchainParams
|
||||||
{
|
{
|
||||||
.surfaceImageFormats {vk::Format::eB8G8R8A8Unorm, vk::Format::eR8G8B8A8Unorm, vk::Format::eB8G8R8Unorm, vk::Format::eR8G8B8Unorm},
|
.surfaceImageFormats {vk::Format::eB8G8R8A8Unorm, vk::Format::eR8G8B8A8Unorm, vk::Format::eB8G8R8Unorm, vk::Format::eR8G8B8Unorm},
|
||||||
|
@ -51,13 +49,13 @@ namespace SHADE
|
||||||
.vsyncOn = false, // TODO: Set to true when shipping game
|
.vsyncOn = false, // TODO: Set to true when shipping game
|
||||||
});
|
});
|
||||||
|
|
||||||
window.RegisterWindowSizeCallback([&]([[maybe_unused]] uint32_t width, [[maybe_unused]] uint32_t height)
|
window->RegisterWindowSizeCallback([&]([[maybe_unused]] uint32_t width, [[maybe_unused]] uint32_t height)
|
||||||
{
|
{
|
||||||
renderContext.SetIsResized(true);
|
renderContext.SetIsResized(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create graphics queue
|
// Create graphics queue
|
||||||
queue = device->GetQueue(SH_Q_FAM::GRAPHICS, 0);
|
graphicsQueue = device->GetQueue(SH_Q_FAM::GRAPHICS, 0);
|
||||||
|
|
||||||
|
|
||||||
// Create Render Context
|
// Create Render Context
|
||||||
|
@ -87,7 +85,7 @@ namespace SHADE
|
||||||
//commandBuffers[i] = commandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); // works
|
//commandBuffers[i] = commandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY); // works
|
||||||
}
|
}
|
||||||
|
|
||||||
|
descPool = device->CreateDescriptorPools();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,12 +99,12 @@ namespace SHADE
|
||||||
renderGraph.AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
renderGraph.AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
||||||
renderGraph.AddResource("Downscale", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
renderGraph.AddResource("Downscale", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
|
||||||
renderGraph.AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
|
renderGraph.AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
|
||||||
auto node = renderGraph.AddNode("G-Buffer", { "Position", "Normals", "Composite" }, {}); // no predecessors
|
auto node = renderGraph.AddNode("G-Buffer", { "Composite", "Position", "Normals", "Present" }, {}); // no predecessors
|
||||||
|
|
||||||
// First subpass to write to G-Buffer
|
// First subpass to write to G-Buffer
|
||||||
auto writeSubpass = node->AddSubpass("G-Buffer Write");
|
auto writeSubpass = node->AddSubpass("G-Buffer Write");
|
||||||
writeSubpass->AddColorOutput("Position");
|
writeSubpass->AddColorOutput("Position");
|
||||||
writeSubpass->AddColorOutput("Normals");
|
writeSubpass->AddColorOutput("Present");
|
||||||
|
|
||||||
// Second subpass to read from G-Buffer
|
// Second subpass to read from G-Buffer
|
||||||
auto compositeSubpass = node->AddSubpass("G-Buffer Composite");
|
auto compositeSubpass = node->AddSubpass("G-Buffer Composite");
|
||||||
|
@ -114,11 +112,11 @@ namespace SHADE
|
||||||
compositeSubpass->AddInput("Normals");
|
compositeSubpass->AddInput("Normals");
|
||||||
compositeSubpass->AddInput("Position");
|
compositeSubpass->AddInput("Position");
|
||||||
|
|
||||||
auto compositeNode = renderGraph.AddNode("Bloom", { "Composite", "Downscale", "Present"}, {"G-Buffer"});
|
//auto compositeNode = renderGraph.AddNode("Bloom", { "Composite", "Downscale", "Present" }, { "G-Buffer" });
|
||||||
auto bloomSubpass = compositeNode->AddSubpass("Downsample");
|
//auto bloomSubpass = compositeNode->AddSubpass("Downsample");
|
||||||
bloomSubpass->AddInput("Composite");
|
//bloomSubpass->AddInput("Composite");
|
||||||
bloomSubpass->AddColorOutput("Downscale");
|
//bloomSubpass->AddColorOutput("Downscale");
|
||||||
bloomSubpass->AddColorOutput("Present");
|
//bloomSubpass->AddColorOutput("Present");
|
||||||
|
|
||||||
renderGraph.Generate();
|
renderGraph.Generate();
|
||||||
|
|
||||||
|
@ -127,11 +125,25 @@ namespace SHADE
|
||||||
/* RENDERGRAPH END TESTING */
|
/* RENDERGRAPH END TESTING */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
}
|
}
|
||||||
SHGraphicsSystem::~SHGraphicsSystem()
|
|
||||||
|
void SHGraphicsSystem::Run(float dt) noexcept
|
||||||
|
{
|
||||||
|
auto const& frameData = renderContext.GetCurrentFrameData();
|
||||||
|
|
||||||
|
renderGraph.Execute(renderContext.GetCurrentFrame());
|
||||||
|
|
||||||
|
graphicsQueue->SubmitCommandBuffer({ renderGraph.GetCommandBuffer(renderContext.GetCurrentFrame()) },
|
||||||
|
{ frameData.semRenderFinishHdl },
|
||||||
|
{ frameData.semImgAvailableHdl },
|
||||||
|
vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests | vk::PipelineStageFlagBits::eLateFragmentTests);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHGraphicsSystem::Exit(void)
|
||||||
{
|
{
|
||||||
//renderPass.Free();
|
//renderPass.Free();
|
||||||
renderContext.Destroy();
|
renderContext.Destroy();
|
||||||
queue.Free();
|
graphicsQueue.Free();
|
||||||
swapchain.Free();
|
swapchain.Free();
|
||||||
surface.Free();
|
surface.Free();
|
||||||
device.Free();
|
device.Free();
|
||||||
|
@ -205,7 +217,7 @@ namespace SHADE
|
||||||
presentInfo.pImageIndices = &CURR_FRAME_IDX;
|
presentInfo.pImageIndices = &CURR_FRAME_IDX;
|
||||||
|
|
||||||
// #BackEndTest: queues an image for presentation
|
// #BackEndTest: queues an image for presentation
|
||||||
if (auto result = device->GetQueue(SH_Q_FAM::GRAPHICS, 0)->GetVkQueue().presentKHR(&presentInfo); result != vk::Result::eSuccess)
|
if (auto result = graphicsQueue->Present(swapchain, {currFrameData.semRenderFinishHdl}, CURR_FRAME_IDX); result != vk::Result::eSuccess)
|
||||||
{
|
{
|
||||||
// If swapchain is incompatible/outdated
|
// If swapchain is incompatible/outdated
|
||||||
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR)
|
if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR)
|
||||||
|
@ -235,4 +247,19 @@ namespace SHADE
|
||||||
void SHGraphicsSystem::RemoveSegment(Handle<SHScreenSegment> segment)
|
void SHGraphicsSystem::RemoveSegment(Handle<SHScreenSegment> segment)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept
|
||||||
|
{
|
||||||
|
window = wind;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHRenderGraph const& SHGraphicsSystem::GetRenderGraph(void) const noexcept
|
||||||
|
{
|
||||||
|
return renderGraph;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHGraphicsSystem::SHGraphicsSystemRoutine::Execute(double dt) noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,14 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Graphics/SHVulkanIncludes.h"
|
#include "Graphics/SHVulkanIncludes.h"
|
||||||
#include "Graphics/MiddleEnd/PerFrame/SHRenderContext.h"
|
#include "Graphics/MiddleEnd/PerFrame/SHRenderContext.h"
|
||||||
#include "Graphics/RenderGraph/SHRenderGraph.h"
|
#include "Graphics/RenderGraph/SHRenderGraph.h"
|
||||||
|
#include "ECS_Base/System/SHSystem.h"
|
||||||
|
#include "ECS_Base/System/SHSystemRoutine.h"
|
||||||
|
#include "Graphics/Descriptors/SHVkDescriptorPool.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Forward Declarations */
|
/* Forward Declarations */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -61,8 +66,15 @@ namespace SHADE
|
||||||
portions of the screen.
|
portions of the screen.
|
||||||
*/
|
*/
|
||||||
/***********************************************************************************/
|
/***********************************************************************************/
|
||||||
class SHGraphicsSystem
|
class SH_API SHGraphicsSystem : public SHSystem
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
class SH_API SHGraphicsSystemRoutine : public SHSystemRoutine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void Execute(double dt) noexcept override;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Constants */
|
/* Constants */
|
||||||
|
@ -72,8 +84,15 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Constructor/Destructors */
|
/* Constructor/Destructors */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
SHGraphicsSystem(SHWindow& window);
|
SHGraphicsSystem (void) = default;
|
||||||
~SHGraphicsSystem();
|
~SHGraphicsSystem(void) noexcept = default;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* SHSystem overrides */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
virtual void Init(void) override;
|
||||||
|
void Run (float dt) noexcept;
|
||||||
|
virtual void Exit(void) override;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Lifecycle Functions */
|
/* Lifecycle Functions */
|
||||||
|
@ -93,12 +112,22 @@ namespace SHADE
|
||||||
Handle<SHScreenSegment> AddSegment(const VkViewport& viewport, Handle<SHVkImage> imageToUse);
|
Handle<SHScreenSegment> AddSegment(const VkViewport& viewport, Handle<SHVkImage> imageToUse);
|
||||||
void RemoveSegment(Handle<SHScreenSegment> segment);
|
void RemoveSegment(Handle<SHScreenSegment> segment);
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
/* Setters */
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
void SetWindow (SHWindow* wind) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Getters (Temporary) */
|
/* Getters (Temporary) */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
Handle<SHVkLogicalDevice> GetDevice() const { return device; }
|
Handle<SHVkLogicalDevice> GetDevice() const { return device; }
|
||||||
Handle<SHVkSwapchain> GetSwapchain() const { return swapchain; }
|
Handle<SHVkSwapchain> GetSwapchain() const { return swapchain; }
|
||||||
Handle<SHVkSurface> GetSurface() const { return surface; }
|
Handle<SHVkSurface> GetSurface() const { return surface; }
|
||||||
|
Handle<SHVkPhysicalDevice> GetPhysicalDevice() const {return physicalDevice;}
|
||||||
|
Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
|
||||||
|
Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
|
||||||
|
SHRenderGraph const& GetRenderGraph (void) const noexcept;
|
||||||
|
|
||||||
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
|
//Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,7 +140,8 @@ namespace SHADE
|
||||||
Handle<SHVkLogicalDevice> device;
|
Handle<SHVkLogicalDevice> device;
|
||||||
Handle<SHVkSurface> surface;
|
Handle<SHVkSurface> surface;
|
||||||
Handle<SHVkSwapchain> swapchain;
|
Handle<SHVkSwapchain> swapchain;
|
||||||
Handle<SHVkQueue> queue;
|
Handle<SHVkQueue> graphicsQueue;
|
||||||
|
Handle<SHVkDescriptorPool> descPool;
|
||||||
//Handle<SHVkRenderpass> renderPass; // Potentially bring out?
|
//Handle<SHVkRenderpass> renderPass; // Potentially bring out?
|
||||||
std::vector<SHScreenSegment> screenSegments;
|
std::vector<SHScreenSegment> screenSegments;
|
||||||
SHRenderContext renderContext;
|
SHRenderContext renderContext;
|
||||||
|
@ -125,5 +155,6 @@ namespace SHADE
|
||||||
//std::vector<SHRenderer> renderers;
|
//std::vector<SHRenderer> renderers;
|
||||||
SHRenderGraph renderGraph;
|
SHRenderGraph renderGraph;
|
||||||
|
|
||||||
|
friend SHGraphicsSystemRoutine;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "SHPerFrameData.h"
|
#include "SHPerFrameData.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -16,7 +17,7 @@ namespace SHADE
|
||||||
//! render context in SHADE engine has is that it requires users to call these explicitly in the middle end. While there
|
//! render context in SHADE engine has is that it requires users to call these explicitly in the middle end. While there
|
||||||
//! is little reason the flow of the render context should deviate from its intended usage, we want to leave it up to
|
//! is little reason the flow of the render context should deviate from its intended usage, we want to leave it up to
|
||||||
//! users to explicitly call functions from here so we don't risk losing opportunities for different usage.
|
//! users to explicitly call functions from here so we don't risk losing opportunities for different usage.
|
||||||
class SHRenderContext
|
class SH_API SHRenderContext
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
//! container of frame data. Note that the manager owns the data, but the frame data themselves do not own anything.
|
//! container of frame data. Note that the manager owns the data, but the frame data themselves do not own anything.
|
||||||
|
|
|
@ -117,7 +117,7 @@ namespace SHADE
|
||||||
dirty = isDirty;
|
dirty = isDirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<uint32_t, uint32_t, vk::Format> SHVertexInputState::GetInfoFromAttribFormat(SHAttribFormat attribFormat) const noexcept
|
std::tuple<SHVertexInputState::numAttribSlots, SHVertexInputState::bytesRequired, vk::Format> SHVertexInputState::GetInfoFromAttribFormat(SHAttribFormat attribFormat) const noexcept
|
||||||
{
|
{
|
||||||
switch (attribFormat)
|
switch (attribFormat)
|
||||||
{
|
{
|
||||||
|
@ -138,6 +138,9 @@ namespace SHADE
|
||||||
case SHAttribFormat::MAT_4D:
|
case SHAttribFormat::MAT_4D:
|
||||||
return std::make_tuple(4, 16, vk::Format::eR32G32B32A32Sfloat);
|
return std::make_tuple(4, 16, vk::Format::eR32G32B32A32Sfloat);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SHAttribFormat::UINT32_1D:
|
||||||
|
return std::make_tuple(1, 4, vk::Format::eR32Uint);
|
||||||
}
|
}
|
||||||
return std::make_tuple(0, 0, vk::Format::eR32Sfloat);
|
return std::make_tuple(0, 0, vk::Format::eR32Sfloat);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Graphics/Synchronization/SHVkSemaphore.h"
|
#include "Graphics/Synchronization/SHVkSemaphore.h"
|
||||||
#include "Graphics/Synchronization/SHVkFence.h"
|
#include "Graphics/Synchronization/SHVkFence.h"
|
||||||
#include "Graphics/Commands/SHVkCommandBuffer.h"
|
#include "Graphics/Commands/SHVkCommandBuffer.h"
|
||||||
|
#include "Graphics/Swapchain/SHVkSwapchain.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -31,14 +32,10 @@ namespace SHADE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::Queue SHVkQueue::GetVkQueue(void) const noexcept
|
void SHVkQueue::SubmitCommandBuffer(std::initializer_list<Handle<SHVkCommandBuffer>> cmdBuffers, std::initializer_list<Handle<SHVkSemaphore>> signalSems /*= {}*/, std::initializer_list<Handle<SHVkSemaphore>> waitSems /*= {}*/, vk::PipelineStageFlags waitDstStageMask /*= {}*/, Handle<SHVkFence> const& optionalFence /*= {}*/) noexcept
|
||||||
{
|
{
|
||||||
return vkQueue;
|
// prepare wait sems
|
||||||
}
|
std::array<vk::Semaphore, 5> vkWaitSems{ };
|
||||||
|
|
||||||
void SHVkQueue::SubmitCommandBuffer(std::initializer_list<Handle<SHVkCommandBuffer>> cmdBuffers, std::initializer_list<Handle<SHVkSemaphore>> signalSems /*= {}*/, std::initializer_list<Handle<SHVkSemaphore>> waitSems /*= {}*/, vk::PipelineStageFlagBits waitDstStageMask /*= {}*/, Handle<SHVkFence> const& optionalFence /*= {}*/) noexcept
|
|
||||||
{
|
|
||||||
std::vector<vk::Semaphore> vkWaitSems{ waitSems.size() };
|
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
for (auto& sem : waitSems)
|
for (auto& sem : waitSems)
|
||||||
{
|
{
|
||||||
|
@ -46,7 +43,8 @@ namespace SHADE
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<vk::Semaphore> vkSignalSems{ signalSems.size() };
|
// prepare signal sems
|
||||||
|
std::array<vk::Semaphore, 5> vkSignalSems{ };
|
||||||
i = 0;
|
i = 0;
|
||||||
for (auto& sem : signalSems)
|
for (auto& sem : signalSems)
|
||||||
{
|
{
|
||||||
|
@ -54,33 +52,76 @@ namespace SHADE
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<vk::CommandBuffer> vkCmdBuffers{ cmdBuffers.size() };
|
// prepare cmd buffers
|
||||||
|
std::array<vk::CommandBuffer, 5> vkCmdBuffers{ };
|
||||||
i = 0;
|
i = 0;
|
||||||
for (auto& cmdBuffer : cmdBuffers)
|
for (auto& cmdBuffer : cmdBuffers)
|
||||||
{
|
{
|
||||||
|
// Check if command buffer is in executable state
|
||||||
|
if (!cmdBuffer->IsReadyToSubmit())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("Command buffer is not in executable state. Cannot submit command buffer. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
vkCmdBuffers[i] = cmdBuffer->GetVkCommandBuffer();
|
vkCmdBuffers[i] = cmdBuffer->GetVkCommandBuffer();
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::PipelineStageFlags mask = waitDstStageMask;
|
// Prepare submit info
|
||||||
|
|
||||||
vk::SubmitInfo submitInfo
|
vk::SubmitInfo submitInfo
|
||||||
{
|
{
|
||||||
.waitSemaphoreCount = static_cast<uint32_t>(vkWaitSems.size()),
|
.waitSemaphoreCount = static_cast<uint32_t>(waitSems.size()),
|
||||||
.pWaitSemaphores = vkWaitSems.data(),
|
.pWaitSemaphores = vkWaitSems.data(),
|
||||||
.pWaitDstStageMask = &mask,
|
.pWaitDstStageMask = &waitDstStageMask,
|
||||||
.commandBufferCount = static_cast<uint32_t>(vkCmdBuffers.size()),
|
.commandBufferCount = static_cast<uint32_t>(cmdBuffers.size()),
|
||||||
.pCommandBuffers = vkCmdBuffers.data(),
|
.pCommandBuffers = vkCmdBuffers.data(),
|
||||||
.signalSemaphoreCount = static_cast<uint32_t>(vkSignalSems.size()),
|
.signalSemaphoreCount = static_cast<uint32_t>(signalSems.size()),
|
||||||
.pSignalSemaphores = vkSignalSems.data(),
|
.pSignalSemaphores = vkSignalSems.data(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// #BackEndTest: Submit the queue
|
// Submit the queue
|
||||||
if (auto result = vkQueue.submit(1, &submitInfo, (optionalFence) ? optionalFence->GetVkFence() : nullptr); result != vk::Result::eSuccess)
|
if (auto result = vkQueue.submit(1, &submitInfo, (optionalFence) ? optionalFence->GetVkFence() : nullptr); result != vk::Result::eSuccess)
|
||||||
{
|
{
|
||||||
SHVulkanDebugUtil::ReportVkError(result, "Failed to submit command buffer. ");
|
SHVulkanDebugUtil::ReportVkError(result, "Failed to submit command buffer. ");
|
||||||
}
|
}
|
||||||
|
else // if success
|
||||||
|
{
|
||||||
|
// Change all command buffers to pending state
|
||||||
|
for (Handle<SHVkCommandBuffer> cmdBuffer : cmdBuffers)
|
||||||
|
{
|
||||||
|
cmdBuffer->HandlePostSubmit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::Result SHVkQueue::Present(Handle<SHVkSwapchain> const& swapchain, std::initializer_list<Handle<SHVkSemaphore>> waitSems, uint32_t frameIndex) noexcept
|
||||||
|
{
|
||||||
|
vk::PresentInfoKHR presentInfo{};
|
||||||
|
|
||||||
|
// prepare wait sems
|
||||||
|
std::array<vk::Semaphore, 5> vkWaitSems{ };
|
||||||
|
uint32_t i = 0;
|
||||||
|
for (auto& sem : waitSems)
|
||||||
|
{
|
||||||
|
vkWaitSems[i] = sem->GetVkSem();
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare presentation information
|
||||||
|
presentInfo.waitSemaphoreCount = static_cast<uint32_t>(waitSems.size());
|
||||||
|
presentInfo.pWaitSemaphores = vkWaitSems.data();
|
||||||
|
presentInfo.swapchainCount = 1;
|
||||||
|
presentInfo.pSwapchains = &swapchain->GetVkSwapchain();
|
||||||
|
presentInfo.pImageIndices = &frameIndex;
|
||||||
|
|
||||||
|
// Present swapchain image.
|
||||||
|
auto result = vkQueue.presentKHR(&presentInfo);
|
||||||
|
if (result != vk::Result::eSuccess)
|
||||||
|
{
|
||||||
|
SHLOGV_ERROR ("Failed to present swapchain image. ");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@ namespace SHADE
|
||||||
class SHVkCommandBuffer;
|
class SHVkCommandBuffer;
|
||||||
class SHVkFence;
|
class SHVkFence;
|
||||||
class SHVkSemaphore;
|
class SHVkSemaphore;
|
||||||
|
class SHVkSwapchain;
|
||||||
|
|
||||||
enum class SH_QUEUE_FAMILY_ARRAY_INDEX : std::size_t
|
enum class SH_QUEUE_FAMILY_ARRAY_INDEX : std::size_t
|
||||||
{
|
{
|
||||||
|
@ -45,9 +46,9 @@ namespace SHADE
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SHVkQueue(vk::Queue inVkQueue, SHQueueFamilyIndex parent, Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl) noexcept;
|
SHVkQueue(vk::Queue inVkQueue, SHQueueFamilyIndex parent, Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl) noexcept;
|
||||||
vk::Queue GetVkQueue(void) const noexcept;
|
|
||||||
|
|
||||||
void SubmitCommandBuffer(std::initializer_list<Handle<SHVkCommandBuffer>> cmdBuffers, std::initializer_list<Handle<SHVkSemaphore>> signalSems = {}, std::initializer_list<Handle<SHVkSemaphore>> waitSems = {}, vk::PipelineStageFlagBits waitDstStageMask = {}, Handle<SHVkFence> const& fence = {}) noexcept;
|
void SubmitCommandBuffer (std::initializer_list<Handle<SHVkCommandBuffer>> cmdBuffers, std::initializer_list<Handle<SHVkSemaphore>> signalSems = {}, std::initializer_list<Handle<SHVkSemaphore>> waitSems = {}, vk::PipelineStageFlags waitDstStageMask = {}, Handle<SHVkFence> const& fence = {}) noexcept;
|
||||||
|
vk::Result Present (Handle<SHVkSwapchain> const& swapchain, std::initializer_list<Handle<SHVkSemaphore>> waitSems, uint32_t frameIndex) noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -209,9 +209,10 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHRenderGraphNode::SHSubpass::SHSubpass(std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
|
SHRenderGraphNode::SHSubpass::SHSubpass(Handle<SHRenderGraphNode> const& parent, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
|
||||||
: resourceAttachmentMapping{ mapping }
|
: resourceAttachmentMapping{ mapping }
|
||||||
, ptrToResources{ resources }
|
, ptrToResources{ resources }
|
||||||
|
, parentNode{ parent }
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -333,6 +334,38 @@ namespace SHADE
|
||||||
inputReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal });
|
inputReferences.push_back({ resourceAttachmentMapping->at(ptrToResources->at(resourceToReference).GetId().Raw), vk::ImageLayout::eShaderReadOnlyOptimal });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNode::SHSubpass::Execute(Handle<SHVkCommandBuffer>& commandBuffer) noexcept
|
||||||
|
{
|
||||||
|
// Draw all the batches
|
||||||
|
|
||||||
|
// Draw all the exterior draw calls
|
||||||
|
for (auto& drawCall : exteriorDrawCalls)
|
||||||
|
{
|
||||||
|
drawCall(commandBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNode::SHSubpass::AddExteriorDrawCalls(std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept
|
||||||
|
{
|
||||||
|
exteriorDrawCalls.push_back(newDrawCall);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Getter for parent renderpass.
|
||||||
|
|
||||||
|
\return
|
||||||
|
Returns the parent renderpass the subpass belongs to.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
Handle<SHRenderGraphNode> const& SHRenderGraphNode::SHSubpass::GetParentNode(void) const noexcept
|
||||||
|
{
|
||||||
|
return parentNode;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -426,10 +459,10 @@ namespace SHADE
|
||||||
// We set this to clear first. If later we find out that some predecessor is writing to the same attachment,
|
// We set this to clear first. If later we find out that some predecessor is writing to the same attachment,
|
||||||
// we set the pred's storeOp to eStore and "this" loadOp to eLoad.
|
// we set the pred's storeOp to eStore and "this" loadOp to eLoad.
|
||||||
newDesc.loadOp = vk::AttachmentLoadOp::eClear;
|
newDesc.loadOp = vk::AttachmentLoadOp::eClear;
|
||||||
newDesc.storeOp = vk::AttachmentStoreOp::eDontCare;
|
newDesc.storeOp = vk::AttachmentStoreOp::eStore;
|
||||||
|
|
||||||
newDesc.stencilLoadOp = vk::AttachmentLoadOp::eClear;
|
newDesc.stencilLoadOp = vk::AttachmentLoadOp::eClear;
|
||||||
newDesc.stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
|
newDesc.stencilStoreOp = vk::AttachmentStoreOp::eStore;
|
||||||
|
|
||||||
newDesc.format = attResources[i]->resourceFormat;
|
newDesc.format = attResources[i]->resourceFormat;
|
||||||
|
|
||||||
|
@ -512,11 +545,44 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add subpass to container and create mapping for it
|
// Add subpass to container and create mapping for it
|
||||||
subpasses.emplace_back(resourceManager.Create<SHSubpass>(&resourceAttachmentMapping, ptrToResources));
|
subpasses.emplace_back(resourceManager.Create<SHSubpass>(GetHandle(), &resourceAttachmentMapping, ptrToResources));
|
||||||
subpassIndexing.try_emplace(subpassName, subpasses.size() - 1);
|
subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
|
||||||
return subpasses.at(subpassIndexing[subpassName]);
|
return subpasses.at(subpassIndexing[subpassName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRenderGraphNode::Execute(Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept
|
||||||
|
{
|
||||||
|
frameIndex = (framebuffers.size() > 1) ? frameIndex : 0;
|
||||||
|
commandBuffer->BeginRenderpass(renderpass, framebuffers[frameIndex]);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < subpasses.size(); ++i)
|
||||||
|
{
|
||||||
|
subpasses[i]->Execute(commandBuffer);
|
||||||
|
|
||||||
|
// Go to next subpass if not last subpass
|
||||||
|
if (i != subpasses.size() - 1)
|
||||||
|
commandBuffer->NextSubpass();
|
||||||
|
}
|
||||||
|
|
||||||
|
commandBuffer->EndRenderpass();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Get the renderpass from the node.
|
||||||
|
|
||||||
|
\return
|
||||||
|
Handle to the renderpass.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
Handle<SHVkRenderpass> SHRenderGraphNode::GetRenderpass(void) const noexcept
|
||||||
|
{
|
||||||
|
return renderpass;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -544,7 +610,7 @@ namespace SHADE
|
||||||
|
|
||||||
*/
|
*/
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint32_t levels /*= 1*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
|
void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
|
||||||
{
|
{
|
||||||
// If we set to
|
// If we set to
|
||||||
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
|
||||||
|
@ -816,6 +882,24 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Configures command pools and command buffers.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***************************************************************************/
|
||||||
|
void SHRenderGraph::ConfigureCommands(void) noexcept
|
||||||
|
{
|
||||||
|
commandPool = logicalDeviceHdl->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
|
||||||
|
commandBuffers.resize(static_cast<std::size_t>(swapchainHdl->GetNumImages()));
|
||||||
|
for (auto& cmdBuffer : commandBuffers)
|
||||||
|
{
|
||||||
|
cmdBuffer = commandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
@ -913,7 +997,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes.emplace_back(resourceManager.Create<SHRenderGraphNode>(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(resources), std::move(predecessors), &graphResources));
|
nodes.emplace_back(resourceManager.Create<SHRenderGraphNode>(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(resources), std::move(predecessors), &graphResources));
|
||||||
nodeIndexing.emplace(nodeName, nodes.size() - 1);
|
nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
|
||||||
return nodes.at(nodeIndexing[nodeName]);
|
return nodes.at(nodeIndexing[nodeName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -936,6 +1020,37 @@ namespace SHADE
|
||||||
ConfigureSubpasses();
|
ConfigureSubpasses();
|
||||||
ConfigureRenderpasses();
|
ConfigureRenderpasses();
|
||||||
ConfigureFramebuffers();
|
ConfigureFramebuffers();
|
||||||
|
ConfigureCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHRenderGraph::Execute(uint32_t frameIndex) noexcept
|
||||||
|
{
|
||||||
|
commandPool->Reset();
|
||||||
|
|
||||||
|
auto& cmdBuffer = commandBuffers[frameIndex];
|
||||||
|
cmdBuffer->BeginRecording();
|
||||||
|
|
||||||
|
cmdBuffer->SetviewportScissor(1920.0f, 1080.0f, 1920, 1080);
|
||||||
|
|
||||||
|
for (auto& node : nodes)
|
||||||
|
{
|
||||||
|
node->Execute(commandBuffers[frameIndex], frameIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdBuffer->EndRecording();
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHRenderGraphNode> SHRenderGraph::GetNode(std::string const& nodeName) const noexcept
|
||||||
|
{
|
||||||
|
if (nodeIndexing.contains(nodeName))
|
||||||
|
return nodes[nodeIndexing.at(nodeName)];
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<SHVkCommandBuffer> const& SHRenderGraph::GetCommandBuffer(uint32_t frameIndex) const noexcept
|
||||||
|
{
|
||||||
|
return commandBuffers[frameIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "Graphics/Renderpass/SHVkRenderpass.h"
|
#include "Graphics/Renderpass/SHVkRenderpass.h"
|
||||||
#include "Resource/ResourceLibrary.h"
|
#include "Resource/ResourceLibrary.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -15,6 +16,8 @@ namespace SHADE
|
||||||
class SHVkImage;
|
class SHVkImage;
|
||||||
class SHVkImageView;
|
class SHVkImageView;
|
||||||
class SHVkFramebuffer;
|
class SHVkFramebuffer;
|
||||||
|
class SHVkCommandPool;
|
||||||
|
class SHVkCommandBuffer;
|
||||||
|
|
||||||
// Used for attachment description creation for renderpass node
|
// Used for attachment description creation for renderpass node
|
||||||
enum class SH_ATT_DESC_TYPE
|
enum class SH_ATT_DESC_TYPE
|
||||||
|
@ -26,7 +29,7 @@ namespace SHADE
|
||||||
DEPTH_STENCIL,
|
DEPTH_STENCIL,
|
||||||
};
|
};
|
||||||
|
|
||||||
class SHRenderGraphResource
|
class SH_API SHRenderGraphResource
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -72,25 +75,44 @@ namespace SHADE
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SHRenderGraphNode
|
class SH_API SHRenderGraphNode : public ISelfHandle<SHRenderGraphNode>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class SHSubpass
|
class SH_API SHSubpass
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SHSubpass(std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources) noexcept;
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* CTORS AND DTORS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
SHSubpass(Handle<SHRenderGraphNode> const& parent, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources) noexcept;
|
||||||
SHSubpass(SHSubpass&& rhs) noexcept;
|
SHSubpass(SHSubpass&& rhs) noexcept;
|
||||||
SHSubpass& operator=(SHSubpass&& rhs) noexcept;
|
SHSubpass& operator=(SHSubpass&& rhs) noexcept;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
// Preparation functions
|
||||||
void AddColorOutput (std::string resourceToReference) noexcept;
|
void AddColorOutput (std::string resourceToReference) noexcept;
|
||||||
void AddDepthOutput (std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType = SH_ATT_DESC_TYPE::DEPTH_STENCIL) noexcept;
|
void AddDepthOutput (std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType = SH_ATT_DESC_TYPE::DEPTH_STENCIL) noexcept;
|
||||||
void AddInput (std::string resourceToReference) noexcept;
|
void AddInput (std::string resourceToReference) noexcept;
|
||||||
|
|
||||||
|
// Runtime functions
|
||||||
|
void Execute (Handle<SHVkCommandBuffer>& commandBuffer) noexcept;
|
||||||
|
void AddExteriorDrawCalls (std::function<void(Handle<SHVkCommandBuffer>&)> const& newDrawCall) noexcept;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* GETTERS AND SETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
Handle<SHRenderGraphNode> const& GetParentNode (void) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
|
//! The parent renderpass that this subpass belongs to
|
||||||
|
Handle<SHRenderGraphNode> parentNode;
|
||||||
|
|
||||||
//! Color attachments
|
//! Color attachments
|
||||||
std::vector<vk::AttachmentReference> colorReferences;
|
std::vector<vk::AttachmentReference> colorReferences;
|
||||||
|
|
||||||
|
@ -106,6 +128,14 @@ namespace SHADE
|
||||||
//! Pointer to resources in the render graph (for getting handle IDs)
|
//! Pointer to resources in the render graph (for getting handle IDs)
|
||||||
std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources;
|
std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources;
|
||||||
|
|
||||||
|
//! Sometimes there exists entities that we want to render onto a render target
|
||||||
|
//! but don't want it to come from the batching system. An example would be ImGUI.
|
||||||
|
//! For these entities we want to link a function from the outside and draw them
|
||||||
|
//! 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<std::function<void(Handle<SHVkCommandBuffer>&)>> exteriorDrawCalls;
|
||||||
|
|
||||||
friend class SHRenderGraphNode;
|
friend class SHRenderGraphNode;
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
};
|
};
|
||||||
|
@ -179,11 +209,17 @@ namespace SHADE
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
Handle<SHSubpass> AddSubpass (std::string subpassName) noexcept;
|
Handle<SHSubpass> AddSubpass (std::string subpassName) noexcept;
|
||||||
|
void Execute (Handle<SHVkCommandBuffer>& commandBuffer, uint32_t frameIndex) noexcept;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* SETTERS AND GETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
Handle<SHVkRenderpass> GetRenderpass (void) const noexcept;
|
||||||
|
|
||||||
friend class SHRenderGraph;
|
friend class SHRenderGraph;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SHRenderGraph
|
class SH_API SHRenderGraph
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@ -193,6 +229,7 @@ namespace SHADE
|
||||||
void ConfigureSubpasses (void) noexcept;
|
void ConfigureSubpasses (void) noexcept;
|
||||||
void ConfigureRenderpasses (void) noexcept;
|
void ConfigureRenderpasses (void) noexcept;
|
||||||
void ConfigureFramebuffers (void) noexcept;
|
void ConfigureFramebuffers (void) noexcept;
|
||||||
|
void ConfigureCommands (void) noexcept;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
|
@ -214,6 +251,13 @@ namespace SHADE
|
||||||
//! Resource library for graph handles
|
//! Resource library for graph handles
|
||||||
ResourceManager resourceManager;
|
ResourceManager resourceManager;
|
||||||
|
|
||||||
|
//! Command pool for the render graph
|
||||||
|
Handle<SHVkCommandPool> commandPool;
|
||||||
|
|
||||||
|
//! Command buffers for the render graph
|
||||||
|
std::vector<Handle<SHVkCommandBuffer>> commandBuffers;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTORS AND DTORS */
|
/* CTORS AND DTORS */
|
||||||
|
@ -223,10 +267,17 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PUBLIC MEMBER FUNCTIONS */
|
/* PUBLIC MEMBER FUNCTIONS */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
void Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept;
|
void Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept;
|
||||||
void AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint32_t levels = 1, vk::ImageCreateFlagBits createFlags = {});
|
void AddResource (std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageCreateFlagBits createFlags = {});
|
||||||
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept;
|
Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept;
|
||||||
void Generate (void) noexcept;
|
void Generate (void) noexcept;
|
||||||
|
void Execute (uint32_t frameIndex) noexcept;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* SETTERS AND GETTERS */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
Handle<SHRenderGraphNode> GetNode (std::string const& nodeName) const noexcept;
|
||||||
|
Handle<SHVkCommandBuffer> const& GetCommandBuffer (uint32_t frameIndex) const noexcept;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,17 @@ namespace SHADE
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
SHVkRenderpass::SHVkRenderpass(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept
|
SHVkRenderpass::SHVkRenderpass(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept
|
||||||
: logicalDeviceHdl {inLogicalDeviceHdl}
|
: logicalDeviceHdl {inLogicalDeviceHdl}
|
||||||
|
, numAttDescs {static_cast<uint32_t>(vkDescriptions.size())}
|
||||||
, clearColors{}
|
, clearColors{}
|
||||||
{
|
{
|
||||||
// TODO: temporary only
|
for (uint32_t i = 0; i < vkDescriptions.size(); ++i)
|
||||||
clearColors[0].color = { {{0.0f, 0.0f, 0.0f, 1.0f}} };
|
{
|
||||||
clearColors[1].depthStencil = vk::ClearDepthStencilValue(1.0f, 0);
|
if (SHVkUtil::IsDepthStencilAttachment(vkDescriptions[i].format))
|
||||||
|
clearColors[i].depthStencil = vk::ClearDepthStencilValue(1.0f, 0);
|
||||||
|
else
|
||||||
|
clearColors[i].color = { {{0.0f, 0.0f, 0.0f, 1.0f}} };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
vk::RenderPassCreateInfo renderPassCreateInfo{};
|
vk::RenderPassCreateInfo renderPassCreateInfo{};
|
||||||
std::vector<vk::SubpassDependency> subpassDeps;
|
std::vector<vk::SubpassDependency> subpassDeps;
|
||||||
|
@ -164,11 +170,16 @@ namespace SHADE
|
||||||
|
|
||||||
SHVkRenderpass::SHVkRenderpass(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, std::span<vk::AttachmentDescription> const vkDescriptions, std::span<vk::SubpassDescription> const spDescs, std::span<vk::SubpassDependency> const spDeps) noexcept
|
SHVkRenderpass::SHVkRenderpass(Handle<SHVkLogicalDevice> const& inLogicalDeviceHdl, std::span<vk::AttachmentDescription> const vkDescriptions, std::span<vk::SubpassDescription> const spDescs, std::span<vk::SubpassDependency> const spDeps) noexcept
|
||||||
: logicalDeviceHdl{ inLogicalDeviceHdl }
|
: logicalDeviceHdl{ inLogicalDeviceHdl }
|
||||||
|
, numAttDescs{ static_cast<uint32_t>(vkDescriptions.size()) }
|
||||||
, clearColors{}
|
, clearColors{}
|
||||||
{
|
{
|
||||||
// TODO: temporary only
|
for (uint32_t i = 0; i < vkDescriptions.size(); ++i)
|
||||||
clearColors[0].color = { {{0.0f, 0.0f, 0.0f, 1.0f}} };
|
{
|
||||||
clearColors[1].depthStencil = vk::ClearDepthStencilValue(1.0f, 0);
|
if (SHVkUtil::IsDepthStencilAttachment(vkDescriptions[i].format))
|
||||||
|
clearColors[i].depthStencil = vk::ClearDepthStencilValue(1.0f, 0);
|
||||||
|
else
|
||||||
|
clearColors[i].color = { {{0.0f, 0.0f, 0.0f, 1.0f}} };
|
||||||
|
}
|
||||||
|
|
||||||
subpassDescriptions.resize (spDescs.size());
|
subpassDescriptions.resize (spDescs.size());
|
||||||
for (uint32_t i = 0; i < subpassDescriptions.size(); ++i)
|
for (uint32_t i = 0; i < subpassDescriptions.size(); ++i)
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* STATIC CONSTEXPR VALUES */
|
/* STATIC CONSTEXPR VALUES */
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
static constexpr uint32_t NUM_CLEAR_COLORS = 2;
|
static constexpr uint32_t NUM_CLEAR_COLORS = 10;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
|
@ -34,6 +34,9 @@ namespace SHADE
|
||||||
//! Clear colors for the color and depth
|
//! Clear colors for the color and depth
|
||||||
std::array<vk::ClearValue, NUM_CLEAR_COLORS> clearColors;
|
std::array<vk::ClearValue, NUM_CLEAR_COLORS> clearColors;
|
||||||
|
|
||||||
|
// number of attachment descriptions
|
||||||
|
uint32_t numAttDescs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* CTOR AND DTOR */
|
/* CTOR AND DTOR */
|
||||||
|
|
|
@ -189,7 +189,7 @@ namespace SHADE
|
||||||
|
|
||||||
Handle<SHShaderBlockInterface> SHShaderDescriptorBindingInfo::GetShaderBlockInterface(uint32_t set, uint32_t binding) const noexcept
|
Handle<SHShaderBlockInterface> SHShaderDescriptorBindingInfo::GetShaderBlockInterface(uint32_t set, uint32_t binding) const noexcept
|
||||||
{
|
{
|
||||||
SHShaderDescriptorBindingInfo::BindingAndSetHash hash = binding;
|
BindingAndSetHash hash = binding;
|
||||||
hash |= static_cast<uint64_t>(set) << 32;
|
hash |= static_cast<uint64_t>(set) << 32;
|
||||||
if (blockInterfaces.contains(hash))
|
if (blockInterfaces.contains(hash))
|
||||||
return blockInterfaces.at(hash);
|
return blockInterfaces.at(hash);
|
||||||
|
|
|
@ -9,11 +9,10 @@
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
using BindingAndSetHash = uint64_t;
|
||||||
|
|
||||||
struct SHShaderDescriptorBindingInfo
|
struct SHShaderDescriptorBindingInfo
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
using BindingAndSetHash = uint64_t;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
/* PRIVATE MEMBER VARIABLES */
|
/* PRIVATE MEMBER VARIABLES */
|
||||||
|
|
|
@ -19,10 +19,14 @@ namespace SHADE
|
||||||
vkPresentModes = physicalDeviceHdl->GetVkPhysicalDevice().getSurfacePresentModesKHR(surfaceHdl->GetVkSurface());
|
vkPresentModes = physicalDeviceHdl->GetVkPhysicalDevice().getSurfacePresentModesKHR(surfaceHdl->GetVkSurface());
|
||||||
|
|
||||||
if (vkSurfaceFormats.size() == 0)
|
if (vkSurfaceFormats.size() == 0)
|
||||||
|
{
|
||||||
SHLOG_ERROR("Failed to get surface formats from the physical device. ");
|
SHLOG_ERROR("Failed to get surface formats from the physical device. ");
|
||||||
|
}
|
||||||
|
|
||||||
if (vkPresentModes.size() == 0)
|
if (vkPresentModes.size() == 0)
|
||||||
|
{
|
||||||
SHLOG_ERROR("Failed to get present modes from the physical device. ");
|
SHLOG_ERROR("Failed to get present modes from the physical device. ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::SurfaceFormatKHR SHVkSwapchain::ChooseSwapSurfaceFormat(std::vector<vk::SurfaceFormatKHR> const& surfaceFormats) const noexcept
|
vk::SurfaceFormatKHR SHVkSwapchain::ChooseSwapSurfaceFormat(std::vector<vk::SurfaceFormatKHR> const& surfaceFormats) const noexcept
|
||||||
|
|
|
@ -18,7 +18,10 @@ namespace SHADE
|
||||||
// that a mat2 can be interpreted as (x, y, x, y), (o, o, o, o) instead of (x, y, o, o), (o, o, o, o)?
|
// that a mat2 can be interpreted as (x, y, x, y), (o, o, o, o) instead of (x, y, o, o), (o, o, o, o)?
|
||||||
MAT_2D,
|
MAT_2D,
|
||||||
MAT_3D,
|
MAT_3D,
|
||||||
MAT_4D
|
MAT_4D,
|
||||||
|
|
||||||
|
// integer formats
|
||||||
|
UINT32_1D,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHVertexAttribute
|
struct SHVertexAttribute
|
||||||
|
|
|
@ -222,7 +222,7 @@ namespace SHADE
|
||||||
return true;
|
return true;
|
||||||
{
|
{
|
||||||
MSG Message;
|
MSG Message;
|
||||||
while (PeekMessageW(&Message, NULL, 0, 0, PM_REMOVE))
|
while (PeekMessageW(&Message, wndHWND, 0, 0, PM_REMOVE))
|
||||||
{
|
{
|
||||||
if (WM_QUIT == Message.message)
|
if (WM_QUIT == Message.message)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "SHWindowMap.h"
|
#include "SHWindowMap.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -67,7 +68,7 @@ namespace SHADE
|
||||||
std::string icoPath = "";
|
std::string icoPath = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
class SHWindow
|
class SH_API SHWindow
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using SHVec2 = std::pair<uint32_t, uint32_t>;
|
using SHVec2 = std::pair<uint32_t, uint32_t>;
|
||||||
|
|
|
@ -139,7 +139,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
ResourceLibrary<T>* library;
|
ResourceLibrary<T>* library = nullptr;
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/* Friend Declarations */
|
/* Friend Declarations */
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace SHADE
|
||||||
/* Helper Functions */
|
/* Helper Functions */
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
void assertHandleValid(Handle<T> handle) const;
|
void assertHandleValid(Handle<T> handle) const;
|
||||||
int getAvailableFreeIndex();
|
uint32_t getAvailableFreeIndex();
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -35,13 +35,13 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
handle.id.Data.Version = 0;
|
handle.id.Data.Version = 0U;
|
||||||
versionCounts.insert(handle.id.Data.Index, handle.id.Data.Version);
|
versionCounts.insert(static_cast<uint32_t>(handle.id.Data.Index), handle.id.Data.Version);
|
||||||
}
|
}
|
||||||
handle.library = this;
|
handle.library = this;
|
||||||
|
|
||||||
// Create the resource
|
// Create the resource
|
||||||
[[maybe_unused]] T& obj = objects.insert(handle.id.Data.Index, std::forward<Args>(args) ...);
|
[[maybe_unused]] T& obj = objects.insert(static_cast<uint32_t>(handle.id.Data.Index), std::forward<Args>(args) ...);
|
||||||
|
|
||||||
// Handling SelfHandle assignment
|
// Handling SelfHandle assignment
|
||||||
if constexpr (std::is_base_of_v<ISelfHandle<T>, T>)
|
if constexpr (std::is_base_of_v<ISelfHandle<T>, T>)
|
||||||
|
@ -89,7 +89,7 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline int ResourceLibrary<T>::getAvailableFreeIndex()
|
inline uint32_t ResourceLibrary<T>::getAvailableFreeIndex()
|
||||||
{
|
{
|
||||||
// Get from the free list if present
|
// Get from the free list if present
|
||||||
if (!freeList.empty())
|
if (!freeList.empty())
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace SHADE
|
||||||
throw std::invalid_argument("An element at this index does not exist!");
|
throw std::invalid_argument("An element at this index does not exist!");
|
||||||
|
|
||||||
// Swap with the last element
|
// Swap with the last element
|
||||||
const int BACK_IDX = denseArray.size() - 1;
|
const auto BACK_IDX = denseArray.size() - 1;
|
||||||
std::swap(denseArray[sparseArray[idx]], denseArray.back());
|
std::swap(denseArray[sparseArray[idx]], denseArray.back());
|
||||||
denseArray.pop_back();
|
denseArray.pop_back();
|
||||||
// Update the sparse set by swapping the indices
|
// Update the sparse set by swapping the indices
|
||||||
|
@ -110,7 +110,7 @@ namespace SHADE
|
||||||
// We need to resize the array
|
// We need to resize the array
|
||||||
if (idx >= sparseArray.size())
|
if (idx >= sparseArray.size())
|
||||||
{
|
{
|
||||||
const int NEW_SIZE = idx + 1;
|
const auto NEW_SIZE = idx + 1;
|
||||||
sparseArray.resize(NEW_SIZE, INVALID);
|
sparseArray.resize(NEW_SIZE, INVALID);
|
||||||
inverseSparseArray.resize(NEW_SIZE, INVALID);
|
inverseSparseArray.resize(NEW_SIZE, INVALID);
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ namespace SHADE
|
||||||
auto& insertedElem = denseArray.emplace_back(std::forward<Args>(args) ...);
|
auto& insertedElem = denseArray.emplace_back(std::forward<Args>(args) ...);
|
||||||
|
|
||||||
// Update sparse and inverse sparse arrays
|
// Update sparse and inverse sparse arrays
|
||||||
const index_type DENSE_IDX = denseArray.size() - 1;
|
const auto DENSE_IDX = static_cast<index_type>(denseArray.size()) - 1;
|
||||||
sparseArray[idx] = DENSE_IDX;
|
sparseArray[idx] = DENSE_IDX;
|
||||||
inverseSparseArray[DENSE_IDX] = idx;
|
inverseSparseArray[DENSE_IDX] = idx;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHCommonTypes.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 8, 2022
|
||||||
|
\brief Contains the definitions of type alias for commonly used units for
|
||||||
|
clarity and convenience.
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
\brief
|
||||||
|
Type used to mark a value that is supposed to represent a size in bytes.
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
using Byte = size_t;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SH_API.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 13, 2022
|
||||||
|
\brief Contains dllexport and dllimport macros for the SHADE Engine.
|
||||||
|
|
||||||
|
Copyright (C) 2022 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Select the correct export system based on the compiler
|
||||||
|
#if defined SH_LIB
|
||||||
|
# define SH_API
|
||||||
|
#else
|
||||||
|
# if defined _WIN32 || defined __CYGWIN__ || defined _MSC_VER
|
||||||
|
# define SH_EXPORT __declspec(dllexport)
|
||||||
|
# define SH_IMPORT __declspec(dllimport)
|
||||||
|
# elif defined __GNUC__ && __GNUC__ >= 4
|
||||||
|
# define SH_EXPORT __attribute__((visibility("default")))
|
||||||
|
# define SH_IMPORT __attribute__((visibility("default")))
|
||||||
|
# else /* Unsupported compiler */
|
||||||
|
# define SH_EXPORT
|
||||||
|
# define SH_IMPORT
|
||||||
|
# endif
|
||||||
|
// Define the correct
|
||||||
|
# ifndef SH_API
|
||||||
|
# if defined SH_API_EXPORT
|
||||||
|
# define SH_API SH_EXPORT
|
||||||
|
# else
|
||||||
|
# define SH_API SH_IMPORT
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
|
@ -33,5 +33,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#include "Common/SHCommonTypes.h"
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLogger.h"
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include "SHSceneGraph.h"
|
#include "SHSceneGraph.h"
|
||||||
|
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "ECS_Base/System/SHEntityManager.h"
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
#include "Tools/SHLogger.h"
|
#include "Tools/SHLogger.h"
|
||||||
#include "Tools/SHException.h"
|
#include "Tools/SHException.h"
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,11 @@
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
#include "SHpch.h"
|
#include "SHpch.h"
|
||||||
#include "SHSceneManager.h"
|
#include "SHSceneManager.h"
|
||||||
#include "ECS_Base/System/SHComponentManager.h"
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
//#include "Input/SHInputManager.h"
|
//#include "Input/SHInputManager.h"
|
||||||
//#include "Rendering/Window/SHRenderingWindow.h"
|
//#include "Rendering/Window/SHRenderingWindow.h"
|
||||||
#include "ECS_Base/System/SHEntityManager.h"
|
#include "ECS_Base/Managers/SHEntityManager.h"
|
||||||
#include "ECS_Base/System/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
//#include "FRC/SHFrameRateController.h"
|
//#include "FRC/SHFrameRateController.h"
|
||||||
//#include "ECS_Base/System/SHApplication.h"
|
//#include "ECS_Base/System/SHApplication.h"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,198 @@
|
||||||
|
/*************************************************************************************//*!
|
||||||
|
\file SHDotNetRuntime.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 2, 2021
|
||||||
|
\brief Contains the definition of the SHDotNetRuntime class.
|
||||||
|
Implementation of code to set up code for SHDotNetRuntime is based on the
|
||||||
|
following repository:
|
||||||
|
https://github.com/mjrousos/SampleCoreCLRHost
|
||||||
|
|
||||||
|
Copyright (C) 2021 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 Header
|
||||||
|
#include <SHpch.h>
|
||||||
|
// Primary Header
|
||||||
|
#include "SHDotNetRuntime.h"
|
||||||
|
// Standard Library
|
||||||
|
#include <array>
|
||||||
|
// External Dependencies
|
||||||
|
#include <shlwapi.h> // PathRemoveFileSpecA
|
||||||
|
#include "Tools/SHLogger.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors/Destructor */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
SHDotNetRuntime::SHDotNetRuntime(bool autoInit)
|
||||||
|
{
|
||||||
|
if (autoInit)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHDotNetRuntime::~SHDotNetRuntime()
|
||||||
|
{
|
||||||
|
if (IsLoaded())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Exit();
|
||||||
|
}
|
||||||
|
catch (std::runtime_error& e)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR(e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Lifecycle Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void SHDotNetRuntime::Init()
|
||||||
|
{
|
||||||
|
// State checking, in case there was an unload before, we must ensure that the state is valid
|
||||||
|
if (initialised)
|
||||||
|
throw std::runtime_error("[DotNetRuntime] Failed to initialise as it was already initialised or was deinitialised into an invalid state.");
|
||||||
|
|
||||||
|
// Get the current executable directory
|
||||||
|
std::string runtimePath(MAX_PATH, '\0');
|
||||||
|
GetModuleFileNameA(nullptr, runtimePath.data(), MAX_PATH);
|
||||||
|
PathRemoveFileSpecA(runtimePath.data());
|
||||||
|
// Since PathRemoveFileSpecA() removes from data(), the size is not updated, so we must manually update it
|
||||||
|
runtimePath.resize(std::strlen(runtimePath.data()));
|
||||||
|
|
||||||
|
// Do not need to load the library if it was previously loaded
|
||||||
|
if (coreClr == nullptr)
|
||||||
|
{
|
||||||
|
// Construct the CoreCLR path
|
||||||
|
std::string coreClrPath(runtimePath); // Works
|
||||||
|
coreClrPath += "\\coreclr.dll";
|
||||||
|
|
||||||
|
// Load the CoreCLR DLL
|
||||||
|
coreClr = LoadLibraryExA(coreClrPath.c_str(), nullptr, 0);
|
||||||
|
if (!coreClr)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "[DotNetRuntime] Error #" << GetLastError() << " Failed to load CoreCLR from \"" << coreClrPath << "\"\n";
|
||||||
|
throw std::runtime_error(oss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: Get CoreCLR hosting functions
|
||||||
|
initializeCoreClr = getCoreClrFunctionPtr<coreclr_initialize_ptr>("coreclr_initialize");
|
||||||
|
createManagedDelegate = getCoreClrFunctionPtr<coreclr_create_delegate_ptr>("coreclr_create_delegate");
|
||||||
|
shutdownCoreClr = getCoreClrFunctionPtr<coreclr_shutdown_ptr>("coreclr_shutdown");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: Construct AppDomain properties used when starting the runtime
|
||||||
|
// Construct the trusted platform assemblies (TPA) list
|
||||||
|
// This is the list of assemblies that .NET Core can load as
|
||||||
|
// trusted system assemblies (similar to the .NET Framework GAC).
|
||||||
|
// For this host (as with most), assemblies next to CoreCLR will
|
||||||
|
// be included in the TPA list
|
||||||
|
std::string tpaList = buildTpaList(runtimePath);
|
||||||
|
|
||||||
|
// Define CoreCLR properties
|
||||||
|
std::array propertyKeys =
|
||||||
|
{
|
||||||
|
"TRUSTED_PLATFORM_ASSEMBLIES", // Trusted assemblies (like the GAC)
|
||||||
|
"APP_PATHS", // Directories to probe for application assemblies
|
||||||
|
// "APP_NI_PATHS", // Directories to probe for application native images (not used in this sample)
|
||||||
|
// "NATIVE_DLL_SEARCH_DIRECTORIES", // Directories to probe for native dlls (not used in this sample)
|
||||||
|
};
|
||||||
|
std::array propertyValues =
|
||||||
|
{
|
||||||
|
tpaList.c_str(),
|
||||||
|
runtimePath.c_str()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Step 4: Start the CoreCLR runtime
|
||||||
|
int result = initializeCoreClr
|
||||||
|
(
|
||||||
|
runtimePath.c_str(), // AppDomain base path
|
||||||
|
"SHADEHost", // AppDomain friendly name
|
||||||
|
static_cast<int>(propertyKeys.size()), // Property count
|
||||||
|
propertyKeys.data(), // Property names
|
||||||
|
propertyValues.data(), // Property values
|
||||||
|
&hostHandle, // Host handle
|
||||||
|
&domainId // AppDomain ID
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check if intiialization of CoreCLR failed
|
||||||
|
throwIfFailed("[DotNetRuntime] Failed to initialize CoreCLR.", result);
|
||||||
|
|
||||||
|
initialised = true;
|
||||||
|
SHLOG_INFO("[DotNetRuntime] Successfully loaded the .NET 5.0 Runtime.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDotNetRuntime::Exit()
|
||||||
|
{
|
||||||
|
// State checking, in case there was an unload before, we must ensure that the state is valid
|
||||||
|
if (!initialised)
|
||||||
|
throw std::runtime_error("[DotNetRuntime] Failed to deinitialise as it was not initialised before.");
|
||||||
|
|
||||||
|
// Shutdown CoreCLR
|
||||||
|
int result = shutdownCoreClr(hostHandle, domainId);
|
||||||
|
throwIfFailed("[DotNetRuntime] Failed to shut down CoreCLR.", result);
|
||||||
|
|
||||||
|
// Unset pointers
|
||||||
|
hostHandle = nullptr;
|
||||||
|
domainId = 0;
|
||||||
|
initialised = false;
|
||||||
|
|
||||||
|
SHLOG_INFO("[DotNetRuntime] Successfully shut down the .NET 5.0 Runtime.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
std::string SHDotNetRuntime::buildTpaList(const std::string& directory)
|
||||||
|
{
|
||||||
|
// Constants
|
||||||
|
static const std::string SEARCH_PATH = directory + "\\*.dll";
|
||||||
|
static constexpr char PATH_DELIMITER = ';';
|
||||||
|
|
||||||
|
// Create a osstream object to compile the string
|
||||||
|
std::ostringstream tpaList;
|
||||||
|
|
||||||
|
// Search the current directory for the TPAs (.DLLs)
|
||||||
|
WIN32_FIND_DATAA findData;
|
||||||
|
HANDLE fileHandle = FindFirstFileA(SEARCH_PATH.c_str(), &findData);
|
||||||
|
if (fileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Append the assembly to the list
|
||||||
|
tpaList << directory << '\\' << findData.cFileName << PATH_DELIMITER;
|
||||||
|
|
||||||
|
// Note that the CLR does not guarantee which assembly will be loaded if an assembly
|
||||||
|
// is in the TPA list multiple times (perhaps from different paths or perhaps with different NI/NI.dll
|
||||||
|
// extensions. Therefore, a real host should probably add items to the list in priority order and only
|
||||||
|
// add a file if it's not already present on the list.
|
||||||
|
//
|
||||||
|
// For this simple sample, though, and because we're only loading TPA assemblies from a single path,
|
||||||
|
// and have no native images, we can ignore that complication.
|
||||||
|
}
|
||||||
|
while (FindNextFileA(fileHandle, &findData));
|
||||||
|
FindClose(fileHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tpaList.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHDotNetRuntime::throwIfFailed(const std::string& errMsg, int resultCode)
|
||||||
|
{
|
||||||
|
if (resultCode < 0)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << std::hex << std::setfill('0') << std::setw(8)
|
||||||
|
<< errMsg
|
||||||
|
<< " Error 0x" << resultCode << "\n";
|
||||||
|
throw std::runtime_error(oss.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,207 @@
|
||||||
|
/*************************************************************************************//*!
|
||||||
|
\file SHDotNetRuntime.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 2, 2021
|
||||||
|
\brief Contains the interface of a wrapper class for interfacing with the
|
||||||
|
.NET 5 Runtime.
|
||||||
|
|
||||||
|
Copyright (C) 2021 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//**************************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Standard Libraries
|
||||||
|
#include <iomanip> // std::setfill, std::setw
|
||||||
|
#include <stdexcept> // std::runtime_error
|
||||||
|
#include <string> // std::string
|
||||||
|
#include <sstream> // std::ostringstream
|
||||||
|
// External Dependencies
|
||||||
|
#include <Windows.h> // HMODULE
|
||||||
|
#include <coreclrhost.h> // coreclr_*
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*************************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
class SHDotNetRuntime
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Class that encapsulates the state of the .NET Core Runtime lifecycle.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/*************************************************************************************/
|
||||||
|
|
||||||
|
class SHDotNetRuntime
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors/Destructor */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Default constructor that immediately initializes the CoreCLR.
|
||||||
|
|
||||||
|
\param autoInit
|
||||||
|
If true, loads the CoreCLR by calling Init().
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
SHDotNetRuntime(bool autoInit = true);
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Destructor that unloads the CoreCLR if it has not been unloaded yet.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
~SHDotNetRuntime();
|
||||||
|
|
||||||
|
// Disallow copy and moving
|
||||||
|
SHDotNetRuntime(const SHDotNetRuntime&) = delete;
|
||||||
|
SHDotNetRuntime(SHDotNetRuntime&&) = delete;
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------------*/
|
||||||
|
/* Lifecycle Functions */
|
||||||
|
/*----------------------------------------------------------------------------------*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Loads the CoreCLR and grabs pointers to bootstrapping functions and kickstarts the
|
||||||
|
CoreCLR.
|
||||||
|
|
||||||
|
\throws std::runtime_error
|
||||||
|
Thrown if there is a failure in loading the CLR and related functions.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
void Init();
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Unloads the CoreCLR.
|
||||||
|
|
||||||
|
\throws std::runtime_error
|
||||||
|
Thrown if there is a failure in unloading the CLR.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
void Exit();
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------------*/
|
||||||
|
/* Usage Functions */
|
||||||
|
/*----------------------------------------------------------------------------------*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Checks if the DotNetRuntime has successfully been initialised.
|
||||||
|
|
||||||
|
\return
|
||||||
|
True if this DotNetRuntime has been initialised.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
inline bool IsLoaded() const noexcept { return initialised; }
|
||||||
|
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Retrieves a function pointer from the a CLR assembly based on the specified
|
||||||
|
assembly, type and function names.
|
||||||
|
|
||||||
|
\tparam FunctionType
|
||||||
|
Type of the function pointer that the specified function name will provide.
|
||||||
|
\param assemblyName
|
||||||
|
Name of the CoreCLR assembly that contains the function.
|
||||||
|
\param typeName
|
||||||
|
Name of the CoreCLR type in the assembly that contains the function. Nested types
|
||||||
|
are separated by a period(.).
|
||||||
|
\param functionName
|
||||||
|
Name of the CoreCLR function to get a pointer to.
|
||||||
|
\return
|
||||||
|
Pointer to the function in the assembly that was specified.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
template<typename FunctionType>
|
||||||
|
FunctionType GetFunctionPtr(const std::string_view& assemblyName,
|
||||||
|
const std::string_view& typeName,
|
||||||
|
const std::string_view& functionName) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
bool initialised = false;
|
||||||
|
// References to CoreCLR key components
|
||||||
|
HMODULE coreClr = nullptr;
|
||||||
|
void* hostHandle = nullptr;
|
||||||
|
unsigned int domainId = 0;
|
||||||
|
// Function Pointers to CoreCLR functions
|
||||||
|
coreclr_initialize_ptr initializeCoreClr = nullptr;
|
||||||
|
coreclr_create_delegate_ptr createManagedDelegate = nullptr;
|
||||||
|
coreclr_shutdown_ptr shutdownCoreClr = nullptr;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Retrieves a function pointer from the CoreCLR based on the specified
|
||||||
|
function name.
|
||||||
|
|
||||||
|
\tparam FunctionType
|
||||||
|
Type of the function pointer that the specified function name will provide.
|
||||||
|
\param functionName
|
||||||
|
Name of the CoreCLR function to get a pointer to.
|
||||||
|
\return
|
||||||
|
Pointer to the function in the CoreCLR that was specified.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
template<typename FunctionType>
|
||||||
|
FunctionType getCoreClrFunctionPtr(const std::string& functionName);
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Compiles a semicolon separated string of trusted platform assemblies by
|
||||||
|
searching the specified directory.
|
||||||
|
|
||||||
|
\param directory
|
||||||
|
Path to the directory where the trusted platform assemblies reside.
|
||||||
|
\return
|
||||||
|
Semicolon separated string of trusted platform assemblies.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
static std::string buildTpaList(const std::string& directory);
|
||||||
|
/***********************************************************************************/
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief
|
||||||
|
Takes in a Win32 result code and throws an exception it if there is an error.
|
||||||
|
|
||||||
|
\param errMsg
|
||||||
|
Error message to display if the resultCode is a failure code.
|
||||||
|
\param resultCode
|
||||||
|
Result code of the function to check.
|
||||||
|
|
||||||
|
*/
|
||||||
|
/***********************************************************************************/
|
||||||
|
static void throwIfFailed(const std::string& errMsg, int resultCode);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "SHDotNetRuntime.hpp"
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*************************************************************************************//*!
|
||||||
|
\file SHDotNetRuntime.hpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Oct 2, 2021
|
||||||
|
\brief Contains the implementation of the template functions of the
|
||||||
|
DotNetRuntime class.
|
||||||
|
|
||||||
|
Copyright (C) 2021 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//**************************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Primary Include
|
||||||
|
#include "SHDotNetRuntime.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
template<typename FunctionType>
|
||||||
|
FunctionType SHDotNetRuntime::GetFunctionPtr(const std::string_view & assemblyName,
|
||||||
|
const std::string_view & typeName,
|
||||||
|
const std::string_view & functionName) const
|
||||||
|
{
|
||||||
|
FunctionType managedDelegate = nullptr;
|
||||||
|
int result = createManagedDelegate
|
||||||
|
(
|
||||||
|
hostHandle,
|
||||||
|
domainId,
|
||||||
|
assemblyName.data(),
|
||||||
|
typeName.data(),
|
||||||
|
functionName.data(),
|
||||||
|
reinterpret_cast<void**>(&managedDelegate)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check if it failed
|
||||||
|
if (result < 0)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << std::hex << std::setfill('0') << std::setw(8)
|
||||||
|
<< "[DotNetRuntime] Failed to get pointer to function \""
|
||||||
|
<< typeName << "." << functionName << "\" in assembly (" << assemblyName << "). "
|
||||||
|
<< "Error 0x" << result << "\n";
|
||||||
|
throw std::runtime_error(oss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return managedDelegate;
|
||||||
|
}
|
||||||
|
template<typename FunctionType>
|
||||||
|
FunctionType SHDotNetRuntime::getCoreClrFunctionPtr(const std::string& functionName)
|
||||||
|
{
|
||||||
|
FunctionType fPtr = reinterpret_cast<FunctionType>(GetProcAddress(coreClr, functionName.c_str()));
|
||||||
|
if (!fPtr)
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "[DotNetRuntime] Unable to get pointer to function: \"" << functionName << "\"";
|
||||||
|
throw std::runtime_error(oss.str());
|
||||||
|
}
|
||||||
|
return fPtr;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,506 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHScriptEngine.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Sep 17, 2021
|
||||||
|
\brief Contains the implementation for ScriptEngine class.
|
||||||
|
|
||||||
|
Copyright (C) 2021 DigiPen Institute of Technology.
|
||||||
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
||||||
|
of DigiPen Institute of Technology is prohibited.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
// Precompiled Headers
|
||||||
|
#include <SHpch.h>
|
||||||
|
// Primary Header
|
||||||
|
#include "SHScriptEngine.h"
|
||||||
|
// Standard Library
|
||||||
|
#include <fstream> // std::fstream
|
||||||
|
#include <filesystem> // std::filesystem::canonical, std::filesystem::remove
|
||||||
|
// Project Headers
|
||||||
|
#include "Tools/SHLogger.h"
|
||||||
|
#include "Tools/SHStringUtils.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*--------------------------------------------------------------------------------*/
|
||||||
|
/* Static Definitions */
|
||||||
|
/*--------------------------------------------------------------------------------*/
|
||||||
|
const std::string SHScriptEngine::DEFAULT_CSHARP_NAMESPACE = std::string("SHADE");
|
||||||
|
SHDotNetRuntime SHScriptEngine::dotNet { false };
|
||||||
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineInit = nullptr;
|
||||||
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineLoadScripts = nullptr;
|
||||||
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineUnloadScripts = nullptr;
|
||||||
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineReloadScripts = nullptr;
|
||||||
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineExit = nullptr;
|
||||||
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsFrameSetUp = nullptr;
|
||||||
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteFixedUpdate = nullptr;
|
||||||
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteUpdate = nullptr;
|
||||||
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteLateUpdate = nullptr;
|
||||||
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsFrameCleanUp = nullptr;
|
||||||
|
SHScriptEngine::CsScriptManipFuncPtr SHScriptEngine::csScriptsAdd = nullptr;
|
||||||
|
SHScriptEngine::CsScriptBasicFuncPtr SHScriptEngine::csScriptsRemoveAll = nullptr;
|
||||||
|
SHScriptEngine::CsScriptOptionalFuncPtr SHScriptEngine::csScriptsRemoveAllImmediately = nullptr;
|
||||||
|
SHScriptEngine::CsScriptSerialiseFuncPtr SHScriptEngine::csScriptsSerialise = nullptr;
|
||||||
|
SHScriptEngine::CsScriptDeserialiseFuncPtr SHScriptEngine::csScriptDeserialise = nullptr;
|
||||||
|
SHScriptEngine::CsScriptSerialiseYamlFuncPtr SHScriptEngine::csScriptsSerialiseYaml = nullptr;
|
||||||
|
SHScriptEngine::CsScriptSerialiseYamlFuncPtr SHScriptEngine::csScriptDeserialiseYaml = nullptr;
|
||||||
|
SHScriptEngine::CsScriptEditorFuncPtr SHScriptEngine::csEditorRenderScripts = nullptr;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Lifecycle Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void SHScriptEngine::Init()
|
||||||
|
{
|
||||||
|
// Do not allow initialization if already initialised
|
||||||
|
if (dotNet.IsLoaded())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("[ScriptEngine] Attempted to initialise an already loaded DotNetRuntime.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dotNet.Init();
|
||||||
|
|
||||||
|
// Load all the helpers
|
||||||
|
loadFunctions();
|
||||||
|
|
||||||
|
// Generate script assembly if it hasn't been before
|
||||||
|
if (!fileExists(std::string(MANAGED_SCRIPT_LIB_NAME) + ".dll"))
|
||||||
|
{
|
||||||
|
BuildScriptAssembly();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialise the CSharp Engine
|
||||||
|
csEngineInit();
|
||||||
|
|
||||||
|
// Link events
|
||||||
|
// - Entity Destruction
|
||||||
|
/*onEntityDestroy = [this](const SHEntity& e)
|
||||||
|
{
|
||||||
|
csScriptsRemoveAll(e.GetEID());
|
||||||
|
csGOLibNotifyDestroyEntity(e.GetEID());
|
||||||
|
};
|
||||||
|
ECS::OnEntityDestroy += onEntityDestroy;*/
|
||||||
|
}
|
||||||
|
void SHScriptEngine::UnloadScriptAssembly()
|
||||||
|
{
|
||||||
|
csEngineUnloadScripts();
|
||||||
|
}
|
||||||
|
void SHScriptEngine::LoadScriptAssembly()
|
||||||
|
{
|
||||||
|
csEngineLoadScripts();
|
||||||
|
}
|
||||||
|
void SHScriptEngine::ReloadScriptAssembly()
|
||||||
|
{
|
||||||
|
csEngineReloadScripts();
|
||||||
|
}
|
||||||
|
void SHScriptEngine::ExecuteFixedUpdates()
|
||||||
|
{
|
||||||
|
csScriptsExecuteFixedUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHScriptEngine::Exit()
|
||||||
|
{
|
||||||
|
// Do not allow deinitialization if not initialised
|
||||||
|
if (!dotNet.IsLoaded())
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("[ScriptEngine] Attempted to clean up an unloaded DotNetRuntime.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlink events
|
||||||
|
/*ECS::OnEntityCreated -= onEntityCreate;
|
||||||
|
ECS::OnEntityDestroy -= onEntityDestroy;*/
|
||||||
|
|
||||||
|
// Clean up the CSharp Engine
|
||||||
|
csEngineExit();
|
||||||
|
|
||||||
|
// Shut down the CLR
|
||||||
|
dotNet.Exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Script Manipulation Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
bool SHScriptEngine::AddScript(const SHEntity& entity, const std::string_view& scriptName)
|
||||||
|
{
|
||||||
|
return csScriptsAdd(entity.GetEID(), scriptName.data());
|
||||||
|
}
|
||||||
|
void SHScriptEngine::RemoveAllScripts(const SHEntity& entity)
|
||||||
|
{
|
||||||
|
csScriptsRemoveAll(entity.GetEID());
|
||||||
|
}
|
||||||
|
void SHScriptEngine::RemoveAllScriptsImmediately(const SHEntity& entity, bool callOnDestroy)
|
||||||
|
{
|
||||||
|
csScriptsRemoveAllImmediately(entity.GetEID(), callOnDestroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Script Serialisation Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
std::string SHScriptEngine::SerialiseScripts(const SHEntity& entity)
|
||||||
|
{
|
||||||
|
// Create buffer needed to store serialised script data
|
||||||
|
constexpr int BUFFER_SIZE = 10240;
|
||||||
|
std::unique_ptr<char> buffer { new char[BUFFER_SIZE] };
|
||||||
|
std::memset(buffer.get(), 0, BUFFER_SIZE);
|
||||||
|
|
||||||
|
// Attempt to serialise the script
|
||||||
|
std::string result;
|
||||||
|
if (csScriptsSerialise(entity.GetEID(), buffer.get(), BUFFER_SIZE))
|
||||||
|
{
|
||||||
|
result = std::string(buffer.get());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("[ScriptEngine] Failed to serialise scripts as string buffer is too small!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return an empty string since we failed to serialise
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Script Serialisation Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void SHScriptEngine::DeserialiseScript(const SHEntity& entity, const std::string& yaml)
|
||||||
|
{
|
||||||
|
csScriptDeserialise(entity.GetEID(), yaml.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Script Editor Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void SHScriptEngine::RenderScriptsInInspector(const SHEntity& entity)
|
||||||
|
{
|
||||||
|
csEditorRenderScripts(entity.GetEID());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Static Utility Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
bool SHScriptEngine::BuildScriptAssembly(bool debug)
|
||||||
|
{
|
||||||
|
constexpr std::string_view BUILD_LOG_PATH = "../Build.log";
|
||||||
|
|
||||||
|
// Generate csproj file if it doesn't exist
|
||||||
|
static const std::filesystem::path CSPROJ_PATH = "../SHADE_Scripting.csproj";
|
||||||
|
if (!std::filesystem::exists(CSPROJ_PATH))
|
||||||
|
{
|
||||||
|
GenerateScriptsCsProjFile(CSPROJ_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare directory (delete useless files)
|
||||||
|
deleteFolder("net5.0");
|
||||||
|
deleteFolder("ref");
|
||||||
|
deleteFolder("../SHADE_Scripting");
|
||||||
|
deleteFolder("../obj");
|
||||||
|
|
||||||
|
// Attempt to build the assembly
|
||||||
|
std::ostringstream oss;
|
||||||
|
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 \"dotnet build \"../SHADE_Scripting.csproj\" -c Debug -o \"./tmp/\" -fl -flp:LogFile=build.log;Verbosity=quiet & exit\""
|
||||||
|
) == 0;
|
||||||
|
if (BUILD_SUCCESS)
|
||||||
|
{
|
||||||
|
// Copy to built dll to the working directory and replace
|
||||||
|
std::filesystem::copy_file("./tmp/SHADE_Scripting.dll", "SHADE_Scripting.dll", std::filesystem::copy_options::overwrite_existing);
|
||||||
|
|
||||||
|
oss << "[ScriptEngine] Successfully built Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!";
|
||||||
|
SHLOG_INFO(oss.str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
oss << "[ScriptEngine] Failed to build Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!";
|
||||||
|
SHLOG_ERROR(oss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up built files
|
||||||
|
deleteFolder("./tmp");
|
||||||
|
|
||||||
|
// Read the build log and output to the console
|
||||||
|
dumpBuildLog(BUILD_LOG_PATH);
|
||||||
|
// Delete the build log file since we no longer need it
|
||||||
|
deleteFile(BUILD_LOG_PATH);
|
||||||
|
|
||||||
|
return BUILD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHScriptEngine::GenerateScriptsCsProjFile(const std::filesystem::path& path)
|
||||||
|
{
|
||||||
|
// Sample
|
||||||
|
static std::string_view FILE_CONTENTS =
|
||||||
|
"<Project Sdk=\"Microsoft.NET.Sdk\">\n\
|
||||||
|
<PropertyGroup>\n\
|
||||||
|
<TargetFramework>net5.0</TargetFramework>\n\
|
||||||
|
<Platforms>x64</Platforms>\n\
|
||||||
|
<Configurations>Release;Debug</Configurations>\n\
|
||||||
|
</PropertyGroup>\n\
|
||||||
|
<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n\
|
||||||
|
<OutputPath>.\\bin_Release-x64</OutputPath>\n\
|
||||||
|
<PlatformTarget>x64</PlatformTarget>\n\
|
||||||
|
</PropertyGroup>\n\
|
||||||
|
<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\"> \n\
|
||||||
|
<OutputPath>.\\bin_Debug-x64</OutputPath>\n\
|
||||||
|
<PlatformTarget>x64</PlatformTarget>\n\
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>\n\
|
||||||
|
<Optimize>false</Optimize>\n\
|
||||||
|
<DebugType>full</DebugType>\n\
|
||||||
|
<DebugSymbols>true</DebugSymbols>\n\
|
||||||
|
</PropertyGroup>\n\
|
||||||
|
<ItemGroup>\n\
|
||||||
|
<Compile Remove=\"bin\\**\" />\n\
|
||||||
|
<EmbeddedResource Remove=\"Assets\\**\" />\n\
|
||||||
|
<EmbeddedResource Remove=\"bin\\**\" />\n\
|
||||||
|
<None Remove=\"bin\\**\" />\n\
|
||||||
|
</ItemGroup>\n\
|
||||||
|
<ItemGroup>\n\
|
||||||
|
<None Remove=\".gitignore\" />\n\
|
||||||
|
<None Remove=\".gitmodules\" />\n\
|
||||||
|
</ItemGroup>\n\
|
||||||
|
<ItemGroup>\n\
|
||||||
|
<Reference Include=\"SHADE_Managed\">\n\
|
||||||
|
<HintPath>.\\bin\\SHADE_Managed.dll</HintPath>\n\
|
||||||
|
</Reference>\n\
|
||||||
|
</ItemGroup>\n\
|
||||||
|
</Project>";
|
||||||
|
|
||||||
|
// Attempt to create the file
|
||||||
|
std::ofstream file(path);
|
||||||
|
if (!file.is_open())
|
||||||
|
throw std::runtime_error("Unable to create CsProj file!");
|
||||||
|
|
||||||
|
// Fill the file
|
||||||
|
file << FILE_CONTENTS;
|
||||||
|
|
||||||
|
// Close
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
void SHScriptEngine::loadFunctions()
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "[ScriptEngine] Loading \"" << DEFAULT_CSHARP_LIB_NAME << "\" CLR library.";
|
||||||
|
SHLOG_INFO(oss.str());
|
||||||
|
|
||||||
|
// Load functions
|
||||||
|
csEngineInit = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
|
||||||
|
"Init"
|
||||||
|
);
|
||||||
|
csEngineLoadScripts = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
|
||||||
|
"LoadScriptAssembly"
|
||||||
|
);
|
||||||
|
csEngineUnloadScripts = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
|
||||||
|
"UnloadScriptAssembly"
|
||||||
|
);
|
||||||
|
csEngineReloadScripts = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
|
||||||
|
"ReloadScriptAssembly"
|
||||||
|
);
|
||||||
|
csEngineExit = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
|
||||||
|
"Exit"
|
||||||
|
);
|
||||||
|
csScriptsFrameSetUp = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"FrameSetUp"
|
||||||
|
);
|
||||||
|
csScriptsExecuteFixedUpdate = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"ExecuteFixedUpdate"
|
||||||
|
);
|
||||||
|
csScriptsExecuteUpdate = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"ExecuteUpdate"
|
||||||
|
);
|
||||||
|
csScriptsExecuteLateUpdate = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"ExecuteLateUpdate"
|
||||||
|
);
|
||||||
|
csScriptsFrameCleanUp = dotNet.GetFunctionPtr<CsFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"FrameCleanUp"
|
||||||
|
);
|
||||||
|
csScriptsAdd = dotNet.GetFunctionPtr<CsScriptManipFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"AddScriptViaName"
|
||||||
|
);
|
||||||
|
csScriptsRemoveAll = dotNet.GetFunctionPtr<CsScriptBasicFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"RemoveAllScripts"
|
||||||
|
);
|
||||||
|
csScriptsRemoveAllImmediately = dotNet.GetFunctionPtr<CsScriptOptionalFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"RemoveAllScriptsImmediately"
|
||||||
|
);
|
||||||
|
/*csScriptsSerialise = dotNet.GetFunctionPtr<CsScriptSerialiseFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"SerialiseScripts"
|
||||||
|
);
|
||||||
|
csScriptsSerialiseYaml = dotNet.GetFunctionPtr<CsScriptSerialiseYamlFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"SerialiseScriptsYaml"
|
||||||
|
);
|
||||||
|
csScriptDeserialise = dotNet.GetFunctionPtr<CsScriptDeserialiseFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"DeserialiseScript"
|
||||||
|
);
|
||||||
|
csScriptDeserialiseYaml = dotNet.GetFunctionPtr<CsScriptSerialiseYamlFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
||||||
|
"SerialiseScriptsYaml"
|
||||||
|
);
|
||||||
|
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
|
||||||
|
(
|
||||||
|
DEFAULT_CSHARP_LIB_NAME,
|
||||||
|
DEFAULT_CSHARP_NAMESPACE + ".Editor",
|
||||||
|
"RenderScriptsInInspector"
|
||||||
|
);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHScriptEngine::dumpBuildLog(const std::string_view& buildLogPath)
|
||||||
|
{
|
||||||
|
std::ifstream buildLog(buildLogPath);
|
||||||
|
|
||||||
|
// Fail to open
|
||||||
|
if (!buildLog.is_open())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Process line by line
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(buildLog, line))
|
||||||
|
{
|
||||||
|
if (line.find("error") != line.npos)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR(line);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_WARNING(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SHScriptEngine::deleteFile(const std::string_view& filePath)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::filesystem::remove(std::filesystem::canonical(filePath));
|
||||||
|
}
|
||||||
|
catch (...) {} // Ignore deletion failures
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHScriptEngine::deleteFolder(const std::string_view& filePath)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::filesystem::remove_all(std::filesystem::canonical(filePath));
|
||||||
|
}
|
||||||
|
catch (...) {} // Ignore deletion failures
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHScriptEngine::fileExists(const std::string_view& filePath)
|
||||||
|
{
|
||||||
|
std::error_code error;
|
||||||
|
if (std::filesystem::exists(filePath, error))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
<< " (" << SHStringUtils::GetWin32ErrorMessage(err) << ")";
|
||||||
|
throw std::runtime_error(oss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for execution to end
|
||||||
|
DWORD status;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const auto SUCCESS = GetExitCodeProcess(procInfo.hProcess, &status);
|
||||||
|
if (!SUCCESS)
|
||||||
|
{
|
||||||
|
auto err = GetLastError();
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "[ScriptEngine] Failed to query process. Error code: " << std::hex << err
|
||||||
|
<< " (" << SHStringUtils::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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue