├── .gitattributes ├── .gitignore ├── .gitmodules ├── Assets ├── Fonts │ ├── Inter-Medium.ttf │ ├── Roboto-Regular.ttf │ ├── fa-regular-400.ttf │ └── fa-solid-900.ttf ├── Sequences │ ├── pica_flycam.json │ └── sponza_flycam.json ├── Shaders │ └── Backend │ │ ├── BloomCS.hlsl │ │ ├── ClearBuffer.hlsl │ │ ├── ClearTexture2D.hlsl │ │ ├── ClearTexture3D.hlsl │ │ ├── ClearTextureCube.hlsl │ │ ├── ConvolveCubeCS.hlsl │ │ ├── DebugLinesPS.hlsl │ │ ├── DebugLinesVS.hlsl │ │ ├── DepthOfFieldCS.hlsl │ │ ├── DownsampleCS.hlsl │ │ ├── FinalComposePS.hlsl │ │ ├── FullscreenTriangleVS.hlsl │ │ ├── GBufferDebugPS.hlsl │ │ ├── GBufferVS.hlsl │ │ ├── GrassRenderPS.hlsl │ │ ├── GrassRenderVS.hlsl │ │ ├── ImGuiPS.hlsl │ │ ├── ImGuiVS.hlsl │ │ ├── Include │ │ ├── Bindless.hlsli │ │ ├── Common.hlsli │ │ ├── DDGI.hlsli │ │ ├── Ffx_A.hlsli │ │ ├── Ffx_SPD.hlsli │ │ ├── Material.hlsli │ │ ├── Packing.hlsli │ │ ├── Random.hlsli │ │ ├── RayTracing.hlsli │ │ └── Sky.hlsli │ │ ├── LightCullTiledCS.hlsl │ │ ├── LightingPS.hlsl │ │ ├── Materials │ │ ├── DeferredPS.hlsl │ │ └── DeferredVS.hlsl │ │ ├── PathTraceCS.hlsl │ │ ├── ProbeDebugPS.hlsl │ │ ├── ProbeDebugVS.hlsl │ │ ├── ProbeSampleCS.hlsl │ │ ├── ProbeTraceCS.hlsl │ │ ├── ProbeUpdateCS.hlsl │ │ ├── ProbeUpdateDepthCS.hlsl │ │ ├── ProbeUpdateIrradianceCS.hlsl │ │ ├── RTAmbientOcclusionCS.hlsl │ │ ├── RTReflectionsCS.hlsl │ │ ├── RTShadowsClassifyCS.hlsl │ │ ├── RTShadowsClearTilesCS.hlsl │ │ ├── RTShadowsDenoiseCS.hlsl │ │ ├── RTShadowsTraceCS.hlsl │ │ ├── SDFUI.hlsl │ │ ├── SSAOTraceCS.hlsl │ │ ├── SSRTraceCS.hlsl │ │ ├── Shaders.json │ │ ├── ShadowMapPS.hlsl │ │ ├── ShadowMapVS.hlsl │ │ ├── SkinningCS.hlsl │ │ ├── SkyCubeCS.hlsl │ │ ├── TAAResolvePS.hlsl │ │ └── gbufferPS.hlsl ├── black4x4.dds ├── camera.png ├── light.png ├── normal4x4.dds └── white4x4.dds ├── CMakeLists.txt ├── Code ├── Core.natvis ├── Editor │ ├── App.cpp │ ├── App.h │ ├── Assets │ │ └── Icon │ │ │ ├── Icon.aps │ │ │ ├── Icon.ico │ │ │ ├── Icon.rc │ │ │ └── resource.h │ ├── CMakeLists.txt │ ├── Compiler.cpp │ ├── Compiler.h │ ├── Editor.cpp │ ├── Editor.h │ ├── GUI.cpp │ ├── GUI.h │ ├── Launcher.cpp │ ├── Launcher.h │ ├── ShaderGraph.cpp │ ├── ShaderGraph.h │ ├── ShaderGraphNodes.cpp │ ├── ShaderGraphNodes.h │ ├── Widget.cpp │ ├── Widget.h │ ├── Widgets │ │ ├── AssetsWidget.cpp │ │ ├── AssetsWidget.h │ │ ├── ConsoleWidget.cpp │ │ ├── ConsoleWidget.h │ │ ├── HierarchyWidget.cpp │ │ ├── HierarchyWidget.h │ │ ├── InspectorWidget.cpp │ │ ├── InspectorWidget.h │ │ ├── MenubarWidget.cpp │ │ ├── MenubarWidget.h │ │ ├── NodeGraphWidget.cpp │ │ ├── NodeGraphWidget.h │ │ ├── ProfileWidget.cpp │ │ ├── ProfileWidget.h │ │ ├── SequenceWidget.cpp │ │ ├── SequenceWidget.h │ │ ├── ViewportWidget.cpp │ │ └── ViewportWidget.h │ ├── main.cpp │ ├── pch.cpp │ └── pch.h ├── Engine │ ├── Animation.cpp │ ├── Animation.h │ ├── Application.cpp │ ├── Application.h │ ├── Archive.cpp │ ├── Archive.h │ ├── Assets.cpp │ ├── Assets.h │ ├── Assimp.cpp │ ├── Assimp.h │ ├── CMakeLists.txt │ ├── CVars.cpp │ ├── CVars.h │ ├── Camera.cpp │ ├── Camera.h │ ├── Components.cpp │ ├── Components.h │ ├── DDS.cpp │ ├── DDS.h │ ├── DebugRenderer.cpp │ ├── DebugRenderer.h │ ├── Defines.h │ ├── DiscordRPC.cpp │ ├── DiscordRPC.h │ ├── ECS.cpp │ ├── ECS.h │ ├── FBX.cpp │ ├── FBX.h │ ├── GLTF.cpp │ ├── GLTF.h │ ├── Hash.h │ ├── Input.cpp │ ├── Input.h │ ├── Iter.h │ ├── JSON.cpp │ ├── JSON.h │ ├── Maths.cpp │ ├── Maths.h │ ├── Member.h │ ├── OBJ.cpp │ ├── OBJ.h │ ├── OS.cpp │ ├── OS.h │ ├── PCH.cpp │ ├── PCH.h │ ├── Physics.cpp │ ├── Physics.h │ ├── Primitives.cpp │ ├── Primitives.h │ ├── Profiler.cpp │ ├── Profiler.h │ ├── RTTI.cpp │ ├── RTTI.h │ ├── Raekor.h │ ├── Renderer │ │ ├── CommandList.cpp │ │ ├── CommandList.h │ │ ├── Device.cpp │ │ ├── Device.h │ │ ├── GPUProfiler.cpp │ │ ├── GPUProfiler.h │ │ ├── RayTracedScene.cpp │ │ ├── RayTracedScene.h │ │ ├── RayTracing.cpp │ │ ├── RayTracing.h │ │ ├── RenderGraph.cpp │ │ ├── RenderGraph.h │ │ ├── RenderPasses.cpp │ │ ├── RenderPasses.h │ │ ├── RenderUtil.h │ │ ├── Renderer.cpp │ │ ├── Renderer.h │ │ ├── Resource.cpp │ │ ├── Resource.h │ │ ├── Samplers.h │ │ ├── Shader.cpp │ │ ├── Shader.h │ │ ├── Shared.h │ │ ├── Upscalers.cpp │ │ └── Upscalers.h │ ├── Scene.cpp │ ├── Scene.h │ ├── Script.cpp │ ├── Script.h │ ├── Serialization.h │ ├── Threading.cpp │ ├── Threading.h │ ├── Timer.cpp │ ├── Timer.h │ ├── UIRenderer.cpp │ ├── UIRenderer.h │ ├── Undo.cpp │ └── Undo.h └── Game │ ├── CMakeLists.txt │ ├── Game.cpp │ ├── Game.h │ ├── Scripts │ ├── AnimateSunScript.cpp │ ├── CharacterControllerScript.cpp │ ├── GunScript.cpp │ ├── LightsScript.cpp │ ├── Scripts.cpp │ ├── Scripts.h │ ├── TestScript.cpp │ └── VehicleControllerScript.cpp │ └── main.cpp ├── Images ├── Editor.png └── Thumbnail.png ├── LICENSE ├── README.md ├── ThirdParty ├── Agility-SDK │ ├── D3D12Core.dll │ ├── agility.def │ ├── d3d12.h │ ├── d3d12SDKLayers.dll │ ├── d3d12sdklayers.h │ ├── d3d12video.h │ ├── d3dcommon.h │ └── dxgiformat.h ├── DirectStorage │ ├── dstorage.dll │ ├── dstorage.h │ ├── dstorage.lib │ ├── dstoragecore.dll │ └── dstorageerr.h ├── FSR2 │ ├── lib │ │ ├── ffx_fsr2_api_dx12_x64.lib │ │ ├── ffx_fsr2_api_dx12_x64d.lib │ │ ├── ffx_fsr2_api_x64.lib │ │ └── ffx_fsr2_api_x64d.lib │ └── src │ │ ├── dx12 │ │ ├── ffx_fsr2_dx12.h │ │ └── shaders │ │ │ └── ffx_fsr2_shaders_dx12.h │ │ ├── ffx_assert.cpp │ │ ├── ffx_assert.h │ │ ├── ffx_error.h │ │ ├── ffx_fsr2.cpp │ │ ├── ffx_fsr2.h │ │ ├── ffx_fsr2_interface.h │ │ ├── ffx_fsr2_maximum_bias.h │ │ ├── ffx_fsr2_private.h │ │ ├── ffx_types.h │ │ ├── ffx_util.h │ │ └── shaders │ │ ├── ffx_fsr2_common.h │ │ └── ffx_fsr2_resources.h ├── PIX │ ├── Include │ │ └── WinPixEventRuntime │ │ │ ├── PIXEvents.h │ │ │ ├── PIXEventsCommon.h │ │ │ ├── PIXEventsLegacy.h │ │ │ ├── pix3.h │ │ │ └── pix3_win.h │ ├── ThirdPartyNotices.txt │ ├── bin │ │ └── x64 │ │ │ ├── WinPixEventRuntime.dll │ │ │ └── WinPixEventRuntime.lib │ └── license.txt ├── cgltf │ ├── LICENSE │ ├── cgltf.h │ └── cgltf_write.h ├── discord_game_sdk │ ├── README.md │ ├── cpp │ │ ├── achievement_manager.cpp │ │ ├── achievement_manager.h │ │ ├── activity_manager.cpp │ │ ├── activity_manager.h │ │ ├── application_manager.cpp │ │ ├── application_manager.h │ │ ├── core.cpp │ │ ├── core.h │ │ ├── discord.h │ │ ├── event.h │ │ ├── ffi.h │ │ ├── image_manager.cpp │ │ ├── image_manager.h │ │ ├── lobby_manager.cpp │ │ ├── lobby_manager.h │ │ ├── network_manager.cpp │ │ ├── network_manager.h │ │ ├── overlay_manager.cpp │ │ ├── overlay_manager.h │ │ ├── relationship_manager.cpp │ │ ├── relationship_manager.h │ │ ├── storage_manager.cpp │ │ ├── storage_manager.h │ │ ├── store_manager.cpp │ │ ├── store_manager.h │ │ ├── types.cpp │ │ ├── types.h │ │ ├── user_manager.cpp │ │ ├── user_manager.h │ │ ├── voice_manager.cpp │ │ └── voice_manager.h │ ├── examples │ │ └── cpp │ │ │ └── main.cpp │ └── lib │ │ └── x86_64 │ │ ├── discord_game_sdk.dll │ │ └── discord_game_sdk.lib ├── dxc │ ├── d3d12shader.h │ ├── dxcapi.h │ ├── dxcompiler.dll │ ├── dxcompiler.lib │ └── dxil.dll └── samplerCPP │ ├── README.txt │ ├── samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_128spp.cpp │ ├── samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_16spp.cpp │ ├── samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_1spp.cpp │ ├── samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_256spp.cpp │ ├── samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_2spp.cpp │ ├── samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_32spp.cpp │ ├── samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_4spp.cpp │ ├── samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_64spp.cpp │ └── samplerBlueNoiseErrorDistribution_128x128_OptimizedFor_2d2d2d2d_8spp.cpp └── vcpkg.json /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/Tine/v15/.suo 2 | *.ark 3 | *.ark_server 4 | *.ark_ignore 5 | *.db 6 | *.o 7 | *.exe 8 | *.spv 9 | *.sln 10 | *.pdb 11 | *.wpix 12 | *.log 13 | *.user 14 | *.cmake 15 | *.vcxproj 16 | *.vcxproj.filters 17 | test.* 18 | CmakeCache.txt 19 | Raekor.dir/ 20 | Build/ 21 | CMakeFiles/ 22 | /vcpkg_installed 23 | Debug/ 24 | Release/ 25 | RelWithDebInfo/ 26 | .vs/ 27 | .vscode/ 28 | .clang-format 29 | Cached/ 30 | Images 31 | !Images/Editor.png 32 | !Images/Thumbnail.png 33 | Assets/Models 34 | Assets/EnvMaps 35 | !Assets/Models/DancingStormtrooper 36 | !Assets/Models/Homer 37 | !Assets/Models/MinecraftBlock 38 | !Assets/Models/Pica 39 | !Assets/Models/Sponza 40 | !Assets/Models/TestCube 41 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "dependencies/stb"] 2 | path = ThirdParty/stb 3 | url = https://github.com/nothings/stb 4 | [submodule "dependencies/glm"] 5 | path = ThirdParty/glm 6 | url = https://github.com/g-truc/glm 7 | [submodule "dependencies/imgui"] 8 | path = dependencies/imgui 9 | url = https://github.com/ocornut/imgui 10 | [submodule "dependencies/ImGuizmo"] 11 | path = ThirdParty/ImGuizmo 12 | url = https://github.com/nicovanbentum/ImGuizmo/ 13 | [submodule "dependencies/VulkanMemoryAllocator"] 14 | path = ThirdParty/VulkanMemoryAllocator 15 | url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator 16 | [submodule "dependencies/IconFontCppHeaders"] 17 | path = ThirdParty/IconFontCppHeaders 18 | url = https://github.com/juliettef/IconFontCppHeaders 19 | [submodule "dependencies/vcpkg"] 20 | path = ThirdParty/vcpkg 21 | url = https://github.com/microsoft/vcpkg 22 | [submodule "dependencies/imnodes"] 23 | path = ThirdParty/imnodes 24 | url = https://github.com/nicovanbentum/imnodes 25 | [submodule "dependencies/JoltPhysics"] 26 | path = ThirdParty/JoltPhysics 27 | url = https://github.com/jrouwe/JoltPhysics 28 | [submodule "dependencies/D3D12MemoryAllocator"] 29 | path = ThirdParty/D3D12MemoryAllocator 30 | url = https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator 31 | [submodule "dependencies/ufbx"] 32 | path = ThirdParty/ufbx 33 | url = https://github.com/ufbx/ufbx 34 | [submodule "dependencies/DLSS"] 35 | path = ThirdParty/DLSS 36 | url = https://github.com/NVIDIA/DLSS 37 | [submodule "dependencies/xess"] 38 | path = ThirdParty/xess 39 | url = https://github.com/intel/xess 40 | [submodule "dependencies/BinaryRelations"] 41 | path = ThirdParty/BinaryRelations 42 | url = https://github.com/RonPieket/BinaryRelations/ 43 | [submodule "dependencies/meshoptimizer"] 44 | path = ThirdParty/meshoptimizer 45 | url = https://github.com/zeux/meshoptimizer/ 46 | [submodule "ThirdParty/imgui"] 47 | path = ThirdParty/imgui 48 | url = https://github.com/ocornut/imgui 49 | -------------------------------------------------------------------------------- /Assets/Fonts/Inter-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Assets/Fonts/Inter-Medium.ttf -------------------------------------------------------------------------------- /Assets/Fonts/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Assets/Fonts/Roboto-Regular.ttf -------------------------------------------------------------------------------- /Assets/Fonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Assets/Fonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /Assets/Fonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Assets/Fonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /Assets/Sequences/pica_flycam.json: -------------------------------------------------------------------------------- 1 | { 2 | "CameraSequence": 3 | { 4 | "Duration": 30.000000, 5 | "Key Frames": 6 | [ 7 | 8 | { 9 | "Time": 0.000000, 10 | "Angle": "(2.84032 -0.150517)", 11 | "Position": "(-18.5852 13.1572 33.9111)" 12 | }, 13 | 14 | { 15 | "Time": 7.560000, 16 | "Angle": "(3.4132 -0.201202)", 17 | "Position": "(-13.9289 6.06995 2.38884)" 18 | }, 19 | 20 | { 21 | "Time": 11.820000, 22 | "Angle": "(2.52699 -0.211953)", 23 | "Position": "(-3.89701 7.38689 17.926)" 24 | }, 25 | 26 | { 27 | "Time": 14.590000, 28 | "Angle": "(3.47771 -0.238063)", 29 | "Position": "(7.49556 8.43879 24.6612)" 30 | }, 31 | 32 | { 33 | "Time": 19.270000, 34 | "Angle": "(3.84479 -0.204274)", 35 | "Position": "(31.7878 13.8061 37.4139)" 36 | }, 37 | 38 | { 39 | "Time": 24.459999, 40 | "Angle": "(2.72973 -0.152053)", 41 | "Position": "(-5.2471 6.25184 21.1145)" 42 | }, 43 | 44 | { 45 | "Time": 30.000000, 46 | "Angle": "(2.84032 -0.150517)", 47 | "Position": "(-18.5852 13.1572 33.9111)" 48 | } 49 | ] 50 | } 51 | } -------------------------------------------------------------------------------- /Assets/Sequences/sponza_flycam.json: -------------------------------------------------------------------------------- 1 | { 2 | "CameraSequence": 3 | { 4 | "Duration": 55.000000, 5 | "Key Frames": 6 | [ 7 | 8 | { 9 | "Time": 0.000000, 10 | "Angle": "(2.2874 -0.0890816)", 11 | "Position": "(-60.3333 10.2723 19.1659)" 12 | }, 13 | 14 | { 15 | "Time": 5.000000, 16 | "Angle": "(4.00452 -0.118264)", 17 | "Position": "(58.7118 11.5473 22.556)" 18 | }, 19 | 20 | { 21 | "Time": 7.090000, 22 | "Angle": "(4.71871 0.104441)", 23 | "Position": "(58.1184 9.52923 -3.53211)" 24 | }, 25 | 26 | { 27 | "Time": 12.120000, 28 | "Angle": "(4.81547 -0.0107512)", 29 | "Position": "(-28.6405 31.4135 -0.57073)" 30 | }, 31 | 32 | { 33 | "Time": 13.770000, 34 | "Angle": "(2.82649 -0.0629715)", 35 | "Position": "(-37.7471 30.4777 -12.0832)" 36 | }, 37 | 38 | { 39 | "Time": 14.970000, 40 | "Angle": "(1.55938 0.0230383)", 41 | "Position": "(-30.0079 30.04 -25.71)" 42 | }, 43 | 44 | { 45 | "Time": 20.379999, 46 | "Angle": "(-0.968696 -0.0906175)", 47 | "Position": "(59.6694 31.6751 -25.0198)" 48 | }, 49 | 50 | { 51 | "Time": 25.219999, 52 | "Angle": "(-2.22352 -0.14591)", 53 | "Position": "(58.2264 32.7864 23.975)" 54 | }, 55 | 56 | { 57 | "Time": 31.959999, 58 | "Angle": "(-4.06659 -0.105976)", 59 | "Position": "(-64.7418 32.5241 21.9034)" 60 | }, 61 | 62 | { 63 | "Time": 38.799999, 64 | "Angle": "(-5.38285 -0.0829381)", 65 | "Position": "(-65.8171 32.6919 -27.0746)" 66 | }, 67 | 68 | { 69 | "Time": 44.400002, 70 | "Angle": "(-7.18752 -0.147446)", 71 | "Position": "(60.2981 33.9615 -26.8109)" 72 | }, 73 | 74 | { 75 | "Time": 54.529999, 76 | "Angle": "(1.65 0)", 77 | "Position": "(-42 10 0)" 78 | } 79 | ] 80 | } 81 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/ClearBuffer.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Common.hlsli" 3 | 4 | ROOT_CONSTANTS(ClearBufferRootConstants, rc) 5 | 6 | [numthreads(64, 1, 1)] 7 | void main(uint3 threadID : SV_DispatchThreadID) { 8 | RWBuffer buffer = ResourceDescriptorHeap[rc.mBuffer]; 9 | buffer[threadID.x] = rc.mClearValue; 10 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/ClearTexture2D.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Packing.hlsli" 3 | #include "Include/Common.hlsli" 4 | #include "Include/Random.hlsli" 5 | #include "Include/DDGI.hlsli" 6 | 7 | ROOT_CONSTANTS(ClearTextureRootConstants, rc) 8 | 9 | [numthreads(8, 8, 1)] 10 | void main(uint3 threadID : SV_DispatchThreadID) { 11 | RWTexture2D texture = ResourceDescriptorHeap[rc.mTexture]; 12 | texture[threadID.xy] = rc.mClearValue; 13 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/ClearTexture3D.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Packing.hlsli" 3 | #include "Include/Common.hlsli" 4 | #include "Include/Random.hlsli" 5 | #include "Include/DDGI.hlsli" 6 | 7 | ROOT_CONSTANTS(ClearTextureRootConstants, rc) 8 | 9 | [numthreads(4, 4, 4)] 10 | void main(uint3 threadID : SV_DispatchThreadID) { 11 | RWTexture3D texture = ResourceDescriptorHeap[rc.mTexture]; 12 | texture[threadID.xyz] = rc.mClearValue; 13 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/ClearTextureCube.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Packing.hlsli" 3 | #include "Include/Common.hlsli" 4 | #include "Include/Random.hlsli" 5 | #include "Include/DDGI.hlsli" 6 | 7 | ROOT_CONSTANTS(ClearTextureRootConstants, rc) 8 | 9 | [numthreads(8, 8, 1)] 10 | void main(uint3 threadID : SV_DispatchThreadID) { 11 | RWTexture2DArray texture = ResourceDescriptorHeap[rc.mTexture]; 12 | texture[threadID.xyz] = rc.mClearValue; 13 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/ConvolveCubeCS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Sky.hlsli" 2 | #include "Include/Common.hlsli" 3 | #include "Include/Random.hlsli" 4 | #include "Include/Bindless.hlsli" 5 | 6 | ROOT_CONSTANTS(ConvolveCubeRootConstants, rc) 7 | 8 | #define PI 3.14159265359 9 | #define NR_OF_SAMPLES 16 10 | 11 | float3 GetCubemapDirection(float2 inUV, uint inFace) 12 | { 13 | float2 clip = inUV * 2.0 - 1.0; 14 | 15 | switch (inFace) 16 | { 17 | case 0: return float3(1.0, -clip.yx); 18 | case 1: return float3(-1.0, -clip.y, clip.x); 19 | case 2: return float3(clip.x, 1.0, clip.y); 20 | case 3: return float3(clip.x, -1.0, -clip.y); 21 | case 4: return float3(clip.x, -clip.y, 1.0); 22 | case 5: return float3(-clip, -1.0); 23 | } 24 | 25 | return 0.xxx; 26 | } 27 | 28 | [numthreads(8, 8, 1)] 29 | void main(uint3 gid : SV_DispatchThreadID) 30 | { 31 | TextureCube cube_texture = ResourceDescriptorHeap[rc.mCubeTexture]; 32 | RWTexture2DArray convolved_texture = ResourceDescriptorHeap[rc.mConvolvedCubeTexture]; 33 | 34 | uint width, height, layers; 35 | convolved_texture.GetDimensions(width, height, layers); 36 | 37 | float2 uv = (float2(gid.xy) + 0.5) / float2(width, height); 38 | float3 dir = normalize(GetCubemapDirection(uv, gid.z)); 39 | 40 | float3 irradiance = 0.xxx; 41 | 42 | for (int i = 0; i < NR_OF_SAMPLES; i++) 43 | { 44 | float2 rand = Hammersley2D(i, NR_OF_SAMPLES); 45 | float3 sample_dir = normalize(dir + SampleCosineWeightedHemisphere(float2(rand.x, rand.y))); 46 | irradiance += cube_texture.Sample(SamplerLinearClamp, sample_dir).rgb; 47 | } 48 | 49 | irradiance /= NR_OF_SAMPLES; 50 | 51 | convolved_texture[gid] = irradiance; 52 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/DebugLinesPS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Packing.hlsli" 3 | 4 | struct VS_OUTPUT 5 | { 6 | float4 mWorldPos : SV_Position; 7 | float4 mColor : COLOR0; 8 | }; 9 | 10 | float4 main(in VS_OUTPUT inParams) : SV_Target0 11 | { 12 | return inParams.mColor; 13 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/DebugLinesVS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Packing.hlsli" 3 | 4 | struct VS_OUTPUT 5 | { 6 | float4 mWorldPos : SV_Position; 7 | float4 mColor : COLOR0; 8 | }; 9 | 10 | PASS_CONSTANTS(pc) 11 | FRAME_CONSTANTS(fc) 12 | ROOT_CONSTANTS(DebugPrimitivesRootConstants, rc) 13 | 14 | VS_OUTPUT main( 15 | #ifdef DEBUG_PROBE_RAYS 16 | in float4 inVertex : POSITION, 17 | #endif 18 | in uint inVertexID : SV_VertexID 19 | ) 20 | { 21 | VS_OUTPUT output; 22 | 23 | #ifndef DEBUG_PROBE_RAYS 24 | float4 inVertex = pc.Load(rc.mBufferOffset + sizeof(float4) * inVertexID); 25 | #endif 26 | 27 | output.mWorldPos = mul(fc.mViewProjectionMatrix, float4(inVertex.xyz, 1.0)); 28 | output.mColor = RGBA8ToFloat4(asuint(inVertex.w)); 29 | 30 | return output; 31 | } 32 | -------------------------------------------------------------------------------- /Assets/Shaders/Backend/DepthOfFieldCS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | 3 | #define GOLDEN_ANGLE 2.39996323 4 | #define MAX_BLUR_SIZE 20.0 5 | #define RAD_SCALE 0.4 // Smaller = nicer blur, larger = faster 6 | 7 | ROOT_CONSTANTS(DepthOfFieldRootConstants, rc) 8 | 9 | 10 | float GetBlurSize(float depth, float focusPoint, float focusScale) 11 | { 12 | float coc = clamp((1.0 / focusPoint - 1.0 / depth) * focusScale, -1.0, 1.0); 13 | return abs(coc) * MAX_BLUR_SIZE; 14 | } 15 | 16 | float LinearizeDepth(float inDepth, float inNearPlane, float inFarPlane) 17 | { 18 | return inNearPlane * inFarPlane / (inFarPlane + inDepth * (inNearPlane - inFarPlane)); 19 | } 20 | 21 | 22 | [numthreads(8, 8, 1)] 23 | void main(uint2 threadID : SV_DispatchThreadID) 24 | { 25 | if (any(threadID.xy >= rc.mDispatchSize.xy)) 26 | return; 27 | 28 | Texture2D input_texture = ResourceDescriptorHeap[rc.mInputTexture]; 29 | Texture2D depth_texture = ResourceDescriptorHeap[rc.mDepthTexture]; 30 | RWTexture2D output_texture = ResourceDescriptorHeap[rc.mOutputTexture]; 31 | 32 | uint width, height; 33 | output_texture.GetDimensions(width, height); 34 | float2 pixel_size = float2(1.0, 1.0) / uint2(width, height); 35 | 36 | const float2 pixel_center = float2(threadID) + float2(0.5, 0.5); 37 | float2 screen_uv = pixel_center / uint2(width, height); 38 | 39 | float center_depth = LinearizeDepth(depth_texture[threadID.xy], rc.mNearPlane, rc.mFarPlane); 40 | float focus_point = LinearizeDepth(depth_texture.SampleLevel(SamplerPointClamp, float2(0.5, 0.5), 0), rc.mNearPlane, rc.mFarPlane); 41 | 42 | float center_size = GetBlurSize(center_depth, focus_point, rc.mFocusScale); 43 | float3 color = input_texture.Sample(SamplerPointClamp, screen_uv).rgb; 44 | 45 | float tot = 1.0; 46 | float radius = RAD_SCALE; 47 | 48 | for (float angle = 0.0; radius < MAX_BLUR_SIZE; angle += GOLDEN_ANGLE) 49 | { 50 | float2 tc = screen_uv + float2(cos(angle), sin(angle)) * pixel_size * radius; 51 | float3 sample_color = input_texture.SampleLevel(SamplerPointClamp, tc, 0).rgb; 52 | 53 | float sample_depth = LinearizeDepth(depth_texture.SampleLevel(SamplerPointClamp, tc, 0), rc.mNearPlane, rc.mFarPlane); 54 | float sample_size = GetBlurSize(sample_depth, focus_point, rc.mFocusScale); 55 | 56 | if (sample_depth > center_depth) 57 | sample_size = clamp(sample_size, 0.0, center_size * 2.0); 58 | 59 | float m = smoothstep(radius - 0.5, radius + 0.5, sample_size); 60 | 61 | color += lerp(color / tot, sample_color, m); 62 | 63 | tot += 1.0; 64 | radius += RAD_SCALE / radius; 65 | } 66 | 67 | output_texture[threadID.xy] = float4(color / tot, 1.0); 68 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/DownsampleCS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Common.hlsli" 3 | 4 | ROOT_CONSTANTS(SpdRootConstants, rc) 5 | 6 | #define A_GPU 7 | #define A_HLSL 8 | #include "Include/Ffx_A.hlsli" 9 | 10 | groupshared AU1 spdCounter; 11 | 12 | groupshared AF1 spdIntermediateR[16][16]; 13 | groupshared AF1 spdIntermediateG[16][16]; 14 | groupshared AF1 spdIntermediateB[16][16]; 15 | groupshared AF1 spdIntermediateA[16][16]; 16 | 17 | 18 | AF4 SpdLoadSourceImage(ASU2 tex, AU1 slice) { 19 | RWTexture2D texture_mip0 = ResourceDescriptorHeap[rc.mTextureMip0]; 20 | return texture_mip0[tex]; 21 | } 22 | 23 | AF4 SpdLoad(ASU2 tex, AU1 slice) { 24 | globallycoherent RWTexture2D texture_mip = ResourceDescriptorHeap[rc.mTextureMip6]; 25 | return texture_mip[tex]; 26 | } 27 | 28 | void SpdStore(ASU2 pix, AF4 outValue, AU1 mip, AU1 slice) { 29 | if (mip == 5) { 30 | globallycoherent RWTexture2D texture = ResourceDescriptorHeap[rc.mTextureMip6]; 31 | texture[pix] = outValue; 32 | return; 33 | } 34 | 35 | uint bindless_index = -1; 36 | 37 | switch (mip) { 38 | case 0: bindless_index = rc.mTextureMip1; break; 39 | case 1: bindless_index = rc.mTextureMip2; break; 40 | case 2: bindless_index = rc.mTextureMip3; break; 41 | case 3: bindless_index = rc.mTextureMip4; break; 42 | case 4: bindless_index = rc.mTextureMip5; break; 43 | case 5: bindless_index = rc.mTextureMip6; break; 44 | case 6: bindless_index = rc.mTextureMip7; break; 45 | case 7: bindless_index = rc.mTextureMip8; break; 46 | case 8: bindless_index = rc.mTextureMip9; break; 47 | case 9: bindless_index = rc.mTextureMip10; break; 48 | case 10: bindless_index = rc.mTextureMip11; break; 49 | case 11: bindless_index = rc.mTextureMip12; break; 50 | case 12: bindless_index = rc.mTextureMip13; break; 51 | } 52 | 53 | RWTexture2D texture = ResourceDescriptorHeap[NonUniformResourceIndex(bindless_index)]; 54 | texture[pix] = outValue; 55 | } 56 | 57 | void SpdIncreaseAtomicCounter(AU1 slice) { 58 | globallycoherent RWStructuredBuffer globalAtomic = ResourceDescriptorHeap[rc.mGlobalAtomicBuffer]; 59 | InterlockedAdd(globalAtomic[0], 1, spdCounter); 60 | } 61 | 62 | AU1 SpdGetAtomicCounter() { 63 | return spdCounter; 64 | } 65 | 66 | void SpdResetAtomicCounter(AU1 slice) { 67 | globallycoherent RWStructuredBuffer globalAtomic = ResourceDescriptorHeap[rc.mGlobalAtomicBuffer]; 68 | globalAtomic[0] = 0; 69 | } 70 | 71 | AF4 SpdLoadIntermediate(AU1 x, AU1 y) { 72 | return AF4( 73 | spdIntermediateR[x][y], 74 | spdIntermediateG[x][y], 75 | spdIntermediateB[x][y], 76 | spdIntermediateA[x][y]); 77 | } 78 | 79 | void SpdStoreIntermediate(AU1 x, AU1 y, AF4 value) { 80 | spdIntermediateR[x][y] = value.x; 81 | spdIntermediateG[x][y] = value.y; 82 | spdIntermediateB[x][y] = value.z; 83 | spdIntermediateA[x][y] = value.w; 84 | } 85 | 86 | AF4 SpdReduce4(AF4 v0, AF4 v1, AF4 v2, AF4 v3) { 87 | return (v0 + v1 + v2 + v3) * 0.25; 88 | } 89 | 90 | #include "include/Ffx_SPD.hlsli" 91 | 92 | [numthreads(256, 1, 1)] 93 | void main(uint3 group_id : SV_GroupID, uint group_index : SV_GroupIndex) { 94 | SpdDownsample(group_id.xy, group_index, rc.mNrOfMips, rc.mNrOfWorkGroups, 0); 95 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/FullscreenTriangleVS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Common.hlsli" 2 | 3 | FULLSCREEN_TRIANGLE_VS_OUT main(uint vertex_id : SV_VertexID) { 4 | FULLSCREEN_TRIANGLE_VS_OUT output; 5 | 6 | output.mScreenUV = float2((vertex_id << 1) & 2, vertex_id & 2); 7 | output.mPixelCoords = float4(output.mScreenUV * float2(2, -2) + float2(-1, 1), 0, 1); 8 | 9 | return output; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /Assets/Shaders/Backend/GBufferDebugPS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Common.hlsli" 3 | #include "Include/Packing.hlsli" 4 | #include "Include/Material.hlsli" 5 | 6 | ROOT_CONSTANTS(GbufferDebugRootConstants, rc) 7 | 8 | float4 main(in FULLSCREEN_TRIANGLE_VS_OUT inParams) : SV_Target0 { 9 | Texture2D gbuffer_texture = ResourceDescriptorHeap[rc.mTexture]; 10 | float4 output_color = gbuffer_texture[int2(inParams.mPixelCoords.xy)]; 11 | 12 | #ifdef DEBUG_TEXTURE_GBUFFER_DEPTH 13 | float depth = gbuffer_texture.Sample(SamplerPointClamp, inParams.mScreenUV).r; 14 | float linear_depth = rc.mNearPlane * rc.mFarPlane / (rc.mFarPlane + depth * (rc.mNearPlane - rc.mFarPlane)); 15 | output_color = float4(1.0f / linear_depth.x, 0.0, 0.0, 1.0); 16 | #endif 17 | 18 | #ifdef DEBUG_TEXTURE_GBUFFER_VELOCITY 19 | output_color = float4(output_color.rg * 100.0f, 0.0, 1.0); 20 | #endif 21 | 22 | Surface surface; 23 | surface.Unpack(asuint(output_color)); 24 | 25 | #if defined(DEBUG_TEXTURE_GBUFFER_ALBEDO) 26 | output_color = surface.mAlbedo; 27 | 28 | #elif defined(DEBUG_TEXTURE_GBUFFER_NORMALS) 29 | output_color.rgb = surface.mNormal * 0.5 + 0.5; 30 | 31 | #elif defined(DEBUG_TEXTURE_GBUFFER_EMISSIVE) 32 | output_color.rgb = surface.mEmissive; 33 | 34 | #elif defined(DEBUG_TEXTURE_GBUFFER_METALLIC) 35 | output_color = surface.mMetallic.xxxx; 36 | 37 | #elif defined(DEBUG_TEXTURE_GBUFFER_ROUGHNESS) 38 | output_color = surface.mRoughness.xxxx; 39 | 40 | #endif 41 | 42 | return float4(output_color.rgb, 1.0); 43 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/GBufferVS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Common.hlsli" 2 | 3 | struct VS_OUTPUT { 4 | float4 sv_position : SV_Position; 5 | float4 curr_position : POS0; 6 | float4 prev_position : POS1; 7 | float2 texcoord : TEXCOORD; 8 | float3 normal : NORMAL; 9 | float3 tangent : TANGENT; 10 | float3 bitangent : BINORMAL; 11 | }; 12 | 13 | FRAME_CONSTANTS(fc) 14 | ROOT_CONSTANTS(GbufferRootConstants, rc) 15 | 16 | VS_OUTPUT main(in uint inVertexID : SV_VertexID) 17 | { 18 | StructuredBuffer geometries = ResourceDescriptorHeap[fc.mInstancesBuffer]; 19 | RTGeometry geometry = geometries[rc.mInstanceIndex]; 20 | 21 | StructuredBuffer vertex_buffer = ResourceDescriptorHeap[geometry.mVertexBuffer]; 22 | 23 | RTVertex vertex = vertex_buffer[inVertexID]; 24 | float4 prev_pos_ws = mul(geometry.mPrevWorldTransform, float4(vertex.mPos, 1.0)); 25 | 26 | TransformToWorldSpace(vertex, geometry.mWorldTransform); 27 | float4 curr_pos_ws = float4(vertex.mPos, 1.0); 28 | 29 | VS_OUTPUT output; 30 | output.normal = normalize(vertex.mNormal); 31 | output.tangent = normalize(vertex.mTangent); 32 | output.tangent = normalize(output.tangent - dot(output.tangent, output.normal) * output.normal); 33 | output.bitangent = normalize(cross(output.normal, output.tangent)); 34 | output.texcoord = vertex.mTexCoord; 35 | 36 | // TODO: prev world transform 37 | output.curr_position = mul(fc.mViewProjectionMatrix, curr_pos_ws); 38 | output.prev_position = mul(fc.mPrevViewProjectionMatrix, prev_pos_ws); 39 | output.sv_position = output.curr_position; 40 | return output; 41 | } 42 | 43 | -------------------------------------------------------------------------------- /Assets/Shaders/Backend/GrassRenderPS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Common.hlsli" 2 | #include "Include/Packing.hlsli" 3 | 4 | struct VS_OUTPUT { 5 | float4 mPos : SV_Position; 6 | float3 mPrevPos : PrevPosition; 7 | float3 mNormal : NORMAL; 8 | float height : Field0; 9 | }; 10 | 11 | struct RenderTargets { 12 | float4 GBufferRT0 : SV_Target0; 13 | }; 14 | 15 | RenderTargets main(VS_OUTPUT input) 16 | { 17 | float4 albedo = float4(0.0, lerp(0, 1, input.height), 0.0, 1.0); 18 | 19 | uint4 packed = uint4(0, 0, 0, 0); 20 | PackAlbedo(albedo.rgb, packed); 21 | PackAlpha(albedo.a, packed); 22 | PackNormal(input.mNormal, packed); 23 | PackMetallicRoughness(0, 1.0, packed); 24 | 25 | RenderTargets mrt; 26 | mrt.GBufferRT0 = asfloat(packed); 27 | return mrt; 28 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/GrassRenderVS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Random.hlsli" 3 | 4 | struct VS_OUTPUT { 5 | float4 mPos : SV_Position; 6 | float3 mPrevPos : PrevPosition; 7 | float3 mNormal : NORMAL; 8 | float height : Field0; 9 | }; 10 | 11 | FRAME_CONSTANTS(fc) 12 | ROOT_CONSTANTS(GrassRenderRootConstants, grc) 13 | 14 | static const float2 vertex_array[] = 15 | { 16 | float2(-0.5, 0.0), 17 | float2(0.5, 0.0), 18 | float2(-0.5, 0.0), 19 | float2(0.5, 0.0), 20 | float2(-0.5, 0.0), 21 | float2(0.5, 0.0), 22 | float2(-0.5, 0.0), 23 | float2(0.5, 0.0), 24 | float2(-0.5, 0.0), 25 | float2(0.5, 0.0), 26 | float2(-0.5, 0.0), 27 | float2(0.5, 0.0), 28 | float2(-0.5, 0.0), 29 | float2(0.5, 0.0), 30 | float2(0.0, 0.0) 31 | }; 32 | 33 | float3 QuadraticBezierCurve(float3 p0, float3 p1, float3 p2, float t) { 34 | return p0 * pow((1 - t), 2) + p1 * 2 * (1 - t) * t + p2 * pow(t, 2); 35 | } 36 | 37 | float3 QuadraticBezierCurveDerivative(float3 p0, float3 p1, float3 p2, float t) { 38 | return p0 * (2 * t - 2) + (2 * p2 - 4 * p1) * t + 2 * p1; 39 | } 40 | 41 | struct VS_INPUT { 42 | uint vertex_id : SV_VertexID; 43 | uint instance_id : SV_InstanceID; 44 | }; 45 | 46 | 47 | VS_OUTPUT main(VS_INPUT input) 48 | { 49 | VS_OUTPUT output; 50 | 51 | uint hash_state = input.instance_id; 52 | hash_state = pcg_hash(hash_state); 53 | 54 | float2 random = pcg_float2(hash_state); 55 | 56 | float blade_height = 2; 57 | float blade_width = 0.10; 58 | 59 | float height01 = float(input.vertex_id / 2) / 7.0; 60 | 61 | uint row = input.instance_id / 256; 62 | uint column = input.instance_id - (row * 256); 63 | 64 | float3 pos = float3(row, 0.0, column); 65 | float2 facing = pcg_float2(hash_state); 66 | //facing = float2(0, 1.0); 67 | 68 | pos.xz *= 0.5; 69 | pos.xz += random; 70 | 71 | float3 control_point0 = pos; 72 | float3 control_point2 = float3(pos.x, blade_height, pos.z); 73 | // tilt the tip of the blade in the direction its facing 74 | control_point2.xz += facing * grc.mTilt; 75 | float3 control_point1 = lerp(control_point0, control_point2, 0.5); 76 | 77 | 78 | //// bend the mid point 79 | control_point1.xz += -facing * grc.mBend; 80 | control_point1.y = lerp(control_point1.y, control_point2.y, grc.mBend); 81 | 82 | float sin_time = sin(fc.mTime * 2.0) * 0.5 + 0.5; 83 | control_point2.xz += -grc.mWindDirection * sin_time; 84 | 85 | output.mPos.xyz = QuadraticBezierCurve(control_point0, control_point1, control_point2, height01); 86 | output.mPos.w = 1.0; 87 | 88 | float2 perp = normalize(cross(float3(facing.x, 0.0, facing.y), float3(0, 1, 0))).xz; 89 | 90 | if (input.vertex_id != 14) 91 | { 92 | if (input.vertex_id % 2) 93 | output.mPos.xz += perp * (blade_width / 2); 94 | else 95 | output.mPos.xz += -perp * (blade_width / 2); 96 | } 97 | 98 | output.mPos = mul(fc.mViewProjectionMatrix, output.mPos); 99 | output.mNormal = float3(facing.x, 1.0, facing.y); 100 | output.height = height01; 101 | 102 | return output; 103 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/ImGuiPS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | 3 | struct VS_OUTPUT 4 | { 5 | float2 uv : TEXCOORD0; 6 | float4 color : COLOR; 7 | }; 8 | 9 | ROOT_CONSTANTS(ImGuiRootConstants, rc) 10 | 11 | 12 | float4 main(VS_OUTPUT input) : SV_TARGET { 13 | float4 sampled = float4(1.0, 1.0, 1.0, 1.0); 14 | 15 | Texture2D texture = ResourceDescriptorHeap[rc.mBindlessTextureIndex]; 16 | sampled = texture.Sample(SamplerLinearClamp, input.uv); 17 | 18 | sampled.a = smoothstep(0.0, 1.0, sampled.r); 19 | sampled = float4(1, 1, 1, sampled.a); 20 | 21 | return input.color * sampled; 22 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/ImGuiVS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | 3 | struct VS_INPUT 4 | { 5 | float2 pos : POSITION; 6 | float2 uv : TEXCOORD; 7 | uint color : COLOR; 8 | }; 9 | 10 | struct VS_OUTPUT 11 | { 12 | float2 uv : TEXCOORD0; 13 | float4 color : COLOR; 14 | }; 15 | 16 | ROOT_CONSTANTS(ImGuiRootConstants, rc) 17 | 18 | VS_OUTPUT main(in VS_INPUT input, out float4 pos : SV_Position) { 19 | pos = mul(rc.mProjection, float4(input.pos, 0.0, 1.0)); 20 | pos.z = (pos.z / pos.w * 0.5 + 0.5) * pos.w; 21 | 22 | VS_OUTPUT output; 23 | output.uv = input.uv; 24 | 25 | output.color.w = float((input.color & uint(0xff000000)) >> 24) / 255; 26 | output.color.z = float((input.color & uint(0x00ff0000)) >> 16) / 255; 27 | output.color.y = float((input.color & uint(0x0000ff00)) >> 8) / 255; 28 | output.color.x = float((input.color & uint(0x000000ff)) >> 0) / 255; 29 | 30 | return output; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Assets/Shaders/Backend/Include/Bindless.hlsli: -------------------------------------------------------------------------------- 1 | #ifndef BINDLESS_HLSLI 2 | #define BINDLESS_HLSLI 3 | 4 | #include "Shared.hlsli" 5 | 6 | //#define GLOBAL_ROOT_SIGNATURE "RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED )," \ 7 | // "RootConstants(num32BitConstants=32, b0), " \ 8 | // "StaticSampler(s0, addressU = TEXTURE_ADDRESS_CLAMP, filter = FILTER_ANISOTROPIC)" 9 | 10 | #define ROOT_CONSTANTS(T, name) ConstantBuffer name : register(b0, space0); 11 | 12 | #define CBV0(T, name) ConstantBuffer name : register(b1, space0); 13 | #define CBV1(T, name) ConstantBuffer name : register(b2, space0); 14 | #define CBV2(T, name) ConstantBuffer name : register(b3, space0); 15 | #define CBV3(T, name) ConstantBuffer name : register(b4, space0); 16 | 17 | #define SRV0(name) ByteAddressBuffer name : register(t0, space0); 18 | #define SRV1(name) ByteAddressBuffer name : register(t1, space0); 19 | #define SRV2(name) ByteAddressBuffer name : register(t2, space0); 20 | #define SRV3(name) ByteAddressBuffer name : register(t3, space0); 21 | 22 | #define UAV0(T, name) RWStructuredBuffer name : register(u0, space0); 23 | #define UAV1(T, name) RWStructuredBuffer name : register(u1, space0); 24 | #define UAV2(T, name) RWStructuredBuffer name : register(u2, space0); 25 | #define UAV3(T, name) RWStructuredBuffer name : register(b3, space0); 26 | 27 | SamplerState SamplerPointWrapNoMips : register(s0); 28 | SamplerState SamplerPointWrap : register(s1); 29 | SamplerState SamplerPointClamp : register(s2); 30 | SamplerState SamplerLinearWrap : register(s3); 31 | SamplerState SamplerLinearClamp : register(s4); 32 | SamplerState SamplerAnisoWrap : register(s5); 33 | SamplerState SamplerAnisoClamp : register(s6); 34 | 35 | #define PASS_CONSTANTS(name) SRV1(name) 36 | #define FRAME_CONSTANTS(name) CBV1(FrameConstants, name) 37 | 38 | #endif // BINDLESS_HLSLI -------------------------------------------------------------------------------- /Assets/Shaders/Backend/Include/Common.hlsli: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_HLSLI 2 | #define COMMON_HLSLI 3 | 4 | #include "Bindless.hlsli" 5 | #include "Packing.hlsli" 6 | 7 | #define M_PI 3.14159265358979323846 8 | 9 | struct FULLSCREEN_TRIANGLE_VS_OUT { 10 | float4 mPixelCoords : SV_Position; 11 | float2 mScreenUV : TEXCOORD; 12 | }; 13 | 14 | 15 | float3 ReconstructWorldPosition(float2 inUV, float inDepth, float4x4 inClipToWorldMatrix) { 16 | float x = inUV.x * 2.0f - 1.0f; 17 | float y = (1.0 - inUV.y) * 2.0f - 1.0f; 18 | float4 position_s = float4(x, y, inDepth, 1.0f); 19 | float4 position_v = mul(inClipToWorldMatrix, position_s); 20 | return position_v.xyz / position_v.w; 21 | } 22 | 23 | float3 ReconstructPosition(float2 inUV, float inDepth, float4x4 inClipToViewMatrix) 24 | { 25 | float x = inUV.x * 2.0f - 1.0f; 26 | float y = (1.0 - inUV.y) * 2.0f - 1.0f; 27 | float4 position_s = float4(x, y, inDepth, 1.0f); 28 | float4 position_v = mul(inClipToViewMatrix, position_s); 29 | return position_v.xyz / position_v.w; 30 | } 31 | 32 | 33 | float2 CalculateViewToScreenUV(float3 inPos, float4x4 inViewToClipMatrix) 34 | { 35 | float4 clip_pos = mul(inViewToClipMatrix, float4(inPos, 1.0)); 36 | clip_pos.xy /= clip_pos.w; 37 | clip_pos.xy = clip_pos.xy * 0.5 + 0.5; 38 | return clip_pos.xy; 39 | } 40 | 41 | float3x3 Adjugate(float4x4 m) 42 | { 43 | return float3x3(cross(m[1].xyz, m[2].xyz), 44 | cross(m[2].xyz, m[0].xyz), 45 | cross(m[0].xyz, m[1].xyz)); 46 | } 47 | 48 | 49 | void TransformToWorldSpace(inout RTVertex inVertex, float4x4 inLocalToWorldMatrix) 50 | { 51 | inVertex.mPos = mul(inLocalToWorldMatrix, float4(inVertex.mPos, 1.0)).xyz; 52 | inVertex.mNormal = normalize(mul(Adjugate(inLocalToWorldMatrix), inVertex.mNormal)); 53 | inVertex.mTangent = normalize(mul(inLocalToWorldMatrix, float4(inVertex.mTangent, 0.0)).xyz); 54 | } 55 | 56 | 57 | float MapRange(float value, float start1, float stop1, float start2, float stop2) { 58 | return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1)); 59 | } 60 | 61 | 62 | template 63 | T square(T inValue) { return inValue * inValue; } 64 | 65 | 66 | float LuminanceLinear(float3 inLinearRGB) 67 | { 68 | return dot(inLinearRGB, float3(0.2127, 0.7152, 0.0722)); 69 | } 70 | 71 | void Discard(bool inDiscard) 72 | { 73 | if (inDiscard) discard; 74 | } 75 | 76 | 77 | // Building an Orthonormal Basis, Revisited 78 | // http://jcgt.org/published/0006/01/01/ 79 | float3x3 BuildOrthonormalBasis(float3 n) 80 | { 81 | float3 b1; 82 | float3 b2; 83 | 84 | if (n.z < 0.0) 85 | { 86 | const float a = 1.0 / (1.0 - n.z); 87 | const float b = n.x * n.y * a; 88 | b1 = float3(1.0 - n.x * n.x * a, -b, n.x); 89 | b2 = float3(b, n.y * n.y * a - 1.0, -n.y); 90 | } 91 | else 92 | { 93 | const float a = 1.0 / (1.0 + n.z); 94 | const float b = -n.x * n.y * a; 95 | b1 = float3(1.0 - n.x * n.x * a, b, -n.x); 96 | b2 = float3(b, 1.0 - n.y * n.y * a, -n.y); 97 | } 98 | 99 | return float3x3( 100 | b1.x, b2.x, n.x, 101 | b1.y, b2.y, n.y, 102 | b1.z, b2.z, n.z 103 | ); 104 | } 105 | 106 | #endif // COMMON_HLSLI 107 | -------------------------------------------------------------------------------- /Assets/Shaders/Backend/Include/RayTracing.hlsli: -------------------------------------------------------------------------------- 1 | #ifndef RT_HLSLI 2 | #define RT_HLSLI 3 | 4 | #include "Shared.hlsli" 5 | 6 | 7 | RTVertex InterpolateVertices(RTVertex v0, RTVertex v1, RTVertex v2, float3 inBaryCentrics) { 8 | RTVertex vertex; 9 | vertex.mPos = v0.mPos * inBaryCentrics.x + v1.mPos * inBaryCentrics.y + v2.mPos * inBaryCentrics.z; 10 | vertex.mTexCoord = v0.mTexCoord * inBaryCentrics.x + v1.mTexCoord * inBaryCentrics.y + v2.mTexCoord * inBaryCentrics.z; 11 | vertex.mNormal = v0.mNormal * inBaryCentrics.x + v1.mNormal * inBaryCentrics.y + v2.mNormal * inBaryCentrics.z; 12 | vertex.mTangent = v0.mTangent * inBaryCentrics.x + v1.mTangent * inBaryCentrics.y + v2.mTangent * inBaryCentrics.z; 13 | 14 | return vertex; 15 | } 16 | 17 | 18 | RTVertex CalculateVertexFromGeometry(RTGeometry inGeometry, uint inPrimitiveIndex, float2 inBaryCentrics) { 19 | StructuredBuffer index_buffer = ResourceDescriptorHeap[NonUniformResourceIndex(inGeometry.mIndexBuffer)]; 20 | StructuredBuffer vertex_buffer = ResourceDescriptorHeap[NonUniformResourceIndex(inGeometry.mVertexBuffer)]; 21 | 22 | const uint3 indices = index_buffer[inPrimitiveIndex]; 23 | const RTVertex v0 = vertex_buffer[indices.x]; 24 | const RTVertex v1 = vertex_buffer[indices.y]; 25 | const RTVertex v2 = vertex_buffer[indices.z]; 26 | 27 | // float3 vert_normal = normalize(cross(v0.mPos - v1.mPos, v0.mPos - v2.mPos)); 28 | 29 | const float3 barycentrics = float3(1.0 - inBaryCentrics.x - inBaryCentrics.y, inBaryCentrics.x, inBaryCentrics.y); 30 | return InterpolateVertices(v0, v1, v2, barycentrics); 31 | } 32 | 33 | 34 | bool TraceShadowRay(RaytracingAccelerationStructure inTLAS, float3 inRayPos, float3 inRayDir, float inTMin, float inTMax) 35 | { 36 | RayDesc shadow_ray; 37 | shadow_ray.Origin = inRayPos; 38 | shadow_ray.Direction = inRayDir; 39 | shadow_ray.TMin = inTMin; 40 | shadow_ray.TMax = inTMax; 41 | 42 | uint shadow_ray_flags = RAY_FLAG_FORCE_OPAQUE | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH | RAY_FLAG_SKIP_CLOSEST_HIT_SHADER; 43 | RayQuery < RAY_FLAG_FORCE_OPAQUE | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH | RAY_FLAG_SKIP_CLOSEST_HIT_SHADER > query; 44 | 45 | query.TraceRayInline(inTLAS, shadow_ray_flags, 0xFF, shadow_ray); 46 | query.Proceed(); 47 | 48 | return query.CommittedStatus() == COMMITTED_TRIANGLE_HIT; 49 | } 50 | 51 | #endif -------------------------------------------------------------------------------- /Assets/Shaders/Backend/LightCullTiledCS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Common.hlsli" 3 | 4 | bool IsLightCulled(RTLight inLight); 5 | 6 | FRAME_CONSTANTS(fc) 7 | ROOT_CONSTANTS(TiledLightCullingRootConstants, rc) 8 | 9 | groupshared uint g_LightCount; 10 | groupshared uint g_LightIndices[LIGHT_CULL_MAX_LIGHTS]; 11 | 12 | [numthreads(LIGHT_CULL_TILE_SIZE, LIGHT_CULL_TILE_SIZE, 1)] 13 | void main(uint3 dispatchThreadID : SV_DispatchThreadID, uint3 groupID : SV_GroupID, uint3 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex) 14 | { 15 | RWByteAddressBuffer light_count_buffer = ResourceDescriptorHeap[rc.mLightGridBuffer]; 16 | RWByteAddressBuffer light_indices_buffer = ResourceDescriptorHeap[rc.mLightIndicesBuffer]; 17 | RWStructuredBuffer bindless_lights_buffer = ResourceDescriptorHeap[fc.mLightsBuffer]; 18 | 19 | if (any(dispatchThreadID.xy >= rc.mFullResSize)) 20 | return; 21 | 22 | if (groupIndex == 0) 23 | g_LightCount = 0; 24 | 25 | GroupMemoryBarrierWithGroupSync(); 26 | 27 | for (int light_idx = 0; light_idx < fc.mNrOfLights; light_idx++) 28 | { 29 | RTLight light = bindless_lights_buffer[light_idx]; 30 | 31 | bool culled = IsLightCulled(light); 32 | 33 | if (!culled) 34 | { 35 | uint lds_light_index; 36 | InterlockedAdd(g_LightCount, 1, lds_light_index); 37 | 38 | if (lds_light_index < LIGHT_CULL_MAX_LIGHTS) 39 | g_LightIndices[lds_light_index] = light_idx; 40 | } 41 | } 42 | 43 | GroupMemoryBarrierWithGroupSync(); 44 | 45 | if (groupIndex == 0) 46 | { 47 | uint light_count = min(g_LightCount, LIGHT_CULL_MAX_LIGHTS); 48 | uint count_offset = rc.mDispatchSize.x * groupID.y + groupID.x; 49 | light_count_buffer.Store(count_offset, light_count); 50 | 51 | uint indices_offset = rc.mDispatchSize.x * LIGHT_CULL_MAX_LIGHTS * groupID.y + groupID.x * LIGHT_CULL_MAX_LIGHTS; 52 | 53 | for (int i = 0; i < light_count; i++) 54 | light_indices_buffer.Store(indices_offset + i, g_LightIndices[i]); 55 | } 56 | } 57 | 58 | 59 | bool IsLightCulled(RTLight inLight) 60 | { 61 | return false; 62 | } 63 | 64 | 65 | //void GetLightIndices(uint2 inPixelCoords, TiledLightCullingRootConstants inConstants, out uint outOffset, out uint outCount) 66 | //{ 67 | // uint2 group_index = inPixelCoords / LIGHT_CULL_TILE_SIZE; 68 | // RWByteAddressBuffer light_count_buffer = ResourceDescriptorHeap[inConstants.mLightGridBuffer]; 69 | // 70 | // outCount = light_count_buffer.Load(inConstants.mTileCount.x.x * group_index.x + group_index.y); 71 | // outOffset = inConstants.mTileCount.x * group_index.x * LIGHT_CULL_MAX_LIGHTS + group_index.y; 72 | //} 73 | -------------------------------------------------------------------------------- /Assets/Shaders/Backend/Materials/DeferredPS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Material.hlsli" 2 | 3 | struct VS_OUTPUT { 4 | float4 sv_position : SV_Position; 5 | float4 curr_position : POS0; 6 | float4 prev_position : POS1; 7 | float2 texcoord : TEXCOORD; 8 | float3 normal : NORMAL; 9 | float3 tangent : TANGENT; 10 | float3 bitangent : BINORMAL; 11 | }; 12 | 13 | struct PS_OUTPUT { 14 | float4 gbuffer: SV_Target0; 15 | float2 motionvectors : SV_Target1; 16 | uint selection : SV_Target2; 17 | }; 18 | 19 | ROOT_CONSTANTS(GbufferRootConstants, rc) 20 | 21 | @Global 22 | 23 | PS_OUTPUT main(in VS_OUTPUT input) { 24 | PS_OUTPUT output; 25 | 26 | StructuredBuffer geometries = ResourceDescriptorHeap[rc.mInstancesBuffer]; 27 | StructuredBuffer materials = ResourceDescriptorHeap[rc.mMaterialsBuffer]; 28 | 29 | RTGeometry geometry = geometries[rc.mInstanceIndex]; 30 | RTMaterial material = materials[geometry.mMaterialIndex]; 31 | 32 | Texture2D albedo_texture = ResourceDescriptorHeap[NonUniformResourceIndex(material.mAlbedoTexture)]; 33 | Texture2D normals_texture = ResourceDescriptorHeap[NonUniformResourceIndex(material.mNormalsTexture)]; 34 | Texture2D emissive_texture = ResourceDescriptorHeap[NonUniformResourceIndex(material.mEmissiveTexture)]; 35 | Texture2D metallic_texture = ResourceDescriptorHeap[NonUniformResourceIndex(material.mMetallicTexture)]; 36 | Texture2D roughness_texture = ResourceDescriptorHeap[NonUniformResourceIndex(material.mRoughnessTexture)]; 37 | 38 | float4 sampled_albedo = albedo_texture.Sample(SamplerAnisoWrap, input.texcoord); 39 | float3 sampled_normal = normals_texture.Sample(SamplerAnisoWrap, input.texcoord).rgb; // alpha channel unused 40 | float3 sampled_emissive = emissive_texture.Sample(SamplerAnisoWrap, input.texcoord).rgb; // alpha channel unused 41 | float sampled_metallic = metallic_texture.Sample(SamplerAnisoWrap, input.texcoord).r; // value swizzled across all channels, just get Red 42 | float sampled_roughness = roughness_texture.Sample(SamplerAnisoWrap, input.texcoord).r; // value swizzled across all channels, just get Red 43 | 44 | //sampled_normal = sampled_normal * 2.0 - 1.0; 45 | sampled_normal = ReconstructNormalBC5(sampled_normal.xy); 46 | 47 | float3x3 TBN = float3x3(input.tangent, input.bitangent, input.normal); 48 | float3 normal = normalize(mul(sampled_normal.xyz, TBN)); 49 | // normal = normalize(input.normal); 50 | 51 | float4 albedo = material.mAlbedo * sampled_albedo; 52 | float metallic = material.mMetallic * sampled_metallic; 53 | float roughness = material.mRoughness * sampled_roughness; 54 | float3 emissive = material.mEmissive.rgb * sampled_emissive; 55 | 56 | uint4 packed = uint4(0, 0, 0, 0); 57 | PackAlbedo(albedo.rgb, packed); 58 | PackAlpha(albedo.a, packed); 59 | PackNormal(normal, packed); 60 | PackEmissive(emissive, packed); 61 | PackMetallicRoughness(metallic, roughness, packed); 62 | 63 | @Main 64 | 65 | output.gbuffer = asfloat(packed); 66 | float2 curr_pos = (input.curr_position.xyz / input.prev_position.w).xy - fc.mJitter; 67 | float2 prev_pos = (input.prev_position.xyz / input.prev_position.w).xy - fc.mPrevJitter; 68 | 69 | output.motionvectors = (curr_pos - prev_pos); 70 | output.motionvectors.xy *= float2(0.5, -0.5); 71 | 72 | output.selection = rc.mEntity; 73 | 74 | return output; 75 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/Materials/DeferredVS.hlsl: -------------------------------------------------------------------------------- 1 | #include "include/shared.h" 2 | #include "include/brdf.hlsli" 3 | #include "include/common.hlsli" 4 | #include "include/packing.hlsli" 5 | #include "include/bindless.hlsli" 6 | 7 | struct VS_OUTPUT 8 | { 9 | float4 sv_position : SV_Position; 10 | float4 curr_position : POS0; 11 | float4 prev_position : POS1; 12 | float2 texcoord : TEXCOORD; 13 | float3 normal : NORMAL; 14 | float3 tangent : TANGENT; 15 | float3 bitangent : BINORMAL; 16 | }; 17 | 18 | ROOT_CONSTANTS(GbufferRootConstants, rc) 19 | 20 | @Global 21 | 22 | VS_OUTPUT main(in uint inVertexID : SV_VertexID) 23 | { 24 | StructuredBuffer geometries = ResourceDescriptorHeap[rc.mInstancesBuffer]; 25 | RTGeometry geometry = geometries[rc.mInstanceIndex]; 26 | 27 | StructuredBuffer vertex_buffer = ResourceDescriptorHeap[geometry.mVertexBuffer]; 28 | RTVertex vertex = vertex_buffer[inVertexID]; 29 | 30 | @Main 31 | 32 | TransformToWorldSpace(vertex, geometry.mWorldTransform); 33 | 34 | VS_OUTPUT output; 35 | output.normal = normalize(vertex.mNormal); 36 | output.tangent = normalize(vertex.mTangent); 37 | output.tangent = normalize(output.tangent - dot(output.tangent, output.normal) * output.normal); 38 | output.bitangent = normalize(cross(output.normal, output.tangent)); 39 | output.texcoord = vertex.mTexCoord; 40 | 41 | // TODO: prev world transform 42 | output.curr_position = mul(fc.mViewProjectionMatrix, float4(vertex.mPos, 1.0)); 43 | output.prev_position = mul(fc.mPrevViewProjectionMatrix, float4(vertex.mPos, 1.0)); 44 | 45 | output.sv_position = output.curr_position; 46 | 47 | return output; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /Assets/Shaders/Backend/ProbeDebugPS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Packing.hlsli" 3 | #include "Include/DDGI.hlsli" 4 | 5 | struct VS_OUTPUT { 6 | uint index : INDEX; 7 | float4 position : SV_Position; 8 | float3 normal : NORMAL; 9 | float3 color : COLOR; 10 | }; 11 | 12 | struct PS_OUTPUT { 13 | float4 rendertarget0: SV_Target0; 14 | }; 15 | 16 | ROOT_CONSTANTS(DDGIData, rc) 17 | 18 | 19 | PS_OUTPUT main(in VS_OUTPUT input) { 20 | Texture2D probes_depth_texture = ResourceDescriptorHeap[rc.mProbesDepthTexture]; 21 | Texture2D probes_irradiance_texture = ResourceDescriptorHeap[rc.mProbesIrradianceTexture]; 22 | 23 | float3 irradiance = DDGISampleIrradianceProbe(input.index, input.normal, probes_irradiance_texture); 24 | 25 | PS_OUTPUT output; 26 | //output.rendertarget0 = DDGIGetProbeDebugColor(input.index, rc.mProbeCount); 27 | output.rendertarget0 = float4(irradiance, 1.0); 28 | 29 | return output; 30 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/ProbeDebugVS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/DDGI.hlsli" 3 | 4 | struct VS_OUTPUT { 5 | uint index : INDEX; 6 | float4 position : SV_Position; 7 | float3 normal : NORMAL; 8 | float3 color : COLOR; 9 | }; 10 | 11 | struct VS_INPUT { 12 | float3 pos : POSITION; 13 | float2 texcoord : TEXCOORD; 14 | float3 normal : NORMAL; 15 | float3 tangent : TANGENT; 16 | }; 17 | 18 | FRAME_CONSTANTS(fc) 19 | ROOT_CONSTANTS(DDGIData, rc) 20 | 21 | VS_OUTPUT main (in VS_INPUT input, uint instance_id : SV_InstanceID) { 22 | VS_OUTPUT output; 23 | output.index = instance_id; 24 | 25 | uint3 probe_coord = Index1DTo3D(instance_id, rc.mProbeCount); 26 | float3 probe_ws_pos = rc.mCornerPosition + rc.mProbeSpacing * probe_coord; 27 | 28 | float min_scale = min(min(rc.mProbeSpacing.x, rc.mProbeSpacing.y), rc.mProbeSpacing.z); 29 | float3 scaled_pos = input.pos * min_scale * rc.mProbeRadius; 30 | 31 | output.position = mul(fc.mViewProjectionMatrix, float4(scaled_pos + probe_ws_pos, 1.0)); 32 | output.normal = normalize(input.normal); 33 | 34 | output.color = max(dot(input.normal, -fc.mSunDirection.xyz), 0).xxx; 35 | 36 | return output; 37 | } 38 | -------------------------------------------------------------------------------- /Assets/Shaders/Backend/ProbeSampleCS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Common.hlsli" 3 | #include "Include/Random.hlsli" 4 | #include "Include/DDGI.hlsli" 5 | #include "Include/Material.hlsli" 6 | #include "Include/Sky.hlsli" 7 | #include "Include/RayTracing.hlsli" 8 | 9 | FRAME_CONSTANTS(fc) 10 | ROOT_CONSTANTS(ProbeSampleRootConstants, rc) 11 | 12 | float max3(float3 inValue) 13 | { 14 | return max(max(inValue.x, inValue.y), inValue.z); 15 | } 16 | 17 | float min3(float3 inValue) 18 | { 19 | return min(min(inValue.x, inValue.y), inValue.z); 20 | } 21 | 22 | [numthreads(8, 8, 1)] 23 | void main(uint3 dispatchThreadID : SV_DispatchThreadID) { 24 | if (any(dispatchThreadID.xy >= rc.mDispatchSize.xy)) 25 | return; 26 | 27 | Texture2D depth_texture = ResourceDescriptorHeap[rc.mDepthTexture]; 28 | Texture2D gbuffer_texture = ResourceDescriptorHeap[rc.mGBufferTexture]; 29 | RWTexture2D ddgi_depth_texture = ResourceDescriptorHeap[rc.mDDGIData.mProbesDepthTexture]; 30 | RWTexture2D ddgi_irradiance_texture = ResourceDescriptorHeap[rc.mDDGIData.mProbesIrradianceTexture]; 31 | 32 | const float depth = depth_texture[dispatchThreadID.xy]; 33 | RWTexture2D output_texture = ResourceDescriptorHeap[rc.mOutputTexture]; 34 | 35 | if (depth >= 1.0f) 36 | { 37 | output_texture[dispatchThreadID.xy] = 0.xxxx; 38 | return; 39 | } 40 | 41 | float2 screen_uv = (float2(dispatchThreadID.xy) + 0.5f) / rc.mDispatchSize; 42 | float3 position_ws = ReconstructWorldPosition(screen_uv, depth, fc.mInvViewProjectionMatrix); 43 | float3 normal = UnpackNormal(asuint(gbuffer_texture[dispatchThreadID.xy])); 44 | 45 | float3 offset = min3(rc.mDDGIData.mProbeSpacing) * 0.1f; 46 | float3 offset_ws_pos = position_ws + normal * offset; 47 | float3 irradiance = DDGISampleIrradiance(offset_ws_pos, normal, rc.mDDGIData); 48 | 49 | output_texture[dispatchThreadID.xy] = float4(irradiance, 1.0); 50 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/ProbeUpdateCS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Packing.hlsli" 3 | #include "Include/Common.hlsli" 4 | #include "Include/Random.hlsli" 5 | #include "Include/DDGI.hlsli" 6 | 7 | FRAME_CONSTANTS(fc) 8 | ROOT_CONSTANTS(ProbeUpdateRootConstants, rc) 9 | 10 | [numthreads(64, 1, 1)] 11 | void main(uint3 threadID : SV_DispatchThreadID, uint3 groupThreadID : SV_GroupThreadID, uint3 groupID : SV_GroupID, uint inGroupIndex : SV_GroupIndex) 12 | { 13 | Texture2D rays_depth_texture = ResourceDescriptorHeap[rc.mDDGIData.mRaysDepthTexture]; 14 | RWStructuredBuffer probe_buffer = ResourceDescriptorHeap[rc.mDDGIData.mProbesDataBuffer]; 15 | 16 | // 1D index of the probe we are on, used to read the 192 ray hits from the ray tracing results 17 | uint probe_index = threadID.x; 18 | 19 | // calculate how many rays the current thread should write to lds 20 | const uint rays_per_lane = DDGI_RAYS_PER_PROBE / 64; 21 | 22 | #if 0 23 | for (uint i = 0; i < rays_per_lane; i++) 24 | { 25 | uint ray_index = inGroupIndex * rays_per_lane + i; 26 | lds_ProbeDepthRays[ray_index] = rays_depth_texture[uint2(ray_index, probe_index)]; 27 | } 28 | 29 | GroupMemoryBarrierWithGroupSync(); 30 | #endif 31 | 32 | ProbeData probe_data; 33 | probe_data.offset = 0.xxx; 34 | probe_data.inactive = false; 35 | 36 | uint backface_count = 0; 37 | for (uint ray_index = 0; ray_index < DDGI_RAYS_PER_PROBE; ray_index++) 38 | { 39 | float depth = rays_depth_texture[uint2(ray_index, probe_index)]; 40 | 41 | if (depth < 0.0f) 42 | { 43 | if (++backface_count >= DDGI_RAYS_BACKFACE_THRESHOLD) 44 | { 45 | probe_data.inactive = true; 46 | break; 47 | } 48 | } 49 | } 50 | 51 | probe_buffer[probe_index] = probe_data; 52 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/RTShadowsClassifyCS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Common.hlsli" 3 | 4 | ROOT_CONSTANTS(ShadowsClassifyRootConstants, rc) 5 | 6 | [numthreads(RT_SHADOWS_GROUP_DIM, RT_SHADOWS_GROUP_DIM, 1)] 7 | void main(uint3 dispatchThreadID : SV_DispatchThreadID, uint3 groupID : SV_GroupID, uint3 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex) 8 | { 9 | Texture2D shadow_ray_texture = ResourceDescriptorHeap[rc.mShadowMaskTexture]; 10 | RWStructuredBuffer tiles_buffer = ResourceDescriptorHeap[rc.mTilesBuffer]; 11 | RWByteAddressBuffer dispatch_buffer = ResourceDescriptorHeap[rc.mDispatchBuffer]; 12 | 13 | //if (any(dispatchThreadID.xy >= rc.mDispatchSize)) 14 | // return; 15 | 16 | // every group writes its coordinates to the tile buffer 17 | if (groupIndex == 0) 18 | { 19 | // add 1 to the X dispatch thread count and mark the tile as needing denoising 20 | uint tile_index; 21 | dispatch_buffer.InterlockedAdd(0 * sizeof(uint), 1, tile_index); 22 | tiles_buffer[tile_index] = UInt2ToUInt(groupID.x, groupID.y); 23 | 24 | // set the Y and Z dispatch thread count to 1 25 | uint temp_value; 26 | dispatch_buffer.InterlockedExchange(1 * sizeof(uint), 1, temp_value); 27 | dispatch_buffer.InterlockedExchange(2 * sizeof(uint), 1, temp_value); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Assets/Shaders/Backend/RTShadowsClearTilesCS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Common.hlsli" 3 | 4 | ROOT_CONSTANTS(ShadowsClearRootConstants, rc) 5 | 6 | [numthreads(64, 1, 1)] 7 | void main(uint3 dispatchThreadID : SV_DispatchThreadID, uint3 groupID : SV_GroupID, uint3 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex) 8 | { 9 | RWStructuredBuffer tiles_buffer = ResourceDescriptorHeap[rc.mTilesBuffer]; 10 | RWByteAddressBuffer dispatch_buffer = ResourceDescriptorHeap[rc.mDispatchBuffer]; 11 | 12 | tiles_buffer[dispatchThreadID.x] = 0; 13 | 14 | if (dispatchThreadID.x == 0) 15 | dispatch_buffer.Store4(0, 0.xxxx); 16 | } 17 | -------------------------------------------------------------------------------- /Assets/Shaders/Backend/RTShadowsTraceCS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Material.hlsli" 3 | #include "Include/Packing.hlsli" 4 | #include "Include/Common.hlsli" 5 | #include "Include/Random.hlsli" 6 | 7 | FRAME_CONSTANTS(fc) 8 | ROOT_CONSTANTS(ShadowMaskRootConstants, rc) 9 | 10 | groupshared uint g_RayHitsMask; 11 | 12 | [numthreads(8, 4, 1)] 13 | void main(uint3 dispatchThreadID : SV_DispatchThreadID, uint3 groupID : SV_GroupID, uint3 groupThreadID : SV_GroupThreadID, uint groupLocalIndex : SV_GroupIndex) 14 | { 15 | if (groupLocalIndex == 0) 16 | g_RayHitsMask = 0; 17 | 18 | GroupMemoryBarrierWithGroupSync(); 19 | 20 | if (any(dispatchThreadID.xy >= rc.mDispatchSize)) 21 | return; 22 | 23 | Texture2D gbuffer_texture = ResourceDescriptorHeap[rc.mGbufferRenderTexture]; 24 | Texture2D gbuffer_depth_texture = ResourceDescriptorHeap[rc.mGbufferDepthTexture]; 25 | RWTexture2D result_texture = ResourceDescriptorHeap[rc.mShadowMaskTexture]; 26 | RaytracingAccelerationStructure TLAS = ResourceDescriptorHeap[fc.mShadowTLAS]; 27 | 28 | const float2 pixel_center = float2(dispatchThreadID.xy) + float2(0.5, 0.5); 29 | float2 screen_uv = pixel_center / rc.mDispatchSize; 30 | 31 | float depth = gbuffer_depth_texture[dispatchThreadID.xy]; 32 | 33 | uint hit = 0; 34 | 35 | uint rng = TeaHash(((dispatchThreadID.y << 16) | dispatchThreadID.x), fc.mFrameCounter + 1); 36 | 37 | if (depth < 1.0) 38 | { 39 | const float4 blue_noise = SampleBlueNoise(dispatchThreadID.xy, fc.mFrameCounter); 40 | const float3 ray_dir = SampleDirectionalLight(fc.mSunDirection.xyz, fc.mSunConeAngle, pcg_float2(rng)); 41 | 42 | const float3 normal = UnpackNormal(asuint(gbuffer_texture[dispatchThreadID.xy])); 43 | const float3 ws_pos = ReconstructWorldPosition(screen_uv, depth, fc.mInvViewProjectionMatrix); 44 | const float3 vs_pos = mul(fc.mViewMatrix, float4(ws_pos, 1.0)).xyz; 45 | 46 | const float bias = (-vs_pos.z + length(ws_pos.xyz)) * 1e-3; 47 | 48 | RayDesc ray; 49 | ray.TMin = 0.0; 50 | ray.TMax = 10000.0; 51 | ray.Origin = ws_pos + normal * bias; 52 | ray.Direction = ray_dir; 53 | 54 | if (dot(normal, ray.Direction) > 0.0) 55 | { 56 | uint ray_flags = RAY_FLAG_FORCE_OPAQUE | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH | RAY_FLAG_SKIP_CLOSEST_HIT_SHADER; 57 | RayQuery < RAY_FLAG_FORCE_OPAQUE | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH | RAY_FLAG_SKIP_CLOSEST_HIT_SHADER > query; 58 | 59 | query.TraceRayInline(TLAS, ray_flags, 0xFF, ray); 60 | query.Proceed(); 61 | 62 | hit = query.CommittedStatus() == COMMITTED_TRIANGLE_HIT; 63 | 64 | } 65 | } 66 | 67 | InterlockedOr(g_RayHitsMask, hit << groupLocalIndex); 68 | 69 | GroupMemoryBarrierWithGroupSync(); 70 | 71 | if (groupLocalIndex == 0) 72 | result_texture[groupID.xy] = g_RayHitsMask; 73 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/SDFUI.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Packing.hlsli" 3 | #include "Include/Common.hlsli" 4 | 5 | FRAME_CONSTANTS(fc) 6 | ROOT_CONSTANTS(SDFUIRootConstants, rc) 7 | 8 | float4 main(in FULLSCREEN_TRIANGLE_VS_OUT inParams) : SV_Target0 9 | { 10 | StructuredBuffer draw_command_buffer = ResourceDescriptorHeap[rc.mDrawCommandBuffer]; 11 | StructuredBuffer draw_header_buffer = ResourceDescriptorHeap[rc.mDrawCommandHeaderBuffer]; 12 | 13 | float4 final_color = float4(0, 0, 0, 0); 14 | 15 | for (int command_index = 0; command_index < rc.mCommandCount; command_index++) 16 | { 17 | DrawCommandHeader header = draw_header_buffer[command_index]; 18 | 19 | if (header.type == DRAW_COMMAND_CIRCLE_FILLED) 20 | { 21 | uint offset = header.startOffset; 22 | float4 color = draw_command_buffer[offset++]; 23 | float4 pos_radius = draw_command_buffer[offset++]; 24 | 25 | float distance = length(inParams.mPixelCoords.xy - pos_radius.xy) - pos_radius.z; 26 | 27 | //float glow_strength = 0.5; 28 | //float glow_mask = saturate(distance / 20.0f); 29 | //final_color = lerp(final_color, float4(1, 1, 0, 1), (1.0 - glow_mask) * glow_strength); 30 | 31 | final_color = lerp(final_color, color, saturate(1.0 - distance)); 32 | } 33 | else if (header.type == DRAW_COMMAND_RECT) 34 | { 35 | uint offset = header.startOffset; 36 | float4 color = draw_command_buffer[offset++]; 37 | float4 pos_size = draw_command_buffer[offset++]; 38 | float radius = draw_command_buffer[offset++].x; 39 | 40 | float distance = length(max(abs(inParams.mPixelCoords.xy - pos_size.xy) - pos_size.zw + radius, 0.0)) - radius; 41 | final_color = lerp(final_color, color, saturate(1.0 - distance)); 42 | } 43 | } 44 | 45 | return final_color; 46 | 47 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/SSRTraceCS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Shared.hlsli" 2 | #include "Include/Common.hlsli" 3 | #include "Include/Random.hlsli" 4 | #include "Include/Bindless.hlsli" 5 | 6 | FRAME_CONSTANTS(fc) 7 | ROOT_CONSTANTS(SSRTraceRootConstants, rc) 8 | 9 | [numthreads(8, 8, 1)] 10 | void main(uint3 threadID : SV_DispatchThreadID) 11 | { 12 | if (any(threadID.xy >= rc.mDispatchSize.xy)) 13 | return; 14 | 15 | Texture2D depth_texture = ResourceDescriptorHeap[rc.mDepthTexture]; 16 | Texture2D scene_texture = ResourceDescriptorHeap[rc.mSceneTexture]; 17 | Texture2D gbuffer_texture = ResourceDescriptorHeap[rc.mGBufferTexture]; 18 | RWTexture2D output_texture = ResourceDescriptorHeap[rc.mOutputTexture]; 19 | 20 | float2 pixel_center = float2(threadID.xy) + float2(0.5, 0.5); 21 | float2 screen_uv = pixel_center / rc.mDispatchSize; 22 | 23 | float depth = depth_texture[threadID.xy]; 24 | 25 | if (depth == 1.0) 26 | { 27 | output_texture[threadID.xy] = 1.0; 28 | return; 29 | } 30 | 31 | float3 ws_pos = ReconstructWorldPosition(screen_uv, depth, fc.mInvViewProjectionMatrix); 32 | float3 ws_normal = UnpackNormal(asuint(gbuffer_texture[threadID.xy])); 33 | 34 | float3 camera_dir = normalize(fc.mCameraPosition.xyz - ws_pos); 35 | float3 ws_ray_dir = normalize(reflect(camera_dir, ws_normal)); 36 | 37 | float4 cs_ray_start = mul(fc.mViewProjectionMatrix, float4(ws_pos, 1.0)); 38 | float4 cs_ray_end = mul(fc.mViewProjectionMatrix, float4(ws_pos + ws_ray_dir, 1.0)); 39 | 40 | float3 ndc_ray_start = cs_ray_start.xyz / cs_ray_start.w; 41 | float3 ndc_ray_end = cs_ray_end.xyz / cs_ray_end.w; 42 | 43 | ndc_ray_start.xy = ndc_ray_start.xy * float2(0.5, -0.5) + float2(0.5, 0.5); 44 | ndc_ray_end.xy = ndc_ray_end.xy * float2(0.5, -0.5) + float2(0.5, 0.5); 45 | 46 | float3 ndc_ray_dir = normalize(ndc_ray_end - ndc_ray_start); 47 | 48 | float sample_depth = 0.0; 49 | float3 sample_color = 0.0.xxx; 50 | 51 | for (int i = 1; i < 64; i++) 52 | { 53 | float3 ndc_sample_pos = ndc_ray_start + ndc_ray_dir * i; 54 | 55 | if (any(ndc_sample_pos.xy < 0.0) || any(ndc_sample_pos.xy > 1.0)) 56 | { 57 | sample_color = 0.xxx; 58 | break; 59 | } 60 | 61 | sample_depth = depth_texture.SampleLevel(SamplerPointClamp, ndc_sample_pos.xy, 0); 62 | 63 | if (sample_depth > depth) 64 | { 65 | sample_color = scene_texture.SampleLevel(SamplerLinearClamp, ndc_sample_pos.xy, 0).rgb; 66 | break; 67 | } 68 | 69 | ndc_ray_dir *= 1.05; 70 | 71 | //sample_color = scene_texture.SampleLevel(SamplerLinearClamp, ndc_sample_pos.xy, 0); 72 | 73 | } 74 | 75 | output_texture[threadID.xy] = float4(sample_color, 1.0); 76 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/ShadowMapPS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Material.hlsli" 3 | #include "Include/Packing.hlsli" 4 | 5 | struct VS_OUTPUT { 6 | float4 position : SV_Position; 7 | }; 8 | 9 | FRAME_CONSTANTS(fc) 10 | ROOT_CONSTANTS(ShadowMapRootConstants, rc) 11 | 12 | 13 | void main(in VS_OUTPUT input) { 14 | 15 | } -------------------------------------------------------------------------------- /Assets/Shaders/Backend/ShadowMapVS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Common.hlsli" 2 | 3 | struct VS_OUTPUT 4 | { 5 | float4 position : SV_Position; 6 | }; 7 | 8 | FRAME_CONSTANTS(fc) 9 | ROOT_CONSTANTS(ShadowMapRootConstants, rc) 10 | 11 | VS_OUTPUT main(in uint inVertexID : SV_VertexID) 12 | { 13 | StructuredBuffer geometries = ResourceDescriptorHeap[fc.mInstancesBuffer]; 14 | RTGeometry geometry = geometries[rc.mInstanceIndex]; 15 | 16 | StructuredBuffer vertex_buffer = ResourceDescriptorHeap[geometry.mVertexBuffer]; 17 | RTVertex vertex = vertex_buffer[inVertexID]; 18 | 19 | TransformToWorldSpace(vertex, geometry.mWorldTransform); 20 | 21 | VS_OUTPUT output; 22 | 23 | output.position = mul(rc.mViewProjMatrix, float4(vertex.mPos, 1.0)); 24 | 25 | return output; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /Assets/Shaders/Backend/SkinningCS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Bindless.hlsli" 2 | #include "Include/Common.hlsli" 3 | 4 | ROOT_CONSTANTS(SkinningRootConstants, rc) 5 | 6 | [numthreads(64, 1, 1)] 7 | void main(uint3 dispatchThreadID : SV_DispatchThreadID, uint3 groupID : SV_GroupID, uint3 groupThreadID : SV_GroupThreadID, uint groupIndex : SV_GroupIndex) 8 | { 9 | StructuredBuffer bone_indices_buffer = ResourceDescriptorHeap[rc.mBoneIndicesBuffer]; 10 | StructuredBuffer bone_weights_buffer = ResourceDescriptorHeap[rc.mBoneWeightsBuffer]; 11 | StructuredBuffer bone_transforms_buffer = ResourceDescriptorHeap[rc.mBoneTransformsBuffer]; 12 | 13 | StructuredBuffer vertex_buffer = ResourceDescriptorHeap[rc.mMeshVertexBuffer]; 14 | RWStructuredBuffer skinned_vertex_buffer = ResourceDescriptorHeap[rc.mSkinnedVertexBuffer]; 15 | 16 | uint vertex_id = dispatchThreadID.x; 17 | if ( vertex_id > rc.mDispatchSize ) 18 | return; 19 | 20 | int4 bone = bone_indices_buffer[vertex_id]; 21 | float4 weight = bone_weights_buffer[vertex_id]; 22 | 23 | float4x4 bone_transform = bone_transforms_buffer[bone[0]] * weight[0]; 24 | bone_transform += bone_transforms_buffer[bone[1]] * weight[1]; 25 | bone_transform += bone_transforms_buffer[bone[2]] * weight[2]; 26 | bone_transform += bone_transforms_buffer[bone[3]] * weight[3]; 27 | 28 | RTVertex vertex = vertex_buffer[vertex_id]; 29 | vertex.mPos = mul(bone_transform, float4(vertex.mPos, 1.0)).xyz; 30 | vertex.mNormal = mul(bone_transform, float4(vertex.mNormal, 0.0)).xyz; 31 | vertex.mTangent = mul(bone_transform, float4(vertex.mTangent, 0.0)).xyz; 32 | 33 | skinned_vertex_buffer[vertex_id] = vertex; 34 | } 35 | -------------------------------------------------------------------------------- /Assets/Shaders/Backend/SkyCubeCS.hlsl: -------------------------------------------------------------------------------- 1 | #include "Include/Sky.hlsli" 2 | #include "Include/Common.hlsli" 3 | #include "Include/Bindless.hlsli" 4 | 5 | FRAME_CONSTANTS(fc) 6 | ROOT_CONSTANTS(SkyCubeRootConstants, rc) 7 | 8 | float3 GetCubemapDirection(float2 inUV, uint inFace) 9 | { 10 | float2 clip = inUV * 2.0 - 1.0; 11 | 12 | switch (inFace) 13 | { 14 | case 0: return float3(1.0, -clip.yx); 15 | case 1: return float3(-1.0, -clip.y, clip.x); 16 | case 2: return float3(clip.x, 1.0, clip.y); 17 | case 3: return float3(clip.x, -1.0, -clip.y); 18 | case 4: return float3(clip.x, -clip.y, 1.0); 19 | case 5: return float3(-clip, -1.0); 20 | } 21 | 22 | return 0.xxx; 23 | } 24 | 25 | [numthreads(8, 8, 1)] 26 | void main(uint3 gid : SV_DispatchThreadID) 27 | { 28 | RWTexture2DArray sky_cube_texture = ResourceDescriptorHeap[rc.mSkyCubeTexture]; 29 | 30 | uint width, height, layers; 31 | sky_cube_texture.GetDimensions(width, height, layers); 32 | 33 | float2 uv = (float2(gid.xy) + 0.5) / float2(width, height); 34 | float3 dir = GetCubemapDirection(uv, gid.z); 35 | 36 | float3 transmittance; 37 | sky_cube_texture[gid] = IntegrateScattering(0.xxx, normalize(-dir), INFINITY, rc.mSunLightDirection, rc.mSunLightColor.rgb, transmittance); 38 | } -------------------------------------------------------------------------------- /Assets/black4x4.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Assets/black4x4.dds -------------------------------------------------------------------------------- /Assets/camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Assets/camera.png -------------------------------------------------------------------------------- /Assets/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Assets/light.png -------------------------------------------------------------------------------- /Assets/normal4x4.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Assets/normal4x4.dds -------------------------------------------------------------------------------- /Assets/white4x4.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Assets/white4x4.dds -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | 3 | set(CMAKE_TOOLCHAIN_FILE "ThirdParty/vcpkg/scripts/buildsystems/vcpkg.cmake") 4 | set(VCPKG_TARGET_TRIPLET x64-windows-static) 5 | set(CMAKE_CONFIGURATION_TYPES "Debug;RelWithDebInfo;Release" CACHE STRING "" FORCE) 6 | 7 | project(Solution) 8 | 9 | find_package(lz4 CONFIG REQUIRED) 10 | find_package(SDL3 CONFIG REQUIRED) 11 | find_package(directx-headers REQUIRED) 12 | 13 | # Enable MSVC parallel build process 14 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP") 15 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") 16 | 17 | add_subdirectory(Code/Engine) 18 | add_subdirectory(Code/Editor) 19 | add_subdirectory(Code/Game) 20 | -------------------------------------------------------------------------------- /Code/Core.natvis: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{ length={length} }} 5 | 6 | length 7 | 8 | length 9 | start 10 | 11 | 12 | 13 | 14 | 15 | {{ Name = {m_Name}, Members : {m_Members.size()} }} 16 | 17 | 18 | 19 | {{ Name = {m_Name} }} 20 | 21 | 22 | -------------------------------------------------------------------------------- /Code/Editor/App.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Editor.h" 4 | #include "Widget.h" 5 | #include "Engine/scene.h" 6 | #include "Engine/assets.h" 7 | #include "Engine/physics.h" 8 | #include "Engine/Renderer/Device.h" 9 | #include "Engine/Renderer/Renderer.h" 10 | #include "Engine/Renderer/CommandList.h" 11 | #include "Engine/Renderer/RayTracedScene.h" 12 | #include "Editor/Widgets/ProfileWidget.h" 13 | 14 | namespace RK::DX12 { 15 | 16 | class DXApp : public Editor 17 | { 18 | public: 19 | DXApp(); 20 | ~DXApp(); 21 | 22 | virtual void OnUpdate(float inDeltaTime) override; 23 | virtual void OnEvent(const SDL_Event& inEvent) override; 24 | 25 | Device& GetDevice() { return m_Device; } 26 | Renderer& GetRenderer() { return m_Renderer; } 27 | RayTracedScene& GetRayTracedScene() { return m_RayTracedScene; } 28 | IRenderInterface* GetRenderInterface() { return &m_RenderInterface; } 29 | 30 | private: 31 | TextureID m_ImGuiFontTextureID; 32 | TextureID m_DefaultWhiteTexture; 33 | TextureID m_DefaultBlackTexture; 34 | TextureID m_DefaultNormalTexture; 35 | 36 | Device m_Device; 37 | Renderer m_Renderer; 38 | RayTracedScene m_RayTracedScene; 39 | RenderInterface m_RenderInterface; 40 | }; 41 | 42 | 43 | class DeviceResourcesWidget : public IWidget 44 | { 45 | public: 46 | RTTI_DECLARE_VIRTUAL_TYPE(DeviceResourcesWidget); 47 | 48 | DeviceResourcesWidget(Editor* inEditor) : IWidget(inEditor, "GPU Resources ") {} 49 | void Draw(Widgets* inWidgets, float inDeltaTime); 50 | void OnEvent(Widgets* inWidgets, const SDL_Event& inEvent) {} 51 | 52 | private: 53 | uint64_t m_BuffersTotalSize = 0; 54 | uint64_t m_TexturesTotalSize = 0; 55 | uint16_t m_BufferUsageFilter = 0xFFFF; 56 | uint16_t m_TextureUsageFilter = 0xFFFF; 57 | HashSet m_SeenResources; 58 | }; 59 | 60 | class GPUProfileWidget : public IWidget 61 | { 62 | public: 63 | RTTI_DECLARE_VIRTUAL_TYPE(GPUProfileWidget); 64 | 65 | GPUProfileWidget(Editor* inEditor) : IWidget(inEditor, "GPU Profiler ") {} 66 | void Draw(Widgets* inWidgets, float inDeltaTime); 67 | void OnEvent(Widgets* inWidgets, const SDL_Event& inEvent); 68 | 69 | private: 70 | float m_Zoom = 1.2f; 71 | String m_FilterInputBuffer; 72 | int m_SelectedSectionIndex = -1; 73 | }; 74 | 75 | } // namespace Raekor::DX12 -------------------------------------------------------------------------------- /Code/Editor/Assets/Icon/Icon.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Code/Editor/Assets/Icon/Icon.aps -------------------------------------------------------------------------------- /Code/Editor/Assets/Icon/Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Code/Editor/Assets/Icon/Icon.ico -------------------------------------------------------------------------------- /Code/Editor/Assets/Icon/Icon.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Code/Editor/Assets/Icon/Icon.rc -------------------------------------------------------------------------------- /Code/Editor/Assets/Icon/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Raekor.rc 4 | // 5 | #define IDI_ICON1 102 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 103 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /Code/Editor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | 3 | project(Editor C CXX) 4 | 5 | # Build a list of all cpp source files 6 | file(GLOB_RECURSE HppFiles ${PROJECT_SOURCE_DIR}/*.h ${Editor_SOURCE_DIR}/*Widget.h) 7 | file(GLOB_RECURSE CppFiles ${PROJECT_SOURCE_DIR}/*.cpp ${Editor_SOURCE_DIR}/*Widget.cpp) 8 | 9 | # Rule to build the actual exectuable and enable c++20 10 | add_executable(${PROJECT_NAME} ${CppFiles} ${HppFiles} Assets/Icon/Icon.rc) 11 | set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "Editor") 12 | target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20) 13 | 14 | # MSVC stuff for root working directory, static runtime and enabling precompiled headers 15 | set_property(TARGET ${PROJECT_NAME} PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}") 16 | set_property(TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") 17 | target_precompile_headers(${PROJECT_NAME} PRIVATE pch.h) 18 | 19 | target_link_libraries(${PROJECT_NAME} PRIVATE Engine) 20 | target_link_libraries(${PROJECT_NAME} PRIVATE Scripts) 21 | 22 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/ThirdParty/xess/bin/libxess.dll" $) 23 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/ThirdParty/DLSS/lib/Windows_x86_64/dev/nvngx_dlss.dll" $) 24 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/ThirdParty/dxc/dxil.dll" $) 25 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/ThirdParty/dxc/dxcompiler.dll" $) 26 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/ThirdParty/DirectStorage/dstorage.dll" $) 27 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/ThirdParty/DirectStorage/dstoragecore.dll" $) 28 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/ThirdParty/Agility-SDK/D3D12Core.dll" $) 29 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/ThirdParty/Agility-SDK/d3d12SDKLayers.dll" $) 30 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/ThirdParty/discord_game_sdk/lib/x86_64/discord_game_sdk.dll" $) 31 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/ThirdParty/PIX/bin/x64/WinPixEventRuntime.dll" $) 32 | 33 | # include dependency directories 34 | target_include_directories(${PROJECT_NAME} PUBLIC 35 | ${PROJECT_SOURCE_DIR} 36 | ${CMAKE_SOURCE_DIR}/Code 37 | ${CMAKE_SOURCE_DIR}/ThirdParty 38 | ${CMAKE_SOURCE_DIR}/ThirdParty/imgui 39 | ) -------------------------------------------------------------------------------- /Code/Editor/Editor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "GUI.h" 4 | #include "Undo.h" 5 | #include "Scene.h" 6 | #include "Assets.h" 7 | #include "Widget.h" 8 | #include "Physics.h" 9 | #include "Compiler.h" 10 | #include "Application.h" 11 | 12 | namespace RK { 13 | 14 | class Editor : public Game 15 | { 16 | struct Settings 17 | { 18 | float& scaleSnap = g_CVariables->Create("editor_scale_snap", 0.1f); 19 | float& rotationSnap = g_CVariables->Create("editor_rotation_snap", 1.0f); 20 | float& translationSnap = g_CVariables->Create("editor_translation_snap", 0.1f); 21 | } m_Settings; 22 | 23 | public: 24 | friend class IWidget; 25 | 26 | Editor(WindowFlags inWindowFlags, IRenderInterface* inRenderInterface); 27 | virtual ~Editor(); 28 | 29 | void OnUpdate(float dt) override; 30 | void OnEvent(const SDL_Event& event) override; 31 | 32 | Scene* GetScene() final { return &m_Scene; } 33 | Assets* GetAssets() final { return &m_Assets; } 34 | Physics* GetPhysics() final { return &m_Physics; } 35 | UndoSystem* GetUndo() final { return &m_UndoSystem; } 36 | 37 | void LogMessage(const String& inMessage) final; 38 | 39 | Settings& GetSettings() { return m_Settings; } 40 | const Settings& GetSettings() const { return m_Settings; } 41 | 42 | Camera& GetCamera() { return m_Camera; } 43 | const Camera& GetCamera() const { return m_Camera; } 44 | 45 | void SetCameraEntity(Entity inEntity) { m_CameraEntity = inEntity; } 46 | Entity GetCameraEntity() const { return m_CameraEntity; } 47 | 48 | void SetActiveEntity(Entity inEntity) final; 49 | Entity GetActiveEntity() const final { return m_ActiveEntity.load(); } 50 | 51 | ImGuiSelectionBasicStorage& GetMultiSelect() { return m_Selection; } 52 | const ImGuiSelectionBasicStorage& GetMultiSelect() const { return m_Selection; } 53 | 54 | bool GetViewportChanged() const { return m_ViewportChanged; } 55 | void SetViewportChanged(bool inChanged) { m_ViewportChanged = inChanged; } 56 | 57 | void BeginImGuiDockSpace(); 58 | void EndImGuiDockSpace(); 59 | 60 | protected: 61 | Scene m_Scene; 62 | Assets m_Assets; 63 | Physics m_Physics; 64 | Widgets m_Widgets; 65 | UndoSystem m_UndoSystem; 66 | IRenderInterface* m_RenderInterface; 67 | 68 | Camera m_Camera; 69 | Entity m_CameraEntity = Entity::Null; 70 | 71 | bool m_ViewportChanged = false; 72 | bool m_ViewportFullscreen = false; 73 | void* m_CompilerWindow = nullptr; 74 | void* m_CompilerProcess = nullptr; 75 | 76 | ImGuiID m_DockSpaceID; 77 | bool m_DockSpaceBuilt = false; 78 | 79 | Array m_Messages; 80 | Atomic m_ActiveEntity = Entity::Null; 81 | ImGuiSelectionBasicStorage m_Selection; 82 | 83 | 84 | }; 85 | 86 | 87 | } // Raekor -------------------------------------------------------------------------------- /Code/Editor/GUI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Engine/Scene.h" 4 | 5 | namespace RK { 6 | class Widgets; 7 | class Viewport; 8 | } 9 | 10 | struct ImVec2; 11 | struct ImVec4; 12 | typedef unsigned int ImU32; 13 | 14 | namespace RK::GUI { 15 | 16 | void BeginFrame(); 17 | void EndFrame(); 18 | 19 | void SetFont(const String& inFilePath); 20 | void SetDarkTheme(); 21 | 22 | IVec2 GetMousePosWindow(const Viewport& viewport, ImVec2 windowPos); 23 | 24 | 25 | } // namespace GUI 26 | 27 | 28 | namespace ImGui { 29 | 30 | // Full credit goes to https://github.com/ocornut/imgui/issues/1901 31 | bool Spinner(const char* label, float radius, int thickness, const ImU32& color); 32 | 33 | bool DragVec3(const char* label, glm::vec3& v, float step, float min, float max, const char* format = "%.2f"); 34 | 35 | void SetNextItemRightAlign(const char* label); 36 | 37 | bool DragDropTargetButton(const char* label, const char* text, bool hasvalue); 38 | 39 | } -------------------------------------------------------------------------------- /Code/Editor/Launcher.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Application.h" 4 | 5 | namespace RK { 6 | 7 | 8 | class SDL_Image 9 | { 10 | public: 11 | ~SDL_Image(); 12 | 13 | bool Load(SDL_Renderer* inRenderer, const Path& inPath); 14 | bool IsLoaded() const { return m_PixelData != nullptr; } 15 | 16 | uint8_t* GetPixels() const { return m_PixelData; } 17 | SDL_Surface* GetSurface() const { return m_Surface; } 18 | SDL_Texture* GetTexture() const { return m_Texture; } 19 | 20 | private: 21 | uint8_t* m_PixelData = nullptr; 22 | SDL_Surface* m_Surface = nullptr; 23 | SDL_Texture* m_Texture = nullptr; 24 | }; 25 | 26 | 27 | 28 | class Launcher : public Application 29 | { 30 | public: 31 | Launcher(); 32 | ~Launcher(); 33 | 34 | virtual void OnUpdate(float inDeltaTime) override; 35 | virtual void OnEvent(const SDL_Event& inEvent) override; 36 | 37 | bool ShouldLaunch() const { return !m_WasClosed; } 38 | 39 | private: 40 | int m_NrOfRows = 0; 41 | int m_ResizeCounter = 0; 42 | bool m_WasClosed = false; 43 | SDL_Image m_BgImage; 44 | SDL_Renderer* m_Renderer; 45 | HashSet m_SortedCvarNames; 46 | }; 47 | 48 | } -------------------------------------------------------------------------------- /Code/Editor/Widget.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Widget.h" 3 | #include "Editor.h" 4 | #include "Profiler.h" 5 | #include "Application.h" 6 | 7 | namespace RK { 8 | 9 | class Application; 10 | 11 | RTTI_DEFINE_TYPE_NO_FACTORY(IWidget) {} 12 | 13 | IWidget::IWidget(Editor* inEditor, const String& title) : 14 | m_Editor(inEditor), m_Title(title) 15 | { 16 | assert(m_Editor); 17 | } 18 | 19 | 20 | Entity IWidget::GetActiveEntity() 21 | { 22 | return m_Editor->GetActiveEntity(); 23 | } 24 | 25 | 26 | void IWidget::SetActiveEntity(Entity inEntity) 27 | { 28 | m_Editor->SetActiveEntity(inEntity); 29 | } 30 | 31 | 32 | Scene& IWidget::GetScene() 33 | { 34 | return *m_Editor->GetScene(); 35 | } 36 | 37 | 38 | Assets& IWidget::GetAssets() 39 | { 40 | return *m_Editor->GetAssets(); 41 | } 42 | 43 | 44 | Physics& IWidget::GetPhysics() 45 | { 46 | return *m_Editor->GetPhysics(); 47 | } 48 | 49 | 50 | IRenderInterface& IWidget::GetRenderInterface() 51 | { 52 | return *m_Editor->GetRenderInterface(); 53 | } 54 | 55 | 56 | void Widgets::Draw(float inDeltaTime) 57 | { 58 | PROFILE_FUNCTION_CPU(); 59 | 60 | for (const auto& widget : m_Widgets) 61 | { 62 | if (widget->IsOpen()) 63 | { 64 | PROFILE_SCOPE_CPU(widget->GetTitle().c_str()); 65 | 66 | ImGuiWindowClass window_class = {}; 67 | window_class.DockNodeFlagsOverrideSet = ImGuiDockNodeFlags_NoCloseButton; 68 | ImGui::SetNextWindowClass(&window_class); 69 | 70 | widget->Draw(this, inDeltaTime); 71 | } 72 | } 73 | } 74 | 75 | 76 | void Widgets::OnEvent(const SDL_Event& inEvent) 77 | { 78 | if (ImGui::GetIO().WantCaptureKeyboard) 79 | return; 80 | 81 | for (const auto& widget : m_Widgets) 82 | if (widget->IsOpen()) 83 | widget->OnEvent(this, inEvent); 84 | } 85 | 86 | } -------------------------------------------------------------------------------- /Code/Editor/Widget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ECS.h" 4 | #include "RTTI.h" 5 | 6 | namespace RK { 7 | 8 | class Editor; 9 | class Scene; 10 | class Assets; 11 | class Physics; 12 | class Widgets; 13 | class IRenderInterface; 14 | class Application; 15 | 16 | class IWidget 17 | { 18 | RTTI_DECLARE_VIRTUAL_TYPE(IWidget); 19 | 20 | public: 21 | IWidget(Editor* inEditor, const String& inTitle); 22 | virtual void Draw(Widgets* inWidgets, float inDeltaTime) = 0; 23 | virtual void OnEvent(Widgets* inWidgets, const SDL_Event& inEvent) = 0; 24 | 25 | void Show() { m_PrevOpen = m_Open; m_Open = true; } 26 | void Hide() { m_PrevOpen = m_Open; m_Open = false; } 27 | void Restore() { m_Open = m_PrevOpen; } 28 | 29 | bool IsOpen() { return m_Open; } 30 | bool IsVisible() { return m_Visible; } 31 | bool IsFocused() { return m_Focused; } 32 | 33 | const String& GetTitle() { return m_Title; } 34 | 35 | protected: 36 | // Need to be defined in the cpp to avoid circular dependencies 37 | Scene& GetScene(); 38 | Assets& GetAssets(); 39 | Physics& GetPhysics(); 40 | IRenderInterface& GetRenderInterface(); 41 | 42 | Entity GetActiveEntity(); 43 | void SetActiveEntity(Entity inEntity); 44 | 45 | Editor* m_Editor; 46 | String m_Title; 47 | bool m_Open = true; 48 | bool m_PrevOpen = true; 49 | bool m_Visible = false; 50 | bool m_Focused = false; 51 | }; 52 | 53 | 54 | class Widgets 55 | { 56 | public: 57 | 58 | template 59 | T* Register(Editor* inEditor) 60 | { 61 | static_assert( std::is_base_of() ); 62 | m_Widgets.emplace_back(std::make_shared(inEditor)); 63 | return std::static_pointer_cast( m_Widgets.back() ).get(); 64 | } 65 | 66 | template 67 | T* GetWidget() 68 | { 69 | for (const auto& widget : m_Widgets) 70 | if (widget->GetRTTI() == RTTI_OF()) 71 | return std::static_pointer_cast( widget ).get(); 72 | 73 | return nullptr; 74 | } 75 | 76 | void Draw(float inDeltaTime); 77 | void OnEvent(const SDL_Event& inEvent); 78 | 79 | auto begin() { return m_Widgets.begin(); } 80 | auto end() { return m_Widgets.end(); } 81 | 82 | private: 83 | Array> m_Widgets; 84 | }; 85 | 86 | } 87 | -------------------------------------------------------------------------------- /Code/Editor/Widgets/AssetsWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Widget.h" 4 | #include "CVars.h" 5 | 6 | namespace RK { 7 | 8 | class Editor; 9 | class Material; 10 | class Animation; 11 | 12 | class MaterialsWidget : public IWidget 13 | { 14 | RTTI_DECLARE_VIRTUAL_TYPE(MaterialsWidget); 15 | 16 | public: 17 | MaterialsWidget(Editor* inEditor); 18 | 19 | virtual void Draw(Widgets* inWidgets, float dt) override; 20 | virtual void OnEvent(Widgets* inWidgets, const SDL_Event& ev) override {} 21 | 22 | void UpdateLayoutSizes(float inAvailableWidth); 23 | 24 | private: 25 | float m_IconSize = 56.0f; 26 | int m_IconSpacing = 10; 27 | int m_IconHitSpacing = 4; 28 | bool m_StretchSpacing = true; 29 | float m_ZoomWheelAccum = 0.0f; 30 | ImVec2 m_LayoutItemSize; 31 | ImVec2 m_LayoutItemStep; 32 | int m_LayoutLineCount = 0; 33 | int m_LayoutColumnCount = 0; 34 | float m_LayoutItemSpacing = 0.0f; 35 | float m_LayoutOuterPadding = 0.0f; 36 | float m_LayoutSelectableSpacing = 0.0f; 37 | }; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Code/Editor/Widgets/ConsoleWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Widget.h" 4 | 5 | namespace RK { 6 | 7 | class Editor; 8 | 9 | class ConsoleWidget : public IWidget 10 | { 11 | public: 12 | RTTI_DECLARE_VIRTUAL_TYPE(ConsoleWidget); 13 | 14 | ConsoleWidget(Editor* inEditor); 15 | virtual void Draw(Widgets* inWidgets, float inDeltaTime) override; 16 | virtual void OnEvent(Widgets* inWidgets, const SDL_Event& inEvent) override {} 17 | 18 | void LogMessage(const String& inMessage); 19 | 20 | private: 21 | static int sEditCallback(ImGuiInputTextCallbackData* data); 22 | 23 | public: 24 | int m_ActiveItem = 0; 25 | bool m_ShouldScrollToBottom = false; 26 | 27 | String m_InputBuffer = ""; 28 | std::mutex m_ItemsMutex; 29 | Array m_Items; 30 | }; 31 | 32 | } // raekor -------------------------------------------------------------------------------- /Code/Editor/Widgets/HierarchyWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Widget.h" 4 | 5 | namespace RK { 6 | 7 | class Editor; 8 | 9 | class HierarchyWidget : public IWidget 10 | { 11 | public: 12 | RTTI_DECLARE_VIRTUAL_TYPE(HierarchyWidget); 13 | 14 | HierarchyWidget(Editor* inEditor); 15 | virtual void Draw(Widgets* inWidgets, float inDeltaTime) override; 16 | virtual void OnEvent(Widgets* inWidgets, const SDL_Event& inEvent) override; 17 | 18 | private: 19 | void DropTargetWindow(Scene& inScene); 20 | void DropTargetNode(Scene& inScene, Entity inEntity); 21 | 22 | void DrawFamily(Scene& inScene, Entity inParent); 23 | bool DrawFamilyNode(Scene& inScene, Entity inEntity); 24 | void DrawChildlessNode(Scene& inScene, Entity inEntity); 25 | 26 | String m_Filter = ""; 27 | Entity m_EntityClicked = Entity::Null; 28 | }; 29 | 30 | } -------------------------------------------------------------------------------- /Code/Editor/Widgets/InspectorWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Widget.h" 4 | #include "Editor.h" 5 | #include "Undo.h" 6 | 7 | namespace RK { 8 | 9 | class RTTI; 10 | class Scene; 11 | class Camera; 12 | class Editor; 13 | class Animation; 14 | 15 | struct Name; 16 | struct Mesh; 17 | struct Skeleton; 18 | struct SoftBody; 19 | struct Material; 20 | struct Transform; 21 | struct Light; 22 | struct RigidBody; 23 | struct NativeScript; 24 | struct DirectionalLight; 25 | struct DDGISceneSettings; 26 | 27 | class InspectorWidget : public IWidget 28 | { 29 | public: 30 | RTTI_DECLARE_VIRTUAL_TYPE(InspectorWidget); 31 | 32 | InspectorWidget(Editor* inEditor); 33 | virtual void Draw(Widgets* inWidgets, float inDeltaTime) override; 34 | virtual void OnEvent(Widgets* inWidgets, const SDL_Event& inEvent) override {} 35 | 36 | bool SceneChanged() const { return m_SceneChanged; } 37 | 38 | private: 39 | void DrawJSONInspector(Widgets* inWidgets); 40 | bool DrawEntityInspector(Widgets* inWidgets); 41 | void DrawKeyFrameInspector(Widgets* inWidgets); 42 | 43 | void DrawScriptMember(const char* inLabel, int& ioValue); 44 | void DrawScriptMember(const char* inLabel, bool& ioValue); 45 | void DrawScriptMember(const char* inLabel, float& ioValue); 46 | void DrawScriptMember(const char* inLabel, Entity& ioValue); 47 | 48 | bool DrawComponent(Entity inEntity, Name& ioName); 49 | bool DrawComponent(Entity inEntity, Mesh& ioMesh); 50 | bool DrawComponent(Entity inEntity, Light& ioLight); 51 | bool DrawComponent(Entity inEntity, Camera& ioCamera); 52 | bool DrawComponent(Entity inEntity, SoftBody& ioSoftBody); 53 | bool DrawComponent(Entity inEntity, Skeleton& ioSkeleton); 54 | bool DrawComponent(Entity inEntity, Material& ioMaterial); 55 | bool DrawComponent(Entity inEntity, Transform& ioTransform); 56 | bool DrawComponent(Entity inEntity, Animation& ioAnimation); 57 | bool DrawComponent(Entity inEntity, RigidBody& ioBoxCollider); 58 | bool DrawComponent(Entity inEntity, NativeScript& ioNativeScript); 59 | bool DrawComponent(Entity inEntity, DirectionalLight& ioDirectionalLight); 60 | bool DrawComponent(Entity inEntity, DDGISceneSettings& ioDDGISceneSettings); 61 | 62 | template 63 | void CheckForUndo(Entity inEntity, T& inComponent, ComponentUndo& inUndo); 64 | 65 | private: 66 | bool m_SceneChanged = false; 67 | ComponentUndo m_NameUndo; 68 | ComponentUndo m_LightUndo; 69 | ComponentUndo m_CameraUndo; 70 | ComponentUndo m_MaterialUndo; 71 | ComponentUndo m_TransformUndo; 72 | ComponentUndo m_DirectionalLightUndo; 73 | ComponentUndo m_DDGISceneSettingsUndo; 74 | }; 75 | 76 | template 77 | void InspectorWidget::CheckForUndo(Entity inEntity, T& inComponent, ComponentUndo& inUndo) 78 | { 79 | if (ImGui::IsItemActivated()) 80 | { 81 | inUndo.entity = inEntity; 82 | inUndo.previous = inComponent; 83 | } 84 | 85 | if (ImGui::IsItemDeactivatedAfterEdit()) 86 | { 87 | inUndo.current = inComponent; 88 | m_Editor->GetUndo()->PushUndo(inUndo); 89 | } 90 | } 91 | 92 | } 93 | 94 | -------------------------------------------------------------------------------- /Code/Editor/Widgets/MenubarWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "widget.h" 4 | 5 | namespace RK { 6 | 7 | class Scene; 8 | class Editor; 9 | 10 | class MenubarWidget : public IWidget 11 | { 12 | RTTI_DECLARE_VIRTUAL_TYPE(MenubarWidget); 13 | public: 14 | 15 | MenubarWidget(Editor* inEditor); 16 | virtual void Draw(Widgets* inWidgets, float dt) override; 17 | virtual void OnEvent(Widgets* inWidgets, const SDL_Event& ev) override {} 18 | }; 19 | 20 | } -------------------------------------------------------------------------------- /Code/Editor/Widgets/NodeGraphWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Widget.h" 4 | #include "ShaderGraph.h" 5 | 6 | namespace RK { 7 | 8 | class Editor; 9 | 10 | class ShaderGraphWidget : public IWidget 11 | { 12 | public: 13 | RTTI_DECLARE_VIRTUAL_TYPE(ShaderGraphWidget); 14 | 15 | struct EditingContext 16 | { 17 | Array SelectedNodes; 18 | Array SelectedLinks; 19 | Pair HoveredNode = std::make_pair(false, -1); 20 | Pair hoveredLink = std::make_pair(false, -1); 21 | }; 22 | 23 | ShaderGraphWidget(Editor* inEditor); 24 | 25 | virtual void Draw(Widgets* inWidgets, float dt) override; 26 | virtual void OnEvent(Widgets* inWidgets, const SDL_Event& ev) override; 27 | 28 | void SetActiveShaderGraph(EShaderGraph inShaderGraph); 29 | 30 | private: 31 | String m_GeneratedCode; 32 | bool m_ShowGeneratedCode = false; 33 | 34 | int m_DroppedLinkID = -1; 35 | ImVec2 m_ClickedMousePos = ImVec2(0, 0); 36 | int m_StartNodeID = -1, m_StartPinID = -1; 37 | int m_EndNodeID = -1, m_EndPinID = -1; 38 | 39 | Path m_OpenFilePath; 40 | Path m_OpenTemplateFilePath; 41 | Path m_OpenGeneratedFilePath; 42 | 43 | EShaderGraph m_ActiveGraph = SHADER_GRAPH_PIXEL; 44 | StaticArray m_Contexts; 45 | StaticArray m_Builders; 46 | StaticArray m_ImNodesContexts; 47 | 48 | EditingContext& m_Context = m_Contexts[m_ActiveGraph]; 49 | ShaderGraphBuilder& m_Builder = m_Builders[m_ActiveGraph]; 50 | ImNodesEditorContext& m_ImNodesContext = m_ImNodesContexts[m_ActiveGraph]; 51 | }; 52 | 53 | } -------------------------------------------------------------------------------- /Code/Editor/Widgets/ProfileWidget.cpp: -------------------------------------------------------------------------------- 1 | #include "PCH.h" 2 | #include "ProfileWidget.h" 3 | 4 | #include "Timer.h" 5 | #include "Editor.h" 6 | #include "Profiler.h" 7 | #include "Application.h" 8 | 9 | namespace RK { 10 | 11 | RTTI_DEFINE_TYPE_NO_FACTORY(ProfileWidget) {} 12 | 13 | 14 | ProfileWidget::ProfileWidget(Editor* inEditor) : IWidget(inEditor, reinterpret_cast( ICON_FA_RULER " Profiler " )) {} 15 | 16 | 17 | void ProfileWidget::Draw(Widgets* inWidgets, float inDeltaTime) 18 | { 19 | ImGui::Begin(m_Title.c_str(), &m_Open); 20 | m_Visible = ImGui::IsWindowAppearing(); 21 | 22 | for (const CPUProfileSection& section : g_Profiler->GetCPUProfileSections()) 23 | { 24 | assert(section.mEndTick); // make sure we're displaying profiled sections have actually finished 25 | 26 | const float time = Timer::sGetTicksToSeconds(section.mEndTick - section.mStartTick); 27 | 28 | for (int depth = 0; depth < section.mDepth; depth++) 29 | { 30 | ImGui::Text(" "); 31 | ImGui::SameLine(); 32 | } 33 | 34 | ImGui::Text("%s : %.2f ms", section.mName, Timer::sToMilliseconds(section.GetSeconds())); 35 | } 36 | 37 | ImGui::End(); 38 | } 39 | 40 | 41 | void ProfileWidget::OnEvent(Widgets* inWidgets, const SDL_Event& inEvent) 42 | { 43 | if (inEvent.type == SDL_EVENT_KEY_DOWN && !inEvent.key.repeat) 44 | { 45 | switch (inEvent.key.key) 46 | { 47 | case SDLK_SPACE: 48 | { 49 | g_Profiler->SetEnabled(!g_Profiler->IsEnabled()); 50 | } break; 51 | } 52 | } 53 | } 54 | 55 | } // raekor -------------------------------------------------------------------------------- /Code/Editor/Widgets/ProfileWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Widget.h" 4 | #include "Timer.h" 5 | 6 | namespace RK { 7 | 8 | class RTTI; 9 | class Editor; 10 | class Application; 11 | 12 | class ProfileWidget : public IWidget 13 | { 14 | public: 15 | RTTI_DECLARE_VIRTUAL_TYPE(ProfileWidget); 16 | 17 | ProfileWidget(Editor* inEditor); 18 | void Draw(Widgets* inWidgets, float inDeltaTime) override; 19 | void OnEvent(Widgets* inWidgets, const SDL_Event& inEvent) override; 20 | }; 21 | 22 | } // raekor -------------------------------------------------------------------------------- /Code/Editor/Widgets/SequenceWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Widget.h" 4 | #include "Camera.h" 5 | #include "Animation.h" 6 | #include "Components.h" 7 | 8 | namespace RK { 9 | 10 | enum SequenceState 11 | { 12 | SEQUENCE_STOPPED = 0, 13 | SEQUENCE_PAUSED, 14 | SEQUENCE_PLAYING 15 | }; 16 | 17 | class Sequence 18 | { 19 | public: 20 | struct KeyFrame 21 | { 22 | KeyFrame() = default; 23 | KeyFrame(float inTime, Vec3 inScale, Quat inRot, Vec3 inPos) : mTime(inTime), mScale(inScale), mRotation(inRot), mPosition(inPos) {} 24 | 25 | float mTime = 0.0f; 26 | Vec3 mScale = {}; 27 | Quat mRotation = {}; 28 | Vec3 mPosition = {}; 29 | }; 30 | 31 | void AddKeyFrame(const KeyFrame& inKeyFrame, float inTime); 32 | void AddKeyFrame(const Transform& inTransform, float inTime); 33 | void RemoveKeyFrame(uint32_t inIndex); 34 | 35 | uint32_t GetKeyFrameCount() const { return m_KeyFrames.size(); } 36 | const Array& GetKeyFrames() const { return m_KeyFrames; } 37 | 38 | KeyFrame& GetKeyFrame(uint32_t inIndex) { return m_KeyFrames[inIndex]; } 39 | const KeyFrame& GetKeyFrame(uint32_t inIndex) const { return m_KeyFrames[inIndex]; } 40 | 41 | private: 42 | Array m_KeyFrames; 43 | }; 44 | 45 | class SequenceWidget : public IWidget 46 | { 47 | public: 48 | RTTI_DECLARE_VIRTUAL_TYPE(SequenceWidget); 49 | 50 | static constexpr float cIncrSequence = 1.0f; 51 | static constexpr float cMinSequenceLength = 1.0f; 52 | static constexpr float cMaxSequenceLength = 60.0f; 53 | 54 | SequenceWidget(Editor* inEditor); 55 | 56 | virtual void Draw(Widgets* inWidgets, float dt) override; 57 | virtual void OnEvent(Widgets* inWidgets, const SDL_Event& ev) override; 58 | 59 | int GetSelectedKeyFrame() const { return m_SelectedKeyframe; } 60 | 61 | void ApplyAnimationToScene(Scene& inScene); 62 | void RemoveAnimationFromScene(Scene& inScene); 63 | 64 | Sequence& GetSequence(Entity inEntity) { return m_Sequences[inEntity]; } 65 | const Sequence& GetSequence(Entity inEntity) const { return m_Sequences.at(inEntity); } 66 | 67 | float GetDuration() const { return m_Duration; } 68 | void SetDuration(float inSeconds) { m_Duration = inSeconds; } 69 | 70 | private: 71 | bool DrawTimeline(const char* inLabel, float& inTime, const float inMinTime, const float inMaxTime); 72 | 73 | private: 74 | float m_Time = 0.0f; 75 | float m_Speed = 1.0f; 76 | float m_Duration = 15.0f; 77 | String m_OpenFile = ""; 78 | int m_SelectedKeyframe = -1; 79 | bool m_LockedToCamera = false; 80 | bool m_IsDraggingKeyframe = false; 81 | SequenceState m_State = SEQUENCE_STOPPED; 82 | Entity m_ActiveAnimationEntity = Entity::Null; 83 | HashMap m_Sequences; 84 | 85 | }; 86 | 87 | } -------------------------------------------------------------------------------- /Code/Editor/Widgets/ViewportWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Widget.h" 4 | #include "CVars.h" 5 | #include "Undo.h" 6 | 7 | namespace RK { 8 | 9 | class Editor; 10 | 11 | struct ClickableQuad 12 | { 13 | Entity mEntity; 14 | std::array mVertices; 15 | }; 16 | 17 | class ViewportWidget : public IWidget 18 | { 19 | static constexpr ImVec4 cRunningColor = ImVec4(0.00f, 1.00f, 0.00f, 1.00f); 20 | static constexpr ImVec4 cPausedColor = ImVec4(0.35f, 0.78f, 1.00f, 1.00f); 21 | static constexpr ImVec4 cStoppedColor = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); 22 | 23 | public: 24 | RTTI_DECLARE_VIRTUAL_TYPE(ViewportWidget); 25 | 26 | ViewportWidget(Editor* inEditor); 27 | virtual void Draw(Widgets* inWidgets, float dt) override; 28 | virtual void OnEvent(Widgets* inWidgets, const SDL_Event& ev) override; 29 | 30 | bool Changed() const { return m_Changed; } 31 | bool IsHovered() const { return m_IsMouseOver; } 32 | void DisableGizmo() { m_IsGizmoEnabled = false; } 33 | 34 | protected: 35 | void AddClickableQuad(const Viewport& inViewport, Entity inEntity, ImTextureID inTexture, Vec3 inPos, float inSize); 36 | 37 | float m_TotalTime = 0; 38 | bool m_Changed = false; 39 | 40 | int m_RenderTargetIndex = 0; 41 | uint64_t m_DisplayTexture = 0; 42 | 43 | bool m_IsMouseOver = false; 44 | bool m_IsGizmoEnabled = true; 45 | bool m_IsUsingGizmo = false; 46 | bool m_WasUsingGizmo = false; 47 | 48 | ImVec2 m_WindowPos; 49 | ImVec2 m_WindowSize; 50 | 51 | ComponentUndo m_TransformUndo; 52 | ImGuizmo::OPERATION m_GizmoOperation = ImGuizmo::OPERATION::TRANSLATE; 53 | 54 | std::vector m_EntityQuads; 55 | }; 56 | 57 | } // raekor -------------------------------------------------------------------------------- /Code/Editor/main.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "App.h" 3 | #include "Launcher.h" 4 | #include "Compiler.h" 5 | #include "Engine/OS.h" 6 | #include "Engine/ecs.h" 7 | #include "Engine/timer.h" 8 | 9 | using namespace RK; 10 | 11 | int main(int argc, char** argv) 12 | { 13 | g_CVariables = new CVariables(argc, argv); 14 | 15 | bool should_launch = true; 16 | bool is_asset_compiler = OS::sCheckCommandLineOption("-asset_compiler"); 17 | 18 | if (g_CVariables->Create("enable_launcher", 0) && !is_asset_compiler) 19 | { 20 | Launcher launcher; 21 | launcher.Run(); 22 | 23 | should_launch = launcher.ShouldLaunch(); 24 | } 25 | 26 | if (!should_launch) 27 | return 0; 28 | 29 | Timer timer; 30 | 31 | Application* app = nullptr; 32 | 33 | if (is_asset_compiler) 34 | app = new CompilerApp(IsDebuggerPresent() ? WindowFlag::NONE : WindowFlag::HIDDEN); 35 | else 36 | app = new DX12::DXApp(); 37 | 38 | app->LogMessage(std::format("[App] App creation took {:.2f} seconds", timer.GetElapsedTime())); 39 | 40 | app->Run(); 41 | 42 | delete app; 43 | delete g_CVariables; 44 | 45 | return 0; 46 | } -------------------------------------------------------------------------------- /Code/Editor/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "PCH.h" -------------------------------------------------------------------------------- /Code/Editor/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Engine/PCH.h" 4 | 5 | ///////////////// 6 | // ImGui library 7 | #ifndef IMGUI_DEFINE_MATH_OPERATORS 8 | #define IMGUI_DEFINE_MATH_OPERATORS 9 | #endif 10 | #include "imgui/imconfig.h" 11 | #include "imgui/imgui.h" 12 | #include "imgui/imgui_internal.h" 13 | #include "imgui/misc/cpp/imgui_stdlib.h" 14 | #include "imgui/backends/imgui_impl_sdl3.h" 15 | #include "imgui/backends/imgui_impl_sdlrenderer3.h" 16 | 17 | ///////////////// 18 | // ImGuizmo library 19 | #include "ImGuizmo.h" 20 | 21 | ///////////////// 22 | // ImNodes library 23 | #include "imnodes.h" 24 | #include "imnodes_internal.h" 25 | 26 | ///////////////// 27 | // FontAwesome 5 Icons 28 | #include "IconsFontAwesome5.h" 29 | -------------------------------------------------------------------------------- /Code/Engine/Assimp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef DEPRECATE_ASSIMP 4 | 5 | #include "scene.h" 6 | 7 | namespace Assimp { 8 | 9 | glm::mat4 toMat4(const aiMatrix4x4& from); 10 | 11 | } // assimp 12 | 13 | namespace RK { 14 | 15 | class Scene; 16 | class Async; 17 | class Assets; 18 | class IRenderer; 19 | 20 | class Mesh; 21 | class Material; 22 | class Skeleton; 23 | 24 | class AssimpImporter : public Importer 25 | { 26 | public: 27 | AssimpImporter(Scene& inScene, IRenderer* inRenderer) : Importer(inScene, inRenderer) {} 28 | bool LoadFromFile(const std::string& inFile, Assets* inAssets) override; 29 | 30 | private: 31 | void ParseMaterial(aiMaterial* inAssimpMaterial, Entity inEntity); 32 | void ParseNode(const aiNode* inAssimpNode, Entity inEntity, Entity inParent); 33 | void ParseMeshes(const aiNode* inAssimpNode, Entity inEntity, Entity inParent); 34 | 35 | void LoadMesh(Entity inEntity, const aiMesh* inAssimpMesh); 36 | void LoadBones(Entity inEntity, const aiMesh* inAssimpMesh); 37 | void LoadMaterial(Entity inEntity, const aiMaterial* inAssimpMaterial); 38 | 39 | private: 40 | Path m_Directory; 41 | const aiScene* m_AiScene = nullptr; 42 | std::shared_ptr m_Importer; 43 | std::vector m_Materials; 44 | }; 45 | 46 | } // raekor 47 | 48 | #endif // DEPRECATE_ASSIMP 49 | -------------------------------------------------------------------------------- /Code/Engine/CVars.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PCH.h" 4 | #include "RTTI.h" 5 | 6 | namespace RK { 7 | 8 | enum CVarKind 9 | { 10 | CVAR_TYPE_NONE, 11 | CVAR_TYPE_INT, 12 | CVAR_TYPE_FLOAT, 13 | CVAR_TYPE_STRING, 14 | CVAR_TYPE_FUNCTION 15 | }; 16 | 17 | class CVar 18 | { 19 | RTTI_DECLARE_TYPE(CVar); 20 | using Function = std::function; 21 | 22 | public: 23 | CVar() : mType(CVAR_TYPE_NONE) {} 24 | CVar(int inValue) : mType(CVAR_TYPE_INT), mIntValue(inValue) {} 25 | CVar(float inValue) : mType(CVAR_TYPE_FLOAT), mFloatValue(inValue) {} 26 | CVar(const String& inValue) : mType(CVAR_TYPE_STRING), mStringValue(inValue) {} 27 | CVar(const Function& inValue) : mType(CVAR_TYPE_FUNCTION), mFunctionValue(inValue) {} 28 | 29 | template T& GetValue(); 30 | template<> int& GetValue() { return mIntValue; } 31 | template<> float& GetValue() { return mFloatValue; } 32 | template<> String& GetValue() { return mStringValue; } 33 | template<> Function& GetValue() { return mFunctionValue; } 34 | 35 | String ToString() const; 36 | bool SetValue(const String& inValue); 37 | 38 | public: 39 | CVarKind mType; 40 | int mIntValue = 0; 41 | float mFloatValue = 0; 42 | String mStringValue; 43 | Function mFunctionValue; // not serialized 44 | }; 45 | 46 | 47 | class CVariables 48 | { 49 | RTTI_DECLARE_TYPE(CVariables); 50 | 51 | public: 52 | CVariables() = default; 53 | CVariables(int argc, char** argv); 54 | ~CVariables(); 55 | 56 | bool Exists(const String& inName) const; 57 | 58 | String GetValue(const String& inName) const; 59 | 60 | template 61 | inline T& Create(const String& inName, T inValue, bool inForce = false); 62 | 63 | void CreateFn(const String& inName, CVar::Function fn); 64 | 65 | template 66 | inline T& GetValue(const String& inName); 67 | 68 | CVar& GetCVar(const String& inName); 69 | 70 | template 71 | inline T* TryGetValue(const String& inName); 72 | 73 | bool SetValue(const String& inName, const String& inValue); 74 | 75 | size_t GetCount() const { return m_ConVars.size(); } 76 | const HashMap& GetCVars() const { return m_ConVars; } 77 | 78 | private: 79 | HashMap m_ConVars; 80 | }; 81 | 82 | template 83 | inline T& CVariables::Create(const std::string& inName, T value, bool force) 84 | { 85 | if (m_ConVars.find(inName) == m_ConVars.end() || force) 86 | m_ConVars[inName] = CVar(value); 87 | 88 | return m_ConVars[inName].GetValue(); 89 | } 90 | 91 | template 92 | inline T& CVariables::GetValue(const std::string& inName) 93 | { 94 | return m_ConVars[inName].GetValue(); 95 | } 96 | 97 | template 98 | inline T* CVariables::TryGetValue(const std::string& inName) 99 | { 100 | if (m_ConVars.find(inName) == m_ConVars.end()) 101 | return nullptr; 102 | 103 | return &m_ConVars[inName].GetValue(); 104 | } 105 | 106 | inline CVariables* g_CVariables = nullptr; 107 | 108 | } // raekor 109 | -------------------------------------------------------------------------------- /Code/Engine/DDS.cpp: -------------------------------------------------------------------------------- 1 | #include "PCH.h" 2 | #include "DDS.h" 3 | 4 | namespace dds { 5 | 6 | } // raekor -------------------------------------------------------------------------------- /Code/Engine/DDS.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Code/Engine/DDS.h -------------------------------------------------------------------------------- /Code/Engine/DebugRenderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace RK { 4 | 5 | class DebugRenderer 6 | { 7 | public: 8 | static constexpr Vec4 cDefaultLineColor = Vec4(0.85, 0.3f, 0.1f, 1.0f); 9 | static constexpr Vec4 cDefaultFillColor = Vec4(0.85, 0.3f, 0.1f, 1.0f); 10 | 11 | // line shapes 12 | void AddLine(const Vec3& inStart, const Vec3& inEnd, const Vec4& inColor = cDefaultLineColor); 13 | 14 | void AddLineCube(const Vec3& inMin, const Vec3& inMax, const Mat4x4& inTransform = Mat4x4(1.0f), const Vec4& inColor = cDefaultLineColor); 15 | void AddLineCone(const Vec3& inPos, const Vec3& inDir, float inLength, float inAngle, const Vec4& inColor = cDefaultLineColor); 16 | 17 | void AddLineSphere(const Vec3& inPos, float inRadius, const Vec4& inColor = cDefaultLineColor); 18 | void AddLineCircle(const Vec3& inPos, float inRadius, const Vec3& inDir, const Vec3& inAxis, const Vec4& inColor = cDefaultLineColor); 19 | void AddLineArrow(const Vec3& inPos, const Vec3& inDir, float inLength, float inExtent, const Vec4& inColor = cDefaultLineColor); 20 | 21 | // filled shapes 22 | void AddQuadColored(const Vec3& inV0, const Vec3& inV1, const Vec3& inV2, const Vec3& inV3, const Vec4& inColor = cDefaultFillColor); 23 | void AddQuadTextured(const Vec3& inV0, const Vec3& inV1, const Vec3& inV2, const Vec3& inV3, uint64_t inTexture); 24 | 25 | void AddCubeColored(const Vec3& inMin, const Vec3& inMax, const Vec4& inColor = cDefaultFillColor); 26 | 27 | void Reset(); // call once per frame as early as possible, will clear data!! 28 | 29 | Slice GetLinesToRender() const { return Slice(m_RenderLines); } 30 | Slice GetTrianglesToRender() const { return Slice(m_RenderTriangles); } 31 | 32 | private: 33 | Array m_RenderLines; // xyz = pos, w = packed color 34 | Array m_RenderTriangles; // xyz = pos, w = packed color or texture index 35 | }; 36 | 37 | extern DebugRenderer g_DebugRenderer; 38 | 39 | } -------------------------------------------------------------------------------- /Code/Engine/Defines.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define ALIGN(x) __declspec(align(x)) 4 | 5 | #define RK_ASSERT(cond) assert(cond) 6 | 7 | #ifndef TOKENPASTE 8 | #define TOKENPASTE(x, y) x ## y 9 | #endif 10 | 11 | #ifndef TOKENPASTE2 12 | #define TOKENPASTE2(x, y) TOKENPASTE(x, y) 13 | #endif 14 | 15 | #define COUT_NC "\033[0m" 16 | #define COUT_RED(str) "\033[0;31m" str COUT_NC 17 | #define COUT_GREEN(str) "\033[1;32m" str COUT_NC 18 | 19 | #define LOG_CATCH(code) try { code; } catch(std::exception e) { std::cout << e.what() << '\n'; } 20 | 21 | #ifndef PRAGMA_OPTIMIZE_OFF 22 | #define PRAGMA_OPTIMIZE_OFF __pragma( optimize( "", off ) ) 23 | #endif 24 | 25 | #ifndef PRAGMA_OPTIMIZE_ON 26 | #define PRAGMA_OPTIMIZE_ON __pragma( optimize( "", on ) ) 27 | #endif 28 | 29 | #define NO_COPY_NO_MOVE(Type) \ 30 | Type(Type&) = delete; \ 31 | Type(Type&&) = delete; \ 32 | Type& operator=(Type&) = delete; \ 33 | Type& operator=(Type&&) = delete \ 34 | 35 | #define TEXTURE_SWIZZLE_RGBA 0b11'10'01'00 36 | #define TEXTURE_SWIZZLE_RRRR 0b00'00'00'00 37 | #define TEXTURE_SWIZZLE_GGGG 0b01'01'01'01 38 | #define TEXTURE_SWIZZLE_BBBB 0b10'10'10'10 39 | #define TEXTURE_SWIZZLE_AAAA 0b11'11'11'11 40 | 41 | 42 | -------------------------------------------------------------------------------- /Code/Engine/DiscordRPC.cpp: -------------------------------------------------------------------------------- 1 | #include "PCH.h" 2 | #include "DiscordRPC.h" 3 | #include "discord.h" 4 | #include "Application.h" 5 | #include "Timer.h" 6 | 7 | namespace RK { 8 | 9 | bool DiscordRPC::Init(Application* inApp) 10 | { 11 | discord::Result result = discord::Core::Create(1322276781851672647, DiscordCreateFlags_NoRequireDiscord, &m_Core); 12 | 13 | if (result != discord::Result::Ok) 14 | return false; 15 | 16 | m_Core->SetLogHook(discord::LogLevel::Debug, [inApp](discord::LogLevel level, const char* message) 17 | { 18 | inApp->LogMessage(std::format("[Discord] {}", message)); 19 | }); 20 | 21 | m_Activity = new discord::Activity(); 22 | m_Activity->SetType(discord::ActivityType::Playing); 23 | m_Activity->GetTimestamps().SetStart(std::chrono::duration_cast( 24 | std::chrono::system_clock::now().time_since_epoch() ).count()); 25 | 26 | m_Core->ActivityManager().UpdateActivity(*m_Activity, [](discord::Result result) {}); 27 | 28 | return true; 29 | } 30 | 31 | 32 | void DiscordRPC::SetActivityState(const char* inState) 33 | { 34 | if (m_Core && m_Activity) 35 | { 36 | m_Activity->SetState(inState); 37 | m_Core->ActivityManager().UpdateActivity(*m_Activity, [](discord::Result result) {}); 38 | } 39 | } 40 | 41 | 42 | void DiscordRPC::SetActivityDetails(const char* inDetails) 43 | { 44 | if (m_Core && m_Activity) 45 | { 46 | m_Activity->SetDetails(inDetails); 47 | m_Core->ActivityManager().UpdateActivity(*m_Activity, [](discord::Result result) {}); 48 | } 49 | } 50 | 51 | 52 | void DiscordRPC::OnUpdate() 53 | { 54 | if (m_Core) 55 | m_Core->RunCallbacks(); 56 | } 57 | 58 | 59 | void DiscordRPC::Destroy() 60 | { 61 | delete m_User; 62 | delete m_Core; 63 | } 64 | 65 | } -------------------------------------------------------------------------------- /Code/Engine/DiscordRPC.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace discord { 4 | 5 | class User; 6 | class Core; 7 | class Activity; 8 | 9 | } 10 | 11 | namespace RK { 12 | 13 | class Application; 14 | 15 | // Sends activity updates to Discord Rich Presence 16 | class DiscordRPC 17 | { 18 | public: 19 | bool Init(Application* inApp); 20 | void Destroy(); 21 | void OnUpdate(); 22 | 23 | void SetActivityState(const char* inState); 24 | void SetActivityDetails(const char* inDetails); 25 | 26 | private: 27 | discord::User* m_User = nullptr; 28 | discord::Core* m_Core = nullptr; 29 | discord::Activity* m_Activity = nullptr; 30 | }; 31 | 32 | } -------------------------------------------------------------------------------- /Code/Engine/ECS.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "ecs.h" 3 | #include "scene.h" 4 | 5 | namespace RK { 6 | 7 | RTTI_DEFINE_TYPE_PRIMITIVE(Entity); 8 | 9 | struct TestName 10 | { 11 | RTTI_DECLARE_TYPE(TestName); 12 | 13 | std::string name; 14 | }; 15 | 16 | RTTI_DEFINE_TYPE(TestName) {} 17 | 18 | struct TestTransform 19 | { 20 | RTTI_DECLARE_TYPE(TestTransform); 21 | 22 | Vec3 pos; 23 | }; 24 | 25 | RTTI_DEFINE_TYPE(TestTransform) {} 26 | 27 | 28 | struct TestMaterial 29 | { 30 | RTTI_DECLARE_TYPE(TestMaterial); 31 | 32 | Vec4 color; 33 | }; 34 | 35 | RTTI_DEFINE_TYPE(TestMaterial) {} 36 | 37 | 38 | void RunECStorageTests() 39 | { 40 | ECStorage ecs; 41 | ecs.EnsureExists(); 42 | ecs.EnsureExists(); 43 | ecs.EnsureExists(); 44 | 45 | Entity entity = ecs.Create(); 46 | { 47 | TestName& name = ecs.Add(entity); 48 | name.name = "FirstEntity"; 49 | } 50 | 51 | assert(ecs.Exists(entity)); 52 | assert(ecs.Has(entity)); 53 | assert(ecs.Get(entity).name == "FirstEntity"); 54 | assert(ecs.Count() == 1); 55 | assert(ecs.GetPtr(entity) != nullptr); 56 | assert(ecs.GetStorage().size() == 1); 57 | assert(ecs.GetEntities().size() == 1); 58 | 59 | ecs.Add(entity); 60 | { 61 | TestMaterial& material = ecs.Add(entity); 62 | } 63 | 64 | for (const auto& [entity, name, transform] : ecs.Each()) 65 | name.name = "NotFirstEntity"; 66 | 67 | for (const auto& [entity, name, transform] : ecs.Each()) 68 | assert(name.name == "NotFirstEntity"); 69 | 70 | for (const auto& [entity, name, transform, material] : ecs.Each()) 71 | assert(name.name == "NotFirstEntity"); 72 | 73 | ecs.Remove(entity); 74 | assert(!ecs.Has(entity)); 75 | 76 | { 77 | TestName& name = ecs.Add(entity); 78 | name.name = "SecondEntity"; 79 | } 80 | 81 | assert(ecs.Get(entity).name == "SecondEntity"); 82 | 83 | for (const auto& [entity, name, transform] : ecs.Each()) 84 | std::cout << name.name << std::endl; 85 | 86 | Array entities; 87 | 88 | for (int i = 0; i < 20; i++) 89 | ecs.Add(entities.emplace_back(ecs.Create())); 90 | 91 | int count = ecs.Count(); 92 | 93 | for (int i = 0; i < 20; i++) 94 | ecs.Destroy(entities[i]); 95 | 96 | entities.clear(); 97 | 98 | for (int i = 0; i < 20; i++) 99 | ecs.Add(entities.emplace_back(ecs.Create())); 100 | 101 | int new_count = ecs.Count(); 102 | assert(new_count == count); 103 | } 104 | 105 | } // namespace RK 106 | -------------------------------------------------------------------------------- /Code/Engine/FBX.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "scene.h" 4 | 5 | namespace RK { 6 | 7 | class FBXImporter : public Importer 8 | { 9 | public: 10 | FBXImporter(Scene& inScene, IRenderInterface* inRenderer) : Importer(inScene, inRenderer) {} 11 | bool LoadFromFile(const std::string& inFile, Assets* inAssets) override; 12 | 13 | private: 14 | void ParseNode(const ufbx_node* inNode, Entity inParent, Entity inEntity); 15 | 16 | void ConvertMesh(Entity inEntity, const ufbx_mesh* inMesh, const ufbx_mesh_material& inMaterial); 17 | void ConvertBones(Entity inEntity, const ufbx_bone_list* inSkeleton); 18 | void ConvertMaterial(Entity inEntity, const ufbx_material* inMaterial); 19 | 20 | private: 21 | Path m_Directory; 22 | ufbx_scene* m_FbxScene; 23 | std::vector m_Materials; 24 | std::vector m_CreatedNodeEntities; 25 | }; 26 | 27 | } -------------------------------------------------------------------------------- /Code/Engine/GLTF.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Scene.h" 4 | 5 | namespace RK { 6 | 7 | class Async; 8 | class Assets; 9 | 10 | class Mesh; 11 | class Material; 12 | class Skeleton; 13 | 14 | class GltfImporter : public Importer 15 | { 16 | public: 17 | GltfImporter(Scene& inScene, IRenderInterface* inRenderer) : Importer(inScene, inRenderer) {} 18 | ~GltfImporter(); 19 | 20 | bool LoadFromFile(const String& inFile, Assets* inAssets) override; 21 | 22 | private: 23 | void ParseNode(const cgltf_node& gltfNode, Entity parent, glm::mat4 transform); 24 | 25 | bool ConvertMesh(Entity inEntity, const cgltf_primitive& inMesh); 26 | void ConvertLight(Entity inEntity, const cgltf_light& inLight); 27 | void ConvertBones(Entity inEntity, const cgltf_node& inSkeleton); 28 | void ConvertMaterial(Entity inEntity, const cgltf_material& inMaterial); 29 | void ConvertAnimation(Entity inEntity, const cgltf_animation& inAnimation); 30 | 31 | Mat4x4 GetLocalTransform(const cgltf_node& inNode); 32 | int GetJointIndex(const cgltf_node* inSkinNode, const cgltf_node* inJointNode); 33 | 34 | private: 35 | Path m_Directory; 36 | cgltf_data* m_GltfData = nullptr; 37 | Array m_Materials; 38 | Array m_Animations; 39 | Array m_CreatedNodeEntities; 40 | }; 41 | 42 | } // raekor 43 | -------------------------------------------------------------------------------- /Code/Engine/Hash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace RK { 6 | 7 | constexpr uint32_t val_32_const = 0x811c9dc5; 8 | constexpr uint32_t prime_32_const = 0x1000193; 9 | constexpr uint64_t val_64_const = 0xcbf29ce484222325; 10 | constexpr uint64_t prime_64_const = 0x100000001b3; 11 | 12 | 13 | inline constexpr uint32_t gHash32Bit(const char* const str, const uint32_t value = val_32_const) noexcept 14 | { 15 | return ( str[0] == '\0' ) ? value : gHash32Bit(&str[1], ( value ^ uint32_t(str[0]) ) * prime_32_const); 16 | } 17 | 18 | 19 | inline constexpr uint64_t gHash64Bit(const char* const str, const uint64_t value = val_64_const) noexcept 20 | { 21 | return ( str[0] == '\0' ) ? value : gHash64Bit(&str[1], ( value ^ uint64_t(str[0]) ) * prime_64_const); 22 | } 23 | 24 | 25 | inline uint64_t gHashFNV1a(const char* const inData, uint64_t inLength) 26 | { 27 | uint64_t hash = val_64_const; 28 | 29 | for (uint32_t i = 0; i < inLength; i++) 30 | hash = ( hash ^ inData[i] ) * prime_64_const; 31 | 32 | return hash; 33 | } 34 | 35 | } // raekor -------------------------------------------------------------------------------- /Code/Engine/Input.cpp: -------------------------------------------------------------------------------- 1 | #include "PCH.h" 2 | #include "Input.h" 3 | 4 | namespace RK { 5 | 6 | Input* g_Input = new Input(); 7 | 8 | Input::Input() : m_KeyboardState(SDL_GetKeyboardState(NULL)) {} 9 | 10 | 11 | void Input::OnEvent(const SDL_Event& inEvent) 12 | { 13 | switch (inEvent.type) 14 | { 15 | case SDL_EVENT_GAMEPAD_ADDED: 16 | { 17 | const int joystick_index = inEvent.cdevice.which; 18 | m_Controller = SDL_OpenGamepad(joystick_index); 19 | } break; 20 | 21 | case SDL_EVENT_GAMEPAD_REMOVED: 22 | { 23 | SDL_CloseGamepad(m_Controller); 24 | m_Controller = nullptr; 25 | } break; 26 | } 27 | } 28 | 29 | 30 | void Input::OnUpdate(float inDeltaTime) 31 | { 32 | if (m_Controller == nullptr) 33 | { 34 | int joystick_count = 0; 35 | SDL_JoystickID* joysticks = SDL_GetJoysticks(&joystick_count); 36 | 37 | for (int i = 0; i < joystick_count; i++) 38 | { 39 | SDL_JoystickID joystick = joysticks[i]; 40 | 41 | if (SDL_IsGamepad(joystick)) 42 | { 43 | m_Controller = SDL_OpenGamepad(joystick); 44 | break; 45 | } 46 | } 47 | } 48 | } 49 | 50 | 51 | bool Input::IsKeyDown(Key key) 52 | { 53 | return m_KeyboardState[static_cast(key)]; 54 | } 55 | 56 | 57 | bool Input::IsButtonDown(uint32_t button) 58 | { 59 | uint32_t state = SDL_GetMouseState(NULL, NULL); 60 | return state & SDL_BUTTON_MASK(button); 61 | } 62 | 63 | 64 | bool Input::IsRelativeMouseMode() 65 | { 66 | return m_RelMouseMode; 67 | } 68 | 69 | 70 | void Input::SetRelativeMouseMode(bool inEnabled) 71 | { 72 | m_RelMouseMode = inEnabled; 73 | } 74 | 75 | } // raekor -------------------------------------------------------------------------------- /Code/Engine/Input.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace RK { 4 | 5 | enum class Key : int 6 | { 7 | UNKNOWN = 0, 8 | A = 4, 9 | B = 5, 10 | C = 6, 11 | D = 7, 12 | E = 8, 13 | F = 9, 14 | G = 10, 15 | H = 11, 16 | I = 12, 17 | J = 13, 18 | K = 14, 19 | L = 15, 20 | M = 16, 21 | N = 17, 22 | O = 18, 23 | P = 19, 24 | Q = 20, 25 | R = 21, 26 | S = 22, 27 | T = 23, 28 | U = 24, 29 | V = 25, 30 | W = 26, 31 | X = 27, 32 | Y = 28, 33 | Z = 29, 34 | DIGIT_1 = 30, 35 | DIGIT_2 = 31, 36 | DIGIT_3 = 32, 37 | DIGIT_4 = 33, 38 | DIGIT_5 = 34, 39 | DIGIT_6 = 35, 40 | DIGIT_7 = 36, 41 | DIGIT_8 = 37, 42 | DIGIT_9 = 38, 43 | DIGIT_0 = 39, 44 | RETURN = 40, 45 | ESCAPE = 41, 46 | BACKSPACE = 42, 47 | TAB = 43, 48 | SPACE = 44, 49 | MINUS = 45, 50 | EQUALS = 46, 51 | LEFTBRACKET = 47, 52 | RIGHTBRACKET = 48, 53 | BACKSLASH = 49, 54 | NONUSHASH = 50, 55 | SEMICOLON = 51, 56 | APOSTROPHE = 52, 57 | GRAVE = 53, 58 | COMMA = 54, 59 | PERIOD = 55, 60 | SLASH = 56, 61 | CAPSLOCK = 57, 62 | F1 = 58, 63 | F2 = 59, 64 | F3 = 60, 65 | F4 = 61, 66 | F5 = 62, 67 | F6 = 63, 68 | F7 = 64, 69 | F8 = 65, 70 | F9 = 66, 71 | F10 = 67, 72 | F11 = 68, 73 | F12 = 69, 74 | PRINTSCREEN = 70, 75 | SCROLLLOCK = 71, 76 | PAUSE = 72, 77 | INSERT = 73, 78 | HOME = 74, 79 | PAGEUP = 75, 80 | DEL = 76, 81 | END = 77, 82 | PAGEDOWN = 78, 83 | RIGHT = 79, 84 | LEFT = 80, 85 | DOWN = 81, 86 | UP = 82, 87 | LCTRL = 224, 88 | LSHIFT = 225, 89 | LALT = 226, 90 | LGUI = 227, 91 | RCTRL = 228, 92 | RSHIFT = 229, 93 | RALT = 230, 94 | RGUI = 231, 95 | MODE = 257 96 | }; 97 | 98 | class Input 99 | { 100 | public: 101 | Input(); 102 | 103 | void OnEvent(const SDL_Event& inEvent); 104 | void OnUpdate(float inDeltaTime); 105 | 106 | bool HasController() const { return m_Controller != nullptr; } 107 | SDL_Gamepad* GetController() { return m_Controller; } 108 | 109 | /* Gets the current state of a keyboard key */ 110 | bool IsKeyDown(Key key); 111 | 112 | /* Gets the current state of a mouse button. 113 | @param button 1 = LMB, 2 = MMB, 3 = RMB */ 114 | bool IsButtonDown(uint32_t button); 115 | 116 | bool IsRelativeMouseMode(); 117 | void SetRelativeMouseMode(bool inEnabled); 118 | 119 | private: 120 | bool m_RelMouseMode = false; 121 | const bool* m_KeyboardState; 122 | SDL_Gamepad* m_Controller = nullptr; 123 | }; 124 | 125 | extern Input* g_Input; 126 | 127 | } -------------------------------------------------------------------------------- /Code/Engine/Iter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | template ()) ), typename = decltype( std::end(std::declval()) )> 5 | constexpr auto gEnumerate(T&& iterable) 6 | { 7 | struct iterator 8 | { 9 | size_t i; 10 | TIter iter; 11 | bool operator != (const iterator& other) const { return iter != other.iter; } 12 | void operator ++ () { ++i; ++iter; } 13 | auto operator * () const { return std::tie(i, *iter); } 14 | }; 15 | 16 | struct iterable_wrapper 17 | { 18 | T iterable; 19 | auto begin() { return iterator { 0, std::begin(iterable) }; } 20 | auto end() { return iterator { 0, std::end(iterable) }; } 21 | }; 22 | 23 | return iterable_wrapper { std::forward(iterable) }; 24 | } 25 | 26 | 27 | template 28 | void _for_each_tuple_element_impl(Tpl&& Tuple, Fx Func, std::index_sequence) 29 | { 30 | // call Func() on the Indices elements of Tuple 31 | int ignored[] = { ( static_cast( Func(std::get(std::forward(Tuple))) ), 0 )... }; 32 | (void)ignored; 33 | } 34 | 35 | template 36 | void gForEachTupleElement(Tpl&& Tuple, Fx Func) 37 | { 38 | // call Func() on each element in Tuple 39 | _for_each_tuple_element_impl( 40 | std::forward(Tuple), Func, std::make_index_sequence>>{}); 41 | } 42 | 43 | template 44 | void gForEachType(Fx Func) 45 | { 46 | gForEachTupleElement(std::tuple(), Func); 47 | } -------------------------------------------------------------------------------- /Code/Engine/JSON.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "json.h" 3 | #include "iter.h" 4 | 5 | namespace RK::JSON { 6 | 7 | JSONData::JSONData(const Path& inPath, bool inTokenizeOnly) 8 | { 9 | auto ifs = std::ifstream(inPath); 10 | std::stringstream buffer; 11 | buffer << ifs.rdbuf(); 12 | m_StrBuffer = buffer.str(); 13 | 14 | jsmn_parser parser; 15 | jsmn_init(&parser); 16 | 17 | const auto nr_of_tokens = jsmn_parse(&parser, m_StrBuffer.c_str(), m_StrBuffer.size(), NULL, 0); 18 | if (nr_of_tokens == 0) 19 | return; 20 | 21 | jsmn_init(&parser); 22 | m_Tokens.resize(nr_of_tokens); 23 | const auto parse_result = jsmn_parse(&parser, m_StrBuffer.c_str(), m_StrBuffer.size(), m_Tokens.data(), m_Tokens.size()); 24 | 25 | if (parse_result != nr_of_tokens || inTokenizeOnly) 26 | return; 27 | 28 | m_Strings.resize(nr_of_tokens); 29 | m_Primitives.resize(nr_of_tokens); 30 | 31 | for (const auto& [index, token] : gEnumerate(m_Tokens)) 32 | { 33 | auto c = m_StrBuffer[token.start]; 34 | 35 | if (token.type == JSMN_PRIMITIVE) 36 | { 37 | if (std::isdigit(c) || c == '.' || c == '-' || c == 'e') 38 | { 39 | std::from_chars(&m_StrBuffer[m_Tokens[index].start], &m_StrBuffer[m_Tokens[index].end], m_Primitives[index]); 40 | } 41 | else if (c == 't' || c == 'f') 42 | m_Primitives[index] = 't' ? (double)true : (double)false; 43 | 44 | } 45 | else if (token.type == JSMN_STRING) 46 | m_Strings[index] = std::string(&m_StrBuffer[token.start], token.end - token.start); 47 | } 48 | } 49 | 50 | 51 | bool JSONData::IsKeyObjectPair(uint32_t inIdx) const 52 | { 53 | return m_Tokens[inIdx].type == JSMN_STRING && m_Tokens[inIdx + 1].type == JSMN_OBJECT; 54 | } 55 | 56 | 57 | uint32_t JSONData::SkipToken(uint32_t inTokenIdx) const 58 | { 59 | if (!( inTokenIdx < m_Tokens.size() )) 60 | return inTokenIdx; 61 | 62 | const auto token_end = m_Tokens[inTokenIdx].end; 63 | 64 | while (m_Tokens[inTokenIdx].start < token_end) 65 | { 66 | inTokenIdx++; 67 | 68 | if (inTokenIdx >= m_Tokens.size()) 69 | return -1; 70 | } 71 | 72 | return inTokenIdx; 73 | } 74 | 75 | } // raekor::JSON -------------------------------------------------------------------------------- /Code/Engine/Member.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "rtti.h" 4 | #include "json.h" 5 | 6 | namespace RK { 7 | 8 | template 9 | class ClassMember : public Member 10 | { 11 | public: 12 | ClassMember() = delete; 13 | ClassMember(const char* inName, const char* inCustomName, T Class::* inMember, RTTI* inRTTI = nullptr, ESerializeType inSerializeType = SERIALIZE_JSON) 14 | : Member(inName, inCustomName, inSerializeType), m_RTTI(inRTTI), m_Member(inMember) 15 | { 16 | } 17 | 18 | void ToJSON(JSON::JSONWriter& inJSON, const void* inClass) override 19 | { 20 | inJSON.GetValueToJSON(GetRef(inClass)); 21 | } 22 | 23 | uint32_t FromJSON(JSON::JSONData& inJSON, uint32_t inTokenIdx, void* inClass) override 24 | { 25 | return inJSON.GetTokenToValue(inTokenIdx, GetRef(inClass)); 26 | } 27 | 28 | void ToBinary(File& inFile, const void* inClass) override 29 | { 30 | WriteFileBinary(inFile, GetRef(inClass)); 31 | } 32 | 33 | void FromBinary(File& inFile, void* inClass) override 34 | { 35 | ReadFileBinary(inFile, GetRef(inClass)); 36 | } 37 | 38 | RTTI* GetRTTI() override { return m_RTTI; } 39 | 40 | void* GetPtr(void* inClass) override { return &( static_cast( inClass )->*m_Member ); } 41 | const void* GetPtr(const void* inClass) override { return &( static_cast( inClass )->*m_Member ); } 42 | 43 | 44 | private: 45 | T Class::* m_Member; 46 | RTTI* m_RTTI = nullptr; 47 | }; 48 | 49 | 50 | class EnumMember : public Member 51 | { 52 | public: 53 | EnumMember(const char* inName, const char* inCustomName, ESerializeType inSerializeType = SERIALIZE_JSON) 54 | : Member(inName, inCustomName, inSerializeType) 55 | { 56 | } 57 | 58 | virtual void* GetPtr(void* inClass) override { return inClass; } 59 | virtual const void* GetPtr(const void* inClass) override { return inClass; } 60 | }; 61 | 62 | } -------------------------------------------------------------------------------- /Code/Engine/OBJ.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Scene.h" 4 | #include "CVars.h" 5 | 6 | namespace RK { 7 | 8 | struct OBJMesh 9 | { 10 | Array v_indices; // Token: f x// 11 | Array vt_indices; // Token: f /x/ 12 | Array vn_indices; // Token: f //x 13 | 14 | void Clear() { v_indices.clear(); vt_indices.clear(); vn_indices.clear(); } 15 | bool IsEmpty() const { return v_indices.empty() && vt_indices.empty() && vn_indices.empty(); } 16 | }; 17 | 18 | struct OBJMaterial 19 | { 20 | // Blinn-Phong properties 21 | Vec3 diffuse = Vec3(0); // Token: 'Kd' 22 | float alpha = 1.0; // Token: 'd' or 'Tr' 23 | Vec3 specular = Vec3(0); // Token: 'Ks' 24 | float specularExp = 1.0; // Token: 'Ns' 25 | Vec3 ambient = Vec3(0); // Token: 'Ka' 26 | float ior = 1.0; // Token: 'Ni' 27 | Vec3 alphaColor = Vec3(0); // Token: 'Tf' 28 | uint32_t illum = 0; // Token: 'illum' 29 | 30 | // PBR properties 31 | Vec3 emissive = Vec3(0); // Token: 'Ke' 32 | float roughness = 1.0; // Token: 'Pr' 33 | float metallic = 0.0; // Token: 'Pm' 34 | float sheen = 0.0; // Token: 'Ps' 35 | float ccThickness = 0.0; // Token: 'Pc' 36 | float ccRoughness = 0.0; // Token: 'Pcr' 37 | float anisotropy = 0.0; // Token: 'aniso' 38 | float anisoRotation = 0.0; // Token: 'anisor' 39 | 40 | // Material Name 41 | String name; 42 | 43 | // Blinn-Phong textures 44 | String bumpMap; // Token: 'map_bump' or 'bump' 45 | String alphaMap; // Token: 'map_d' 46 | String decalMap; // Token: 'decal' 47 | String ambientMap; // Token: 'map_Ka' 48 | String diffuseMap; // Token: 'map_Kd' 49 | String specularMap; // Token: 'map_Ks' 50 | String specularExpMap; // Token: 'map_Ns' 51 | String displacementMap; // Token: 'disp' 52 | 53 | // PBR Textures 54 | String sheenMap; // Token: 'map_Ps' 55 | String normalMap; // Token: 'norm' 56 | String metallicMap; // Token: 'map_Pm' 57 | String emissiveMap; // Token: 'map_Ke' 58 | String roughnessMap; // Token: 'map_Pr' 59 | 60 | // Extra PBR Textures 61 | String rmaMap; // Token: 'map_RMA' 62 | String ormMap; // Token: 'map_ORM' 63 | }; 64 | 65 | class OBJImporter : public Importer 66 | { 67 | public: 68 | struct 69 | { 70 | int& importGrouping = g_CVariables->Create("obj_import_groupings", 1, true); 71 | int& importMaterials = g_CVariables->Create("obj_import_materials", 1, true); 72 | } m_Settings; 73 | 74 | public: 75 | OBJImporter(Scene& inScene, IRenderInterface* inRenderer) : Importer(inScene, inRenderer) {} 76 | bool LoadFromFile(const String& inFile, Assets* inAssets) override; 77 | 78 | private: 79 | bool LoadMaterials(const Path& inFilePath); 80 | void ConvertMesh(Entity inEntity, const OBJMesh& inMesh); 81 | void ConvertMaterial(Entity inEntity, const OBJMaterial& inMaterial); 82 | 83 | private: 84 | Path m_Directory; 85 | Array m_Normals; 86 | Array m_Positions; 87 | Array m_Texcoords; 88 | Array m_Meshes; 89 | Array m_Materials; 90 | Array m_ObjMaterials; 91 | }; 92 | 93 | } -------------------------------------------------------------------------------- /Code/Engine/OS.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "pch.h" 4 | 5 | namespace RK::OS { 6 | /* 7 | Interface for OS specific tasks. 8 | Compile time decides which function definitions to pull in. 9 | */ 10 | 11 | enum class EDirectoryChange 12 | { 13 | FILE_CREATED 14 | }; 15 | 16 | bool sWatchDirectory(const Path& inDirPath, EDirectoryChange& outChange, Path& outFilePath); 17 | 18 | void sOpenFile(const char* inFile); 19 | bool sRunMsBuild(const char* args); 20 | bool sCreateProcess(const char* inCmd); 21 | void sCopyToClipboard(const char* inText); 22 | bool sSetDarkTitleBar(SDL_Window* inWindow); 23 | void* sGetFunctionPointer(const char* inName); 24 | 25 | bool sCheckCommandLineOption(const char* inOption); 26 | String sGetCommandLineValue(const char* inOption); 27 | 28 | String sOpenFileDialog(const char* filters); 29 | String sSaveFileDialog(const char* filters, const char* defaultExt); 30 | String sSelectFolderDialog(); 31 | 32 | Path sGetTempPath(); 33 | Path sGetExecutablePath(); 34 | Path sGetExecutableDirectoryPath(); 35 | 36 | } // namespace Raekor::OS 37 | -------------------------------------------------------------------------------- /Code/Engine/PCH.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | 3 | #define CGLTF_IMPLEMENTATION 4 | #include "cgltf.h" 5 | 6 | #define STB_IMAGE_IMPLEMENTATION 7 | #include "stb_image.h" 8 | 9 | #define STB_IMAGE_WRITE_IMPLEMENTATION 10 | #include "stb_image_write.h" 11 | 12 | #define STB_DXT_IMPLEMENTATION 13 | #include "stb_dxt.h" 14 | 15 | #define STB_IMAGE_RESIZE_IMPLEMENTATION 16 | #include "stb_image_resize2.h" 17 | -------------------------------------------------------------------------------- /Code/Engine/Primitives.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "primitives.h" 3 | #include "components.h" 4 | 5 | namespace RK { 6 | 7 | } -------------------------------------------------------------------------------- /Code/Engine/Primitives.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace RK { 4 | 5 | struct Vertex 6 | { 7 | constexpr Vertex( 8 | Vec3 p = {}, 9 | Vec2 uv = {}, 10 | Vec3 n = {}, 11 | Vec3 t = {} 12 | ) : 13 | pos(p), 14 | uv(uv), 15 | normal(n), 16 | tangent(t) 17 | { 18 | } 19 | 20 | Vec3 pos; 21 | Vec2 uv; 22 | Vec3 normal; 23 | Vec3 tangent; 24 | }; 25 | 26 | 27 | struct Triangle 28 | { 29 | constexpr Triangle( 30 | uint32_t _p1 = {}, 31 | uint32_t _p2 = {}, 32 | uint32_t _p3 = {} 33 | ) : 34 | p1(_p1), 35 | p2(_p2), 36 | p3(_p3) 37 | { 38 | } 39 | 40 | uint32_t p1, p2, p3; 41 | }; 42 | 43 | } -------------------------------------------------------------------------------- /Code/Engine/Profiler.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Profiler.h" 3 | 4 | namespace RK { 5 | 6 | Profiler* g_Profiler = new Profiler(); 7 | 8 | void Profiler::Reset() 9 | { 10 | if (m_IsEnabled) 11 | { 12 | m_HistoryCPUSections = m_CPUSections; 13 | std::scoped_lock lock(m_SectionsMutex); 14 | m_CPUSections.clear(); 15 | } 16 | } 17 | 18 | 19 | int Profiler::AllocateCPU() 20 | { 21 | std::scoped_lock lock(m_SectionsMutex); 22 | m_CPUSections.emplace_back(); 23 | return m_CPUSections.size() - 1; 24 | } 25 | 26 | 27 | CPUProfileSectionScoped::CPUProfileSectionScoped(const char* inName) 28 | { 29 | if (g_Profiler->IsEnabled()) 30 | { 31 | mIndex = g_Profiler->AllocateCPU(); 32 | 33 | CPUProfileSection& section = g_Profiler->GetSectionCPU(mIndex); 34 | section.mStartTick = Timer::sGetCurrentTick(); 35 | section.mName = inName; 36 | section.mDepth = g_Profiler->m_Depth++; 37 | } 38 | } 39 | 40 | 41 | CPUProfileSectionScoped::~CPUProfileSectionScoped() 42 | { 43 | if (g_Profiler->IsEnabled()) 44 | { 45 | CPUProfileSection& section = g_Profiler->GetSectionCPU(mIndex); 46 | section.mEndTick = Timer::sGetCurrentTick(); 47 | g_Profiler->m_Depth--; 48 | } 49 | } 50 | 51 | 52 | 53 | 54 | } // raekor -------------------------------------------------------------------------------- /Code/Engine/Profiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "timer.h" 4 | 5 | namespace RK { 6 | 7 | #define PROFILE_SCOPE_CPU(name) CPUProfileSectionScoped TOKENPASTE2(cpu_profile_section_, __LINE__)(name) 8 | 9 | #define PROFILE_FUNCTION_CPU() CPUProfileSectionScoped TOKENPASTE2(cpu_profile_section_, __LINE__)(__FUNCTION__) 10 | 11 | 12 | struct ProfileSection 13 | { 14 | uint32_t mDepth = 0; 15 | uint64_t mEndTick = 0; 16 | uint64_t mStartTick = 0; 17 | const char* mName = nullptr; 18 | 19 | virtual float GetSeconds() const = 0; 20 | }; 21 | 22 | struct CPUProfileSection : public ProfileSection 23 | { 24 | float GetSeconds() const final { return Timer::sGetTicksToSeconds(mEndTick - mStartTick); } 25 | }; 26 | 27 | class Profiler 28 | { 29 | public: 30 | friend class CPUProfileSection; 31 | friend class CPUProfileSectionScoped; 32 | 33 | void Reset(); 34 | 35 | bool IsEnabled() const { return m_IsEnabled; } 36 | void SetEnabled(bool inEnabled) { m_IsEnabled = inEnabled; } 37 | 38 | int AllocateCPU(); 39 | CPUProfileSection& GetSectionCPU(int inIndex) { return m_CPUSections[inIndex]; } 40 | const Array& GetCPUProfileSections() const { return m_HistoryCPUSections; } 41 | 42 | protected: 43 | int m_Depth = 0; 44 | bool m_IsEnabled = true; 45 | 46 | Mutex m_SectionsMutex; 47 | Array m_CPUSections; 48 | Array m_HistoryCPUSections; 49 | }; 50 | 51 | 52 | extern Profiler* g_Profiler; 53 | 54 | 55 | class CPUProfileSectionScoped 56 | { 57 | public: 58 | CPUProfileSectionScoped(const char* inName); 59 | ~CPUProfileSectionScoped(); 60 | 61 | private: 62 | int mIndex = 0; 63 | }; 64 | 65 | } -------------------------------------------------------------------------------- /Code/Engine/RTTI.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "rtti.h" 3 | #include "iter.h" 4 | #include "hash.h" 5 | 6 | namespace RK { 7 | 8 | RTTIFactory g_RTTIFactory; 9 | 10 | 11 | RTTI::RTTI(const char* inName) 12 | : mHash(gHash32Bit(inName)), m_Name(inName) 13 | { 14 | } 15 | 16 | 17 | RTTI::RTTI(const char* inName, CreateFn inCreateFn, Constructor inConstructor) 18 | : mHash(gHash32Bit(inName)), m_Name(inName), m_Constructor(inConstructor) 19 | { 20 | inCreateFn(*this); 21 | } 22 | 23 | 24 | void RTTI::AddMember(Member* inMember) 25 | { 26 | m_Members.emplace_back(std::unique_ptr(inMember)); 27 | } 28 | 29 | 30 | Member* RTTI::GetMember(uint32_t inIndex) const 31 | { 32 | return m_Members[inIndex].get(); 33 | } 34 | 35 | 36 | Member* RTTI::GetMember(const char* inName) const 37 | { 38 | const uint32_t name_hash = gHash32Bit(inName); 39 | for (const auto& member : m_Members) 40 | if (name_hash == member->GetNameHash() || name_hash == member->GetCustomNameHash()) 41 | return member.get(); 42 | 43 | return nullptr; 44 | } 45 | 46 | 47 | int32_t RTTI::GetMemberIndex(const char* inName) const 48 | { 49 | const uint32_t name_hash = gHash32Bit(inName); 50 | for (const auto& [index, member] : gEnumerate(m_Members)) 51 | if (name_hash == member->GetNameHash() || name_hash == member->GetCustomNameHash()) 52 | return index; 53 | 54 | return -1; 55 | } 56 | 57 | 58 | Member::Member(const char* inName, const char* inCustomName, ESerializeType inSerializeType) 59 | : m_NameHash(gHash32Bit(inName)), m_CustomNameHash(gHash32Bit(inCustomName)), m_Name(inName), m_CustomName(inCustomName), m_SerializeType(inSerializeType) 60 | { 61 | } 62 | 63 | void RTTIFactory::Register(RTTI& inRTTI) 64 | { 65 | if (m_RegisteredTypes.find(inRTTI.mHash) == m_RegisteredTypes.end()) 66 | m_RegisteredTypes[inRTTI.mHash] = &inRTTI; 67 | } 68 | 69 | 70 | void RTTI::AddBaseClass(RTTI& inRTTI) 71 | { 72 | m_BaseClasses.push_back(&inRTTI); 73 | } 74 | 75 | 76 | RTTI* RTTI::GetBaseClass(uint32_t inIndex) const 77 | { 78 | return m_BaseClasses[inIndex]; 79 | } 80 | 81 | 82 | bool RTTI::IsDerivedFrom(RTTI* inRTTI) const 83 | { 84 | if (this == inRTTI) 85 | return true; 86 | 87 | for (RTTI* base_class : m_BaseClasses) 88 | if (base_class->IsDerivedFrom(inRTTI)) 89 | return true; 90 | 91 | return false; 92 | } 93 | 94 | 95 | 96 | RTTI* RTTIFactory::GetRTTI(uint32_t inHash) 97 | { 98 | if (m_RegisteredTypes.contains(inHash)) 99 | return m_RegisteredTypes.at(inHash); 100 | else 101 | return nullptr; 102 | } 103 | 104 | 105 | RTTI* RTTIFactory::GetRTTI(const char* inType) 106 | { 107 | return GetRTTI(gHash32Bit(inType)); 108 | } 109 | 110 | void* RTTIFactory::Construct(const char* inType) 111 | { 112 | if (RTTI* rtti = GetRTTI(inType)) 113 | return rtti->m_Constructor(); 114 | else 115 | return nullptr; 116 | } 117 | 118 | } // namespace Raekor 119 | 120 | RTTI_DEFINE_TYPE_PRIMITIVE(int); 121 | RTTI_DEFINE_TYPE_PRIMITIVE(bool); 122 | RTTI_DEFINE_TYPE_PRIMITIVE(float); 123 | RTTI_DEFINE_TYPE_PRIMITIVE(uint32_t); 124 | 125 | void gRegisterPrimitiveTypes() 126 | { 127 | RK::g_RTTIFactory.Register(); 128 | RK::g_RTTIFactory.Register(); 129 | RK::g_RTTIFactory.Register(); 130 | RK::g_RTTIFactory.Register(); 131 | } 132 | -------------------------------------------------------------------------------- /Code/Engine/Raekor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef _CRT_SECURE_NO_WARNINGS 4 | #define _CRT_SECURE_NO_WARNINGS 5 | #endif 6 | 7 | #include "PCH.h" 8 | #include "ECS.h" 9 | #include "RTTI.h" 10 | #include "Math.h" 11 | #include "Input.h" 12 | #include "Scene.h" 13 | #include "Assets.h" 14 | #include "Member.h" 15 | #include "Camera.h" 16 | #include "Script.h" 17 | #include "Physics.h" 18 | #include "Components.h" 19 | #include "Application.h" 20 | #include "UIRenderer.h" 21 | #include "DebugRenderer.h" 22 | 23 | #ifndef RAEKOR_SCRIPT 24 | #include "Camera.h" 25 | #include "Assets.h" 26 | #include "Application.h" 27 | #endif 28 | 29 | -------------------------------------------------------------------------------- /Code/Engine/Renderer/CommandList.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "pch.h" 4 | #include "Resource.h" 5 | 6 | namespace RK { 7 | struct Mesh; 8 | class Viewport; 9 | } 10 | 11 | namespace RK::DX12 { 12 | 13 | class Device; 14 | class ScopedMarker; 15 | 16 | class CommandList 17 | { 18 | public: 19 | CommandList() = default; 20 | CommandList(Device& inDevice, D3D12_COMMAND_LIST_TYPE inType); 21 | CommandList(Device& inDevice, D3D12_COMMAND_LIST_TYPE inType, uint32_t inFrameIndex); 22 | 23 | operator ID3D12GraphicsCommandList* () { return m_CommandList.Get(); } 24 | operator const ID3D12GraphicsCommandList* () const { return m_CommandList.Get(); } 25 | ID3D12GraphicsCommandList4* operator-> () { return m_CommandList.Get(); } 26 | const ID3D12GraphicsCommandList4* operator-> () const { return m_CommandList.Get(); } 27 | 28 | void Reset(); 29 | void Begin(); 30 | void Close(); 31 | 32 | uint32_t GetFrameIndex() const { return m_FrameIndex; } 33 | uint64_t GetFenceValue() const { return m_SubmittedFenceValue; } 34 | 35 | void SetViewportAndScissor(Texture& inTexture, uint32_t inSubResource = 0); 36 | void SetViewportAndScissor(const Viewport& inViewport); 37 | 38 | void ClearBuffer(Device& inDevice, BufferID inBuffer, Vec4 inValue); 39 | void ClearTexture(Device& inDevice, TextureID inTexture, Vec4 inValue); 40 | 41 | void PushMarker(const char* inLabel, uint32_t inColor); 42 | void PopMarker(); 43 | 44 | void BindDefaults(Device& inDevice); 45 | void BindIndexBuffer(Buffer& inBuffer); 46 | void BindVertexAndIndexBuffers(Device& inDevice, const RK::Mesh& inMesh); 47 | 48 | template requires ( sizeof(T) < sMaxRootConstantsSize && std::default_initializable ) 49 | void PushGraphicsConstants(const T& inValue); 50 | 51 | template requires ( sizeof(T) < sMaxRootConstantsSize&& std::default_initializable ) 52 | void PushComputeConstants(const T& inValue); 53 | 54 | void BindToSlot(Buffer& inBuffer, EBindSlot inSlot, uint32_t inOffset = 0); 55 | 56 | void Submit(Device& inDevice, ID3D12CommandQueue* inQueue); 57 | 58 | private: 59 | uint32_t m_FrameIndex = 0; 60 | uint64_t m_SubmittedFenceValue = 0; 61 | ComPtr m_Fence = nullptr; 62 | Array m_ResourceRefs; 63 | ComPtr m_CommandList; 64 | ComPtr m_CommandAllocator; 65 | }; 66 | 67 | template requires ( sizeof(T) < sMaxRootConstantsSize&& std::default_initializable ) 68 | void CommandList::PushGraphicsConstants(const T& inValue) 69 | { 70 | m_CommandList->SetGraphicsRoot32BitConstants(0, sizeof(T) / sizeof(DWORD), &inValue, 0); 71 | } 72 | 73 | template // omg c++ 20 concepts, much wow so cool 74 | requires ( sizeof(T) < sMaxRootConstantsSize&& std::default_initializable ) 75 | void CommandList::PushComputeConstants(const T& inValue) 76 | { 77 | m_CommandList->SetComputeRoot32BitConstants(0, sizeof(T) / sizeof(DWORD), &inValue, 0); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /Code/Engine/Renderer/GPUProfiler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Profiler.h" 4 | #include "Resource.h" 5 | #include "CommandList.h" 6 | 7 | namespace RK::DX12 { 8 | 9 | #define EVENT_SCOPE_GPU(cmdlist, name) GPUEventScoped TOKENPASTE2(gpu_event_, __LINE__)(cmdlist, name, 0) 10 | 11 | #define PROFILE_SCOPE_GPU(cmdlist, name) GPUProfileSectionScoped TOKENPASTE2(gpu_profile_section_, __LINE__)(cmdlist, name) 12 | 13 | #define PROFILE_FUNCTION_GPU(cmdlist) GPUProfileSectionScoped TOKENPASTE2(gpu_profile_section_, __LINE__)(cmdlist, __FUNCTION__) 14 | 15 | 16 | struct GPUProfileSection : public ProfileSection 17 | { 18 | uint32_t mBeginQueryIndex = 0; 19 | uint32_t mEndQueryIndex = 0; 20 | 21 | float GetSeconds() const final { return Timer::sGetTicksToSeconds(mEndTick - mStartTick); } 22 | }; 23 | 24 | class GPUProfiler 25 | { 26 | public: 27 | static constexpr int MAX_QUERIES = 2048; 28 | 29 | public: 30 | friend class GPUProfileSection; 31 | friend class GPUProfileSectionScoped; 32 | 33 | GPUProfiler(Device& inDevice); 34 | ~GPUProfiler() = default; 35 | 36 | void Reset(Device& inDevice); 37 | void Resolve(Device& inDevice, CommandList& inCmdList); 38 | void Readback(Device& inDevice, uint32_t inFrameIndex); 39 | 40 | bool IsEnabled() const { return m_IsEnabled; } 41 | void SetEnabled(bool inEnabled) { m_IsEnabled = inEnabled; } 42 | 43 | void BeginQuery(GPUProfileSection& inSection, CommandList& inCmdList); 44 | void EndQuery(GPUProfileSection& inSection, CommandList& inCmdList); 45 | 46 | int AllocateGPU(); 47 | GPUProfileSection& GetSectionGPU(int inIndex) { return m_GPUSections[inIndex]; } 48 | const Array& GetGPUProfileSections() const { return m_GPUReadbackSections[m_ReadbackIndex]; } 49 | 50 | protected: 51 | int m_Depth = 0; 52 | int m_QueryCount = 0; 53 | int m_ReadbackIndex = 0; 54 | bool m_IsEnabled = true; 55 | 56 | uint32_t m_TimestampCount = 0; 57 | ComPtr m_TimestampFence = nullptr; 58 | BufferID m_TimestampReadbackBuffers[sFrameCount]; 59 | ComPtr m_TimestampQueryHeaps[sFrameCount]; 60 | 61 | Mutex m_SectionsMutex; 62 | Array m_GPUSections; 63 | Array m_HistoryGPUSections[sFrameCount]; 64 | Array m_GPUReadbackSections[sFrameCount]; 65 | }; 66 | 67 | extern GPUProfiler* g_GPUProfiler; 68 | 69 | 70 | class GPUProfileSectionScoped 71 | { 72 | public: 73 | GPUProfileSectionScoped(CommandList& inCmdList, const char* inName); 74 | ~GPUProfileSectionScoped(); 75 | 76 | private: 77 | int m_Index = 0; 78 | CommandList& m_CmdList; 79 | }; 80 | 81 | 82 | class GPUEventScoped 83 | { 84 | public: 85 | GPUEventScoped(CommandList& inCmdList, const char* inName, uint32_t inColor); 86 | ~GPUEventScoped(); 87 | 88 | private: 89 | CommandList& m_CmdList; 90 | }; 91 | 92 | } -------------------------------------------------------------------------------- /Code/Engine/Script.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "script.h" 3 | #include "input.h" 4 | #include "scene.h" 5 | #include "assets.h" 6 | #include "application.h" 7 | 8 | // this once contained chaiscript, but in the future I'll mainly support native code or integrate Mono for C# 9 | 10 | namespace RK { 11 | 12 | RTTI_DEFINE_TYPE_NO_FACTORY(INativeScript) {} 13 | 14 | Scene* INativeScript::GetScene() { return m_App->GetScene(); } 15 | 16 | Assets* INativeScript::GetAssets() { return m_App->GetAssets(); } 17 | 18 | Physics* INativeScript::GetPhysics() { return m_App->GetPhysics(); } 19 | 20 | IRenderInterface* INativeScript::GetRenderInterface() { return m_App->GetRenderInterface(); } 21 | 22 | void INativeScript::Log(const std::string& inText) { m_App->LogMessage(inText.data()); } 23 | 24 | } // raekor 25 | -------------------------------------------------------------------------------- /Code/Engine/Script.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ECS.h" 4 | #include "Scene.h" 5 | #include "Assets.h" 6 | 7 | #define DECLARE_SCRIPT_CLASS(T) class T : public INativeScript { public: RTTI_DECLARE_VIRTUAL_TYPE(T); }; 8 | 9 | #define SCRIPT_EXPORTED_FUNCTION_STR "gGetTypes" 10 | #define SCRIPT_EXPORTED_FUNCTION_NAME gGetTypes 11 | 12 | namespace RK { 13 | 14 | class Input; 15 | class Scene; 16 | class Camera; 17 | class Physics; 18 | class Application; 19 | class DebugRenderer; 20 | class IRenderInterface; 21 | 22 | class INativeScript 23 | { 24 | public: 25 | RTTI_DECLARE_VIRTUAL_TYPE(INativeScript); 26 | 27 | friend class Scene; 28 | 29 | typedef int ( __cdecl* RegisterFn ) ( RTTI** ); 30 | 31 | virtual ~INativeScript() = default; 32 | 33 | virtual void OnBind() {}; 34 | 35 | virtual void OnStart() {}; 36 | 37 | virtual void OnStop() {}; 38 | 39 | virtual void OnUpdate(float inDeltaTime) = 0; 40 | 41 | virtual void OnEvent(const SDL_Event& inEvent) = 0; 42 | 43 | RK::Entity GetEntity() const { return m_Entity; } 44 | 45 | // helper functions to interface with the engine 46 | Scene* GetScene(); 47 | Assets* GetAssets(); 48 | Physics* GetPhysics(); 49 | IRenderInterface* GetRenderInterface(); 50 | 51 | template 52 | T& GetComponent(); 53 | 54 | template 55 | bool HasComponent(); 56 | 57 | template 58 | T* FindComponent(); 59 | 60 | template 61 | T* FindComponent(Entity inEntity); 62 | 63 | template requires std::derived_from 64 | T* GetAsset(const Path& inPath); 65 | 66 | void Log(const String& inText); 67 | 68 | protected: 69 | RK::Entity m_Entity; 70 | RK::Input* m_Input = nullptr; 71 | RK::Scene* m_Scene = nullptr; 72 | RK::Application* m_App = nullptr; 73 | RK::DebugRenderer* m_DebugRenderer = nullptr; 74 | }; 75 | 76 | 77 | template 78 | T& INativeScript::GetComponent() 79 | { 80 | return m_Scene->Get(m_Entity); 81 | } 82 | 83 | template 84 | bool INativeScript::HasComponent() 85 | { 86 | return m_Scene->Has(m_Entity); 87 | } 88 | 89 | template 90 | T* INativeScript::FindComponent() 91 | { 92 | return m_Scene->GetPtr(m_Entity); 93 | } 94 | 95 | template 96 | T* INativeScript::FindComponent(Entity inEntity) 97 | { 98 | return m_Scene->GetPtr(inEntity); 99 | } 100 | 101 | template requires std::derived_from 102 | T* INativeScript::GetAsset(const Path& inPath) 103 | { 104 | return GetAssets()->GetAsset(inPath); 105 | } 106 | 107 | 108 | } // Raekor 109 | -------------------------------------------------------------------------------- /Code/Engine/Threading.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace RK { 4 | 5 | class Job 6 | { 7 | public: 8 | using Ptr = std::shared_ptr; 9 | using Function = std::function; 10 | 11 | Job(const Function& inFunction) : m_Function(inFunction) {} 12 | void Run() { m_Function(); m_Finished = true; } 13 | void WaitCPU() const { while (!m_Finished) {} } 14 | 15 | class Barrier 16 | { 17 | public: 18 | Barrier(uint32_t inJobCount) { m_Jobs.reserve(inJobCount); } 19 | void AddJob(Job::Ptr inJob) { m_Jobs.push_back(inJob); } 20 | void Wait() const; 21 | 22 | private: 23 | Array m_Jobs; 24 | }; 25 | 26 | private: 27 | Function m_Function; 28 | Atomic m_Finished = false; 29 | }; 30 | 31 | 32 | class ThreadPool 33 | { 34 | private: 35 | 36 | public: 37 | ThreadPool(); 38 | ThreadPool(uint32_t threadCount); 39 | ~ThreadPool(); 40 | 41 | using JobPtr = Job::Ptr; 42 | /* Queue up a job: lambda of signature void(void) */ 43 | JobPtr QueueJob(const Job::Function& inJobFunction); 44 | 45 | /* Wait for all jobs to finish. */ 46 | void WaitForJobs(); 47 | 48 | /* exits all the threads. */ 49 | void Shutdown(); 50 | 51 | /* Scoped lock on the global mutex, 52 | useful for ensuring thread safety inside a job function. */ 53 | Mutex& GetMutex() { return m_Mutex; } 54 | 55 | void SetActiveThreadCount(uint32_t inValue) { m_ActiveThreadCount = std::min(inValue, GetThreadCount()); } 56 | 57 | uint32_t GetThreadCount() { return uint32_t(m_Threads.size()); } 58 | int32_t GetActiveJobCount() { return m_ActiveJobCount.load(); } 59 | 60 | private: 61 | // per-thread function that waits on and executes tasks 62 | void ThreadLoop(uint32_t inThreadIndex); 63 | 64 | bool m_Quit = false; 65 | Mutex m_Mutex; 66 | Queue m_JobQueue; 67 | Array m_Threads; 68 | Atomic m_ActiveJobCount; 69 | Atomic m_ActiveThreadCount; 70 | std::condition_variable m_ConditionVariable; 71 | }; 72 | 73 | 74 | extern ThreadPool g_ThreadPool; 75 | 76 | 77 | } -------------------------------------------------------------------------------- /Code/Engine/Timer.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "timer.h" 3 | 4 | namespace RK { 5 | 6 | uint64_t GetCPUFrequency() 7 | { 8 | static uint64_t frequency = SDL_GetPerformanceFrequency(); 9 | return frequency; 10 | } 11 | 12 | Timer::Timer() 13 | { 14 | m_StartTime = SDL_GetPerformanceCounter(); 15 | } 16 | 17 | 18 | float Timer::Restart() 19 | { 20 | float time = GetElapsedTime(); 21 | m_StartTime = SDL_GetPerformanceCounter(); 22 | return time; 23 | } 24 | 25 | 26 | float Timer::GetElapsedTime() 27 | { 28 | return (float)( ( SDL_GetPerformanceCounter() - m_StartTime ) / (float)GetCPUFrequency() ); 29 | } 30 | 31 | 32 | uint64_t Timer::sGetCurrentTick() 33 | { 34 | return SDL_GetPerformanceCounter(); 35 | } 36 | 37 | 38 | float Timer::sGetTicksToSeconds(uint64_t inTicks) 39 | { 40 | static const uint64_t frequency = GetCPUFrequency(); 41 | return (float)( ( inTicks ) / (float)frequency ); 42 | } 43 | 44 | 45 | std::string Timer::GetElapsedFormatted() 46 | { 47 | return std::to_string((float)( ( SDL_GetPerformanceCounter() - m_StartTime ) / (float)GetCPUFrequency() )); 48 | } 49 | 50 | } // raekor -------------------------------------------------------------------------------- /Code/Engine/Timer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace RK { 4 | 5 | class Timer 6 | { 7 | public: 8 | /* Creates and starts a Timer. */ 9 | Timer(); 10 | 11 | /* Restarts the timer and returns the elapsed time in seconds. */ 12 | float Restart(); 13 | 14 | /* Returns the elapsed time in seconds. */ 15 | float GetElapsedTime(); 16 | 17 | /* Returns the elapsed time in seconds. */ 18 | std::string GetElapsedFormatted(); 19 | 20 | static uint64_t sGetCurrentTick(); 21 | static float sGetTicksToSeconds(uint64_t inTicks); 22 | 23 | static float sToMilliseconds(float inTime) { return inTime * 1000; } 24 | static float sToMicroseconds(float inTime) { return inTime * 1'000'000; } 25 | 26 | private: 27 | uint64_t m_StartTime = 0; 28 | }; 29 | 30 | } // namespace Raekor -------------------------------------------------------------------------------- /Code/Engine/UIRenderer.cpp: -------------------------------------------------------------------------------- 1 | #include "PCH.h" 2 | #include "UIRenderer.h" 3 | #include "Renderer/Shared.h" 4 | 5 | namespace RK { 6 | 7 | UIRenderer g_UIRenderer; 8 | 9 | void UIRenderer::Reset() 10 | { 11 | m_DrawCommandBuffer.clear(); 12 | m_DrawCommandHeaderBuffer.clear(); 13 | } 14 | 15 | void UIRenderer::AddRectFilled(Vec2 inPos, Vec2 inSize, float inRadius, Vec4 inColor) 16 | { 17 | DrawCommandHeader header = {}; 18 | header.type = DRAW_COMMAND_RECT; 19 | header.startOffset = m_DrawCommandBuffer.size(); 20 | m_DrawCommandHeaderBuffer.push_back(header); 21 | 22 | m_DrawCommandBuffer.push_back(inColor); 23 | m_DrawCommandBuffer.push_back(Vec4(inPos.x, inPos.y, inSize.x, inSize.y)); 24 | m_DrawCommandBuffer.push_back(Vec4(inRadius, inRadius, inRadius, inRadius)); 25 | } 26 | 27 | void UIRenderer::AddCircleFilled(Vec2 inPos, float inRadius, Vec4 inColor) 28 | { 29 | DrawCommandHeader header = {}; 30 | header.type = DRAW_COMMAND_CIRCLE_FILLED; 31 | header.startOffset = m_DrawCommandBuffer.size(); 32 | m_DrawCommandHeaderBuffer.push_back(header); 33 | 34 | m_DrawCommandBuffer.push_back(inColor); 35 | m_DrawCommandBuffer.push_back(Vec4(inPos.x, inPos.y, inRadius, 0.0f)); 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /Code/Engine/UIRenderer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Renderer/Shared.h" 4 | 5 | namespace RK { 6 | 7 | class UIRenderer 8 | { 9 | public: 10 | void Reset(); 11 | 12 | void AddRectFilled(Vec2 inPos, Vec2 inSize, float inRadius, Vec4 inColor); 13 | void AddCircleFilled(Vec2 inPos, float inRadius, Vec4 inColor); 14 | 15 | Slice GetDrawCommands() const { return Slice(m_DrawCommandBuffer); } 16 | Slice GetDrawCommandHeaders() const { return Slice(m_DrawCommandHeaderBuffer); } 17 | 18 | private: 19 | Array m_DrawCommandBuffer; 20 | Array m_DrawCommandHeaderBuffer; 21 | }; 22 | 23 | extern UIRenderer g_UIRenderer; 24 | 25 | } -------------------------------------------------------------------------------- /Code/Engine/Undo.cpp: -------------------------------------------------------------------------------- 1 | #include "PCH.h" 2 | #include "Undo.h" 3 | 4 | namespace RK { 5 | 6 | void UndoSystem::Undo() 7 | { 8 | if (!HasUndo()) 9 | return; 10 | 11 | //std::cout << "Undo " << m_UndoStack.back()->GetName() << " at index " << m_UndoStack.size() - 1 << std::endl; 12 | 13 | m_UndoStack.back()->Undo(m_Scene); 14 | m_RedoStack.push_back(m_UndoStack.back()); 15 | m_UndoStack.pop_back(); 16 | } 17 | 18 | void UndoSystem::Redo() 19 | { 20 | if (!HasRedo()) 21 | return; 22 | 23 | //std::cout << "Redo " << m_RedoStack.back()->GetName() << " at index " << m_RedoStack.size() - 1 << std::endl; 24 | 25 | m_RedoStack.back()->Redo(m_Scene); 26 | m_UndoStack.push_back(m_RedoStack.back()); 27 | m_RedoStack.pop_back(); 28 | } 29 | 30 | void UndoSystem::Clear() 31 | { 32 | m_UndoStack.clear(); 33 | m_RedoStack.clear(); 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /Code/Engine/Undo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ECS.h" 4 | #include "RTTI.h" 5 | #include "Scene.h" 6 | #include "Components.h" 7 | 8 | namespace RK { 9 | 10 | struct UndoAction 11 | { 12 | virtual ~UndoAction() = default; 13 | 14 | virtual const char* GetName() = 0; 15 | virtual void Undo(Scene& inScene) = 0; 16 | virtual void Redo(Scene& inScene) = 0; 17 | }; 18 | 19 | class UndoSystem 20 | { 21 | public: 22 | UndoSystem(Scene& inScene) : m_Scene(inScene) {} 23 | 24 | template requires std::is_base_of_v 25 | void PushUndo(const T& inAction) 26 | { 27 | m_RedoStack.clear(); 28 | m_UndoStack.push_back(std::make_shared(inAction)); 29 | //std::cout << "Pushed " << m_UndoStack.back()->GetName() << " at index " << m_UndoStack.size() - 1 << std::endl; 30 | } 31 | 32 | bool HasUndo() const { return !m_UndoStack.empty(); } 33 | bool HasRedo() const { return !m_RedoStack.empty(); } 34 | 35 | void Undo(); 36 | void Redo(); 37 | void Clear(); 38 | 39 | private: 40 | Scene& m_Scene; 41 | Array> m_UndoStack; 42 | Array> m_RedoStack; 43 | }; 44 | 45 | template requires ( sizeof(T) < 1024 && std::default_initializable ) 46 | struct ComponentUndo : public UndoAction 47 | { 48 | T current; 49 | T previous; 50 | Entity entity = Entity::Null; 51 | 52 | virtual const char* GetName() { return RTTI_OF().GetTypeName(); } 53 | 54 | void Undo(Scene& inScene) override 55 | { 56 | T& component = inScene.Get(entity); 57 | component = previous; 58 | } 59 | 60 | void Redo(Scene& inScene) override 61 | { 62 | T& component = inScene.Get(entity); 63 | component = current; 64 | } 65 | }; 66 | 67 | } -------------------------------------------------------------------------------- /Code/Game/Game.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Assets.h" 4 | #include "Physics.h" 5 | #include "Application.h" 6 | #include "Renderer/Device.h" 7 | #include "Renderer/Resource.h" 8 | #include "Renderer/Renderer.h" 9 | 10 | namespace RK { 11 | 12 | class GameApp : public Game 13 | { 14 | public: 15 | GameApp(); 16 | ~GameApp(); 17 | 18 | void OnUpdate(float inDeltaTime) override; 19 | void OnEvent(const SDL_Event& inEvent) override; 20 | 21 | void SetCameraEntity(Entity inEntity) { m_CameraEntity = inEntity; } 22 | Entity GetCameraEntity() const { return m_CameraEntity; } 23 | 24 | Scene* GetScene() override { return &m_Scene; } 25 | Assets* GetAssets() override { return &m_Assets; } 26 | Physics* GetPhysics() override { return &m_Physics; } 27 | IRenderInterface* GetRenderInterface() override { return &m_RenderInterface; } 28 | 29 | private: 30 | Scene m_Scene; 31 | Assets m_Assets; 32 | Physics m_Physics; 33 | 34 | DX12::Device m_Device; 35 | DX12::Renderer m_Renderer; 36 | DX12::RayTracedScene m_RayTracedScene; 37 | DX12::RenderInterface m_RenderInterface; 38 | 39 | DX12::TextureID m_DefaultWhiteTexture; 40 | DX12::TextureID m_DefaultBlackTexture; 41 | DX12::TextureID m_DefaultNormalTexture; 42 | 43 | Camera m_Camera; 44 | Entity m_CameraEntity = Entity::Null; 45 | }; 46 | 47 | } // RK -------------------------------------------------------------------------------- /Code/Game/Scripts/AnimateSunScript.cpp: -------------------------------------------------------------------------------- 1 | #define RAEKOR_SCRIPT 2 | #include "../Engine/raekor.h" 3 | 4 | namespace RK { 5 | 6 | class AnimateSunScript : public INativeScript 7 | { 8 | public: 9 | RTTI_DECLARE_VIRTUAL_TYPE(AnimateSunScript); 10 | 11 | void OnUpdate(float inDeltaTime) override 12 | { 13 | Transform& transform = GetComponent(); 14 | Vec3 degrees = glm::degrees(glm::eulerAngles(transform.rotation)); 15 | 16 | degrees.x += sin(m_Speed * inDeltaTime); 17 | 18 | if (degrees.x > 90) 19 | degrees.x = -90; 20 | 21 | if (degrees.x < -90) 22 | degrees.x = 90; 23 | 24 | transform.rotation = glm::quat(glm::radians(degrees)); 25 | 26 | transform.Compose(); 27 | } 28 | 29 | void OnEvent(const SDL_Event& inEvent) 30 | { 31 | } 32 | 33 | private: 34 | float m_Speed = 0.150f; 35 | }; 36 | 37 | 38 | RTTI_DEFINE_TYPE(AnimateSunScript) 39 | { 40 | RTTI_DEFINE_TYPE_INHERITANCE(AnimateSunScript, INativeScript); 41 | 42 | RTTI_DEFINE_SCRIPT_MEMBER(AnimateSunScript, SERIALIZE_ALL, "Speed", m_Speed); 43 | } 44 | 45 | } // RK 46 | -------------------------------------------------------------------------------- /Code/Game/Scripts/LightsScript.cpp: -------------------------------------------------------------------------------- 1 | #define RAEKOR_SCRIPT 2 | #include "../Engine/raekor.h" 3 | 4 | namespace RK { 5 | 6 | class LightsScript : public INativeScript 7 | { 8 | public: 9 | RTTI_DECLARE_VIRTUAL_TYPE(LightsScript); 10 | 11 | void OnBind() override 12 | { 13 | for (const auto& [entity, light] : m_Scene->Each()) 14 | light.color.a = 0.0f; 15 | 16 | BBox3D scene_bounds; 17 | 18 | for (const auto& [entity, transform, mesh] : m_Scene->Each()) 19 | scene_bounds.Combine(mesh.bbox.Transformed(transform.worldTransform)); 20 | 21 | constexpr float cPointLightRadius = 2.5f; 22 | constexpr float cPointLightIntensity = 6.0f; 23 | 24 | int point_light_count = 0; 25 | 26 | for (float x = scene_bounds.GetMin().x; x < scene_bounds.GetMax().x; x += cPointLightRadius) 27 | { 28 | for (float y = scene_bounds.GetMin().y; y < scene_bounds.GetMax().y; y += cPointLightRadius) 29 | { 30 | for (float z = scene_bounds.GetMin().z; z < scene_bounds.GetMax().z; z += cPointLightRadius) 31 | { 32 | const Entity entity = m_Scene->CreateSpatialEntity(std::format("PointLight {}", point_light_count)); 33 | 34 | GetScene()->ParentTo(entity, m_Entity); 35 | 36 | Transform& transform = m_Scene->Get(entity); 37 | transform.position = Vec3(x, y, z) + Vec3(cPointLightRadius) * 0.5f; 38 | transform.Compose(); 39 | 40 | Light& light = m_Scene->Add(entity); 41 | light.type = LIGHT_TYPE_POINT; 42 | light.attributes.x = cPointLightRadius; 43 | 44 | light.color.r = gRandomFloatZO(); 45 | light.color.g = gRandomFloatZO(); 46 | light.color.b = gRandomFloatZO(); 47 | light.color.a = cPointLightIntensity; 48 | 49 | point_light_count++; 50 | } 51 | } 52 | } 53 | 54 | GetComponent().name = std::format("PointLights ({})", point_light_count); 55 | } 56 | 57 | void OnUpdate(float inDeltaTime) override 58 | { 59 | Transform& transform = GetComponent(); 60 | 61 | transform.rotation *= glm::angleAxis(float(M_PI) / 128.0f, Vec3(0.0f, 1.0f, 0.0f)); 62 | 63 | transform.Compose(); 64 | } 65 | 66 | void OnEvent(const SDL_Event& inEvent) {} 67 | }; 68 | 69 | 70 | RTTI_DEFINE_TYPE(LightsScript) 71 | { 72 | RTTI_DEFINE_TYPE_INHERITANCE(LightsScript, INativeScript); 73 | } 74 | 75 | } // RK -------------------------------------------------------------------------------- /Code/Game/Scripts/Scripts.cpp: -------------------------------------------------------------------------------- 1 | #include "PCH.h" 2 | #include "Scripts.h" 3 | #include "../Engine/RTTI.h" 4 | #include "../Engine/Script.h" 5 | 6 | namespace RK { 7 | 8 | DECLARE_SCRIPT_CLASS(GunScript); 9 | DECLARE_SCRIPT_CLASS(TestScript); 10 | DECLARE_SCRIPT_CLASS(LightsScript); 11 | DECLARE_SCRIPT_CLASS(AnimateSunScript); 12 | DECLARE_SCRIPT_CLASS(VehicleControllerScript); 13 | DECLARE_SCRIPT_CLASS(CharacterControllerScript); 14 | 15 | void gRegisterScriptTypes() 16 | { 17 | g_RTTIFactory.Register(); 18 | g_RTTIFactory.Register(); 19 | g_RTTIFactory.Register(); 20 | g_RTTIFactory.Register(); 21 | g_RTTIFactory.Register(); 22 | g_RTTIFactory.Register(); 23 | } 24 | 25 | } // RK 26 | 27 | -------------------------------------------------------------------------------- /Code/Game/Scripts/Scripts.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace RK { 4 | 5 | class RTTI; 6 | extern void gRegisterScriptTypes(); 7 | int SCRIPT_EXPORTED_FUNCTION_NAME(RTTI** outTypes); 8 | 9 | } // RK 10 | -------------------------------------------------------------------------------- /Code/Game/main.cpp: -------------------------------------------------------------------------------- 1 | #include "PCH.h" 2 | #include "Game.h" 3 | #include "../Engine/RTTI.h" 4 | #include "../Engine/CVars.h" 5 | #include "../Engine/Script.h" 6 | 7 | using namespace RK; 8 | 9 | int main(int argc, char** argv) 10 | { 11 | g_CVariables = new CVariables(argc, argv); 12 | 13 | Application* app = new GameApp(); 14 | 15 | app->Run(); 16 | 17 | delete app; 18 | 19 | return 0; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /Images/Editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Images/Editor.png -------------------------------------------------------------------------------- /Images/Thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/Images/Thumbnail.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Nico van Bentum 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Build (CMake - Windows) 2 | 3 | ### Requirements 4 | * Graphics card with RTX and Shader Model 6_6 support. 5 | * Windows SDK 10.0.20348 or higher (configure using the Visual Studio Installer). 6 | 7 | ## Instructions 8 | 9 | Clone this repository using 10 | ```git clone --recursive https://github.com/nicovanbentum/Raekor.git``` 11 | >**_NOTE:_** If the path to the repository contains any whitespace the shaders will fail to compile. 12 | 13 | * Run ``` cmake -B Build ``` from the root of the repository. This can take a while as it builds everything, there are no pre-built binaries. 14 | 15 | * Build using the generated ```Solution.sln``` visual studio solution inside of the newly created ```Build``` folder. 16 | 17 | # Engine 18 | ![image](https://github.com/nicovanbentum/Raekor/blob/DX12-Only/Images/Editor.png) 19 | * Simple Job System 20 | * Simple CVar system 21 | * JoltPhysics Integration 22 | * Hotloadable C++ scripts (WIP) 23 | * Skinning & Animation 24 | * Custom Scene Format 25 | - GLTF / FBX / OBJ import (cgltf, ufbx, assimp) 26 | - RTTI-based Serialisation 27 | - Entity Component System 28 | - Multi-threaded Asset Loading 29 | * A scene editor using ImGui that can transform objects, adjust materials, merge scenes, create sequences.. 30 | 31 | ### Renderer 32 | ![image](https://github.com/nicovanbentum/Raekor/blob/DX12-Only/Images/Thumbnail.png) 33 | 34 | Basic RenderGraph architecture (automatically creates resource views and handles resource barriers) on top of DirectX 12. Heavily relies on shader model 6_6 bindless. Lots of ray tracing. Implements an editor, so can edit the scene in real-time. The rendergraph currently features: 35 | 36 | - Compute Skinning Pass 37 | - Geometry Buffer Pass 38 | - Path Trace Pass (For comparisons) 39 | - Ray Traced Shadows (denoiser WIP) 40 | - Ray Traced Ambient Occlusion (denoiser WIP) 41 | - Ray Traced Reflections (denoiser WIP) 42 | - Ray Traced Irradiance Probes (DDGI) 43 | - Deferred Shading 44 | - TAA / FSR2 / DLSS / XeSS 45 | - Post Processing 46 | 47 | ![image](https://svgshare.com/i/yZn.svg) 48 | -------------------------------------------------------------------------------- /ThirdParty/Agility-SDK/D3D12Core.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/Agility-SDK/D3D12Core.dll -------------------------------------------------------------------------------- /ThirdParty/Agility-SDK/agility.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | 3 | D3D12SDKVersion DATA PRIVATE 4 | 5 | D3D12SDKPath DATA PRIVATE -------------------------------------------------------------------------------- /ThirdParty/Agility-SDK/d3d12SDKLayers.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/Agility-SDK/d3d12SDKLayers.dll -------------------------------------------------------------------------------- /ThirdParty/DirectStorage/dstorage.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/DirectStorage/dstorage.dll -------------------------------------------------------------------------------- /ThirdParty/DirectStorage/dstorage.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/DirectStorage/dstorage.lib -------------------------------------------------------------------------------- /ThirdParty/DirectStorage/dstoragecore.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/DirectStorage/dstoragecore.dll -------------------------------------------------------------------------------- /ThirdParty/FSR2/lib/ffx_fsr2_api_dx12_x64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/FSR2/lib/ffx_fsr2_api_dx12_x64.lib -------------------------------------------------------------------------------- /ThirdParty/FSR2/lib/ffx_fsr2_api_dx12_x64d.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/FSR2/lib/ffx_fsr2_api_dx12_x64d.lib -------------------------------------------------------------------------------- /ThirdParty/FSR2/lib/ffx_fsr2_api_x64.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/FSR2/lib/ffx_fsr2_api_x64.lib -------------------------------------------------------------------------------- /ThirdParty/FSR2/lib/ffx_fsr2_api_x64d.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/FSR2/lib/ffx_fsr2_api_x64d.lib -------------------------------------------------------------------------------- /ThirdParty/FSR2/src/ffx_assert.cpp: -------------------------------------------------------------------------------- 1 | // This file is part of the FidelityFX SDK. 2 | // 3 | // Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | #include "ffx_assert.h" 23 | #include // for malloc() 24 | 25 | #ifdef _WIN32 26 | #ifndef WIN32_LEAN_AND_MEAN 27 | #define WIN32_LEAN_AND_MEAN 28 | #endif 29 | #include // required for OutputDebugString() 30 | #include // required for sprintf_s 31 | #endif // #ifndef _WIN32 32 | 33 | static FfxAssertCallback s_assertCallback; 34 | 35 | // set the printing callback function 36 | void ffxAssertSetPrintingCallback(FfxAssertCallback callback) 37 | { 38 | s_assertCallback = callback; 39 | return; 40 | } 41 | 42 | // implementation of assert reporting 43 | bool ffxAssertReport(const char* file, int32_t line, const char* condition, const char* message) 44 | { 45 | if (!file) { 46 | 47 | return true; 48 | } 49 | 50 | #ifdef _WIN32 51 | // form the final assertion string and output to the TTY. 52 | const size_t bufferSize = static_cast(snprintf(nullptr, 0, "%s(%d): ASSERTION FAILED. %s\n", file, line, message ? message : condition)) + 1; 53 | char* tempBuf = static_cast(malloc(bufferSize)); 54 | if (!tempBuf) { 55 | 56 | return true; 57 | } 58 | 59 | if (!message) { 60 | sprintf_s(tempBuf, bufferSize, "%s(%d): ASSERTION FAILED. %s\n", file, line, condition); 61 | } else { 62 | sprintf_s(tempBuf, bufferSize, "%s(%d): ASSERTION FAILED. %s\n", file, line, message); 63 | } 64 | 65 | if (!s_assertCallback) { 66 | OutputDebugStringA(tempBuf); 67 | } else { 68 | s_assertCallback(tempBuf); 69 | } 70 | 71 | // free the buffer. 72 | free(tempBuf); 73 | 74 | #else 75 | FFX_UNUSED(line); 76 | FFX_UNUSED(condition); 77 | FFX_UNUSED(message); 78 | #endif 79 | 80 | return true; 81 | } 82 | -------------------------------------------------------------------------------- /ThirdParty/FSR2/src/ffx_fsr2_maximum_bias.h: -------------------------------------------------------------------------------- 1 | // This file is part of the FidelityFX SDK. 2 | // 3 | // Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | // @internal 23 | 24 | #pragma once 25 | 26 | static const int FFX_FSR2_MAXIMUM_BIAS_TEXTURE_WIDTH = 16; 27 | static const int FFX_FSR2_MAXIMUM_BIAS_TEXTURE_HEIGHT = 16; 28 | static const float ffxFsr2MaximumBias[] = { 29 | 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.876f, 1.809f, 1.772f, 1.753f, 1.748f, 30 | 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.869f, 1.801f, 1.764f, 1.745f, 1.739f, 31 | 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.976f, 1.841f, 1.774f, 1.737f, 1.716f, 1.71f, 32 | 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.914f, 1.784f, 1.716f, 1.673f, 1.649f, 1.641f, 33 | 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.793f, 1.676f, 1.604f, 1.562f, 1.54f, 1.533f, 34 | 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.802f, 1.619f, 1.536f, 1.492f, 1.467f, 1.454f, 1.449f, 35 | 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.812f, 1.575f, 1.496f, 1.456f, 1.432f, 1.416f, 1.408f, 1.405f, 36 | 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.555f, 1.479f, 1.438f, 1.413f, 1.398f, 1.387f, 1.381f, 1.379f, 37 | 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.812f, 1.555f, 1.474f, 1.43f, 1.404f, 1.387f, 1.376f, 1.368f, 1.363f, 1.362f, 38 | 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 1.802f, 1.575f, 1.479f, 1.43f, 1.401f, 1.382f, 1.369f, 1.36f, 1.354f, 1.351f, 1.35f, 39 | 2.0f, 2.0f, 1.976f, 1.914f, 1.793f, 1.619f, 1.496f, 1.438f, 1.404f, 1.382f, 1.367f, 1.357f, 1.349f, 1.344f, 1.341f, 1.34f, 40 | 1.876f, 1.869f, 1.841f, 1.784f, 1.676f, 1.536f, 1.456f, 1.413f, 1.387f, 1.369f, 1.357f, 1.347f, 1.341f, 1.336f, 1.333f, 1.332f, 41 | 1.809f, 1.801f, 1.774f, 1.716f, 1.604f, 1.492f, 1.432f, 1.398f, 1.376f, 1.36f, 1.349f, 1.341f, 1.335f, 1.33f, 1.328f, 1.327f, 42 | 1.772f, 1.764f, 1.737f, 1.673f, 1.562f, 1.467f, 1.416f, 1.387f, 1.368f, 1.354f, 1.344f, 1.336f, 1.33f, 1.326f, 1.323f, 1.323f, 43 | 1.753f, 1.745f, 1.716f, 1.649f, 1.54f, 1.454f, 1.408f, 1.381f, 1.363f, 1.351f, 1.341f, 1.333f, 1.328f, 1.323f, 1.321f, 1.32f, 44 | 1.748f, 1.739f, 1.71f, 1.641f, 1.533f, 1.449f, 1.405f, 1.379f, 1.362f, 1.35f, 1.34f, 1.332f, 1.327f, 1.323f, 1.32f, 1.319f, 45 | 46 | }; 47 | -------------------------------------------------------------------------------- /ThirdParty/PIX/bin/x64/WinPixEventRuntime.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/PIX/bin/x64/WinPixEventRuntime.dll -------------------------------------------------------------------------------- /ThirdParty/PIX/bin/x64/WinPixEventRuntime.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/PIX/bin/x64/WinPixEventRuntime.lib -------------------------------------------------------------------------------- /ThirdParty/cgltf/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018-2021 Johannes Kuhlmann 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/README.md: -------------------------------------------------------------------------------- 1 | ## Discord Game SDK 2 | 3 | > The SDK is currently under extensive development and is subject to change. Suggestions 4 | > about the current API are welcome. 5 | 6 | ### Setup 7 | 8 | - Create an application on the Discord [developer site](https://discordapp.com/developers/applications/me). 9 | - Set a redirect URL. If you don't have one right now, just use . 10 | - Enable Rich Presence for the application. This enables whitelist access for the SDK. 11 | - When you are ready to test with more people, add them to the whitelist. 12 | - Copy the **Client ID**. 13 | - Use this `CLIENT_ID` when initializing the SDK. 14 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/achievement_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | namespace discord { 6 | 7 | class AchievementManager final { 8 | public: 9 | ~AchievementManager() = default; 10 | 11 | void SetUserAchievement(Snowflake achievementId, 12 | std::uint8_t percentComplete, 13 | std::function callback); 14 | void FetchUserAchievements(std::function callback); 15 | void CountUserAchievements(std::int32_t* count); 16 | Result GetUserAchievement(Snowflake userAchievementId, UserAchievement* userAchievement); 17 | Result GetUserAchievementAt(std::int32_t index, UserAchievement* userAchievement); 18 | 19 | Event OnUserAchievementUpdate; 20 | 21 | private: 22 | friend class Core; 23 | 24 | AchievementManager() = default; 25 | AchievementManager(AchievementManager const& rhs) = delete; 26 | AchievementManager& operator=(AchievementManager const& rhs) = delete; 27 | AchievementManager(AchievementManager&& rhs) = delete; 28 | AchievementManager& operator=(AchievementManager&& rhs) = delete; 29 | 30 | IDiscordAchievementManager* internal_; 31 | static IDiscordAchievementEvents events_; 32 | }; 33 | 34 | } // namespace discord 35 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/activity_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | namespace discord { 6 | 7 | class ActivityManager final { 8 | public: 9 | ~ActivityManager() = default; 10 | 11 | Result RegisterCommand(char const* command); 12 | Result RegisterSteam(std::uint32_t steamId); 13 | void UpdateActivity(Activity const& activity, std::function callback); 14 | void ClearActivity(std::function callback); 15 | void SendRequestReply(UserId userId, 16 | ActivityJoinRequestReply reply, 17 | std::function callback); 18 | void SendInvite(UserId userId, 19 | ActivityActionType type, 20 | char const* content, 21 | std::function callback); 22 | void AcceptInvite(UserId userId, std::function callback); 23 | 24 | Event OnActivityJoin; 25 | Event OnActivitySpectate; 26 | Event OnActivityJoinRequest; 27 | Event OnActivityInvite; 28 | 29 | private: 30 | friend class Core; 31 | 32 | ActivityManager() = default; 33 | ActivityManager(ActivityManager const& rhs) = delete; 34 | ActivityManager& operator=(ActivityManager const& rhs) = delete; 35 | ActivityManager(ActivityManager&& rhs) = delete; 36 | ActivityManager& operator=(ActivityManager&& rhs) = delete; 37 | 38 | IDiscordActivityManager* internal_; 39 | static IDiscordActivityEvents events_; 40 | }; 41 | 42 | } // namespace discord 43 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/application_manager.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(_CRT_SECURE_NO_WARNINGS) 2 | #define _CRT_SECURE_NO_WARNINGS 3 | #endif 4 | 5 | #include "application_manager.h" 6 | 7 | #include "core.h" 8 | 9 | #include 10 | #include 11 | 12 | namespace discord { 13 | 14 | void ApplicationManager::ValidateOrExit(std::function callback) 15 | { 16 | static auto wrapper = [](void* callbackData, EDiscordResult result) -> void { 17 | std::unique_ptr> cb( 18 | reinterpret_cast*>(callbackData)); 19 | if (!cb || !(*cb)) { 20 | return; 21 | } 22 | (*cb)(static_cast(result)); 23 | }; 24 | std::unique_ptr> cb{}; 25 | cb.reset(new std::function(std::move(callback))); 26 | internal_->validate_or_exit(internal_, cb.release(), wrapper); 27 | } 28 | 29 | void ApplicationManager::GetCurrentLocale(char locale[128]) 30 | { 31 | if (!locale) { 32 | return; 33 | } 34 | 35 | internal_->get_current_locale(internal_, reinterpret_cast(locale)); 36 | } 37 | 38 | void ApplicationManager::GetCurrentBranch(char branch[4096]) 39 | { 40 | if (!branch) { 41 | return; 42 | } 43 | 44 | internal_->get_current_branch(internal_, reinterpret_cast(branch)); 45 | } 46 | 47 | void ApplicationManager::GetOAuth2Token(std::function callback) 48 | { 49 | static auto wrapper = 50 | [](void* callbackData, EDiscordResult result, DiscordOAuth2Token* oauth2Token) -> void { 51 | std::unique_ptr> cb( 52 | reinterpret_cast*>(callbackData)); 53 | if (!cb || !(*cb)) { 54 | return; 55 | } 56 | (*cb)(static_cast(result), *reinterpret_cast(oauth2Token)); 57 | }; 58 | std::unique_ptr> cb{}; 59 | cb.reset(new std::function(std::move(callback))); 60 | internal_->get_oauth2_token(internal_, cb.release(), wrapper); 61 | } 62 | 63 | void ApplicationManager::GetTicket(std::function callback) 64 | { 65 | static auto wrapper = [](void* callbackData, EDiscordResult result, char const* data) -> void { 66 | std::unique_ptr> cb( 67 | reinterpret_cast*>(callbackData)); 68 | if (!cb || !(*cb)) { 69 | return; 70 | } 71 | (*cb)(static_cast(result), static_cast(data)); 72 | }; 73 | std::unique_ptr> cb{}; 74 | cb.reset(new std::function(std::move(callback))); 75 | internal_->get_ticket(internal_, cb.release(), wrapper); 76 | } 77 | 78 | } // namespace discord 79 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/application_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | namespace discord { 6 | 7 | class ApplicationManager final { 8 | public: 9 | ~ApplicationManager() = default; 10 | 11 | void ValidateOrExit(std::function callback); 12 | void GetCurrentLocale(char locale[128]); 13 | void GetCurrentBranch(char branch[4096]); 14 | void GetOAuth2Token(std::function callback); 15 | void GetTicket(std::function callback); 16 | 17 | private: 18 | friend class Core; 19 | 20 | ApplicationManager() = default; 21 | ApplicationManager(ApplicationManager const& rhs) = delete; 22 | ApplicationManager& operator=(ApplicationManager const& rhs) = delete; 23 | ApplicationManager(ApplicationManager&& rhs) = delete; 24 | ApplicationManager& operator=(ApplicationManager&& rhs) = delete; 25 | 26 | IDiscordApplicationManager* internal_; 27 | static IDiscordApplicationEvents events_; 28 | }; 29 | 30 | } // namespace discord 31 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/core.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | #include "application_manager.h" 5 | #include "user_manager.h" 6 | #include "image_manager.h" 7 | #include "activity_manager.h" 8 | #include "relationship_manager.h" 9 | #include "lobby_manager.h" 10 | #include "network_manager.h" 11 | #include "overlay_manager.h" 12 | #include "storage_manager.h" 13 | #include "store_manager.h" 14 | #include "voice_manager.h" 15 | #include "achievement_manager.h" 16 | 17 | namespace discord { 18 | 19 | class Core final { 20 | public: 21 | static Result Create(ClientId clientId, std::uint64_t flags, Core** instance); 22 | 23 | ~Core(); 24 | 25 | Result RunCallbacks(); 26 | void SetLogHook(LogLevel minLevel, std::function hook); 27 | 28 | discord::ApplicationManager& ApplicationManager(); 29 | discord::UserManager& UserManager(); 30 | discord::ImageManager& ImageManager(); 31 | discord::ActivityManager& ActivityManager(); 32 | discord::RelationshipManager& RelationshipManager(); 33 | discord::LobbyManager& LobbyManager(); 34 | discord::NetworkManager& NetworkManager(); 35 | discord::OverlayManager& OverlayManager(); 36 | discord::StorageManager& StorageManager(); 37 | discord::StoreManager& StoreManager(); 38 | discord::VoiceManager& VoiceManager(); 39 | discord::AchievementManager& AchievementManager(); 40 | 41 | private: 42 | Core() = default; 43 | Core(Core const& rhs) = delete; 44 | Core& operator=(Core const& rhs) = delete; 45 | Core(Core&& rhs) = delete; 46 | Core& operator=(Core&& rhs) = delete; 47 | 48 | IDiscordCore* internal_; 49 | Event setLogHook_; 50 | discord::ApplicationManager applicationManager_; 51 | discord::UserManager userManager_; 52 | discord::ImageManager imageManager_; 53 | discord::ActivityManager activityManager_; 54 | discord::RelationshipManager relationshipManager_; 55 | discord::LobbyManager lobbyManager_; 56 | discord::NetworkManager networkManager_; 57 | discord::OverlayManager overlayManager_; 58 | discord::StorageManager storageManager_; 59 | discord::StoreManager storeManager_; 60 | discord::VoiceManager voiceManager_; 61 | discord::AchievementManager achievementManager_; 62 | }; 63 | 64 | } // namespace discord 65 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/discord.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | #include "core.h" 5 | #include "application_manager.h" 6 | #include "user_manager.h" 7 | #include "image_manager.h" 8 | #include "activity_manager.h" 9 | #include "relationship_manager.h" 10 | #include "lobby_manager.h" 11 | #include "network_manager.h" 12 | #include "overlay_manager.h" 13 | #include "storage_manager.h" 14 | #include "store_manager.h" 15 | #include "voice_manager.h" 16 | #include "achievement_manager.h" 17 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/event.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace discord { 7 | 8 | template 9 | class Event final { 10 | public: 11 | using Token = int; 12 | 13 | Event() { slots_.reserve(4); } 14 | 15 | Event(Event const&) = default; 16 | Event(Event&&) = default; 17 | ~Event() = default; 18 | 19 | Event& operator=(Event const&) = default; 20 | Event& operator=(Event&&) = default; 21 | 22 | template 23 | Token Connect(EventHandler slot) 24 | { 25 | slots_.emplace_back(Slot{nextToken_, std::move(slot)}); 26 | return nextToken_++; 27 | } 28 | 29 | void Disconnect(Token token) 30 | { 31 | for (auto& slot : slots_) { 32 | if (slot.token == token) { 33 | slot = slots_.back(); 34 | slots_.pop_back(); 35 | break; 36 | } 37 | } 38 | } 39 | 40 | void DisconnectAll() { slots_ = {}; } 41 | 42 | void operator()(Args... args) 43 | { 44 | for (auto const& slot : slots_) { 45 | slot.fn(std::forward(args)...); 46 | } 47 | } 48 | 49 | private: 50 | struct Slot { 51 | Token token; 52 | std::function fn; 53 | }; 54 | 55 | Token nextToken_{}; 56 | std::vector slots_{}; 57 | }; 58 | 59 | } // namespace discord 60 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/image_manager.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(_CRT_SECURE_NO_WARNINGS) 2 | #define _CRT_SECURE_NO_WARNINGS 3 | #endif 4 | 5 | #include "image_manager.h" 6 | 7 | #include "core.h" 8 | 9 | #include 10 | #include 11 | 12 | namespace discord { 13 | 14 | void ImageManager::Fetch(ImageHandle handle, 15 | bool refresh, 16 | std::function callback) 17 | { 18 | static auto wrapper = 19 | [](void* callbackData, EDiscordResult result, DiscordImageHandle handleResult) -> void { 20 | std::unique_ptr> cb( 21 | reinterpret_cast*>(callbackData)); 22 | if (!cb || !(*cb)) { 23 | return; 24 | } 25 | (*cb)(static_cast(result), *reinterpret_cast(&handleResult)); 26 | }; 27 | std::unique_ptr> cb{}; 28 | cb.reset(new std::function(std::move(callback))); 29 | internal_->fetch(internal_, 30 | *reinterpret_cast(&handle), 31 | (refresh ? 1 : 0), 32 | cb.release(), 33 | wrapper); 34 | } 35 | 36 | Result ImageManager::GetDimensions(ImageHandle handle, ImageDimensions* dimensions) 37 | { 38 | if (!dimensions) { 39 | return Result::InternalError; 40 | } 41 | 42 | auto result = internal_->get_dimensions(internal_, 43 | *reinterpret_cast(&handle), 44 | reinterpret_cast(dimensions)); 45 | return static_cast(result); 46 | } 47 | 48 | Result ImageManager::GetData(ImageHandle handle, std::uint8_t* data, std::uint32_t dataLength) 49 | { 50 | auto result = internal_->get_data(internal_, 51 | *reinterpret_cast(&handle), 52 | reinterpret_cast(data), 53 | dataLength); 54 | return static_cast(result); 55 | } 56 | 57 | } // namespace discord 58 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/image_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | namespace discord { 6 | 7 | class ImageManager final { 8 | public: 9 | ~ImageManager() = default; 10 | 11 | void Fetch(ImageHandle handle, bool refresh, std::function callback); 12 | Result GetDimensions(ImageHandle handle, ImageDimensions* dimensions); 13 | Result GetData(ImageHandle handle, std::uint8_t* data, std::uint32_t dataLength); 14 | 15 | private: 16 | friend class Core; 17 | 18 | ImageManager() = default; 19 | ImageManager(ImageManager const& rhs) = delete; 20 | ImageManager& operator=(ImageManager const& rhs) = delete; 21 | ImageManager(ImageManager&& rhs) = delete; 22 | ImageManager& operator=(ImageManager&& rhs) = delete; 23 | 24 | IDiscordImageManager* internal_; 25 | static IDiscordImageEvents events_; 26 | }; 27 | 28 | } // namespace discord 29 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/network_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | namespace discord { 6 | 7 | class NetworkManager final { 8 | public: 9 | ~NetworkManager() = default; 10 | 11 | /** 12 | * Get the local peer ID for this process. 13 | */ 14 | void GetPeerId(NetworkPeerId* peerId); 15 | /** 16 | * Send pending network messages. 17 | */ 18 | Result Flush(); 19 | /** 20 | * Open a connection to a remote peer. 21 | */ 22 | Result OpenPeer(NetworkPeerId peerId, char const* routeData); 23 | /** 24 | * Update the route data for a connected peer. 25 | */ 26 | Result UpdatePeer(NetworkPeerId peerId, char const* routeData); 27 | /** 28 | * Close the connection to a remote peer. 29 | */ 30 | Result ClosePeer(NetworkPeerId peerId); 31 | /** 32 | * Open a message channel to a connected peer. 33 | */ 34 | Result OpenChannel(NetworkPeerId peerId, NetworkChannelId channelId, bool reliable); 35 | /** 36 | * Close a message channel to a connected peer. 37 | */ 38 | Result CloseChannel(NetworkPeerId peerId, NetworkChannelId channelId); 39 | /** 40 | * Send a message to a connected peer over an opened message channel. 41 | */ 42 | Result SendMessage(NetworkPeerId peerId, 43 | NetworkChannelId channelId, 44 | std::uint8_t* data, 45 | std::uint32_t dataLength); 46 | 47 | Event OnMessage; 48 | Event OnRouteUpdate; 49 | 50 | private: 51 | friend class Core; 52 | 53 | NetworkManager() = default; 54 | NetworkManager(NetworkManager const& rhs) = delete; 55 | NetworkManager& operator=(NetworkManager const& rhs) = delete; 56 | NetworkManager(NetworkManager&& rhs) = delete; 57 | NetworkManager& operator=(NetworkManager&& rhs) = delete; 58 | 59 | IDiscordNetworkManager* internal_; 60 | static IDiscordNetworkEvents events_; 61 | }; 62 | 63 | } // namespace discord 64 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/overlay_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | namespace discord { 6 | 7 | class OverlayManager final { 8 | public: 9 | ~OverlayManager() = default; 10 | 11 | void IsEnabled(bool* enabled); 12 | void IsLocked(bool* locked); 13 | void SetLocked(bool locked, std::function callback); 14 | void OpenActivityInvite(ActivityActionType type, std::function callback); 15 | void OpenGuildInvite(char const* code, std::function callback); 16 | void OpenVoiceSettings(std::function callback); 17 | Result InitDrawingDxgi(IDXGISwapChain* swapchain, bool useMessageForwarding); 18 | void OnPresent(); 19 | void ForwardMessage(MSG* message); 20 | void KeyEvent(bool down, char const* keyCode, KeyVariant variant); 21 | void CharEvent(char const* character); 22 | void MouseButtonEvent(std::uint8_t down, 23 | std::int32_t clickCount, 24 | MouseButton which, 25 | std::int32_t x, 26 | std::int32_t y); 27 | void MouseMotionEvent(std::int32_t x, std::int32_t y); 28 | void ImeCommitText(char const* text); 29 | void ImeSetComposition(char const* text, 30 | ImeUnderline* underlines, 31 | std::uint32_t underlinesLength, 32 | std::int32_t from, 33 | std::int32_t to); 34 | void ImeCancelComposition(); 35 | void SetImeCompositionRangeCallback( 36 | std::function 37 | onImeCompositionRangeChanged); 38 | void SetImeSelectionBoundsCallback( 39 | std::function onImeSelectionBoundsChanged); 40 | bool IsPointInsideClickZone(std::int32_t x, std::int32_t y); 41 | 42 | Event OnToggle; 43 | 44 | private: 45 | friend class Core; 46 | 47 | OverlayManager() = default; 48 | OverlayManager(OverlayManager const& rhs) = delete; 49 | OverlayManager& operator=(OverlayManager const& rhs) = delete; 50 | OverlayManager(OverlayManager&& rhs) = delete; 51 | OverlayManager& operator=(OverlayManager&& rhs) = delete; 52 | 53 | IDiscordOverlayManager* internal_; 54 | static IDiscordOverlayEvents events_; 55 | }; 56 | 57 | } // namespace discord 58 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/relationship_manager.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(_CRT_SECURE_NO_WARNINGS) 2 | #define _CRT_SECURE_NO_WARNINGS 3 | #endif 4 | 5 | #include "relationship_manager.h" 6 | 7 | #include "core.h" 8 | 9 | #include 10 | #include 11 | 12 | namespace discord { 13 | 14 | class RelationshipEvents final { 15 | public: 16 | static void DISCORD_CALLBACK OnRefresh(void* callbackData) 17 | { 18 | auto* core = reinterpret_cast(callbackData); 19 | if (!core) { 20 | return; 21 | } 22 | 23 | auto& module = core->RelationshipManager(); 24 | module.OnRefresh(); 25 | } 26 | 27 | static void DISCORD_CALLBACK OnRelationshipUpdate(void* callbackData, 28 | DiscordRelationship* relationship) 29 | { 30 | auto* core = reinterpret_cast(callbackData); 31 | if (!core) { 32 | return; 33 | } 34 | 35 | auto& module = core->RelationshipManager(); 36 | module.OnRelationshipUpdate(*reinterpret_cast(relationship)); 37 | } 38 | }; 39 | 40 | IDiscordRelationshipEvents RelationshipManager::events_{ 41 | &RelationshipEvents::OnRefresh, 42 | &RelationshipEvents::OnRelationshipUpdate, 43 | }; 44 | 45 | void RelationshipManager::Filter(std::function filter) 46 | { 47 | static auto wrapper = [](void* callbackData, DiscordRelationship* relationship) -> bool { 48 | auto cb(reinterpret_cast*>(callbackData)); 49 | if (!cb || !(*cb)) { 50 | return {}; 51 | } 52 | return (*cb)(*reinterpret_cast(relationship)); 53 | }; 54 | std::unique_ptr> cb{}; 55 | cb.reset(new std::function(std::move(filter))); 56 | internal_->filter(internal_, cb.get(), wrapper); 57 | } 58 | 59 | Result RelationshipManager::Count(std::int32_t* count) 60 | { 61 | if (!count) { 62 | return Result::InternalError; 63 | } 64 | 65 | auto result = internal_->count(internal_, reinterpret_cast(count)); 66 | return static_cast(result); 67 | } 68 | 69 | Result RelationshipManager::Get(UserId userId, Relationship* relationship) 70 | { 71 | if (!relationship) { 72 | return Result::InternalError; 73 | } 74 | 75 | auto result = 76 | internal_->get(internal_, userId, reinterpret_cast(relationship)); 77 | return static_cast(result); 78 | } 79 | 80 | Result RelationshipManager::GetAt(std::uint32_t index, Relationship* relationship) 81 | { 82 | if (!relationship) { 83 | return Result::InternalError; 84 | } 85 | 86 | auto result = 87 | internal_->get_at(internal_, index, reinterpret_cast(relationship)); 88 | return static_cast(result); 89 | } 90 | 91 | } // namespace discord 92 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/relationship_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | namespace discord { 6 | 7 | class RelationshipManager final { 8 | public: 9 | ~RelationshipManager() = default; 10 | 11 | void Filter(std::function filter); 12 | Result Count(std::int32_t* count); 13 | Result Get(UserId userId, Relationship* relationship); 14 | Result GetAt(std::uint32_t index, Relationship* relationship); 15 | 16 | Event<> OnRefresh; 17 | Event OnRelationshipUpdate; 18 | 19 | private: 20 | friend class Core; 21 | 22 | RelationshipManager() = default; 23 | RelationshipManager(RelationshipManager const& rhs) = delete; 24 | RelationshipManager& operator=(RelationshipManager const& rhs) = delete; 25 | RelationshipManager(RelationshipManager&& rhs) = delete; 26 | RelationshipManager& operator=(RelationshipManager&& rhs) = delete; 27 | 28 | IDiscordRelationshipManager* internal_; 29 | static IDiscordRelationshipEvents events_; 30 | }; 31 | 32 | } // namespace discord 33 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/storage_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | namespace discord { 6 | 7 | class StorageManager final { 8 | public: 9 | ~StorageManager() = default; 10 | 11 | Result Read(char const* name, 12 | std::uint8_t* data, 13 | std::uint32_t dataLength, 14 | std::uint32_t* read); 15 | void ReadAsync(char const* name, 16 | std::function callback); 17 | void ReadAsyncPartial(char const* name, 18 | std::uint64_t offset, 19 | std::uint64_t length, 20 | std::function callback); 21 | Result Write(char const* name, std::uint8_t* data, std::uint32_t dataLength); 22 | void WriteAsync(char const* name, 23 | std::uint8_t* data, 24 | std::uint32_t dataLength, 25 | std::function callback); 26 | Result Delete(char const* name); 27 | Result Exists(char const* name, bool* exists); 28 | void Count(std::int32_t* count); 29 | Result Stat(char const* name, FileStat* stat); 30 | Result StatAt(std::int32_t index, FileStat* stat); 31 | Result GetPath(char path[4096]); 32 | 33 | private: 34 | friend class Core; 35 | 36 | StorageManager() = default; 37 | StorageManager(StorageManager const& rhs) = delete; 38 | StorageManager& operator=(StorageManager const& rhs) = delete; 39 | StorageManager(StorageManager&& rhs) = delete; 40 | StorageManager& operator=(StorageManager&& rhs) = delete; 41 | 42 | IDiscordStorageManager* internal_; 43 | static IDiscordStorageEvents events_; 44 | }; 45 | 46 | } // namespace discord 47 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/store_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | namespace discord { 6 | 7 | class StoreManager final { 8 | public: 9 | ~StoreManager() = default; 10 | 11 | void FetchSkus(std::function callback); 12 | void CountSkus(std::int32_t* count); 13 | Result GetSku(Snowflake skuId, Sku* sku); 14 | Result GetSkuAt(std::int32_t index, Sku* sku); 15 | void FetchEntitlements(std::function callback); 16 | void CountEntitlements(std::int32_t* count); 17 | Result GetEntitlement(Snowflake entitlementId, Entitlement* entitlement); 18 | Result GetEntitlementAt(std::int32_t index, Entitlement* entitlement); 19 | Result HasSkuEntitlement(Snowflake skuId, bool* hasEntitlement); 20 | void StartPurchase(Snowflake skuId, std::function callback); 21 | 22 | Event OnEntitlementCreate; 23 | Event OnEntitlementDelete; 24 | 25 | private: 26 | friend class Core; 27 | 28 | StoreManager() = default; 29 | StoreManager(StoreManager const& rhs) = delete; 30 | StoreManager& operator=(StoreManager const& rhs) = delete; 31 | StoreManager(StoreManager&& rhs) = delete; 32 | StoreManager& operator=(StoreManager&& rhs) = delete; 33 | 34 | IDiscordStoreManager* internal_; 35 | static IDiscordStoreEvents events_; 36 | }; 37 | 38 | } // namespace discord 39 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/user_manager.cpp: -------------------------------------------------------------------------------- 1 | #if !defined(_CRT_SECURE_NO_WARNINGS) 2 | #define _CRT_SECURE_NO_WARNINGS 3 | #endif 4 | 5 | #include "user_manager.h" 6 | 7 | #include "core.h" 8 | 9 | #include 10 | #include 11 | 12 | namespace discord { 13 | 14 | class UserEvents final { 15 | public: 16 | static void DISCORD_CALLBACK OnCurrentUserUpdate(void* callbackData) 17 | { 18 | auto* core = reinterpret_cast(callbackData); 19 | if (!core) { 20 | return; 21 | } 22 | 23 | auto& module = core->UserManager(); 24 | module.OnCurrentUserUpdate(); 25 | } 26 | }; 27 | 28 | IDiscordUserEvents UserManager::events_{ 29 | &UserEvents::OnCurrentUserUpdate, 30 | }; 31 | 32 | Result UserManager::GetCurrentUser(User* currentUser) 33 | { 34 | if (!currentUser) { 35 | return Result::InternalError; 36 | } 37 | 38 | auto result = 39 | internal_->get_current_user(internal_, reinterpret_cast(currentUser)); 40 | return static_cast(result); 41 | } 42 | 43 | void UserManager::GetUser(UserId userId, std::function callback) 44 | { 45 | static auto wrapper = [](void* callbackData, EDiscordResult result, DiscordUser* user) -> void { 46 | std::unique_ptr> cb( 47 | reinterpret_cast*>(callbackData)); 48 | if (!cb || !(*cb)) { 49 | return; 50 | } 51 | (*cb)(static_cast(result), *reinterpret_cast(user)); 52 | }; 53 | std::unique_ptr> cb{}; 54 | cb.reset(new std::function(std::move(callback))); 55 | internal_->get_user(internal_, userId, cb.release(), wrapper); 56 | } 57 | 58 | Result UserManager::GetCurrentUserPremiumType(PremiumType* premiumType) 59 | { 60 | if (!premiumType) { 61 | return Result::InternalError; 62 | } 63 | 64 | auto result = internal_->get_current_user_premium_type( 65 | internal_, reinterpret_cast(premiumType)); 66 | return static_cast(result); 67 | } 68 | 69 | Result UserManager::CurrentUserHasFlag(UserFlag flag, bool* hasFlag) 70 | { 71 | if (!hasFlag) { 72 | return Result::InternalError; 73 | } 74 | 75 | auto result = internal_->current_user_has_flag( 76 | internal_, static_cast(flag), reinterpret_cast(hasFlag)); 77 | return static_cast(result); 78 | } 79 | 80 | } // namespace discord 81 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/user_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | namespace discord { 6 | 7 | class UserManager final { 8 | public: 9 | ~UserManager() = default; 10 | 11 | Result GetCurrentUser(User* currentUser); 12 | void GetUser(UserId userId, std::function callback); 13 | Result GetCurrentUserPremiumType(PremiumType* premiumType); 14 | Result CurrentUserHasFlag(UserFlag flag, bool* hasFlag); 15 | 16 | Event<> OnCurrentUserUpdate; 17 | 18 | private: 19 | friend class Core; 20 | 21 | UserManager() = default; 22 | UserManager(UserManager const& rhs) = delete; 23 | UserManager& operator=(UserManager const& rhs) = delete; 24 | UserManager(UserManager&& rhs) = delete; 25 | UserManager& operator=(UserManager&& rhs) = delete; 26 | 27 | IDiscordUserManager* internal_; 28 | static IDiscordUserEvents events_; 29 | }; 30 | 31 | } // namespace discord 32 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/cpp/voice_manager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | namespace discord { 6 | 7 | class VoiceManager final { 8 | public: 9 | ~VoiceManager() = default; 10 | 11 | Result GetInputMode(InputMode* inputMode); 12 | void SetInputMode(InputMode inputMode, std::function callback); 13 | Result IsSelfMute(bool* mute); 14 | Result SetSelfMute(bool mute); 15 | Result IsSelfDeaf(bool* deaf); 16 | Result SetSelfDeaf(bool deaf); 17 | Result IsLocalMute(Snowflake userId, bool* mute); 18 | Result SetLocalMute(Snowflake userId, bool mute); 19 | Result GetLocalVolume(Snowflake userId, std::uint8_t* volume); 20 | Result SetLocalVolume(Snowflake userId, std::uint8_t volume); 21 | 22 | Event<> OnSettingsUpdate; 23 | 24 | private: 25 | friend class Core; 26 | 27 | VoiceManager() = default; 28 | VoiceManager(VoiceManager const& rhs) = delete; 29 | VoiceManager& operator=(VoiceManager const& rhs) = delete; 30 | VoiceManager(VoiceManager&& rhs) = delete; 31 | VoiceManager& operator=(VoiceManager&& rhs) = delete; 32 | 33 | IDiscordVoiceManager* internal_; 34 | static IDiscordVoiceEvents events_; 35 | }; 36 | 37 | } // namespace discord 38 | -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/lib/x86_64/discord_game_sdk.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/discord_game_sdk/lib/x86_64/discord_game_sdk.dll -------------------------------------------------------------------------------- /ThirdParty/discord_game_sdk/lib/x86_64/discord_game_sdk.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/discord_game_sdk/lib/x86_64/discord_game_sdk.lib -------------------------------------------------------------------------------- /ThirdParty/dxc/dxcompiler.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/dxc/dxcompiler.dll -------------------------------------------------------------------------------- /ThirdParty/dxc/dxcompiler.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/dxc/dxcompiler.lib -------------------------------------------------------------------------------- /ThirdParty/dxc/dxil.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicovanbentum/Raekor/4c96ce00e3efd0783e906d3ce625d14531f945ee/ThirdParty/dxc/dxil.dll -------------------------------------------------------------------------------- /ThirdParty/samplerCPP/README.txt: -------------------------------------------------------------------------------- 1 | We provide our samplers optimized for N = 1, 2, 4, 8, 16, 32, 64, 128 and 256. Each sampler generates up to 256 spp in a 128x128 wrappable tile. The blue-noise distribution of the error is 2 | - optimal when spp=N, 3 | - good when sppN. 5 | 6 | Each sample has up to 256 dimensions. We optimized only the first eight dimensions by pairs, i.e. we computed four optimizations for D=2. 7 | 8 | Each .cpp file provides: 9 | - the Owen-scrambled Sobol sequence (256 samples x 256 dimensions). 10 | - the scrambling tile: 128x128x8. 11 | - the ranking tile: 128x128x4. It is actually 128x128x8 but the data are currently duplicated. This can be optimized. 12 | -------------------------------------------------------------------------------- /vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "raekor", 3 | "version-string": "0.1", 4 | "dependencies": [ 5 | { 6 | "name": "lz4", 7 | "platform": "windows & static" 8 | }, 9 | { 10 | "name": "sdl3", 11 | "features": [], 12 | "platform": "windows & static" 13 | }, 14 | { 15 | "name": "directx-headers", 16 | "platform": "windows & static" 17 | } 18 | ], 19 | "builtin-baseline": "4d224151a371ad6b9cbcff46ed3ea0065b128d1a", 20 | "overrides": [ 21 | { "name": "lz4", "version": "1.9.4#1" }, 22 | { "name": "sdl3", "version": "3.2.4" }, 23 | { "name": "imgui", "version": "1.89.4" }, 24 | { "name": "directx-headers", "version": "1.608.2#1" } 25 | ] 26 | } 27 | --------------------------------------------------------------------------------