This commit is contained in:
Dmitry 2023-08-12 14:43:56 +03:00
parent d5c8eb3d64
commit eeacc05f69
210 changed files with 12870 additions and 13488 deletions

View File

@ -45,23 +45,23 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion> <VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<ProjectGuid>{26bd6e61-e36d-464a-a312-4110adf10083}</ProjectGuid> <ProjectGuid>{26bd6e61-e36d-464a-a312-4110adf10083}</ProjectGuid>
<RootNamespace>HelloTexturedCube</RootNamespace> <RootNamespace>HelloTexturedCube</RootNamespace>
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -79,12 +79,6 @@
<Import Project="..\Verus\Verus.props" /> <Import Project="..\Verus\Verus.props" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
@ -93,6 +87,7 @@
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -113,6 +108,7 @@ xcopy /y $(ProjectDir)src\HelloTexturedCube.dds $(OutDir)Data\Textures\</Command
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>

View File

@ -1,55 +1,52 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Game
{ {
namespace Game class HelloTexturedCubeGame : public Singleton<HelloTexturedCubeGame>, public BaseGame
{ {
class HelloTexturedCubeGame : public Singleton<HelloTexturedCubeGame>, public BaseGame struct Vertex
{ {
struct Vertex float _x, _y, _z;
{ UINT32 _color;
float _x, _y, _z;
UINT32 _color;
};
VERUS_TYPEDEFS(Vertex);
VERUS_UBUFFER_STRUCT UB_ShaderVS
{
mataff _matW;
matrix _matVP;
};
VERUS_UBUFFER_STRUCT UB_ShaderFS
{
float _phase;
};
Vector3 _rotation = Vector3(0);
CGI::GeometryPwn _geo;
CGI::ShaderPwn _shader;
CGI::PipelinePwn _pipe;
CGI::TexturePwn _tex;
CSZ _shaderCode;
CGI::CSHandle _csh; // Complex set handle. Simple set has one uniform buffer. Complex set additionally has textures.
UB_ShaderVS _ubShaderVS;
UB_ShaderFS _ubShaderFS;
int _vertCount = 0;
int _indexCount = 0;
public:
HelloTexturedCubeGame();
~HelloTexturedCubeGame();
virtual void BaseGame_UpdateSettings(App::Window::RDesc windowDesc) override;
virtual void BaseGame_LoadContent() override;
virtual void BaseGame_UnloadContent() override;
virtual void BaseGame_Update() override;
virtual void BaseGame_Draw() override;
virtual void BaseGame_DrawView(CGI::RcViewDesc viewDesc) override;
}; };
VERUS_TYPEDEFS(HelloTexturedCubeGame); VERUS_TYPEDEFS(Vertex);
}
VERUS_UBUFFER_STRUCT UB_ShaderVS
{
mataff _matW;
matrix _matVP;
};
VERUS_UBUFFER_STRUCT UB_ShaderFS
{
float _phase;
};
Vector3 _rotation = Vector3(0);
CGI::GeometryPwn _geo;
CGI::ShaderPwn _shader;
CGI::PipelinePwn _pipe;
CGI::TexturePwn _tex;
CSZ _shaderCode;
CGI::CSHandle _csh; // Complex set handle. Simple set has one uniform buffer. Complex set additionally has textures.
UB_ShaderVS _ubShaderVS;
UB_ShaderFS _ubShaderFS;
int _vertCount = 0;
int _indexCount = 0;
public:
HelloTexturedCubeGame();
~HelloTexturedCubeGame();
virtual void BaseGame_UpdateSettings(App::Window::RDesc windowDesc) override;
virtual void BaseGame_LoadContent() override;
virtual void BaseGame_UnloadContent() override;
virtual void BaseGame_Update() override;
virtual void BaseGame_Draw() override;
virtual void BaseGame_DrawView(CGI::RcViewDesc viewDesc) override;
};
VERUS_TYPEDEFS(HelloTexturedCubeGame);
} }
#define VERUS_QREF_GAME Game::RHelloTexturedCubeGame game = Game::HelloTexturedCubeGame::I() #define VERUS_QREF_GAME Game::RHelloTexturedCubeGame game = Game::HelloTexturedCubeGame::I()

View File

@ -45,23 +45,23 @@
</None> </None>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion> <VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<ProjectGuid>{bc17acd3-97eb-4d5c-a2c9-574cdaa7576b}</ProjectGuid> <ProjectGuid>{bc17acd3-97eb-4d5c-a2c9-574cdaa7576b}</ProjectGuid>
<RootNamespace>HelloTriangle</RootNamespace> <RootNamespace>HelloTriangle</RootNamespace>
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -79,12 +79,6 @@
<Import Project="..\Verus\Verus.props" /> <Import Project="..\Verus\Verus.props" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
@ -93,6 +87,7 @@
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -109,6 +104,7 @@
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>

View File

@ -1,55 +1,52 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Game
{ {
namespace Game // Epigraph
// "Vulkan (it takes) 1000 lines to draw a triangle"
// "- I thought you only needed 3 lines to draw a triangle"
// https://www.reddit.com/r/linux/comments/58fyqn/vulkan_1000_lines_to_draw_a_triangle/
class HelloTriangleGame : public Singleton<HelloTriangleGame>, public BaseGame
{ {
// Epigraph struct Vertex
// "Vulkan (it takes) 1000 lines to draw a triangle"
// "- I thought you only needed 3 lines to draw a triangle"
// https://www.reddit.com/r/linux/comments/58fyqn/vulkan_1000_lines_to_draw_a_triangle/
class HelloTriangleGame : public Singleton<HelloTriangleGame>, public BaseGame
{ {
struct Vertex float _x, _y, _z;
{ UINT32 _color;
float _x, _y, _z;
UINT32 _color;
};
VERUS_TYPEDEFS(Vertex);
VERUS_UBUFFER_STRUCT UB_ShaderVS
{
matrix _matWVP;
};
VERUS_UBUFFER_STRUCT UB_ShaderFS
{
float _phase;
};
CGI::GeometryPwn _geo;
CGI::ShaderPwn _shader;
CGI::PipelinePwn _pipe;
CSZ _shaderCode;
UB_ShaderVS _ubShaderVS;
UB_ShaderFS _ubShaderFS;
int _vertCount = 0;
public:
HelloTriangleGame();
~HelloTriangleGame();
virtual void BaseGame_UpdateSettings(App::Window::RDesc windowDesc) override;
virtual void BaseGame_LoadContent() override;
virtual void BaseGame_UnloadContent() override;
virtual void BaseGame_Update() override;
virtual void BaseGame_Draw() override;
virtual void BaseGame_DrawView(CGI::RcViewDesc viewDesc) override;
}; };
VERUS_TYPEDEFS(HelloTriangleGame); VERUS_TYPEDEFS(Vertex);
}
VERUS_UBUFFER_STRUCT UB_ShaderVS
{
matrix _matWVP;
};
VERUS_UBUFFER_STRUCT UB_ShaderFS
{
float _phase;
};
CGI::GeometryPwn _geo;
CGI::ShaderPwn _shader;
CGI::PipelinePwn _pipe;
CSZ _shaderCode;
UB_ShaderVS _ubShaderVS;
UB_ShaderFS _ubShaderFS;
int _vertCount = 0;
public:
HelloTriangleGame();
~HelloTriangleGame();
virtual void BaseGame_UpdateSettings(App::Window::RDesc windowDesc) override;
virtual void BaseGame_LoadContent() override;
virtual void BaseGame_UnloadContent() override;
virtual void BaseGame_Update() override;
virtual void BaseGame_Draw() override;
virtual void BaseGame_DrawView(CGI::RcViewDesc viewDesc) override;
};
VERUS_TYPEDEFS(HelloTriangleGame);
} }
#define VERUS_QREF_GAME Game::RHelloTriangleGame game = Game::HelloTriangleGame::I() #define VERUS_QREF_GAME Game::RHelloTriangleGame game = Game::HelloTriangleGame::I()

View File

@ -11,23 +11,23 @@
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion> <VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<ProjectGuid>{EBF1E2F9-65AA-419D-A3D3-AD66EB086E57}</ProjectGuid> <ProjectGuid>{EBF1E2F9-65AA-419D-A3D3-AD66EB086E57}</ProjectGuid>
<RootNamespace>PAKBuilder</RootNamespace> <RootNamespace>PAKBuilder</RootNamespace>
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -45,18 +45,13 @@
<Import Project="..\Verus\Verus.props" /> <Import Project="..\Verus\Verus.props" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -71,6 +66,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>

View File

@ -11,23 +11,23 @@
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion> <VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<ProjectGuid>{8269dcce-e226-46e4-b9f6-290ab5df2678}</ProjectGuid> <ProjectGuid>{8269dcce-e226-46e4-b9f6-290ab5df2678}</ProjectGuid>
<RootNamespace>RendererDirect3D11</RootNamespace> <RootNamespace>RendererDirect3D11</RootNamespace>
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -45,12 +45,6 @@
<Import Project="..\Verus\Verus.props" /> <Import Project="..\Verus\Verus.props" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
@ -61,6 +55,7 @@
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<FloatingPointModel>Fast</FloatingPointModel> <FloatingPointModel>Fast</FloatingPointModel>
<AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -80,6 +75,7 @@
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<FloatingPointModel>Fast</FloatingPointModel> <FloatingPointModel>Fast</FloatingPointModel>
<AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>

View File

@ -1,65 +1,62 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class CommandBufferD3D11 : public BaseCommandBuffer
{ {
class CommandBufferD3D11 : public BaseCommandBuffer ComPtr<ID3D11DeviceContext> _pDeviceContext;
{ RP::PcD3DRenderPass _pRenderPass = nullptr;
ComPtr<ID3D11DeviceContext> _pDeviceContext; RP::PcD3DFramebuffer _pFramebuffer = nullptr;
RP::PcD3DRenderPass _pRenderPass = nullptr; Vector<FLOAT> _vClearValues;
RP::PcD3DFramebuffer _pFramebuffer = nullptr; int _subpassIndex = 0;
Vector<FLOAT> _vClearValues; float _blendFactor[4];
int _subpassIndex = 0;
float _blendFactor[4];
public: public:
CommandBufferD3D11(); CommandBufferD3D11();
virtual ~CommandBufferD3D11() override; virtual ~CommandBufferD3D11() override;
virtual void Init() override; virtual void Init() override;
virtual void Done() override; virtual void Done() override;
virtual void InitOneTimeSubmit() override; virtual void InitOneTimeSubmit() override;
virtual void DoneOneTimeSubmit() override; virtual void DoneOneTimeSubmit() override;
virtual void Begin() override; virtual void Begin() override;
virtual void End() override; virtual void End() override;
virtual void PipelineImageMemoryBarrier(TexturePtr tex, ImageLayout oldLayout, ImageLayout newLayout, Range mipLevels, Range arrayLayers) override; virtual void PipelineImageMemoryBarrier(TexturePtr tex, ImageLayout oldLayout, ImageLayout newLayout, Range mipLevels, Range arrayLayers) override;
virtual void BeginRenderPass(RPHandle renderPassHandle, FBHandle framebufferHandle, virtual void BeginRenderPass(RPHandle renderPassHandle, FBHandle framebufferHandle,
std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf) override; std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf) override;
virtual void NextSubpass() override; virtual void NextSubpass() override;
virtual void EndRenderPass() override; virtual void EndRenderPass() override;
virtual void BindPipeline(PipelinePtr pipe) override; virtual void BindPipeline(PipelinePtr pipe) override;
virtual void SetViewport(std::initializer_list<Vector4> il, float minDepth, float maxDepth) override; virtual void SetViewport(std::initializer_list<Vector4> il, float minDepth, float maxDepth) override;
virtual void SetScissor(std::initializer_list<Vector4> il) override; virtual void SetScissor(std::initializer_list<Vector4> il) override;
virtual void SetBlendConstants(const float* p) override; virtual void SetBlendConstants(const float* p) override;
virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter) override; virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter) override;
virtual void BindIndexBuffer(GeometryPtr geo) override; virtual void BindIndexBuffer(GeometryPtr geo) override;
virtual bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle) override; virtual bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle) override;
virtual bool BindDescriptors(ShaderPtr shader, int setNumber, GeometryPtr geo, int sbIndex) override; virtual bool BindDescriptors(ShaderPtr shader, int setNumber, GeometryPtr geo, int sbIndex) override;
virtual void PushConstants(ShaderPtr shader, int offset, int size, const void* p, ShaderStageFlags stageFlags) override; virtual void PushConstants(ShaderPtr shader, int offset, int size, const void* p, ShaderStageFlags stageFlags) override;
virtual void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance) override; virtual void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance) override;
virtual void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int vertexOffset, int firstInstance) override; virtual void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int vertexOffset, int firstInstance) override;
virtual void Dispatch(int groupCountX, int groupCountY, int groupCountZ) override; virtual void Dispatch(int groupCountX, int groupCountY, int groupCountZ) override;
virtual void DispatchMesh(int groupCountX, int groupCountY, int groupCountZ) override; virtual void DispatchMesh(int groupCountX, int groupCountY, int groupCountZ) override;
virtual void TraceRays(int width, int height, int depth) override; virtual void TraceRays(int width, int height, int depth) override;
// //
// D3D11 // D3D11
// //
ID3D11DeviceContext* GetD3DDeviceContext() const; ID3D11DeviceContext* GetD3DDeviceContext() const;
void PrepareSubpass(); void PrepareSubpass();
}; };
VERUS_TYPEDEFS(CommandBufferD3D11); VERUS_TYPEDEFS(CommandBufferD3D11);
}
} }

View File

@ -1,66 +1,63 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class RendererD3D11;
class ExtRealityD3D11 : public BaseExtReality
{ {
class RendererD3D11; struct SwapChainEx
class ExtRealityD3D11 : public BaseExtReality
{ {
struct SwapChainEx XrSwapchain _handle = XR_NULL_HANDLE;
{ int32_t _width = 0;
XrSwapchain _handle = XR_NULL_HANDLE; int32_t _height = 0;
int32_t _width = 0; Vector<XrSwapchainImageD3D11KHR> _vImages;
int32_t _height = 0; Vector<ComPtr<ID3D11RenderTargetView>> _vImageViews;
Vector<XrSwapchainImageD3D11KHR> _vImages;
Vector<ComPtr<ID3D11RenderTargetView>> _vImageViews;
};
Vector<SwapChainEx> _vSwapChains;
LUID _adapterLuid;
D3D_FEATURE_LEVEL _minFeatureLevel = D3D_FEATURE_LEVEL_11_0;
public:
ExtRealityD3D11();
virtual ~ExtRealityD3D11() override;
virtual void Init() override;
virtual void Done() override;
void InitByRenderer(RendererD3D11* pRenderer);
private:
void GetSystem();
void CreateSwapChains(ID3D11Device* pDevice, int64_t format);
ComPtr<ID3D11RenderTargetView> CreateImageView(ID3D11Device* pDevice, int64_t format, XrSwapchainImageD3D11KHR& image);
virtual XrSwapchain GetSwapChain(int viewIndex) override;
virtual void GetSwapChainSize(int viewIndex, int32_t& w, int32_t& h) override;
public:
LUID GetAdapterLuid() const { return _adapterLuid; }
D3D_FEATURE_LEVEL GetMinFeatureLevel() const { return _minFeatureLevel; }
ID3D11RenderTargetView* GetRTV(int viewIndex, int imageIndex) const;
virtual void CreateActions() override;
virtual void PollEvents() override;
virtual void SyncActions(UINT32 activeActionSetsMask) override;
virtual bool GetActionStateBoolean(int actionIndex, bool& currentState, bool* pChangedState, int subaction) override;
virtual bool GetActionStateFloat(int actionIndex, float& currentState, bool* pChangedState, int subaction) override;
virtual bool GetActionStatePose(int actionIndex, bool& currentState, Math::RPose pose, int subaction) override;
virtual void BeginFrame() override;
virtual int LocateViews() override;
virtual void BeginView(int viewIndex, RViewDesc viewDesc) override;
virtual void AcquireSwapChainImage() override;
virtual void EndView(int viewIndex) override;
virtual void EndFrame() override;
virtual void BeginAreaUpdate() override;
virtual void EndAreaUpdate(PcVector4 pUserOffset) override;
}; };
VERUS_TYPEDEFS(ExtRealityD3D11);
} Vector<SwapChainEx> _vSwapChains;
LUID _adapterLuid;
D3D_FEATURE_LEVEL _minFeatureLevel = D3D_FEATURE_LEVEL_11_0;
public:
ExtRealityD3D11();
virtual ~ExtRealityD3D11() override;
virtual void Init() override;
virtual void Done() override;
void InitByRenderer(RendererD3D11* pRenderer);
private:
void GetSystem();
void CreateSwapChains(ID3D11Device* pDevice, int64_t format);
ComPtr<ID3D11RenderTargetView> CreateImageView(ID3D11Device* pDevice, int64_t format, XrSwapchainImageD3D11KHR& image);
virtual XrSwapchain GetSwapChain(int viewIndex) override;
virtual void GetSwapChainSize(int viewIndex, int32_t& w, int32_t& h) override;
public:
LUID GetAdapterLuid() const { return _adapterLuid; }
D3D_FEATURE_LEVEL GetMinFeatureLevel() const { return _minFeatureLevel; }
ID3D11RenderTargetView* GetRTV(int viewIndex, int imageIndex) const;
virtual void CreateActions() override;
virtual void PollEvents() override;
virtual void SyncActions(UINT32 activeActionSetsMask) override;
virtual bool GetActionStateBoolean(int actionIndex, bool& currentState, bool* pChangedState, int subaction) override;
virtual bool GetActionStateFloat(int actionIndex, float& currentState, bool* pChangedState, int subaction) override;
virtual bool GetActionStatePose(int actionIndex, bool& currentState, Math::RPose pose, int subaction) override;
virtual void BeginFrame() override;
virtual int LocateViews() override;
virtual void BeginView(int viewIndex, RViewDesc viewDesc) override;
virtual void AcquireSwapChainImage() override;
virtual void EndView(int viewIndex) override;
virtual void EndFrame() override;
virtual void BeginAreaUpdate() override;
virtual void EndAreaUpdate(PcVector4 pUserOffset) override;
};
VERUS_TYPEDEFS(ExtRealityD3D11);
} }

View File

@ -1,61 +1,58 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class GeometryD3D11 : public BaseGeometry
{ {
class GeometryD3D11 : public BaseGeometry struct BufferEx
{ {
struct BufferEx ComPtr<ID3D11Buffer> _pBuffer;
{ UINT64 _bufferSize = 0;
ComPtr<ID3D11Buffer> _pBuffer;
UINT64 _bufferSize = 0;
};
struct StructuredBufferEx : BufferEx
{
ComPtr<ID3D11ShaderResourceView> _pSRV;
int _structSize = 0;
};
Vector<BufferEx> _vVertexBuffers;
BufferEx _indexBuffer;
Vector<StructuredBufferEx> _vStructuredBuffers;
Vector<D3D11_INPUT_ELEMENT_DESC> _vInputElementDescs;
Vector<int> _vStrides;
public:
GeometryD3D11();
virtual ~GeometryD3D11() override;
virtual void Init(RcGeometryDesc desc) override;
virtual void Done() override;
virtual void CreateVertexBuffer(int count, int binding) override;
virtual void UpdateVertexBuffer(const void* p, int binding, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual void CreateIndexBuffer(int count) override;
virtual void UpdateIndexBuffer(const void* p, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual void CreateStorageBuffer(int count, int structSize, int sbIndex, ShaderStageFlags stageFlags) override;
virtual void UpdateStorageBuffer(const void* p, int sbIndex, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual int GetStorageBufferStructSize(int sbIndex) const override;
virtual Continue Scheduled_Update() override;
//
// D3D11
//
void GetD3DInputElementDescs(UINT32 bindingsFilter, Vector<D3D11_INPUT_ELEMENT_DESC>& vInputElementDescs) const;
int GetStride(int binding) const { return _vStrides[binding]; }
int GetVertexBufferCount() const { return Utils::Cast32(_vVertexBuffers.size()); }
ID3D11Buffer* GetD3DVertexBuffer(int binding) const { return _vVertexBuffers[binding]._pBuffer.Get(); }
ID3D11Buffer* GetD3DIndexBuffer() const { return _indexBuffer._pBuffer.Get(); }
ID3D11ShaderResourceView* GetD3DStructuredBufferSRV(int sbIndex) const { return _vStructuredBuffers[sbIndex]._pSRV.Get(); }
}; };
VERUS_TYPEDEFS(GeometryD3D11);
} struct StructuredBufferEx : BufferEx
{
ComPtr<ID3D11ShaderResourceView> _pSRV;
int _structSize = 0;
};
Vector<BufferEx> _vVertexBuffers;
BufferEx _indexBuffer;
Vector<StructuredBufferEx> _vStructuredBuffers;
Vector<D3D11_INPUT_ELEMENT_DESC> _vInputElementDescs;
Vector<int> _vStrides;
public:
GeometryD3D11();
virtual ~GeometryD3D11() override;
virtual void Init(RcGeometryDesc desc) override;
virtual void Done() override;
virtual void CreateVertexBuffer(int count, int binding) override;
virtual void UpdateVertexBuffer(const void* p, int binding, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual void CreateIndexBuffer(int count) override;
virtual void UpdateIndexBuffer(const void* p, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual void CreateStorageBuffer(int count, int structSize, int sbIndex, ShaderStageFlags stageFlags) override;
virtual void UpdateStorageBuffer(const void* p, int sbIndex, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual int GetStorageBufferStructSize(int sbIndex) const override;
virtual Continue Scheduled_Update() override;
//
// D3D11
//
void GetD3DInputElementDescs(UINT32 bindingsFilter, Vector<D3D11_INPUT_ELEMENT_DESC>& vInputElementDescs) const;
int GetStride(int binding) const { return _vStrides[binding]; }
int GetVertexBufferCount() const { return Utils::Cast32(_vVertexBuffers.size()); }
ID3D11Buffer* GetD3DVertexBuffer(int binding) const { return _vVertexBuffers[binding]._pBuffer.Get(); }
ID3D11Buffer* GetD3DIndexBuffer() const { return _indexBuffer._pBuffer.Get(); }
ID3D11ShaderResourceView* GetD3DStructuredBufferSRV(int sbIndex) const { return _vStructuredBuffers[sbIndex]._pSRV.Get(); }
};
VERUS_TYPEDEFS(GeometryD3D11);
} }

View File

@ -1,24 +1,21 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI D3D11_COMPARISON_FUNC ToNativeCompareOp(CompareOp compareOp);
{
D3D11_COMPARISON_FUNC ToNativeCompareOp(CompareOp compareOp);
UINT ToNativeCubeMapFace(CubeMapFace face); UINT ToNativeCubeMapFace(CubeMapFace face);
D3D11_FILL_MODE ToNativePolygonMode(PolygonMode polygonMode); D3D11_FILL_MODE ToNativePolygonMode(PolygonMode polygonMode);
D3D11_CULL_MODE ToNativeCullMode(CullMode cullMode); D3D11_CULL_MODE ToNativeCullMode(CullMode cullMode);
D3D_PRIMITIVE_TOPOLOGY ToNativePrimitiveTopology(PrimitiveTopology primitiveTopology); D3D_PRIMITIVE_TOPOLOGY ToNativePrimitiveTopology(PrimitiveTopology primitiveTopology);
DXGI_FORMAT ToNativeFormat(Format format, bool typeless); DXGI_FORMAT ToNativeFormat(Format format, bool typeless);
DXGI_FORMAT ToNativeSampledDepthFormat(Format format); DXGI_FORMAT ToNativeSampledDepthFormat(Format format);
CSZ ToNativeSemanticName(ViaUsage usage); CSZ ToNativeSemanticName(ViaUsage usage);
DXGI_FORMAT ToNativeFormat(ViaUsage usage, ViaType type, int components); DXGI_FORMAT ToNativeFormat(ViaUsage usage, ViaType type, int components);
}
} }

View File

@ -1,55 +1,52 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class PipelineD3D11 : public BasePipeline
{ {
class PipelineD3D11 : public BasePipeline ComPtr<ID3D11VertexShader> _pVS;
{ ComPtr<ID3D11HullShader> _pHS;
ComPtr<ID3D11VertexShader> _pVS; ComPtr<ID3D11DomainShader> _pDS;
ComPtr<ID3D11HullShader> _pHS; ComPtr<ID3D11GeometryShader> _pGS;
ComPtr<ID3D11DomainShader> _pDS; ComPtr<ID3D11PixelShader> _pPS;
ComPtr<ID3D11GeometryShader> _pGS; ComPtr<ID3D11ComputeShader> _pCS;
ComPtr<ID3D11PixelShader> _pPS; ComPtr<ID3D11BlendState> _pBlendState;
ComPtr<ID3D11ComputeShader> _pCS; ComPtr<ID3D11RasterizerState> _pRasterizerState;
ComPtr<ID3D11BlendState> _pBlendState; ComPtr<ID3D11DepthStencilState> _pDepthStencilState;
ComPtr<ID3D11RasterizerState> _pRasterizerState; ComPtr<ID3D11InputLayout> _pInputLayout;
ComPtr<ID3D11DepthStencilState> _pDepthStencilState; UINT _sampleMask = UINT_MAX;
ComPtr<ID3D11InputLayout> _pInputLayout; UINT _stencilRef = 0;
UINT _sampleMask = UINT_MAX; D3D_PRIMITIVE_TOPOLOGY _topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
UINT _stencilRef = 0; bool _compute = false;
D3D_PRIMITIVE_TOPOLOGY _topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
bool _compute = false;
public: public:
PipelineD3D11(); PipelineD3D11();
virtual ~PipelineD3D11() override; virtual ~PipelineD3D11() override;
virtual void Init(RcPipelineDesc desc) override; virtual void Init(RcPipelineDesc desc) override;
virtual void Done() override; virtual void Done() override;
// //
// D3D11 // D3D11
// //
VERUS_P(void InitCompute(RcPipelineDesc desc)); VERUS_P(void InitCompute(RcPipelineDesc desc));
bool IsCompute() const { return _compute; } bool IsCompute() const { return _compute; }
ID3D11VertexShader* GetD3DVS() const { return _pVS.Get(); } ID3D11VertexShader* GetD3DVS() const { return _pVS.Get(); }
ID3D11HullShader* GetD3DHS() const { return _pHS.Get(); } ID3D11HullShader* GetD3DHS() const { return _pHS.Get(); }
ID3D11DomainShader* GetD3DDS() const { return _pDS.Get(); } ID3D11DomainShader* GetD3DDS() const { return _pDS.Get(); }
ID3D11GeometryShader* GetD3DGS() const { return _pGS.Get(); } ID3D11GeometryShader* GetD3DGS() const { return _pGS.Get(); }
ID3D11PixelShader* GetD3DPS() const { return _pPS.Get(); } ID3D11PixelShader* GetD3DPS() const { return _pPS.Get(); }
ID3D11ComputeShader* GetD3DCS() const { return _pCS.Get(); } ID3D11ComputeShader* GetD3DCS() const { return _pCS.Get(); }
ID3D11BlendState* GetD3DBlendState() const { return _pBlendState.Get(); } ID3D11BlendState* GetD3DBlendState() const { return _pBlendState.Get(); }
ID3D11RasterizerState* GetD3DRasterizerState() const { return _pRasterizerState.Get(); } ID3D11RasterizerState* GetD3DRasterizerState() const { return _pRasterizerState.Get(); }
ID3D11DepthStencilState* GetD3DDepthStencilState() const { return _pDepthStencilState.Get(); } ID3D11DepthStencilState* GetD3DDepthStencilState() const { return _pDepthStencilState.Get(); }
ID3D11InputLayout* GetD3DInputLayout() const { return _pInputLayout.Get(); } ID3D11InputLayout* GetD3DInputLayout() const { return _pInputLayout.Get(); }
UINT GetSampleMask() const { return _sampleMask; } UINT GetSampleMask() const { return _sampleMask; }
UINT GetStencilRef() const { return _stencilRef; } UINT GetStencilRef() const { return _stencilRef; }
D3D_PRIMITIVE_TOPOLOGY GetD3DPrimitiveTopology() const { return _topology; } D3D_PRIMITIVE_TOPOLOGY GetD3DPrimitiveTopology() const { return _topology; }
void FillBlendStateRenderTargets(RcPipelineDesc desc, int attachmentCount, D3D11_BLEND_DESC& blendDesc); void FillBlendStateRenderTargets(RcPipelineDesc desc, int attachmentCount, D3D11_BLEND_DESC& blendDesc);
}; };
VERUS_TYPEDEFS(PipelineD3D11); VERUS_TYPEDEFS(PipelineD3D11);
}
} }

View File

@ -1,76 +1,70 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI::RP
{ {
namespace CGI class D3DAttachment
{ {
namespace RP public:
{ Format _format = Format::unormR8G8B8A8;
class D3DAttachment int _sampleCount = 1;
{ Attachment::LoadOp _loadOp = Attachment::LoadOp::load;
public: Attachment::StoreOp _storeOp = Attachment::StoreOp::store;
Format _format = Format::unormR8G8B8A8; Attachment::LoadOp _stencilLoadOp = Attachment::LoadOp::dontCare;
int _sampleCount = 1; Attachment::StoreOp _stencilStoreOp = Attachment::StoreOp::dontCare;
Attachment::LoadOp _loadOp = Attachment::LoadOp::load; int _clearSubpassIndex = -1;
Attachment::StoreOp _storeOp = Attachment::StoreOp::store; };
Attachment::LoadOp _stencilLoadOp = Attachment::LoadOp::dontCare; VERUS_TYPEDEFS(D3DAttachment);
Attachment::StoreOp _stencilStoreOp = Attachment::StoreOp::dontCare;
int _clearSubpassIndex = -1;
};
VERUS_TYPEDEFS(D3DAttachment);
class D3DRef class D3DRef
{ {
public: public:
int _index = -1; int _index = -1;
}; };
VERUS_TYPEDEFS(D3DRef); VERUS_TYPEDEFS(D3DRef);
class D3DSubpass class D3DSubpass
{ {
public: public:
Vector<D3DRef> _vInput; Vector<D3DRef> _vInput;
Vector<D3DRef> _vColor; Vector<D3DRef> _vColor;
Vector<D3DRef> _vResolve; Vector<D3DRef> _vResolve;
Vector<int> _vPreserve; Vector<int> _vPreserve;
D3DRef _depthStencil; D3DRef _depthStencil;
bool _depthStencilReadOnly = false; bool _depthStencilReadOnly = false;
}; };
VERUS_TYPEDEFS(D3DSubpass); VERUS_TYPEDEFS(D3DSubpass);
class D3DDependency class D3DDependency
{ {
public: public:
}; };
VERUS_TYPEDEFS(D3DDependency); VERUS_TYPEDEFS(D3DDependency);
class D3DRenderPass class D3DRenderPass
{ {
public: public:
Vector<D3DAttachment> _vAttachments; Vector<D3DAttachment> _vAttachments;
Vector<D3DSubpass> _vSubpasses; Vector<D3DSubpass> _vSubpasses;
}; };
VERUS_TYPEDEFS(D3DRenderPass); VERUS_TYPEDEFS(D3DRenderPass);
class D3DFramebufferSubpass class D3DFramebufferSubpass
{ {
public: public:
Vector<ID3D11RenderTargetView*> _vRTVs; Vector<ID3D11RenderTargetView*> _vRTVs;
ID3D11DepthStencilView* _pDSV = nullptr; ID3D11DepthStencilView* _pDSV = nullptr;
}; };
VERUS_TYPEDEFS(D3DFramebufferSubpass); VERUS_TYPEDEFS(D3DFramebufferSubpass);
class D3DFramebuffer class D3DFramebuffer
{ {
public: public:
Vector<D3DFramebufferSubpass> _vSubpasses; Vector<D3DFramebufferSubpass> _vSubpasses;
int _width = 0; int _width = 0;
int _height = 0; int _height = 0;
int _mipLevels = 1; int _mipLevels = 1;
CubeMapFace _cubeMapFace = CubeMapFace::none; CubeMapFace _cubeMapFace = CubeMapFace::none;
}; };
VERUS_TYPEDEFS(D3DFramebuffer); VERUS_TYPEDEFS(D3DFramebuffer);
}
}
} }

View File

@ -1,99 +1,96 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI typedef Store<CommandBufferD3D11> TStoreCommandBuffers;
typedef Store<GeometryD3D11> TStoreGeometry;
typedef Store<PipelineD3D11> TStorePipelines;
typedef Store<ShaderD3D11> TStoreShaders;
typedef Store<TextureD3D11> TStoreTextures;
class RendererD3D11 : public Singleton<RendererD3D11>, public BaseRenderer,
private TStoreCommandBuffers, private TStoreGeometry, private TStorePipelines, private TStoreShaders, private TStoreTextures
{ {
typedef Store<CommandBufferD3D11> TStoreCommandBuffers; ExtRealityD3D11 _extReality;
typedef Store<GeometryD3D11> TStoreGeometry; ComPtr<ID3D11Device> _pDevice;
typedef Store<PipelineD3D11> TStorePipelines; ComPtr<ID3D11DeviceContext> _pDeviceContext;
typedef Store<ShaderD3D11> TStoreShaders; ComPtr<IDXGISwapChain> _pSwapChain;
typedef Store<TextureD3D11> TStoreTextures; ComPtr<ID3D11Texture2D> _pSwapChainBuffer;
class RendererD3D11 : public Singleton<RendererD3D11>, public BaseRenderer, ComPtr<ID3D11RenderTargetView> _pSwapChainBufferRTV;
private TStoreCommandBuffers, private TStoreGeometry, private TStorePipelines, private TStoreShaders, private TStoreTextures
{
ExtRealityD3D11 _extReality;
ComPtr<ID3D11Device> _pDevice;
ComPtr<ID3D11DeviceContext> _pDeviceContext;
ComPtr<IDXGISwapChain> _pSwapChain;
ComPtr<ID3D11Texture2D> _pSwapChainBuffer;
ComPtr<ID3D11RenderTargetView> _pSwapChainBufferRTV;
Vector<ComPtr<ID3D11SamplerState>> _vSamplers; Vector<ComPtr<ID3D11SamplerState>> _vSamplers;
Vector<RP::D3DRenderPass> _vRenderPasses; Vector<RP::D3DRenderPass> _vRenderPasses;
Vector<RP::D3DFramebuffer> _vFramebuffers; Vector<RP::D3DFramebuffer> _vFramebuffers;
D3D_FEATURE_LEVEL _featureLevel = D3D_FEATURE_LEVEL_11_0; D3D_FEATURE_LEVEL _featureLevel = D3D_FEATURE_LEVEL_11_0;
DXGI_SWAP_CHAIN_DESC _swapChainDesc = {}; DXGI_SWAP_CHAIN_DESC _swapChainDesc = {};
public: public:
RendererD3D11(); RendererD3D11();
~RendererD3D11(); ~RendererD3D11();
virtual void ReleaseMe() override; virtual void ReleaseMe() override;
void Init(); void Init();
void Done(); void Done();
private: private:
static ComPtr<IDXGIFactory1> CreateFactory(); static ComPtr<IDXGIFactory1> CreateFactory();
ComPtr<IDXGIAdapter1> GetAdapter(ComPtr<IDXGIFactory1> pFactory) const; ComPtr<IDXGIAdapter1> GetAdapter(ComPtr<IDXGIFactory1> pFactory) const;
void CreateSwapChainBufferRTV(); void CreateSwapChainBufferRTV();
void InitD3D(); void InitD3D();
public: public:
// <CreateAndGet> // <CreateAndGet>
void CreateSamplers(); void CreateSamplers();
ID3D11Device* GetD3DDevice() const { return _pDevice.Get(); } ID3D11Device* GetD3DDevice() const { return _pDevice.Get(); }
ID3D11DeviceContext* GetD3DDeviceContext() const { return _pDeviceContext.Get(); } ID3D11DeviceContext* GetD3DDeviceContext() const { return _pDeviceContext.Get(); }
ID3D11SamplerState* GetD3DSamplerState(Sampler s) const; ID3D11SamplerState* GetD3DSamplerState(Sampler s) const;
// </CreateAndGet> // </CreateAndGet>
virtual void ImGuiInit(RPHandle renderPassHandle) override; virtual void ImGuiInit(RPHandle renderPassHandle) override;
virtual void ImGuiRenderDrawData() override; virtual void ImGuiRenderDrawData() override;
virtual void ResizeSwapChain() override; virtual void ResizeSwapChain() override;
virtual PBaseExtReality GetExtReality() override; virtual PBaseExtReality GetExtReality() override;
// Which graphics API? // Which graphics API?
virtual Gapi GetGapi() override { return Gapi::direct3D11; } virtual Gapi GetGapi() override { return Gapi::direct3D11; }
// <FrameCycle> // <FrameCycle>
virtual void BeginFrame() override; virtual void BeginFrame() override;
virtual void AcquireSwapChainImage() override; virtual void AcquireSwapChainImage() override;
virtual void EndFrame() override; virtual void EndFrame() override;
virtual void WaitIdle() override; virtual void WaitIdle() override;
virtual void OnMinimized() override; virtual void OnMinimized() override;
// </FrameCycle> // </FrameCycle>
// <Resources> // <Resources>
virtual PBaseCommandBuffer InsertCommandBuffer() override; virtual PBaseCommandBuffer InsertCommandBuffer() override;
virtual PBaseGeometry InsertGeometry() override; virtual PBaseGeometry InsertGeometry() override;
virtual PBasePipeline InsertPipeline() override; virtual PBasePipeline InsertPipeline() override;
virtual PBaseShader InsertShader() override; virtual PBaseShader InsertShader() override;
virtual PBaseTexture InsertTexture() override; virtual PBaseTexture InsertTexture() override;
virtual void DeleteCommandBuffer(PBaseCommandBuffer p) override; virtual void DeleteCommandBuffer(PBaseCommandBuffer p) override;
virtual void DeleteGeometry(PBaseGeometry p) override; virtual void DeleteGeometry(PBaseGeometry p) override;
virtual void DeletePipeline(PBasePipeline p) override; virtual void DeletePipeline(PBasePipeline p) override;
virtual void DeleteShader(PBaseShader p) override; virtual void DeleteShader(PBaseShader p) override;
virtual void DeleteTexture(PBaseTexture p) override; virtual void DeleteTexture(PBaseTexture p) override;
virtual RPHandle CreateRenderPass(std::initializer_list<RP::Attachment> ilA, std::initializer_list<RP::Subpass> ilS, std::initializer_list<RP::Dependency> ilD) override; virtual RPHandle CreateRenderPass(std::initializer_list<RP::Attachment> ilA, std::initializer_list<RP::Subpass> ilS, std::initializer_list<RP::Dependency> ilD) override;
virtual FBHandle CreateFramebuffer(RPHandle renderPassHandle, std::initializer_list<TexturePtr> il, int w, int h, virtual FBHandle CreateFramebuffer(RPHandle renderPassHandle, std::initializer_list<TexturePtr> il, int w, int h,
int swapChainBufferIndex = -1, CubeMapFace cubeMapFace = CubeMapFace::none) override; int swapChainBufferIndex = -1, CubeMapFace cubeMapFace = CubeMapFace::none) override;
virtual void DeleteRenderPass(RPHandle handle) override; virtual void DeleteRenderPass(RPHandle handle) override;
virtual void DeleteFramebuffer(FBHandle handle) override; virtual void DeleteFramebuffer(FBHandle handle) override;
int GetNextRenderPassIndex() const; int GetNextRenderPassIndex() const;
int GetNextFramebufferIndex() const; int GetNextFramebufferIndex() const;
RP::RcD3DRenderPass GetRenderPass(RPHandle handle) const; RP::RcD3DRenderPass GetRenderPass(RPHandle handle) const;
RP::RcD3DFramebuffer GetFramebuffer(FBHandle handle) const; RP::RcD3DFramebuffer GetFramebuffer(FBHandle handle) const;
// </Resources> // </Resources>
}; };
VERUS_TYPEDEFS(RendererD3D11); VERUS_TYPEDEFS(RendererD3D11);
}
} }
#define VERUS_QREF_RENDERER_D3D11 CGI::PRendererD3D11 pRendererD3D11 = CGI::RendererD3D11::P() #define VERUS_QREF_RENDERER_D3D11 CGI::PRendererD3D11 pRendererD3D11 = CGI::RendererD3D11::P()

View File

@ -59,13 +59,13 @@ void ShaderD3D11::Init(CSZ source, CSZ sourceName, CSZ* branches)
ComPtr<ID3DBlob> pBlob; ComPtr<ID3DBlob> pBlob;
auto CheckErrorMsgs = [this](ComPtr<ID3DBlob>& pErrorMsgs) auto CheckErrorMsgs = [this](ComPtr<ID3DBlob>& pErrorMsgs)
{
if (pErrorMsgs)
{ {
OnError(static_cast<CSZ>(pErrorMsgs->GetBufferPointer())); if (pErrorMsgs)
pErrorMsgs.Reset(); {
} OnError(static_cast<CSZ>(pErrorMsgs->GetBufferPointer()));
}; pErrorMsgs.Reset();
}
};
while (*branches) while (*branches)
{ {
@ -191,10 +191,10 @@ void ShaderD3D11::Done()
for (auto& dsd : _vDescriptorSetDesc) for (auto& dsd : _vDescriptorSetDesc)
dsd._pConstantBuffer.Reset(); dsd._pConstantBuffer.Reset();
for (auto& x : _mapCompiled) for (auto& [key, value] : _mapCompiled)
{ {
VERUS_FOR(i, +Stage::count) VERUS_FOR(i, +Stage::count)
x.second._pBlobs[i].Reset(); value._pBlobs[i].Reset();
} }
VERUS_DONE(ShaderD3D11); VERUS_DONE(ShaderD3D11);

View File

@ -1,108 +1,105 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI struct ShaderInclude : public ID3DInclude
{ {
struct ShaderInclude : public ID3DInclude public:
virtual HRESULT STDMETHODCALLTYPE Open(
D3D_INCLUDE_TYPE IncludeType,
LPCSTR pFileName,
LPCVOID pParentData,
LPCVOID* ppData,
UINT* pBytes) override;
virtual HRESULT STDMETHODCALLTYPE Close(LPCVOID pData) override;
};
VERUS_TYPEDEFS(ShaderInclude);
struct ShaderResources
{
UINT _srvCount = 0;
UINT _uavCount = 0;
UINT _srvStartSlot = 0;
UINT _uavStartSlot = 0;
ID3D11ShaderResourceView* _srvs[VERUS_MAX_FB_ATTACH];
ID3D11UnorderedAccessView* _uavs[VERUS_MAX_FB_ATTACH];
ID3D11SamplerState* _samplers[VERUS_MAX_FB_ATTACH];
};
VERUS_TYPEDEFS(ShaderResources);
class ShaderD3D11 : public BaseShader
{
public:
struct Compiled
{ {
public: ComPtr<ID3DBlob> _pBlobs[+Stage::count];
virtual HRESULT STDMETHODCALLTYPE Open( String _entry;
D3D_INCLUDE_TYPE IncludeType, int _stageCount = 0;
LPCSTR pFileName,
LPCVOID pParentData,
LPCVOID* ppData,
UINT* pBytes) override;
virtual HRESULT STDMETHODCALLTYPE Close(LPCVOID pData) override;
}; };
VERUS_TYPEDEFS(ShaderInclude); VERUS_TYPEDEFS(Compiled);
struct ShaderResources private:
typedef Map<String, Compiled> TMapCompiled;
struct DescriptorSetDesc
{ {
UINT _srvCount = 0; Vector<Sampler> _vSamplers;
UINT _uavCount = 0; ComPtr<ID3D11Buffer> _pConstantBuffer;
UINT _srvStartSlot = 0; const void* _pSrc = nullptr;
UINT _uavStartSlot = 0; int _size = 0;
ID3D11ShaderResourceView* _srvs[VERUS_MAX_FB_ATTACH]; int _alignedSize = 0;
ID3D11UnorderedAccessView* _uavs[VERUS_MAX_FB_ATTACH]; int _capacity = 1;
ID3D11SamplerState* _samplers[VERUS_MAX_FB_ATTACH]; int _capacityInBytes = 0;
UINT _srvCount = 0;
UINT _uavCount = 0;
UINT _srvStartSlot = 0;
UINT _uavStartSlot = 0;
ShaderStageFlags _stageFlags = ShaderStageFlags::vs_fs;
}; };
VERUS_TYPEDEFS(ShaderResources);
class ShaderD3D11 : public BaseShader struct ComplexSet
{ {
public: Vector<TexturePtr> _vTextures;
struct Compiled Vector<ID3D11ShaderResourceView*> _vSRVs;
{ Vector<ID3D11UnorderedAccessView*> _vUAVs;
ComPtr<ID3DBlob> _pBlobs[+Stage::count];
String _entry;
int _stageCount = 0;
};
VERUS_TYPEDEFS(Compiled);
private:
typedef Map<String, Compiled> TMapCompiled;
struct DescriptorSetDesc
{
Vector<Sampler> _vSamplers;
ComPtr<ID3D11Buffer> _pConstantBuffer;
const void* _pSrc = nullptr;
int _size = 0;
int _alignedSize = 0;
int _capacity = 1;
int _capacityInBytes = 0;
UINT _srvCount = 0;
UINT _uavCount = 0;
UINT _srvStartSlot = 0;
UINT _uavStartSlot = 0;
ShaderStageFlags _stageFlags = ShaderStageFlags::vs_fs;
};
struct ComplexSet
{
Vector<TexturePtr> _vTextures;
Vector<ID3D11ShaderResourceView*> _vSRVs;
Vector<ID3D11UnorderedAccessView*> _vUAVs;
};
VERUS_TYPEDEFS(ComplexSet);
TMapCompiled _mapCompiled;
Vector<DescriptorSetDesc> _vDescriptorSetDesc;
Vector<ComplexSet> _vComplexSets;
bool _compute = false;
public:
ShaderD3D11();
virtual ~ShaderD3D11() override;
virtual void Init(CSZ source, CSZ sourceName, CSZ* branches) override;
virtual void Done() override;
virtual void CreateDescriptorSet(int setNumber, const void* pSrc, int size, int capacity, std::initializer_list<Sampler> il, ShaderStageFlags stageFlags) override;
virtual void CreatePipelineLayout() override;
virtual CSHandle BindDescriptorSetTextures(int setNumber, std::initializer_list<TexturePtr> il, const int* pMipLevels, const int* pArrayLayers) override;
virtual void FreeDescriptorSet(CSHandle& complexSetHandle) override;
virtual void BeginBindDescriptors() override;
virtual void EndBindDescriptors() override;
//
// D3D11
//
RcCompiled GetCompiled(CSZ branch) const { return _mapCompiled.at(branch); }
ID3D11Buffer* UpdateConstantBuffer(int setNumber) const;
ShaderStageFlags GetShaderStageFlags(int setNumber) const;
void GetShaderResources(int setNumber, int complexSetHandle, RShaderResources shaderResources) const;
void GetSamplers(int setNumber, int complexSetHandle, RShaderResources shaderResources) const;
int GetDescriptorSetCount() const { return static_cast<int>(_vDescriptorSetDesc.size()); }
bool IsCompute() const { return _compute; }
void OnError(CSZ s) const;
}; };
VERUS_TYPEDEFS(ShaderD3D11); VERUS_TYPEDEFS(ComplexSet);
}
TMapCompiled _mapCompiled;
Vector<DescriptorSetDesc> _vDescriptorSetDesc;
Vector<ComplexSet> _vComplexSets;
bool _compute = false;
public:
ShaderD3D11();
virtual ~ShaderD3D11() override;
virtual void Init(CSZ source, CSZ sourceName, CSZ* branches) override;
virtual void Done() override;
virtual void CreateDescriptorSet(int setNumber, const void* pSrc, int size, int capacity, std::initializer_list<Sampler> il, ShaderStageFlags stageFlags) override;
virtual void CreatePipelineLayout() override;
virtual CSHandle BindDescriptorSetTextures(int setNumber, std::initializer_list<TexturePtr> il, const int* pMipLevels, const int* pArrayLayers) override;
virtual void FreeDescriptorSet(CSHandle& complexSetHandle) override;
virtual void BeginBindDescriptors() override;
virtual void EndBindDescriptors() override;
//
// D3D11
//
RcCompiled GetCompiled(CSZ branch) const { return _mapCompiled.at(branch); }
ID3D11Buffer* UpdateConstantBuffer(int setNumber) const;
ShaderStageFlags GetShaderStageFlags(int setNumber) const;
void GetShaderResources(int setNumber, int complexSetHandle, RShaderResources shaderResources) const;
void GetSamplers(int setNumber, int complexSetHandle, RShaderResources shaderResources) const;
int GetDescriptorSetCount() const { return static_cast<int>(_vDescriptorSetDesc.size()); }
bool IsCompute() const { return _compute; }
void OnError(CSZ s) const;
};
VERUS_TYPEDEFS(ShaderD3D11);
} }

View File

@ -1,56 +1,53 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class TextureD3D11 : public BaseTexture
{ {
class TextureD3D11 : public BaseTexture ComPtr<ID3D11Texture2D> _pTexture2D;
{ ComPtr<ID3D11Texture3D> _pTexture3D;
ComPtr<ID3D11Texture2D> _pTexture2D; ComPtr<ID3D11Texture2D> _pUaTexture;
ComPtr<ID3D11Texture3D> _pTexture3D; Vector<ComPtr<ID3D11Texture2D>> _vReadbackTextures;
ComPtr<ID3D11Texture2D> _pUaTexture; Vector<CSHandle> _vCshGenerateMips;
Vector<ComPtr<ID3D11Texture2D>> _vReadbackTextures; ComPtr<ID3D11ShaderResourceView> _pSRV;
Vector<CSHandle> _vCshGenerateMips; Vector<ComPtr<ID3D11UnorderedAccessView>> _vUAVs;
ComPtr<ID3D11ShaderResourceView> _pSRV; Vector<ComPtr<ID3D11RenderTargetView>> _vRTVs;
Vector<ComPtr<ID3D11UnorderedAccessView>> _vUAVs; ComPtr<ID3D11DepthStencilView> _pDSV[2];
Vector<ComPtr<ID3D11RenderTargetView>> _vRTVs; ComPtr<ID3D11SamplerState> _pSamplerState;
ComPtr<ID3D11DepthStencilView> _pDSV[2];
ComPtr<ID3D11SamplerState> _pSamplerState;
public: public:
TextureD3D11(); TextureD3D11();
virtual ~TextureD3D11() override; virtual ~TextureD3D11() override;
virtual void Init(RcTextureDesc desc) override; virtual void Init(RcTextureDesc desc) override;
virtual void Done() override; virtual void Done() override;
virtual void UpdateSubresource(const void* p, int mipLevel, int arrayLayer, PBaseCommandBuffer pCB) override; virtual void UpdateSubresource(const void* p, int mipLevel, int arrayLayer, PBaseCommandBuffer pCB) override;
virtual bool ReadbackSubresource(void* p, bool recordCopyCommand, PBaseCommandBuffer pCB) override; virtual bool ReadbackSubresource(void* p, bool recordCopyCommand, PBaseCommandBuffer pCB) override;
virtual void GenerateMips(PBaseCommandBuffer pCB) override; virtual void GenerateMips(PBaseCommandBuffer pCB) override;
void GenerateCubeMapMips(PBaseCommandBuffer pCB); void GenerateCubeMapMips(PBaseCommandBuffer pCB);
virtual Continue Scheduled_Update() override; virtual Continue Scheduled_Update() override;
// //
// D3D11 // D3D11
// //
void ClearCshGenerateMips(); void ClearCshGenerateMips();
void CreateSampler(); void CreateSampler();
ID3D11Resource* GetD3DResource() const; ID3D11Resource* GetD3DResource() const;
ID3D11ShaderResourceView* GetSRV() const { return _pSRV.Get(); } ID3D11ShaderResourceView* GetSRV() const { return _pSRV.Get(); }
ID3D11UnorderedAccessView* GetUAV(int index = 0) const { return _vUAVs[index].Get(); } ID3D11UnorderedAccessView* GetUAV(int index = 0) const { return _vUAVs[index].Get(); }
ID3D11RenderTargetView* GetRTV(int index = 0) const { return _vRTVs[index].Get(); } ID3D11RenderTargetView* GetRTV(int index = 0) const { return _vRTVs[index].Get(); }
ID3D11DepthStencilView* GetDSV(bool readOnly = false) const { return readOnly ? _pDSV[1].Get() : _pDSV[0].Get(); } ID3D11DepthStencilView* GetDSV(bool readOnly = false) const { return readOnly ? _pDSV[1].Get() : _pDSV[0].Get(); }
ID3D11SamplerState* GetD3DSamplerState() const { return _pSamplerState.Get(); } ID3D11SamplerState* GetD3DSamplerState() const { return _pSamplerState.Get(); }
static DXGI_FORMAT RemoveSRGB(DXGI_FORMAT format); static DXGI_FORMAT RemoveSRGB(DXGI_FORMAT format);
}; };
VERUS_TYPEDEFS(TextureD3D11); VERUS_TYPEDEFS(TextureD3D11);
}
} }

View File

@ -11,23 +11,23 @@
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion> <VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<ProjectGuid>{53923514-84B2-4B78-889A-8709C6BFA3A5}</ProjectGuid> <ProjectGuid>{53923514-84B2-4B78-889A-8709C6BFA3A5}</ProjectGuid>
<RootNamespace>RendererDirect3D12</RootNamespace> <RootNamespace>RendererDirect3D12</RootNamespace>
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -45,12 +45,6 @@
<Import Project="..\Verus\Verus.props" /> <Import Project="..\Verus\Verus.props" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
@ -61,6 +55,7 @@
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<FloatingPointModel>Fast</FloatingPointModel> <FloatingPointModel>Fast</FloatingPointModel>
<AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -80,6 +75,7 @@
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<FloatingPointModel>Fast</FloatingPointModel> <FloatingPointModel>Fast</FloatingPointModel>
<AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>

View File

@ -1,71 +1,68 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class CommandBufferD3D12 : public BaseCommandBuffer
{ {
class CommandBufferD3D12 : public BaseCommandBuffer ComPtr<ID3D12CommandAllocator> _pOneTimeCommandAllocator;
{ ComPtr<ID3D12GraphicsCommandList3> _pCommandLists[BaseRenderer::s_ringBufferSize];
ComPtr<ID3D12CommandAllocator> _pOneTimeCommandAllocator; RP::PcD3DRenderPass _pRenderPass = nullptr;
ComPtr<ID3D12GraphicsCommandList3> _pCommandLists[BaseRenderer::s_ringBufferSize]; RP::PcD3DFramebuffer _pFramebuffer = nullptr;
RP::PcD3DRenderPass _pRenderPass = nullptr; Vector<FLOAT> _vClearValues;
RP::PcD3DFramebuffer _pFramebuffer = nullptr; Vector<D3D12_RESOURCE_STATES> _vAttachmentStates;
Vector<FLOAT> _vClearValues; Vector<D3D12_RESOURCE_BARRIER> _vBarriers;
Vector<D3D12_RESOURCE_STATES> _vAttachmentStates; int _subpassIndex = 0;
Vector<D3D12_RESOURCE_BARRIER> _vBarriers;
int _subpassIndex = 0;
public: public:
CommandBufferD3D12(); CommandBufferD3D12();
virtual ~CommandBufferD3D12() override; virtual ~CommandBufferD3D12() override;
virtual void Init() override; virtual void Init() override;
virtual void Done() override; virtual void Done() override;
virtual void InitOneTimeSubmit() override; virtual void InitOneTimeSubmit() override;
virtual void DoneOneTimeSubmit() override; virtual void DoneOneTimeSubmit() override;
virtual void Begin() override; virtual void Begin() override;
virtual void End() override; virtual void End() override;
virtual void PipelineImageMemoryBarrier(TexturePtr tex, ImageLayout oldLayout, ImageLayout newLayout, Range mipLevels, Range arrayLayers) override; virtual void PipelineImageMemoryBarrier(TexturePtr tex, ImageLayout oldLayout, ImageLayout newLayout, Range mipLevels, Range arrayLayers) override;
virtual void BeginRenderPass(RPHandle renderPassHandle, FBHandle framebufferHandle, virtual void BeginRenderPass(RPHandle renderPassHandle, FBHandle framebufferHandle,
std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf) override; std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf) override;
virtual void NextSubpass() override; virtual void NextSubpass() override;
virtual void EndRenderPass() override; virtual void EndRenderPass() override;
virtual void BindPipeline(PipelinePtr pipe) override; virtual void BindPipeline(PipelinePtr pipe) override;
virtual void SetViewport(std::initializer_list<Vector4> il, float minDepth, float maxDepth) override; virtual void SetViewport(std::initializer_list<Vector4> il, float minDepth, float maxDepth) override;
virtual void SetScissor(std::initializer_list<Vector4> il) override; virtual void SetScissor(std::initializer_list<Vector4> il) override;
virtual void SetBlendConstants(const float* p) override; virtual void SetBlendConstants(const float* p) override;
virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter) override; virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter) override;
virtual void BindIndexBuffer(GeometryPtr geo) override; virtual void BindIndexBuffer(GeometryPtr geo) override;
virtual bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle) override; virtual bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle) override;
virtual bool BindDescriptors(ShaderPtr shader, int setNumber, GeometryPtr geo, int sbIndex) override; virtual bool BindDescriptors(ShaderPtr shader, int setNumber, GeometryPtr geo, int sbIndex) override;
virtual void PushConstants(ShaderPtr shader, int offset, int size, const void* p, ShaderStageFlags stageFlags) override; virtual void PushConstants(ShaderPtr shader, int offset, int size, const void* p, ShaderStageFlags stageFlags) override;
virtual void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance) override; virtual void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance) override;
virtual void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int vertexOffset, int firstInstance) override; virtual void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int vertexOffset, int firstInstance) override;
virtual void Dispatch(int groupCountX, int groupCountY, int groupCountZ) override; virtual void Dispatch(int groupCountX, int groupCountY, int groupCountZ) override;
virtual void DispatchMesh(int groupCountX, int groupCountY, int groupCountZ) override; virtual void DispatchMesh(int groupCountX, int groupCountY, int groupCountZ) override;
virtual void TraceRays(int width, int height, int depth) override; virtual void TraceRays(int width, int height, int depth) override;
virtual void ProfilerBeginEvent(UINT32 color, CSZ text) override; virtual void ProfilerBeginEvent(UINT32 color, CSZ text) override;
virtual void ProfilerEndEvent() override; virtual void ProfilerEndEvent() override;
virtual void ProfilerSetMarker(UINT32 color, CSZ text) override; virtual void ProfilerSetMarker(UINT32 color, CSZ text) override;
// //
// D3D12 // D3D12
// //
ID3D12GraphicsCommandList3* GetD3DGraphicsCommandList() const; ID3D12GraphicsCommandList3* GetD3DGraphicsCommandList() const;
void PrepareSubpass(); void PrepareSubpass();
}; };
VERUS_TYPEDEFS(CommandBufferD3D12); VERUS_TYPEDEFS(CommandBufferD3D12);
}
} }

View File

@ -1,61 +1,58 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class DescriptorHeap
{ {
class DescriptorHeap ComPtr<ID3D12DescriptorHeap> _pDescriptorHeap;
{ CD3DX12_CPU_DESCRIPTOR_HANDLE _hCPUHandleForHeapStart;
ComPtr<ID3D12DescriptorHeap> _pDescriptorHeap; CD3DX12_GPU_DESCRIPTOR_HANDLE _hGPUHandleForHeapStart;
CD3DX12_CPU_DESCRIPTOR_HANDLE _hCPUHandleForHeapStart; D3D12_DESCRIPTOR_HEAP_TYPE _type = D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES;
CD3DX12_GPU_DESCRIPTOR_HANDLE _hGPUHandleForHeapStart; UINT _handleIncrementSize = 0;
D3D12_DESCRIPTOR_HEAP_TYPE _type = D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES;
UINT _handleIncrementSize = 0;
public: public:
void Reset() { VERUS_COM_RELEASE_CHECK(_pDescriptorHeap.Get()); _pDescriptorHeap.Reset(); } void Reset() { VERUS_COM_RELEASE_CHECK(_pDescriptorHeap.Get()); _pDescriptorHeap.Reset(); }
ID3D12DescriptorHeap* GetD3DDescriptorHeap() const { return _pDescriptorHeap.Get(); } ID3D12DescriptorHeap* GetD3DDescriptorHeap() const { return _pDescriptorHeap.Get(); }
void Create(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_TYPE type, int count, bool shaderVisible = false); void Create(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_TYPE type, int count, bool shaderVisible = false);
CD3DX12_CPU_DESCRIPTOR_HANDLE AtCPU(int index) const; CD3DX12_CPU_DESCRIPTOR_HANDLE AtCPU(int index) const;
CD3DX12_GPU_DESCRIPTOR_HANDLE AtGPU(int index) const; CD3DX12_GPU_DESCRIPTOR_HANDLE AtGPU(int index) const;
D3D12_DESCRIPTOR_HEAP_TYPE GetType() const { return _type; } D3D12_DESCRIPTOR_HEAP_TYPE GetType() const { return _type; }
UINT GetHandleIncrementSize() const { return _handleIncrementSize; } UINT GetHandleIncrementSize() const { return _handleIncrementSize; }
}; };
VERUS_TYPEDEFS(DescriptorHeap); VERUS_TYPEDEFS(DescriptorHeap);
struct HandlePair struct HandlePair
{ {
CD3DX12_CPU_DESCRIPTOR_HANDLE _hCPU; CD3DX12_CPU_DESCRIPTOR_HANDLE _hCPU;
CD3DX12_GPU_DESCRIPTOR_HANDLE _hGPU; CD3DX12_GPU_DESCRIPTOR_HANDLE _hGPU;
HandlePair( HandlePair(
CD3DX12_CPU_DESCRIPTOR_HANDLE hCPU = D3D12_DEFAULT, CD3DX12_CPU_DESCRIPTOR_HANDLE hCPU = D3D12_DEFAULT,
CD3DX12_GPU_DESCRIPTOR_HANDLE hGPU = D3D12_DEFAULT) : _hCPU(hCPU), _hGPU(hGPU) {} CD3DX12_GPU_DESCRIPTOR_HANDLE hGPU = D3D12_DEFAULT) : _hCPU(hCPU), _hGPU(hGPU) {}
}; };
VERUS_TYPEDEFS(HandlePair); VERUS_TYPEDEFS(HandlePair);
// This descriptor heap should be refilled every frame: // This descriptor heap should be refilled every frame:
class DynamicDescriptorHeap : public DescriptorHeap class DynamicDescriptorHeap : public DescriptorHeap
{ {
int _capacity = 0; int _capacity = 0;
int _offset = 0; int _offset = 0;
UINT64 _currentFrame = UINT64_MAX; UINT64 _currentFrame = UINT64_MAX;
UINT64 _peakLoad = 0; UINT64 _peakLoad = 0;
public: public:
void Create(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_TYPE type, int count, int staticCount = 0, bool shaderVisible = false); void Create(ID3D12Device* pDevice, D3D12_DESCRIPTOR_HEAP_TYPE type, int count, int staticCount = 0, bool shaderVisible = false);
HandlePair GetNextHandlePair(int count = 1); HandlePair GetNextHandlePair(int count = 1);
HandlePair GetStaticHandlePair(int index); HandlePair GetStaticHandlePair(int index);
int GetCapacity() const { return _capacity; } int GetCapacity() const { return _capacity; }
int GetOffset() const { return _offset; } int GetOffset() const { return _offset; }
}; };
VERUS_TYPEDEFS(DynamicDescriptorHeap); VERUS_TYPEDEFS(DynamicDescriptorHeap);
}
} }

View File

@ -1,67 +1,64 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class RendererD3D12;
class ExtRealityD3D12 : public BaseExtReality
{ {
class RendererD3D12; struct SwapChainEx
class ExtRealityD3D12 : public BaseExtReality
{ {
struct SwapChainEx XrSwapchain _handle = XR_NULL_HANDLE;
{ int32_t _width = 0;
XrSwapchain _handle = XR_NULL_HANDLE; int32_t _height = 0;
int32_t _width = 0; Vector<XrSwapchainImageD3D12KHR> _vImages;
int32_t _height = 0; DescriptorHeap _dhImageViews;
Vector<XrSwapchainImageD3D12KHR> _vImages;
DescriptorHeap _dhImageViews;
};
Vector<SwapChainEx> _vSwapChains;
LUID _adapterLuid;
D3D_FEATURE_LEVEL _minFeatureLevel = D3D_FEATURE_LEVEL_11_0;
public:
ExtRealityD3D12();
virtual ~ExtRealityD3D12() override;
virtual void Init() override;
virtual void Done() override;
void InitByRenderer(RendererD3D12* pRenderer);
private:
void GetSystem();
void CreateSwapChains(ID3D12Device* pDevice, int64_t format);
void CreateImageView(ID3D12Device* pDevice, int64_t format, XrSwapchainImageD3D12KHR& image, D3D12_CPU_DESCRIPTOR_HANDLE handle);
virtual XrSwapchain GetSwapChain(int viewIndex) override;
virtual void GetSwapChainSize(int viewIndex, int32_t& w, int32_t& h) override;
public:
LUID GetAdapterLuid() const { return _adapterLuid; }
D3D_FEATURE_LEVEL GetMinFeatureLevel() const { return _minFeatureLevel; }
ID3D12Resource* GetD3DResource(int viewIndex, int imageIndex) const;
D3D12_CPU_DESCRIPTOR_HANDLE GetRTV(int viewIndex, int imageIndex) const;
virtual void CreateActions() override;
virtual void PollEvents() override;
virtual void SyncActions(UINT32 activeActionSetsMask) override;
virtual bool GetActionStateBoolean(int actionIndex, bool& currentState, bool* pChangedState, int subaction) override;
virtual bool GetActionStateFloat(int actionIndex, float& currentState, bool* pChangedState, int subaction) override;
virtual bool GetActionStatePose(int actionIndex, bool& currentState, Math::RPose pose, int subaction) override;
virtual void BeginFrame() override;
virtual int LocateViews() override;
virtual void BeginView(int viewIndex, RViewDesc viewDesc) override;
virtual void AcquireSwapChainImage() override;
virtual void EndView(int viewIndex) override;
virtual void EndFrame() override;
virtual void BeginAreaUpdate() override;
virtual void EndAreaUpdate(PcVector4 pUserOffset) override;
}; };
VERUS_TYPEDEFS(ExtRealityD3D12);
} Vector<SwapChainEx> _vSwapChains;
LUID _adapterLuid;
D3D_FEATURE_LEVEL _minFeatureLevel = D3D_FEATURE_LEVEL_11_0;
public:
ExtRealityD3D12();
virtual ~ExtRealityD3D12() override;
virtual void Init() override;
virtual void Done() override;
void InitByRenderer(RendererD3D12* pRenderer);
private:
void GetSystem();
void CreateSwapChains(ID3D12Device* pDevice, int64_t format);
void CreateImageView(ID3D12Device* pDevice, int64_t format, XrSwapchainImageD3D12KHR& image, D3D12_CPU_DESCRIPTOR_HANDLE handle);
virtual XrSwapchain GetSwapChain(int viewIndex) override;
virtual void GetSwapChainSize(int viewIndex, int32_t& w, int32_t& h) override;
public:
LUID GetAdapterLuid() const { return _adapterLuid; }
D3D_FEATURE_LEVEL GetMinFeatureLevel() const { return _minFeatureLevel; }
ID3D12Resource* GetD3DResource(int viewIndex, int imageIndex) const;
D3D12_CPU_DESCRIPTOR_HANDLE GetRTV(int viewIndex, int imageIndex) const;
virtual void CreateActions() override;
virtual void PollEvents() override;
virtual void SyncActions(UINT32 activeActionSetsMask) override;
virtual bool GetActionStateBoolean(int actionIndex, bool& currentState, bool* pChangedState, int subaction) override;
virtual bool GetActionStateFloat(int actionIndex, float& currentState, bool* pChangedState, int subaction) override;
virtual bool GetActionStatePose(int actionIndex, bool& currentState, Math::RPose pose, int subaction) override;
virtual void BeginFrame() override;
virtual int LocateViews() override;
virtual void BeginView(int viewIndex, RViewDesc viewDesc) override;
virtual void AcquireSwapChainImage() override;
virtual void EndView(int viewIndex) override;
virtual void EndFrame() override;
virtual void BeginAreaUpdate() override;
virtual void EndAreaUpdate(PcVector4 pUserOffset) override;
};
VERUS_TYPEDEFS(ExtRealityD3D12);
} }

View File

@ -1,72 +1,69 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class GeometryD3D12 : public BaseGeometry
{ {
class GeometryD3D12 : public BaseGeometry struct BufferEx
{ {
struct BufferEx D3D12MA::Allocation* _pMaAllocation = nullptr;
{ ComPtr<ID3D12Resource> _pBuffer;
D3D12MA::Allocation* _pMaAllocation = nullptr; UINT64 _bufferSize = 0;
ComPtr<ID3D12Resource> _pBuffer; INT64 _utilization = -1;
UINT64 _bufferSize = 0;
INT64 _utilization = -1;
};
struct VertexBufferEx : BufferEx
{
D3D12_VERTEX_BUFFER_VIEW _bufferView[BaseRenderer::s_ringBufferSize] = {};
};
struct StructuredBufferEx : BufferEx
{
DescriptorHeap _dhDynamicOffsets;
int _structSize = 0;
};
Vector<VertexBufferEx> _vVertexBuffers;
BufferEx _indexBuffer;
Vector<VertexBufferEx> _vStagingVertexBuffers;
BufferEx _stagingIndexBuffer;
Vector<StructuredBufferEx> _vStructuredBuffers;
D3D12_INDEX_BUFFER_VIEW _indexBufferView[BaseRenderer::s_ringBufferSize] = {};
Vector<D3D12_INPUT_ELEMENT_DESC> _vInputElementDescs;
Vector<int> _vStrides;
public:
GeometryD3D12();
virtual ~GeometryD3D12() override;
virtual void Init(RcGeometryDesc desc) override;
virtual void Done() override;
virtual void CreateVertexBuffer(int count, int binding) override;
virtual void UpdateVertexBuffer(const void* p, int binding, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual void CreateIndexBuffer(int count) override;
virtual void UpdateIndexBuffer(const void* p, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual void CreateStorageBuffer(int count, int structSize, int sbIndex, ShaderStageFlags stageFlags) override;
virtual void UpdateStorageBuffer(const void* p, int sbIndex, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual int GetStorageBufferStructSize(int sbIndex) const override;
virtual Continue Scheduled_Update() override;
//
// D3D12
//
D3D12_INPUT_LAYOUT_DESC GetD3DInputLayoutDesc(UINT32 bindingsFilter, Vector<D3D12_INPUT_ELEMENT_DESC>& vInputElementDescs) const;
int GetVertexBufferCount() const { return Utils::Cast32(_vVertexBuffers.size()); }
const D3D12_VERTEX_BUFFER_VIEW* GetD3DVertexBufferView(int binding) const;
const D3D12_INDEX_BUFFER_VIEW* GetD3DIndexBufferView() const;
CD3DX12_GPU_DESCRIPTOR_HANDLE CopyStructuredBufferView(int sbIndex) const;
void UpdateUtilization() const;
}; };
VERUS_TYPEDEFS(GeometryD3D12);
} struct VertexBufferEx : BufferEx
{
D3D12_VERTEX_BUFFER_VIEW _bufferView[BaseRenderer::s_ringBufferSize] = {};
};
struct StructuredBufferEx : BufferEx
{
DescriptorHeap _dhDynamicOffsets;
int _structSize = 0;
};
Vector<VertexBufferEx> _vVertexBuffers;
BufferEx _indexBuffer;
Vector<VertexBufferEx> _vStagingVertexBuffers;
BufferEx _stagingIndexBuffer;
Vector<StructuredBufferEx> _vStructuredBuffers;
D3D12_INDEX_BUFFER_VIEW _indexBufferView[BaseRenderer::s_ringBufferSize] = {};
Vector<D3D12_INPUT_ELEMENT_DESC> _vInputElementDescs;
Vector<int> _vStrides;
public:
GeometryD3D12();
virtual ~GeometryD3D12() override;
virtual void Init(RcGeometryDesc desc) override;
virtual void Done() override;
virtual void CreateVertexBuffer(int count, int binding) override;
virtual void UpdateVertexBuffer(const void* p, int binding, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual void CreateIndexBuffer(int count) override;
virtual void UpdateIndexBuffer(const void* p, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual void CreateStorageBuffer(int count, int structSize, int sbIndex, ShaderStageFlags stageFlags) override;
virtual void UpdateStorageBuffer(const void* p, int sbIndex, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual int GetStorageBufferStructSize(int sbIndex) const override;
virtual Continue Scheduled_Update() override;
//
// D3D12
//
D3D12_INPUT_LAYOUT_DESC GetD3DInputLayoutDesc(UINT32 bindingsFilter, Vector<D3D12_INPUT_ELEMENT_DESC>& vInputElementDescs) const;
int GetVertexBufferCount() const { return Utils::Cast32(_vVertexBuffers.size()); }
const D3D12_VERTEX_BUFFER_VIEW* GetD3DVertexBufferView(int binding) const;
const D3D12_INDEX_BUFFER_VIEW* GetD3DIndexBufferView() const;
CD3DX12_GPU_DESCRIPTOR_HANDLE CopyStructuredBufferView(int sbIndex) const;
void UpdateUtilization() const;
};
VERUS_TYPEDEFS(GeometryD3D12);
} }

View File

@ -1,27 +1,24 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI D3D12_COMPARISON_FUNC ToNativeCompareOp(CompareOp compareOp);
{
D3D12_COMPARISON_FUNC ToNativeCompareOp(CompareOp compareOp);
UINT ToNativeCubeMapFace(CubeMapFace face); UINT ToNativeCubeMapFace(CubeMapFace face);
D3D12_FILL_MODE ToNativePolygonMode(PolygonMode polygonMode); D3D12_FILL_MODE ToNativePolygonMode(PolygonMode polygonMode);
D3D12_CULL_MODE ToNativeCullMode(CullMode cullMode); D3D12_CULL_MODE ToNativeCullMode(CullMode cullMode);
D3D_PRIMITIVE_TOPOLOGY ToNativePrimitiveTopology(PrimitiveTopology primitiveTopology); D3D_PRIMITIVE_TOPOLOGY ToNativePrimitiveTopology(PrimitiveTopology primitiveTopology);
D3D12_PRIMITIVE_TOPOLOGY_TYPE ToNativePrimitiveTopologyType(PrimitiveTopology primitiveTopology); D3D12_PRIMITIVE_TOPOLOGY_TYPE ToNativePrimitiveTopologyType(PrimitiveTopology primitiveTopology);
D3D12_RESOURCE_STATES ToNativeImageLayout(ImageLayout layout); D3D12_RESOURCE_STATES ToNativeImageLayout(ImageLayout layout);
DXGI_FORMAT ToNativeFormat(Format format, bool typeless); DXGI_FORMAT ToNativeFormat(Format format, bool typeless);
DXGI_FORMAT ToNativeSampledDepthFormat(Format format); DXGI_FORMAT ToNativeSampledDepthFormat(Format format);
CSZ ToNativeSemanticName(ViaUsage usage); CSZ ToNativeSemanticName(ViaUsage usage);
DXGI_FORMAT ToNativeFormat(ViaUsage usage, ViaType type, int components); DXGI_FORMAT ToNativeFormat(ViaUsage usage, ViaType type, int components);
}
} }

View File

@ -1,37 +1,34 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class PipelineD3D12 : public BasePipeline
{ {
class PipelineD3D12 : public BasePipeline ComPtr<ID3D12PipelineState> _pPipelineState;
{ ID3D12RootSignature* _pRootSignature = nullptr;
ComPtr<ID3D12PipelineState> _pPipelineState; D3D_PRIMITIVE_TOPOLOGY _topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
ID3D12RootSignature* _pRootSignature = nullptr; bool _compute = false;
D3D_PRIMITIVE_TOPOLOGY _topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
bool _compute = false;
public: public:
PipelineD3D12(); PipelineD3D12();
virtual ~PipelineD3D12() override; virtual ~PipelineD3D12() override;
virtual void Init(RcPipelineDesc desc) override; virtual void Init(RcPipelineDesc desc) override;
virtual void Done() override; virtual void Done() override;
// //
// D3D12 // D3D12
// //
VERUS_P(void InitCompute(RcPipelineDesc desc)); VERUS_P(void InitCompute(RcPipelineDesc desc));
VERUS_P(void InitMeshShading(RcPipelineDesc desc)); VERUS_P(void InitMeshShading(RcPipelineDesc desc));
D3D12_SHADER_BYTECODE ToBytecode(ID3DBlob* pBlob); D3D12_SHADER_BYTECODE ToBytecode(ID3DBlob* pBlob);
bool IsCompute() const { return _compute; } bool IsCompute() const { return _compute; }
ID3D12PipelineState* GetD3DPipelineState() const { return _pPipelineState.Get(); } ID3D12PipelineState* GetD3DPipelineState() const { return _pPipelineState.Get(); }
ID3D12RootSignature* GetD3DRootSignature() const { return _pRootSignature; } ID3D12RootSignature* GetD3DRootSignature() const { return _pRootSignature; }
D3D_PRIMITIVE_TOPOLOGY GetD3DPrimitiveTopology() const { return _topology; } D3D_PRIMITIVE_TOPOLOGY GetD3DPrimitiveTopology() const { return _topology; }
void FillBlendStateRenderTargets(RcPipelineDesc desc, int attachmentCount, D3D12_BLEND_DESC& blendDesc); void FillBlendStateRenderTargets(RcPipelineDesc desc, int attachmentCount, D3D12_BLEND_DESC& blendDesc);
}; };
VERUS_TYPEDEFS(PipelineD3D12); VERUS_TYPEDEFS(PipelineD3D12);
}
} }

View File

@ -1,80 +1,74 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI::RP
{ {
namespace CGI class D3DAttachment
{ {
namespace RP public:
{ Format _format = Format::unormR8G8B8A8;
class D3DAttachment int _sampleCount = 1;
{ Attachment::LoadOp _loadOp = Attachment::LoadOp::load;
public: Attachment::StoreOp _storeOp = Attachment::StoreOp::store;
Format _format = Format::unormR8G8B8A8; Attachment::LoadOp _stencilLoadOp = Attachment::LoadOp::dontCare;
int _sampleCount = 1; Attachment::StoreOp _stencilStoreOp = Attachment::StoreOp::dontCare;
Attachment::LoadOp _loadOp = Attachment::LoadOp::load; D3D12_RESOURCE_STATES _initialState = D3D12_RESOURCE_STATE_COMMON;
Attachment::StoreOp _storeOp = Attachment::StoreOp::store; D3D12_RESOURCE_STATES _finalState = D3D12_RESOURCE_STATE_COMMON;
Attachment::LoadOp _stencilLoadOp = Attachment::LoadOp::dontCare; int _clearSubpassIndex = -1;
Attachment::StoreOp _stencilStoreOp = Attachment::StoreOp::dontCare; };
D3D12_RESOURCE_STATES _initialState = D3D12_RESOURCE_STATE_COMMON; VERUS_TYPEDEFS(D3DAttachment);
D3D12_RESOURCE_STATES _finalState = D3D12_RESOURCE_STATE_COMMON;
int _clearSubpassIndex = -1;
};
VERUS_TYPEDEFS(D3DAttachment);
class D3DRef class D3DRef
{ {
public: public:
int _index = -1; int _index = -1;
D3D12_RESOURCE_STATES _state = D3D12_RESOURCE_STATE_COMMON; D3D12_RESOURCE_STATES _state = D3D12_RESOURCE_STATE_COMMON;
}; };
VERUS_TYPEDEFS(D3DRef); VERUS_TYPEDEFS(D3DRef);
class D3DSubpass class D3DSubpass
{ {
public: public:
Vector<D3DRef> _vInput; Vector<D3DRef> _vInput;
Vector<D3DRef> _vColor; Vector<D3DRef> _vColor;
Vector<D3DRef> _vResolve; Vector<D3DRef> _vResolve;
Vector<int> _vPreserve; Vector<int> _vPreserve;
D3DRef _depthStencil; D3DRef _depthStencil;
}; };
VERUS_TYPEDEFS(D3DSubpass); VERUS_TYPEDEFS(D3DSubpass);
class D3DDependency class D3DDependency
{ {
public: public:
}; };
VERUS_TYPEDEFS(D3DDependency); VERUS_TYPEDEFS(D3DDependency);
class D3DRenderPass class D3DRenderPass
{ {
public: public:
Vector<D3DAttachment> _vAttachments; Vector<D3DAttachment> _vAttachments;
Vector<D3DSubpass> _vSubpasses; Vector<D3DSubpass> _vSubpasses;
}; };
VERUS_TYPEDEFS(D3DRenderPass); VERUS_TYPEDEFS(D3DRenderPass);
class D3DFramebufferSubpass class D3DFramebufferSubpass
{ {
public: public:
Vector<ID3D12Resource*> _vResources; Vector<ID3D12Resource*> _vResources;
DescriptorHeap _dhRTVs; DescriptorHeap _dhRTVs;
DescriptorHeap _dhDSV; DescriptorHeap _dhDSV;
}; };
VERUS_TYPEDEFS(D3DFramebufferSubpass); VERUS_TYPEDEFS(D3DFramebufferSubpass);
class D3DFramebuffer class D3DFramebuffer
{ {
public: public:
Vector<ID3D12Resource*> _vResources; Vector<ID3D12Resource*> _vResources;
Vector<D3DFramebufferSubpass> _vSubpasses; Vector<D3DFramebufferSubpass> _vSubpasses;
int _width = 0; int _width = 0;
int _height = 0; int _height = 0;
int _mipLevels = 1; int _mipLevels = 1;
CubeMapFace _cubeMapFace = CubeMapFace::none; CubeMapFace _cubeMapFace = CubeMapFace::none;
}; };
VERUS_TYPEDEFS(D3DFramebuffer); VERUS_TYPEDEFS(D3DFramebuffer);
}
}
} }

View File

@ -1,129 +1,126 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI typedef Store<CommandBufferD3D12> TStoreCommandBuffers;
typedef Store<GeometryD3D12> TStoreGeometry;
typedef Store<PipelineD3D12> TStorePipelines;
typedef Store<ShaderD3D12> TStoreShaders;
typedef Store<TextureD3D12> TStoreTextures;
class RendererD3D12 : public Singleton<RendererD3D12>, public BaseRenderer,
private TStoreCommandBuffers, private TStoreGeometry, private TStorePipelines, private TStoreShaders, private TStoreTextures
{ {
typedef Store<CommandBufferD3D12> TStoreCommandBuffers; typedef Map<std::thread::id, ComPtr<ID3D12CommandAllocator>> TMapCommandAllocators;
typedef Store<GeometryD3D12> TStoreGeometry;
typedef Store<PipelineD3D12> TStorePipelines;
typedef Store<ShaderD3D12> TStoreShaders;
typedef Store<TextureD3D12> TStoreTextures;
class RendererD3D12 : public Singleton<RendererD3D12>, public BaseRenderer,
private TStoreCommandBuffers, private TStoreGeometry, private TStorePipelines, private TStoreShaders, private TStoreTextures
{
typedef Map<std::thread::id, ComPtr<ID3D12CommandAllocator>> TMapCommandAllocators;
D3D12MA::Allocator* _pMaAllocator = nullptr; D3D12MA::Allocator* _pMaAllocator = nullptr;
ExtRealityD3D12 _extReality; ExtRealityD3D12 _extReality;
ComPtr<ID3D12Device3> _pDevice; ComPtr<ID3D12Device3> _pDevice;
ComPtr<ID3D12CommandQueue> _pCommandQueue; ComPtr<ID3D12CommandQueue> _pCommandQueue;
ComPtr<IDXGISwapChain4> _pSwapChain; ComPtr<IDXGISwapChain4> _pSwapChain;
Vector<ComPtr<ID3D12Resource>> _vSwapChainBuffers; Vector<ComPtr<ID3D12Resource>> _vSwapChainBuffers;
DescriptorHeap _dhSwapChainBuffersRTVs; DescriptorHeap _dhSwapChainBuffersRTVs;
DynamicDescriptorHeap _dhViews; DynamicDescriptorHeap _dhViews;
DynamicDescriptorHeap _dhSamplers; DynamicDescriptorHeap _dhSamplers;
TMapCommandAllocators _mapCommandAllocators[s_ringBufferSize]; TMapCommandAllocators _mapCommandAllocators[s_ringBufferSize];
ComPtr<ID3D12Fence> _pFence; ComPtr<ID3D12Fence> _pFence;
HANDLE _hFence = INVALID_HANDLE_VALUE; HANDLE _hFence = INVALID_HANDLE_VALUE;
HANDLE _hFrameLatencyWaitableObject = INVALID_HANDLE_VALUE; HANDLE _hFrameLatencyWaitableObject = INVALID_HANDLE_VALUE;
UINT64 _nextFenceValue = 1; UINT64 _nextFenceValue = 1;
UINT64 _fenceValues[s_ringBufferSize] = {}; UINT64 _fenceValues[s_ringBufferSize] = {};
Vector<D3D12_STATIC_SAMPLER_DESC> _vSamplers; Vector<D3D12_STATIC_SAMPLER_DESC> _vSamplers;
Vector<RP::D3DRenderPass> _vRenderPasses; Vector<RP::D3DRenderPass> _vRenderPasses;
Vector<RP::D3DFramebuffer> _vFramebuffers; Vector<RP::D3DFramebuffer> _vFramebuffers;
D3D_FEATURE_LEVEL _featureLevel = D3D_FEATURE_LEVEL_11_0; D3D_FEATURE_LEVEL _featureLevel = D3D_FEATURE_LEVEL_11_0;
DXGI_SWAP_CHAIN_DESC1 _swapChainDesc = {}; DXGI_SWAP_CHAIN_DESC1 _swapChainDesc = {};
public: public:
RendererD3D12(); RendererD3D12();
~RendererD3D12(); ~RendererD3D12();
virtual void ReleaseMe() override; virtual void ReleaseMe() override;
void Init(); void Init();
void Done(); void Done();
private: private:
static void EnableDebugLayer(); static void EnableDebugLayer();
static ComPtr<IDXGIFactory6> CreateFactory(); static ComPtr<IDXGIFactory6> CreateFactory();
ComPtr<IDXGIAdapter4> GetAdapter(ComPtr<IDXGIFactory6> pFactory, D3D_FEATURE_LEVEL featureLevel) const; ComPtr<IDXGIAdapter4> GetAdapter(ComPtr<IDXGIFactory6> pFactory, D3D_FEATURE_LEVEL featureLevel) const;
static bool CheckFeatureSupportAllowTearing(ComPtr<IDXGIFactory6> pFactory); static bool CheckFeatureSupportAllowTearing(ComPtr<IDXGIFactory6> pFactory);
void CreateSwapChainBuffersRTVs(); void CreateSwapChainBuffersRTVs();
void InitD3D(); void InitD3D();
void WaitForFrameLatencyWaitableObject(); void WaitForFrameLatencyWaitableObject();
public: public:
// <CreateAndGet> // <CreateAndGet>
ComPtr<ID3D12CommandQueue> CreateD3DCommandQueue(D3D12_COMMAND_LIST_TYPE type); ComPtr<ID3D12CommandQueue> CreateD3DCommandQueue(D3D12_COMMAND_LIST_TYPE type);
ComPtr<ID3D12CommandAllocator> CreateD3DCommandAllocator(D3D12_COMMAND_LIST_TYPE type); ComPtr<ID3D12CommandAllocator> CreateD3DCommandAllocator(D3D12_COMMAND_LIST_TYPE type);
ComPtr<ID3D12GraphicsCommandList3> CreateD3DCommandList(D3D12_COMMAND_LIST_TYPE type, ComPtr<ID3D12CommandAllocator> pCommandAllocator); ComPtr<ID3D12GraphicsCommandList3> CreateD3DCommandList(D3D12_COMMAND_LIST_TYPE type, ComPtr<ID3D12CommandAllocator> pCommandAllocator);
ComPtr<ID3D12Fence> CreateD3DFence(); ComPtr<ID3D12Fence> CreateD3DFence();
UINT64 QueueSignal(); UINT64 QueueSignal();
void WaitForFenceValue(UINT64 value); void WaitForFenceValue(UINT64 value);
void QueueWaitIdle(); void QueueWaitIdle();
void CreateSamplers(); void CreateSamplers();
ID3D12Device3* GetD3DDevice() const { return _pDevice.Get(); } ID3D12Device3* GetD3DDevice() const { return _pDevice.Get(); }
ID3D12CommandQueue* GetD3DCommandQueue() const { return _pCommandQueue.Get(); } ID3D12CommandQueue* GetD3DCommandQueue() const { return _pCommandQueue.Get(); }
D3D12MA::Allocator* GetMaAllocator() const { return _pMaAllocator; } D3D12MA::Allocator* GetMaAllocator() const { return _pMaAllocator; }
ID3D12CommandAllocator* GetD3DCommandAllocator(int ringBufferIndex) const { return _mapCommandAllocators[ringBufferIndex].at(std::this_thread::get_id()).Get(); } ID3D12CommandAllocator* GetD3DCommandAllocator(int ringBufferIndex) const { return _mapCommandAllocators[ringBufferIndex].at(std::this_thread::get_id()).Get(); }
D3D12_STATIC_SAMPLER_DESC GetD3DStaticSamplerDesc(Sampler s) const; D3D12_STATIC_SAMPLER_DESC GetD3DStaticSamplerDesc(Sampler s) const;
// </CreateAndGet> // </CreateAndGet>
virtual void ImGuiInit(RPHandle renderPassHandle) override; virtual void ImGuiInit(RPHandle renderPassHandle) override;
virtual void ImGuiRenderDrawData() override; virtual void ImGuiRenderDrawData() override;
virtual void ResizeSwapChain() override; virtual void ResizeSwapChain() override;
virtual PBaseExtReality GetExtReality() override; virtual PBaseExtReality GetExtReality() override;
// Which graphics API? // Which graphics API?
virtual Gapi GetGapi() override { return Gapi::direct3D12; } virtual Gapi GetGapi() override { return Gapi::direct3D12; }
// <FrameCycle> // <FrameCycle>
virtual void BeginFrame() override; virtual void BeginFrame() override;
virtual void AcquireSwapChainImage() override; virtual void AcquireSwapChainImage() override;
virtual void EndFrame() override; virtual void EndFrame() override;
virtual void WaitIdle() override; virtual void WaitIdle() override;
virtual void OnMinimized() override; virtual void OnMinimized() override;
// </FrameCycle> // </FrameCycle>
// <Resources> // <Resources>
virtual PBaseCommandBuffer InsertCommandBuffer() override; virtual PBaseCommandBuffer InsertCommandBuffer() override;
virtual PBaseGeometry InsertGeometry() override; virtual PBaseGeometry InsertGeometry() override;
virtual PBasePipeline InsertPipeline() override; virtual PBasePipeline InsertPipeline() override;
virtual PBaseShader InsertShader() override; virtual PBaseShader InsertShader() override;
virtual PBaseTexture InsertTexture() override; virtual PBaseTexture InsertTexture() override;
virtual void DeleteCommandBuffer(PBaseCommandBuffer p) override; virtual void DeleteCommandBuffer(PBaseCommandBuffer p) override;
virtual void DeleteGeometry(PBaseGeometry p) override; virtual void DeleteGeometry(PBaseGeometry p) override;
virtual void DeletePipeline(PBasePipeline p) override; virtual void DeletePipeline(PBasePipeline p) override;
virtual void DeleteShader(PBaseShader p) override; virtual void DeleteShader(PBaseShader p) override;
virtual void DeleteTexture(PBaseTexture p) override; virtual void DeleteTexture(PBaseTexture p) override;
virtual RPHandle CreateRenderPass(std::initializer_list<RP::Attachment> ilA, std::initializer_list<RP::Subpass> ilS, std::initializer_list<RP::Dependency> ilD) override; virtual RPHandle CreateRenderPass(std::initializer_list<RP::Attachment> ilA, std::initializer_list<RP::Subpass> ilS, std::initializer_list<RP::Dependency> ilD) override;
virtual FBHandle CreateFramebuffer(RPHandle renderPassHandle, std::initializer_list<TexturePtr> il, int w, int h, virtual FBHandle CreateFramebuffer(RPHandle renderPassHandle, std::initializer_list<TexturePtr> il, int w, int h,
int swapChainBufferIndex = -1, CubeMapFace cubeMapFace = CubeMapFace::none) override; int swapChainBufferIndex = -1, CubeMapFace cubeMapFace = CubeMapFace::none) override;
virtual void DeleteRenderPass(RPHandle handle) override; virtual void DeleteRenderPass(RPHandle handle) override;
virtual void DeleteFramebuffer(FBHandle handle) override; virtual void DeleteFramebuffer(FBHandle handle) override;
int GetNextRenderPassIndex() const; int GetNextRenderPassIndex() const;
int GetNextFramebufferIndex() const; int GetNextFramebufferIndex() const;
RP::RcD3DRenderPass GetRenderPass(RPHandle handle) const; RP::RcD3DRenderPass GetRenderPass(RPHandle handle) const;
RP::RcD3DFramebuffer GetFramebuffer(FBHandle handle) const; RP::RcD3DFramebuffer GetFramebuffer(FBHandle handle) const;
// </Resources> // </Resources>
RDynamicDescriptorHeap GetViewHeap() { return _dhViews; } RDynamicDescriptorHeap GetViewHeap() { return _dhViews; }
RDynamicDescriptorHeap GetSamplerHeap() { return _dhSamplers; } RDynamicDescriptorHeap GetSamplerHeap() { return _dhSamplers; }
void SetDescriptorHeaps(PBaseCommandBuffer p); void SetDescriptorHeaps(PBaseCommandBuffer p);
virtual void UpdateUtilization() override; virtual void UpdateUtilization() override;
}; };
VERUS_TYPEDEFS(RendererD3D12); VERUS_TYPEDEFS(RendererD3D12);
}
} }
#define VERUS_QREF_RENDERER_D3D12 CGI::PRendererD3D12 pRendererD3D12 = CGI::RendererD3D12::P() #define VERUS_QREF_RENDERER_D3D12 CGI::PRendererD3D12 pRendererD3D12 = CGI::RendererD3D12::P()

View File

@ -58,13 +58,13 @@ void ShaderD3D12::Init(CSZ source, CSZ sourceName, CSZ* branches)
ComPtr<ID3DBlob> pErrorMsgs; ComPtr<ID3DBlob> pErrorMsgs;
auto CheckErrorMsgs = [this](ComPtr<ID3DBlob>& pErrorMsgs) auto CheckErrorMsgs = [this](ComPtr<ID3DBlob>& pErrorMsgs)
{
if (pErrorMsgs)
{ {
OnError(static_cast<CSZ>(pErrorMsgs->GetBufferPointer())); if (pErrorMsgs)
pErrorMsgs.Reset(); {
} OnError(static_cast<CSZ>(pErrorMsgs->GetBufferPointer()));
}; pErrorMsgs.Reset();
}
};
while (*branches) while (*branches)
{ {
@ -197,12 +197,12 @@ void ShaderD3D12::Done()
_pRootSignature.Reset(); // Can be shared with another shader, don't check ref count. _pRootSignature.Reset(); // Can be shared with another shader, don't check ref count.
for (auto& x : _mapCompiled) for (auto& [key, value] : _mapCompiled)
{ {
VERUS_FOR(i, +Stage::count) VERUS_FOR(i, +Stage::count)
{ {
VERUS_COM_RELEASE_CHECK(x.second._pBlobs[i].Get()); VERUS_COM_RELEASE_CHECK(value._pBlobs[i].Get());
x.second._pBlobs[i].Reset(); value._pBlobs[i].Reset();
} }
} }
@ -693,19 +693,19 @@ void ShaderD3D12::UpdateDebugInfo(
StringStream ss; StringStream ss;
auto PrintShaderVisibility = [&ss](D3D12_SHADER_VISIBILITY shaderVisibility) auto PrintShaderVisibility = [&ss](D3D12_SHADER_VISIBILITY shaderVisibility)
{
switch (shaderVisibility)
{ {
case D3D12_SHADER_VISIBILITY_ALL: ss << "All"; break; switch (shaderVisibility)
case D3D12_SHADER_VISIBILITY_VERTEX: ss << "V"; break; {
case D3D12_SHADER_VISIBILITY_HULL: ss << "H"; break; case D3D12_SHADER_VISIBILITY_ALL: ss << "All"; break;
case D3D12_SHADER_VISIBILITY_DOMAIN: ss << "D"; break; case D3D12_SHADER_VISIBILITY_VERTEX: ss << "V"; break;
case D3D12_SHADER_VISIBILITY_GEOMETRY: ss << "G"; break; case D3D12_SHADER_VISIBILITY_HULL: ss << "H"; break;
case D3D12_SHADER_VISIBILITY_PIXEL: ss << "P"; break; case D3D12_SHADER_VISIBILITY_DOMAIN: ss << "D"; break;
case D3D12_SHADER_VISIBILITY_AMPLIFICATION: ss << "A"; break; case D3D12_SHADER_VISIBILITY_GEOMETRY: ss << "G"; break;
case D3D12_SHADER_VISIBILITY_MESH: ss << "M"; break; case D3D12_SHADER_VISIBILITY_PIXEL: ss << "P"; break;
} case D3D12_SHADER_VISIBILITY_AMPLIFICATION: ss << "A"; break;
}; case D3D12_SHADER_VISIBILITY_MESH: ss << "M"; break;
}
};
int totalSize = 0; int totalSize = 0;
int index = 0; int index = 0;

View File

@ -1,117 +1,114 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI struct ShaderInclude : public ID3DInclude
{ {
struct ShaderInclude : public ID3DInclude public:
virtual HRESULT STDMETHODCALLTYPE Open(
D3D_INCLUDE_TYPE IncludeType,
LPCSTR pFileName,
LPCVOID pParentData,
LPCVOID* ppData,
UINT* pBytes) override;
virtual HRESULT STDMETHODCALLTYPE Close(LPCVOID pData) override;
};
VERUS_TYPEDEFS(ShaderInclude);
class ShaderD3D12 : public BaseShader
{
public:
enum SET_MOD
{ {
public: SET_MOD_TO_VIEW_HEAP = 0x10000
virtual HRESULT STDMETHODCALLTYPE Open(
D3D_INCLUDE_TYPE IncludeType,
LPCSTR pFileName,
LPCVOID pParentData,
LPCVOID* ppData,
UINT* pBytes) override;
virtual HRESULT STDMETHODCALLTYPE Close(LPCVOID pData) override;
}; };
VERUS_TYPEDEFS(ShaderInclude);
class ShaderD3D12 : public BaseShader struct Compiled
{ {
public: ComPtr<ID3DBlob> _pBlobs[+Stage::count];
enum SET_MOD String _entry;
{ int _stageCount = 0;
SET_MOD_TO_VIEW_HEAP = 0x10000
};
struct Compiled
{
ComPtr<ID3DBlob> _pBlobs[+Stage::count];
String _entry;
int _stageCount = 0;
};
VERUS_TYPEDEFS(Compiled);
private:
typedef Map<String, Compiled> TMapCompiled;
struct DescriptorSetDesc
{
Vector<Sampler> _vSamplers;
ComPtr<ID3D12Resource> _pConstantBuffer;
D3D12MA::Allocation* _pMaAllocation = nullptr;
DescriptorHeap _dhDynamicOffsets;
BYTE* _pMappedData = nullptr;
const void* _pSrc = nullptr;
int _size = 0;
int _alignedSize = 0;
int _capacity = 1;
int _capacityInBytes = 0;
int _offset = 0;
int _peakLoad = 0;
int _index = 0;
ShaderStageFlags _stageFlags = ShaderStageFlags::vs_fs;
bool _staticSamplersOnly = true;
};
struct ComplexSet
{
Vector<TexturePtr> _vTextures;
DescriptorHeap _dhViews;
DescriptorHeap _dhSamplers;
HandlePair _hpBase;
};
VERUS_TYPEDEFS(ComplexSet);
TMapCompiled _mapCompiled;
Vector<DescriptorSetDesc> _vDescriptorSetDesc;
Vector<ComplexSet> _vComplexSets;
ComPtr<ID3D12RootSignature> _pRootSignature;
String _debugInfo;
UINT64 _currentFrame = UINT64_MAX;
bool _compute = false;
public:
ShaderD3D12();
virtual ~ShaderD3D12() override;
virtual void Init(CSZ source, CSZ sourceName, CSZ* branches) override;
virtual void Done() override;
virtual void CreateDescriptorSet(int setNumber, const void* pSrc, int size, int capacity, std::initializer_list<Sampler> il, ShaderStageFlags stageFlags) override;
virtual void CreatePipelineLayout() override;
virtual CSHandle BindDescriptorSetTextures(int setNumber, std::initializer_list<TexturePtr> il, const int* pMipLevels, const int* pArrayLayers) override;
virtual void FreeDescriptorSet(CSHandle& complexSetHandle) override;
virtual void BeginBindDescriptors() override;
virtual void EndBindDescriptors() override;
//
// D3D12
//
RcCompiled GetCompiled(CSZ branch) const { return _mapCompiled.at(branch); }
ID3D12RootSignature* GetD3DRootSignature() const { return _pRootSignature.Get(); }
UINT ToRootParameterIndex(int setNumber) const;
bool TryRootConstants(int setNumber, RBaseCommandBuffer cb) const;
CD3DX12_GPU_DESCRIPTOR_HANDLE UpdateConstantBuffer(int setNumber, int complexSetHandle);
CD3DX12_GPU_DESCRIPTOR_HANDLE UpdateSamplers(int setNumber, int complexSetHandle) const;
int GetDescriptorSetCount() const { return static_cast<int>(_vDescriptorSetDesc.size()); }
bool IsCompute() const { return _compute; }
void OnError(CSZ s) const;
void UpdateDebugInfo(
const Vector<CD3DX12_ROOT_PARAMETER1>& vRootParams,
const Vector<D3D12_STATIC_SAMPLER_DESC>& vStaticSamplers,
D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags);
void UpdateUtilization() const;
}; };
VERUS_TYPEDEFS(ShaderD3D12); VERUS_TYPEDEFS(Compiled);
}
private:
typedef Map<String, Compiled> TMapCompiled;
struct DescriptorSetDesc
{
Vector<Sampler> _vSamplers;
ComPtr<ID3D12Resource> _pConstantBuffer;
D3D12MA::Allocation* _pMaAllocation = nullptr;
DescriptorHeap _dhDynamicOffsets;
BYTE* _pMappedData = nullptr;
const void* _pSrc = nullptr;
int _size = 0;
int _alignedSize = 0;
int _capacity = 1;
int _capacityInBytes = 0;
int _offset = 0;
int _peakLoad = 0;
int _index = 0;
ShaderStageFlags _stageFlags = ShaderStageFlags::vs_fs;
bool _staticSamplersOnly = true;
};
struct ComplexSet
{
Vector<TexturePtr> _vTextures;
DescriptorHeap _dhViews;
DescriptorHeap _dhSamplers;
HandlePair _hpBase;
};
VERUS_TYPEDEFS(ComplexSet);
TMapCompiled _mapCompiled;
Vector<DescriptorSetDesc> _vDescriptorSetDesc;
Vector<ComplexSet> _vComplexSets;
ComPtr<ID3D12RootSignature> _pRootSignature;
String _debugInfo;
UINT64 _currentFrame = UINT64_MAX;
bool _compute = false;
public:
ShaderD3D12();
virtual ~ShaderD3D12() override;
virtual void Init(CSZ source, CSZ sourceName, CSZ* branches) override;
virtual void Done() override;
virtual void CreateDescriptorSet(int setNumber, const void* pSrc, int size, int capacity, std::initializer_list<Sampler> il, ShaderStageFlags stageFlags) override;
virtual void CreatePipelineLayout() override;
virtual CSHandle BindDescriptorSetTextures(int setNumber, std::initializer_list<TexturePtr> il, const int* pMipLevels, const int* pArrayLayers) override;
virtual void FreeDescriptorSet(CSHandle& complexSetHandle) override;
virtual void BeginBindDescriptors() override;
virtual void EndBindDescriptors() override;
//
// D3D12
//
RcCompiled GetCompiled(CSZ branch) const { return _mapCompiled.at(branch); }
ID3D12RootSignature* GetD3DRootSignature() const { return _pRootSignature.Get(); }
UINT ToRootParameterIndex(int setNumber) const;
bool TryRootConstants(int setNumber, RBaseCommandBuffer cb) const;
CD3DX12_GPU_DESCRIPTOR_HANDLE UpdateConstantBuffer(int setNumber, int complexSetHandle);
CD3DX12_GPU_DESCRIPTOR_HANDLE UpdateSamplers(int setNumber, int complexSetHandle) const;
int GetDescriptorSetCount() const { return static_cast<int>(_vDescriptorSetDesc.size()); }
bool IsCompute() const { return _compute; }
void OnError(CSZ s) const;
void UpdateDebugInfo(
const Vector<CD3DX12_ROOT_PARAMETER1>& vRootParams,
const Vector<D3D12_STATIC_SAMPLER_DESC>& vStaticSamplers,
D3D12_ROOT_SIGNATURE_FLAGS rootSignatureFlags);
void UpdateUtilization() const;
};
VERUS_TYPEDEFS(ShaderD3D12);
} }

View File

@ -1,62 +1,59 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class TextureD3D12 : public BaseTexture
{ {
class TextureD3D12 : public BaseTexture struct ResourceEx
{ {
struct ResourceEx ComPtr<ID3D12Resource> _pResource;
{ D3D12MA::Allocation* _pMaAllocation = nullptr;
ComPtr<ID3D12Resource> _pResource;
D3D12MA::Allocation* _pMaAllocation = nullptr;
};
ResourceEx _resource;
ResourceEx _uaResource;
Vector<ResourceEx> _vStagingBuffers;
Vector<ResourceEx> _vReadbackBuffers;
Vector<CSHandle> _vCshGenerateMips;
DescriptorHeap _dhSRV;
DescriptorHeap _dhUAV;
DescriptorHeap _dhRTV;
DescriptorHeap _dhDSV;
DescriptorHeap _dhSampler;
public:
TextureD3D12();
virtual ~TextureD3D12() override;
virtual void Init(RcTextureDesc desc) override;
virtual void Done() override;
virtual void UpdateSubresource(const void* p, int mipLevel, int arrayLayer, PBaseCommandBuffer pCB) override;
virtual bool ReadbackSubresource(void* p, bool recordCopyCommand, PBaseCommandBuffer pCB) override;
virtual void GenerateMips(PBaseCommandBuffer pCB) override;
void GenerateCubeMapMips(PBaseCommandBuffer pCB);
virtual Continue Scheduled_Update() override;
//
// D3D12
//
void ClearCshGenerateMips();
void CreateSampler();
ID3D12Resource* GetD3DResource() const { return _resource._pResource.Get(); }
RcDescriptorHeap GetDescriptorHeapSRV() const { return _dhSRV; }
RcDescriptorHeap GetDescriptorHeapUAV() const { return _dhUAV; }
RcDescriptorHeap GetDescriptorHeapRTV() const { return _dhRTV; }
RcDescriptorHeap GetDescriptorHeapDSV() const { return _dhDSV; }
RcDescriptorHeap GetDescriptorHeapSampler() const { return _dhSampler; };
static DXGI_FORMAT RemoveSRGB(DXGI_FORMAT format);
}; };
VERUS_TYPEDEFS(TextureD3D12);
} ResourceEx _resource;
ResourceEx _uaResource;
Vector<ResourceEx> _vStagingBuffers;
Vector<ResourceEx> _vReadbackBuffers;
Vector<CSHandle> _vCshGenerateMips;
DescriptorHeap _dhSRV;
DescriptorHeap _dhUAV;
DescriptorHeap _dhRTV;
DescriptorHeap _dhDSV;
DescriptorHeap _dhSampler;
public:
TextureD3D12();
virtual ~TextureD3D12() override;
virtual void Init(RcTextureDesc desc) override;
virtual void Done() override;
virtual void UpdateSubresource(const void* p, int mipLevel, int arrayLayer, PBaseCommandBuffer pCB) override;
virtual bool ReadbackSubresource(void* p, bool recordCopyCommand, PBaseCommandBuffer pCB) override;
virtual void GenerateMips(PBaseCommandBuffer pCB) override;
void GenerateCubeMapMips(PBaseCommandBuffer pCB);
virtual Continue Scheduled_Update() override;
//
// D3D12
//
void ClearCshGenerateMips();
void CreateSampler();
ID3D12Resource* GetD3DResource() const { return _resource._pResource.Get(); }
RcDescriptorHeap GetDescriptorHeapSRV() const { return _dhSRV; }
RcDescriptorHeap GetDescriptorHeapUAV() const { return _dhUAV; }
RcDescriptorHeap GetDescriptorHeapRTV() const { return _dhRTV; }
RcDescriptorHeap GetDescriptorHeapDSV() const { return _dhDSV; }
RcDescriptorHeap GetDescriptorHeapSampler() const { return _dhSampler; };
static DXGI_FORMAT RemoveSRGB(DXGI_FORMAT format);
};
VERUS_TYPEDEFS(TextureD3D12);
} }

View File

@ -11,23 +11,23 @@
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion> <VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<ProjectGuid>{C9195A1C-9224-4B40-BBBC-AA90EF3BE3E0}</ProjectGuid> <ProjectGuid>{C9195A1C-9224-4B40-BBBC-AA90EF3BE3E0}</ProjectGuid>
<RootNamespace>RendererVulkan</RootNamespace> <RootNamespace>RendererVulkan</RootNamespace>
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -45,12 +45,6 @@
<Import Project="..\Verus\Verus.props" /> <Import Project="..\Verus\Verus.props" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
@ -61,6 +55,7 @@
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<FloatingPointModel>Fast</FloatingPointModel> <FloatingPointModel>Fast</FloatingPointModel>
<AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -80,6 +75,7 @@
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<FloatingPointModel>Fast</FloatingPointModel> <FloatingPointModel>Fast</FloatingPointModel>
<AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>

View File

@ -1,58 +1,55 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class CommandBufferVulkan : public BaseCommandBuffer
{ {
class CommandBufferVulkan : public BaseCommandBuffer VkCommandBuffer _commandBuffers[BaseRenderer::s_ringBufferSize] = {};
{ bool _oneTimeSubmit = false;
VkCommandBuffer _commandBuffers[BaseRenderer::s_ringBufferSize] = {};
bool _oneTimeSubmit = false;
public: public:
CommandBufferVulkan(); CommandBufferVulkan();
virtual ~CommandBufferVulkan() override; virtual ~CommandBufferVulkan() override;
virtual void Init() override; virtual void Init() override;
virtual void Done() override; virtual void Done() override;
virtual void InitOneTimeSubmit() override; virtual void InitOneTimeSubmit() override;
virtual void DoneOneTimeSubmit() override; virtual void DoneOneTimeSubmit() override;
virtual void Begin() override; virtual void Begin() override;
virtual void End() override; virtual void End() override;
virtual void PipelineImageMemoryBarrier(TexturePtr tex, ImageLayout oldLayout, ImageLayout newLayout, Range mipLevels, Range arrayLayers) override; virtual void PipelineImageMemoryBarrier(TexturePtr tex, ImageLayout oldLayout, ImageLayout newLayout, Range mipLevels, Range arrayLayers) override;
virtual void BeginRenderPass(RPHandle renderPassHandle, FBHandle framebufferHandle, virtual void BeginRenderPass(RPHandle renderPassHandle, FBHandle framebufferHandle,
std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf) override; std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf) override;
virtual void NextSubpass() override; virtual void NextSubpass() override;
virtual void EndRenderPass() override; virtual void EndRenderPass() override;
virtual void BindPipeline(PipelinePtr pipe) override; virtual void BindPipeline(PipelinePtr pipe) override;
virtual void SetViewport(std::initializer_list<Vector4> il, float minDepth, float maxDepth) override; virtual void SetViewport(std::initializer_list<Vector4> il, float minDepth, float maxDepth) override;
virtual void SetScissor(std::initializer_list<Vector4> il) override; virtual void SetScissor(std::initializer_list<Vector4> il) override;
virtual void SetBlendConstants(const float* p) override; virtual void SetBlendConstants(const float* p) override;
virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter) override; virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter) override;
virtual void BindIndexBuffer(GeometryPtr geo) override; virtual void BindIndexBuffer(GeometryPtr geo) override;
virtual bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle) override; virtual bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle) override;
virtual bool BindDescriptors(ShaderPtr shader, int setNumber, GeometryPtr geo, int sbIndex) override; virtual bool BindDescriptors(ShaderPtr shader, int setNumber, GeometryPtr geo, int sbIndex) override;
virtual void PushConstants(ShaderPtr shader, int offset, int size, const void* p, ShaderStageFlags stageFlags) override; virtual void PushConstants(ShaderPtr shader, int offset, int size, const void* p, ShaderStageFlags stageFlags) override;
virtual void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance) override; virtual void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance) override;
virtual void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int vertexOffset, int firstInstance) override; virtual void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int vertexOffset, int firstInstance) override;
virtual void Dispatch(int groupCountX, int groupCountY, int groupCountZ) override; virtual void Dispatch(int groupCountX, int groupCountY, int groupCountZ) override;
virtual void TraceRays(int width, int height, int depth) override; virtual void TraceRays(int width, int height, int depth) override;
// //
// Vulkan // Vulkan
// //
VkCommandBuffer GetVkCommandBuffer() const; VkCommandBuffer GetVkCommandBuffer() const;
}; };
VERUS_TYPEDEFS(CommandBufferVulkan); VERUS_TYPEDEFS(CommandBufferVulkan);
}
} }

View File

@ -98,18 +98,18 @@ bool Descriptors::CreatePool(bool freeDescriptorSet)
vkdpci.flags = freeDescriptorSet ? VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT : 0; vkdpci.flags = freeDescriptorSet ? VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT : 0;
Vector<VkDescriptorPoolSize> vDescriptorPoolSizes; Vector<VkDescriptorPoolSize> vDescriptorPoolSizes;
vDescriptorPoolSizes.reserve(_mapTypeCount.size()); vDescriptorPoolSizes.reserve(_mapTypeCount.size());
for (const auto& kv : _mapTypeCount) for (const auto& [key, value] : _mapTypeCount)
{ {
VkDescriptorPoolSize vkdps; VkDescriptorPoolSize vkdps;
vkdps.type = kv.first; vkdps.type = key;
vkdps.descriptorCount = kv.second; vkdps.descriptorCount = value;
vDescriptorPoolSizes.push_back(vkdps); vDescriptorPoolSizes.push_back(vkdps);
switch (kv.first) switch (key)
{ {
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
vkdpci.maxSets += kv.second; vkdpci.maxSets += value;
} }
} }
vkdpci.poolSizeCount = Utils::Cast32(vDescriptorPoolSizes.size()); vkdpci.poolSizeCount = Utils::Cast32(vDescriptorPoolSizes.size());

View File

@ -1,67 +1,64 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class Descriptors : public Object
{ {
class Descriptors : public Object typedef Map<VkDescriptorType, int> TMapTypeCount;
struct SetLayoutDesc
{ {
typedef Map<VkDescriptorType, int> TMapTypeCount; Vector<VkDescriptorSetLayoutBinding> _vSetLayoutBindings;
int _capacity = 0;
struct SetLayoutDesc
{
Vector<VkDescriptorSetLayoutBinding> _vSetLayoutBindings;
int _capacity = 0;
};
TMapTypeCount _mapTypeCount;
Vector<SetLayoutDesc> _vSetLayoutDesc;
Vector<VkDescriptorSetLayout> _vSetLayouts;
Vector<VkDescriptorBufferInfo> _vBufferInfo;
Vector<VkDescriptorImageInfo> _vImageInfo;
Vector<VkWriteDescriptorSet> _vWriteSet;
VkDescriptorPool _pool = VK_NULL_HANDLE;
VkDescriptorSet _activeSet = VK_NULL_HANDLE;
int _activeSetNumber = 0;
int _complexCapacity = 0;
public:
Descriptors();
~Descriptors();
void Init();
void Done();
void BeginCreateSetLayout(int setNumber, int capacity);
void SetLayoutBinding(int binding, VkDescriptorType type, int count, VkShaderStageFlags stageFlags, const VkSampler* pImmutableSampler = nullptr);
void EndCreateSetLayout();
bool CreatePool(bool freeDescriptorSet);
bool BeginAllocateSet(int setNumber);
void BufferInfo(int binding, VkBuffer buffer, VkDeviceSize range, VkDeviceSize offset = 0);
void ImageInfo(int binding, VkSampler sampler, VkImageView imageView, VkImageLayout imageLayout);
VkDescriptorSet EndAllocateSet();
void IncreaseComplexCapacityBy(int capacity) { _complexCapacity += capacity; }
int GetComplexCapacity() const { return _complexCapacity; }
int GetSetLayoutCount() const;
const VkDescriptorSetLayout* GetSetLayouts() const;
VkDescriptorPool GetPool() const { return _pool; }
template<typename T>
void ForEach(int setNumber, const T& fn)
{
for (auto& x : _vSetLayoutDesc[setNumber]._vSetLayoutBindings)
{
if (Continue::no == fn(x))
break;
}
}
}; };
VERUS_TYPEDEFS(Descriptors);
} TMapTypeCount _mapTypeCount;
Vector<SetLayoutDesc> _vSetLayoutDesc;
Vector<VkDescriptorSetLayout> _vSetLayouts;
Vector<VkDescriptorBufferInfo> _vBufferInfo;
Vector<VkDescriptorImageInfo> _vImageInfo;
Vector<VkWriteDescriptorSet> _vWriteSet;
VkDescriptorPool _pool = VK_NULL_HANDLE;
VkDescriptorSet _activeSet = VK_NULL_HANDLE;
int _activeSetNumber = 0;
int _complexCapacity = 0;
public:
Descriptors();
~Descriptors();
void Init();
void Done();
void BeginCreateSetLayout(int setNumber, int capacity);
void SetLayoutBinding(int binding, VkDescriptorType type, int count, VkShaderStageFlags stageFlags, const VkSampler* pImmutableSampler = nullptr);
void EndCreateSetLayout();
bool CreatePool(bool freeDescriptorSet);
bool BeginAllocateSet(int setNumber);
void BufferInfo(int binding, VkBuffer buffer, VkDeviceSize range, VkDeviceSize offset = 0);
void ImageInfo(int binding, VkSampler sampler, VkImageView imageView, VkImageLayout imageLayout);
VkDescriptorSet EndAllocateSet();
void IncreaseComplexCapacityBy(int capacity) { _complexCapacity += capacity; }
int GetComplexCapacity() const { return _complexCapacity; }
int GetSetLayoutCount() const;
const VkDescriptorSetLayout* GetSetLayouts() const;
VkDescriptorPool GetPool() const { return _pool; }
template<typename T>
void ForEach(int setNumber, const T& fn)
{
for (auto& x : _vSetLayoutDesc[setNumber]._vSetLayoutBindings)
{
if (Continue::no == fn(x))
break;
}
}
};
VERUS_TYPEDEFS(Descriptors);
} }

View File

@ -1,65 +1,62 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class RendererVulkan;
class ExtRealityVulkan : public BaseExtReality
{ {
class RendererVulkan; struct SwapChainEx
class ExtRealityVulkan : public BaseExtReality
{ {
struct SwapChainEx XrSwapchain _handle = XR_NULL_HANDLE;
{ int32_t _width = 0;
XrSwapchain _handle = XR_NULL_HANDLE; int32_t _height = 0;
int32_t _width = 0; Vector<XrSwapchainImageVulkan2KHR> _vImages;
int32_t _height = 0; Vector<VkImageView> _vImageViews;
Vector<XrSwapchainImageVulkan2KHR> _vImages;
Vector<VkImageView> _vImageViews;
};
Vector<SwapChainEx> _vSwapChains;
public:
ExtRealityVulkan();
virtual ~ExtRealityVulkan() override;
virtual void Init() override;
virtual void Done() override;
VkResult CreateVulkanInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance);
VkPhysicalDevice GetVulkanGraphicsDevice(VkInstance vulkanInstance);
VkResult CreateVulkanDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice);
void InitByRenderer(RendererVulkan* pRenderer);
private:
void GetSystem();
void CreateSwapChains(RendererVulkan* pRenderer, int64_t format);
VkImageView CreateImageView(RendererVulkan* pRenderer, int64_t format, XrSwapchainImageVulkan2KHR& image);
virtual XrSwapchain GetSwapChain(int viewIndex) override;
virtual void GetSwapChainSize(int viewIndex, int32_t& w, int32_t& h) override;
public:
VkImageView GetVkImageView(int viewIndex, int imageIndex) const;
virtual void CreateActions() override;
virtual void PollEvents() override;
virtual void SyncActions(UINT32 activeActionSetsMask) override;
virtual bool GetActionStateBoolean(int actionIndex, bool& currentState, bool* pChangedState, int subaction) override;
virtual bool GetActionStateFloat(int actionIndex, float& currentState, bool* pChangedState, int subaction) override;
virtual bool GetActionStatePose(int actionIndex, bool& currentState, Math::RPose pose, int subaction) override;
virtual void BeginFrame() override;
virtual int LocateViews() override;
virtual void BeginView(int viewIndex, RViewDesc viewDesc) override;
virtual void AcquireSwapChainImage() override;
virtual void EndView(int viewIndex) override;
virtual void EndFrame() override;
virtual void BeginAreaUpdate() override;
virtual void EndAreaUpdate(PcVector4 pUserOffset) override;
}; };
VERUS_TYPEDEFS(ExtRealityVulkan);
} Vector<SwapChainEx> _vSwapChains;
public:
ExtRealityVulkan();
virtual ~ExtRealityVulkan() override;
virtual void Init() override;
virtual void Done() override;
VkResult CreateVulkanInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance);
VkPhysicalDevice GetVulkanGraphicsDevice(VkInstance vulkanInstance);
VkResult CreateVulkanDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice);
void InitByRenderer(RendererVulkan* pRenderer);
private:
void GetSystem();
void CreateSwapChains(RendererVulkan* pRenderer, int64_t format);
VkImageView CreateImageView(RendererVulkan* pRenderer, int64_t format, XrSwapchainImageVulkan2KHR& image);
virtual XrSwapchain GetSwapChain(int viewIndex) override;
virtual void GetSwapChainSize(int viewIndex, int32_t& w, int32_t& h) override;
public:
VkImageView GetVkImageView(int viewIndex, int imageIndex) const;
virtual void CreateActions() override;
virtual void PollEvents() override;
virtual void SyncActions(UINT32 activeActionSetsMask) override;
virtual bool GetActionStateBoolean(int actionIndex, bool& currentState, bool* pChangedState, int subaction) override;
virtual bool GetActionStateFloat(int actionIndex, float& currentState, bool* pChangedState, int subaction) override;
virtual bool GetActionStatePose(int actionIndex, bool& currentState, Math::RPose pose, int subaction) override;
virtual void BeginFrame() override;
virtual int LocateViews() override;
virtual void BeginView(int viewIndex, RViewDesc viewDesc) override;
virtual void AcquireSwapChainImage() override;
virtual void EndView(int viewIndex) override;
virtual void EndFrame() override;
virtual void BeginAreaUpdate() override;
virtual void EndAreaUpdate(PcVector4 pUserOffset) override;
};
VERUS_TYPEDEFS(ExtRealityVulkan);
} }

View File

@ -1,76 +1,73 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class GeometryVulkan : public BaseGeometry
{ {
class GeometryVulkan : public BaseGeometry static const int s_maxStorageBuffers = 8;
struct BufferEx
{ {
static const int s_maxStorageBuffers = 8; VmaAllocation _vmaAllocation = VK_NULL_HANDLE;
VkBuffer _buffer = VK_NULL_HANDLE;
struct BufferEx VkDeviceSize _bufferSize = 0;
{ INT64 _utilization = -1;
VmaAllocation _vmaAllocation = VK_NULL_HANDLE;
VkBuffer _buffer = VK_NULL_HANDLE;
VkDeviceSize _bufferSize = 0;
INT64 _utilization = -1;
};
struct StorageBufferEx : BufferEx
{
VkDescriptorSet _descriptorSet = VK_NULL_HANDLE;
int _structSize = 0;
};
Vector<BufferEx> _vVertexBuffers;
BufferEx _indexBuffer;
Vector<BufferEx> _vStagingVertexBuffers;
BufferEx _stagingIndexBuffer;
Vector<StorageBufferEx> _vStorageBuffers;
Vector<VkVertexInputBindingDescription> _vVertexInputBindingDesc;
Vector<VkVertexInputAttributeDescription> _vVertexInputAttributeDesc;
Vector<int> _vStrides;
Descriptors _descriptors;
public:
GeometryVulkan();
virtual ~GeometryVulkan() override;
virtual void Init(RcGeometryDesc desc) override;
virtual void Done() override;
virtual void CreateVertexBuffer(int count, int binding) override;
virtual void UpdateVertexBuffer(const void* p, int binding, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual void CreateIndexBuffer(int count) override;
virtual void UpdateIndexBuffer(const void* p, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual void CreateStorageBuffer(int count, int structSize, int sbIndex, ShaderStageFlags stageFlags) override;
virtual void UpdateStorageBuffer(const void* p, int sbIndex, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual int GetStorageBufferStructSize(int sbIndex) const override;
virtual Continue Scheduled_Update() override;
//
// Vulkan
//
VkPipelineVertexInputStateCreateInfo GetVkPipelineVertexInputStateCreateInfo(UINT32 bindingsFilter,
Vector<VkVertexInputBindingDescription>& vVertexInputBindingDesc, Vector<VkVertexInputAttributeDescription>& vVertexInputAttributeDesc) const;
int GetVertexBufferCount() const { return Utils::Cast32(_vVertexBuffers.size()); }
VkBuffer GetVkVertexBuffer(int binding) const { return _vVertexBuffers[binding]._buffer; }
VkDeviceSize GetVkVertexBufferOffset(int binding) const;
VkBuffer GetVkIndexBuffer() const { return _indexBuffer._buffer; }
VkDeviceSize GetVkIndexBufferOffset() const;
VkDescriptorSet GetVkDescriptorSet(int sbIndex) const { return _vStorageBuffers[sbIndex]._descriptorSet; }
VkDeviceSize GetVkStorageBufferOffset(int sbIndex) const;
void UpdateUtilization() const;;
}; };
VERUS_TYPEDEFS(GeometryVulkan);
} struct StorageBufferEx : BufferEx
{
VkDescriptorSet _descriptorSet = VK_NULL_HANDLE;
int _structSize = 0;
};
Vector<BufferEx> _vVertexBuffers;
BufferEx _indexBuffer;
Vector<BufferEx> _vStagingVertexBuffers;
BufferEx _stagingIndexBuffer;
Vector<StorageBufferEx> _vStorageBuffers;
Vector<VkVertexInputBindingDescription> _vVertexInputBindingDesc;
Vector<VkVertexInputAttributeDescription> _vVertexInputAttributeDesc;
Vector<int> _vStrides;
Descriptors _descriptors;
public:
GeometryVulkan();
virtual ~GeometryVulkan() override;
virtual void Init(RcGeometryDesc desc) override;
virtual void Done() override;
virtual void CreateVertexBuffer(int count, int binding) override;
virtual void UpdateVertexBuffer(const void* p, int binding, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual void CreateIndexBuffer(int count) override;
virtual void UpdateIndexBuffer(const void* p, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual void CreateStorageBuffer(int count, int structSize, int sbIndex, ShaderStageFlags stageFlags) override;
virtual void UpdateStorageBuffer(const void* p, int sbIndex, PBaseCommandBuffer pCB, INT64 size, INT64 offset) override;
virtual int GetStorageBufferStructSize(int sbIndex) const override;
virtual Continue Scheduled_Update() override;
//
// Vulkan
//
VkPipelineVertexInputStateCreateInfo GetVkPipelineVertexInputStateCreateInfo(UINT32 bindingsFilter,
Vector<VkVertexInputBindingDescription>& vVertexInputBindingDesc, Vector<VkVertexInputAttributeDescription>& vVertexInputAttributeDesc) const;
int GetVertexBufferCount() const { return Utils::Cast32(_vVertexBuffers.size()); }
VkBuffer GetVkVertexBuffer(int binding) const { return _vVertexBuffers[binding]._buffer; }
VkDeviceSize GetVkVertexBufferOffset(int binding) const;
VkBuffer GetVkIndexBuffer() const { return _indexBuffer._buffer; }
VkDeviceSize GetVkIndexBufferOffset() const;
VkDescriptorSet GetVkDescriptorSet(int sbIndex) const { return _vStorageBuffers[sbIndex]._descriptorSet; }
VkDeviceSize GetVkStorageBufferOffset(int sbIndex) const;
void UpdateUtilization() const;;
};
VERUS_TYPEDEFS(GeometryVulkan);
} }

View File

@ -1,29 +1,26 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI VkCompareOp ToNativeCompareOp(CompareOp compareOp);
{
VkCompareOp ToNativeCompareOp(CompareOp compareOp);
uint32_t ToNativeCubeMapFace(CubeMapFace face); uint32_t ToNativeCubeMapFace(CubeMapFace face);
VkPolygonMode ToNativePolygonMode(PolygonMode polygonMode); VkPolygonMode ToNativePolygonMode(PolygonMode polygonMode);
VkCullModeFlagBits ToNativeCullMode(CullMode cullMode); VkCullModeFlagBits ToNativeCullMode(CullMode cullMode);
VkPrimitiveTopology ToNativePrimitiveTopology(PrimitiveTopology primitiveTopology); VkPrimitiveTopology ToNativePrimitiveTopology(PrimitiveTopology primitiveTopology);
VkImageLayout ToNativeImageLayout(ImageLayout layout); VkImageLayout ToNativeImageLayout(ImageLayout layout);
VkShaderStageFlags ToNativeStageFlags(ShaderStageFlags stageFlags); VkShaderStageFlags ToNativeStageFlags(ShaderStageFlags stageFlags);
VkSampleCountFlagBits ToNativeSampleCount(int sampleCount); VkSampleCountFlagBits ToNativeSampleCount(int sampleCount);
VkFormat ToNativeFormat(Format format); VkFormat ToNativeFormat(Format format);
int ToNativeLocation(ViaUsage usage, int usageIndex); int ToNativeLocation(ViaUsage usage, int usageIndex);
VkFormat ToNativeFormat(ViaUsage usage, ViaType type, int components); VkFormat ToNativeFormat(ViaUsage usage, ViaType type, int components);
}
} }

View File

@ -1,31 +1,28 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class PipelineVulkan : public BasePipeline
{ {
class PipelineVulkan : public BasePipeline VkPipeline _pipeline = VK_NULL_HANDLE;
{ bool _compute = false;
VkPipeline _pipeline = VK_NULL_HANDLE;
bool _compute = false;
public: public:
PipelineVulkan(); PipelineVulkan();
virtual ~PipelineVulkan() override; virtual ~PipelineVulkan() override;
virtual void Init(RcPipelineDesc desc) override; virtual void Init(RcPipelineDesc desc) override;
virtual void Done() override; virtual void Done() override;
// //
// Vulkan // Vulkan
// //
VERUS_P(void InitCompute(RcPipelineDesc desc)); VERUS_P(void InitCompute(RcPipelineDesc desc));
bool IsCompute() const { return _compute; } bool IsCompute() const { return _compute; }
VkPipeline GetVkPipeline() const { return _pipeline; } VkPipeline GetVkPipeline() const { return _pipeline; }
void FillColorBlendAttachmentStates(RcPipelineDesc desc, int attachmentCount, VkPipelineColorBlendAttachmentState vkpcbas[]); void FillColorBlendAttachmentStates(RcPipelineDesc desc, int attachmentCount, VkPipelineColorBlendAttachmentState vkpcbas[]);
}; };
VERUS_TYPEDEFS(PipelineVulkan); VERUS_TYPEDEFS(PipelineVulkan);
}
} }

View File

@ -1,217 +1,214 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI enum class HostAccess : int
{ {
enum class HostAccess : int forbidden,
sequentialWrite,
random
};
struct BaseShaderInclude
{
virtual void Open(CSZ filename, void** ppData, UINT32* pBytes) = 0;
virtual void Close(void* pData) = 0;
};
typedef Store<CommandBufferVulkan> TStoreCommandBuffers;
typedef Store<GeometryVulkan> TStoreGeometry;
typedef Store<PipelineVulkan> TStorePipelines;
typedef Store<ShaderVulkan> TStoreShaders;
typedef Store<TextureVulkan> TStoreTextures;
class RendererVulkan : public Singleton<RendererVulkan>, public BaseRenderer,
private TStoreCommandBuffers, private TStoreGeometry, private TStorePipelines, private TStoreShaders, private TStoreTextures
{
public:
struct Framebuffer
{ {
forbidden, VkFramebuffer _framebuffer = VK_NULL_HANDLE;
sequentialWrite, int _width = 0;
random int _height = 0;
};
VERUS_TYPEDEFS(Framebuffer);
private:
struct QueueFamilyIndices
{
int _graphicsFamilyIndex = -1;
int _presentFamilyIndex = -1;
bool IsComplete() const
{
return _graphicsFamilyIndex >= 0 && _presentFamilyIndex >= 0;
}
bool IsSameQueue() const
{
return _graphicsFamilyIndex == _presentFamilyIndex;
}
}; };
struct BaseShaderInclude struct SwapChainInfo
{ {
virtual void Open(CSZ filename, void** ppData, UINT32* pBytes) = 0; VkSurfaceCapabilitiesKHR _surfaceCapabilities = {};
virtual void Close(void* pData) = 0; Vector<VkSurfaceFormatKHR> _vSurfaceFormats;
Vector<VkPresentModeKHR> _vSurfacePresentModes;
}; };
typedef Store<CommandBufferVulkan> TStoreCommandBuffers; static const uint32_t s_apiVersion = VK_API_VERSION_1_1;
typedef Store<GeometryVulkan> TStoreGeometry;
typedef Store<PipelineVulkan> TStorePipelines;
typedef Store<ShaderVulkan> TStoreShaders;
typedef Store<TextureVulkan> TStoreTextures;
class RendererVulkan : public Singleton<RendererVulkan>, public BaseRenderer,
private TStoreCommandBuffers, private TStoreGeometry, private TStorePipelines, private TStoreShaders, private TStoreTextures
{
public:
struct Framebuffer
{
VkFramebuffer _framebuffer = VK_NULL_HANDLE;
int _width = 0;
int _height = 0;
};
VERUS_TYPEDEFS(Framebuffer);
private: static CSZ s_requiredValidationLayers[];
struct QueueFamilyIndices static CSZ s_requiredDeviceExtensions[];
{
int _graphicsFamilyIndex = -1;
int _presentFamilyIndex = -1;
bool IsComplete() const ExtRealityVulkan _extReality;
{ VkInstance _instance = VK_NULL_HANDLE;
return _graphicsFamilyIndex >= 0 && _presentFamilyIndex >= 0; VkDebugUtilsMessengerEXT _debugUtilsMessenger = VK_NULL_HANDLE;
} VkSurfaceKHR _surface = VK_NULL_HANDLE;
VkPhysicalDevice _physicalDevice = VK_NULL_HANDLE;
VkDevice _device = VK_NULL_HANDLE;
VkQueue _graphicsQueue = VK_NULL_HANDLE;
VkQueue _presentQueue = VK_NULL_HANDLE;
VmaAllocator _vmaAllocator = VK_NULL_HANDLE;
VkSwapchainKHR _swapChain = VK_NULL_HANDLE;
Vector<VkImage> _vSwapChainImages;
Vector<VkImageView> _vSwapChainImageViews;
VkCommandPool _commandPools[s_ringBufferSize] = {};
VkSemaphore _acquireNextImageSemaphores[s_ringBufferSize] = {};
VkSemaphore _queueSubmitSemaphores[s_ringBufferSize] = {};
VkSemaphore _acquireNextImageSemaphore = VK_NULL_HANDLE;
VkSemaphore _queueSubmitSemaphore = VK_NULL_HANDLE;
VkFence _queueSubmitFences[s_ringBufferSize] = {};
QueueFamilyIndices _queueFamilyIndices;
VkDescriptorPool _descriptorPoolImGui = VK_NULL_HANDLE;
Vector<VkSampler> _vSamplers;
Vector<VkRenderPass> _vRenderPasses;
Vector<Framebuffer> _vFramebuffers;
bool _advancedLineRasterization = false;
bool IsSameQueue() const public:
{ RendererVulkan();
return _graphicsFamilyIndex == _presentFamilyIndex; ~RendererVulkan();
}
};
struct SwapChainInfo virtual void ReleaseMe() override;
{
VkSurfaceCapabilitiesKHR _surfaceCapabilities = {};
Vector<VkSurfaceFormatKHR> _vSurfaceFormats;
Vector<VkPresentModeKHR> _vSurfacePresentModes;
};
static const uint32_t s_apiVersion = VK_API_VERSION_1_1; void Init();
void Done();
static CSZ s_requiredValidationLayers[]; static void VulkanCompilerInit();
static CSZ s_requiredDeviceExtensions[]; static void VulkanCompilerDone();
static bool VulkanCompile(CSZ source, CSZ sourceName, CSZ* defines, BaseShaderInclude* pInclude,
CSZ entryPoint, CSZ target, UINT32 flags, UINT32** ppCode, UINT32* pSize, CSZ* ppErrorMsgs);
ExtRealityVulkan _extReality; private:
VkInstance _instance = VK_NULL_HANDLE; static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsMessengerCallback(
VkDebugUtilsMessengerEXT _debugUtilsMessenger = VK_NULL_HANDLE; VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverityFlagBits,
VkSurfaceKHR _surface = VK_NULL_HANDLE; VkDebugUtilsMessageTypeFlagsEXT messageTypeFlags,
VkPhysicalDevice _physicalDevice = VK_NULL_HANDLE; const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
VkDevice _device = VK_NULL_HANDLE; void* pUserData);
VkQueue _graphicsQueue = VK_NULL_HANDLE; bool CheckRequiredValidationLayers();
VkQueue _presentQueue = VK_NULL_HANDLE; Vector<CSZ> GetRequiredExtensions();
VmaAllocator _vmaAllocator = VK_NULL_HANDLE; void CreateInstance();
VkSwapchainKHR _swapChain = VK_NULL_HANDLE; void FillDebugUtilsMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& vkdumci);
Vector<VkImage> _vSwapChainImages; void CreateDebugUtilsMessenger();
Vector<VkImageView> _vSwapChainImageViews; void CreateSurface();
VkCommandPool _commandPools[s_ringBufferSize] = {}; QueueFamilyIndices FindQueueFamilyIndices(VkPhysicalDevice device);
VkSemaphore _acquireNextImageSemaphores[s_ringBufferSize] = {}; bool CheckRequiredDeviceExtensions(VkPhysicalDevice device);
VkSemaphore _queueSubmitSemaphores[s_ringBufferSize] = {}; bool IsDeviceSuitable(VkPhysicalDevice device);
VkSemaphore _acquireNextImageSemaphore = VK_NULL_HANDLE; void PickPhysicalDevice();
VkSemaphore _queueSubmitSemaphore = VK_NULL_HANDLE; void CreateDevice();
VkFence _queueSubmitFences[s_ringBufferSize] = {}; SwapChainInfo GetSwapChainInfo(VkPhysicalDevice device);
QueueFamilyIndices _queueFamilyIndices; void CreateSwapChain(VkSwapchainKHR oldSwapchain = VK_NULL_HANDLE);
VkDescriptorPool _descriptorPoolImGui = VK_NULL_HANDLE; void CreateImageViews();
Vector<VkSampler> _vSamplers; void CreateCommandPools();
Vector<VkRenderPass> _vRenderPasses; void CreateSyncObjects();
Vector<Framebuffer> _vFramebuffers; void CreateSamplers();
bool _advancedLineRasterization = false;
public: public:
RendererVulkan(); // <CreateAndGet>
~RendererVulkan(); VkCommandBuffer CreateVkCommandBuffer(VkCommandPool commandPool);
virtual void ReleaseMe() override; VkInstance GetVkInstance() const { return _instance; }
VkPhysicalDevice GetVkPhysicalDevice() const { return _physicalDevice; }
VkDevice GetVkDevice() const { return _device; }
int GetGraphicsQueueFamilyIndex() const { return _queueFamilyIndices._graphicsFamilyIndex; }
VkQueue GetVkGraphicsQueue() const { return _graphicsQueue; }
const VkAllocationCallbacks* GetAllocator() const { return nullptr; }
VmaAllocator GetVmaAllocator() const { return _vmaAllocator; }
VkCommandPool GetVkCommandPool(int ringBufferIndex) const { return _commandPools[ringBufferIndex]; }
const VkSampler* GetImmutableSampler(Sampler s) const;
// </CreateAndGet>
void Init(); static void ImGuiCheckVkResultFn(VkResult res);
void Done(); virtual void ImGuiInit(RPHandle renderPassHandle) override;
virtual void ImGuiRenderDrawData() override;
static void VulkanCompilerInit(); virtual void ResizeSwapChain() override;
static void VulkanCompilerDone();
static bool VulkanCompile(CSZ source, CSZ sourceName, CSZ* defines, BaseShaderInclude* pInclude,
CSZ entryPoint, CSZ target, UINT32 flags, UINT32** ppCode, UINT32* pSize, CSZ* ppErrorMsgs);
private: virtual PBaseExtReality GetExtReality() override;
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsMessengerCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverityFlagBits,
VkDebugUtilsMessageTypeFlagsEXT messageTypeFlags,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData);
bool CheckRequiredValidationLayers();
Vector<CSZ> GetRequiredExtensions();
void CreateInstance();
void FillDebugUtilsMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& vkdumci);
void CreateDebugUtilsMessenger();
void CreateSurface();
QueueFamilyIndices FindQueueFamilyIndices(VkPhysicalDevice device);
bool CheckRequiredDeviceExtensions(VkPhysicalDevice device);
bool IsDeviceSuitable(VkPhysicalDevice device);
void PickPhysicalDevice();
void CreateDevice();
SwapChainInfo GetSwapChainInfo(VkPhysicalDevice device);
void CreateSwapChain(VkSwapchainKHR oldSwapchain = VK_NULL_HANDLE);
void CreateImageViews();
void CreateCommandPools();
void CreateSyncObjects();
void CreateSamplers();
public: // Which graphics API?
// <CreateAndGet> virtual Gapi GetGapi() override { return Gapi::vulkan; }
VkCommandBuffer CreateVkCommandBuffer(VkCommandPool commandPool);
VkInstance GetVkInstance() const { return _instance; } // <FrameCycle>
VkPhysicalDevice GetVkPhysicalDevice() const { return _physicalDevice; } virtual void BeginFrame() override;
VkDevice GetVkDevice() const { return _device; } virtual void AcquireSwapChainImage() override;
int GetGraphicsQueueFamilyIndex() const { return _queueFamilyIndices._graphicsFamilyIndex; } virtual void EndFrame() override;
VkQueue GetVkGraphicsQueue() const { return _graphicsQueue; } virtual void WaitIdle() override;
const VkAllocationCallbacks* GetAllocator() const { return nullptr; } virtual void OnMinimized() override;
VmaAllocator GetVmaAllocator() const { return _vmaAllocator; } // </FrameCycle>
VkCommandPool GetVkCommandPool(int ringBufferIndex) const { return _commandPools[ringBufferIndex]; }
const VkSampler* GetImmutableSampler(Sampler s) const;
// </CreateAndGet>
static void ImGuiCheckVkResultFn(VkResult res); // <Resources>
virtual void ImGuiInit(RPHandle renderPassHandle) override; virtual PBaseCommandBuffer InsertCommandBuffer() override;
virtual void ImGuiRenderDrawData() override; virtual PBaseGeometry InsertGeometry() override;
virtual PBasePipeline InsertPipeline() override;
virtual PBaseShader InsertShader() override;
virtual PBaseTexture InsertTexture() override;
virtual void ResizeSwapChain() override; virtual void DeleteCommandBuffer(PBaseCommandBuffer p) override;
virtual void DeleteGeometry(PBaseGeometry p) override;
virtual void DeletePipeline(PBasePipeline p) override;
virtual void DeleteShader(PBaseShader p) override;
virtual void DeleteTexture(PBaseTexture p) override;
virtual PBaseExtReality GetExtReality() override; virtual RPHandle CreateRenderPass(std::initializer_list<RP::Attachment> ilA, std::initializer_list<RP::Subpass> ilS, std::initializer_list<RP::Dependency> ilD) override;
virtual FBHandle CreateFramebuffer(RPHandle renderPassHandle, std::initializer_list<TexturePtr> il, int w, int h,
int swapChainBufferIndex = -1, CubeMapFace cubeMapFace = CubeMapFace::none) override;
virtual void DeleteRenderPass(RPHandle handle) override;
virtual void DeleteFramebuffer(FBHandle handle) override;
int GetNextRenderPassIndex() const;
int GetNextFramebufferIndex() const;
VkRenderPass GetRenderPass(RPHandle handle) const;
RcFramebuffer GetFramebuffer(FBHandle handle) const;
// </Resources>
// Which graphics API? // <BufferAndImage>
virtual Gapi GetGapi() override { return Gapi::vulkan; } void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, HostAccess hostAccess, VkBuffer& buffer, VmaAllocation& vmaAllocation);
void CopyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size, PBaseCommandBuffer pCB = nullptr);
void CreateImage(const VkImageCreateInfo* pImageCreateInfo, HostAccess hostAccess, VkImage& image, VmaAllocation& vmaAllocation);
void CopyImage(
VkImage srcImage, uint32_t srcMipLevel, uint32_t srcArrayLayer,
VkImage dstImage, uint32_t dstMipLevel, uint32_t dstArrayLayer,
uint32_t width, uint32_t height,
PBaseCommandBuffer pCB = nullptr);
void CopyBufferToImage(
VkBuffer buffer,
VkImage image, uint32_t mipLevel, uint32_t arrayLayer,
uint32_t width, uint32_t height,
PBaseCommandBuffer pCB = nullptr);
void CopyImageToBuffer(
VkImage image, uint32_t mipLevel, uint32_t arrayLayer,
uint32_t width, uint32_t height,
VkBuffer buffer,
PBaseCommandBuffer pCB = nullptr);
// </BufferAndImage>
// <FrameCycle> virtual void UpdateUtilization() override;
virtual void BeginFrame() override;
virtual void AcquireSwapChainImage() override;
virtual void EndFrame() override;
virtual void WaitIdle() override;
virtual void OnMinimized() override;
// </FrameCycle>
// <Resources> bool IsAdvancedLineRasterizationSupported() const { return _advancedLineRasterization; }
virtual PBaseCommandBuffer InsertCommandBuffer() override; };
virtual PBaseGeometry InsertGeometry() override; VERUS_TYPEDEFS(RendererVulkan);
virtual PBasePipeline InsertPipeline() override;
virtual PBaseShader InsertShader() override;
virtual PBaseTexture InsertTexture() override;
virtual void DeleteCommandBuffer(PBaseCommandBuffer p) override;
virtual void DeleteGeometry(PBaseGeometry p) override;
virtual void DeletePipeline(PBasePipeline p) override;
virtual void DeleteShader(PBaseShader p) override;
virtual void DeleteTexture(PBaseTexture p) override;
virtual RPHandle CreateRenderPass(std::initializer_list<RP::Attachment> ilA, std::initializer_list<RP::Subpass> ilS, std::initializer_list<RP::Dependency> ilD) override;
virtual FBHandle CreateFramebuffer(RPHandle renderPassHandle, std::initializer_list<TexturePtr> il, int w, int h,
int swapChainBufferIndex = -1, CubeMapFace cubeMapFace = CubeMapFace::none) override;
virtual void DeleteRenderPass(RPHandle handle) override;
virtual void DeleteFramebuffer(FBHandle handle) override;
int GetNextRenderPassIndex() const;
int GetNextFramebufferIndex() const;
VkRenderPass GetRenderPass(RPHandle handle) const;
RcFramebuffer GetFramebuffer(FBHandle handle) const;
// </Resources>
// <BufferAndImage>
void CreateBuffer(VkDeviceSize size, VkBufferUsageFlags usage, HostAccess hostAccess, VkBuffer& buffer, VmaAllocation& vmaAllocation);
void CopyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size, PBaseCommandBuffer pCB = nullptr);
void CreateImage(const VkImageCreateInfo* pImageCreateInfo, HostAccess hostAccess, VkImage& image, VmaAllocation& vmaAllocation);
void CopyImage(
VkImage srcImage, uint32_t srcMipLevel, uint32_t srcArrayLayer,
VkImage dstImage, uint32_t dstMipLevel, uint32_t dstArrayLayer,
uint32_t width, uint32_t height,
PBaseCommandBuffer pCB = nullptr);
void CopyBufferToImage(
VkBuffer buffer,
VkImage image, uint32_t mipLevel, uint32_t arrayLayer,
uint32_t width, uint32_t height,
PBaseCommandBuffer pCB = nullptr);
void CopyImageToBuffer(
VkImage image, uint32_t mipLevel, uint32_t arrayLayer,
uint32_t width, uint32_t height,
VkBuffer buffer,
PBaseCommandBuffer pCB = nullptr);
// </BufferAndImage>
virtual void UpdateUtilization() override;
bool IsAdvancedLineRasterizationSupported() const { return _advancedLineRasterization; }
};
VERUS_TYPEDEFS(RendererVulkan);
}
extern "C" extern "C"
{ {

View File

@ -209,12 +209,12 @@ void ShaderVulkan::Done()
for (auto& x : _vDescriptorSetDesc) for (auto& x : _vDescriptorSetDesc)
VERUS_VULKAN_DESTROY(x._buffer, vmaDestroyBuffer(pRendererVulkan->GetVmaAllocator(), x._buffer, x._vmaAllocation)); VERUS_VULKAN_DESTROY(x._buffer, vmaDestroyBuffer(pRendererVulkan->GetVmaAllocator(), x._buffer, x._vmaAllocation));
_vDescriptorSetDesc.clear(); _vDescriptorSetDesc.clear();
for (auto& kv : _mapCompiled) for (auto& [key, value] : _mapCompiled)
{ {
VERUS_FOR(i, +Stage::count) VERUS_FOR(i, +Stage::count)
{ {
VERUS_VULKAN_DESTROY(kv.second._shaderModules[i], VERUS_VULKAN_DESTROY(value._shaderModules[i],
vkDestroyShaderModule(pRendererVulkan->GetVkDevice(), kv.second._shaderModules[i], pRendererVulkan->GetAllocator())); vkDestroyShaderModule(pRendererVulkan->GetVkDevice(), value._shaderModules[i], pRendererVulkan->GetAllocator()));
} }
} }
_mapCompiled.clear(); _mapCompiled.clear();

View File

@ -1,86 +1,83 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class ShaderVulkan : public BaseShader
{ {
class ShaderVulkan : public BaseShader public:
struct Compiled
{ {
public: VkShaderModule _shaderModules[+Stage::count] = {};
struct Compiled String _entry;
{ int _stageCount = 0;
VkShaderModule _shaderModules[+Stage::count] = {};
String _entry;
int _stageCount = 0;
};
VERUS_TYPEDEFS(Compiled);
private:
typedef Map<String, Compiled> TMapCompiled;
struct DescriptorSetDesc
{
Vector<Sampler> _vSamplers;
VkBuffer _buffer = VK_NULL_HANDLE;
VmaAllocation _vmaAllocation = VK_NULL_HANDLE;
VkDescriptorSet _descriptorSet = VK_NULL_HANDLE;
BYTE* _pMappedData = nullptr;
const void* _pSrc = nullptr;
int _size = 0;
int _alignedSize = 0;
int _capacity = 1;
int _capacityInBytes = 0;
int _offset = 0;
int _peakLoad = 0;
VkShaderStageFlags _stageFlags = 0;
};
TMapCompiled _mapCompiled;
Vector<DescriptorSetDesc> _vDescriptorSetDesc;
Vector<VkDescriptorSet> _vComplexDescriptorSets;
Descriptors _descriptors;
VkPipelineLayout _pipelineLayout = VK_NULL_HANDLE;
String _debugInfo;
UINT64 _currentFrame = UINT64_MAX;
bool _compute = false;
public:
ShaderVulkan();
virtual ~ShaderVulkan() override;
virtual void Init(CSZ source, CSZ sourceName, CSZ* branches) override;
virtual void Done() override;
virtual void CreateDescriptorSet(int setNumber, const void* pSrc, int size, int capacity, std::initializer_list<Sampler> il, ShaderStageFlags stageFlags) override;
virtual void CreatePipelineLayout() override;
virtual CSHandle BindDescriptorSetTextures(int setNumber, std::initializer_list<TexturePtr> il, const int* pMipLevels, const int* pArrayLayers) override;
virtual void FreeDescriptorSet(CSHandle& complexSetHandle) override;
virtual void BeginBindDescriptors() override;
virtual void EndBindDescriptors() override;
//
// Vulkan
//
void CreateDescriptorSets();
VkDescriptorSet GetVkDescriptorSet(int setNumber) const;
VkDescriptorSet GetComplexVkDescriptorSet(CSHandle descSetID) const;
RcCompiled GetCompiled(CSZ branch) const { return _mapCompiled.at(branch); }
VkPipelineLayout GetVkPipelineLayout() const { return _pipelineLayout; }
bool TryPushConstants(int setNumber, RBaseCommandBuffer cb) const;
int UpdateUniformBuffer(int setNumber);
bool IsCompute() const { return _compute; }
void OnError(CSZ s) const;
void UpdateUtilization() const;
}; };
VERUS_TYPEDEFS(ShaderVulkan); VERUS_TYPEDEFS(Compiled);
}
private:
typedef Map<String, Compiled> TMapCompiled;
struct DescriptorSetDesc
{
Vector<Sampler> _vSamplers;
VkBuffer _buffer = VK_NULL_HANDLE;
VmaAllocation _vmaAllocation = VK_NULL_HANDLE;
VkDescriptorSet _descriptorSet = VK_NULL_HANDLE;
BYTE* _pMappedData = nullptr;
const void* _pSrc = nullptr;
int _size = 0;
int _alignedSize = 0;
int _capacity = 1;
int _capacityInBytes = 0;
int _offset = 0;
int _peakLoad = 0;
VkShaderStageFlags _stageFlags = 0;
};
TMapCompiled _mapCompiled;
Vector<DescriptorSetDesc> _vDescriptorSetDesc;
Vector<VkDescriptorSet> _vComplexDescriptorSets;
Descriptors _descriptors;
VkPipelineLayout _pipelineLayout = VK_NULL_HANDLE;
String _debugInfo;
UINT64 _currentFrame = UINT64_MAX;
bool _compute = false;
public:
ShaderVulkan();
virtual ~ShaderVulkan() override;
virtual void Init(CSZ source, CSZ sourceName, CSZ* branches) override;
virtual void Done() override;
virtual void CreateDescriptorSet(int setNumber, const void* pSrc, int size, int capacity, std::initializer_list<Sampler> il, ShaderStageFlags stageFlags) override;
virtual void CreatePipelineLayout() override;
virtual CSHandle BindDescriptorSetTextures(int setNumber, std::initializer_list<TexturePtr> il, const int* pMipLevels, const int* pArrayLayers) override;
virtual void FreeDescriptorSet(CSHandle& complexSetHandle) override;
virtual void BeginBindDescriptors() override;
virtual void EndBindDescriptors() override;
//
// Vulkan
//
void CreateDescriptorSets();
VkDescriptorSet GetVkDescriptorSet(int setNumber) const;
VkDescriptorSet GetComplexVkDescriptorSet(CSHandle descSetID) const;
RcCompiled GetCompiled(CSZ branch) const { return _mapCompiled.at(branch); }
VkPipelineLayout GetVkPipelineLayout() const { return _pipelineLayout; }
bool TryPushConstants(int setNumber, RBaseCommandBuffer cb) const;
int UpdateUniformBuffer(int setNumber);
bool IsCompute() const { return _compute; }
void OnError(CSZ s) const;
void UpdateUtilization() const;
};
VERUS_TYPEDEFS(ShaderVulkan);
} }

View File

@ -1,63 +1,60 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class TextureVulkan : public BaseTexture
{ {
class TextureVulkan : public BaseTexture struct BufferEx
{ {
struct BufferEx VkBuffer _buffer = VK_NULL_HANDLE;
{ VmaAllocation _vmaAllocation = VK_NULL_HANDLE;
VkBuffer _buffer = VK_NULL_HANDLE;
VmaAllocation _vmaAllocation = VK_NULL_HANDLE;
};
VkImage _image = VK_NULL_HANDLE;
VmaAllocation _vmaAllocation = VK_NULL_HANDLE;
VkImage _storageImage = VK_NULL_HANDLE;
VmaAllocation _storageVmaAllocation = VK_NULL_HANDLE;
VkImageView _imageView = VK_NULL_HANDLE;
VkImageView _imageViewForFramebuffer[+CubeMapFace::count] = {};
VkSampler _sampler = VK_NULL_HANDLE;
Vector<UINT32> _vDefinedSubresources;
Vector<VkImageView> _vStorageImageViews;
Vector<BufferEx> _vStagingBuffers;
Vector<BufferEx> _vReadbackBuffers;
Vector<CSHandle> _vCshGenerateMips;
bool _definedStorage = false;
public:
TextureVulkan();
virtual ~TextureVulkan() override;
virtual void Init(RcTextureDesc desc) override;
virtual void Done() override;
virtual void UpdateSubresource(const void* p, int mipLevel, int arrayLayer, PBaseCommandBuffer pCB) override;
virtual bool ReadbackSubresource(void* p, bool recordCopyCommand, PBaseCommandBuffer pCB) override;
virtual void GenerateMips(PBaseCommandBuffer pCB) override;
void GenerateCubeMapMips(PBaseCommandBuffer pCB);
virtual Continue Scheduled_Update() override;
//
// Vulkan
//
void CreateSampler();
VkImage GetVkImage() const { return _image; }
VkImageView GetVkImageView() const { return _imageView; }
VkImageView GetVkImageViewForFramebuffer(CubeMapFace face) const;
VkImageView GetStorageVkImageView(int mipLevel, int arrayLayer) const { return _vStorageImageViews[mipLevel + arrayLayer * (_desc._mipLevels - 1)]; }
VkSampler GetVkSampler() const { return _sampler; }
ImageLayout GetSubresourceMainLayout(int mipLevel, int arrayLayer) const;
void MarkSubresourceDefined(int mipLevel, int arrayLayer);
static VkFormat RemoveSRGB(VkFormat format);
}; };
VERUS_TYPEDEFS(TextureVulkan);
} VkImage _image = VK_NULL_HANDLE;
VmaAllocation _vmaAllocation = VK_NULL_HANDLE;
VkImage _storageImage = VK_NULL_HANDLE;
VmaAllocation _storageVmaAllocation = VK_NULL_HANDLE;
VkImageView _imageView = VK_NULL_HANDLE;
VkImageView _imageViewForFramebuffer[+CubeMapFace::count] = {};
VkSampler _sampler = VK_NULL_HANDLE;
Vector<UINT32> _vDefinedSubresources;
Vector<VkImageView> _vStorageImageViews;
Vector<BufferEx> _vStagingBuffers;
Vector<BufferEx> _vReadbackBuffers;
Vector<CSHandle> _vCshGenerateMips;
bool _definedStorage = false;
public:
TextureVulkan();
virtual ~TextureVulkan() override;
virtual void Init(RcTextureDesc desc) override;
virtual void Done() override;
virtual void UpdateSubresource(const void* p, int mipLevel, int arrayLayer, PBaseCommandBuffer pCB) override;
virtual bool ReadbackSubresource(void* p, bool recordCopyCommand, PBaseCommandBuffer pCB) override;
virtual void GenerateMips(PBaseCommandBuffer pCB) override;
void GenerateCubeMapMips(PBaseCommandBuffer pCB);
virtual Continue Scheduled_Update() override;
//
// Vulkan
//
void CreateSampler();
VkImage GetVkImage() const { return _image; }
VkImageView GetVkImageView() const { return _imageView; }
VkImageView GetVkImageViewForFramebuffer(CubeMapFace face) const;
VkImageView GetStorageVkImageView(int mipLevel, int arrayLayer) const { return _vStorageImageViews[mipLevel + arrayLayer * (_desc._mipLevels - 1)]; }
VkSampler GetVkSampler() const { return _sampler; }
ImageLayout GetSubresourceMainLayout(int mipLevel, int arrayLayer) const;
void MarkSubresourceDefined(int mipLevel, int arrayLayer);
static VkFormat RemoveSRGB(VkFormat format);
};
VERUS_TYPEDEFS(TextureVulkan);
} }

View File

@ -11,23 +11,23 @@
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion> <VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<ProjectGuid>{5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}</ProjectGuid> <ProjectGuid>{5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}</ProjectGuid>
<RootNamespace>TextureTool</RootNamespace> <RootNamespace>TextureTool</RootNamespace>
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -45,18 +45,13 @@
<Import Project="..\Verus\Verus.props" /> <Import Project="..\Verus\Verus.props" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@ -71,6 +66,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>

View File

@ -1,25 +1,25 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 17
VisualStudioVersion = 16.0.29613.14 VisualStudioVersion = 17.7.34003.232
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Verus", "Verus\Verus.vcxproj", "{B154D670-E4B1-4D8A-885C-69546A5BD833}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HelloTexturedCube", "HelloTexturedCube\HelloTexturedCube.vcxproj", "{26BD6E61-E36D-464A-A312-4110ADF10083}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HelloTriangle", "HelloTriangle\HelloTriangle.vcxproj", "{BC17ACD3-97EB-4D5C-A2C9-574CDAA7576B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PAKBuilder", "PAKBuilder\PAKBuilder.vcxproj", "{EBF1E2F9-65AA-419D-A3D3-AD66EB086E57}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererDirect3D11", "RendererDirect3D11\RendererDirect3D11.vcxproj", "{8269DCCE-E226-46E4-B9F6-290AB5DF2678}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererDirect3D12", "RendererDirect3D12\RendererDirect3D12.vcxproj", "{53923514-84B2-4B78-889A-8709C6BFA3A5}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererDirect3D12", "RendererDirect3D12\RendererDirect3D12.vcxproj", "{53923514-84B2-4B78-889A-8709C6BFA3A5}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererVulkan", "RendererVulkan\RendererVulkan.vcxproj", "{C9195A1C-9224-4B40-BBBC-AA90EF3BE3E0}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererVulkan", "RendererVulkan\RendererVulkan.vcxproj", "{C9195A1C-9224-4B40-BBBC-AA90EF3BE3E0}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VulkanShaderCompiler", "VulkanShaderCompiler\VulkanShaderCompiler.vcxproj", "{1EA5F5D1-9138-406D-871B-3CD75343E14C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PAKBuilder", "PAKBuilder\PAKBuilder.vcxproj", "{EBF1E2F9-65AA-419D-A3D3-AD66EB086E57}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TextureTool", "TextureTool\TextureTool.vcxproj", "{5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TextureTool", "TextureTool\TextureTool.vcxproj", "{5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HelloTriangle", "HelloTriangle\HelloTriangle.vcxproj", "{BC17ACD3-97EB-4D5C-A2C9-574CDAA7576B}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Verus", "Verus\Verus.vcxproj", "{B154D670-E4B1-4D8A-885C-69546A5BD833}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HelloTexturedCube", "HelloTexturedCube\HelloTexturedCube.vcxproj", "{26BD6E61-E36D-464A-A312-4110ADF10083}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VulkanShaderCompiler", "VulkanShaderCompiler\VulkanShaderCompiler.vcxproj", "{1EA5F5D1-9138-406D-871B-3CD75343E14C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererDirect3D11", "RendererDirect3D11\RendererDirect3D11.vcxproj", "{8269DCCE-E226-46E4-B9F6-290AB5DF2678}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -27,10 +27,22 @@ Global
Release|x64 = Release|x64 Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B154D670-E4B1-4D8A-885C-69546A5BD833}.Debug|x64.ActiveCfg = Debug|x64 {26BD6E61-E36D-464A-A312-4110ADF10083}.Debug|x64.ActiveCfg = Debug|x64
{B154D670-E4B1-4D8A-885C-69546A5BD833}.Debug|x64.Build.0 = Debug|x64 {26BD6E61-E36D-464A-A312-4110ADF10083}.Debug|x64.Build.0 = Debug|x64
{B154D670-E4B1-4D8A-885C-69546A5BD833}.Release|x64.ActiveCfg = Release|x64 {26BD6E61-E36D-464A-A312-4110ADF10083}.Release|x64.ActiveCfg = Release|x64
{B154D670-E4B1-4D8A-885C-69546A5BD833}.Release|x64.Build.0 = Release|x64 {26BD6E61-E36D-464A-A312-4110ADF10083}.Release|x64.Build.0 = Release|x64
{BC17ACD3-97EB-4D5C-A2C9-574CDAA7576B}.Debug|x64.ActiveCfg = Debug|x64
{BC17ACD3-97EB-4D5C-A2C9-574CDAA7576B}.Debug|x64.Build.0 = Debug|x64
{BC17ACD3-97EB-4D5C-A2C9-574CDAA7576B}.Release|x64.ActiveCfg = Release|x64
{BC17ACD3-97EB-4D5C-A2C9-574CDAA7576B}.Release|x64.Build.0 = Release|x64
{EBF1E2F9-65AA-419D-A3D3-AD66EB086E57}.Debug|x64.ActiveCfg = Debug|x64
{EBF1E2F9-65AA-419D-A3D3-AD66EB086E57}.Debug|x64.Build.0 = Debug|x64
{EBF1E2F9-65AA-419D-A3D3-AD66EB086E57}.Release|x64.ActiveCfg = Release|x64
{EBF1E2F9-65AA-419D-A3D3-AD66EB086E57}.Release|x64.Build.0 = Release|x64
{8269DCCE-E226-46E4-B9F6-290AB5DF2678}.Debug|x64.ActiveCfg = Debug|x64
{8269DCCE-E226-46E4-B9F6-290AB5DF2678}.Debug|x64.Build.0 = Debug|x64
{8269DCCE-E226-46E4-B9F6-290AB5DF2678}.Release|x64.ActiveCfg = Release|x64
{8269DCCE-E226-46E4-B9F6-290AB5DF2678}.Release|x64.Build.0 = Release|x64
{53923514-84B2-4B78-889A-8709C6BFA3A5}.Debug|x64.ActiveCfg = Debug|x64 {53923514-84B2-4B78-889A-8709C6BFA3A5}.Debug|x64.ActiveCfg = Debug|x64
{53923514-84B2-4B78-889A-8709C6BFA3A5}.Debug|x64.Build.0 = Debug|x64 {53923514-84B2-4B78-889A-8709C6BFA3A5}.Debug|x64.Build.0 = Debug|x64
{53923514-84B2-4B78-889A-8709C6BFA3A5}.Release|x64.ActiveCfg = Release|x64 {53923514-84B2-4B78-889A-8709C6BFA3A5}.Release|x64.ActiveCfg = Release|x64
@ -39,30 +51,18 @@ Global
{C9195A1C-9224-4B40-BBBC-AA90EF3BE3E0}.Debug|x64.Build.0 = Debug|x64 {C9195A1C-9224-4B40-BBBC-AA90EF3BE3E0}.Debug|x64.Build.0 = Debug|x64
{C9195A1C-9224-4B40-BBBC-AA90EF3BE3E0}.Release|x64.ActiveCfg = Release|x64 {C9195A1C-9224-4B40-BBBC-AA90EF3BE3E0}.Release|x64.ActiveCfg = Release|x64
{C9195A1C-9224-4B40-BBBC-AA90EF3BE3E0}.Release|x64.Build.0 = Release|x64 {C9195A1C-9224-4B40-BBBC-AA90EF3BE3E0}.Release|x64.Build.0 = Release|x64
{1EA5F5D1-9138-406D-871B-3CD75343E14C}.Debug|x64.ActiveCfg = Debug|x64
{1EA5F5D1-9138-406D-871B-3CD75343E14C}.Debug|x64.Build.0 = Debug|x64
{1EA5F5D1-9138-406D-871B-3CD75343E14C}.Release|x64.ActiveCfg = Release|x64
{1EA5F5D1-9138-406D-871B-3CD75343E14C}.Release|x64.Build.0 = Release|x64
{EBF1E2F9-65AA-419D-A3D3-AD66EB086E57}.Debug|x64.ActiveCfg = Debug|x64
{EBF1E2F9-65AA-419D-A3D3-AD66EB086E57}.Debug|x64.Build.0 = Debug|x64
{EBF1E2F9-65AA-419D-A3D3-AD66EB086E57}.Release|x64.ActiveCfg = Release|x64
{EBF1E2F9-65AA-419D-A3D3-AD66EB086E57}.Release|x64.Build.0 = Release|x64
{5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}.Debug|x64.ActiveCfg = Debug|x64 {5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}.Debug|x64.ActiveCfg = Debug|x64
{5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}.Debug|x64.Build.0 = Debug|x64 {5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}.Debug|x64.Build.0 = Debug|x64
{5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}.Release|x64.ActiveCfg = Release|x64 {5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}.Release|x64.ActiveCfg = Release|x64
{5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}.Release|x64.Build.0 = Release|x64 {5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}.Release|x64.Build.0 = Release|x64
{BC17ACD3-97EB-4D5C-A2C9-574CDAA7576B}.Debug|x64.ActiveCfg = Debug|x64 {B154D670-E4B1-4D8A-885C-69546A5BD833}.Debug|x64.ActiveCfg = Debug|x64
{BC17ACD3-97EB-4D5C-A2C9-574CDAA7576B}.Debug|x64.Build.0 = Debug|x64 {B154D670-E4B1-4D8A-885C-69546A5BD833}.Debug|x64.Build.0 = Debug|x64
{BC17ACD3-97EB-4D5C-A2C9-574CDAA7576B}.Release|x64.ActiveCfg = Release|x64 {B154D670-E4B1-4D8A-885C-69546A5BD833}.Release|x64.ActiveCfg = Release|x64
{BC17ACD3-97EB-4D5C-A2C9-574CDAA7576B}.Release|x64.Build.0 = Release|x64 {B154D670-E4B1-4D8A-885C-69546A5BD833}.Release|x64.Build.0 = Release|x64
{26BD6E61-E36D-464A-A312-4110ADF10083}.Debug|x64.ActiveCfg = Debug|x64 {1EA5F5D1-9138-406D-871B-3CD75343E14C}.Debug|x64.ActiveCfg = Debug|x64
{26BD6E61-E36D-464A-A312-4110ADF10083}.Debug|x64.Build.0 = Debug|x64 {1EA5F5D1-9138-406D-871B-3CD75343E14C}.Debug|x64.Build.0 = Debug|x64
{26BD6E61-E36D-464A-A312-4110ADF10083}.Release|x64.ActiveCfg = Release|x64 {1EA5F5D1-9138-406D-871B-3CD75343E14C}.Release|x64.ActiveCfg = Release|x64
{26BD6E61-E36D-464A-A312-4110ADF10083}.Release|x64.Build.0 = Release|x64 {1EA5F5D1-9138-406D-871B-3CD75343E14C}.Release|x64.Build.0 = Release|x64
{8269DCCE-E226-46E4-B9F6-290AB5DF2678}.Debug|x64.ActiveCfg = Debug|x64
{8269DCCE-E226-46E4-B9F6-290AB5DF2678}.Debug|x64.Build.0 = Debug|x64
{8269DCCE-E226-46E4-B9F6-290AB5DF2678}.Release|x64.ActiveCfg = Release|x64
{8269DCCE-E226-46E4-B9F6-290AB5DF2678}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -3,8 +3,8 @@
<ImportGroup Label="PropertySheets" /> <ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup> <PropertyGroup>
<IncludePath>C:\Compressonator_4.3.206\include;C:\Home\Projects\Verus\verus\Verus\src;C:\Home\Middleware\AMD Tootle 2.3\include;C:\Home\Middleware\bullet3-2.89\src;C:\Home\Middleware\bullet3-2.89\Extras;C:\Home\Middleware\libogg-1.3.5\include;C:\Home\Middleware\libvorbis-1.3.7\include;C:\Home\Middleware\openal-soft-1.22.0-bin\include;C:\Home\Middleware\OpenXR-SDK-release-1.0.27\include;C:\Home\Middleware\SDL2-2.0.22\include;C:\Home\Middleware\WinPixEventRuntime\include;C:\VulkanSDK\1.3.239.0\Include;$(IncludePath)</IncludePath> <IncludePath>C:\Compressonator_4.3.206\include;C:\Home\Projects\Verus\verus\Verus\src;C:\Home\Middleware\AMD Tootle 2.3\include;C:\Home\Middleware\bullet3-3.25\src;C:\Home\Middleware\bullet3-3.25\Extras;C:\Home\Middleware\libogg-1.3.5\include;C:\Home\Middleware\libvorbis-1.3.7\include;C:\Home\Middleware\openal-soft-1.22.0-bin\include;C:\Home\Middleware\OpenXR-SDK-release-1.0.27\include;C:\Home\Middleware\SDL2-2.0.22\include;C:\Home\Middleware\WinPixEventRuntime\include;C:\VulkanSDK\1.3.239.0\Include;$(IncludePath)</IncludePath>
<LibraryPath>C:\Compressonator_4.3.206\lib\VS2019\x64;C:\Home\Middleware\bullet3-2.89\bin;C:\Home\Middleware\AMD Tootle 2.3\lib;C:\Home\Middleware\libogg-1.3.5\lib;C:\Home\Middleware\libvorbis-1.3.7\lib2;C:\Home\Middleware\openal-soft-1.22.0-bin\libs\Win64;C:\Home\Middleware\OpenXR-SDK-release-1.0.27\lib;C:\Home\Middleware\SDL2-2.0.22\lib\x64;C:\Home\Middleware\WinPixEventRuntime\lib;C:\VulkanSDK\1.3.239.0\Lib;$(LibraryPath)</LibraryPath> <LibraryPath>C:\Compressonator_4.3.206\lib\VS2019\x64;C:\Home\Middleware\bullet3-3.25\bin;C:\Home\Middleware\AMD Tootle 2.3\lib;C:\Home\Middleware\libogg-1.3.5\lib;C:\Home\Middleware\libvorbis-1.3.7\lib2;C:\Home\Middleware\openal-soft-1.22.0-bin\libs\Win64;C:\Home\Middleware\OpenXR-SDK-release-1.0.27\lib;C:\Home\Middleware\SDL2-2.0.22\lib\x64;C:\Home\Middleware\WinPixEventRuntime\lib;C:\VulkanSDK\1.3.239.0\Lib;$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup /> <ItemDefinitionGroup />
<ItemGroup /> <ItemGroup />

View File

@ -11,23 +11,23 @@
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion> <VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<ProjectGuid>{B154D670-E4B1-4D8A-885C-69546A5BD833}</ProjectGuid> <ProjectGuid>{B154D670-E4B1-4D8A-885C-69546A5BD833}</ProjectGuid>
<RootNamespace>Verus</RootNamespace> <RootNamespace>Verus</RootNamespace>
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType> <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType> <ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset> <PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
@ -45,12 +45,6 @@
<Import Project="Verus.props" /> <Import Project="Verus.props" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
@ -60,6 +54,7 @@
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>verus.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>verus.h</PrecompiledHeaderFile>
<FloatingPointModel>Fast</FloatingPointModel> <FloatingPointModel>Fast</FloatingPointModel>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem> <SubSystem>
@ -78,6 +73,7 @@
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>verus.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>verus.h</PrecompiledHeaderFile>
<FloatingPointModel>Fast</FloatingPointModel> <FloatingPointModel>Fast</FloatingPointModel>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem> <SubSystem>
@ -216,7 +212,6 @@
<ClInclude Include="src\Global\Macros.h" /> <ClInclude Include="src\Global\Macros.h" />
<ClInclude Include="src\Global\Global.h" /> <ClInclude Include="src\Global\Global.h" />
<ClInclude Include="src\Global\STL.h" /> <ClInclude Include="src\Global\STL.h" />
<ClInclude Include="src\Global\SyntaxHighlight.h" />
<ClInclude Include="src\Global\Typedef.h" /> <ClInclude Include="src\Global\Typedef.h" />
<ClInclude Include="src\IO\StreamPtr.h" /> <ClInclude Include="src\IO\StreamPtr.h" />
<ClInclude Include="src\IO\Vwx.h" /> <ClInclude Include="src\IO\Vwx.h" />

View File

@ -165,9 +165,6 @@
<ClInclude Include="src\Global\STL.h"> <ClInclude Include="src\Global\STL.h">
<Filter>src\Global</Filter> <Filter>src\Global</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\Global\SyntaxHighlight.h">
<Filter>src\Global</Filter>
</ClInclude>
<ClInclude Include="src\Global\Typedef.h"> <ClInclude Include="src\Global\Typedef.h">
<Filter>src\Global</Filter> <Filter>src\Global</Filter>
</ClInclude> </ClInclude>

View File

@ -1,59 +1,56 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::AI
{ {
namespace AI struct TaskDriverDelegate
{ {
struct TaskDriverDelegate virtual void TaskDriver_OnTask(CSZ task, CSZ mode) = 0;
};
VERUS_TYPEDEFS(TaskDriverDelegate);
class TaskDriver
{
struct Task
{ {
virtual void TaskDriver_OnTask(CSZ task, CSZ mode) = 0; String _name;
float _chance = 100;
float _time = 0;
float _deadline = 0;
float _intervalMin = 0;
float _intervalSize = 0;
}; };
VERUS_TYPEDEFS(TaskDriverDelegate); VERUS_TYPEDEFS(Task);
class TaskDriver typedef Map<String, Task> TMapTasks;
struct Mode
{ {
struct Task String _name;
{ TMapTasks _mapTasks;
String _name;
float _chance = 100;
float _time = 0;
float _deadline = 0;
float _intervalMin = 0;
float _intervalSize = 0;
};
VERUS_TYPEDEFS(Task);
typedef Map<String, Task> TMapTasks;
struct Mode
{
String _name;
TMapTasks _mapTasks;
};
VERUS_TYPEDEFS(Mode);
typedef Map<String, Mode> TMapModes;
TMapModes _mapModes;
String _currentMode;
PTaskDriverDelegate _pDelegate = nullptr;
float _cooldown = 1;
float _cooldownTimer = 0;
public:
TaskDriver();
~TaskDriver();
void Update();
Str GetCurrentMode() const { return _C(_currentMode); }
void SetCurrentMode(CSZ name) { _currentMode = name; }
void SetDelegate(PTaskDriverDelegate p) { _pDelegate = p; }
void AddMode(CSZ name);
void AddTask(CSZ name, float chance, float intervalMin, float intervalMax, CSZ mode = nullptr);
}; };
VERUS_TYPEDEFS(TaskDriver); VERUS_TYPEDEFS(Mode);
}
typedef Map<String, Mode> TMapModes;
TMapModes _mapModes;
String _currentMode;
PTaskDriverDelegate _pDelegate = nullptr;
float _cooldown = 1;
float _cooldownTimer = 0;
public:
TaskDriver();
~TaskDriver();
void Update();
Str GetCurrentMode() const { return _C(_currentMode); }
void SetCurrentMode(CSZ name) { _currentMode = name; }
void SetDelegate(PTaskDriverDelegate p) { _pDelegate = p; }
void AddMode(CSZ name);
void AddTask(CSZ name, float chance, float intervalMin, float intervalMax, CSZ mode = nullptr);
};
VERUS_TYPEDEFS(TaskDriver);
} }

View File

@ -1,38 +1,35 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::AI
{ {
namespace AI class Turret
{ {
class Turret float _targetPitch = 0;
{ float _targetYaw = 0;
float _targetPitch = 0; float _actualPitch = 0;
float _targetYaw = 0; float _actualYaw = 0;
float _actualPitch = 0; float _pitchSpeed = 1;
float _actualYaw = 0; float _yawSpeed = 1;
float _pitchSpeed = 1;
float _yawSpeed = 1;
public: public:
void Update(); void Update();
float GetTargetPitch() const { return _targetPitch; } float GetTargetPitch() const { return _targetPitch; }
float GetTargetYaw() const { return _targetYaw; } float GetTargetYaw() const { return _targetYaw; }
float GetActualPitch() const { return _actualPitch; } float GetActualPitch() const { return _actualPitch; }
float GetActualYaw() const { return _actualYaw; } float GetActualYaw() const { return _actualYaw; }
bool IsTargetPitchReached(float threshold) const; bool IsTargetPitchReached(float threshold) const;
bool IsTargetYawReached(float threshold) const; bool IsTargetYawReached(float threshold) const;
// Speed: // Speed:
float GetPitchSpeed() const { return _pitchSpeed; } float GetPitchSpeed() const { return _pitchSpeed; }
float GetYawSpeed() const { return _yawSpeed; } float GetYawSpeed() const { return _yawSpeed; }
void SetPitchSpeed(float x) { _pitchSpeed = x; } void SetPitchSpeed(float x) { _pitchSpeed = x; }
void SetYawSpeed(float x) { _yawSpeed = x; } void SetYawSpeed(float x) { _yawSpeed = x; }
void LookAt(RcVector3 rayFromTurret, bool instantly = false); void LookAt(RcVector3 rayFromTurret, bool instantly = false);
}; };
VERUS_TYPEDEFS(Turret); VERUS_TYPEDEFS(Turret);
}
} }

View File

@ -1,114 +1,111 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Anim
{ {
namespace Anim struct AnimationDelegate
{ {
struct AnimationDelegate virtual void Animation_OnEnd(CSZ name) {}
virtual void Animation_OnTrigger(CSZ name, int state) {}
};
VERUS_TYPEDEFS(AnimationDelegate);
// Objects of this type are stored in Collection.
struct MotionData
{
Motion _motion;
float _duration = 0;
bool _looping = true;
bool _fast = false; // For auto easing.
};
VERUS_TYPEDEFS(MotionData);
typedef StoreUniqueWithNoRefCount<String, MotionData> TStoreMotions;
// The collection of motion objects that can be reused by multiple animation objects.
class Collection : private TStoreMotions, public IO::AsyncDelegate
{
bool _useShortNames = true;
public:
Collection(bool useShortNames = true);
~Collection();
virtual void Async_WhenLoaded(CSZ url, RcBlob blob) override;
void AddMotion(CSZ name, bool looping = true, float duration = 0, bool fast = false);
void DeleteAll();
PMotionData Find(CSZ name);
int GetMaxBones();
};
VERUS_TYPEDEFS(Collection);
// Holds the collection of motion objects and provides the ability to interpolate between them.
// Note: triggers will work properly with 'multiple animations' + 'single collection' only if you add motions before binding collection.
class Animation : public MotionDelegate
{
public:
static const int s_maxLayers = 8;
enum class Edge : int
{ {
virtual void Animation_OnEnd(CSZ name) {} begin = (1 << 0),
virtual void Animation_OnTrigger(CSZ name, int state) {} end = (1 << 1)
}; };
VERUS_TYPEDEFS(AnimationDelegate);
// Objects of this type are stored in Collection. struct Layer
struct MotionData
{ {
Motion _motion; Animation* _pAnimation = nullptr;
float _duration = 0; CSZ _rootBone = nullptr;
bool _looping = true;
bool _fast = false; // For auto easing.
}; };
VERUS_TYPEDEFS(MotionData); VERUS_TYPEDEFS(Layer);
typedef StoreUniqueWithNoRefCount<String, MotionData> TStoreMotions; private:
// The collection of motion objects that can be reused by multiple animation objects. PCollection _pCollection = nullptr;
class Collection : private TStoreMotions, public IO::AsyncDelegate PAnimationDelegate _pDelegate = nullptr;
{ PSkeleton _pSkeleton = nullptr;
bool _useShortNames = true; Motion _transitionMotion;
String _currentMotion;
String _prevMotion;
Vector<int> _vTriggerStates;
Easing _easing = Easing::none;
float _time = 0;
float _transitionDuration = 0;
float _transitionTime = 0;
bool _transition = false;
bool _playing = false;
public: public:
Collection(bool useShortNames = true); Animation();
~Collection(); ~Animation();
virtual void Async_WhenLoaded(CSZ url, RcBlob blob) override; void Update(int layerCount = 0, PLayer pLayers = nullptr);
void UpdateSkeleton(int layerCount = 0, PLayer pLayers = nullptr);
void AddMotion(CSZ name, bool looping = true, float duration = 0, bool fast = false); void BindCollection(PCollection p);
void DeleteAll(); void BindSkeleton(PSkeleton p);
PMotionData Find(CSZ name); PAnimationDelegate SetDelegate(PAnimationDelegate p) { return Utils::Swap(_pDelegate, p); }
int GetMaxBones();
};
VERUS_TYPEDEFS(Collection);
// Holds the collection of motion objects and provides the ability to interpolate between them. bool IsPlaying() const { return _playing; }
// Note: triggers will work properly with 'multiple animations' + 'single collection' only if you add motions before binding collection. void Play();
class Animation : public MotionDelegate void Stop();
{ void Pause();
public:
static const int s_maxLayers = 8;
enum class Edge : int Str GetCurrentMotionName() const { return _C(_currentMotion); }
{
begin = (1 << 0),
end = (1 << 1)
};
struct Layer void TransitionTo(CSZ name,
{ Interval duration = 0.5f, int randTime = -1, PMotion pFromMotion = nullptr);
Animation* _pAnimation = nullptr; bool TransitionToNew(std::initializer_list<CSZ> names,
CSZ _rootBone = nullptr; Interval duration = 0.5f, int randTime = -1, PMotion pFromMotion = nullptr);
}; bool IsInTransition() const { return _transition; }
VERUS_TYPEDEFS(Layer);
private: virtual void Motion_OnTrigger(CSZ name, int state) override;
PCollection _pCollection = nullptr;
PAnimationDelegate _pDelegate = nullptr;
PSkeleton _pSkeleton = nullptr;
Motion _transitionMotion;
String _currentMotion;
String _prevMotion;
Vector<int> _vTriggerStates;
Easing _easing = Easing::none;
float _time = 0;
float _transitionDuration = 0;
float _transitionTime = 0;
bool _transition = false;
bool _playing = false;
public: PMotion GetMotion();
Animation(); float GetAlpha(CSZ name = nullptr) const;
~Animation(); float GetTime();
bool IsNearEdge(float t = 0.1f, Edge edge = Edge::begin | Edge::end);
void Update(int layerCount = 0, PLayer pLayers = nullptr); int* GetTriggerStatesArray() { return _vTriggerStates.empty() ? nullptr : _vTriggerStates.data(); }
void UpdateSkeleton(int layerCount = 0, PLayer pLayers = nullptr); };
VERUS_TYPEDEFS(Animation);
void BindCollection(PCollection p);
void BindSkeleton(PSkeleton p);
PAnimationDelegate SetDelegate(PAnimationDelegate p) { return Utils::Swap(_pDelegate, p); }
bool IsPlaying() const { return _playing; }
void Play();
void Stop();
void Pause();
Str GetCurrentMotionName() const { return _C(_currentMotion); }
void TransitionTo(CSZ name,
Interval duration = 0.5f, int randTime = -1, PMotion pFromMotion = nullptr);
bool TransitionToNew(std::initializer_list<CSZ> names,
Interval duration = 0.5f, int randTime = -1, PMotion pFromMotion = nullptr);
bool IsInTransition() const { return _transition; }
virtual void Motion_OnTrigger(CSZ name, int state) override;
PMotion GetMotion();
float GetAlpha(CSZ name = nullptr) const;
float GetTime();
bool IsNearEdge(float t = 0.1f, Edge edge = Edge::begin | Edge::end);
int* GetTriggerStatesArray() { return _vTriggerStates.empty() ? nullptr : _vTriggerStates.data(); }
};
VERUS_TYPEDEFS(Animation);
}
} }

View File

@ -1,135 +1,132 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Anim
{ {
namespace Anim template<typename T, bool angle = false>
class Elastic
{ {
template<typename T, bool angle = false> T _target = 0;
class Elastic T _actual = 0;
float _speed = 1;
float _rate = 1;
public:
Elastic() { _rate = log(10.f); }
Elastic(const T& x) : _target(x), _actual(x) { _rate = log(10.f); }
Elastic(const T& x, float speed) : _target(x), _actual(x), _speed(speed) { _rate = log(10.f); }
void operator=(const T& x) { _target = x; }
operator const T& () const { return _actual; }
const T& GetTarget() const { return _target; }
void SetActual(const T& x) { _actual = x; }
void SetSpeed(float s) { _speed = s; }
void ForceTarget() { _actual = _target; }
void ForceTarget(const T& x) { _actual = _target = x; }
float GetDelta() const { return angle ? Math::WrapAngle(_target - _actual) : _target - _actual; }
void Update()
{ {
T _target = 0; const T d = _target - _actual;
T _actual = 0; if (angle)
float _speed = 1;
float _rate = 1;
public:
Elastic() { _rate = log(10.f); }
Elastic(const T& x) : _target(x), _actual(x) { _rate = log(10.f); }
Elastic(const T& x, float speed) : _target(x), _actual(x), _speed(speed) { _rate = log(10.f); }
void operator=(const T& x) { _target = x; }
operator const T& () const { return _actual; }
const T& GetTarget() const { return _target; }
void SetActual(const T& x) { _actual = x; }
void SetSpeed(float s) { _speed = s; }
void ForceTarget() { _actual = _target; }
void ForceTarget(const T& x) { _actual = _target = x; }
float GetDelta() const { return angle ? Math::WrapAngle(_target - _actual) : _target - _actual; }
void Update()
{ {
const T d = _target - _actual; VERUS_RT_ASSERT(_target >= T(-4) && _target < T(4));
VERUS_RT_ASSERT(_actual >= T(-4) && _actual < T(4));
if (d > T(VERUS_PI))
_actual += VERUS_2PI;
else if (d < T(-VERUS_PI))
_actual -= VERUS_2PI;
}
if (abs(d) < VERUS_FLOAT_THRESHOLD)
{
_actual = _target;
}
else
{
VERUS_QREF_TIMER;
const float ratio = 1 / exp(_speed * dt * _rate); // Exponential decay.
_actual = Math::Lerp(_target, _actual, ratio);
if (angle) if (angle)
{ _actual = Math::WrapAngle(_actual);
VERUS_RT_ASSERT(_target >= T(-4) && _target < T(4));
VERUS_RT_ASSERT(_actual >= T(-4) && _actual < T(4));
if (d > T(VERUS_PI))
_actual += VERUS_2PI;
else if (d < T(-VERUS_PI))
_actual -= VERUS_2PI;
}
if (abs(d) < VERUS_FLOAT_THRESHOLD)
{
_actual = _target;
}
else
{
VERUS_QREF_TIMER;
const float ratio = 1 / exp(_speed * dt * _rate); // Exponential decay.
_actual = Math::Lerp(_target, _actual, ratio);
if (angle)
_actual = Math::WrapAngle(_actual);
}
} }
}; }
};
template<> template<>
class Elastic<Vector3, false> class Elastic<Vector3, false>
{
typedef Vector3 T;
T _target = 0;
T _actual = 0;
float _speed = 1;
float _rate = 1;
public:
Elastic() { _rate = log(10.f); }
Elastic(const T& x) : _target(x), _actual(x) { _rate = log(10.f); }
Elastic(const T& x, float speed) : _target(x), _actual(x), _speed(speed) { _rate = log(10.f); }
void operator=(const T& x) { _target = x; }
operator const T& () const { return _actual; }
const T& GetTarget() const { return _target; }
void SetActual(const T& x) { _actual = x; }
void SetSpeed(float s) { _speed = s; }
void ForceTarget() { _actual = _target; }
void ForceTarget(const T& x) { _actual = _target = x; }
void Update()
{ {
typedef Vector3 T; const Vector3 d = _target - _actual;
if (VMath::dot(d, d) < VERUS_FLOAT_THRESHOLD * VERUS_FLOAT_THRESHOLD)
T _target = 0;
T _actual = 0;
float _speed = 1;
float _rate = 1;
public:
Elastic() { _rate = log(10.f); }
Elastic(const T& x) : _target(x), _actual(x) { _rate = log(10.f); }
Elastic(const T& x, float speed) : _target(x), _actual(x), _speed(speed) { _rate = log(10.f); }
void operator=(const T& x) { _target = x; }
operator const T& () const { return _actual; }
const T& GetTarget() const { return _target; }
void SetActual(const T& x) { _actual = x; }
void SetSpeed(float s) { _speed = s; }
void ForceTarget() { _actual = _target; }
void ForceTarget(const T& x) { _actual = _target = x; }
void Update()
{ {
const Vector3 d = _target - _actual; _actual = _target;
if (VMath::dot(d, d) < VERUS_FLOAT_THRESHOLD * VERUS_FLOAT_THRESHOLD)
{
_actual = _target;
}
else
{
VERUS_QREF_TIMER;
const float ratio = 1 / exp(_speed * dt * _rate); // Exponential decay.
_actual = VMath::lerp(ratio, _target, _actual);
}
} }
}; else
{
VERUS_QREF_TIMER;
const float ratio = 1 / exp(_speed * dt * _rate); // Exponential decay.
_actual = VMath::lerp(ratio, _target, _actual);
}
}
};
template<> template<>
class Elastic<Point3, false> class Elastic<Point3, false>
{
typedef Point3 T;
T _target = 0;
T _actual = 0;
float _speed = 1;
float _rate = 1;
public:
Elastic() { _rate = log(10.f); }
Elastic(const T& x) : _target(x), _actual(x) { _rate = log(10.f); }
Elastic(const T& x, float speed) : _target(x), _actual(x), _speed(speed) { _rate = log(10.f); }
void operator=(const T& x) { _target = x; }
operator const T& () const { return _actual; }
const T& GetTarget() const { return _target; }
void SetActual(const T& x) { _actual = x; }
void SetSpeed(float s) { _speed = s; }
void ForceTarget() { _actual = _target; }
void ForceTarget(const T& x) { _actual = _target = x; }
void Update()
{ {
typedef Point3 T; const Vector3 d = _target - _actual;
if (VMath::dot(d, d) < VERUS_FLOAT_THRESHOLD * VERUS_FLOAT_THRESHOLD)
T _target = 0;
T _actual = 0;
float _speed = 1;
float _rate = 1;
public:
Elastic() { _rate = log(10.f); }
Elastic(const T& x) : _target(x), _actual(x) { _rate = log(10.f); }
Elastic(const T& x, float speed) : _target(x), _actual(x), _speed(speed) { _rate = log(10.f); }
void operator=(const T& x) { _target = x; }
operator const T& () const { return _actual; }
const T& GetTarget() const { return _target; }
void SetActual(const T& x) { _actual = x; }
void SetSpeed(float s) { _speed = s; }
void ForceTarget() { _actual = _target; }
void ForceTarget(const T& x) { _actual = _target = x; }
void Update()
{ {
const Vector3 d = _target - _actual; _actual = _target;
if (VMath::dot(d, d) < VERUS_FLOAT_THRESHOLD * VERUS_FLOAT_THRESHOLD)
{
_actual = _target;
}
else
{
VERUS_QREF_TIMER;
const float ratio = 1 / exp(_speed * dt * _rate); // Exponential decay.
_actual = VMath::lerp(ratio, _target, _actual);
}
} }
}; else
} {
VERUS_QREF_TIMER;
const float ratio = 1 / exp(_speed * dt * _rate); // Exponential decay.
_actual = VMath::lerp(ratio, _target, _actual);
}
}
};
} }

View File

@ -462,16 +462,16 @@ void Motion::Bone::DeleteRedundantKeyframes(float boneAccLength)
// Which keyframe can be removed with the least error? // Which keyframe can be removed with the least error?
float leastError = threshold; float leastError = threshold;
int frameWithLeastError = -1; int frameWithLeastError = -1;
for (const auto& kv : mapSaved) for (const auto& [key, value] : mapSaved)
{ {
const int excludeFrame = kv.first; const int excludeFrame = key;
if (!excludeFrame || _pMotion->GetFrameCount() == excludeFrame) if (!excludeFrame || _pMotion->GetFrameCount() == excludeFrame)
continue; continue;
_mapRot.clear(); _mapRot.clear();
for (const auto& kv2 : mapSaved) for (const auto& [key2, value2] : mapSaved)
{ {
if (kv2.first != excludeFrame) if (key2 != excludeFrame)
_mapRot[kv2.first] = kv2.second; _mapRot[key2] = value2;
} }
float accError = 0; float accError = 0;
@ -523,16 +523,16 @@ void Motion::Bone::DeleteRedundantKeyframes(float boneAccLength)
// Which keyframe can be removed with the least error? // Which keyframe can be removed with the least error?
float leastError = threshold; float leastError = threshold;
int frameWithLeastError = -1; int frameWithLeastError = -1;
for (const auto& kv : mapSaved) for (const auto& [key, value] : mapSaved)
{ {
const int excludeFrame = kv.first; const int excludeFrame = key;
if (!excludeFrame || _pMotion->GetFrameCount() == excludeFrame) if (!excludeFrame || _pMotion->GetFrameCount() == excludeFrame)
continue; continue;
_mapPos.clear(); _mapPos.clear();
for (const auto& kv2 : mapSaved) for (const auto& [key2, value2] : mapSaved)
{ {
if (kv2.first != excludeFrame) if (key2 != excludeFrame)
_mapPos[kv2.first] = kv2.second; _mapPos[key2] = value2;
} }
float accError = 0; float accError = 0;
@ -584,16 +584,16 @@ void Motion::Bone::DeleteRedundantKeyframes(float boneAccLength)
// Which keyframe can be removed with the least error? // Which keyframe can be removed with the least error?
float leastError = threshold; float leastError = threshold;
int frameWithLeastError = -1; int frameWithLeastError = -1;
for (const auto& kv : mapSaved) for (const auto& [key, value] : mapSaved)
{ {
const int excludeFrame = kv.first; const int excludeFrame = key;
if (!excludeFrame || _pMotion->GetFrameCount() == excludeFrame) if (!excludeFrame || _pMotion->GetFrameCount() == excludeFrame)
continue; continue;
_mapScale.clear(); _mapScale.clear();
for (const auto& kv2 : mapSaved) for (const auto& [key2, value2] : mapSaved)
{ {
if (kv2.first != excludeFrame) if (key2 != excludeFrame)
_mapScale[kv2.first] = kv2.second; _mapScale[key2] = value2;
} }
float accError = 0; float accError = 0;
@ -927,10 +927,10 @@ void Motion::Done()
Motion::PBone Motion::GetBoneByIndex(int index) Motion::PBone Motion::GetBoneByIndex(int index)
{ {
int i = 0; int i = 0;
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
if (i == index) if (i == index)
return &kv.second; return &value;
i++; i++;
} }
return nullptr; return nullptr;
@ -989,9 +989,9 @@ void Motion::Serialize(IO::RStream stream)
stream << _fps; stream << _fps;
stream << GetBoneCount(); stream << GetBoneCount();
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
RBone bone = kv.second; RBone bone = value;
stream.WriteString(_C(bone.GetName())); stream.WriteString(_C(bone.GetName()));
bone.Serialize(stream, version); bone.Serialize(stream, version);
} }
@ -1078,27 +1078,27 @@ void Motion::DeleteRedundantKeyframes(Map<String, float>& mapBoneAccLengths)
void Motion::DeleteOddKeyframes() void Motion::DeleteOddKeyframes()
{ {
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
kv.second.DeleteOddKeyframes(); value.DeleteOddKeyframes();
} }
void Motion::InsertLoopKeyframes() void Motion::InsertLoopKeyframes()
{ {
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
kv.second.InsertLoopKeyframes(); value.InsertLoopKeyframes();
} }
void Motion::Cut(int frame, bool before) void Motion::Cut(int frame, bool before)
{ {
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
kv.second.Cut(frame, before); value.Cut(frame, before);
_frameCount = before ? _frameCount - frame : frame + 1; _frameCount = before ? _frameCount - frame : frame + 1;
} }
void Motion::Fix(bool speedLimit) void Motion::Fix(bool speedLimit)
{ {
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
kv.second.Fix(speedLimit); value.Fix(speedLimit);
} }
void Motion::ProcessTriggers(float time, PMotionDelegate p, int* pUserTriggerStates) void Motion::ProcessTriggers(float time, PMotionDelegate p, int* pUserTriggerStates)
@ -1110,9 +1110,9 @@ void Motion::ProcessTriggers(float time, PMotionDelegate p, int* pUserTriggerSta
nativeTime = GetNativeDuration() - nativeTime; nativeTime = GetNativeDuration() - nativeTime;
int i = 0; int i = 0;
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
PBone pBone = &kv.second; PBone pBone = &value;
int state = 0; int state = 0;
if (!(_reversed && nativeTime < _fpsInv * 0.5f)) // Avoid edge case for the first frame in reverse. if (!(_reversed && nativeTime < _fpsInv * 0.5f)) // Avoid edge case for the first frame in reverse.
pBone->ComputeTriggerAt(nativeTime, state); pBone->ComputeTriggerAt(nativeTime, state);
@ -1132,9 +1132,9 @@ void Motion::ProcessTriggers(float time, PMotionDelegate p, int* pUserTriggerSta
void Motion::ResetTriggers(int* pUserTriggerStates) void Motion::ResetTriggers(int* pUserTriggerStates)
{ {
int i = 0; int i = 0;
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
PBone pBone = &kv.second; PBone pBone = &value;
int state = 0; int state = 0;
if (_reversed) if (_reversed)
pBone->ComputeTriggerAt(GetNativeDuration(), state); pBone->ComputeTriggerAt(GetNativeDuration(), state);
@ -1153,9 +1153,9 @@ void Motion::SkipTriggers(float time, int* pUserTriggerStates)
nativeTime = GetNativeDuration() - nativeTime; nativeTime = GetNativeDuration() - nativeTime;
int i = 0; int i = 0;
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
PBone pBone = &kv.second; PBone pBone = &value;
int state; int state;
pBone->ComputeTriggerAt(nativeTime, state); pBone->ComputeTriggerAt(nativeTime, state);
if (pUserTriggerStates) if (pUserTriggerStates)
@ -1242,14 +1242,14 @@ void Motion::Exec(CSZ code, PBone pBone, Bone::Channel channel)
} }
else else
{ {
for (auto& bone : _mapBones) for (auto& [key, value] : _mapBones)
{ {
if (!strcmp(what, "rot")) if (!strcmp(what, "rot"))
bone.second._mapRot.clear(); value._mapRot.clear();
if (!strcmp(what, "pos")) if (!strcmp(what, "pos"))
bone.second._mapPos.clear(); value._mapPos.clear();
if (!strcmp(what, "scale")) if (!strcmp(what, "scale"))
bone.second._mapScale.clear(); value._mapScale.clear();
} }
} }
} }

View File

@ -1,342 +1,339 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Anim
{ {
namespace Anim struct MotionDelegate
{ {
struct MotionDelegate virtual void Motion_OnTrigger(CSZ name, int state) = 0;
{ };
virtual void Motion_OnTrigger(CSZ name, int state) = 0; VERUS_TYPEDEFS(MotionDelegate);
};
VERUS_TYPEDEFS(MotionDelegate);
// Motion holds a series of keyframes and provides the ability to interpolate between them. // Motion holds a series of keyframes and provides the ability to interpolate between them.
// Motion can be stored in XAN format. // Motion can be stored in XAN format.
// Motion's rate can be scaled and even reversed. // Motion's rate can be scaled and even reversed.
// Animation object can be used to handle multiple motion objects. // Animation object can be used to handle multiple motion objects.
class Motion : public Object class Motion : public Object
{
public:
class Bone : public AllocatorAware
{ {
public: public:
class Bone : public AllocatorAware enum class Channel : int
{ {
public: rotation,
enum class Channel : int position,
{ scale,
rotation, trigger
position, };
scale,
trigger enum class Flags : UINT32
}; {
none = 0,
enum class Flags : UINT32 slerpRot = (1 << 0),
{ splinePos = (1 << 1),
none = 0, splineScale = (1 << 2)
slerpRot = (1 << 0),
splinePos = (1 << 1),
splineScale = (1 << 2)
};
private:
friend class Motion;
static const float s_magicValueForCircle;
class Rotation
{
public:
Quat _q;
Rotation();
Rotation(RcQuat q);
Rotation(RcVector3 euler);
};
VERUS_TYPEDEFS(Rotation);
typedef Map<int, Rotation> TMapRot;
typedef Map<int, Vector3> TMapPos;
typedef Map<int, Vector3> TMapScale;
typedef Map<int, int> TMapTrigger;
String _name;
Motion* _pMotion = nullptr;
TMapRot _mapRot; // Rotation keyframes.
TMapPos _mapPos; // Position keyframes.
TMapScale _mapScale; // Scaling keyframes.
TMapTrigger _mapTrigger; // Trigger keyframes.
int _lastTriggerState = 0;
Flags _flags = Flags::none;
template<typename TMap, typename T>
float FindControlPoints(const TMap& m, int frames[4], T keys[4], float time) const
{
frames[0] = frames[1] = frames[2] = frames[3] = -1;
if (m.empty()) // No frames at all, so return null.
return 0;
time = Math::Max(0.f, time); // Negative time is not allowed.
float alpha;
const int frame = static_cast<int>(_pMotion->GetFps() * time); // Frame is before or at 'time'.
typename TMap::const_iterator it = m.upper_bound(frame); // Find frame after 'time'.
if (it != m.cend()) // There are frames greater (after 'time'):
{
if (it != m.cbegin()) // And there are less than (before 'time'), full interpolation:
{
typename TMap::const_iterator itPrev = it;
itPrev--;
frames[1] = itPrev->first;
keys[1] = itPrev->second;
if (itPrev != m.cbegin())
{
itPrev--;
frames[0] = itPrev->first;
keys[0] = itPrev->second;
}
frames[2] = it->first;
keys[2] = it->second;
it++;
if (it != m.cend())
{
frames[3] = it->first;
keys[3] = it->second;
}
alpha = (time - (frames[1] * _pMotion->GetFpsInv())) / ((frames[2] - frames[1]) * _pMotion->GetFpsInv());
}
else // But there are no less than:
{
frames[2] = it->first;
keys[2] = it->second;
it++;
if (it != m.cend())
{
frames[3] = it->first;
keys[3] = it->second;
}
alpha = time / (frames[2] * _pMotion->GetFpsInv());
}
}
else // There are no frames greater, but there are less than:
{
it--;
frames[1] = it->first;
keys[1] = it->second;
if (it != m.cbegin())
{
it--;
frames[0] = it->first;
keys[0] = it->second;
}
alpha = 0;
}
return alpha;
}
template<typename TMap>
static bool SpaceTimeSyncTemplate(TMap& m, int fromFrame, int toFrame)
{
const auto itFrom = m.find(fromFrame);
const auto itTo = m.find(toFrame);
if (m.end() == itFrom || m.end() == itTo) // Endpoints must exist.
return false;
const int totalFrames = toFrame - fromFrame;
auto it = itFrom;
Vector<float> vSegments;
vSegments.reserve(8);
float totalDist = 0;
while (it != itTo)
{
const auto& posA = it->second;
it++;
const auto& posB = it->second;
const float d = VMath::dist(Point3(posA), Point3(posB));
vSegments.push_back(d);
totalDist += d;
}
if (totalDist < 1e-4f) // Distance is too small.
return false;
const float invTotalDist = 1.f / totalDist;
TMap tempMap;
it = itFrom;
it++;
while (it != itTo) // Copy all keys in-between, delete original keys.
{
tempMap[it->first] = std::move(it->second);
it = m.erase(it);
}
it = tempMap.begin();
float distAcc = 0;
int i = 0;
while (it != tempMap.end())
{
distAcc += vSegments[i++];
int syncedFrame = fromFrame + static_cast<int>(totalFrames * (distAcc * invTotalDist) + 0.5f);
while (m.end() != m.find(syncedFrame)) // Frame already occupied?
syncedFrame++;
m[syncedFrame] = it->second;
it++;
}
return true;
}
public:
Bone(Motion* pMotion = nullptr);
~Bone();
Str GetName() const { return _C(_name); }
void Rename(CSZ name) { _name = name; }
int GetLastTriggerState() const { return _lastTriggerState; }
void SetLastTriggerState(int state) { _lastTriggerState = state; }
Flags GetFlags() const { return _flags; }
void SetFlags(Flags flags) { _flags = flags; }
void DeleteAll();
// Insert:
void InsertKeyframeRotation(int frame, RcQuat q);
void InsertKeyframeRotation(int frame, RcVector3 euler);
void InsertKeyframePosition(int frame, RcVector3 pos);
void InsertKeyframeScale(int frame, RcVector3 scale);
void InsertKeyframeTrigger(int frame, int state);
// Delete:
void DeleteKeyframeRotation(int frame);
void DeleteKeyframePosition(int frame);
void DeleteKeyframeScale(int frame);
void DeleteKeyframeTrigger(int frame);
// Find:
bool FindKeyframeRotation(int frame, RVector3 euler, RQuat q) const;
bool FindKeyframePosition(int frame, RVector3 pos) const;
bool FindKeyframeScale(int frame, RVector3 scale) const;
bool FindKeyframeTrigger(int frame, int& state) const;
// Compute:
void ComputeRotationAt(float time, RVector3 euler, RQuat q) const;
void ComputePositionAt(float time, RVector3 pos) const;
void ComputeScaleAt(float time, RVector3 scale) const;
void ComputeTriggerAt(float time, int& state) const;
void ComputeMatrixAt(float time, RTransform3 mat);
void MoveKeyframe(int direction, Channel channel, int frame);
int GetRotationKeyCount() const { return Utils::Cast32(_mapRot.size()); }
int GetPositionKeyCount() const { return Utils::Cast32(_mapPos.size()); }
int GetScaleKeyCount() const { return Utils::Cast32(_mapScale.size()); }
int GetTriggerKeyCount() const { return Utils::Cast32(_mapTrigger.size()); }
VERUS_P(void Serialize(IO::RStream stream, UINT16 version));
VERUS_P(void Deserialize(IO::RStream stream, UINT16 version));
void DeleteRedundantKeyframes(float boneAccLength);
void DeleteOddKeyframes();
void InsertLoopKeyframes();
void Cut(int frame, bool before);
void Fix(bool speedLimit);
void ApplyScaleBias(RcVector3 scale, RcVector3 bias);
void Scatter(int srcFrom, int srcTo, int dMin, int dMax);
bool SpaceTimeSync(Channel channel, int fromFrame, int toFrame);
int GetLastKeyframe() const;
}; };
VERUS_TYPEDEFS(Bone);
private: private:
static const int s_xanVersion = 0x0102; friend class Motion;
static const int s_maxFps = 10000;
static const int s_maxBones = 10000;
static const int s_maxFrames = 32 * 1024 * 1024;
typedef Map<String, Bone> TMapBones; static const float s_magicValueForCircle;
TMapBones _mapBones; class Rotation
Motion* _pBlendMotion = nullptr;
int _frameCount = 60;
int _fps = 12;
float _fpsInv = 1 / 12.f;
float _blendAlpha = 0;
float _playbackSpeed = 1;
float _playbackSpeedInv = 1;
bool _reversed = false;
public:
Motion();
~Motion();
void Init();
void Done();
int GetFps() const { return _fps; }
float GetFpsInv() const { return _fpsInv; }
void SetFps(int fps) { _fps = fps; _fpsInv = 1.f / _fps; }
int GetFrameCount() const { return _frameCount; }
void SetFrameCount(int count) { _frameCount = count; }
int GetBoneCount() const { return Utils::Cast32(_mapBones.size()); }
float GetDuration() const { return GetNativeDuration() * _playbackSpeedInv; }
float GetNativeDuration() const { return _frameCount * _fpsInv; }
PBone GetBoneByIndex(int index);
int GetBoneIndex(CSZ name) const;
PBone InsertBone(CSZ name);
void DeleteBone(CSZ name);
void DeleteAllBones();
PBone FindBone(CSZ name);
template<typename T>
void ForEachBone(const T& fn)
{ {
for (auto& kv : _mapBones) public:
Quat _q;
Rotation();
Rotation(RcQuat q);
Rotation(RcVector3 euler);
};
VERUS_TYPEDEFS(Rotation);
typedef Map<int, Rotation> TMapRot;
typedef Map<int, Vector3> TMapPos;
typedef Map<int, Vector3> TMapScale;
typedef Map<int, int> TMapTrigger;
String _name;
Motion* _pMotion = nullptr;
TMapRot _mapRot; // Rotation keyframes.
TMapPos _mapPos; // Position keyframes.
TMapScale _mapScale; // Scaling keyframes.
TMapTrigger _mapTrigger; // Trigger keyframes.
int _lastTriggerState = 0;
Flags _flags = Flags::none;
template<typename TMap, typename T>
float FindControlPoints(const TMap& m, int frames[4], T keys[4], float time) const
{
frames[0] = frames[1] = frames[2] = frames[3] = -1;
if (m.empty()) // No frames at all, so return null.
return 0;
time = Math::Max(0.f, time); // Negative time is not allowed.
float alpha;
const int frame = static_cast<int>(_pMotion->GetFps() * time); // Frame is before or at 'time'.
typename TMap::const_iterator it = m.upper_bound(frame); // Find frame after 'time'.
if (it != m.cend()) // There are frames greater (after 'time'):
{ {
if (Continue::no == fn(kv.second)) if (it != m.cbegin()) // And there are less than (before 'time'), full interpolation:
break; {
typename TMap::const_iterator itPrev = it;
itPrev--;
frames[1] = itPrev->first;
keys[1] = itPrev->second;
if (itPrev != m.cbegin())
{
itPrev--;
frames[0] = itPrev->first;
keys[0] = itPrev->second;
}
frames[2] = it->first;
keys[2] = it->second;
it++;
if (it != m.cend())
{
frames[3] = it->first;
keys[3] = it->second;
}
alpha = (time - (frames[1] * _pMotion->GetFpsInv())) / ((frames[2] - frames[1]) * _pMotion->GetFpsInv());
}
else // But there are no less than:
{
frames[2] = it->first;
keys[2] = it->second;
it++;
if (it != m.cend())
{
frames[3] = it->first;
keys[3] = it->second;
}
alpha = time / (frames[2] * _pMotion->GetFpsInv());
}
} }
else // There are no frames greater, but there are less than:
{
it--;
frames[1] = it->first;
keys[1] = it->second;
if (it != m.cbegin())
{
it--;
frames[0] = it->first;
keys[0] = it->second;
}
alpha = 0;
}
return alpha;
} }
void Serialize(IO::RStream stream); template<typename TMap>
void Deserialize(IO::RStream stream); static bool SpaceTimeSyncTemplate(TMap& m, int fromFrame, int toFrame)
{
const auto itFrom = m.find(fromFrame);
const auto itTo = m.find(toFrame);
if (m.end() == itFrom || m.end() == itTo) // Endpoints must exist.
return false;
void BakeMotionAt(float time, Motion& dest) const; const int totalFrames = toFrame - fromFrame;
void BindBlendMotion(Motion* p, float alpha);
Motion* GetBlendMotion() const { return _pBlendMotion; }
float GetBlendAlpha() const { return _blendAlpha; }
void DeleteRedundantKeyframes(Map<String, float>& mapBoneAccLengths); auto it = itFrom;
Vector<float> vSegments;
vSegments.reserve(8);
float totalDist = 0;
while (it != itTo)
{
const auto& posA = it->second;
it++;
const auto& posB = it->second;
const float d = VMath::dist(Point3(posA), Point3(posB));
vSegments.push_back(d);
totalDist += d;
}
if (totalDist < 1e-4f) // Distance is too small.
return false;
const float invTotalDist = 1.f / totalDist;
TMap tempMap;
it = itFrom;
it++;
while (it != itTo) // Copy all keys in-between, delete original keys.
{
tempMap[it->first] = std::move(it->second);
it = m.erase(it);
}
it = tempMap.begin();
float distAcc = 0;
int i = 0;
while (it != tempMap.end())
{
distAcc += vSegments[i++];
int syncedFrame = fromFrame + static_cast<int>(totalFrames * (distAcc * invTotalDist) + 0.5f);
while (m.end() != m.find(syncedFrame)) // Frame already occupied?
syncedFrame++;
m[syncedFrame] = it->second;
it++;
}
return true;
}
public:
Bone(Motion* pMotion = nullptr);
~Bone();
Str GetName() const { return _C(_name); }
void Rename(CSZ name) { _name = name; }
int GetLastTriggerState() const { return _lastTriggerState; }
void SetLastTriggerState(int state) { _lastTriggerState = state; }
Flags GetFlags() const { return _flags; }
void SetFlags(Flags flags) { _flags = flags; }
void DeleteAll();
// Insert:
void InsertKeyframeRotation(int frame, RcQuat q);
void InsertKeyframeRotation(int frame, RcVector3 euler);
void InsertKeyframePosition(int frame, RcVector3 pos);
void InsertKeyframeScale(int frame, RcVector3 scale);
void InsertKeyframeTrigger(int frame, int state);
// Delete:
void DeleteKeyframeRotation(int frame);
void DeleteKeyframePosition(int frame);
void DeleteKeyframeScale(int frame);
void DeleteKeyframeTrigger(int frame);
// Find:
bool FindKeyframeRotation(int frame, RVector3 euler, RQuat q) const;
bool FindKeyframePosition(int frame, RVector3 pos) const;
bool FindKeyframeScale(int frame, RVector3 scale) const;
bool FindKeyframeTrigger(int frame, int& state) const;
// Compute:
void ComputeRotationAt(float time, RVector3 euler, RQuat q) const;
void ComputePositionAt(float time, RVector3 pos) const;
void ComputeScaleAt(float time, RVector3 scale) const;
void ComputeTriggerAt(float time, int& state) const;
void ComputeMatrixAt(float time, RTransform3 mat);
void MoveKeyframe(int direction, Channel channel, int frame);
int GetRotationKeyCount() const { return Utils::Cast32(_mapRot.size()); }
int GetPositionKeyCount() const { return Utils::Cast32(_mapPos.size()); }
int GetScaleKeyCount() const { return Utils::Cast32(_mapScale.size()); }
int GetTriggerKeyCount() const { return Utils::Cast32(_mapTrigger.size()); }
VERUS_P(void Serialize(IO::RStream stream, UINT16 version));
VERUS_P(void Deserialize(IO::RStream stream, UINT16 version));
void DeleteRedundantKeyframes(float boneAccLength);
void DeleteOddKeyframes(); void DeleteOddKeyframes();
void InsertLoopKeyframes(); void InsertLoopKeyframes();
void Cut(int frame, bool before = true); void Cut(int frame, bool before);
void Fix(bool speedLimit); void Fix(bool speedLimit);
// Triggers: void ApplyScaleBias(RcVector3 scale, RcVector3 bias);
void ProcessTriggers(float time, PMotionDelegate p, int* pUserTriggerStates = nullptr);
void ResetTriggers(int* pUserTriggerStates = nullptr);
void SkipTriggers(float time, int* pUserTriggerStates = nullptr);
void ApplyScaleBias(CSZ name, RcVector3 scale, RcVector3 bias); void Scatter(int srcFrom, int srcTo, int dMin, int dMax);
float GetPlaybackSpeed() const { return _playbackSpeed; } bool SpaceTimeSync(Channel channel, int fromFrame, int toFrame);
float GetPlaybackSpeedInv() const { return _playbackSpeedInv; }
void SetPlaybackSpeed(float x);
void ComputePlaybackSpeed(float duration);
bool IsReversed() const { return _reversed; }
void Exec(CSZ code, PBone pBone = nullptr, Bone::Channel channel = Bone::Channel::rotation);
int GetLastKeyframe() const; int GetLastKeyframe() const;
static bool ExtractNestBone(CSZ name, SZ nestBone);
}; };
VERUS_TYPEDEFS(Motion); VERUS_TYPEDEFS(Bone);
}
private:
static const int s_xanVersion = 0x0102;
static const int s_maxFps = 10000;
static const int s_maxBones = 10000;
static const int s_maxFrames = 32 * 1024 * 1024;
typedef Map<String, Bone> TMapBones;
TMapBones _mapBones;
Motion* _pBlendMotion = nullptr;
int _frameCount = 60;
int _fps = 12;
float _fpsInv = 1 / 12.f;
float _blendAlpha = 0;
float _playbackSpeed = 1;
float _playbackSpeedInv = 1;
bool _reversed = false;
public:
Motion();
~Motion();
void Init();
void Done();
int GetFps() const { return _fps; }
float GetFpsInv() const { return _fpsInv; }
void SetFps(int fps) { _fps = fps; _fpsInv = 1.f / _fps; }
int GetFrameCount() const { return _frameCount; }
void SetFrameCount(int count) { _frameCount = count; }
int GetBoneCount() const { return Utils::Cast32(_mapBones.size()); }
float GetDuration() const { return GetNativeDuration() * _playbackSpeedInv; }
float GetNativeDuration() const { return _frameCount * _fpsInv; }
PBone GetBoneByIndex(int index);
int GetBoneIndex(CSZ name) const;
PBone InsertBone(CSZ name);
void DeleteBone(CSZ name);
void DeleteAllBones();
PBone FindBone(CSZ name);
template<typename T>
void ForEachBone(const T& fn)
{
for (auto& [key, value] : _mapBones)
{
if (Continue::no == fn(value))
break;
}
}
void Serialize(IO::RStream stream);
void Deserialize(IO::RStream stream);
void BakeMotionAt(float time, Motion& dest) const;
void BindBlendMotion(Motion* p, float alpha);
Motion* GetBlendMotion() const { return _pBlendMotion; }
float GetBlendAlpha() const { return _blendAlpha; }
void DeleteRedundantKeyframes(Map<String, float>& mapBoneAccLengths);
void DeleteOddKeyframes();
void InsertLoopKeyframes();
void Cut(int frame, bool before = true);
void Fix(bool speedLimit);
// Triggers:
void ProcessTriggers(float time, PMotionDelegate p, int* pUserTriggerStates = nullptr);
void ResetTriggers(int* pUserTriggerStates = nullptr);
void SkipTriggers(float time, int* pUserTriggerStates = nullptr);
void ApplyScaleBias(CSZ name, RcVector3 scale, RcVector3 bias);
float GetPlaybackSpeed() const { return _playbackSpeed; }
float GetPlaybackSpeedInv() const { return _playbackSpeedInv; }
void SetPlaybackSpeed(float x);
void ComputePlaybackSpeed(float duration);
bool IsReversed() const { return _reversed; }
void Exec(CSZ code, PBone pBone = nullptr, Bone::Channel channel = Bone::Channel::rotation);
int GetLastKeyframe() const;
static bool ExtractNestBone(CSZ name, SZ nestBone);
};
VERUS_TYPEDEFS(Motion);
} }

View File

@ -1,47 +1,44 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Anim
{ {
namespace Anim class Orbit
{ {
class Orbit Matrix3 _matrix;
{ Elastic<float, true> _pitch;
Matrix3 _matrix; Elastic<float, true> _yaw;
Elastic<float, true> _pitch; float _basePitch = 0;
Elastic<float, true> _yaw; float _baseYaw = 0;
float _basePitch = 0; float _speed = 1;
float _baseYaw = 0; float _offsetStrength = 0;
float _speed = 1; float _maxPitch = 0.45f;
float _offsetStrength = 0; bool _locked = false;
float _maxPitch = 0.45f;
bool _locked = false;
public: public:
Orbit(); Orbit();
~Orbit(); ~Orbit();
void Update(bool smoothRestore = true); void Update(bool smoothRestore = true);
void Lock(); void Lock();
void Unlock(); void Unlock();
bool IsLocked() const { return _locked; } bool IsLocked() const { return _locked; }
void AddPitch(float a); void AddPitch(float a);
void AddYaw(float a); void AddYaw(float a);
void AddPitchFree(float a); void AddPitchFree(float a);
void AddYawFree(float a); void AddYawFree(float a);
float GetPitch() const { return _pitch; } float GetPitch() const { return _pitch; }
float GetYaw() const { return _yaw; } float GetYaw() const { return _yaw; }
RcMatrix3 GetMatrix() const { return _matrix; } RcMatrix3 GetMatrix() const { return _matrix; }
float GetOffsetStrength() const { return _offsetStrength; } float GetOffsetStrength() const { return _offsetStrength; }
void SetSpeed(float x) { _speed = x; } void SetSpeed(float x) { _speed = x; }
void SetMaxPitch(float a) { _maxPitch = a; } void SetMaxPitch(float a) { _maxPitch = a; }
}; };
VERUS_TYPEDEFS(Orbit); VERUS_TYPEDEFS(Orbit);
}
} }

View File

@ -1,49 +1,46 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Anim
{ {
namespace Anim // Shaker can load standard wav file, 8-bit mono, and use it as a function of time.
// Works well for camera's shaking effects.
class Shaker
{ {
// Shaker can load standard wav file, 8-bit mono, and use it as a function of time. String _url;
// Works well for camera's shaking effects. Vector<float> _vData;
class Shaker float _speed = 0;
{ float _offset = 0;
String _url; float _value = 0;
Vector<float> _vData; float _scale = 1;
float _speed = 0; float _bias = 0;
float _offset = 0; bool _looping = false;
float _value = 0;
float _scale = 1;
float _bias = 0;
bool _looping = false;
public: public:
Shaker(float speed = 400, bool looping = true) : _speed(speed), _looping(looping) {} Shaker(float speed = 400, bool looping = true) : _speed(speed), _looping(looping) {}
bool IsLoaded() const { return !_vData.empty(); } bool IsLoaded() const { return !_vData.empty(); }
void Load(CSZ url); void Load(CSZ url);
Str GetURL() const { return _C(_url); } Str GetURL() const { return _C(_url); }
void Update(); void Update();
void Reset() { _offset = 0; } void Reset() { _offset = 0; }
void Randomize(); void Randomize();
// Returns the current value in the range [-1 to 1]. // Returns the current value in the range [-1 to 1].
float Get(); float Get();
float GetSpeed() const { return _speed; } float GetSpeed() const { return _speed; }
void SetSpeed(float speed) { _speed = speed; } void SetSpeed(float speed) { _speed = speed; }
float GetScale() const { return _scale; } float GetScale() const { return _scale; }
void SetScale(float scale) { _scale = scale; } void SetScale(float scale) { _scale = scale; }
float GetBias() const { return _bias; } float GetBias() const { return _bias; }
void SetBias(float bias) { _bias = bias; } void SetBias(float bias) { _bias = bias; }
bool IsLooping() const { return _looping; } bool IsLooping() const { return _looping; }
void SetLooping(float looping) { _looping = looping; } void SetLooping(float looping) { _looping = looping; }
}; };
VERUS_TYPEDEFS(Shaker); VERUS_TYPEDEFS(Shaker);
}
} }

View File

@ -16,8 +16,8 @@ Skeleton::~Skeleton()
void Skeleton::operator=(RcSkeleton that) void Skeleton::operator=(RcSkeleton that)
{ {
Init(); Init();
for (const auto& kv : that._mapBones) for (const auto& [key, value] : that._mapBones)
_mapBones[kv.first] = kv.second; _mapBones[key] = value;
_primaryBoneCount = that._primaryBoneCount; _primaryBoneCount = that._primaryBoneCount;
} }
@ -36,9 +36,9 @@ void Skeleton::Draw(bool bindPose, PcTransform3 pMat, int selected)
{ {
VERUS_QREF_DD; VERUS_QREF_DD;
dd.Begin(CGI::DebugDraw::Type::lines, pMat, false); dd.Begin(CGI::DebugDraw::Type::lines, pMat, false);
for (const auto& kv : _mapBones) for (const auto& [key, value] : _mapBones)
{ {
PcBone pBone = &kv.second; PcBone pBone = &value;
PcBone pParent = FindBone(_C(pBone->_parentName)); PcBone pParent = FindBone(_C(pBone->_parentName));
if (pParent) if (pParent)
{ {
@ -58,9 +58,9 @@ void Skeleton::Draw(bool bindPose, PcTransform3 pMat, int selected)
} }
} }
} }
for (const auto& kv : _mapBones) for (const auto& [key, value] : _mapBones)
{ {
PcBone pBone = &kv.second; PcBone pBone = &value;
const Transform3 mat = bindPose ? pBone->_matFromBoneSpace : pBone->_matFinal * pBone->_matFromBoneSpace; const Transform3 mat = bindPose ? pBone->_matFromBoneSpace : pBone->_matFinal * pBone->_matFromBoneSpace;
const float scale = 0.04f; const float scale = 0.04f;
@ -122,10 +122,10 @@ Skeleton::PcBone Skeleton::FindBone(CSZ name) const
Skeleton::PBone Skeleton::FindBoneByIndex(int index) Skeleton::PBone Skeleton::FindBoneByIndex(int index)
{ {
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
if (kv.second._shaderIndex == index) if (value._shaderIndex == index)
return &kv.second; return &value;
} }
return nullptr; return nullptr;
} }
@ -134,9 +134,9 @@ void Skeleton::ApplyMotion(RMotion motion, float time, int layeredMotionCount, P
{ {
if (_ragdollMode) if (_ragdollMode)
{ {
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
RBone bone = kv.second; RBone bone = value;
if (bone._pRigidBody) if (bone._pRigidBody)
{ {
btTransform btr; btTransform btr;
@ -176,9 +176,9 @@ void Skeleton::ApplyMotion(RMotion motion, float time, int layeredMotionCount, P
_pLayeredMotions = pLayeredMotions; _pLayeredMotions = pLayeredMotions;
ResetBones(); ResetBones();
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
RBone bone = kv.second; RBone bone = value;
if (!bone._ready) if (!bone._ready)
{ {
_pCurrentBone = &bone; _pCurrentBone = &bone;
@ -198,9 +198,9 @@ void Skeleton::ApplyMotion(RMotion motion, float time, int layeredMotionCount, P
void Skeleton::UpdateUniformBufferArray(mataff* p) const void Skeleton::UpdateUniformBufferArray(mataff* p) const
{ {
for (const auto& kv : _mapBones) for (const auto& [key, value] : _mapBones)
{ {
RcBone bone = kv.second; RcBone bone = value;
if (bone._shaderIndex >= 0 && bone._shaderIndex < VERUS_MAX_BONES) if (bone._shaderIndex >= 0 && bone._shaderIndex < VERUS_MAX_BONES)
p[bone._shaderIndex] = bone._matFinal.UniformBufferFormat(); p[bone._shaderIndex] = bone._matFinal.UniformBufferFormat();
} }
@ -208,17 +208,17 @@ void Skeleton::UpdateUniformBufferArray(mataff* p) const
void Skeleton::ResetFinalPose() void Skeleton::ResetFinalPose()
{ {
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
kv.second._matFinal = Transform3::identity(); value._matFinal = Transform3::identity();
kv.second._matFinalInv = Transform3::identity(); value._matFinalInv = Transform3::identity();
} }
} }
void Skeleton::ResetBones() void Skeleton::ResetBones()
{ {
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
kv.second._ready = false; value._ready = false;
} }
void Skeleton::RecursiveBoneUpdate() void Skeleton::RecursiveBoneUpdate()
@ -300,8 +300,8 @@ void Skeleton::RecursiveBoneUpdate()
void Skeleton::InsertBonesIntoMotion(RMotion motion) const void Skeleton::InsertBonesIntoMotion(RMotion motion) const
{ {
for (const auto& kv : _mapBones) for (const auto& [key, value] : _mapBones)
motion.InsertBone(_C(kv.first)); motion.InsertBone(_C(key));
} }
void Skeleton::DeleteOutsiders(RMotion motion) const void Skeleton::DeleteOutsiders(RMotion motion) const
@ -332,9 +332,9 @@ void Skeleton::AdjustPrimaryBones(const Vector<String>& vPrimaryBones)
if (inverse) if (inverse)
std::swap(addPri, addSec); std::swap(addPri, addSec);
for (const auto& kv : _mapBones) for (const auto& [key, value] : _mapBones)
{ {
RcBone bone = kv.second; RcBone bone = value;
if (vPrimaryBones.end() != std::find(vPrimaryBones.begin(), vPrimaryBones.end(), bone._name)) if (vPrimaryBones.end() != std::find(vPrimaryBones.begin(), vPrimaryBones.end(), bone._name))
mapSort[bone._shaderIndex + addPri] = bone._name; mapSort[bone._shaderIndex + addPri] = bone._name;
else else
@ -343,11 +343,11 @@ void Skeleton::AdjustPrimaryBones(const Vector<String>& vPrimaryBones)
_primaryBoneCount = 0; _primaryBoneCount = 0;
for (const auto& kv : mapSort) for (const auto& [key, value] : mapSort)
{ {
if (kv.first < secondaryOffset) // Primary bone: if (key < secondaryOffset) // Primary bone:
{ {
PBone pBone = FindBone(_C(kv.second)); PBone pBone = FindBone(_C(value));
const int newIndex = Utils::Cast32(_mapPrimary.size()); const int newIndex = Utils::Cast32(_mapPrimary.size());
_mapPrimary[pBone->_shaderIndex] = newIndex; _mapPrimary[pBone->_shaderIndex] = newIndex;
pBone->_shaderIndex = newIndex; pBone->_shaderIndex = newIndex;
@ -355,7 +355,7 @@ void Skeleton::AdjustPrimaryBones(const Vector<String>& vPrimaryBones)
} }
else // Secondary bone: else // Secondary bone:
{ {
PBone pBone = FindBone(_C(kv.second)); PBone pBone = FindBone(_C(value));
PcBone pParent = FindBone(_C(pBone->_parentName)); PcBone pParent = FindBone(_C(pBone->_parentName));
bool isPrimary = false; bool isPrimary = false;
while (!isPrimary) while (!isPrimary)
@ -400,9 +400,9 @@ void Skeleton::LoadRigInfo(CSZ url)
void Skeleton::LoadRigInfoFromPtr(SZ p) void Skeleton::LoadRigInfoFromPtr(SZ p)
{ {
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
RBone bone = kv.second; RBone bone = value;
bone._rigRot = Vector3(0); bone._rigRot = Vector3(0);
bone._cRot = Vector3(0); bone._cRot = Vector3(0);
bone._cLimits = Vector3(0); bone._cLimits = Vector3(0);
@ -419,9 +419,9 @@ void Skeleton::LoadRigInfoFromPtr(SZ p)
float massCheck = 0; float massCheck = 0;
if (p) if (p)
{ {
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
RBone bone = kv.second; RBone bone = value;
bone._rigBone = false; bone._rigBone = false;
} }
@ -498,12 +498,12 @@ void Skeleton::BeginRagdoll(RcTransform3 matW, RcVector3 impulse, CSZ bone)
const float sleepL = 1.6f; const float sleepL = 1.6f;
const float sleepA = 2.5f; const float sleepA = 2.5f;
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
kv.second._ready = true; value._ready = true;
for (const auto& kv : _mapBones) for (const auto& [key, value] : _mapBones)
{ {
PcBone pBone = &kv.second; PcBone pBone = &value;
PBone pParent = FindBone(_C(pBone->_parentName)); PBone pParent = FindBone(_C(pBone->_parentName));
if (pParent && pParent->_rigBone && !pParent->_pShape) // Create a shape for parent bone: if (pParent && pParent->_rigBone && !pParent->_pShape) // Create a shape for parent bone:
@ -574,9 +574,9 @@ void Skeleton::BeginRagdoll(RcTransform3 matW, RcVector3 impulse, CSZ bone)
const Transform3 matInitC = Transform3::rotationZYX(Vector3(-VERUS_PI / 2, 0, -VERUS_PI / 2)); const Transform3 matInitC = Transform3::rotationZYX(Vector3(-VERUS_PI / 2, 0, -VERUS_PI / 2));
// Create leaf actors and joints: // Create leaf actors and joints:
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
PBone pBone = &kv.second; PBone pBone = &value;
PBone pParent = pBone; PBone pParent = pBone;
do do
{ {
@ -667,9 +667,9 @@ void Skeleton::EndRagdoll()
{ {
VERUS_QREF_BULLET; VERUS_QREF_BULLET;
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
RBone bone = kv.second; RBone bone = value;
if (bone._pConstraint) if (bone._pConstraint)
{ {
bullet.GetWorld()->removeConstraint(bone._pConstraint); bullet.GetWorld()->removeConstraint(bone._pConstraint);
@ -678,9 +678,9 @@ void Skeleton::EndRagdoll()
} }
} }
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
RBone bone = kv.second; RBone bone = value;
if (bone._pRigidBody) if (bone._pRigidBody)
{ {
bullet.GetWorld()->removeRigidBody(bone._pRigidBody); bullet.GetWorld()->removeRigidBody(bone._pRigidBody);
@ -700,9 +700,9 @@ void Skeleton::EndRagdoll()
void Skeleton::BakeMotion(RMotion motion, int frame, bool kinect) void Skeleton::BakeMotion(RMotion motion, int frame, bool kinect)
{ {
for (const auto& kv : _mapBones) for (const auto& [key, value] : _mapBones)
{ {
RcBone bone = kv.second; RcBone bone = value;
if (kinect && !IsKinectBone(_C(bone._name))) if (kinect && !IsKinectBone(_C(bone._name)))
continue; continue;
PcBone pParent = FindBone(_C(bone._parentName)); PcBone pParent = FindBone(_C(bone._parentName));
@ -792,9 +792,9 @@ void Skeleton::AdaptBindPoseOf(RcSkeleton that)
// TODO: improve. // TODO: improve.
const Point3 origin(0); const Point3 origin(0);
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
RBone boneDst = kv.second; RBone boneDst = value;
PBone pParentDst = FindBone(_C(boneDst._parentName)); PBone pParentDst = FindBone(_C(boneDst._parentName));
PcBone pBoneSrc = that.FindBone(_C(boneDst._name)); PcBone pBoneSrc = that.FindBone(_C(boneDst._name));
PcBone pParentSrc = pBoneSrc ? that.FindBone(_C(pBoneSrc->_parentName)) : nullptr; PcBone pParentSrc = pBoneSrc ? that.FindBone(_C(pBoneSrc->_parentName)) : nullptr;
@ -850,10 +850,10 @@ void Skeleton::SimpleIK(CSZ boneDriven, CSZ boneDriver, RcVector3 dirDriverSpace
void Skeleton::ProcessKinectData(const BYTE* p, RMotion motion, int frame) void Skeleton::ProcessKinectData(const BYTE* p, RMotion motion, int frame)
{ {
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
kv.second._matFinal = Transform3::identity(); value._matFinal = Transform3::identity();
kv.second._matExternal = Transform3::identity(); value._matExternal = Transform3::identity();
} }
UINT64 timestamp; UINT64 timestamp;
@ -925,9 +925,9 @@ void Skeleton::ProcessKinectData(const BYTE* p, RMotion motion, int frame)
shTwist *= 1 - abs(shAxis.getY()); shTwist *= 1 - abs(shAxis.getY());
} }
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
RBone bone = kv.second; RBone bone = value;
if (!IsKinectBone(_C(bone._name))) if (!IsKinectBone(_C(bone._name)))
continue; continue;
#if 0 #if 0
@ -970,9 +970,9 @@ void Skeleton::ProcessKinectData(const BYTE* p, RMotion motion, int frame)
VERUS_FOR(i, 4) VERUS_FOR(i, 4)
{ {
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
RBone bone = kv.second; RBone bone = value;
if (IsKinectBone(_C(bone._name)) && !IsKinectLeafBone(_C(bone._name))) if (IsKinectBone(_C(bone._name)) && !IsKinectLeafBone(_C(bone._name)))
continue; continue;
PBone pParent = FindBone(_C(bone._parentName)); PBone pParent = FindBone(_C(bone._parentName));
@ -985,10 +985,10 @@ void Skeleton::ProcessKinectData(const BYTE* p, RMotion motion, int frame)
BakeMotion(motion, frame, true); BakeMotion(motion, frame, true);
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
kv.second._matFinal = Transform3::identity(); value._matFinal = Transform3::identity();
kv.second._matExternal = Transform3::identity(); value._matExternal = Transform3::identity();
} }
} }
@ -1033,9 +1033,9 @@ void Skeleton::LoadKinectBindPose(CSZ xml)
mapData[pElem->Attribute("n")] = pos; mapData[pElem->Attribute("n")] = pos;
} }
for (const auto& kv : _mapBones) for (const auto& [key, value] : _mapBones)
{ {
RBone bone = kv.second; RBone bone = value;
if (!IsKinectBone(_C(bone._name))) if (!IsKinectBone(_C(bone._name)))
continue; continue;
PBone pParent = FindBone(_C(bone._parentName)); PBone pParent = FindBone(_C(bone._parentName));
@ -1229,9 +1229,9 @@ Vector3 Skeleton::GetHighestSpeed(RMotion motion, CSZ name, RcVector3 scale, boo
void Skeleton::ComputeBoneLengths(Map<String, float>& m, bool accumulated) void Skeleton::ComputeBoneLengths(Map<String, float>& m, bool accumulated)
{ {
for (auto& kv : _mapBones) for (auto& [key, value] : _mapBones)
{ {
RcBone bone = kv.second; RcBone bone = value;
PcBone pParentBone = FindBone(_C(bone._parentName)); PcBone pParentBone = FindBone(_C(bone._parentName));
float len = 0; float len = 0;
if (pParentBone) if (pParentBone)
@ -1261,7 +1261,7 @@ void Skeleton::ComputeBoneLengths(Map<String, float>& m, bool accumulated)
} }
if (accumulated) // Add leaf bone lengths? if (accumulated) // Add leaf bone lengths?
{ {
for (auto& kv : m) for (auto& [key, value] : m)
kv.second += 0.02f; value += 0.02f;
} }
} }

View File

@ -1,163 +1,160 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Anim
{ {
namespace Anim // Standard skeleton, which can be animated using motion object.
// X3D format can support up to 256 bones, but the hardware has certain limitations.
// With Shader Model 2.0 the shader can hold about 32 bone matrices.
// Other bones must be remapped using Primary Bones concept.
// Layered motions add the ability to mix multiple motions, just like images are mixed with alpha channel.
// Layered motion affects it's root bone and all descendants of that bone.
// A ragdoll can be created automatically or configured using XML .rig file.
// Ragdoll's simulation can start from any motion frame and any simulated pose can be baked back into motion object,
// allowing smooth transition to ragdoll simulation and back to motion.
class Skeleton : public Object
{ {
// Standard skeleton, which can be animated using motion object. public:
// X3D format can support up to 256 bones, but the hardware has certain limitations. struct LayeredMotion
// With Shader Model 2.0 the shader can hold about 32 bone matrices.
// Other bones must be remapped using Primary Bones concept.
// Layered motions add the ability to mix multiple motions, just like images are mixed with alpha channel.
// Layered motion affects it's root bone and all descendants of that bone.
// A ragdoll can be created automatically or configured using XML .rig file.
// Ragdoll's simulation can start from any motion frame and any simulated pose can be baked back into motion object,
// allowing smooth transition to ragdoll simulation and back to motion.
class Skeleton : public Object
{ {
public: PMotion _pMotion = nullptr;
struct LayeredMotion CSZ _rootBone = nullptr;
{ float _alpha = 0;
PMotion _pMotion = nullptr; float _time = 0;
CSZ _rootBone = nullptr;
float _alpha = 0;
float _time = 0;
};
VERUS_TYPEDEFS(LayeredMotion);
struct Bone : AllocatorAware
{
Transform3 _matToBoneSpace = Transform3::identity();
Transform3 _matFromBoneSpace = Transform3::identity();
Transform3 _matFinal = Transform3::identity();
Transform3 _matFinalInv = Transform3::identity();
Transform3 _matExternal = Transform3::identity();
Transform3 _matAdapt = Transform3::identity();
Transform3 _matToActorSpace = Transform3::identity();
Vector3 _rigRot = Vector3(0); // Rotation angles of ragdoll's rigid component.
Vector3 _cRot = Vector3(0); // Constraint's rotation angles.
Vector3 _cLimits = Vector3(0); // Constraint's limits.
Vector3 _boxSize = Vector3(0); // For a box shape.
String _name;
String _parentName;
btCollisionShape* _pShape = nullptr;
btRigidBody* _pRigidBody = nullptr;
btTypedConstraint* _pConstraint = nullptr;
float _width = 0;
float _length = 0;
float _mass = 0;
float _friction = 0;
int _shaderIndex = 0; // Index of a matrix in the vertex shader.
bool _ready = false;
bool _rigBone = true;
bool _hinge = false; // btHingeConstraint vs btConeTwistConstraint.
bool _noCollision = false;
};
VERUS_TYPEDEFS(Bone);
private:
typedef Map<String, Bone> TMapBones;
typedef Map<int, int> TMapPrimary;
Transform3 _matParents = Transform3::identity();
Transform3 _matRagdollToWorld = Transform3::identity();
Transform3 _matRagdollToWorldInv = Transform3::identity();
TMapBones _mapBones;
TMapPrimary _mapPrimary;
PBone _pCurrentBone = nullptr;
PMotion _pCurrentMotion = nullptr;
PLayeredMotion _pLayeredMotions = nullptr;
float _currentTime = 0;
float _mass = 0;
int _primaryBoneCount = 0;
int _layeredMotionCount = 0;
bool _ragdollMode = false;
public:
Skeleton();
~Skeleton();
void operator=(const Skeleton& that);
void Init();
void Done();
void Draw(bool bindPose = true, PcTransform3 pMat = nullptr, int selected = -1);
static CSZ RootName() { return "$ROOT"; }
PBone InsertBone(RBone bone);
PBone FindBone(CSZ name);
PcBone FindBone(CSZ name) const;
// Uses shader's array index to find a bone.
PBone FindBoneByIndex(int index);
// Sets the current pose using motion object (Motion).
void ApplyMotion(RMotion motion, float time,
int layeredMotionCount = 0, PLayeredMotion pLayeredMotions = nullptr);
// Fills the array of matrices that will be used by a shader.
void UpdateUniformBufferArray(mataff* p) const;
void ResetFinalPose();
VERUS_P(void ResetBones());
VERUS_P(void RecursiveBoneUpdate());
int GetBoneCount() const { return _primaryBoneCount ? _primaryBoneCount : Utils::Cast32(_mapBones.size()); }
template<typename F>
void ForEachBone(const F& fn)
{
for (auto& kv : _mapBones)
if (Continue::no == fn(kv.second))
return;
}
template<typename F>
void ForEachBone(const F& fn) const
{
for (const auto& kv : _mapBones)
if (Continue::no == fn(kv.second))
return;
}
// Adds skeleton's bones to motion object (Motion).
void InsertBonesIntoMotion(RMotion motion) const;
// Removes motion's bones, which are not skeleton's bones.
void DeleteOutsiders(RMotion motion) const;
void AdjustPrimaryBones(const Vector<String>& vPrimaryBones);
int RemapBoneIndex(int index) const;
bool IsParentOf(CSZ bone, CSZ parent) const;
void LoadRigInfo(CSZ url);
void LoadRigInfoFromPtr(SZ p);
void BeginRagdoll(RcTransform3 matW, RcVector3 impulse = Vector3(0), CSZ bone = "Spine2");
void EndRagdoll();
bool IsRagdollMode() const { return _ragdollMode; }
RcTransform3 GetRagdollToWorldMatrix() { return _matRagdollToWorld; }
// Saves the current pose into motion object (Motion) at some frame.
void BakeMotion(RMotion motion, int frame = 0, bool kinect = false);
void AdaptBindPoseOf(const Skeleton& that);
void SimpleIK(CSZ boneDriven, CSZ boneDriver, RcVector3 dirDriverSpace, RcVector3 dirDesiredMeshSpace, float limitDot, float alpha);
void ProcessKinectData(const BYTE* p, RMotion motion, int frame = 0);
void ProcessKinectJoint(const BYTE* p, CSZ name, RcVector3 skeletonPos);
void LoadKinectBindPose(CSZ xml);
static bool IsKinectBone(CSZ name);
static bool IsKinectLeafBone(CSZ name);
void FixateFeet(RMotion motion);
// Tries to compute the highest speed at which a bone would move with this motion applied.
// Can be used to sync animation and movement to fix the sliding feet problem.
Vector3 GetHighestSpeed(RMotion motion, CSZ name, RcVector3 scale = Vector3(1, 0, 1), bool positive = false);
void ComputeBoneLengths(Map<String, float>& m, bool accumulated = false);
}; };
VERUS_TYPEDEFS(Skeleton); VERUS_TYPEDEFS(LayeredMotion);
}
struct Bone : AllocatorAware
{
Transform3 _matToBoneSpace = Transform3::identity();
Transform3 _matFromBoneSpace = Transform3::identity();
Transform3 _matFinal = Transform3::identity();
Transform3 _matFinalInv = Transform3::identity();
Transform3 _matExternal = Transform3::identity();
Transform3 _matAdapt = Transform3::identity();
Transform3 _matToActorSpace = Transform3::identity();
Vector3 _rigRot = Vector3(0); // Rotation angles of ragdoll's rigid component.
Vector3 _cRot = Vector3(0); // Constraint's rotation angles.
Vector3 _cLimits = Vector3(0); // Constraint's limits.
Vector3 _boxSize = Vector3(0); // For a box shape.
String _name;
String _parentName;
btCollisionShape* _pShape = nullptr;
btRigidBody* _pRigidBody = nullptr;
btTypedConstraint* _pConstraint = nullptr;
float _width = 0;
float _length = 0;
float _mass = 0;
float _friction = 0;
int _shaderIndex = 0; // Index of a matrix in the vertex shader.
bool _ready = false;
bool _rigBone = true;
bool _hinge = false; // btHingeConstraint vs btConeTwistConstraint.
bool _noCollision = false;
};
VERUS_TYPEDEFS(Bone);
private:
typedef Map<String, Bone> TMapBones;
typedef Map<int, int> TMapPrimary;
Transform3 _matParents = Transform3::identity();
Transform3 _matRagdollToWorld = Transform3::identity();
Transform3 _matRagdollToWorldInv = Transform3::identity();
TMapBones _mapBones;
TMapPrimary _mapPrimary;
PBone _pCurrentBone = nullptr;
PMotion _pCurrentMotion = nullptr;
PLayeredMotion _pLayeredMotions = nullptr;
float _currentTime = 0;
float _mass = 0;
int _primaryBoneCount = 0;
int _layeredMotionCount = 0;
bool _ragdollMode = false;
public:
Skeleton();
~Skeleton();
void operator=(const Skeleton& that);
void Init();
void Done();
void Draw(bool bindPose = true, PcTransform3 pMat = nullptr, int selected = -1);
static CSZ RootName() { return "$ROOT"; }
PBone InsertBone(RBone bone);
PBone FindBone(CSZ name);
PcBone FindBone(CSZ name) const;
// Uses shader's array index to find a bone.
PBone FindBoneByIndex(int index);
// Sets the current pose using motion object (Motion).
void ApplyMotion(RMotion motion, float time,
int layeredMotionCount = 0, PLayeredMotion pLayeredMotions = nullptr);
// Fills the array of matrices that will be used by a shader.
void UpdateUniformBufferArray(mataff* p) const;
void ResetFinalPose();
VERUS_P(void ResetBones());
VERUS_P(void RecursiveBoneUpdate());
int GetBoneCount() const { return _primaryBoneCount ? _primaryBoneCount : Utils::Cast32(_mapBones.size()); }
template<typename F>
void ForEachBone(const F& fn)
{
for (auto& [key, value] : _mapBones)
if (Continue::no == fn(value))
return;
}
template<typename F>
void ForEachBone(const F& fn) const
{
for (const auto& [key, value] : _mapBones)
if (Continue::no == fn(value))
return;
}
// Adds skeleton's bones to motion object (Motion).
void InsertBonesIntoMotion(RMotion motion) const;
// Removes motion's bones, which are not skeleton's bones.
void DeleteOutsiders(RMotion motion) const;
void AdjustPrimaryBones(const Vector<String>& vPrimaryBones);
int RemapBoneIndex(int index) const;
bool IsParentOf(CSZ bone, CSZ parent) const;
void LoadRigInfo(CSZ url);
void LoadRigInfoFromPtr(SZ p);
void BeginRagdoll(RcTransform3 matW, RcVector3 impulse = Vector3(0), CSZ bone = "Spine2");
void EndRagdoll();
bool IsRagdollMode() const { return _ragdollMode; }
RcTransform3 GetRagdollToWorldMatrix() { return _matRagdollToWorld; }
// Saves the current pose into motion object (Motion) at some frame.
void BakeMotion(RMotion motion, int frame = 0, bool kinect = false);
void AdaptBindPoseOf(const Skeleton& that);
void SimpleIK(CSZ boneDriven, CSZ boneDriver, RcVector3 dirDriverSpace, RcVector3 dirDesiredMeshSpace, float limitDot, float alpha);
void ProcessKinectData(const BYTE* p, RMotion motion, int frame = 0);
void ProcessKinectJoint(const BYTE* p, CSZ name, RcVector3 skeletonPos);
void LoadKinectBindPose(CSZ xml);
static bool IsKinectBone(CSZ name);
static bool IsKinectLeafBone(CSZ name);
void FixateFeet(RMotion motion);
// Tries to compute the highest speed at which a bone would move with this motion applied.
// Can be used to sync animation and movement to fix the sliding feet problem.
Vector3 GetHighestSpeed(RMotion motion, CSZ name, RcVector3 scale = Vector3(1, 0, 1), bool positive = false);
void ComputeBoneLengths(Map<String, float>& m, bool accumulated = false);
};
VERUS_TYPEDEFS(Skeleton);
} }

View File

@ -1,83 +1,80 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Anim
{ {
namespace Anim // Warp manages sphere-based deformations to create such effects like dangling and speech.
// Any other part of the mesh can also be deformed.
// Warp's zone objects can use motion object or can simulate spring physics,
// for example to simulate female's breast.
// Warp class includes a function to convert special audio files to motion.
// If there is a filename.wav, containing character's speech, some additional files must be created:
// 1. filename_Jaw.wav; effects: Stretch 400, Dynamic 10 Gate, 8000 8-bit.
// 2. filename_O.wav; effects: Low pass 5000Hz, Keep O noise, Dynamic 10 Gate, 8000 8-bit.
// 3. filename_S.wav; effects: Keep S noise, Dynamic 10 Gate, Stretch 400, 8000 8-bit.
// Motion should be applied to the skeleton before it will be used in Update() method.
// Then _skeletonReady can be set to true for the mesh.
class Warp : public Object
{ {
// Warp manages sphere-based deformations to create such effects like dangling and speech. public:
// Any other part of the mesh can also be deformed. typedef Map<String, Vector3> TMapOffsets;
// Warp's zone objects can use motion object or can simulate spring physics, class Zone
// for example to simulate female's breast.
// Warp class includes a function to convert special audio files to motion.
// If there is a filename.wav, containing character's speech, some additional files must be created:
// 1. filename_Jaw.wav; effects: Stretch 400, Dynamic 10 Gate, 8000 8-bit.
// 2. filename_O.wav; effects: Low pass 5000Hz, Keep O noise, Dynamic 10 Gate, 8000 8-bit.
// 3. filename_S.wav; effects: Keep S noise, Dynamic 10 Gate, Stretch 400, 8000 8-bit.
// Motion should be applied to the skeleton before it will be used in Update() method.
// Then _skeletonReady can be set to true for the mesh.
class Warp : public Object
{ {
public: public:
typedef Map<String, Vector3> TMapOffsets; Point3 _pos = Point3(0);
class Zone Point3 _posW = Point3(0);
{ Vector3 _vel = Vector3(0);
public: Vector3 _off = Vector3(0);
Point3 _pos = Point3(0); String _name;
Point3 _posW = Point3(0); String _bone;
Vector3 _vel = Vector3(0); TMapOffsets _mapOffsets;
Vector3 _off = Vector3(0); float _radius = 0;
String _name; float _spring = 0;
String _bone; float _damping = 5;
TMapOffsets _mapOffsets; float _maxOffset = 0;
float _radius = 0; char _type = 0;
float _spring = 0;
float _damping = 5;
float _maxOffset = 0;
char _type = 0;
};
VERUS_TYPEDEFS(Zone);
private:
Vector<Zone> _vZones;
String _preview;
float _yMin = FLT_MAX;
float _jawScale = 1;
public:
Warp();
~Warp();
void Init();
void Done();
void Update(RSkeleton skeleton);
void DrawLines() const;
void DrawZones() const;
void Load(CSZ url);
void LoadFromPtr(SZ p);
void Fill(PVector4 p);
void ApplyMotion(RMotion motion, float time);
static void ComputeLipSyncFromAudio(RcBlob blob, RMotion motion, float jawScale = 1);
float GetJawScale() const { return _jawScale; }
template<typename T>
void ForEachZone(const T& fn)
{
for (auto& zone : _vZones)
{
if (Continue::no == fn(zone))
break;
}
}
void SetPreview(CSZ preview) { _preview = preview; }
}; };
VERUS_TYPEDEFS(Warp); VERUS_TYPEDEFS(Zone);
}
private:
Vector<Zone> _vZones;
String _preview;
float _yMin = FLT_MAX;
float _jawScale = 1;
public:
Warp();
~Warp();
void Init();
void Done();
void Update(RSkeleton skeleton);
void DrawLines() const;
void DrawZones() const;
void Load(CSZ url);
void LoadFromPtr(SZ p);
void Fill(PVector4 p);
void ApplyMotion(RMotion motion, float time);
static void ComputeLipSyncFromAudio(RcBlob blob, RMotion motion, float jawScale = 1);
float GetJawScale() const { return _jawScale; }
template<typename T>
void ForEachZone(const T& fn)
{
for (auto& zone : _vZones)
{
if (Continue::no == fn(zone))
break;
}
}
void SetPreview(CSZ preview) { _preview = preview; }
};
VERUS_TYPEDEFS(Warp);
} }

View File

@ -11,10 +11,7 @@ namespace verus
void Free_App(); void Free_App();
} }
namespace verus namespace verus::App
{ {
namespace App void RunEventLoop();
{
void RunEventLoop();
}
} }

View File

@ -1,192 +1,189 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::App
{ {
namespace App enum class DisplayMode : int
{ {
enum class DisplayMode : int exclusiveFullscreen,
windowed,
borderlessWindowed
};
class Info
{
public:
CSZ _appName = nullptr;
UINT32 _appVersion = 0;
CSZ _engineName = nullptr;
UINT32 _engineVersion = 0;
};
VERUS_TYPEDEFS(Info);
class QualitySettings
{
public:
enum class OverallQuality : int
{ {
exclusiveFullscreen, custom,
windowed, low,
borderlessWindowed medium,
high,
ultra
}; };
class Info enum class Quality : int
{ {
public: low,
CSZ _appName = nullptr; medium,
UINT32 _appVersion = 0; high,
CSZ _engineName = nullptr; ultra
UINT32 _engineVersion = 0;
}; };
VERUS_TYPEDEFS(Info);
class QualitySettings enum class WaterQuality : int
{ {
public: solidColor,
enum class OverallQuality : int simpleReflection,
{ distortedReflection,
custom, trueWavesReflection,
low, trueWavesRefraction
medium,
high,
ultra
};
enum class Quality : int
{
low,
medium,
high,
ultra
};
enum class WaterQuality : int
{
solidColor,
simpleReflection,
distortedReflection,
trueWavesReflection,
trueWavesRefraction
};
public:
bool _displayOffscreenDraw = true;
float _displayOffscreenScale = 1;
int _gpuAnisotropyLevel = 4;
int _gpuAntiAliasingLevel = 0;
Quality _gpuShaderQuality = Quality::medium;
bool _gpuTessellation = false;
int _gpuTextureLodLevel = 0;
bool _gpuTrilinearFilter = true;
bool _postProcessAntiAliasing = false;
bool _postProcessBloom = true;
bool _postProcessCinema = false;
bool _postProcessLightShafts = true;
bool _postProcessMotionBlur = false;
bool _postProcessSSAO = true;
bool _postProcessSSR = false;
bool _sceneAmbientOcclusion = true;
int _sceneGrassDensity = 600;
Quality _sceneShadowQuality = Quality::medium;
WaterQuality _sceneWaterQuality = WaterQuality::solidColor;
bool operator==(const QualitySettings& that) const;
bool operator!=(const QualitySettings& that) const;
void SetQuality(OverallQuality q);
void SetXrQuality();
OverallQuality DetectQuality() const;
}; };
VERUS_TYPEDEFS(QualitySettings);
// Capacity is per frame. 3 frames are buffered. public:
class Limits bool _displayOffscreenDraw = true;
float _displayOffscreenScale = 1;
int _gpuAnisotropyLevel = 4;
int _gpuAntiAliasingLevel = 0;
Quality _gpuShaderQuality = Quality::medium;
bool _gpuTessellation = false;
int _gpuTextureLodLevel = 0;
bool _gpuTrilinearFilter = true;
bool _postProcessAntiAliasing = false;
bool _postProcessBloom = true;
bool _postProcessCinema = false;
bool _postProcessLightShafts = true;
bool _postProcessMotionBlur = false;
bool _postProcessSSAO = true;
bool _postProcessSSR = false;
bool _sceneAmbientOcclusion = true;
int _sceneGrassDensity = 600;
Quality _sceneShadowQuality = Quality::medium;
WaterQuality _sceneWaterQuality = WaterQuality::solidColor;
bool operator==(const QualitySettings& that) const;
bool operator!=(const QualitySettings& that) const;
void SetQuality(OverallQuality q);
void SetXrQuality();
OverallQuality DetectQuality() const;
};
VERUS_TYPEDEFS(QualitySettings);
// Capacity is per frame. 3 frames are buffered.
class Limits
{
public:
int _d3d12_dhViewsCapacity = 50000; // D3D limit is one million.
int _d3d12_dhSamplersCapacity = 500; // D3D limit is 2048.
int _ds_ubViewCapacity = 20;
int _ds_ubSubpassFSCapacity = 20;
int _ds_ubShadowFSCapacity = 50;
int _ds_ubMeshVSCapacity = 20;
int _forest_ubVSCapacity = 200;
int _forest_ubFSCapacity = 200;
int _generateMips_ubCapacity = 50;
int _generateCubeMapMips_ubCapacity = 50;
int _grass_ubVSCapacity = 20;
int _grass_ubFSCapacity = 20;
int _gui_ubGuiCapacity = 100;
int _gui_ubGuiFSCapacity = 100;
int _mesh_ubViewCapacity = 800;
int _mesh_ubMaterialFSCapacity = 1000;
int _mesh_ubMeshVSCapacity = 2000;
int _mesh_ubSkeletonVSCapacity = 200;
int _particles_ubVSCapacity = 100;
int _particles_ubFSCapacity = 100;
int _quad_ubVSCapacity = 20;
int _quad_ubFSCapacity = 20;
int _sky_ubViewCapacity = 80;
int _sky_ubMaterialFSCapacity = 80;
int _sky_ubMeshVSCapacity = 80;
int _sky_ubObjectCapacity = 80;
int _terrain_ubVSCapacity = 40;
int _terrain_ubFSCapacity = 40;
int _water_ubVSCapacity = 20;
int _water_ubFSCapacity = 20;
};
VERUS_TYPEDEFS(Limits);
class Settings : public QualitySettings, public Singleton<Settings>, IO::Json
{
typedef Map<String, String> TMapLocalizedStrings;
TMapLocalizedStrings _mapLocalizedStrings;
public:
struct CommandLine
{ {
public: int _gapi = -1;
int _d3d12_dhViewsCapacity = 50000; // D3D limit is one million. int _openXR = -1;
int _d3d12_dhSamplersCapacity = 500; // D3D limit is 2048. float _xrHeight = -FLT_MAX;
int _ds_ubViewCapacity = 20; bool _exclusiveFullscreen = false;
int _ds_ubSubpassFSCapacity = 20; bool _windowed = false;
int _ds_ubShadowFSCapacity = 50; bool _borderlessWindowed = false;
int _ds_ubMeshVSCapacity = 20; bool _restarted = false;
int _forest_ubVSCapacity = 200;
int _forest_ubFSCapacity = 200;
int _generateMips_ubCapacity = 50;
int _generateCubeMapMips_ubCapacity = 50;
int _grass_ubVSCapacity = 20;
int _grass_ubFSCapacity = 20;
int _gui_ubGuiCapacity = 100;
int _gui_ubGuiFSCapacity = 100;
int _mesh_ubViewCapacity = 800;
int _mesh_ubMaterialFSCapacity = 1000;
int _mesh_ubMeshVSCapacity = 2000;
int _mesh_ubSkeletonVSCapacity = 200;
int _particles_ubVSCapacity = 100;
int _particles_ubFSCapacity = 100;
int _quad_ubVSCapacity = 20;
int _quad_ubFSCapacity = 20;
int _sky_ubViewCapacity = 80;
int _sky_ubMaterialFSCapacity = 80;
int _sky_ubMeshVSCapacity = 80;
int _sky_ubObjectCapacity = 80;
int _terrain_ubVSCapacity = 40;
int _terrain_ubFSCapacity = 40;
int _water_ubVSCapacity = 20;
int _water_ubFSCapacity = 20;
}; };
VERUS_TYPEDEFS(Limits);
class Settings : public QualitySettings, public Singleton<Settings>, IO::Json enum Platform : int
{ {
typedef Map<String, String> TMapLocalizedStrings; classic,
uwp
TMapLocalizedStrings _mapLocalizedStrings;
public:
struct CommandLine
{
int _gapi = -1;
int _openXR = -1;
float _xrHeight = -FLT_MAX;
bool _exclusiveFullscreen = false;
bool _windowed = false;
bool _borderlessWindowed = false;
bool _restarted = false;
};
enum Platform : int
{
classic,
uwp
};
bool _displayAllowHighDPI = true;
float _displayFOV = 70;
DisplayMode _displayMode = DisplayMode::windowed;
int _displaySizeHeight = 720;
int _displaySizeWidth = 1280;
bool _displayVSync = true;
int _gapi = 0;
float _inputMouseSensitivity = 1;
bool _openXR = false;
bool _physicsSupportDebugDraw = false;
String _uiLang = "EN";
float _xrFOV = 110;
float _xrHeight = 0;
CommandLine _commandLine;
Limits _limits;
String _imguiFont;
Info _info;
float _highDpiScale = 1;
Platform _platform = Platform::classic;
Settings();
~Settings();
void ParseCommandLineArgs(int argc, wchar_t* argv[]);
void ParseCommandLineArgs(int argc, char* argv[]);
void Load();
void HandleHighDpi();
void HandleCommandLineArgs();
void Validate();
void Save();
void MatchScreen();
RcLimits GetLimits() const { return _limits; }
void LoadLocalizedStrings(CSZ url);
CSZ GetLocalizedString(CSZ id) const;
void UpdateHighDpiScale();
int GetFontSize() const;
int Scale(int size, float extraScale = 1) const;
float GetScale() const;
}; };
VERUS_TYPEDEFS(Settings);
} bool _displayAllowHighDPI = true;
float _displayFOV = 70;
DisplayMode _displayMode = DisplayMode::windowed;
int _displaySizeHeight = 720;
int _displaySizeWidth = 1280;
bool _displayVSync = true;
int _gapi = 0;
float _inputMouseSensitivity = 1;
bool _openXR = false;
bool _physicsSupportDebugDraw = false;
String _uiLang = "EN";
float _xrFOV = 110;
float _xrHeight = 0;
CommandLine _commandLine;
Limits _limits;
String _imguiFont;
Info _info;
float _highDpiScale = 1;
Platform _platform = Platform::classic;
Settings();
~Settings();
void ParseCommandLineArgs(int argc, wchar_t* argv[]);
void ParseCommandLineArgs(int argc, char* argv[]);
void Load();
void HandleHighDpi();
void HandleCommandLineArgs();
void Validate();
void Save();
void MatchScreen();
RcLimits GetLimits() const { return _limits; }
void LoadLocalizedStrings(CSZ url);
CSZ GetLocalizedString(CSZ id) const;
void UpdateHighDpiScale();
int GetFontSize() const;
int Scale(int size, float extraScale = 1) const;
float GetScale() const;
};
VERUS_TYPEDEFS(Settings);
} }

View File

@ -1,71 +1,68 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::App
{ {
namespace App class UndoManager : public Object
{ {
class UndoManager : public Object public:
class Command
{ {
public: bool _hasRedo = false;
class Command
{
bool _hasRedo = false;
public:
virtual ~Command() {}
virtual void SaveState(bool forUndo = false) = 0;
virtual void Undo() = 0;
virtual void Redo() = 0;
virtual Str GetName() const { return ""; }
virtual bool IsValid() const { return true; }
bool HasRedo() const { return _hasRedo; }
void SetHasRedo(bool hasRedo) { _hasRedo = hasRedo; };
};
VERUS_TYPEDEFS(Command);
private:
Vector<PCommand> _vCommands;
int _maxCommands = 30;
int _nextUndo = 0;
public: public:
UndoManager(); virtual ~Command() {}
~UndoManager(); virtual void SaveState(bool forUndo = false) = 0;
virtual void Undo() = 0;
void Init(int maxCommands = 30); virtual void Redo() = 0;
void Done(); virtual Str GetName() const { return ""; }
virtual bool IsValid() const { return true; }
int GetMaxCommands() const { return _maxCommands; } bool HasRedo() const { return _hasRedo; }
void SetMaxCommands(int maxCommands); void SetHasRedo(bool hasRedo) { _hasRedo = hasRedo; };
int GetCommandCount() const { return Utils::Cast32(_vCommands.size()); }
void Undo();
void Redo();
bool CanUndo() const;
bool CanRedo() const;
PCommand BeginChange(PCommand pCommand);
PCommand EndChange(PCommand pCommand = nullptr);
void DeleteInvalidCommands();
template<typename T>
void ForEachCommand(const T& fn)
{
int i = 0;
for (auto& x : _vCommands)
{
if (Continue::no == fn(x, i < _nextUndo))
return;
i++;
}
}
int GetNextUndo() const { return _nextUndo; }
}; };
VERUS_TYPEDEFS(UndoManager); VERUS_TYPEDEFS(Command);
}
private:
Vector<PCommand> _vCommands;
int _maxCommands = 30;
int _nextUndo = 0;
public:
UndoManager();
~UndoManager();
void Init(int maxCommands = 30);
void Done();
int GetMaxCommands() const { return _maxCommands; }
void SetMaxCommands(int maxCommands);
int GetCommandCount() const { return Utils::Cast32(_vCommands.size()); }
void Undo();
void Redo();
bool CanUndo() const;
bool CanRedo() const;
PCommand BeginChange(PCommand pCommand);
PCommand EndChange(PCommand pCommand = nullptr);
void DeleteInvalidCommands();
template<typename T>
void ForEachCommand(const T& fn)
{
int i = 0;
for (auto& x : _vCommands)
{
if (Continue::no == fn(x, i < _nextUndo))
return;
i++;
}
}
int GetNextUndo() const { return _nextUndo; }
};
VERUS_TYPEDEFS(UndoManager);
} }

View File

@ -1,41 +1,38 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::App
{ {
namespace App class Window : public Object
{ {
class Window : public Object SDL_Window* _pWnd = nullptr;
public:
struct Desc
{ {
SDL_Window* _pWnd = nullptr; CSZ _title = nullptr;
int _x = SDL_WINDOWPOS_CENTERED;
int _y = SDL_WINDOWPOS_CENTERED;
int _width = 0;
int _height = 0;
Uint32 _flags = 0;
DisplayMode _displayMode = DisplayMode::windowed;
UINT32 _color = VERUS_COLOR_BLACK;
bool _resizable = true;
bool _maximized = false;
bool _useSettings = true;
public: void ApplySettings();
struct Desc
{
CSZ _title = nullptr;
int _x = SDL_WINDOWPOS_CENTERED;
int _y = SDL_WINDOWPOS_CENTERED;
int _width = 0;
int _height = 0;
Uint32 _flags = 0;
DisplayMode _displayMode = DisplayMode::windowed;
UINT32 _color = VERUS_COLOR_BLACK;
bool _resizable = true;
bool _maximized = false;
bool _useSettings = true;
void ApplySettings();
};
VERUS_TYPEDEFS(Desc);
Window();
~Window();
void Init(RcDesc desc = Desc());
void Done();
SDL_Window* GetSDL() const { return _pWnd; }
}; };
VERUS_TYPEDEFS(Window); VERUS_TYPEDEFS(Desc);
}
Window();
~Window();
void Init(RcDesc desc = Desc());
void Done();
SDL_Window* GetSDL() const { return _pWnd; }
};
VERUS_TYPEDEFS(Window);
} }

View File

@ -68,14 +68,14 @@ void AudioSystem::Update()
_streamPlayers[i].Update(); _streamPlayers[i].Update();
// Update every frame: // Update every frame:
for (auto& x : TStoreSounds::_map) for (auto& [key, value] : TStoreSounds::_map)
x.second.Update(); value.Update();
// Update ~15 times per second: // Update ~15 times per second:
if (timer.IsEventEvery(67)) if (timer.IsEventEvery(67))
{ {
for (auto& x : TStoreSounds::_map) for (auto& [key, value] : TStoreSounds::_map)
x.second.UpdateHRTF(); value.UpdateHRTF();
if (VMath::lengthSqr(_listenerDirection) > 0.1f && if (VMath::lengthSqr(_listenerDirection) > 0.1f &&
VMath::lengthSqr(_listenerUp) > 0.1f) VMath::lengthSqr(_listenerUp) > 0.1f)

View File

@ -1,45 +1,42 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Audio
{ {
namespace Audio typedef StoreUnique<String, Sound> TStoreSounds;
class AudioSystem : public Singleton<AudioSystem>, public Object, private TStoreSounds
{ {
typedef StoreUnique<String, Sound> TStoreSounds; Point3 _listenerPosition = Point3(0);
class AudioSystem : public Singleton<AudioSystem>, public Object, private TStoreSounds Vector3 _listenerDirection = Vector3(0, 0, 1);
{ Vector3 _listenerVelocity = Vector3(0);
Point3 _listenerPosition = Point3(0); Vector3 _listenerUp = Vector3(0, 1, 0);
Vector3 _listenerDirection = Vector3(0, 0, 1); ALCdevice* _pDevice = nullptr;
Vector3 _listenerVelocity = Vector3(0); ALCcontext* _pContext = nullptr;
Vector3 _listenerUp = Vector3(0, 1, 0); String _version;
ALCdevice* _pDevice = nullptr; String _deviceSpecifier;
ALCcontext* _pContext = nullptr; StreamPlayer _streamPlayers[4];
String _version;
String _deviceSpecifier;
StreamPlayer _streamPlayers[4];
public: public:
AudioSystem(); AudioSystem();
~AudioSystem(); ~AudioSystem();
void Init(); void Init();
void Done(); void Done();
void Update(); void Update();
RStreamPlayer GetStreamPlayer(int index) { return _streamPlayers[index]; } RStreamPlayer GetStreamPlayer(int index) { return _streamPlayers[index]; }
void DeleteAllStreams(); void DeleteAllStreams();
PSound InsertSound(CSZ url); PSound InsertSound(CSZ url);
PSound FindSound(CSZ url); PSound FindSound(CSZ url);
void DeleteSound(CSZ url); void DeleteSound(CSZ url);
void DeleteAllSounds(); void DeleteAllSounds();
void UpdateListener(RcPoint3 pos, RcVector3 dir, RcVector3 vel, RcVector3 up); void UpdateListener(RcPoint3 pos, RcVector3 dir, RcVector3 vel, RcVector3 up);
float ComputeTravelDelay(RcPoint3 pos) const; float ComputeTravelDelay(RcPoint3 pos) const;
static CSZ GetSingletonFailMessage() { return "Make_Audio(); // FAIL.\r\n"; } static CSZ GetSingletonFailMessage() { return "Make_Audio(); // FAIL.\r\n"; }
}; };
VERUS_TYPEDEFS(AudioSystem); VERUS_TYPEDEFS(AudioSystem);
}
} }

View File

@ -1,47 +1,44 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#include "verus.h" #include "verus.h"
namespace verus namespace verus::Audio
{ {
namespace Audio size_t read_func(void* ptr, size_t size, size_t nmemb, void* datasource)
{ {
size_t read_func(void* ptr, size_t size, size_t nmemb, void* datasource) POggDataSource pDS = static_cast<POggDataSource>(datasource);
{ INT64 readLen = size * nmemb;
POggDataSource pDS = static_cast<POggDataSource>(datasource); const INT64 maxLen = pDS->_size - pDS->_cursor;
INT64 readLen = size * nmemb; if (readLen > maxLen)
const INT64 maxLen = pDS->_size - pDS->_cursor; readLen = maxLen;
if (readLen > maxLen) memcpy(ptr, pDS->_p + pDS->_cursor, size_t(readLen));
readLen = maxLen; pDS->_cursor += readLen;
memcpy(ptr, pDS->_p + pDS->_cursor, size_t(readLen)); return size_t(readLen);
pDS->_cursor += readLen;
return size_t(readLen);
}
int seek_func(void* datasource, ogg_int64_t offset, int whence)
{
POggDataSource pDS = static_cast<POggDataSource>(datasource);
switch (whence)
{
case SEEK_SET: pDS->_cursor = offset; return 0;
case SEEK_CUR: pDS->_cursor += offset; return 0;
case SEEK_END: pDS->_cursor = pDS->_size - offset; return 0;
}
return -1;
}
int close_func(void* datasource)
{
POggDataSource pDS = static_cast<POggDataSource>(datasource);
pDS->_cursor = 0;
return 0;
}
long tell_func(void* datasource)
{
POggDataSource pDS = static_cast<POggDataSource>(datasource);
return long(pDS->_cursor);
}
const ov_callbacks g_oggCallbacks = { read_func, seek_func, close_func, tell_func };
} }
int seek_func(void* datasource, ogg_int64_t offset, int whence)
{
POggDataSource pDS = static_cast<POggDataSource>(datasource);
switch (whence)
{
case SEEK_SET: pDS->_cursor = offset; return 0;
case SEEK_CUR: pDS->_cursor += offset; return 0;
case SEEK_END: pDS->_cursor = pDS->_size - offset; return 0;
}
return -1;
}
int close_func(void* datasource)
{
POggDataSource pDS = static_cast<POggDataSource>(datasource);
pDS->_cursor = 0;
return 0;
}
long tell_func(void* datasource)
{
POggDataSource pDS = static_cast<POggDataSource>(datasource);
return long(pDS->_cursor);
}
const ov_callbacks g_oggCallbacks = { read_func, seek_func, close_func, tell_func };
} }

View File

@ -1,23 +1,20 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Audio
{ {
namespace Audio struct OggDataSource
{ {
struct OggDataSource const BYTE* _p = nullptr;
{ INT64 _size = 0;
const BYTE* _p = nullptr; INT64 _cursor = 0;
INT64 _size = 0; };
INT64 _cursor = 0; VERUS_TYPEDEFS(OggDataSource);
};
VERUS_TYPEDEFS(OggDataSource);
size_t read_func(void*, size_t, size_t, void*); size_t read_func(void*, size_t, size_t, void*);
int seek_func(void*, ogg_int64_t, int); int seek_func(void*, ogg_int64_t, int);
int close_func(void*); int close_func(void*);
long tell_func(void*); long tell_func(void*);
extern const ov_callbacks g_oggCallbacks; extern const ov_callbacks g_oggCallbacks;
}
} }

View File

@ -1,152 +1,149 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Audio
{ {
namespace Audio struct SoundFlags
{ {
struct SoundFlags enum
{ {
enum loaded = (ObjectFlags::user << 0),
{ is3D = (ObjectFlags::user << 1),
loaded = (ObjectFlags::user << 0), looping = (ObjectFlags::user << 2),
is3D = (ObjectFlags::user << 1), randOff = (ObjectFlags::user << 3),
looping = (ObjectFlags::user << 2), keepPcmBuffer = (ObjectFlags::user << 4),
randOff = (ObjectFlags::user << 3), user = (ObjectFlags::user << 5)
keepPcmBuffer = (ObjectFlags::user << 4),
user = (ObjectFlags::user << 5)
};
}; };
};
class Sound : public Object, public IO::AsyncDelegate class Sound : public Object, public IO::AsyncDelegate
{
Source _sources[8];
String _url;
Vector<BYTE> _vPcmBuffer;
ALuint _buffer = 0;
int _refCount = 0;
int _next = 0;
Interval _gain = 1;
Interval _pitch = 1;
float _referenceDistance = 4;
float _length = 0;
public:
// Note that this structure contains some default values for new sources, which can be changed per source.
struct Desc
{ {
Source _sources[8]; CSZ _url = nullptr;
String _url; Interval _gain = 0.8f;
Vector<BYTE> _vPcmBuffer; Interval _pitch = 1;
ALuint _buffer = 0; float _referenceDistance = 4;
int _refCount = 0; bool _is3D = false;
int _next = 0; bool _looping = false;
Interval _gain = 1; bool _randomOffset = false;
Interval _pitch = 1; bool _keepPcmBuffer = false;
float _referenceDistance = 4;
float _length = 0;
public: Desc(CSZ url) : _url(url) {}
// Note that this structure contains some default values for new sources, which can be changed per source. Desc& Set3D(bool b = true) { _is3D = b; return *this; }
struct Desc Desc& SetLooping(bool b = true) { _looping = b; return *this; }
{ Desc& SetRandomOffset(bool b = true) { _randomOffset = b; return *this; }
CSZ _url = nullptr; Desc& SetGain(Interval gain) { _gain = gain; return *this; }
Interval _gain = 0.8f; Desc& SetPitch(Interval pitch) { _pitch = pitch; return *this; }
Interval _pitch = 1; Desc& SetReferenceDistance(float rd) { _referenceDistance = rd; return *this; }
float _referenceDistance = 4;
bool _is3D = false;
bool _looping = false;
bool _randomOffset = false;
bool _keepPcmBuffer = false;
Desc(CSZ url) : _url(url) {}
Desc& Set3D(bool b = true) { _is3D = b; return *this; }
Desc& SetLooping(bool b = true) { _looping = b; return *this; }
Desc& SetRandomOffset(bool b = true) { _randomOffset = b; return *this; }
Desc& SetGain(Interval gain) { _gain = gain; return *this; }
Desc& SetPitch(Interval pitch) { _pitch = pitch; return *this; }
Desc& SetReferenceDistance(float rd) { _referenceDistance = rd; return *this; }
};
VERUS_TYPEDEFS(Desc);
Sound();
~Sound();
void AddRef() { _refCount++; }
int GetRefCount() const { return _refCount; }
void Init(RcDesc desc);
bool Done();
void Update();
void UpdateHRTF();
// <Resources>
virtual void Async_WhenLoaded(CSZ url, RcBlob blob) override;
bool IsLoaded() const { return IsFlagSet(SoundFlags::loaded); }
Str GetURL() const { return _C(_url); }
// </Resources>
SourcePtr NewSource(PSourcePtr pID = nullptr, Source::RcDesc desc = Source::Desc());
Interval GetGain() const { return _gain; }
Interval GetPitch() const { return _pitch; }
float GetLength() const { return _length; }
float GetRandomOffset() const;
void SetRandomOffset(bool b) { b ? SetFlag(SoundFlags::randOff) : ResetFlag(SoundFlags::randOff); }
bool HasRandomOffset() const { return IsFlagSet(SoundFlags::randOff); }
Blob GetPcmBuffer() const;
}; };
VERUS_TYPEDEFS(Sound); VERUS_TYPEDEFS(Desc);
class SoundPtr : public Ptr<Sound> Sound();
~Sound();
void AddRef() { _refCount++; }
int GetRefCount() const { return _refCount; }
void Init(RcDesc desc);
bool Done();
void Update();
void UpdateHRTF();
// <Resources>
virtual void Async_WhenLoaded(CSZ url, RcBlob blob) override;
bool IsLoaded() const { return IsFlagSet(SoundFlags::loaded); }
Str GetURL() const { return _C(_url); }
// </Resources>
SourcePtr NewSource(PSourcePtr pID = nullptr, Source::RcDesc desc = Source::Desc());
Interval GetGain() const { return _gain; }
Interval GetPitch() const { return _pitch; }
float GetLength() const { return _length; }
float GetRandomOffset() const;
void SetRandomOffset(bool b) { b ? SetFlag(SoundFlags::randOff) : ResetFlag(SoundFlags::randOff); }
bool HasRandomOffset() const { return IsFlagSet(SoundFlags::randOff); }
Blob GetPcmBuffer() const;
};
VERUS_TYPEDEFS(Sound);
class SoundPtr : public Ptr<Sound>
{
public:
void Init(Sound::RcDesc desc);
};
VERUS_TYPEDEFS(SoundPtr);
class SoundPwn : public SoundPtr
{
public:
~SoundPwn() { Done(); }
void Done();
};
VERUS_TYPEDEFS(SoundPwn);
template<int COUNT>
class SoundPwns
{
SoundPwn _sounds[COUNT];
int _prev = 0;
public:
SoundPwns()
{ {
public: }
void Init(Sound::RcDesc desc);
};
VERUS_TYPEDEFS(SoundPtr);
class SoundPwn : public SoundPtr ~SoundPwns()
{ {
public: Done();
~SoundPwn() { Done(); } }
void Done();
};
VERUS_TYPEDEFS(SoundPwn);
template<int COUNT> void Init(Sound::RcDesc desc)
class SoundPwns
{ {
SoundPwn _sounds[COUNT]; char buffer[200];
int _prev = 0; VERUS_FOR(i, COUNT)
public:
SoundPwns()
{ {
sprintf_s(buffer, desc._url, i);
Sound::Desc descs = desc;
descs._url = buffer;
_sounds[i].Init(descs);
} }
}
~SoundPwns() void Done()
{ {
Done(); VERUS_FOR(i, COUNT)
} _sounds[i].Done();
}
void Init(Sound::RcDesc desc) RSoundPtr operator[](int i)
{ {
char buffer[200]; const bool useRand = i < 0;
VERUS_FOR(i, COUNT) if (useRand)
{ i = Utils::I().GetRandom().Next() & 0xFF; // Only positive.
sprintf_s(buffer, desc._url, i); i %= COUNT;
Sound::Desc descs = desc; if (useRand && (i == _prev))
descs._url = buffer; i = (i + 1) % COUNT;
_sounds[i].Init(descs); _prev = i;
} return _sounds[i];
} }
};
void Done()
{
VERUS_FOR(i, COUNT)
_sounds[i].Done();
}
RSoundPtr operator[](int i)
{
const bool useRand = i < 0;
if (useRand)
i = Utils::I().GetRandom().Next() & 0xFF; // Only positive.
i %= COUNT;
if (useRand && (i == _prev))
i = (i + 1) % COUNT;
_prev = i;
return _sounds[i];
}
};
}
} }

View File

@ -1,57 +1,54 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Audio
{ {
namespace Audio class Source
{ {
class Source friend class SourcePtr; // _pSound @ Attach().
friend class Sound; // _sid @ NewSource().
Point3 _position = Point3(0);
Vector3 _direction = Vector3(0);
Vector3 _velocity = Vector3(0);
Sound* _pSound = nullptr;
ALuint _sid = 0;
float _travelDelay = 0;
public:
struct Desc
{ {
friend class SourcePtr; // _pSound @ Attach(). float _secOffset = 0;
friend class Sound; // _sid @ NewSource(). float _gain = 1;
float _pitch = 1;
Point3 _position = Point3(0); bool _stopSource = true;
Vector3 _direction = Vector3(0);
Vector3 _velocity = Vector3(0);
Sound* _pSound = nullptr;
ALuint _sid = 0;
float _travelDelay = 0;
public:
struct Desc
{
float _secOffset = 0;
float _gain = 1;
float _pitch = 1;
bool _stopSource = true;
};
VERUS_TYPEDEFS(Desc);
Source();
~Source();
void Done();
void Update();
void UpdateHRTF(bool is3D);
void Play();
void PlayAt(RcPoint3 pos, RcVector3 dir = Vector3(0), RcVector3 vel = Vector3(0), float delay = 0);
void Stop();
void MoveTo(RcPoint3 pos, RcVector3 dir = Vector3(0), RcVector3 vel = Vector3(0));
void SetGain(float gain);
void SetPitch(float pitch);
void SetLooping(bool loop);
}; };
VERUS_TYPEDEFS(Source); VERUS_TYPEDEFS(Desc);
class SourcePtr : public Ptr<Source> Source();
{ ~Source();
public:
void Attach(Source* pSource, Sound* pSound); void Done();
void Done();
}; void Update();
VERUS_TYPEDEFS(SourcePtr); void UpdateHRTF(bool is3D);
}
void Play();
void PlayAt(RcPoint3 pos, RcVector3 dir = Vector3(0), RcVector3 vel = Vector3(0), float delay = 0);
void Stop();
void MoveTo(RcPoint3 pos, RcVector3 dir = Vector3(0), RcVector3 vel = Vector3(0));
void SetGain(float gain);
void SetPitch(float pitch);
void SetLooping(bool loop);
};
VERUS_TYPEDEFS(Source);
class SourcePtr : public Ptr<Source>
{
public:
void Attach(Source* pSource, Sound* pSound);
void Done();
};
VERUS_TYPEDEFS(SourcePtr);
} }

View File

@ -1,83 +1,80 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Audio
{ {
namespace Audio class Track : public IO::AsyncDelegate
{ {
class Track : public IO::AsyncDelegate Vector<BYTE> _vOggEncodedTrack;
OggDataSource _ds;
std::atomic_bool _loaded;
public:
Track();
~Track();
POggDataSource GetOggDataSource() { return &_ds; }
void Init(CSZ url);
void Done();
virtual void Async_WhenLoaded(CSZ url, RcBlob blob) override;
bool IsLoaded() const { return _loaded; }
};
VERUS_TYPEDEFS(Track);
struct StreamPlayerFlags
{
enum
{ {
Vector<BYTE> _vOggEncodedTrack; stopThread = (ObjectFlags::user << 0),
OggDataSource _ds; play = (ObjectFlags::user << 1),
std::atomic_bool _loaded; noLock = (ObjectFlags::user << 2)
public:
Track();
~Track();
POggDataSource GetOggDataSource() { return &_ds; }
void Init(CSZ url);
void Done();
virtual void Async_WhenLoaded(CSZ url, RcBlob blob) override;
bool IsLoaded() const { return _loaded; }
}; };
VERUS_TYPEDEFS(Track); };
struct StreamPlayerFlags class StreamPlayer : public Object, public Lockable
{ {
enum Track _nativeTrack;
{ Vector<PTrack> _vTracks;
stopThread = (ObjectFlags::user << 0), Vector<BYTE> _vSmallBuffer;
play = (ObjectFlags::user << 1), Vector<BYTE> _vMediumBuffer;
noLock = (ObjectFlags::user << 2) std::thread _thread;
}; std::condition_variable _cv;
}; vorbis_info* _pVorbisInfo = nullptr;
PTrack _pTrack = nullptr;
OggVorbis_File _oggVorbisFile;
ALuint _buffers[2];
ALuint _source = 0;
ALenum _format = 0;
Linear<float> _fade;
float _gain = 0.25f;
int _currentTrack = 0;
class StreamPlayer : public Object, public Lockable public:
{ StreamPlayer();
Track _nativeTrack; ~StreamPlayer();
Vector<PTrack> _vTracks;
Vector<BYTE> _vSmallBuffer;
Vector<BYTE> _vMediumBuffer;
std::thread _thread;
std::condition_variable _cv;
vorbis_info* _pVorbisInfo = nullptr;
PTrack _pTrack = nullptr;
OggVorbis_File _oggVorbisFile;
ALuint _buffers[2];
ALuint _source = 0;
ALenum _format = 0;
Linear<float> _fade;
float _gain = 0.25f;
int _currentTrack = 0;
public: void Init();
StreamPlayer(); void Done();
~StreamPlayer();
void Init(); void Update();
void Done();
void Update(); void AddTrack(PTrack pTrack);
void DeleteTrack(PTrack pTrack);
void SwitchToTrack(PTrack pTrack);
void AddTrack(PTrack pTrack); void Play();
void DeleteTrack(PTrack pTrack); void Stop();
void SwitchToTrack(PTrack pTrack); void Seek(int pos);
void Play(); VERUS_P(void ThreadProc());
void Stop(); VERUS_P(void StopThread());
void Seek(int pos); VERUS_P(void FillBuffer(ALuint buffer));
VERUS_P(void ThreadProc()); void FadeIn(float time);
VERUS_P(void StopThread()); void FadeOut(float time);
VERUS_P(void FillBuffer(ALuint buffer)); void Mute();
void SetGain(float gain);
void FadeIn(float time); };
void FadeOut(float time); VERUS_TYPEDEFS(StreamPlayer);
void Mute();
void SetGain(float gain);
};
VERUS_TYPEDEFS(StreamPlayer);
}
} }

View File

@ -1,113 +1,110 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI // View can be a smaller portion of framebuffer with an offset.
enum class ViewportScissorFlags : UINT32
{ {
// View can be a smaller portion of framebuffer with an offset. none = 0,
enum class ViewportScissorFlags : UINT32 setViewportForFramebuffer = (1 << 0),
{ setViewportForCurrentView = (1 << 1),
none = 0, setScissorForFramebuffer = (1 << 2),
setViewportForFramebuffer = (1 << 0), setScissorForCurrentView = (1 << 3),
setViewportForCurrentView = (1 << 1), applyOffscreenScale = (1 << 4),
setScissorForFramebuffer = (1 << 2), applyHalfScale = (1 << 5),
setScissorForCurrentView = (1 << 3), setAllForFramebuffer = setViewportForFramebuffer | setScissorForFramebuffer,
applyOffscreenScale = (1 << 4), setAllForCurrentView = setViewportForCurrentView | setScissorForCurrentView,
applyHalfScale = (1 << 5), setAllForCurrentViewScaled = setAllForCurrentView | applyOffscreenScale
setAllForFramebuffer = setViewportForFramebuffer | setScissorForFramebuffer, };
setAllForCurrentView = setViewportForCurrentView | setScissorForCurrentView,
setAllForCurrentViewScaled = setAllForCurrentView | applyOffscreenScale
};
class BaseCommandBuffer : public Object, public Scheduled class BaseCommandBuffer : public Object, public Scheduled
{ {
protected: protected:
Vector4 _viewportSize = Vector4(0); Vector4 _viewportSize = Vector4(0);
Vector4 _viewScaleBias = Vector4(0); Vector4 _viewScaleBias = Vector4(0);
void SetViewportAndScissor(ViewportScissorFlags vsf, int width, int height); void SetViewportAndScissor(ViewportScissorFlags vsf, int width, int height);
BaseCommandBuffer() = default; BaseCommandBuffer() = default;
virtual ~BaseCommandBuffer() = default; virtual ~BaseCommandBuffer() = default;
public: public:
virtual void Init() = 0; virtual void Init() = 0;
virtual void Done() = 0; virtual void Done() = 0;
virtual void InitOneTimeSubmit() = 0; virtual void InitOneTimeSubmit() = 0;
virtual void DoneOneTimeSubmit() = 0; virtual void DoneOneTimeSubmit() = 0;
virtual void Begin() = 0; virtual void Begin() = 0;
virtual void End() = 0; virtual void End() = 0;
virtual void PipelineImageMemoryBarrier(TexturePtr tex, ImageLayout oldLayout, ImageLayout newLayout, virtual void PipelineImageMemoryBarrier(TexturePtr tex, ImageLayout oldLayout, ImageLayout newLayout,
Range mipLevels, Range arrayLayers = 0) = 0; Range mipLevels, Range arrayLayers = 0) = 0;
// <RenderPass> // <RenderPass>
virtual void BeginRenderPass(RPHandle renderPassHandle, FBHandle framebufferHandle, virtual void BeginRenderPass(RPHandle renderPassHandle, FBHandle framebufferHandle,
std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf = ViewportScissorFlags::setAllForCurrentViewScaled) = 0; std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf = ViewportScissorFlags::setAllForCurrentViewScaled) = 0;
virtual void NextSubpass() = 0; virtual void NextSubpass() = 0;
virtual void EndRenderPass() = 0; virtual void EndRenderPass() = 0;
// </RenderPass> // </RenderPass>
// <Pipeline> // <Pipeline>
virtual void BindPipeline(PipelinePtr pipe) = 0; virtual void BindPipeline(PipelinePtr pipe) = 0;
virtual void SetViewport(std::initializer_list<Vector4> il, float minDepth = 0, float maxDepth = 1) = 0; virtual void SetViewport(std::initializer_list<Vector4> il, float minDepth = 0, float maxDepth = 1) = 0;
virtual void SetScissor(std::initializer_list<Vector4> il) = 0; virtual void SetScissor(std::initializer_list<Vector4> il) = 0;
virtual void SetBlendConstants(const float* p) = 0; virtual void SetBlendConstants(const float* p) = 0;
// </Pipeline> // </Pipeline>
// <VertexInput> // <VertexInput>
virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter = UINT32_MAX) = 0; virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter = UINT32_MAX) = 0;
virtual void BindIndexBuffer(GeometryPtr geo) = 0; virtual void BindIndexBuffer(GeometryPtr geo) = 0;
// </VertexInput> // </VertexInput>
// <Descriptors> // <Descriptors>
virtual bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle = CSHandle()) = 0; virtual bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle = CSHandle()) = 0;
virtual bool BindDescriptors(ShaderPtr shader, int setNumber, GeometryPtr geo, int sbIndex) = 0; virtual bool BindDescriptors(ShaderPtr shader, int setNumber, GeometryPtr geo, int sbIndex) = 0;
virtual void PushConstants(ShaderPtr shader, int offset, int size, const void* p, ShaderStageFlags stageFlags = ShaderStageFlags::vs_fs) = 0; virtual void PushConstants(ShaderPtr shader, int offset, int size, const void* p, ShaderStageFlags stageFlags = ShaderStageFlags::vs_fs) = 0;
// </Descriptors> // </Descriptors>
// <Draw> // <Draw>
virtual void Draw(int vertexCount, int instanceCount = 1, int firstVertex = 0, int firstInstance = 0) = 0; virtual void Draw(int vertexCount, int instanceCount = 1, int firstVertex = 0, int firstInstance = 0) = 0;
virtual void DrawIndexed(int indexCount, int instanceCount = 1, int firstIndex = 0, int vertexOffset = 0, int firstInstance = 0) = 0; virtual void DrawIndexed(int indexCount, int instanceCount = 1, int firstIndex = 0, int vertexOffset = 0, int firstInstance = 0) = 0;
virtual void Dispatch(int groupCountX, int groupCountY, int groupCountZ = 1) = 0; virtual void Dispatch(int groupCountX, int groupCountY, int groupCountZ = 1) = 0;
virtual void DispatchIndirect() {} // WIP. virtual void DispatchIndirect() {} // WIP.
virtual void DispatchMesh(int groupCountX, int groupCountY, int groupCountZ) {} // WIP. virtual void DispatchMesh(int groupCountX, int groupCountY, int groupCountZ) {} // WIP.
virtual void TraceRays(int width, int height, int depth) {} // WIP. virtual void TraceRays(int width, int height, int depth) {} // WIP.
// </Draw> // </Draw>
// <Profiler> // <Profiler>
virtual void ProfilerBeginEvent(UINT32 color, CSZ text) {} virtual void ProfilerBeginEvent(UINT32 color, CSZ text) {}
virtual void ProfilerEndEvent() {} virtual void ProfilerEndEvent() {}
virtual void ProfilerSetMarker(UINT32 color, CSZ text) {} virtual void ProfilerSetMarker(UINT32 color, CSZ text) {}
// </Profiler> // </Profiler>
RcVector4 GetViewportSize() const { return _viewportSize; } RcVector4 GetViewportSize() const { return _viewportSize; }
RcVector4 GetViewScaleBias() const { return _viewScaleBias; } RcVector4 GetViewScaleBias() const { return _viewScaleBias; }
}; };
VERUS_TYPEDEFS(BaseCommandBuffer); VERUS_TYPEDEFS(BaseCommandBuffer);
class CommandBufferPtr : public Ptr<BaseCommandBuffer> class CommandBufferPtr : public Ptr<BaseCommandBuffer>
{ {
public: public:
void Init(); void Init();
void InitOneTimeSubmit(); void InitOneTimeSubmit();
}; };
VERUS_TYPEDEFS(CommandBufferPtr); VERUS_TYPEDEFS(CommandBufferPtr);
class CommandBufferPwn : public CommandBufferPtr class CommandBufferPwn : public CommandBufferPtr
{ {
public: public:
~CommandBufferPwn() { Done(); } ~CommandBufferPwn() { Done(); }
void Done(); void Done();
}; };
VERUS_TYPEDEFS(CommandBufferPwn); VERUS_TYPEDEFS(CommandBufferPwn);
template<int COUNT> template<int COUNT>
class CommandBufferPwns : public Pwns<CommandBufferPwn, COUNT> class CommandBufferPwns : public Pwns<CommandBufferPwn, COUNT>
{ {
}; };
}
} }

View File

@ -3,121 +3,118 @@
#define VERUS_XR_DESTROY(xr, fn) {if (XR_NULL_HANDLE != xr) {fn; xr = XR_NULL_HANDLE;}} #define VERUS_XR_DESTROY(xr, fn) {if (XR_NULL_HANDLE != xr) {fn; xr = XR_NULL_HANDLE;}}
namespace verus namespace verus::CGI
{ {
namespace CGI class BaseExtReality : public Object
{ {
class BaseExtReality : public Object struct ActionEx
{ {
struct ActionEx XrAction _handle = XR_NULL_HANDLE;
{ Vector<XrPath> _vSubactionPaths;
XrAction _handle = XR_NULL_HANDLE; Vector<XrSpace> _vActionSpaces;
Vector<XrPath> _vSubactionPaths;
Vector<XrSpace> _vActionSpaces;
};
VERUS_TYPEDEFS(ActionEx);
protected:
Math::Pose _areaSpaceHeadPose;
Math::Pose _worldSpaceHeadPose;
Math::Pose _areaPose; // In world space.
Transform3 _trAreaToWorld = Transform3::identity();
Point3 _areaOrigin = Point3(0);
Vector4 _areaSpaceUserOffset = Vector4(0); // W is yaw.
XrInstance _instance = XR_NULL_HANDLE;
XrDebugUtilsMessengerEXT _debugUtilsMessenger = XR_NULL_HANDLE;
XrSystemId _systemId = XR_NULL_SYSTEM_ID;
XrSession _session = XR_NULL_HANDLE;
XrSpace _referenceSpace = XR_NULL_HANDLE;
XrSpace _headSpace = XR_NULL_HANDLE;
XrTime _predictedDisplayTime = 0;
Vector<CSZ> _vRequiredExtensions;
Vector<XrView> _vViews;
Vector<XrCompositionLayerProjectionView> _vCompositionLayerProjectionViews;
Vector<XrActionSet> _vActionSets;
Vector<XrActiveActionSet> _vActiveActionSets;
Vector<ActionEx> _vActions;
XrFormFactor _formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
XrViewConfigurationType _viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
XrEnvironmentBlendMode _envBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
XrSessionState _sessionState = XR_SESSION_STATE_UNKNOWN;
XrPosef _identityPose;
float _userHeight = 1.5f;
float _areaYaw = 0;
int _combinedSwapChainWidth = 0;
int _combinedSwapChainHeight = 0;
int _currentViewIndex = 0;
int _swapChainBufferCount = 0;
int _swapChainBufferIndex = 0;
RPHandle _rph;
Vector<FBHandle> _fbh;
bool _runningSession = false;
bool _shouldRender = false;
bool _areaUpdated = false;
BaseExtReality();
virtual ~BaseExtReality();
public:
virtual void Init();
virtual void Done();
protected:
static XRAPI_ATTR XrBool32 XRAPI_CALL DebugUtilsMessengerCallback(
XrDebugUtilsMessageSeverityFlagsEXT messageSeverityFlags,
XrDebugUtilsMessageTypeFlagsEXT messageTypeFlags,
const XrDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData);
bool CheckRequiredExtensions() const;
void CreateInstance();
void CreateDebugUtilsMessenger();
void CreateReferenceSpace();
void CreateHeadSpace();
virtual XrSwapchain GetSwapChain(int viewIndex) = 0;
virtual void GetSwapChainSize(int viewIndex, int32_t& w, int32_t& h) = 0;
public:
virtual void CreateActions();
virtual void PollEvents();
virtual void SyncActions(UINT32 activeActionSetsMask = -1);
virtual bool GetActionStateBoolean(int actionIndex, bool& currentState, bool* pChangedState, int subaction);
virtual bool GetActionStateFloat(int actionIndex, float& currentState, bool* pChangedState, int subaction);
virtual bool GetActionStatePose(int actionIndex, bool& currentState, Math::RPose pose, int subaction);
virtual void BeginFrame();
virtual int LocateViews();
virtual void BeginView(int viewIndex, RViewDesc viewDesc);
virtual void AcquireSwapChainImage();
virtual void EndView(int viewIndex);
virtual void EndFrame();
int GetCombinedSwapChainWidth() const { return _combinedSwapChainWidth; }
int GetCombinedSwapChainHeight() const { return _combinedSwapChainHeight; }
RPHandle GetRenderPassHandle() const;
FBHandle GetFramebufferHandle() const;
Math::RcPose GetAreaSpaceHeadPose() const { return _areaSpaceHeadPose; }
Math::RcPose GetWorldSpaceHeadPose() const { return _worldSpaceHeadPose; }
// <AreaAndUser>
virtual void BeginAreaUpdate();
virtual void EndAreaUpdate(PcVector4 pUserOffset = nullptr);
float GetUserHeight() const { return _userHeight; }
void SetUserHeight(float height);
float GetAreaYaw() const { return _areaYaw; }
void SetAreaYaw(float yaw);
RcPoint3 GetAreaOrigin() const { return _areaOrigin; }
void SetAreaOrigin(RcPoint3 origin);
void MoveAreaBy(RcVector3 offset);
void TurnAreaBy(float angle);
RcVector4 GetAreaSpaceUserOffset() const { return _areaSpaceUserOffset; }
void TeleportUserTo(RcPoint3 pos, float yaw);
void UpdateAreaTransform();
void AreaSpacePoseToWorldSpacePose(Math::RPose pose);
// </AreaAndUser>
}; };
VERUS_TYPEDEFS(BaseExtReality); VERUS_TYPEDEFS(ActionEx);
}
protected:
Math::Pose _areaSpaceHeadPose;
Math::Pose _worldSpaceHeadPose;
Math::Pose _areaPose; // In world space.
Transform3 _trAreaToWorld = Transform3::identity();
Point3 _areaOrigin = Point3(0);
Vector4 _areaSpaceUserOffset = Vector4(0); // W is yaw.
XrInstance _instance = XR_NULL_HANDLE;
XrDebugUtilsMessengerEXT _debugUtilsMessenger = XR_NULL_HANDLE;
XrSystemId _systemId = XR_NULL_SYSTEM_ID;
XrSession _session = XR_NULL_HANDLE;
XrSpace _referenceSpace = XR_NULL_HANDLE;
XrSpace _headSpace = XR_NULL_HANDLE;
XrTime _predictedDisplayTime = 0;
Vector<CSZ> _vRequiredExtensions;
Vector<XrView> _vViews;
Vector<XrCompositionLayerProjectionView> _vCompositionLayerProjectionViews;
Vector<XrActionSet> _vActionSets;
Vector<XrActiveActionSet> _vActiveActionSets;
Vector<ActionEx> _vActions;
XrFormFactor _formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
XrViewConfigurationType _viewConfigurationType = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
XrEnvironmentBlendMode _envBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
XrSessionState _sessionState = XR_SESSION_STATE_UNKNOWN;
XrPosef _identityPose;
float _userHeight = 1.5f;
float _areaYaw = 0;
int _combinedSwapChainWidth = 0;
int _combinedSwapChainHeight = 0;
int _currentViewIndex = 0;
int _swapChainBufferCount = 0;
int _swapChainBufferIndex = 0;
RPHandle _rph;
Vector<FBHandle> _fbh;
bool _runningSession = false;
bool _shouldRender = false;
bool _areaUpdated = false;
BaseExtReality();
virtual ~BaseExtReality();
public:
virtual void Init();
virtual void Done();
protected:
static XRAPI_ATTR XrBool32 XRAPI_CALL DebugUtilsMessengerCallback(
XrDebugUtilsMessageSeverityFlagsEXT messageSeverityFlags,
XrDebugUtilsMessageTypeFlagsEXT messageTypeFlags,
const XrDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData);
bool CheckRequiredExtensions() const;
void CreateInstance();
void CreateDebugUtilsMessenger();
void CreateReferenceSpace();
void CreateHeadSpace();
virtual XrSwapchain GetSwapChain(int viewIndex) = 0;
virtual void GetSwapChainSize(int viewIndex, int32_t& w, int32_t& h) = 0;
public:
virtual void CreateActions();
virtual void PollEvents();
virtual void SyncActions(UINT32 activeActionSetsMask = -1);
virtual bool GetActionStateBoolean(int actionIndex, bool& currentState, bool* pChangedState, int subaction);
virtual bool GetActionStateFloat(int actionIndex, float& currentState, bool* pChangedState, int subaction);
virtual bool GetActionStatePose(int actionIndex, bool& currentState, Math::RPose pose, int subaction);
virtual void BeginFrame();
virtual int LocateViews();
virtual void BeginView(int viewIndex, RViewDesc viewDesc);
virtual void AcquireSwapChainImage();
virtual void EndView(int viewIndex);
virtual void EndFrame();
int GetCombinedSwapChainWidth() const { return _combinedSwapChainWidth; }
int GetCombinedSwapChainHeight() const { return _combinedSwapChainHeight; }
RPHandle GetRenderPassHandle() const;
FBHandle GetFramebufferHandle() const;
Math::RcPose GetAreaSpaceHeadPose() const { return _areaSpaceHeadPose; }
Math::RcPose GetWorldSpaceHeadPose() const { return _worldSpaceHeadPose; }
// <AreaAndUser>
virtual void BeginAreaUpdate();
virtual void EndAreaUpdate(PcVector4 pUserOffset = nullptr);
float GetUserHeight() const { return _userHeight; }
void SetUserHeight(float height);
float GetAreaYaw() const { return _areaYaw; }
void SetAreaYaw(float yaw);
RcPoint3 GetAreaOrigin() const { return _areaOrigin; }
void SetAreaOrigin(RcPoint3 origin);
void MoveAreaBy(RcVector3 offset);
void TurnAreaBy(float angle);
RcVector4 GetAreaSpaceUserOffset() const { return _areaSpaceUserOffset; }
void TeleportUserTo(RcPoint3 pos, float yaw);
void UpdateAreaTransform();
void AreaSpacePoseToWorldSpacePose(Math::RPose pose);
// </AreaAndUser>
};
VERUS_TYPEDEFS(BaseExtReality);
} }

View File

@ -1,72 +1,69 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class BaseCommandBuffer;
struct GeometryDesc
{ {
class BaseCommandBuffer; CSZ _name = nullptr;
PcVertexInputAttrDesc _pVertexInputAttrDesc = nullptr;
const int* _pStrides = nullptr;
UINT32 _dynBindingsMask = 0;
bool _32BitIndices = false;
};
VERUS_TYPEDEFS(GeometryDesc);
struct GeometryDesc class BaseGeometry : public Object, public Scheduled
{ {
CSZ _name = nullptr; protected:
PcVertexInputAttrDesc _pVertexInputAttrDesc = nullptr; String _name;
const int* _pStrides = nullptr; UINT32 _instBindingsMask = 0;
UINT32 _dynBindingsMask = 0; UINT32 _dynBindingsMask = 0;
bool _32BitIndices = false; bool _32BitIndices = false;
};
VERUS_TYPEDEFS(GeometryDesc);
class BaseGeometry : public Object, public Scheduled BaseGeometry() = default;
{ virtual ~BaseGeometry() = default;
protected:
String _name;
UINT32 _instBindingsMask = 0;
UINT32 _dynBindingsMask = 0;
bool _32BitIndices = false;
BaseGeometry() = default; public:
virtual ~BaseGeometry() = default; virtual void Init(RcGeometryDesc desc) = 0;
virtual void Done() = 0;
public: virtual void CreateVertexBuffer(int count, int binding) = 0;
virtual void Init(RcGeometryDesc desc) = 0; virtual void UpdateVertexBuffer(const void* p, int binding, BaseCommandBuffer* pCB = nullptr, INT64 size = 0, INT64 offset = 0) = 0;
virtual void Done() = 0;
virtual void CreateVertexBuffer(int count, int binding) = 0; virtual void CreateIndexBuffer(int count) = 0;
virtual void UpdateVertexBuffer(const void* p, int binding, BaseCommandBuffer* pCB = nullptr, INT64 size = 0, INT64 offset = 0) = 0; virtual void UpdateIndexBuffer(const void* p, BaseCommandBuffer* pCB = nullptr, INT64 size = 0, INT64 offset = 0) = 0;
virtual void CreateIndexBuffer(int count) = 0; virtual void CreateStorageBuffer(int count, int structSize, int sbIndex, ShaderStageFlags stageFlags) = 0;
virtual void UpdateIndexBuffer(const void* p, BaseCommandBuffer* pCB = nullptr, INT64 size = 0, INT64 offset = 0) = 0; virtual void UpdateStorageBuffer(const void* p, int sbIndex, BaseCommandBuffer* pCB = nullptr, INT64 size = 0, INT64 offset = 0) = 0;
virtual int GetStorageBufferStructSize(int sbIndex) const = 0;
virtual void CreateStorageBuffer(int count, int structSize, int sbIndex, ShaderStageFlags stageFlags) = 0; static int GetVertexInputAttrDescCount(PcVertexInputAttrDesc p);
virtual void UpdateStorageBuffer(const void* p, int sbIndex, BaseCommandBuffer* pCB = nullptr, INT64 size = 0, INT64 offset = 0) = 0; static int GetBindingCount(PcVertexInputAttrDesc p);
virtual int GetStorageBufferStructSize(int sbIndex) const = 0;
static int GetVertexInputAttrDescCount(PcVertexInputAttrDesc p); bool Has32BitIndices() const { return _32BitIndices; }
static int GetBindingCount(PcVertexInputAttrDesc p); };
VERUS_TYPEDEFS(BaseGeometry);
bool Has32BitIndices() const { return _32BitIndices; } class GeometryPtr : public Ptr<BaseGeometry>
}; {
VERUS_TYPEDEFS(BaseGeometry); public:
void Init(RcGeometryDesc desc);
};
VERUS_TYPEDEFS(GeometryPtr);
class GeometryPtr : public Ptr<BaseGeometry> class GeometryPwn : public GeometryPtr
{ {
public: public:
void Init(RcGeometryDesc desc); ~GeometryPwn() { Done(); }
}; void Done();
VERUS_TYPEDEFS(GeometryPtr); };
VERUS_TYPEDEFS(GeometryPwn);
class GeometryPwn : public GeometryPtr template<int COUNT>
{ class GeometryPwns : public Pwns<GeometryPwn, COUNT>
public: {
~GeometryPwn() { Done(); } };
void Done();
};
VERUS_TYPEDEFS(GeometryPwn);
template<int COUNT>
class GeometryPwns : public Pwns<GeometryPwn, COUNT>
{
};
}
} }

View File

@ -1,92 +1,89 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI struct PipelineDesc
{ {
struct PipelineDesc GeometryPtr _geometry;
ShaderPtr _shader;
CSZ _shaderBranch = nullptr;
String _colorAttachBlendEqs[VERUS_MAX_CA];
String _colorAttachWriteMasks[VERUS_MAX_CA];
PipelineRasterizationState _rasterizationState;
PrimitiveTopology _topology = PrimitiveTopology::triangleList;
int _sampleCount = 1;
RPHandle _renderPassHandle;
int _subpass = 0;
UINT32 _vertexInputBindingsFilter = UINT32_MAX;
CompareOp _depthCompareOp = CompareOp::less;
bool _depthTestEnable = true;
bool _depthWriteEnable = true;
bool _stencilTestEnable = false;
bool _primitiveRestartEnable = false; // Special index value is 0xFFFFFFFF for 32-bit and 0xFFFF for 16-bit indices.
bool _compute = false; // Compute pipeline, use PipelineDesc(ShaderPtr, CSZ) to set this to true.
// What to draw (geo)? How to draw (shader)? Where to draw (render pass)?
PipelineDesc(GeometryPtr geo, ShaderPtr shader, CSZ branch, RPHandle renderPassHandle, int subpass = 0) :
_geometry(geo), _shader(shader), _shaderBranch(branch), _renderPassHandle(renderPassHandle), _subpass(subpass)
{ {
GeometryPtr _geometry; _colorAttachBlendEqs[0] = VERUS_COLOR_BLEND_OFF;
ShaderPtr _shader; VERUS_FOR(i, VERUS_COUNT_OF(_colorAttachWriteMasks))
CSZ _shaderBranch = nullptr; _colorAttachWriteMasks[i] = "rgba";
String _colorAttachBlendEqs[VERUS_MAX_CA]; }
String _colorAttachWriteMasks[VERUS_MAX_CA]; PipelineDesc(ShaderPtr shader, CSZ branch) :
PipelineRasterizationState _rasterizationState; _shader(shader), _shaderBranch(branch), _compute(true) {}
PrimitiveTopology _topology = PrimitiveTopology::triangleList;
int _sampleCount = 1;
RPHandle _renderPassHandle;
int _subpass = 0;
UINT32 _vertexInputBindingsFilter = UINT32_MAX;
CompareOp _depthCompareOp = CompareOp::less;
bool _depthTestEnable = true;
bool _depthWriteEnable = true;
bool _stencilTestEnable = false;
bool _primitiveRestartEnable = false; // Special index value is 0xFFFFFFFF for 32-bit and 0xFFFF for 16-bit indices.
bool _compute = false; // Compute pipeline, use PipelineDesc(ShaderPtr, CSZ) to set this to true.
// What to draw (geo)? How to draw (shader)? Where to draw (render pass)? void DisableDepthTest()
PipelineDesc(GeometryPtr geo, ShaderPtr shader, CSZ branch, RPHandle renderPassHandle, int subpass = 0) :
_geometry(geo), _shader(shader), _shaderBranch(branch), _renderPassHandle(renderPassHandle), _subpass(subpass)
{
_colorAttachBlendEqs[0] = VERUS_COLOR_BLEND_OFF;
VERUS_FOR(i, VERUS_COUNT_OF(_colorAttachWriteMasks))
_colorAttachWriteMasks[i] = "rgba";
}
PipelineDesc(ShaderPtr shader, CSZ branch) :
_shader(shader), _shaderBranch(branch), _compute(true) {}
void DisableDepthTest()
{
_depthTestEnable = false;
_depthWriteEnable = false;
}
void EnableDepthBias()
{
_rasterizationState._depthBiasEnable = true;
_rasterizationState._depthBiasConstantFactor = 14;
_rasterizationState._depthBiasSlopeFactor = 1.1f;
if (App::Settings::I()._sceneShadowQuality >= App::Settings::Quality::high)
_rasterizationState._depthBiasConstantFactor = 50;
}
};
VERUS_TYPEDEFS(PipelineDesc);
class BasePipeline : public Object, public Scheduled
{ {
protected: _depthTestEnable = false;
UINT32 _vertexInputBindingsFilter = UINT32_MAX; _depthWriteEnable = false;
}
BasePipeline() = default; void EnableDepthBias()
virtual ~BasePipeline() = default;
public:
virtual void Init(RcPipelineDesc desc) = 0;
virtual void Done() = 0;
UINT32 GetVertexInputBindingsFilter() const { return _vertexInputBindingsFilter; }
};
VERUS_TYPEDEFS(BasePipeline);
class PipelinePtr : public Ptr<BasePipeline>
{ {
public: _rasterizationState._depthBiasEnable = true;
void Init(RcPipelineDesc desc); _rasterizationState._depthBiasConstantFactor = 14;
}; _rasterizationState._depthBiasSlopeFactor = 1.1f;
VERUS_TYPEDEFS(PipelinePtr); if (App::Settings::I()._sceneShadowQuality >= App::Settings::Quality::high)
_rasterizationState._depthBiasConstantFactor = 50;
}
};
VERUS_TYPEDEFS(PipelineDesc);
class PipelinePwn : public PipelinePtr class BasePipeline : public Object, public Scheduled
{ {
public: protected:
~PipelinePwn() { Done(); } UINT32 _vertexInputBindingsFilter = UINT32_MAX;
void Done();
};
VERUS_TYPEDEFS(PipelinePwn);
template<int COUNT> BasePipeline() = default;
class PipelinePwns : public Pwns<PipelinePwn, COUNT> virtual ~BasePipeline() = default;
{
}; public:
} virtual void Init(RcPipelineDesc desc) = 0;
virtual void Done() = 0;
UINT32 GetVertexInputBindingsFilter() const { return _vertexInputBindingsFilter; }
};
VERUS_TYPEDEFS(BasePipeline);
class PipelinePtr : public Ptr<BasePipeline>
{
public:
void Init(RcPipelineDesc desc);
};
VERUS_TYPEDEFS(PipelinePtr);
class PipelinePwn : public PipelinePtr
{
public:
~PipelinePwn() { Done(); }
void Done();
};
VERUS_TYPEDEFS(PipelinePwn);
template<int COUNT>
class PipelinePwns : public Pwns<PipelinePwn, COUNT>
{
};
} }

View File

@ -1,113 +1,110 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI enum class Gapi : int
{ {
enum class Gapi : int unknown,
vulkan,
direct3D11,
direct3D12
};
struct BaseRendererDesc
{
GlobalVarsClipboard _gvc;
BaseRendererDesc()
{ {
unknown, _gvc.Copy();
vulkan, }
direct3D11, };
direct3D12 VERUS_TYPEDEFS(BaseRendererDesc);
};
struct BaseRendererDesc class BaseRenderer : public Object
{ {
GlobalVarsClipboard _gvc; protected:
Vector<PScheduled> _vScheduled;
BaseRendererDesc _desc;
int _swapChainBufferCount = 0;
int _swapChainBufferIndex = 0;
int _ringBufferIndex = 0;
BaseRendererDesc() BaseRenderer();
{ virtual ~BaseRenderer();
_gvc.Copy();
}
};
VERUS_TYPEDEFS(BaseRendererDesc);
class BaseRenderer : public Object public:
{ static const int s_ringBufferSize = 3;
protected:
Vector<PScheduled> _vScheduled;
BaseRendererDesc _desc;
int _swapChainBufferCount = 0;
int _swapChainBufferIndex = 0;
int _ringBufferIndex = 0;
BaseRenderer(); static BaseRenderer* Load(CSZ dll, RBaseRendererDesc desc);
virtual ~BaseRenderer(); virtual void ReleaseMe() = 0;
public: void SetDesc(RBaseRendererDesc desc) { _desc = desc; }
static const int s_ringBufferSize = 3;
static BaseRenderer* Load(CSZ dll, RBaseRendererDesc desc); int GetSwapChainBufferCount() const { return _swapChainBufferCount; }
virtual void ReleaseMe() = 0; int GetSwapChainBufferIndex() const { return _swapChainBufferIndex; }
int GetRingBufferIndex() const { return _ringBufferIndex; }
void SetDesc(RBaseRendererDesc desc) { _desc = desc; } void Schedule(PScheduled p);
void Unschedule(PScheduled p);
void UpdateScheduled();
int GetSwapChainBufferCount() const { return _swapChainBufferCount; } virtual void ImGuiInit(RPHandle renderPassHandle) = 0;
int GetSwapChainBufferIndex() const { return _swapChainBufferIndex; } virtual void ImGuiRenderDrawData() = 0;
int GetRingBufferIndex() const { return _ringBufferIndex; }
void Schedule(PScheduled p); virtual void ResizeSwapChain() = 0;
void Unschedule(PScheduled p);
void UpdateScheduled();
virtual void ImGuiInit(RPHandle renderPassHandle) = 0; virtual PBaseExtReality GetExtReality() { return nullptr; }
virtual void ImGuiRenderDrawData() = 0;
virtual void ResizeSwapChain() = 0; // Which graphics API?
virtual Gapi GetGapi() = 0;
virtual PBaseExtReality GetExtReality() { return nullptr; } // <FrameCycle>
virtual void BeginFrame() = 0;
virtual void AcquireSwapChainImage() = 0;
virtual void EndFrame() = 0;
virtual void WaitIdle() = 0;
virtual void OnMinimized() = 0;
// </FrameCycle>
// Which graphics API? // <Resources>
virtual Gapi GetGapi() = 0; virtual PBaseCommandBuffer InsertCommandBuffer() = 0;
virtual PBaseGeometry InsertGeometry() = 0;
virtual PBasePipeline InsertPipeline() = 0;
virtual PBaseShader InsertShader() = 0;
virtual PBaseTexture InsertTexture() = 0;
// <FrameCycle> virtual void DeleteCommandBuffer(PBaseCommandBuffer p) = 0;
virtual void BeginFrame() = 0; virtual void DeleteGeometry(PBaseGeometry p) = 0;
virtual void AcquireSwapChainImage() = 0; virtual void DeletePipeline(PBasePipeline p) = 0;
virtual void EndFrame() = 0; virtual void DeleteShader(PBaseShader p) = 0;
virtual void WaitIdle() = 0; virtual void DeleteTexture(PBaseTexture p) = 0;
virtual void OnMinimized() = 0;
// </FrameCycle>
// <Resources> RPHandle CreateSimpleRenderPass(Format format, RP::Attachment::LoadOp loadOp = RP::Attachment::LoadOp::dontCare, ImageLayout layout = ImageLayout::fsReadOnly);
virtual PBaseCommandBuffer InsertCommandBuffer() = 0; RPHandle CreateShadowRenderPass(Format format, RP::Attachment::LoadOp loadOp = RP::Attachment::LoadOp::clear);
virtual PBaseGeometry InsertGeometry() = 0; virtual RPHandle CreateRenderPass(std::initializer_list<RP::Attachment> ilA, std::initializer_list<RP::Subpass> ilS, std::initializer_list<RP::Dependency> ilD) = 0;
virtual PBasePipeline InsertPipeline() = 0; virtual FBHandle CreateFramebuffer(RPHandle renderPassHandle, std::initializer_list<TexturePtr> il, int w, int h,
virtual PBaseShader InsertShader() = 0; int swapChainBufferIndex = -1, CubeMapFace cubeMapFace = CubeMapFace::none) = 0;
virtual PBaseTexture InsertTexture() = 0; virtual void DeleteRenderPass(RPHandle handle) = 0;
virtual void DeleteFramebuffer(FBHandle handle) = 0;
// </Resources>
virtual void DeleteCommandBuffer(PBaseCommandBuffer p) = 0; static void SetAlphaBlendHelper(
virtual void DeleteGeometry(PBaseGeometry p) = 0; CSZ sz,
virtual void DeletePipeline(PBasePipeline p) = 0; int& colorBlendOp,
virtual void DeleteShader(PBaseShader p) = 0; int& alphaBlendOp,
virtual void DeleteTexture(PBaseTexture p) = 0; int& srcColorBlendFactor,
int& dstColorBlendFactor,
int& srcAlphaBlendFactor,
int& dstAlphaBlendFactor);
RPHandle CreateSimpleRenderPass(Format format, RP::Attachment::LoadOp loadOp = RP::Attachment::LoadOp::dontCare, ImageLayout layout = ImageLayout::fsReadOnly); virtual void UpdateUtilization() {}
RPHandle CreateShadowRenderPass(Format format, RP::Attachment::LoadOp loadOp = RP::Attachment::LoadOp::clear); };
virtual RPHandle CreateRenderPass(std::initializer_list<RP::Attachment> ilA, std::initializer_list<RP::Subpass> ilS, std::initializer_list<RP::Dependency> ilD) = 0; VERUS_TYPEDEFS(BaseRenderer);
virtual FBHandle CreateFramebuffer(RPHandle renderPassHandle, std::initializer_list<TexturePtr> il, int w, int h,
int swapChainBufferIndex = -1, CubeMapFace cubeMapFace = CubeMapFace::none) = 0;
virtual void DeleteRenderPass(RPHandle handle) = 0;
virtual void DeleteFramebuffer(FBHandle handle) = 0;
// </Resources>
static void SetAlphaBlendHelper(
CSZ sz,
int& colorBlendOp,
int& alphaBlendOp,
int& srcColorBlendFactor,
int& dstColorBlendFactor,
int& srcAlphaBlendFactor,
int& dstAlphaBlendFactor);
virtual void UpdateUtilization() {}
};
VERUS_TYPEDEFS(BaseRenderer);
}
extern "C" extern "C"
{ {
typedef CGI::PBaseRenderer(*PFNCREATERENDERER)(UINT32 version, CGI::BaseRendererDesc* pDesc); typedef PBaseRenderer(*PFNCREATERENDERER)(UINT32 version, BaseRendererDesc* pDesc);
} }
} }

View File

@ -1,103 +1,100 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI struct ShaderDesc
{ {
struct ShaderDesc CSZ _url = nullptr;
CSZ _source = nullptr;
CSZ* _branches = nullptr;
CSZ* _ignoreList = nullptr;
CSZ _userDefines = nullptr;
bool _saveCompiled = false;
ShaderDesc(CSZ url = nullptr) : _url(url) {}
};
VERUS_TYPEDEFS(ShaderDesc);
class BaseShader : public Object, public Scheduled
{
static CSZ s_branchCommentMarker;
public:
enum class Stage : int
{ {
CSZ _url = nullptr; vs, // Vertex shader
CSZ _source = nullptr; hs, // Tessellation control shader (Hull shader)
CSZ* _branches = nullptr; ds, // Tessellation evaluation shader (Domain shader)
CSZ* _ignoreList = nullptr; gs, // Geometry shader
CSZ _userDefines = nullptr; fs, // Fragment shader (Pixel shader)
bool _saveCompiled = false; cs, // Compute Shader
count
ShaderDesc(CSZ url = nullptr) : _url(url) {}
}; };
VERUS_TYPEDEFS(ShaderDesc);
class BaseShader : public Object, public Scheduled protected:
{ String _sourceName;
static CSZ s_branchCommentMarker; CSZ* _ignoreList = nullptr;
CSZ _userDefines = nullptr;
bool _saveCompiled = false;
public: BaseShader() = default;
enum class Stage : int virtual ~BaseShader() = default;
{
vs, // Vertex shader
hs, // Tessellation control shader (Hull shader)
ds, // Tessellation evaluation shader (Domain shader)
gs, // Geometry shader
fs, // Fragment shader (Pixel shader)
cs, // Compute Shader
count
};
protected: public:
String _sourceName; virtual void Init(CSZ source, CSZ sourceName, CSZ* branches) = 0;
CSZ* _ignoreList = nullptr; virtual void Done() = 0;
CSZ _userDefines = nullptr;
bool _saveCompiled = false;
BaseShader() = default; void Load(CSZ url);
virtual ~BaseShader() = default; static String Parse(
CSZ branchDesc,
RString entry,
String stageEntries[],
RString stages,
Vector<String>& vMacroName,
Vector<String>& vMacroValue,
CSZ prefix);
static void TestParse();
public: virtual void CreateDescriptorSet(int setNumber, const void* pSrc, int size,
virtual void Init(CSZ source, CSZ sourceName, CSZ* branches) = 0; int capacity = 1, std::initializer_list<Sampler> il = {}, ShaderStageFlags stageFlags = ShaderStageFlags::vs_fs) = 0;
virtual void Done() = 0; virtual void CreatePipelineLayout() = 0;
virtual CSHandle BindDescriptorSetTextures(int setNumber, std::initializer_list<TexturePtr> il,
const int* pMipLevels = nullptr, const int* pArrayLayers = nullptr) = 0;
virtual void FreeDescriptorSet(CSHandle& complexSetHandle) = 0;
void Load(CSZ url); virtual void BeginBindDescriptors() = 0;
static String Parse( virtual void EndBindDescriptors() = 0;
CSZ branchDesc,
RString entry,
String stageEntries[],
RString stages,
Vector<String>& vMacroName,
Vector<String>& vMacroValue,
CSZ prefix);
static void TestParse();
virtual void CreateDescriptorSet(int setNumber, const void* pSrc, int size, Str GetSourceName() const { return _C(_sourceName); }
int capacity = 1, std::initializer_list<Sampler> il = {}, ShaderStageFlags stageFlags = ShaderStageFlags::vs_fs) = 0;
virtual void CreatePipelineLayout() = 0;
virtual CSHandle BindDescriptorSetTextures(int setNumber, std::initializer_list<TexturePtr> il,
const int* pMipLevels = nullptr, const int* pArrayLayers = nullptr) = 0;
virtual void FreeDescriptorSet(CSHandle& complexSetHandle) = 0;
virtual void BeginBindDescriptors() = 0; void SetIgnoreList(CSZ* list) { _ignoreList = list; }
virtual void EndBindDescriptors() = 0; bool IsInIgnoreList(CSZ name) const;
Str GetSourceName() const { return _C(_sourceName); } void SetUserDefines(CSZ def) { _userDefines = def; }
void SetIgnoreList(CSZ* list) { _ignoreList = list; } void SetSaveCompiled(bool b) { _saveCompiled = b; }
bool IsInIgnoreList(CSZ name) const; static void SaveCompiled(CSZ code, CSZ filename);
};
VERUS_TYPEDEFS(BaseShader);
void SetUserDefines(CSZ def) { _userDefines = def; } class ShaderPtr : public Ptr<BaseShader>
{
public:
void Init(RcShaderDesc desc);
};
VERUS_TYPEDEFS(ShaderPtr);
void SetSaveCompiled(bool b) { _saveCompiled = b; } class ShaderPwn : public ShaderPtr
static void SaveCompiled(CSZ code, CSZ filename); {
}; public:
VERUS_TYPEDEFS(BaseShader); ~ShaderPwn() { Done(); }
void Done();
};
VERUS_TYPEDEFS(ShaderPwn);
class ShaderPtr : public Ptr<BaseShader> template<int COUNT>
{ class ShaderPwns : public Pwns<ShaderPwn, COUNT>
public: {
void Init(RcShaderDesc desc); };
};
VERUS_TYPEDEFS(ShaderPtr);
class ShaderPwn : public ShaderPtr
{
public:
~ShaderPwn() { Done(); }
void Done();
};
VERUS_TYPEDEFS(ShaderPwn);
template<int COUNT>
class ShaderPwns : public Pwns<ShaderPwn, COUNT>
{
};
}
} }

View File

@ -1,156 +1,153 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI struct SamplerDesc
{ {
struct SamplerDesc Vector4 _borderColor = Vector4(0);
char _filterMagMinMip[4];
char _addressModeUVW[4];
float _mipLodBias = 0;
float _minLod = 0;
float _maxLod = 15;
SamplerDesc()
{ {
Vector4 _borderColor = Vector4(0); VERUS_ZERO_MEM(_filterMagMinMip);
char _filterMagMinMip[4]; VERUS_ZERO_MEM(_addressModeUVW);
char _addressModeUVW[4]; }
float _mipLodBias = 0;
float _minLod = 0;
float _maxLod = 15;
SamplerDesc() void SetFilter(CSZ f) { strcpy(_filterMagMinMip, f); }
{ void SetAddressMode(CSZ a) { strcpy(_addressModeUVW, a); }
VERUS_ZERO_MEM(_filterMagMinMip); void Set(CSZ f, CSZ a) { SetFilter(f); SetAddressMode(a); }
VERUS_ZERO_MEM(_addressModeUVW); };
} VERUS_TYPEDEFS(SamplerDesc);
void SetFilter(CSZ f) { strcpy(_filterMagMinMip, f); } struct TextureDesc
void SetAddressMode(CSZ a) { strcpy(_addressModeUVW, a); } {
void Set(CSZ f, CSZ a) { SetFilter(f); SetAddressMode(a); } enum class Flags : UINT32
};
VERUS_TYPEDEFS(SamplerDesc);
struct TextureDesc
{ {
enum class Flags : UINT32 none = 0,
{ colorAttachment = (1 << 0), // Texture can be used as a render target.
none = 0, inputAttachment = (1 << 1), // Texture can be used as an input attachment in a framebuffer (optimization for tiled rendering).
colorAttachment = (1 << 0), // Texture can be used as a render target. depthSampledR = (1 << 2), // Depth can be sampled in a shader, initial layout will be depthStencilReadOnly.
inputAttachment = (1 << 1), // Texture can be used as an input attachment in a framebuffer (optimization for tiled rendering). depthSampledW = (1 << 3), // Depth can be sampled in a shader, initial layout will be depthStencilAttachment.
depthSampledR = (1 << 2), // Depth can be sampled in a shader, initial layout will be depthStencilReadOnly. anyShaderResource = (1 << 4), // Will use xsReadOnly as main layout (any shader can sample this texture).
depthSampledW = (1 << 3), // Depth can be sampled in a shader, initial layout will be depthStencilAttachment. generateMips = (1 << 5), // Allows GenerateMips calls. Not compatible with BGRA format on some systems.
anyShaderResource = (1 << 4), // Will use xsReadOnly as main layout (any shader can sample this texture). forceArrayTexture = (1 << 6), // Create array texture even if arrayLayers=1.
generateMips = (1 << 5), // Allows GenerateMips calls. Not compatible with BGRA format on some systems. sync = (1 << 7), // Load image data synchronously.
forceArrayTexture = (1 << 6), // Create array texture even if arrayLayers=1. exposureMips = (1 << 8), // Internal flag for automatic exposure.
sync = (1 << 7), // Load image data synchronously. cubeMap = (1 << 9)
exposureMips = (1 << 8), // Internal flag for automatic exposure.
cubeMap = (1 << 9)
};
Vector4 _clearValue = Vector4(0);
PcSamplerDesc _pSamplerDesc = nullptr;
CSZ _name = nullptr;
CSZ _url = nullptr;
CSZ* _urls = nullptr;
Format _format = Format::unormR8G8B8A8;
int _width = 0;
int _height = 0;
short _depth = 1;
short _mipLevels = 1;
short _arrayLayers = 1;
short _sampleCount = 1;
Flags _flags = Flags::none;
short _texturePart = 0;
short _readbackMip = SHRT_MAX; // -1 means the smallest one, SHRT_MAX means readback is disabled.
TextureDesc(CSZ url = nullptr) : _url(url) {}
void Reset(int w = 0, int h = 0, Format format = Format::unormR8G8B8A8)
{
*this = TextureDesc();
_format = format;
_width = w;
_height = h;
}
}; };
VERUS_TYPEDEFS(TextureDesc);
class BaseTexture : public Object, public IO::AsyncDelegate, public Scheduled Vector4 _clearValue = Vector4(0);
PcSamplerDesc _pSamplerDesc = nullptr;
CSZ _name = nullptr;
CSZ _url = nullptr;
CSZ* _urls = nullptr;
Format _format = Format::unormR8G8B8A8;
int _width = 0;
int _height = 0;
short _depth = 1;
short _mipLevels = 1;
short _arrayLayers = 1;
short _sampleCount = 1;
Flags _flags = Flags::none;
short _texturePart = 0;
short _readbackMip = SHRT_MAX; // -1 means the smallest one, SHRT_MAX means readback is disabled.
TextureDesc(CSZ url = nullptr) : _url(url) {}
void Reset(int w = 0, int h = 0, Format format = Format::unormR8G8B8A8)
{ {
protected: *this = TextureDesc();
Vector4 _size = Vector4(0); _format = format;
String _name; _width = w;
TextureDesc _desc; _height = h;
UINT64 _initAtFrame = 0; }
ImageLayout _mainLayout = ImageLayout::fsReadOnly; };
int _part = 0; VERUS_TYPEDEFS(TextureDesc);
int _bytesPerPixel = 0;
BaseTexture(); class BaseTexture : public Object, public IO::AsyncDelegate, public Scheduled
virtual ~BaseTexture(); {
protected:
Vector4 _size = Vector4(0);
String _name;
TextureDesc _desc;
UINT64 _initAtFrame = 0;
ImageLayout _mainLayout = ImageLayout::fsReadOnly;
int _part = 0;
int _bytesPerPixel = 0;
public: BaseTexture();
virtual void Init(RcTextureDesc desc) = 0; virtual ~BaseTexture();
virtual void Done() = 0;
bool IsLoaded() const { return _desc._width != 0; } public:
Str GetName() const { return _C(_name); } virtual void Init(RcTextureDesc desc) = 0;
virtual void Done() = 0;
RcTextureDesc GetDesc() const { return _desc; } bool IsLoaded() const { return _desc._width != 0; }
RcVector4 GetClearValue() const { return _desc._clearValue; } Str GetName() const { return _C(_name); }
Format GetFormat() const { return _desc._format; }
int GetWidth() const { return _desc._width; }
int GetHeight() const { return _desc._height; }
int GetDepth() const { return _desc._depth; }
int GetMipLevelCount() const { return _desc._mipLevels; }
int GetArrayLayerCount() const { return _desc._arrayLayers; }
int GetPart() const { return _part; } RcTextureDesc GetDesc() const { return _desc; }
RcVector4 GetSize() const { return _size; } RcVector4 GetClearValue() const { return _desc._clearValue; }
bool IsSRGB() const; Format GetFormat() const { return _desc._format; }
Format ToTextureBcFormat(IO::RcDDSHeader header, IO::RcDDSHeaderDXT10 header10) const; int GetWidth() const { return _desc._width; }
int GetHeight() const { return _desc._height; }
int GetDepth() const { return _desc._depth; }
int GetMipLevelCount() const { return _desc._mipLevels; }
int GetArrayLayerCount() const { return _desc._arrayLayers; }
void SetLoadingFlags(TextureDesc::Flags flags) { _desc._flags = flags; } int GetPart() const { return _part; }
void SetLoadingSamplerDesc(PcSamplerDesc pSamplerDesc) { _desc._pSamplerDesc = pSamplerDesc; } RcVector4 GetSize() const { return _size; }
bool IsSRGB() const;
Format ToTextureBcFormat(IO::RcDDSHeader header, IO::RcDDSHeaderDXT10 header10) const;
void LoadDDS(CSZ url, int texturePart = 0); void SetLoadingFlags(TextureDesc::Flags flags) { _desc._flags = flags; }
void LoadDDS(CSZ url, RcBlob blob); void SetLoadingSamplerDesc(PcSamplerDesc pSamplerDesc) { _desc._pSamplerDesc = pSamplerDesc; }
void LoadDDSArray(CSZ* urls);
virtual void Async_WhenLoaded(CSZ url, RcBlob blob) override; void LoadDDS(CSZ url, int texturePart = 0);
void LoadDDS(CSZ url, RcBlob blob);
void LoadDDSArray(CSZ* urls);
virtual void UpdateSubresource(const void* p, int mipLevel = 0, int arrayLayer = 0, BaseCommandBuffer* pCB = nullptr) = 0; virtual void Async_WhenLoaded(CSZ url, RcBlob blob) override;
virtual bool ReadbackSubresource(void* p, bool recordCopyCommand = true, BaseCommandBuffer* pCB = nullptr) = 0;
virtual void GenerateMips(BaseCommandBuffer* pCB = nullptr) = 0; virtual void UpdateSubresource(const void* p, int mipLevel = 0, int arrayLayer = 0, BaseCommandBuffer* pCB = nullptr) = 0;
virtual bool ReadbackSubresource(void* p, bool recordCopyCommand = true, BaseCommandBuffer* pCB = nullptr) = 0;
static int FormatToBytesPerPixel(Format format); virtual void GenerateMips(BaseCommandBuffer* pCB = nullptr) = 0;
static bool IsSRGBFormat(Format format);
static bool IsBC(Format format);
static bool Is4BitsBC(Format format);
static bool IsDepthFormat(Format format);
};
VERUS_TYPEDEFS(BaseTexture);
class TexturePtr : public Ptr<BaseTexture> static int FormatToBytesPerPixel(Format format);
{ static bool IsSRGBFormat(Format format);
public: static bool IsBC(Format format);
TexturePtr() = default; static bool Is4BitsBC(Format format);
TexturePtr(nullptr_t) : Ptr(nullptr) {} static bool IsDepthFormat(Format format);
};
VERUS_TYPEDEFS(BaseTexture);
void Init(RcTextureDesc desc); class TexturePtr : public Ptr<BaseTexture>
{
public:
TexturePtr() = default;
TexturePtr(nullptr_t) : Ptr(nullptr) {}
static TexturePtr From(PBaseTexture p); void Init(RcTextureDesc desc);
};
VERUS_TYPEDEFS(TexturePtr);
class TexturePwn : public TexturePtr static TexturePtr From(PBaseTexture p);
{ };
public: VERUS_TYPEDEFS(TexturePtr);
~TexturePwn() { Done(); }
void Done();
};
VERUS_TYPEDEFS(TexturePwn);
template<int COUNT> class TexturePwn : public TexturePtr
class TexturePwns : public Pwns<TexturePwn, COUNT> {
{ public:
}; ~TexturePwn() { Done(); }
} void Done();
};
VERUS_TYPEDEFS(TexturePwn);
template<int COUNT>
class TexturePwns : public Pwns<TexturePwn, COUNT>
{
};
} }

View File

@ -1,77 +1,74 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class DebugDraw : public Singleton<DebugDraw>, public Object
{ {
class DebugDraw : public Singleton<DebugDraw>, public Object
{
#include "../Shaders/DebugDraw.inc.hlsl" #include "../Shaders/DebugDraw.inc.hlsl"
enum PIPE enum PIPE
{ {
PIPE_POINTS, PIPE_POINTS,
PIPE_POINTS_NO_Z, PIPE_POINTS_NO_Z,
PIPE_LINES, PIPE_LINES,
PIPE_LINES_NO_Z, PIPE_LINES_NO_Z,
PIPE_POLY, PIPE_POLY,
PIPE_POLY_NO_Z, PIPE_POLY_NO_Z,
PIPE_COUNT PIPE_COUNT
};
public:
enum class Type : int
{
points,
lines,
poly
};
private:
struct Vertex
{
float _pos[3];
BYTE _color[4];
};
static UB_DebugDraw s_ubDebugDraw;
GeometryPwn _geo;
ShaderPwn _shader;
PipelinePwns<PIPE_COUNT> _pipe;
Vector<Vertex> _vDynamicBuffer;
UINT64 _currentFrame = UINT64_MAX;
const int _maxVerts = 0x10000;
int _vertCount = 0;
int _offset = 0;
int _peakLoad = 0;
Type _type = Type::points;
public:
DebugDraw();
~DebugDraw();
void Init();
void Done();
void Begin(Type type, PcTransform3 pMat = nullptr, bool zEnable = true);
void End();
bool AddPoint(
RcPoint3 pos,
UINT32 color);
bool AddLine(
RcPoint3 posA,
RcPoint3 posB,
UINT32 colorA,
UINT32 colorB = 0);
bool AddTriangle(
RcPoint3 posA,
RcPoint3 posB,
RcPoint3 posC,
UINT32 color);
}; };
VERUS_TYPEDEFS(DebugDraw);
} public:
enum class Type : int
{
points,
lines,
poly
};
private:
struct Vertex
{
float _pos[3];
BYTE _color[4];
};
static UB_DebugDraw s_ubDebugDraw;
GeometryPwn _geo;
ShaderPwn _shader;
PipelinePwns<PIPE_COUNT> _pipe;
Vector<Vertex> _vDynamicBuffer;
UINT64 _currentFrame = UINT64_MAX;
const int _maxVerts = 0x10000;
int _vertCount = 0;
int _offset = 0;
int _peakLoad = 0;
Type _type = Type::points;
public:
DebugDraw();
~DebugDraw();
void Init();
void Done();
void Begin(Type type, PcTransform3 pMat = nullptr, bool zEnable = true);
void End();
bool AddPoint(
RcPoint3 pos,
UINT32 color);
bool AddLine(
RcPoint3 posA,
RcPoint3 posB,
UINT32 colorA,
UINT32 colorB = 0);
bool AddTriangle(
RcPoint3 posA,
RcPoint3 posB,
RcPoint3 posC,
UINT32 color);
};
VERUS_TYPEDEFS(DebugDraw);
} }

View File

@ -1,20 +1,18 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI enum class LightType : int
{ {
enum class LightType : int none,
{ dir,
none, omni,
dir, spot
omni, };
spot
};
class DeferredShading : public Object class DeferredShading : public Object
{ {
#include "../Shaders/DS.inc.hlsl" #include "../Shaders/DS.inc.hlsl"
#include "../Shaders/DS_Ambient.inc.hlsl" #include "../Shaders/DS_Ambient.inc.hlsl"
#include "../Shaders/DS_AmbientNode.inc.hlsl" #include "../Shaders/DS_AmbientNode.inc.hlsl"
@ -23,207 +21,206 @@ namespace verus
#include "../Shaders/DS_Reflection.inc.hlsl" #include "../Shaders/DS_Reflection.inc.hlsl"
#include "../Shaders/DS_BakeSprites.inc.hlsl" #include "../Shaders/DS_BakeSprites.inc.hlsl"
enum SHADER enum SHADER
{ {
SHADER_LIGHT, SHADER_LIGHT,
SHADER_AMBIENT, SHADER_AMBIENT,
SHADER_AMBIENT_NODE, SHADER_AMBIENT_NODE,
SHADER_PROJECT_NODE, SHADER_PROJECT_NODE,
SHADER_COMPOSE, SHADER_COMPOSE,
SHADER_REFLECTION, SHADER_REFLECTION,
SHADER_BAKE_SPRITES, SHADER_BAKE_SPRITES,
SHADER_COUNT SHADER_COUNT
};
enum PIPE
{
PIPE_INSTANCED_DIR,
PIPE_INSTANCED_OMNI,
PIPE_INSTANCED_SPOT,
PIPE_AMBIENT,
PIPE_AMBIENT_NODE_MUL,
PIPE_AMBIENT_NODE_ADD,
PIPE_PROJECT_NODE,
PIPE_COMPOSE,
PIPE_REFLECTION,
PIPE_REFLECTION_DEBUG,
PIPE_TONE_MAPPING,
PIPE_QUAD,
PIPE_BAKE_SPRITES,
PIPE_COUNT
};
enum TEX
{
TEX_GBUFFER_0, // {Albedo.rgb, SSSHue}.
TEX_GBUFFER_1, // {Normal.xy, Emission, MotionBlur}.
TEX_GBUFFER_2, // {Occlusion, Roughness, Metallic, WrapDiffuse}.
TEX_GBUFFER_3, // {Tangent.xy, AnisoSpec, RoughDiffuse}.
TEX_LIGHT_ACC_AMBIENT,
TEX_LIGHT_ACC_DIFFUSE,
TEX_LIGHT_ACC_SPECULAR,
TEX_COMPOSED_A,
TEX_COMPOSED_B,
TEX_COUNT
};
static UB_View s_ubView;
static UB_SubpassFS s_ubSubpassFS;
static UB_ShadowFS s_ubShadowFS;
static UB_MeshVS s_ubMeshVS;
static UB_Object s_ubObject;
static UB_AmbientVS s_ubAmbientVS;
static UB_AmbientFS s_ubAmbientFS;
static UB_AmbientNodeView s_ubAmbientNodeView;
static UB_AmbientNodeSubpassFS s_ubAmbientNodeSubpassFS;
static UB_AmbientNodeMeshVS s_ubAmbientNodeMeshVS;
static UB_AmbientNodeObject s_ubAmbientNodeObject;
static UB_ProjectNodeView s_ubProjectNodeView;
static UB_ProjectNodeSubpassFS s_ubProjectNodeSubpassFS;
static UB_ProjectNodeMeshVS s_ubProjectNodeMeshVS;
static UB_ProjectNodeTextureFS s_ubProjectNodeTextureFS;
static UB_ProjectNodeObject s_ubProjectNodeObject;
static UB_ComposeVS s_ubComposeVS;
static UB_ComposeFS s_ubComposeFS;
static UB_ReflectionVS s_ubReflectionVS;
static UB_ReflectionFS s_ubReflectionFS;
static UB_BakeSpritesVS s_ubBakeSpritesVS;
static UB_BakeSpritesFS s_ubBakeSpritesFS;
Vector4 _backgroundColor = Vector4(0);
ShaderPwns<SHADER_COUNT> _shader;
PipelinePwns<PIPE_COUNT> _pipe;
TexturePwns<TEX_COUNT> _tex;
TexturePtr _texTerrainHeightmap;
TexturePtr _texTerrainBlend;
UINT64 _frame = 0;
RPHandle _rph;
RPHandle _rphCompose;
RPHandle _rphForwardRendering;
RPHandle _rphReflection;
RPHandle _rphBakeSprites;
FBHandle _fbh;
FBHandle _fbhCompose;
FBHandle _fbhForwardRendering;
FBHandle _fbhReflection;
FBHandle _fbhBakeSprites;
CSHandle _cshLight;
CSHandle _cshLightShadow;
CSHandle _cshAmbient;
CSHandle _cshAmbientNode;
CSHandle _cshProjectNode;
CSHandle _cshCompose;
CSHandle _cshReflection;
CSHandle _cshToneMapping;
CSHandle _cshQuad[7];
CSHandle _cshBakeSprites;
int _terrainMapSide = 1;
bool _activeGeometryPass = false;
bool _activeLightingPass = false;
bool _activeForwardRendering = false;
bool _async_initPipe = false;
public:
DeferredShading();
~DeferredShading();
void Init();
void InitGBuffers(int w, int h);
void InitByBloom(TexturePtr tex);
void InitByCascadedShadowMapBaker(TexturePtr texShadow);
void InitByTerrain(TexturePtr texHeightmap, TexturePtr texBlend, int mapSide);
void Done();
void OnSwapChainResized(bool init, bool done);
static bool IsLoaded();
void ResetInstanceCount();
void Draw(int gbuffer,
RcVector4 rMultiplexer = Vector4(1, 0, 0, 0),
RcVector4 gMultiplexer = Vector4(0, 1, 0, 0),
RcVector4 bMultiplexer = Vector4(0, 0, 1, 0),
RcVector4 aMultiplexer = Vector4(0, 0, 0, 1));
RPHandle GetRenderPassHandle() const { return _rph; }
RPHandle GetRenderPassHandle_ForwardRendering() const { return _rphForwardRendering; }
// <Steps>
void BeginGeometryPass();
void EndGeometryPass();
bool BeginLightingPass(bool ambient = true, bool terrainOcclusion = true);
void EndLightingPass();
void BeginComposeAndForwardRendering(bool underwaterMask = true);
void EndComposeAndForwardRendering();
void DrawReflection();
void ToneMapping();
bool IsActiveGeometryPass() const { return _activeGeometryPass; }
bool IsActiveLightingPass() const { return _activeLightingPass; }
bool IsActiveForwardRendering() const { return _activeForwardRendering; }
// </Steps>
// <Lighting>
static bool IsLightURL(CSZ url);
void BindPipeline_NewLightType(CommandBufferPtr cb, LightType type, bool wireframe = false);
void BindDescriptors_MeshVS(CommandBufferPtr cb);
static UB_MeshVS& GetUbMeshVS() { return s_ubMeshVS; }
CSHandle BindDescriptorSetTexturesForVSM(TexturePtr texShadow);
void BindDescriptorsForVSM(CommandBufferPtr cb, int firstInstance, CSHandle complexSetHandle, float presence);
// </Lighting>
// <AmbientNode>
void BindPipeline_NewAmbientNodePriority(CommandBufferPtr cb, int firstInstance, bool add);
void BindDescriptors_AmbientNodeMeshVS(CommandBufferPtr cb);
static UB_AmbientNodeMeshVS& GetUbAmbientNodeMeshVS() { return s_ubAmbientNodeMeshVS; }
// </AmbientNode>
// <ProjectNode>
void BindPipeline_ProjectNode(CommandBufferPtr cb);
void BindDescriptors_ProjectNodeMeshVS(CommandBufferPtr cb);
static UB_ProjectNodeMeshVS& GetUbProjectNodeMeshVS() { return s_ubProjectNodeMeshVS; }
void BindDescriptors_ProjectNodeTextureFS(CommandBufferPtr cb, CSHandle csh);
void BindDescriptors_ProjectNodeObject(CommandBufferPtr cb);
static UB_ProjectNodeObject& GetUbProjectNodeObject() { return s_ubProjectNodeObject; }
// </ProjectNode>
void Load();
ShaderPtr GetLightShader() const;
ShaderPtr GetAmbientNodeShader() const;
ShaderPtr GetProjectNodeShader() const;
TexturePtr GetGBuffer(int index) const;
TexturePtr GetLightAccAmbientTexture() const;
TexturePtr GetLightAccDiffuseTexture() const;
TexturePtr GetLightAccSpecularTexture() const;
TexturePtr GetComposedTextureA() const;
TexturePtr GetComposedTextureB() const;
static Vector4 GetClearValueForGBuffer0(float albedo = 0);
static Vector4 GetClearValueForGBuffer1(float normal = 0, float motionBlur = 1);
static Vector4 GetClearValueForGBuffer2(float roughness = 0);
static Vector4 GetClearValueForGBuffer3(float tangent = 0);
void SetBackgroundColor(RcVector4 backgroundColor) { _backgroundColor = backgroundColor; }
void BakeSprites(TexturePtr texGBufferIn[4], TexturePtr texGBufferOut[4], PBaseCommandBuffer pCB = nullptr);
void BakeSpritesCleanup();
}; };
VERUS_TYPEDEFS(DeferredShading);
} enum PIPE
{
PIPE_INSTANCED_DIR,
PIPE_INSTANCED_OMNI,
PIPE_INSTANCED_SPOT,
PIPE_AMBIENT,
PIPE_AMBIENT_NODE_MUL,
PIPE_AMBIENT_NODE_ADD,
PIPE_PROJECT_NODE,
PIPE_COMPOSE,
PIPE_REFLECTION,
PIPE_REFLECTION_DEBUG,
PIPE_TONE_MAPPING,
PIPE_QUAD,
PIPE_BAKE_SPRITES,
PIPE_COUNT
};
enum TEX
{
TEX_GBUFFER_0, // {Albedo.rgb, SSSHue}.
TEX_GBUFFER_1, // {Normal.xy, Emission, MotionBlur}.
TEX_GBUFFER_2, // {Occlusion, Roughness, Metallic, WrapDiffuse}.
TEX_GBUFFER_3, // {Tangent.xy, AnisoSpec, RoughDiffuse}.
TEX_LIGHT_ACC_AMBIENT,
TEX_LIGHT_ACC_DIFFUSE,
TEX_LIGHT_ACC_SPECULAR,
TEX_COMPOSED_A,
TEX_COMPOSED_B,
TEX_COUNT
};
static UB_View s_ubView;
static UB_SubpassFS s_ubSubpassFS;
static UB_ShadowFS s_ubShadowFS;
static UB_MeshVS s_ubMeshVS;
static UB_Object s_ubObject;
static UB_AmbientVS s_ubAmbientVS;
static UB_AmbientFS s_ubAmbientFS;
static UB_AmbientNodeView s_ubAmbientNodeView;
static UB_AmbientNodeSubpassFS s_ubAmbientNodeSubpassFS;
static UB_AmbientNodeMeshVS s_ubAmbientNodeMeshVS;
static UB_AmbientNodeObject s_ubAmbientNodeObject;
static UB_ProjectNodeView s_ubProjectNodeView;
static UB_ProjectNodeSubpassFS s_ubProjectNodeSubpassFS;
static UB_ProjectNodeMeshVS s_ubProjectNodeMeshVS;
static UB_ProjectNodeTextureFS s_ubProjectNodeTextureFS;
static UB_ProjectNodeObject s_ubProjectNodeObject;
static UB_ComposeVS s_ubComposeVS;
static UB_ComposeFS s_ubComposeFS;
static UB_ReflectionVS s_ubReflectionVS;
static UB_ReflectionFS s_ubReflectionFS;
static UB_BakeSpritesVS s_ubBakeSpritesVS;
static UB_BakeSpritesFS s_ubBakeSpritesFS;
Vector4 _backgroundColor = Vector4(0);
ShaderPwns<SHADER_COUNT> _shader;
PipelinePwns<PIPE_COUNT> _pipe;
TexturePwns<TEX_COUNT> _tex;
TexturePtr _texTerrainHeightmap;
TexturePtr _texTerrainBlend;
UINT64 _frame = 0;
RPHandle _rph;
RPHandle _rphCompose;
RPHandle _rphForwardRendering;
RPHandle _rphReflection;
RPHandle _rphBakeSprites;
FBHandle _fbh;
FBHandle _fbhCompose;
FBHandle _fbhForwardRendering;
FBHandle _fbhReflection;
FBHandle _fbhBakeSprites;
CSHandle _cshLight;
CSHandle _cshLightShadow;
CSHandle _cshAmbient;
CSHandle _cshAmbientNode;
CSHandle _cshProjectNode;
CSHandle _cshCompose;
CSHandle _cshReflection;
CSHandle _cshToneMapping;
CSHandle _cshQuad[7];
CSHandle _cshBakeSprites;
int _terrainMapSide = 1;
bool _activeGeometryPass = false;
bool _activeLightingPass = false;
bool _activeForwardRendering = false;
bool _async_initPipe = false;
public:
DeferredShading();
~DeferredShading();
void Init();
void InitGBuffers(int w, int h);
void InitByBloom(TexturePtr tex);
void InitByCascadedShadowMapBaker(TexturePtr texShadow);
void InitByTerrain(TexturePtr texHeightmap, TexturePtr texBlend, int mapSide);
void Done();
void OnSwapChainResized(bool init, bool done);
static bool IsLoaded();
void ResetInstanceCount();
void Draw(int gbuffer,
RcVector4 rMultiplexer = Vector4(1, 0, 0, 0),
RcVector4 gMultiplexer = Vector4(0, 1, 0, 0),
RcVector4 bMultiplexer = Vector4(0, 0, 1, 0),
RcVector4 aMultiplexer = Vector4(0, 0, 0, 1));
RPHandle GetRenderPassHandle() const { return _rph; }
RPHandle GetRenderPassHandle_ForwardRendering() const { return _rphForwardRendering; }
// <Steps>
void BeginGeometryPass();
void EndGeometryPass();
bool BeginLightingPass(bool ambient = true, bool terrainOcclusion = true);
void EndLightingPass();
void BeginComposeAndForwardRendering(bool underwaterMask = true);
void EndComposeAndForwardRendering();
void DrawReflection();
void ToneMapping();
bool IsActiveGeometryPass() const { return _activeGeometryPass; }
bool IsActiveLightingPass() const { return _activeLightingPass; }
bool IsActiveForwardRendering() const { return _activeForwardRendering; }
// </Steps>
// <Lighting>
static bool IsLightURL(CSZ url);
void BindPipeline_NewLightType(CommandBufferPtr cb, LightType type, bool wireframe = false);
void BindDescriptors_MeshVS(CommandBufferPtr cb);
static UB_MeshVS& GetUbMeshVS() { return s_ubMeshVS; }
CSHandle BindDescriptorSetTexturesForVSM(TexturePtr texShadow);
void BindDescriptorsForVSM(CommandBufferPtr cb, int firstInstance, CSHandle complexSetHandle, float presence);
// </Lighting>
// <AmbientNode>
void BindPipeline_NewAmbientNodePriority(CommandBufferPtr cb, int firstInstance, bool add);
void BindDescriptors_AmbientNodeMeshVS(CommandBufferPtr cb);
static UB_AmbientNodeMeshVS& GetUbAmbientNodeMeshVS() { return s_ubAmbientNodeMeshVS; }
// </AmbientNode>
// <ProjectNode>
void BindPipeline_ProjectNode(CommandBufferPtr cb);
void BindDescriptors_ProjectNodeMeshVS(CommandBufferPtr cb);
static UB_ProjectNodeMeshVS& GetUbProjectNodeMeshVS() { return s_ubProjectNodeMeshVS; }
void BindDescriptors_ProjectNodeTextureFS(CommandBufferPtr cb, CSHandle csh);
void BindDescriptors_ProjectNodeObject(CommandBufferPtr cb);
static UB_ProjectNodeObject& GetUbProjectNodeObject() { return s_ubProjectNodeObject; }
// </ProjectNode>
void Load();
ShaderPtr GetLightShader() const;
ShaderPtr GetAmbientNodeShader() const;
ShaderPtr GetProjectNodeShader() const;
TexturePtr GetGBuffer(int index) const;
TexturePtr GetLightAccAmbientTexture() const;
TexturePtr GetLightAccDiffuseTexture() const;
TexturePtr GetLightAccSpecularTexture() const;
TexturePtr GetComposedTextureA() const;
TexturePtr GetComposedTextureB() const;
static Vector4 GetClearValueForGBuffer0(float albedo = 0);
static Vector4 GetClearValueForGBuffer1(float normal = 0, float motionBlur = 1);
static Vector4 GetClearValueForGBuffer2(float roughness = 0);
static Vector4 GetClearValueForGBuffer3(float tangent = 0);
void SetBackgroundColor(RcVector4 backgroundColor) { _backgroundColor = backgroundColor; }
void BakeSprites(TexturePtr texGBufferIn[4], TexturePtr texGBufferOut[4], PBaseCommandBuffer pCB = nullptr);
void BakeSpritesCleanup();
};
VERUS_TYPEDEFS(DeferredShading);
} }

View File

@ -1,89 +1,86 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI template<typename T>
class DynamicBuffer : public GeometryPwn
{ {
template<typename T> Vector<T> _vVB;
class DynamicBuffer : public GeometryPwn int _maxVerts = 1024;
int _vertCount = 0;
int _firstVertex = 0;
public:
DynamicBuffer()
{ {
Vector<T> _vVB; }
int _maxVerts = 1024;
int _vertCount = 0;
int _firstVertex = 0;
public: ~DynamicBuffer()
DynamicBuffer() {
{ }
}
~DynamicBuffer() void Init(RcGeometryDesc desc, int maxVerts = 1024)
{ {
} _maxVerts = maxVerts;
GeometryDesc dynDesc(desc);
dynDesc._dynBindingsMask = 0x1;
GeometryPwn::Init(dynDesc);
}
void Init(RcGeometryDesc desc, int maxVerts = 1024) void CreateVertexBuffer()
{ {
_maxVerts = maxVerts; _vVB.resize(_maxVerts);
GeometryDesc dynDesc(desc); (*this)->CreateVertexBuffer(_maxVerts, 0);
dynDesc._dynBindingsMask = 0x1; }
GeometryPwn::Init(dynDesc);
}
void CreateVertexBuffer() void Reset()
{ {
_vVB.resize(_maxVerts); _vertCount = 0;
(*this)->CreateVertexBuffer(_maxVerts, 0); _firstVertex = 0;
} }
void Reset() void Begin()
{ {
_vertCount = 0; _firstVertex = _vertCount;
_firstVertex = 0; }
}
void Begin() void End(BaseCommandBuffer* pCB = nullptr)
{
VERUS_QREF_RENDERER;
const int vertCount = _vertCount - _firstVertex;
if (vertCount)
{ {
_firstVertex = _vertCount; if (!pCB)
pCB = renderer.GetCommandBuffer().Get();
(*this)->UpdateVertexBuffer(&_vVB[_firstVertex], 0, pCB, vertCount, _firstVertex);
pCB->Draw(vertCount, 1, _firstVertex);
} }
}
void End(BaseCommandBuffer* pCB = nullptr) bool Add(const T& v)
{ {
VERUS_QREF_RENDERER; if (_vertCount + 1 > _maxVerts)
const int vertCount = _vertCount - _firstVertex; return false;
if (vertCount) _vVB[_vertCount++] = v;
{ return true;
if (!pCB) }
pCB = renderer.GetCommandBuffer().Get();
(*this)->UpdateVertexBuffer(&_vVB[_firstVertex], 0, pCB, vertCount, _firstVertex);
pCB->Draw(vertCount, 1, _firstVertex);
}
}
bool Add(const T& v) bool AddQuad(
{ const T& a0,
if (_vertCount + 1 > _maxVerts) const T& a1,
return false; const T& b0,
_vVB[_vertCount++] = v; const T& b1)
return true; {
} if (_vertCount + 6 > _maxVerts)
return false;
bool AddQuad( _vVB[_vertCount++] = a0;
const T& a0, _vVB[_vertCount++] = b0;
const T& a1, _vVB[_vertCount++] = a1;
const T& b0, _vVB[_vertCount++] = a1;
const T& b1) _vVB[_vertCount++] = b0;
{ _vVB[_vertCount++] = b1;
if (_vertCount + 6 > _maxVerts) return true;
return false; }
_vVB[_vertCount++] = a0; };
_vVB[_vertCount++] = b0;
_vVB[_vertCount++] = a1;
_vVB[_vertCount++] = a1;
_vVB[_vertCount++] = b0;
_vVB[_vertCount++] = b1;
return true;
}
};
}
} }

View File

@ -1,54 +1,51 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI // See: https://vulkan.gpuinfo.org/listformats.php?platform=android
enum class Format : int
{ {
// See: https://vulkan.gpuinfo.org/listformats.php?platform=android // Special Formats:
enum class Format : int unormR10G10B10A2,
{ sintR16,
// Special Formats: floatR11G11B10,
unormR10G10B10A2,
sintR16,
floatR11G11B10,
// Unsigned Formats: // Unsigned Formats:
unormR8, unormR8,
unormR8G8, unormR8G8,
unormR8G8B8A8, unormR8G8B8A8,
unormB8G8R8A8, unormB8G8R8A8,
srgbR8G8B8A8, srgbR8G8B8A8,
srgbB8G8R8A8, srgbB8G8R8A8,
// Floating-Point Formats: // Floating-Point Formats:
floatR16, floatR16,
floatR16G16, floatR16G16,
floatR16G16B16A16, floatR16G16B16A16,
// IEEE Formats: // IEEE Formats:
floatR32, floatR32,
floatR32G32, floatR32G32,
floatR32G32B32A32, floatR32G32B32A32,
// Depth-Stencil: // Depth-Stencil:
unormD16, unormD16,
unormD24uintS8, unormD24uintS8,
floatD32, floatD32,
// Compressed Texture Formats: // Compressed Texture Formats:
unormBC1, // Deprecated RGBA. unormBC1, // Deprecated RGBA.
unormBC2, // Deprecated RGBA. unormBC2, // Deprecated RGBA.
unormBC3, // Deprecated RGBA. unormBC3, // Deprecated RGBA.
unormBC4, // R. unormBC4, // R.
unormBC5, // RG. unormBC5, // RG.
unormBC7, // RGBA. unormBC7, // RGBA.
snormBC4, // R. snormBC4, // R.
snormBC5, // RG. snormBC5, // RG.
srgbBC1, // Deprecated RGBA. srgbBC1, // Deprecated RGBA.
srgbBC2, // Deprecated RGBA. srgbBC2, // Deprecated RGBA.
srgbBC3, // Deprecated RGBA. srgbBC3, // Deprecated RGBA.
srgbBC7 // RGBA. srgbBC7 // RGBA.
}; };
}
} }

View File

@ -1,93 +1,87 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI::RP
{ {
namespace CGI class Attachment
{ {
namespace RP public:
enum class LoadOp : int
{ {
class Attachment load,
{ clear,
public: dontCare
enum class LoadOp : int };
{
load,
clear,
dontCare
};
enum class StoreOp : int enum class StoreOp : int
{ {
store, store,
dontCare dontCare
}; };
CSZ _name = nullptr; CSZ _name = nullptr;
Format _format = Format::unormR8G8B8A8; Format _format = Format::unormR8G8B8A8;
int _sampleCount = 1; int _sampleCount = 1;
LoadOp _loadOp = LoadOp::load; LoadOp _loadOp = LoadOp::load;
StoreOp _storeOp = StoreOp::store; StoreOp _storeOp = StoreOp::store;
LoadOp _stencilLoadOp = LoadOp::dontCare; LoadOp _stencilLoadOp = LoadOp::dontCare;
StoreOp _stencilStoreOp = StoreOp::dontCare; StoreOp _stencilStoreOp = StoreOp::dontCare;
ImageLayout _initialLayout = ImageLayout::undefined; ImageLayout _initialLayout = ImageLayout::undefined;
ImageLayout _finalLayout = ImageLayout::undefined; ImageLayout _finalLayout = ImageLayout::undefined;
Attachment(CSZ name, Format format, int sampleCount = 1); Attachment(CSZ name, Format format, int sampleCount = 1);
Attachment& SetLoadOp(LoadOp op); Attachment& SetLoadOp(LoadOp op);
Attachment& LoadOpClear(); Attachment& LoadOpClear();
Attachment& LoadOpDontCare(); Attachment& LoadOpDontCare();
Attachment& SetStoreOp(StoreOp op); Attachment& SetStoreOp(StoreOp op);
Attachment& StoreOpDontCare(); Attachment& StoreOpDontCare();
Attachment& Layout(ImageLayout whenBegins, ImageLayout whenEnds); Attachment& Layout(ImageLayout whenBegins, ImageLayout whenEnds);
Attachment& Layout(ImageLayout both); Attachment& Layout(ImageLayout both);
}; };
VERUS_TYPEDEFS(Attachment); VERUS_TYPEDEFS(Attachment);
class Ref class Ref
{ {
public: public:
CSZ _name = nullptr; CSZ _name = nullptr;
ImageLayout _layout = ImageLayout::undefined; ImageLayout _layout = ImageLayout::undefined;
Ref() = default; Ref() = default;
Ref(CSZ name, ImageLayout layout) : _name(name), _layout(layout) {} Ref(CSZ name, ImageLayout layout) : _name(name), _layout(layout) {}
}; };
VERUS_TYPEDEFS(Ref); VERUS_TYPEDEFS(Ref);
class Subpass class Subpass
{ {
public: public:
CSZ _name = nullptr; CSZ _name = nullptr;
std::initializer_list<Ref> _ilInput; std::initializer_list<Ref> _ilInput;
std::initializer_list<Ref> _ilColor; std::initializer_list<Ref> _ilColor;
std::initializer_list<Ref> _ilResolve; std::initializer_list<Ref> _ilResolve;
std::initializer_list<Ref> _ilPreserve; std::initializer_list<Ref> _ilPreserve;
Ref _depthStencil; Ref _depthStencil;
Subpass(CSZ name); Subpass(CSZ name);
Subpass& Input(std::initializer_list<Ref> il); Subpass& Input(std::initializer_list<Ref> il);
Subpass& Color(std::initializer_list<Ref> il); Subpass& Color(std::initializer_list<Ref> il);
Subpass& Resolve(std::initializer_list<Ref> il); Subpass& Resolve(std::initializer_list<Ref> il);
Subpass& Preserve(std::initializer_list<Ref> il); Subpass& Preserve(std::initializer_list<Ref> il);
Subpass& DepthStencil(Ref r); Subpass& DepthStencil(Ref r);
}; };
VERUS_TYPEDEFS(Subpass); VERUS_TYPEDEFS(Subpass);
class Dependency class Dependency
{ {
public: public:
CSZ _srcSubpass = nullptr; CSZ _srcSubpass = nullptr;
CSZ _dstSubpass = nullptr; CSZ _dstSubpass = nullptr;
int _mode = 0; int _mode = 0;
Dependency(CSZ src = nullptr, CSZ dst = nullptr); Dependency(CSZ src = nullptr, CSZ dst = nullptr);
Dependency& Mode(int mode); Dependency& Mode(int mode);
}; };
VERUS_TYPEDEFS(Dependency); VERUS_TYPEDEFS(Dependency);
}
}
} }

View File

@ -1,209 +1,206 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI struct RendererDelegate
{ {
struct RendererDelegate virtual void Renderer_OnDraw() = 0;
{ virtual void Renderer_OnDrawView(RcViewDesc viewDesc) = 0;
virtual void Renderer_OnDraw() = 0; };
virtual void Renderer_OnDrawView(RcViewDesc viewDesc) = 0; VERUS_TYPEDEFS(RendererDelegate);
};
VERUS_TYPEDEFS(RendererDelegate);
class Renderer : public Singleton<Renderer>, public Object class Renderer : public Singleton<Renderer>, public Object
{ {
#include "../Shaders/GenerateMips.inc.hlsl" #include "../Shaders/GenerateMips.inc.hlsl"
#include "../Shaders/GenerateCubeMapMips.inc.hlsl" #include "../Shaders/GenerateCubeMapMips.inc.hlsl"
#include "../Shaders/Quad.inc.hlsl" #include "../Shaders/Quad.inc.hlsl"
enum SHADER enum SHADER
{ {
SHADER_GENERATE_MIPS, SHADER_GENERATE_MIPS,
SHADER_GENERATE_CUBE_MAP_MIPS, SHADER_GENERATE_CUBE_MAP_MIPS,
SHADER_QUAD, SHADER_QUAD,
SHADER_COUNT SHADER_COUNT
};
enum PIPE
{
PIPE_GENERATE_MIPS,
PIPE_GENERATE_MIPS_EXPOSURE,
PIPE_GENERATE_CUBE_MAP_MIPS,
PIPE_OFFSCREEN_COLOR,
PIPE_COUNT
};
enum TEX
{
TEX_OFFSCREEN_COLOR,
TEX_DEPTH_STENCIL,
TEX_COUNT
};
struct Utilization
{
String _name;
INT64 _value = 0;
INT64 _total = 0;
float _fraction = 0;
float _balance = 0;
};
VERUS_TYPEDEFS(Utilization);
struct Vertex
{
glm::vec2 _pos;
};
Vector<Utilization> _vUtilization;
App::PWindow _pMainWindow = nullptr;
PBaseRenderer _pBaseRenderer = nullptr;
PRendererDelegate _pRendererDelegate = nullptr;
CommandBufferPwn _commandBuffer;
GeometryPwn _geoQuad;
ShaderPwns<SHADER_COUNT> _shader;
PipelinePwns<PIPE_COUNT> _pipe;
TexturePwns<TEX_COUNT> _tex;
DeferredShading _ds;
UINT64 _frameCount = 0;
Gapi _gapi = Gapi::unknown;
int _screenSwapChainWidth = 0;
int _screenSwapChainHeight = 0;
int _combinedSwapChainWidth = 0;
int _combinedSwapChainHeight = 0;
ViewType _currentViewType = ViewType::none;
int _currentViewIndex = 0;
int _currentViewWidth = 0;
int _currentViewHeight = 0;
int _currentViewX = 0;
int _currentViewY = 0;
float _preferredZNear = 0.1f;
float _preferredZFar = 10000;
float _fps = 30;
float _exposure[2] = {}; // Linear and EV.
RPHandle _rphScreenSwapChain;
RPHandle _rphScreenSwapChainWithDepth;
Vector<FBHandle> _fbhScreenSwapChain;
Vector<FBHandle> _fbhScreenSwapChainWithDepth;
RPHandle _rphOffscreen;
RPHandle _rphOffscreenWithDepth;
FBHandle _fbhOffscreen;
FBHandle _fbhOffscreenWithDepth;
CSHandle _cshOffscreenColor;
UB_GenerateMips _ubGenerateMips;
UB_GenerateCubeMapMips _ubGenerateCubeMapMips;
UB_QuadVS _ubQuadVS;
UB_QuadFS _ubQuadFS;
int _utilIgnoreIfTotal = 0;
bool _utilSortByBalance = false;
bool _autoExposure = true;
bool _allowInitShaders = true;
bool _showUtilization = false;
public:
Renderer();
~Renderer();
// Device-specific:
PBaseRenderer operator->();
static bool IsLoaded();
void Init(PRendererDelegate pDelegate, bool allowInitShaders = true);
void InitCmd();
void Done();
// Frame cycle:
void Update();
void Draw();
void BeginFrame();
void AcquireSwapChainImage();
void EndFrame();
// Window:
App::PWindow GetMainWindow() const { return _pMainWindow; }
App::PWindow SetMainWindow(App::PWindow p) { return Utils::Swap(_pMainWindow, p); }
bool OnWindowSizeChanged(int w, int h);
// Swap chain & view:
void UpdateCombinedSwapChainSize();
VERUS_P(void OnScreenSwapChainResized(bool init, bool done));
int GetScreenSwapChainWidth() const { return _screenSwapChainWidth; }
int GetScreenSwapChainHeight() const { return _screenSwapChainHeight; }
int GetCombinedSwapChainWidth() const { return _combinedSwapChainWidth; }
int GetCombinedSwapChainHeight() const { return _combinedSwapChainHeight; }
ViewType GetCurrentViewType() const { return _currentViewType; }
int GetCurrentViewWidth() const { return _currentViewWidth; }
int GetCurrentViewHeight() const { return _currentViewHeight; }
int GetCurrentViewX() const { return _currentViewX; }
int GetCurrentViewY() const { return _currentViewY; }
float GetCurrentViewAspectRatio() const;
static Format GetSwapChainFormat() { return Format::srgbB8G8R8A8; }
float GetPreferredZNear() const { return _preferredZNear; }
float GetPreferredZFar() const { return _preferredZFar; }
// Simple (fullscreen) quad:
void DrawQuad(PBaseCommandBuffer pCB = nullptr);
void DrawOffscreenColor(PBaseCommandBuffer pCB = nullptr, bool endRenderPass = true);
void DrawOffscreenColorSwitchRenderPass(PBaseCommandBuffer pCB = nullptr);
CommandBufferPtr GetCommandBuffer() const { return _commandBuffer; }
TexturePtr GetTexOffscreenColor() const;
TexturePtr GetTexDepthStencil() const;
RDeferredShading GetDS() { return _ds; }
void OnShaderError(CSZ s);
void OnShaderWarning(CSZ s);
// ImGui:
virtual void ImGuiSetCurrentContext(ImGuiContext* pContext);
void ImGuiUpdateStyle();
// Frame rate:
float GetFps() const { return _fps; }
UINT64 GetFrameCount() const { return _frameCount; }
// RenderPass & Framebuffer:
RPHandle GetRenderPassHandle_ScreenSwapChain() const;
RPHandle GetRenderPassHandle_ScreenSwapChainWithDepth() const;
RPHandle GetRenderPassHandle_Offscreen() const;
RPHandle GetRenderPassHandle_OffscreenWithDepth() const;
RPHandle GetRenderPassHandle_Auto() const;
RPHandle GetRenderPassHandle_AutoWithDepth() const;
FBHandle GetFramebufferHandle_ScreenSwapChain(int index) const;
FBHandle GetFramebufferHandle_ScreenSwapChainWithDepth(int index) const;
FBHandle GetFramebufferHandle_Offscreen() const;
FBHandle GetFramebufferHandle_OffscreenWithDepth() const;
FBHandle GetFramebufferHandle_Auto(int index) const;
FBHandle GetFramebufferHandle_AutoWithDepth(int index) const;
// Generate mips:
ShaderPtr GetShaderGenerateMips() const;
ShaderPtr GetShaderGenerateCubeMapMips() const;
PipelinePtr GetPipelineGenerateMips(bool exposure = false) const;
PipelinePtr GetPipelineGenerateCubeMapMips() const;
UB_GenerateMips& GetUbGenerateMips();
UB_GenerateCubeMapMips& GetUbGenerateCubeMapMips();
// Quad:
GeometryPtr GetGeoQuad() const;
ShaderPtr GetShaderQuad() const;
UB_QuadVS& GetUbQuadVS();
UB_QuadFS& GetUbQuadFS();
void ResetQuadMultiplexer();
// Exposure:
bool IsAutoExposureEnabled() const { return _autoExposure; }
void EnableAutoExposure(bool b = true) { _autoExposure = b; }
float GetExposure() const { return _exposure[0]; }
float GetExposureValue() const { return _exposure[1]; }
void SetExposureValue(float ev);
void ToggleUtilization() { _showUtilization = !_showUtilization; }
void UpdateUtilization();
void AddUtilization(CSZ name, INT64 value, INT64 total);
}; };
VERUS_TYPEDEFS(Renderer);
} enum PIPE
{
PIPE_GENERATE_MIPS,
PIPE_GENERATE_MIPS_EXPOSURE,
PIPE_GENERATE_CUBE_MAP_MIPS,
PIPE_OFFSCREEN_COLOR,
PIPE_COUNT
};
enum TEX
{
TEX_OFFSCREEN_COLOR,
TEX_DEPTH_STENCIL,
TEX_COUNT
};
struct Utilization
{
String _name;
INT64 _value = 0;
INT64 _total = 0;
float _fraction = 0;
float _balance = 0;
};
VERUS_TYPEDEFS(Utilization);
struct Vertex
{
glm::vec2 _pos;
};
Vector<Utilization> _vUtilization;
App::PWindow _pMainWindow = nullptr;
PBaseRenderer _pBaseRenderer = nullptr;
PRendererDelegate _pRendererDelegate = nullptr;
CommandBufferPwn _commandBuffer;
GeometryPwn _geoQuad;
ShaderPwns<SHADER_COUNT> _shader;
PipelinePwns<PIPE_COUNT> _pipe;
TexturePwns<TEX_COUNT> _tex;
DeferredShading _ds;
UINT64 _frameCount = 0;
Gapi _gapi = Gapi::unknown;
int _screenSwapChainWidth = 0;
int _screenSwapChainHeight = 0;
int _combinedSwapChainWidth = 0;
int _combinedSwapChainHeight = 0;
ViewType _currentViewType = ViewType::none;
int _currentViewIndex = 0;
int _currentViewWidth = 0;
int _currentViewHeight = 0;
int _currentViewX = 0;
int _currentViewY = 0;
float _preferredZNear = 0.1f;
float _preferredZFar = 10000;
float _fps = 30;
float _exposure[2] = {}; // Linear and EV.
RPHandle _rphScreenSwapChain;
RPHandle _rphScreenSwapChainWithDepth;
Vector<FBHandle> _fbhScreenSwapChain;
Vector<FBHandle> _fbhScreenSwapChainWithDepth;
RPHandle _rphOffscreen;
RPHandle _rphOffscreenWithDepth;
FBHandle _fbhOffscreen;
FBHandle _fbhOffscreenWithDepth;
CSHandle _cshOffscreenColor;
UB_GenerateMips _ubGenerateMips;
UB_GenerateCubeMapMips _ubGenerateCubeMapMips;
UB_QuadVS _ubQuadVS;
UB_QuadFS _ubQuadFS;
int _utilIgnoreIfTotal = 0;
bool _utilSortByBalance = false;
bool _autoExposure = true;
bool _allowInitShaders = true;
bool _showUtilization = false;
public:
Renderer();
~Renderer();
// Device-specific:
PBaseRenderer operator->();
static bool IsLoaded();
void Init(PRendererDelegate pDelegate, bool allowInitShaders = true);
void InitCmd();
void Done();
// Frame cycle:
void Update();
void Draw();
void BeginFrame();
void AcquireSwapChainImage();
void EndFrame();
// Window:
App::PWindow GetMainWindow() const { return _pMainWindow; }
App::PWindow SetMainWindow(App::PWindow p) { return Utils::Swap(_pMainWindow, p); }
bool OnWindowSizeChanged(int w, int h);
// Swap chain & view:
void UpdateCombinedSwapChainSize();
VERUS_P(void OnScreenSwapChainResized(bool init, bool done));
int GetScreenSwapChainWidth() const { return _screenSwapChainWidth; }
int GetScreenSwapChainHeight() const { return _screenSwapChainHeight; }
int GetCombinedSwapChainWidth() const { return _combinedSwapChainWidth; }
int GetCombinedSwapChainHeight() const { return _combinedSwapChainHeight; }
ViewType GetCurrentViewType() const { return _currentViewType; }
int GetCurrentViewWidth() const { return _currentViewWidth; }
int GetCurrentViewHeight() const { return _currentViewHeight; }
int GetCurrentViewX() const { return _currentViewX; }
int GetCurrentViewY() const { return _currentViewY; }
float GetCurrentViewAspectRatio() const;
static Format GetSwapChainFormat() { return Format::srgbB8G8R8A8; }
float GetPreferredZNear() const { return _preferredZNear; }
float GetPreferredZFar() const { return _preferredZFar; }
// Simple (fullscreen) quad:
void DrawQuad(PBaseCommandBuffer pCB = nullptr);
void DrawOffscreenColor(PBaseCommandBuffer pCB = nullptr, bool endRenderPass = true);
void DrawOffscreenColorSwitchRenderPass(PBaseCommandBuffer pCB = nullptr);
CommandBufferPtr GetCommandBuffer() const { return _commandBuffer; }
TexturePtr GetTexOffscreenColor() const;
TexturePtr GetTexDepthStencil() const;
RDeferredShading GetDS() { return _ds; }
void OnShaderError(CSZ s);
void OnShaderWarning(CSZ s);
// ImGui:
virtual void ImGuiSetCurrentContext(ImGuiContext* pContext);
void ImGuiUpdateStyle();
// Frame rate:
float GetFps() const { return _fps; }
UINT64 GetFrameCount() const { return _frameCount; }
// RenderPass & Framebuffer:
RPHandle GetRenderPassHandle_ScreenSwapChain() const;
RPHandle GetRenderPassHandle_ScreenSwapChainWithDepth() const;
RPHandle GetRenderPassHandle_Offscreen() const;
RPHandle GetRenderPassHandle_OffscreenWithDepth() const;
RPHandle GetRenderPassHandle_Auto() const;
RPHandle GetRenderPassHandle_AutoWithDepth() const;
FBHandle GetFramebufferHandle_ScreenSwapChain(int index) const;
FBHandle GetFramebufferHandle_ScreenSwapChainWithDepth(int index) const;
FBHandle GetFramebufferHandle_Offscreen() const;
FBHandle GetFramebufferHandle_OffscreenWithDepth() const;
FBHandle GetFramebufferHandle_Auto(int index) const;
FBHandle GetFramebufferHandle_AutoWithDepth(int index) const;
// Generate mips:
ShaderPtr GetShaderGenerateMips() const;
ShaderPtr GetShaderGenerateCubeMapMips() const;
PipelinePtr GetPipelineGenerateMips(bool exposure = false) const;
PipelinePtr GetPipelineGenerateCubeMapMips() const;
UB_GenerateMips& GetUbGenerateMips();
UB_GenerateCubeMapMips& GetUbGenerateCubeMapMips();
// Quad:
GeometryPtr GetGeoQuad() const;
ShaderPtr GetShaderQuad() const;
UB_QuadVS& GetUbQuadVS();
UB_QuadFS& GetUbQuadFS();
void ResetQuadMultiplexer();
// Exposure:
bool IsAutoExposureEnabled() const { return _autoExposure; }
void EnableAutoExposure(bool b = true) { _autoExposure = b; }
float GetExposure() const { return _exposure[0]; }
float GetExposureValue() const { return _exposure[1]; }
void SetExposureValue(float ev);
void ToggleUtilization() { _showUtilization = !_showUtilization; }
void UpdateUtilization();
void AddUtilization(CSZ name, INT64 value, INT64 total);
};
VERUS_TYPEDEFS(Renderer);
} }

View File

@ -1,20 +1,17 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class RendererParser
{ {
class RendererParser static int StrCompare(const void* pA, const void* pB);
{
static int StrCompare(const void* pA, const void* pB);
public: public:
static int Expect(CSZ& p, CSZ* ppOptions); static int Expect(CSZ& p, CSZ* ppOptions);
static int ExpectBlendOp(CSZ& p); static int ExpectBlendOp(CSZ& p);
static int ExpectCompFunc(CSZ& p, char end, bool skipSpace); static int ExpectCompFunc(CSZ& p, char end, bool skipSpace);
static int ExpectStencilOp(CSZ& p, char end, bool skipSpace); static int ExpectStencilOp(CSZ& p, char end, bool skipSpace);
static int SkipSpace(CSZ& p); static int SkipSpace(CSZ& p);
}; };
}
} }

View File

@ -1,21 +1,18 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class Scheduled
{ {
class Scheduled UINT64 _doneFrame = UINT64_MAX;
{
UINT64 _doneFrame = UINT64_MAX;
public: public:
virtual Continue Scheduled_Update() { return Continue::no; } virtual Continue Scheduled_Update() { return Continue::no; }
void Schedule(INT64 extraFrameCount = -1); void Schedule(INT64 extraFrameCount = -1);
void ForceScheduled(); void ForceScheduled();
bool IsScheduledAllowed(); bool IsScheduledAllowed();
}; };
VERUS_TYPEDEFS(Scheduled); VERUS_TYPEDEFS(Scheduled);
}
} }

View File

@ -1,28 +1,25 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI class TextureRAM : public BaseTexture
{ {
class TextureRAM : public BaseTexture Vector<BYTE> _vBuffer;
{
Vector<BYTE> _vBuffer;
public: public:
TextureRAM(); TextureRAM();
virtual ~TextureRAM() override; virtual ~TextureRAM() override;
virtual void Init(RcTextureDesc desc) override; virtual void Init(RcTextureDesc desc) override;
virtual void Done() override; virtual void Done() override;
virtual void UpdateSubresource(const void* p, int mipLevel, int arrayLayer, PBaseCommandBuffer pCB) override; virtual void UpdateSubresource(const void* p, int mipLevel, int arrayLayer, PBaseCommandBuffer pCB) override;
virtual bool ReadbackSubresource(void* p, bool recordCopyCommand, PBaseCommandBuffer pCB) override; virtual bool ReadbackSubresource(void* p, bool recordCopyCommand, PBaseCommandBuffer pCB) override;
virtual void GenerateMips(PBaseCommandBuffer pCB) override; virtual void GenerateMips(PBaseCommandBuffer pCB) override;
const BYTE* GetData() const { VERUS_RT_ASSERT(IsLoaded()); return _vBuffer.data(); } const BYTE* GetData() const { VERUS_RT_ASSERT(IsLoaded()); return _vBuffer.data(); }
}; };
VERUS_TYPEDEFS(TextureRAM); VERUS_TYPEDEFS(TextureRAM);
}
} }

View File

@ -1,217 +1,214 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::CGI
{ {
namespace CGI enum class CompareOp : int
{ {
enum class CompareOp : int never,
{ less, // <
never, equal, // ==
less, // < lessOrEqual, // <=
equal, // == greater, // >
lessOrEqual, // <= notEqual, // !=
greater, // > greaterOrEqual, // >=
notEqual, // != always
greaterOrEqual, // >= };
always
};
enum class CubeMapFace : int enum class CubeMapFace : int
{ {
posX, posX,
negX, negX,
posY, posY,
negY, negY,
posZ, posZ,
negZ, negZ,
count, count,
all, // Match texture index to cube map face when creating framebuffer. all, // Match texture index to cube map face when creating framebuffer.
none = -1 none = -1
}; };
enum class PolygonMode : int enum class PolygonMode : int
{ {
fill, fill,
line line
}; };
enum class CullMode : int enum class CullMode : int
{ {
none, none,
front, front,
back back
}; };
struct PipelineRasterizationState struct PipelineRasterizationState
{ {
PolygonMode _polygonMode = PolygonMode::fill; PolygonMode _polygonMode = PolygonMode::fill;
CullMode _cullMode = CullMode::back; CullMode _cullMode = CullMode::back;
float _depthBiasConstantFactor = 0; float _depthBiasConstantFactor = 0;
float _depthBiasClamp = 0; float _depthBiasClamp = 0;
float _depthBiasSlopeFactor = 0; float _depthBiasSlopeFactor = 0;
bool _depthBiasEnable = false; bool _depthBiasEnable = false;
}; };
enum class PrimitiveTopology : int enum class PrimitiveTopology : int
{ {
pointList, pointList,
lineList, lineList,
lineStrip, lineStrip,
triangleList, triangleList,
triangleStrip, triangleStrip,
patchList3, patchList3,
patchList4 patchList4
}; };
enum class ImageLayout : int enum class ImageLayout : int
{ {
undefined, // Does not support device access, the contents of the memory are not guaranteed to be preserved. undefined, // Does not support device access, the contents of the memory are not guaranteed to be preserved.
general, // Supports all types of device access. general, // Supports all types of device access.
colorAttachment, // Must only be used as a color or resolve attachment. colorAttachment, // Must only be used as a color or resolve attachment.
depthStencilAttachment, // Must only be used as a depth/stencil or depth/stencil resolve attachment. depthStencilAttachment, // Must only be used as a depth/stencil or depth/stencil resolve attachment.
depthStencilReadOnly, // Must only be used as a read-only depth/stencil attachment or as a read-only image in a shader. depthStencilReadOnly, // Must only be used as a read-only depth/stencil attachment or as a read-only image in a shader.
xsReadOnly, // Must only be used as a read-only image in any shader. xsReadOnly, // Must only be used as a read-only image in any shader.
fsReadOnly, // Must only be used as a read-only image in fragment shader. fsReadOnly, // Must only be used as a read-only image in fragment shader.
transferSrc, // Must only be used as a source image of a transfer command. transferSrc, // Must only be used as a source image of a transfer command.
transferDst, // Must only be used as a destination image of a transfer command. transferDst, // Must only be used as a destination image of a transfer command.
presentSrc // Must only be used for presenting a presentable image for display. presentSrc // Must only be used for presenting a presentable image for display.
}; };
enum class Sampler : int enum class Sampler : int
{ {
custom, // Not immutable, not static sampler. custom, // Not immutable, not static sampler.
inputAttach, // SubpassInput<>, which is Vulkan-specific, nearestMipN elsewhere. inputAttach, // SubpassInput<>, which is Vulkan-specific, nearestMipN elsewhere.
storageImage, // RWTexture2D<>, UAV. storageImage, // RWTexture2D<>, UAV.
lodBias, lodBias,
shadow, shadow,
aniso, // Most common sampler for 3D. aniso, // Most common sampler for 3D.
anisoClamp, anisoClamp,
anisoSharp, // For UI. anisoSharp, // For UI.
linearMipL, linearMipL,
nearestMipL, nearestMipL,
linearMipN, linearMipN,
nearestMipN, nearestMipN,
linearClampMipL, linearClampMipL,
nearestClampMipL, nearestClampMipL,
linearClampMipN, linearClampMipN,
nearestClampMipN, nearestClampMipN,
count count
}; };
enum class ShaderStageFlags : UINT32 enum class ShaderStageFlags : UINT32
{ {
// Classic pipeline: // Classic pipeline:
vs = (1 << 0), // Vertex shader. vs = (1 << 0), // Vertex shader.
hs = (1 << 1), // Hull shader. Also known as tessellation control shader. hs = (1 << 1), // Hull shader. Also known as tessellation control shader.
ds = (1 << 2), // Domain shader. Also known as tessellation evaluation shader. ds = (1 << 2), // Domain shader. Also known as tessellation evaluation shader.
gs = (1 << 3), // Geometry shader. gs = (1 << 3), // Geometry shader.
fs = (1 << 4), // Fragment shader. Also known as pixel shader. fs = (1 << 4), // Fragment shader. Also known as pixel shader.
cs = (1 << 5), // Compute shader. Also known as kernel shader. cs = (1 << 5), // Compute shader. Also known as kernel shader.
// Raytracing: // Raytracing:
rtrg = (1 << 6), // Ray generation shader. rtrg = (1 << 6), // Ray generation shader.
rtah = (1 << 7), // Any hit shader. rtah = (1 << 7), // Any hit shader.
rtch = (1 << 8), // Closest hit shader. rtch = (1 << 8), // Closest hit shader.
rtm = (1 << 9), // Miss shader. rtm = (1 << 9), // Miss shader.
rti = (1 << 10), // Intersection shader. rti = (1 << 10), // Intersection shader.
rtc = (1 << 11), // Callable shader. rtc = (1 << 11), // Callable shader.
// Mesh shading pipeline: // Mesh shading pipeline:
ts = (1 << 12), // Task shader. Also known as amplification shader. ts = (1 << 12), // Task shader. Also known as amplification shader.
ms = (1 << 13), // Mesh shader. ms = (1 << 13), // Mesh shader.
vs_fs = vs | fs, vs_fs = vs | fs,
vs_hs_ds = vs | hs | ds, vs_hs_ds = vs | hs | ds,
vs_hs_ds_fs = vs | hs | ds | fs vs_hs_ds_fs = vs | hs | ds | fs
}; };
enum class ViaType : int enum class ViaType : int
{ {
floats, floats,
halfs, halfs,
shorts, shorts,
ubytes ubytes
}; };
// See: https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3ddeclusage // See: https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3ddeclusage
enum class ViaUsage : int enum class ViaUsage : int
{ {
position, // "POSITION" in glTF. position, // "POSITION" in glTF.
blendWeights, // "WEIGHTS_0" in glTF. blendWeights, // "WEIGHTS_0" in glTF.
blendIndices, // "JOINTS_0" in glTF. blendIndices, // "JOINTS_0" in glTF.
normal, // "NORMAL" in glTF. normal, // "NORMAL" in glTF.
tangent, // "TANGENT" in glTF. tangent, // "TANGENT" in glTF.
binormal, binormal,
color, // "COLOR_X" in glTF. color, // "COLOR_X" in glTF.
psize, psize,
texCoord, // "TEXCOORD_X" in glTF. texCoord, // "TEXCOORD_X" in glTF.
instData, instData,
attr attr
}; };
// See: https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dvertexelement9 // See: https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dvertexelement9
struct VertexInputAttrDesc struct VertexInputAttrDesc
{ {
int _binding; int _binding;
int _offset; int _offset;
ViaType _type; ViaType _type;
int _components; int _components;
ViaUsage _usage; ViaUsage _usage;
int _usageIndex; int _usageIndex;
static constexpr VertexInputAttrDesc End() { return { -1, -1, ViaType::floats, 0, ViaUsage::position, 0 }; } static constexpr VertexInputAttrDesc End() { return { -1, -1, ViaType::floats, 0, ViaUsage::position, 0 }; }
}; };
VERUS_TYPEDEFS(VertexInputAttrDesc); VERUS_TYPEDEFS(VertexInputAttrDesc);
class RPHandle : public BaseHandle<RPHandle> class RPHandle : public BaseHandle<RPHandle>
{ {
public: public:
static RPHandle Make(int value) { return BaseHandle::Make(value); } static RPHandle Make(int value) { return BaseHandle::Make(value); }
}; };
class FBHandle : public BaseHandle<FBHandle> class FBHandle : public BaseHandle<FBHandle>
{ {
public: public:
static FBHandle Make(int value) { return BaseHandle::Make(value); } static FBHandle Make(int value) { return BaseHandle::Make(value); }
}; };
class CSHandle : public BaseHandle<CSHandle> class CSHandle : public BaseHandle<CSHandle>
{ {
public: public:
static CSHandle Make(int value) { return BaseHandle::Make(value); } static CSHandle Make(int value) { return BaseHandle::Make(value); }
}; };
enum class ViewType : int enum class ViewType : int
{ {
none, // Undefined or common (layout) view. none, // Undefined or common (layout) view.
screen, // View for main window. screen, // View for main window.
splitScreen2H, splitScreen2H,
splitScreen2V, splitScreen2V,
splitScreen2X, splitScreen2X,
splitScreen4, splitScreen4,
openXR // Per eye view of OpenXR. openXR // Per eye view of OpenXR.
}; };
struct ViewDesc struct ViewDesc
{ {
Transform3 _matV = Transform3::identity(); Transform3 _matV = Transform3::identity();
Matrix4 _matP = Matrix4::identity(); Matrix4 _matP = Matrix4::identity();
Math::Pose _pose; Math::Pose _pose;
float _fovLeft = 0; float _fovLeft = 0;
float _fovRight = 0; float _fovRight = 0;
float _fovUp = 0; float _fovUp = 0;
float _fovDown = 0; float _fovDown = 0;
float _zNear = 0; float _zNear = 0;
float _zFar = 0; float _zFar = 0;
int _vpX = 0; int _vpX = 0;
int _vpY = 0; int _vpY = 0;
int _vpWidth = 0; int _vpWidth = 0;
int _vpHeight = 0; int _vpHeight = 0;
ViewType _type = ViewType::none; ViewType _type = ViewType::none;
int _index = 0; // To distinguish between left and right eye or player index in split screen mode. int _index = 0; // To distinguish between left and right eye or player index in split screen mode.
}; };
VERUS_TYPEDEFS(ViewDesc); VERUS_TYPEDEFS(ViewDesc);
}
} }

View File

@ -1,4 +1,4 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
#define VERUS_CT_ASSERT(x) static_assert(x, "VERUS_CT_ASSERT") #define VERUS_CT_ASSERT(x) static_assert(x)

View File

@ -6,33 +6,30 @@
#define VERUS_LOG_INFO(txt) {StringStream ss_Log; ss_Log << txt; D::Log::I().Write(_C(ss_Log.str()), std::this_thread::get_id(), __FILE__, __LINE__, D::Log::Severity::info);} #define VERUS_LOG_INFO(txt) {StringStream ss_Log; ss_Log << txt; D::Log::I().Write(_C(ss_Log.str()), std::this_thread::get_id(), __FILE__, __LINE__, D::Log::Severity::info);}
#define VERUS_LOG_DEBUG(txt) {StringStream ss_Log; ss_Log << txt; D::Log::I().Write(_C(ss_Log.str()), std::this_thread::get_id(), __FILE__, __LINE__, D::Log::Severity::debug);} #define VERUS_LOG_DEBUG(txt) {StringStream ss_Log; ss_Log << txt; D::Log::I().Write(_C(ss_Log.str()), std::this_thread::get_id(), __FILE__, __LINE__, D::Log::Severity::debug);}
namespace verus namespace verus::D
{ {
namespace D class Log : public Singleton<Log>
{ {
class Log : public Singleton<Log> public:
enum class Severity : int
{ {
public: error,
enum class Severity : int warning,
{ info,
error, debug
warning,
info,
debug
};
private:
std::mutex _mutex;
std::string _pathname;
public:
std::mutex& GetMutex() { return _mutex; }
void Write(CSZ txt, std::thread::id tid, CSZ filename, UINT32 line, Severity severity);
static void FormatTime(char* buffer, size_t size);
static CSZ GetSeverityLetter(Severity severity);
static String ExtractFilename(CSZ filename);
}; };
}
private:
std::mutex _mutex;
std::string _pathname;
public:
std::mutex& GetMutex() { return _mutex; }
void Write(CSZ txt, std::thread::id tid, CSZ filename, UINT32 line, Severity severity);
static void FormatTime(char* buffer, size_t size);
static CSZ GetSeverityLetter(Severity severity);
static String ExtractFilename(CSZ filename);
};
} }

View File

@ -1,33 +1,30 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::D
{ {
namespace D class Recoverable : public RuntimeError
{ {
class Recoverable : public RuntimeError public:
Recoverable(std::thread::id tid = std::this_thread::get_id(), CSZ file = "", UINT32 line = __LINE__) : RuntimeError(tid, file, line) {}
Recoverable(const Recoverable& that)
{ {
public: *this = that;
Recoverable(std::thread::id tid = std::this_thread::get_id(), CSZ file = "", UINT32 line = __LINE__) : RuntimeError(tid, file, line) {} }
Recoverable(const Recoverable& that) Recoverable& operator=(const Recoverable& that)
{ {
*this = that; RuntimeError::operator=(that);
} return *this;
Recoverable& operator=(const Recoverable& that) }
{
RuntimeError::operator=(that);
return *this;
}
template<typename T> template<typename T>
Recoverable& operator<<(const T& t) Recoverable& operator<<(const T& t)
{ {
RuntimeError::operator<<(t); RuntimeError::operator<<(t);
return *this; return *this;
} }
}; };
VERUS_TYPEDEFS(Recoverable); VERUS_TYPEDEFS(Recoverable);
}
} }
#define VERUS_RECOVERABLE verus::D::Recoverable(std::this_thread::get_id(), __FILE__, __LINE__) #define VERUS_RECOVERABLE verus::D::Recoverable(std::this_thread::get_id(), __FILE__, __LINE__)

View File

@ -1,68 +1,65 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::D
{ {
namespace D // See: https://marknelson.us/posts/2007/11/13/no-exceptions.html
class RuntimeError : public std::exception
{ {
// See: https://marknelson.us/posts/2007/11/13/no-exceptions.html mutable StringStream _ss;
class RuntimeError : public std::exception mutable String _what;
std::thread::id _tid;
String _file;
UINT32 _line = 0;
public:
RuntimeError(std::thread::id tid = std::this_thread::get_id(), CSZ file = "", UINT32 line = __LINE__) :
_tid(tid), _line(line)
{ {
mutable StringStream _ss; CSZ p = strrchr(file, '/');
mutable String _what; if (!p)
std::thread::id _tid; p = strrchr(file, '\\');
String _file; _file = p ? p + 1 : file;
UINT32 _line = 0; }
RuntimeError(const RuntimeError& that)
{
*this = that;
}
RuntimeError& operator=(const RuntimeError& that)
{
_what += that._what;
_what += that._ss.str();
_tid = that._tid;
_file = that._file;
_line = that._line;
return *this;
}
virtual ~RuntimeError() throw() {}
public: virtual CSZ what() const throw()
RuntimeError(std::thread::id tid = std::this_thread::get_id(), CSZ file = "", UINT32 line = __LINE__) : {
_tid(tid), _line(line) if (_ss.str().size())
{ {
CSZ p = strrchr(file, '/'); _what += _ss.str();
if (!p) _ss.str("");
p = strrchr(file, '\\');
_file = p ? p + 1 : file;
} }
RuntimeError(const RuntimeError& that) return _C(_what);
{ }
*this = that;
}
RuntimeError& operator=(const RuntimeError& that)
{
_what += that._what;
_what += that._ss.str();
_tid = that._tid;
_file = that._file;
_line = that._line;
return *this;
}
virtual ~RuntimeError() throw() {}
virtual CSZ what() const throw() std::thread::id GetThreadID() const { return _tid; }
{ CSZ GetFile() const { return _C(_file); }
if (_ss.str().size()) UINT32 GetLine() const { return _line; }
{
_what += _ss.str();
_ss.str("");
}
return _C(_what);
}
std::thread::id GetThreadID() const { return _tid; } template<typename T>
CSZ GetFile() const { return _C(_file); } RuntimeError& operator<<(const T& t)
UINT32 GetLine() const { return _line; } {
_ss << t;
return *this;
}
template<typename T> bool IsRaised() const { return !!strlen(what()); }
RuntimeError& operator<<(const T& t) };
{ VERUS_TYPEDEFS(RuntimeError);
_ss << t;
return *this;
}
bool IsRaised() const { return !!strlen(what()); }
};
VERUS_TYPEDEFS(RuntimeError);
}
} }
#define VERUS_RUNTIME_ERROR verus::D::RuntimeError(std::this_thread::get_id(), __FILE__, __LINE__) #define VERUS_RUNTIME_ERROR verus::D::RuntimeError(std::this_thread::get_id(), __FILE__, __LINE__)

View File

@ -1,69 +1,66 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Effects
{ {
namespace Effects class Bloom : public Singleton<Bloom>, public Object
{ {
class Bloom : public Singleton<Bloom>, public Object
{
#include "../Shaders/Bloom.inc.hlsl" #include "../Shaders/Bloom.inc.hlsl"
enum PIPE enum PIPE
{ {
PIPE_MAIN, PIPE_MAIN,
PIPE_LIGHT_SHAFTS, PIPE_LIGHT_SHAFTS,
PIPE_COUNT PIPE_COUNT
};
enum TEX
{
TEX_PING,
TEX_PONG,
TEX_COUNT
};
static UB_BloomVS s_ubBloomVS;
static UB_BloomFS s_ubBloomFS;
static UB_BloomLightShaftsFS s_ubBloomLightShaftsFS;
CGI::ShaderPwn _shader;
CGI::PipelinePwns<PIPE_COUNT> _pipe;
CGI::TexturePwns<TEX_COUNT> _tex;
CGI::TexturePtr _texCSMB;
CGI::RPHandle _rph;
CGI::RPHandle _rphLightShafts;
CGI::FBHandle _fbh;
CGI::CSHandle _csh;
CGI::CSHandle _cshLightShafts;
float _colorScale = 0.7f;
float _colorBias = 1.4f;
float _maxDist = 20;
float _sunGloss = 128;
float _wideStrength = 0.15f;
float _sunStrength = 0.35f;
bool _blur = true;
bool _blurLightShafts = true;
bool _editMode = false;
public:
Bloom();
~Bloom();
void Init();
void InitByCascadedShadowMapBaker(CGI::TexturePtr texShadow);
void Done();
void OnSwapChainResized();
void Generate();
CGI::TexturePtr GetTexture() const;
CGI::TexturePtr GetPongTexture() const;
bool IsEditMode() const { return _editMode; }
void ToggleEditMode() { _editMode = !_editMode; }
}; };
VERUS_TYPEDEFS(Bloom);
} enum TEX
{
TEX_PING,
TEX_PONG,
TEX_COUNT
};
static UB_BloomVS s_ubBloomVS;
static UB_BloomFS s_ubBloomFS;
static UB_BloomLightShaftsFS s_ubBloomLightShaftsFS;
CGI::ShaderPwn _shader;
CGI::PipelinePwns<PIPE_COUNT> _pipe;
CGI::TexturePwns<TEX_COUNT> _tex;
CGI::TexturePtr _texCSMB;
CGI::RPHandle _rph;
CGI::RPHandle _rphLightShafts;
CGI::FBHandle _fbh;
CGI::CSHandle _csh;
CGI::CSHandle _cshLightShafts;
float _colorScale = 0.7f;
float _colorBias = 1.4f;
float _maxDist = 20;
float _sunGloss = 128;
float _wideStrength = 0.15f;
float _sunStrength = 0.35f;
bool _blur = true;
bool _blurLightShafts = true;
bool _editMode = false;
public:
Bloom();
~Bloom();
void Init();
void InitByCascadedShadowMapBaker(CGI::TexturePtr texShadow);
void Done();
void OnSwapChainResized();
void Generate();
CGI::TexturePtr GetTexture() const;
CGI::TexturePtr GetPongTexture() const;
bool IsEditMode() const { return _editMode; }
void ToggleEditMode() { _editMode = !_editMode; }
};
VERUS_TYPEDEFS(Bloom);
} }

View File

@ -1,127 +1,124 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Effects
{ {
namespace Effects class Blur : public Singleton<Blur>, public Object
{ {
class Blur : public Singleton<Blur>, public Object
{
#include "../Shaders/Blur.inc.hlsl" #include "../Shaders/Blur.inc.hlsl"
enum PIPE enum PIPE
{ {
PIPE_U, PIPE_U,
PIPE_V, PIPE_V,
PIPE_VSM_U, PIPE_VSM_U,
PIPE_VSM_V, PIPE_VSM_V,
PIPE_SSAO, PIPE_SSAO,
PIPE_RESOLVE_DITHERING, PIPE_RESOLVE_DITHERING,
PIPE_SHARPEN, PIPE_SHARPEN,
PIPE_DOF_U, PIPE_DOF_U,
PIPE_DOF_V, PIPE_DOF_V,
PIPE_BLOOM_U, PIPE_BLOOM_U,
PIPE_BLOOM_V, PIPE_BLOOM_V,
PIPE_BLOOM_LIGHT_SHAFTS_U, PIPE_BLOOM_LIGHT_SHAFTS_U,
PIPE_BLOOM_LIGHT_SHAFTS_V, PIPE_BLOOM_LIGHT_SHAFTS_V,
PIPE_AA, PIPE_AA,
PIPE_AA_OFF, PIPE_AA_OFF,
PIPE_MOTION_BLUR, PIPE_MOTION_BLUR,
PIPE_MOTION_BLUR_OFF, PIPE_MOTION_BLUR_OFF,
PIPE_COUNT PIPE_COUNT
};
struct Handles
{
CGI::RPHandle _rphU;
CGI::RPHandle _rphV;
CGI::FBHandle _fbhU;
CGI::FBHandle _fbhV;
CGI::CSHandle _cshU;
CGI::CSHandle _cshV;
void FreeDescriptorSets(CGI::ShaderPtr shader);
void DeleteFramebuffers();
void DeleteRenderPasses();
};
static UB_BlurVS s_ubBlurVS;
static UB_BlurFS s_ubBlurFS;
static UB_ExtraBlurFS s_ubExtraBlurFS;
CGI::ShaderPwn _shader;
CGI::PipelinePwns<PIPE_COUNT> _pipe;
CGI::RPHandle _rphVsmU;
CGI::RPHandle _rphVsmV;
CGI::RPHandle _rphSsao;
CGI::FBHandle _fbhSsao;
CGI::CSHandle _cshSsao;
Handles _rdsHandles;
CGI::CSHandle _cshRdsExtra;
Handles _dofHandles;
CGI::CSHandle _cshDofExtra;
Handles _bloomHandles;
CGI::RPHandle _rphAntiAliasing;
CGI::FBHandle _fbhAntiAliasing;
CGI::CSHandle _cshAntiAliasing;
CGI::CSHandle _cshAntiAliasingExtra;
CGI::RPHandle _rphMotionBlur;
CGI::FBHandle _fbhMotionBlur;
CGI::CSHandle _cshMotionBlur;
CGI::CSHandle _cshMotionBlurExtra;
float _dofFocusDist = 10;
float _dofRadius = 0.005f;
float _bloomRadius = 0.02f;
float _bloomLightShaftsRadius = 0.002f;
bool _enableDepthOfField = false;
public:
Blur();
~Blur();
void Init();
void Done();
void OnSwapChainResized();
CGI::ShaderPtr GetShader() const { return _shader; }
void GenerateForVSM(CGI::FBHandle fbhU, CGI::FBHandle fbhV, CGI::CSHandle cshU, CGI::CSHandle cshV,
RcVector4 rc, RcVector4 zNearFarEx);
void GenerateForSsao();
void GenerateForResolveDitheringAndSharpen();
void GenerateForDepthOfField();
void GenerateForBloom(bool forLightShafts);
void GenerateForAntiAliasing();
void GenerateForMotionBlur();
void UpdateUniformBuffer(float radius, int sampleCount, int texSize = 0, float samplesPerPixel = 1, int maxSamples = 61);
CGI::RPHandle GetRenderPassHandleForVsmU() const { return _rphVsmU; }
CGI::RPHandle GetRenderPassHandleForVsmV() const { return _rphVsmV; }
bool IsDepthOfFieldEnabled() const { return _enableDepthOfField; }
void EnableDepthOfField(bool b) { _enableDepthOfField = b; }
float GetDofFocusDistance() const { return _dofFocusDist; }
void SetDofFocusDistance(float dist) { _dofFocusDist = dist; }
float GetDofRadius() const { return _dofRadius; }
void SetDofRadius(float radius) { _dofRadius = radius; }
}; };
VERUS_TYPEDEFS(Blur);
} struct Handles
{
CGI::RPHandle _rphU;
CGI::RPHandle _rphV;
CGI::FBHandle _fbhU;
CGI::FBHandle _fbhV;
CGI::CSHandle _cshU;
CGI::CSHandle _cshV;
void FreeDescriptorSets(CGI::ShaderPtr shader);
void DeleteFramebuffers();
void DeleteRenderPasses();
};
static UB_BlurVS s_ubBlurVS;
static UB_BlurFS s_ubBlurFS;
static UB_ExtraBlurFS s_ubExtraBlurFS;
CGI::ShaderPwn _shader;
CGI::PipelinePwns<PIPE_COUNT> _pipe;
CGI::RPHandle _rphVsmU;
CGI::RPHandle _rphVsmV;
CGI::RPHandle _rphSsao;
CGI::FBHandle _fbhSsao;
CGI::CSHandle _cshSsao;
Handles _rdsHandles;
CGI::CSHandle _cshRdsExtra;
Handles _dofHandles;
CGI::CSHandle _cshDofExtra;
Handles _bloomHandles;
CGI::RPHandle _rphAntiAliasing;
CGI::FBHandle _fbhAntiAliasing;
CGI::CSHandle _cshAntiAliasing;
CGI::CSHandle _cshAntiAliasingExtra;
CGI::RPHandle _rphMotionBlur;
CGI::FBHandle _fbhMotionBlur;
CGI::CSHandle _cshMotionBlur;
CGI::CSHandle _cshMotionBlurExtra;
float _dofFocusDist = 10;
float _dofRadius = 0.005f;
float _bloomRadius = 0.02f;
float _bloomLightShaftsRadius = 0.002f;
bool _enableDepthOfField = false;
public:
Blur();
~Blur();
void Init();
void Done();
void OnSwapChainResized();
CGI::ShaderPtr GetShader() const { return _shader; }
void GenerateForVSM(CGI::FBHandle fbhU, CGI::FBHandle fbhV, CGI::CSHandle cshU, CGI::CSHandle cshV,
RcVector4 rc, RcVector4 zNearFarEx);
void GenerateForSsao();
void GenerateForResolveDitheringAndSharpen();
void GenerateForDepthOfField();
void GenerateForBloom(bool forLightShafts);
void GenerateForAntiAliasing();
void GenerateForMotionBlur();
void UpdateUniformBuffer(float radius, int sampleCount, int texSize = 0, float samplesPerPixel = 1, int maxSamples = 61);
CGI::RPHandle GetRenderPassHandleForVsmU() const { return _rphVsmU; }
CGI::RPHandle GetRenderPassHandleForVsmV() const { return _rphVsmV; }
bool IsDepthOfFieldEnabled() const { return _enableDepthOfField; }
void EnableDepthOfField(bool b) { _enableDepthOfField = b; }
float GetDofFocusDistance() const { return _dofFocusDist; }
void SetDofFocusDistance(float dist) { _dofFocusDist = dist; }
float GetDofRadius() const { return _dofRadius; }
void SetDofRadius(float radius) { _dofRadius = radius; }
};
VERUS_TYPEDEFS(Blur);
} }

View File

@ -1,40 +1,37 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Effects
{ {
namespace Effects class Cinema : public Singleton<Cinema>, public Object
{ {
class Cinema : public Singleton<Cinema>, public Object
{
#include "../Shaders/Cinema.inc.hlsl" #include "../Shaders/Cinema.inc.hlsl"
static UB_CinemaVS s_ubCinemaVS; static UB_CinemaVS s_ubCinemaVS;
static UB_CinemaFS s_ubCinemaFS; static UB_CinemaFS s_ubCinemaFS;
CGI::ShaderPwn _shader; CGI::ShaderPwn _shader;
CGI::PipelinePwn _pipe; CGI::PipelinePwn _pipe;
CGI::TexturePwn _texFilmGrain; CGI::TexturePwn _texFilmGrain;
CGI::CSHandle _csh; CGI::CSHandle _csh;
float _uOffset = 0; float _uOffset = 0;
float _vOffset = 0; float _vOffset = 0;
float _brightness = 1; float _brightness = 1;
float _flickerStrength = 0.02f; float _flickerStrength = 0.02f;
float _noiseStrength = 0.2f; float _noiseStrength = 0.2f;
bool _editMode = false; bool _editMode = false;
public: public:
Cinema(); Cinema();
~Cinema(); ~Cinema();
void Init(); void Init();
void Done(); void Done();
void Draw(); void Draw();
bool IsEditMode() const { return _editMode; } bool IsEditMode() const { return _editMode; }
void ToggleEditMode() { _editMode = !_editMode; } void ToggleEditMode() { _editMode = !_editMode; }
}; };
VERUS_TYPEDEFS(Cinema); VERUS_TYPEDEFS(Cinema);
}
} }

View File

@ -1,188 +1,185 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Effects
{ {
namespace Effects enum class BillboardType : int
{ {
enum class BillboardType : int none,
{ screenViewplaneOriented,
none, screenViewpointOriented,
screenViewplaneOriented, worldViewplaneOriented,
screenViewpointOriented, worldViewpointOriented,
worldViewplaneOriented, axial
worldViewpointOriented, };
axial
};
class Particle class Particle
{ {
public: public:
Point3 _position = Point3(0); Point3 _position = Point3(0);
Point3 _prevPosition = Point3(0); Point3 _prevPosition = Point3(0);
Vector3 _velocity = Vector3(0, 1, 0); Vector3 _velocity = Vector3(0, 1, 0);
Vector3 _axis = Vector3(0, 1, 0); Vector3 _axis = Vector3(0, 1, 0);
Vector4 _tcOffset = Vector4(0); Vector4 _tcOffset = Vector4(0);
Vector4 _beginColor = Vector4::Replicate(1); Vector4 _beginColor = Vector4::Replicate(1);
Vector4 _endColor = Vector4::Replicate(1); Vector4 _endColor = Vector4::Replicate(1);
void* _pUser = nullptr; void* _pUser = nullptr;
float _invTotalTime = 0; float _invTotalTime = 0;
float _timeLeft = -1; float _timeLeft = -1;
float _beginAdditive = 0; float _beginAdditive = 0;
float _endAdditive = 0; float _endAdditive = 0;
float _beginSize = 0; float _beginSize = 0;
float _endSize = 0; float _endSize = 0;
float _beginSpin = 0; float _beginSpin = 0;
float _endSpin = 0; float _endSpin = 0;
bool _inContact = false; bool _inContact = false;
}; };
VERUS_TYPEDEFS(Particle); VERUS_TYPEDEFS(Particle);
class Particles; class Particles;
class ParticlesDelegate class ParticlesDelegate
{ {
public: public:
virtual void Particles_OnUpdate(Particles& particles, int index, RParticle particle, virtual void Particles_OnUpdate(Particles& particles, int index, RParticle particle,
RVector3 up, RVector3 normal, RTransform3 matAim) = 0; RVector3 up, RVector3 normal, RTransform3 matAim) = 0;
}; };
VERUS_TYPEDEFS(ParticlesDelegate); VERUS_TYPEDEFS(ParticlesDelegate);
class Particles : public Object class Particles : public Object
{ {
#include "../Shaders/Particles.inc.hlsl" #include "../Shaders/Particles.inc.hlsl"
enum PIPE enum PIPE
{ {
PIPE_MAIN, PIPE_MAIN,
PIPE_BILLBOARDS, PIPE_BILLBOARDS,
PIPE_COUNT PIPE_COUNT
};
struct Vertex
{
glm::vec4 pos;
glm::vec2 tc0;
UINT32 color;
float psize;
};
VERUS_TYPEDEFS(Vertex);
static CGI::ShaderPwn s_shader;
static CGI::PipelinePwns<PIPE_COUNT> s_pipe;
static UB_ParticlesVS s_ubParticlesVS;
static UB_ParticlesFS s_ubParticlesFS;
Vector4 _tilesetSize = Vector4::Replicate(1);
Vector3 _lifeTimeRange = Vector3(0, 1, 1);
Vector3 _speedRange = Vector3(0, 1, 1);
Vector3 _beginAdditiveRange = Vector3(0);
Vector3 _endAdditiveRange = Vector3(0);
Vector4 _beginColorMin = Vector4(0);
Vector4 _beginColorDelta = Vector4(0);
Vector4 _endColorMin = Vector4(0);
Vector4 _endColorDelta = Vector4(0);
Vector3 _beginSizeRange = Vector3(0, 1, 1);
Vector3 _endSizeRange = Vector3(0, 1, 1);
Vector3 _beginSpinRange = Vector3(0, 1, 1);
Vector3 _endSpinRange = Vector3(0, 1, 1);
Vector3 _gravity = Vector3(0, -9.8f, 0);
String _url;
Vector<Particle> _vParticles;
Vector<Vertex> _vVB;
Vector<UINT16> _vIB;
CGI::GeometryPwn _geo;
CGI::TexturePwn _tex;
CGI::CSHandle _csh;
PParticlesDelegate _pDelegate = nullptr;
const float* _pUserZone = nullptr;
BillboardType _billboardType = BillboardType::none;
int _tilesetX = 0;
int _tilesetY = 0;
int _indexCount = 0;
int _capacity = 0;
int _addAt = 0;
int _drawCount = 0;
float _ratio = 1;
float _brightness = 1;
float _bounceStrength = 0.5f;
float _gravityStrength = 1;
float _windStrength = 0;
float _flowRemainder = 0;
float _particlesPerSecond = 0;
float _zone = 0;
bool _collide = false;
bool _decal = false;
bool _flowEnabled = true;
public:
Particles();
~Particles();
static void InitStatic();
static void DoneStatic();
void Init(CSZ url);
void Done();
void Update(); // Call this after adding particles!
void Draw();
Str GetURL() const { return _C(_url); }
int GetTilesetX() const { return _tilesetX; }
int GetTilesetY() const { return _tilesetY; }
int GetCapacity() const { return _capacity; }
int GetDrawCount() const { return _drawCount; }
PParticlesDelegate SetDelegate(PParticlesDelegate p) { return Utils::Swap(_pDelegate, p); }
void SetUserZone(const float* pZone) { _pUserZone = pZone; }
void GetLifeTime(float& mn, float& mx) const;
void SetLifeTime(float mn, float mx);
void GetSpeed(float& mn, float& mx) const;
void SetSpeed(float mn, float mx);
void GetBeginAdditive(float& mn, float& mx) const;
void SetBeginAdditive(float mn, float mx);
void GetBeginColor(RVector4 mn, RVector4 mx) const;
void SetBeginColor(RcVector4 mn, RcVector4 mx);
void GetEndColor(RVector4 mn, RVector4 mx) const;
void SetEndColor(RcVector4 mn, RcVector4 mx);
void GetEndAdditive(float& mn, float& mx) const;
void SetEndAdditive(float mn, float mx);
void GetBeginSize(float& mn, float& mx) const;
void SetBeginSize(float mn, float mx);
void GetEndSize(float& mn, float& mx) const;
void SetEndSize(float mn, float mx);
void GetBeginSpin(float& mn, float& mx) const;
void SetBeginSpin(float mn, float mx);
void GetEndSpin(float& mn, float& mx) const;
void SetEndSpin(float mn, float mx);
float GetBrightness() const { return _brightness; }
void SetBrightness(float value) { _brightness = value; }
float GetBounce() const { return _bounceStrength; }
void SetBounce(float value) { _bounceStrength = value; }
float GetGravity() const { return _gravityStrength; }
void SetGravity(float value) { _gravityStrength = value; }
float GetWind() const { return _windStrength; }
void SetWind(float value) { _windStrength = value; }
float GetParticlesPerSecond() const { return _particlesPerSecond; }
void SetParticlesPerSecond(float value) { _particlesPerSecond = value; }
float GetZone() const { return _zone; }
void SetZone(float value) { _zone = value; }
int Add(RcPoint3 pos, RcVector3 dir,
float scale = 1, PcVector4 pUserColor = nullptr, void* pUser = nullptr);
void AddFlow(RcPoint3 pos, RcVector3 dirOffset,
float scale = 1, PcVector4 pUserColor = nullptr, float* pUserFlowRemainder = nullptr, float intensity = 1);
bool IsFlowEnabled() const { return _flowEnabled; }
void EnableFlow(bool b = true) { _flowEnabled = b; }
bool TimeCorrectedVerletIntegration(RParticle particle, RPoint3 point, RVector3 normal);
bool EulerIntegration(RParticle particle, RPoint3 point, RVector3 normal);
void PushPointSprite(int index, RcVector4 color, float size, float additive);
void PushBillboard(int index, RcVector4 color, RcTransform3 matW, float additive);
Transform3 GetBillboardMatrix(int index, float size, float spin, RcVector3 up, RcVector3 normal, RTransform3 matAim);
}; };
VERUS_TYPEDEFS(Particles);
} struct Vertex
{
glm::vec4 pos;
glm::vec2 tc0;
UINT32 color;
float psize;
};
VERUS_TYPEDEFS(Vertex);
static CGI::ShaderPwn s_shader;
static CGI::PipelinePwns<PIPE_COUNT> s_pipe;
static UB_ParticlesVS s_ubParticlesVS;
static UB_ParticlesFS s_ubParticlesFS;
Vector4 _tilesetSize = Vector4::Replicate(1);
Vector3 _lifeTimeRange = Vector3(0, 1, 1);
Vector3 _speedRange = Vector3(0, 1, 1);
Vector3 _beginAdditiveRange = Vector3(0);
Vector3 _endAdditiveRange = Vector3(0);
Vector4 _beginColorMin = Vector4(0);
Vector4 _beginColorDelta = Vector4(0);
Vector4 _endColorMin = Vector4(0);
Vector4 _endColorDelta = Vector4(0);
Vector3 _beginSizeRange = Vector3(0, 1, 1);
Vector3 _endSizeRange = Vector3(0, 1, 1);
Vector3 _beginSpinRange = Vector3(0, 1, 1);
Vector3 _endSpinRange = Vector3(0, 1, 1);
Vector3 _gravity = Vector3(0, -9.8f, 0);
String _url;
Vector<Particle> _vParticles;
Vector<Vertex> _vVB;
Vector<UINT16> _vIB;
CGI::GeometryPwn _geo;
CGI::TexturePwn _tex;
CGI::CSHandle _csh;
PParticlesDelegate _pDelegate = nullptr;
const float* _pUserZone = nullptr;
BillboardType _billboardType = BillboardType::none;
int _tilesetX = 0;
int _tilesetY = 0;
int _indexCount = 0;
int _capacity = 0;
int _addAt = 0;
int _drawCount = 0;
float _ratio = 1;
float _brightness = 1;
float _bounceStrength = 0.5f;
float _gravityStrength = 1;
float _windStrength = 0;
float _flowRemainder = 0;
float _particlesPerSecond = 0;
float _zone = 0;
bool _collide = false;
bool _decal = false;
bool _flowEnabled = true;
public:
Particles();
~Particles();
static void InitStatic();
static void DoneStatic();
void Init(CSZ url);
void Done();
void Update(); // Call this after adding particles!
void Draw();
Str GetURL() const { return _C(_url); }
int GetTilesetX() const { return _tilesetX; }
int GetTilesetY() const { return _tilesetY; }
int GetCapacity() const { return _capacity; }
int GetDrawCount() const { return _drawCount; }
PParticlesDelegate SetDelegate(PParticlesDelegate p) { return Utils::Swap(_pDelegate, p); }
void SetUserZone(const float* pZone) { _pUserZone = pZone; }
void GetLifeTime(float& mn, float& mx) const;
void SetLifeTime(float mn, float mx);
void GetSpeed(float& mn, float& mx) const;
void SetSpeed(float mn, float mx);
void GetBeginAdditive(float& mn, float& mx) const;
void SetBeginAdditive(float mn, float mx);
void GetBeginColor(RVector4 mn, RVector4 mx) const;
void SetBeginColor(RcVector4 mn, RcVector4 mx);
void GetEndColor(RVector4 mn, RVector4 mx) const;
void SetEndColor(RcVector4 mn, RcVector4 mx);
void GetEndAdditive(float& mn, float& mx) const;
void SetEndAdditive(float mn, float mx);
void GetBeginSize(float& mn, float& mx) const;
void SetBeginSize(float mn, float mx);
void GetEndSize(float& mn, float& mx) const;
void SetEndSize(float mn, float mx);
void GetBeginSpin(float& mn, float& mx) const;
void SetBeginSpin(float mn, float mx);
void GetEndSpin(float& mn, float& mx) const;
void SetEndSpin(float mn, float mx);
float GetBrightness() const { return _brightness; }
void SetBrightness(float value) { _brightness = value; }
float GetBounce() const { return _bounceStrength; }
void SetBounce(float value) { _bounceStrength = value; }
float GetGravity() const { return _gravityStrength; }
void SetGravity(float value) { _gravityStrength = value; }
float GetWind() const { return _windStrength; }
void SetWind(float value) { _windStrength = value; }
float GetParticlesPerSecond() const { return _particlesPerSecond; }
void SetParticlesPerSecond(float value) { _particlesPerSecond = value; }
float GetZone() const { return _zone; }
void SetZone(float value) { _zone = value; }
int Add(RcPoint3 pos, RcVector3 dir,
float scale = 1, PcVector4 pUserColor = nullptr, void* pUser = nullptr);
void AddFlow(RcPoint3 pos, RcVector3 dirOffset,
float scale = 1, PcVector4 pUserColor = nullptr, float* pUserFlowRemainder = nullptr, float intensity = 1);
bool IsFlowEnabled() const { return _flowEnabled; }
void EnableFlow(bool b = true) { _flowEnabled = b; }
bool TimeCorrectedVerletIntegration(RParticle particle, RPoint3 point, RVector3 normal);
bool EulerIntegration(RParticle particle, RPoint3 point, RVector3 normal);
void PushPointSprite(int index, RcVector4 color, float size, float additive);
void PushBillboard(int index, RcVector4 color, RcTransform3 matW, float additive);
Transform3 GetBillboardMatrix(int index, float size, float spin, RcVector3 up, RcVector3 normal, RTransform3 matAim);
};
VERUS_TYPEDEFS(Particles);
} }

View File

@ -1,47 +1,44 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Effects
{ {
namespace Effects class Ssao : public Singleton<Ssao>, public Object
{ {
class Ssao : public Singleton<Ssao>, public Object
{
#include "../Shaders/Ssao.inc.hlsl" #include "../Shaders/Ssao.inc.hlsl"
static UB_SsaoVS s_ubSsaoVS; static UB_SsaoVS s_ubSsaoVS;
static UB_SsaoFS s_ubSsaoFS; static UB_SsaoFS s_ubSsaoFS;
CGI::ShaderPwn _shader; CGI::ShaderPwn _shader;
CGI::PipelinePwn _pipe; CGI::PipelinePwn _pipe;
CGI::TexturePwn _texRandNormals; CGI::TexturePwn _texRandNormals;
CGI::RPHandle _rph; CGI::RPHandle _rph;
CGI::FBHandle _fbh; CGI::FBHandle _fbh;
CGI::CSHandle _csh; CGI::CSHandle _csh;
float _smallRad = 0.02f; float _smallRad = 0.02f;
float _largeRad = 0.05f; float _largeRad = 0.05f;
float _weightScale = 10; float _weightScale = 10;
float _weightBias = 2.5f; float _weightBias = 2.5f;
bool _blur = true; bool _blur = true;
bool _editMode = false; bool _editMode = false;
public: public:
Ssao(); Ssao();
~Ssao(); ~Ssao();
void Init(); void Init();
void InitCmd(); void InitCmd();
void Done(); void Done();
void OnSwapChainResized(); void OnSwapChainResized();
void Generate(); void Generate();
void UpdateRandNormalsTexture(); void UpdateRandNormalsTexture();
bool IsEditMode() const { return _editMode; } bool IsEditMode() const { return _editMode; }
void ToggleEditMode() { _editMode = !_editMode; } void ToggleEditMode() { _editMode = !_editMode; }
}; };
VERUS_TYPEDEFS(Ssao); VERUS_TYPEDEFS(Ssao);
}
} }

View File

@ -1,55 +1,52 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Effects
{ {
namespace Effects class Ssr : public Singleton<Ssr>, public Object
{ {
class Ssr : public Singleton<Ssr>, public Object
{
#include "../Shaders/Ssr.inc.hlsl" #include "../Shaders/Ssr.inc.hlsl"
enum PIPE enum PIPE
{ {
PIPE_MAIN, PIPE_MAIN,
PIPE_DEBUG_CUBE_MAP, PIPE_DEBUG_CUBE_MAP,
PIPE_COUNT PIPE_COUNT
};
static UB_SsrVS s_ubSsrVS;
static UB_SsrFS s_ubSsrFS;
CGI::ShaderPwn _shader;
CGI::PipelinePwns<PIPE_COUNT> _pipe;
CGI::RPHandle _rph;
CGI::FBHandle _fbh;
CGI::CSHandle _csh;
float _radius = 2.2f;
float _depthBias = 0.03f;
float _thickness = 0.3f;
float _equalizeDist = 20;
bool _cubeMapDebugMode = false;
bool _editMode = false;
public:
Ssr();
~Ssr();
void Init();
void Done();
void OnSwapChainResized();
bool BindDescriptorSetTextures();
void Generate();
bool IsCubeMapDebugMode() const { return _cubeMapDebugMode; }
void ToggleCubeMapDebugMode() { _cubeMapDebugMode = !_cubeMapDebugMode; }
bool IsEditMode() const { return _editMode; }
void ToggleEditMode() { _editMode = !_editMode; }
}; };
VERUS_TYPEDEFS(Ssr);
} static UB_SsrVS s_ubSsrVS;
static UB_SsrFS s_ubSsrFS;
CGI::ShaderPwn _shader;
CGI::PipelinePwns<PIPE_COUNT> _pipe;
CGI::RPHandle _rph;
CGI::FBHandle _fbh;
CGI::CSHandle _csh;
float _radius = 2.2f;
float _depthBias = 0.03f;
float _thickness = 0.3f;
float _equalizeDist = 20;
bool _cubeMapDebugMode = false;
bool _editMode = false;
public:
Ssr();
~Ssr();
void Init();
void Done();
void OnSwapChainResized();
bool BindDescriptorSetTextures();
void Generate();
bool IsCubeMapDebugMode() const { return _cubeMapDebugMode; }
void ToggleCubeMapDebugMode() { _cubeMapDebugMode = !_cubeMapDebugMode; }
bool IsEditMode() const { return _editMode; }
void ToggleEditMode() { _editMode = !_editMode; }
};
VERUS_TYPEDEFS(Ssr);
} }

View File

@ -1,244 +1,241 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Extra
{ {
namespace Extra struct BaseConvertDelegate;
class BaseConvert
{ {
struct BaseConvertDelegate; public:
class Mesh
class BaseConvert
{ {
public: public:
class Mesh enum class Found : int
{ {
public: null = 0,
enum class Found : int faces = (1 << 0),
{ posAndTexCoord0 = (1 << 1),
null = 0, normals = (1 << 2),
faces = (1 << 0), tangentSpace = (1 << 3),
posAndTexCoord0 = (1 << 1), skinning = (1 << 4),
normals = (1 << 2), texCoord1 = (1 << 5)
tangentSpace = (1 << 3),
skinning = (1 << 4),
texCoord1 = (1 << 5)
};
struct UberVertex
{
glm::vec3 _pos;
glm::vec3 _nrm;
glm::vec2 _tc0;
glm::vec2 _tc1;
glm::vec3 _tan;
glm::vec3 _bin;
UINT32 _bi[4];
float _bw[4];
int _currentWeight = 0;
UberVertex();
bool operator==(const UberVertex& that) const;
void Add(UINT32 index, float weight);
void CompileBits(UINT32& ii, UINT32& ww) const;
UINT32 GetDominantIndex();
};
VERUS_TYPEDEFS(UberVertex);
struct Face
{
UINT16 _indices[3];
};
VERUS_TYPEDEFS(Face);
struct Bone
{
String _name;
String _parentName;
glm::mat4 _trLocal;
glm::mat4 _trGlobal;
glm::mat4 _trToBoneSpace; // Inverse of Global.
bool _usedInSkin = false;
};
VERUS_TYPEDEFS(Bone);
private:
struct Vec3Short
{
short _x;
short _y;
short _z;
};
struct Vec2Short
{
short _u;
short _v;
};
struct Vec3Char
{
char _x;
char _y;
char _z;
};
struct Aabb
{
glm::vec3 _mn = glm::vec3(+FLT_MAX);
glm::vec3 _mx = glm::vec3(-FLT_MAX);
void Reset();
void Include(const glm::vec3& point);
glm::vec3 GetExtents() const;
};
BaseConvert* _pBaseConvert = nullptr;
String _name;
String _copyOf;
Vector<UberVertex> _vUberVerts;
Vector<Face> _vFaces;
Vector<Vec3Short> _vZipPos;
Vector<Vec3Char> _vZipNormal;
Vector<Vec3Char> _vZipTan;
Vector<Vec3Char> _vZipBin;
Vector<Vec2Short> _vZipTc0;
Vector<Vec2Short> _vZipTc1;
Vector<Bone> _vBones;
int _vertCount = 0;
int _faceCount = 0;
int _boneCount = 0;
glm::vec3 _posScale;
glm::vec3 _posBias;
glm::vec2 _tc0Scale;
glm::vec2 _tc0Bias;
glm::vec2 _tc1Scale;
glm::vec2 _tc1Bias;
glm::mat4 _matBoneAxis;
glm::mat4 _matGlobal;
glm::mat4 _worldSpace;
Found _found = Found::null;
int _materialIndex = 0;
public:
Mesh(BaseConvert* pBaseConvert);
~Mesh();
PBone FindBone(CSZ name);
VERUS_P(void CleanBones());
VERUS_P(void Optimize());
VERUS_P(void RecalculateTangentSpace());
VERUS_P(void Compress());
void SerializeX3D3(IO::RFile file);
RcString GetName() const { return _name; }
void SetName(CSZ name) { _name = name; }
const glm::mat4& GetBoneAxisMatrix() const { return _matBoneAxis; }
const glm::mat4& GetGlobalMatrix() const { return _matGlobal; }
void SetGlobalMatrix(const glm::mat4& mat) { _matGlobal = mat; }
const glm::mat4& GetWorldSpaceMatrix() const { return _worldSpace; }
void SetWorldSpaceMatrix(const glm::mat4& mat) { _worldSpace = mat; }
int GetVertCount() const { return _vertCount; }
int GetFaceCount() const { return _faceCount; }
int GetBoneCount() const { return _boneCount; }
void SetVertCount(int count) { _vertCount = count; }
void SetFaceCount(int count) { _faceCount = count; }
void SetBoneCount(int count) { _boneCount = count; }
void ResizeVertsArray(int size) { _vUberVerts.resize(size); }
void ResizeFacesArray(int size) { _vFaces.resize(size); }
RUberVertex GetSetVertexAt(int index) { return _vUberVerts[index]; }
RFace GetSetFaceAt(int index) { return _vFaces[index]; }
void AddFoundFlag(Found flag) { _found |= flag; }
int GetNextBoneIndex() const { return Utils::Cast32(_vBones.size()); }
void AddBone(RcBone bone) { _vBones.push_back(bone); }
bool IsCopyOf(Mesh& that);
bool IsCopy() const { return !_copyOf.empty(); }
RcString GetCopyOfName() const { return _copyOf; }
int GetMaterialIndex() const { return _materialIndex; }
void SetMaterialIndex(int index) { _materialIndex = index; }
};
VERUS_TYPEDEFS(Mesh);
struct SubKey
{
Quat _q;
bool _redundant = false;
}; };
struct AnimationKey // Represents one bone's channel in motion file. struct UberVertex
{ {
Vector<SubKey> _vFrame; glm::vec3 _pos;
int _type = 0; glm::vec3 _nrm;
int _logicFrameCount = 0; glm::vec2 _tc0;
glm::vec2 _tc1;
glm::vec3 _tan;
glm::vec3 _bin;
UINT32 _bi[4];
float _bw[4];
int _currentWeight = 0;
void DetectRedundantFrames(float threshold = 0.0001f); UberVertex();
bool operator==(const UberVertex& that) const;
void Add(UINT32 index, float weight);
void CompileBits(UINT32& ii, UINT32& ww) const;
UINT32 GetDominantIndex();
};
VERUS_TYPEDEFS(UberVertex);
struct Face
{
UINT16 _indices[3];
};
VERUS_TYPEDEFS(Face);
struct Bone
{
String _name;
String _parentName;
glm::mat4 _trLocal;
glm::mat4 _trGlobal;
glm::mat4 _trToBoneSpace; // Inverse of Global.
bool _usedInSkin = false;
};
VERUS_TYPEDEFS(Bone);
private:
struct Vec3Short
{
short _x;
short _y;
short _z;
}; };
struct Animation // Represents one bone in motion file. struct Vec2Short
{ {
String _name; short _u;
Vector<AnimationKey> _vAnimKeys; short _v;
}; };
struct AnimationSet // Represents one motion file. struct Vec3Char
{ {
String _name; char _x;
Vector<Animation> _vAnimations; char _y;
char _z;
void CleanUp();
}; };
protected: struct Aabb
typedef Map<String, String> TMapBoneNames; {
glm::vec3 _mn = glm::vec3(+FLT_MAX);
glm::vec3 _mx = glm::vec3(-FLT_MAX);
TMapBoneNames _mapBoneNames; void Reset();
BaseConvertDelegate* _pDelegate = nullptr; void Include(const glm::vec3& point);
Vector<PMesh> _vMeshes; glm::vec3 GetExtents() const;
Vector<AnimationSet> _vAnimSets; };
std::unique_ptr<Mesh> _pCurrentMesh;
BaseConvert* _pBaseConvert = nullptr;
String _name;
String _copyOf;
Vector<UberVertex> _vUberVerts;
Vector<Face> _vFaces;
Vector<Vec3Short> _vZipPos;
Vector<Vec3Char> _vZipNormal;
Vector<Vec3Char> _vZipTan;
Vector<Vec3Char> _vZipBin;
Vector<Vec2Short> _vZipTc0;
Vector<Vec2Short> _vZipTc1;
Vector<Bone> _vBones;
int _vertCount = 0;
int _faceCount = 0;
int _boneCount = 0;
glm::vec3 _posScale;
glm::vec3 _posBias;
glm::vec2 _tc0Scale;
glm::vec2 _tc0Bias;
glm::vec2 _tc1Scale;
glm::vec2 _tc1Bias;
glm::mat4 _matBoneAxis;
glm::mat4 _matGlobal;
glm::mat4 _worldSpace;
Found _found = Found::null;
int _materialIndex = 0;
public: public:
BaseConvert(); Mesh(BaseConvert* pBaseConvert);
~BaseConvert(); ~Mesh();
void LoadBoneNames(CSZ pathname); PBone FindBone(CSZ name);
String RenameBone(CSZ name);
protected: VERUS_P(void CleanBones());
PMesh AddMesh(PMesh pMesh); VERUS_P(void Optimize());
PMesh FindMesh(CSZ name); VERUS_P(void RecalculateTangentSpace());
void DeleteAll(); VERUS_P(void Compress());
void SerializeX3D3(IO::RFile file);
void OnProgress(float percent); RcString GetName() const { return _name; }
void OnProgressText(CSZ txt); void SetName(CSZ name) { _name = name; }
virtual bool UseAreaBasedNormals() { return false; } const glm::mat4& GetBoneAxisMatrix() const { return _matBoneAxis; }
virtual bool UseRigidBones() { return false; }
virtual Str GetPathname() { return ""; }
void SerializeMotions(SZ pathname); const glm::mat4& GetGlobalMatrix() const { return _matGlobal; }
void SetGlobalMatrix(const glm::mat4& mat) { _matGlobal = mat; }
const glm::mat4& GetWorldSpaceMatrix() const { return _worldSpace; }
void SetWorldSpaceMatrix(const glm::mat4& mat) { _worldSpace = mat; }
int GetVertCount() const { return _vertCount; }
int GetFaceCount() const { return _faceCount; }
int GetBoneCount() const { return _boneCount; }
void SetVertCount(int count) { _vertCount = count; }
void SetFaceCount(int count) { _faceCount = count; }
void SetBoneCount(int count) { _boneCount = count; }
void ResizeVertsArray(int size) { _vUberVerts.resize(size); }
void ResizeFacesArray(int size) { _vFaces.resize(size); }
RUberVertex GetSetVertexAt(int index) { return _vUberVerts[index]; }
RFace GetSetFaceAt(int index) { return _vFaces[index]; }
void AddFoundFlag(Found flag) { _found |= flag; }
int GetNextBoneIndex() const { return Utils::Cast32(_vBones.size()); }
void AddBone(RcBone bone) { _vBones.push_back(bone); }
bool IsCopyOf(Mesh& that);
bool IsCopy() const { return !_copyOf.empty(); }
RcString GetCopyOfName() const { return _copyOf; }
int GetMaterialIndex() const { return _materialIndex; }
void SetMaterialIndex(int index) { _materialIndex = index; }
}; };
VERUS_TYPEDEFS(BaseConvert); VERUS_TYPEDEFS(Mesh);
struct BaseConvertDelegate struct SubKey
{ {
virtual void BaseConvert_OnProgress(float percent) = 0; Quat _q;
virtual void BaseConvert_OnProgressText(CSZ txt) = 0; bool _redundant = false;
virtual void BaseConvert_Optimize(
Vector<BaseConvert::Mesh::UberVertex>& vVB,
Vector<BaseConvert::Mesh::Face>& vIB) = 0;
virtual bool BaseConvert_CanOverwriteFile(CSZ filename) { return true; }
}; };
VERUS_TYPEDEFS(BaseConvertDelegate);
} struct AnimationKey // Represents one bone's channel in motion file.
{
Vector<SubKey> _vFrame;
int _type = 0;
int _logicFrameCount = 0;
void DetectRedundantFrames(float threshold = 0.0001f);
};
struct Animation // Represents one bone in motion file.
{
String _name;
Vector<AnimationKey> _vAnimKeys;
};
struct AnimationSet // Represents one motion file.
{
String _name;
Vector<Animation> _vAnimations;
void CleanUp();
};
protected:
typedef Map<String, String> TMapBoneNames;
TMapBoneNames _mapBoneNames;
BaseConvertDelegate* _pDelegate = nullptr;
Vector<PMesh> _vMeshes;
Vector<AnimationSet> _vAnimSets;
std::unique_ptr<Mesh> _pCurrentMesh;
public:
BaseConvert();
~BaseConvert();
void LoadBoneNames(CSZ pathname);
String RenameBone(CSZ name);
protected:
PMesh AddMesh(PMesh pMesh);
PMesh FindMesh(CSZ name);
void DeleteAll();
void OnProgress(float percent);
void OnProgressText(CSZ txt);
virtual bool UseAreaBasedNormals() { return false; }
virtual bool UseRigidBones() { return false; }
virtual Str GetPathname() { return ""; }
void SerializeMotions(SZ pathname);
};
VERUS_TYPEDEFS(BaseConvert);
struct BaseConvertDelegate
{
virtual void BaseConvert_OnProgress(float percent) = 0;
virtual void BaseConvert_OnProgressText(CSZ txt) = 0;
virtual void BaseConvert_Optimize(
Vector<BaseConvert::Mesh::UberVertex>& vVB,
Vector<BaseConvert::Mesh::Face>& vIB) = 0;
virtual bool BaseConvert_CanOverwriteFile(CSZ filename) { return true; }
};
VERUS_TYPEDEFS(BaseConvertDelegate);
} }

View File

@ -1,76 +1,73 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Extra
{ {
namespace Extra class ConvertGLTF : public Singleton<ConvertGLTF>, public Object, public BaseConvert
{ {
class ConvertGLTF : public Singleton<ConvertGLTF>, public Object, public BaseConvert public:
struct Desc
{ {
public: glm::vec3 _bias = glm::vec3(0);
struct Desc float _scaleFactor = 1;
{ float _angle = 0;
glm::vec3 _bias = glm::vec3(0); float _areaBasedNormals = 0;
float _scaleFactor = 1; bool _flipNormals = false;
float _angle = 0; bool _flipFaces = false;
float _areaBasedNormals = 0; bool _useRigidBones = false;
bool _flipNormals = false; bool _convertAsScene = false;
bool _flipFaces = false;
bool _useRigidBones = false;
bool _convertAsScene = false;
};
VERUS_TYPEDEFS(Desc);
private:
struct NodeExtraData
{
int _parent = -1;
glm::mat4 _trLocal;
glm::mat4 _trGlobal;
};
tinygltf::TinyGLTF _context;
tinygltf::Model _model;
String _pathname;
Vector<char> _vData;
Vector<NodeExtraData> _vNodeExtraData;
std::future<void> _future;
Desc _desc;
public:
ConvertGLTF();
~ConvertGLTF();
void Init(PBaseConvertDelegate p, RcDesc desc);
void Done();
virtual bool UseAreaBasedNormals() override;
virtual bool UseRigidBones() override;
virtual Str GetPathname() override;
void ParseData(CSZ pathname);
void SerializeAll(CSZ pathname);
void AsyncRun(CSZ pathname);
void AsyncJoin();
bool IsAsyncStarted() const;
bool IsAsyncFinished() const;
private:
void LoadFromFile(CSZ pathname);
void ProcessNodeRecursive(const tinygltf::Node& node, int nodeIndex, bool computeExtraData);
void ProcessMesh(const tinygltf::Mesh& mesh, int nodeIndex, int skinIndex);
void ProcessSkin(const tinygltf::Skin& skin);
void ProcessAnimation(const tinygltf::Animation& anim);
void TryResizeVertsArray(int vertCount);
static glm::vec3 ToVec3(const double* p);
static glm::quat ToQuat(const double* p);
static glm::mat4 ToMat4(const double* p);
static glm::mat4 GetNodeMatrix(const tinygltf::Node& node);
}; };
VERUS_TYPEDEFS(ConvertGLTF); VERUS_TYPEDEFS(Desc);
}
private:
struct NodeExtraData
{
int _parent = -1;
glm::mat4 _trLocal;
glm::mat4 _trGlobal;
};
tinygltf::TinyGLTF _context;
tinygltf::Model _model;
String _pathname;
Vector<char> _vData;
Vector<NodeExtraData> _vNodeExtraData;
std::future<void> _future;
Desc _desc;
public:
ConvertGLTF();
~ConvertGLTF();
void Init(PBaseConvertDelegate p, RcDesc desc);
void Done();
virtual bool UseAreaBasedNormals() override;
virtual bool UseRigidBones() override;
virtual Str GetPathname() override;
void ParseData(CSZ pathname);
void SerializeAll(CSZ pathname);
void AsyncRun(CSZ pathname);
void AsyncJoin();
bool IsAsyncStarted() const;
bool IsAsyncFinished() const;
private:
void LoadFromFile(CSZ pathname);
void ProcessNodeRecursive(const tinygltf::Node& node, int nodeIndex, bool computeExtraData);
void ProcessMesh(const tinygltf::Mesh& mesh, int nodeIndex, int skinIndex);
void ProcessSkin(const tinygltf::Skin& skin);
void ProcessAnimation(const tinygltf::Animation& anim);
void TryResizeVertsArray(int vertCount);
static glm::vec3 ToVec3(const double* p);
static glm::quat ToQuat(const double* p);
static glm::mat4 ToMat4(const double* p);
static glm::mat4 GetNodeMatrix(const tinygltf::Node& node);
};
VERUS_TYPEDEFS(ConvertGLTF);
} }

View File

@ -1,127 +1,124 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::Extra
{ {
namespace Extra class ConvertX : public Singleton<ConvertX>, public Object, public BaseConvert
{ {
class ConvertX : public Singleton<ConvertX>, public Object, public BaseConvert public:
struct Desc
{ {
public: glm::vec3 _bias = glm::vec3(0);
struct Desc float _scaleFactor = 1;
{ float _angle = 0;
glm::vec3 _bias = glm::vec3(0); float _areaBasedNormals = 0;
float _scaleFactor = 1; bool _useRigidBones = false;
float _angle = 0; bool _convertAsScene = false;
float _areaBasedNormals = 0; bool _useDefaultMaterial = false;
bool _useRigidBones = false; bool _rightHanded = true;
bool _convertAsScene = false;
bool _useDefaultMaterial = false;
bool _rightHanded = true;
};
VERUS_TYPEDEFS(Desc);
private:
struct Frame
{
String _name;
String _parentName;
glm::mat4 _trLocal;
glm::mat4 _trGlobal;
};
VERUS_TYPEDEFS(Frame);
struct Material
{
String _name;
String _copyOf;
String _textureFilename;
glm::vec4 _faceColor;
glm::vec3 _specularColor;
glm::vec3 _emissiveColor;
float _power = 1;
bool IsCopyOf(const Material& that)
{
const float e = 0.01f;
return
_textureFilename == that._textureFilename &&
glm::all(glm::epsilonEqual(_faceColor, that._faceColor, e)) &&
glm::all(glm::epsilonEqual(_specularColor, that._specularColor, e)) &&
glm::all(glm::epsilonEqual(_emissiveColor, that._emissiveColor, e)) &&
glm::epsilonEqual(_power, that._power, e);
}
};
VERUS_TYPEDEFS(Material);
typedef Map<String, Frame> TMapFrames;
Transform3 _trRoot;
String _currentMesh;
String _pathname;
Vector<char> _vData;
const char* _pData;
const char* _pDataBegin;
TMapFrames _mapFrames;
Vector<Frame> _stackFrames;
Vector<Material> _vMaterials;
std::future<void> _future;
Desc _desc;
int _depth = 0;
StringStream _ssDebug;
public:
ConvertX();
~ConvertX();
void Init(PBaseConvertDelegate p, RcDesc desc);
void Done();
virtual bool UseAreaBasedNormals() override;
virtual bool UseRigidBones() override;
virtual Str GetPathname() override;
void ParseData(CSZ pathname);
void SerializeAll(CSZ pathname);
void AsyncRun(CSZ pathname);
void AsyncJoin();
bool IsAsyncStarted() const;
bool IsAsyncFinished() const;
private:
void LoadFromFile(CSZ pathname);
void StreamReadUntil(SZ dest, int destSize, CSZ separator);
void StreamSkipWhitespace();
void StreamSkipUntil(char c);
void FixBones();
void ParseBlockRecursive(CSZ type, CSZ blockName);
void ParseBlockData_Mesh();
void ParseBlockData_MeshTextureCoords();
void ParseBlockData_MeshNormals();
void ParseBlockData_FVFData(bool declData);
void ParseBlockData_XSkinMeshHeader();
void ParseBlockData_SkinWeights();
void ParseBlockData_Frame(CSZ blockName);
void ParseBlockData_FrameTransformMatrix();
void ParseBlockData_AnimationSet(CSZ blockName);
void ParseBlockData_Animation(CSZ blockName);
void ParseBlockData_AnimationKey();
void ParseBlockData_Material();
void ParseBlockData_TextureFilename();
void ParseBlockData_MeshMaterialList();
void OnProgress(float percent);
void OnProgressText(CSZ txt);
void Debug(CSZ txt);
void DetectMaterialCopies();
String GetXmlMaterial(int i);
}; };
VERUS_TYPEDEFS(ConvertX); VERUS_TYPEDEFS(Desc);
}
private:
struct Frame
{
String _name;
String _parentName;
glm::mat4 _trLocal;
glm::mat4 _trGlobal;
};
VERUS_TYPEDEFS(Frame);
struct Material
{
String _name;
String _copyOf;
String _textureFilename;
glm::vec4 _faceColor;
glm::vec3 _specularColor;
glm::vec3 _emissiveColor;
float _power = 1;
bool IsCopyOf(const Material& that)
{
const float e = 0.01f;
return
_textureFilename == that._textureFilename &&
glm::all(glm::epsilonEqual(_faceColor, that._faceColor, e)) &&
glm::all(glm::epsilonEqual(_specularColor, that._specularColor, e)) &&
glm::all(glm::epsilonEqual(_emissiveColor, that._emissiveColor, e)) &&
glm::epsilonEqual(_power, that._power, e);
}
};
VERUS_TYPEDEFS(Material);
typedef Map<String, Frame> TMapFrames;
Transform3 _trRoot;
String _currentMesh;
String _pathname;
Vector<char> _vData;
const char* _pData;
const char* _pDataBegin;
TMapFrames _mapFrames;
Vector<Frame> _stackFrames;
Vector<Material> _vMaterials;
std::future<void> _future;
Desc _desc;
int _depth = 0;
StringStream _ssDebug;
public:
ConvertX();
~ConvertX();
void Init(PBaseConvertDelegate p, RcDesc desc);
void Done();
virtual bool UseAreaBasedNormals() override;
virtual bool UseRigidBones() override;
virtual Str GetPathname() override;
void ParseData(CSZ pathname);
void SerializeAll(CSZ pathname);
void AsyncRun(CSZ pathname);
void AsyncJoin();
bool IsAsyncStarted() const;
bool IsAsyncFinished() const;
private:
void LoadFromFile(CSZ pathname);
void StreamReadUntil(SZ dest, int destSize, CSZ separator);
void StreamSkipWhitespace();
void StreamSkipUntil(char c);
void FixBones();
void ParseBlockRecursive(CSZ type, CSZ blockName);
void ParseBlockData_Mesh();
void ParseBlockData_MeshTextureCoords();
void ParseBlockData_MeshNormals();
void ParseBlockData_FVFData(bool declData);
void ParseBlockData_XSkinMeshHeader();
void ParseBlockData_SkinWeights();
void ParseBlockData_Frame(CSZ blockName);
void ParseBlockData_FrameTransformMatrix();
void ParseBlockData_AnimationSet(CSZ blockName);
void ParseBlockData_Animation(CSZ blockName);
void ParseBlockData_AnimationKey();
void ParseBlockData_Material();
void ParseBlockData_TextureFilename();
void ParseBlockData_MeshMaterialList();
void OnProgress(float percent);
void OnProgressText(CSZ txt);
void Debug(CSZ txt);
void DetectMaterialCopies();
String GetXmlMaterial(int i);
};
VERUS_TYPEDEFS(ConvertX);
} }

View File

@ -1,118 +1,115 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::GUI
{ {
namespace GUI template<typename T>
struct Animated
{ {
template<typename T> T _from = 0;
struct Animated T _to = 0;
T _current = 0;
float _time = 0;
float _invDuration = 0;
float _delay = 0;
Easing _easing = Easing::none;
T Lerp(const T& a, const T& b, float ratio)
{ {
T _from = 0; return Math::Lerp(a, b, ratio);
T _to = 0; }
T _current = 0;
float _time = 0;
float _invDuration = 0;
float _delay = 0;
Easing _easing = Easing::none;
T Lerp(const T& a, const T& b, float ratio) void Update(float dt)
{
return Math::Lerp(a, b, ratio);
}
void Update(float dt)
{
if (_invDuration > 0)
{
if (_time >= 0)
_time += dt;
const float ratio = Math::Clamp<float>((_time - _delay) * _invDuration, 0, 1);
const float ratioWithEasing = Math::ApplyEasing(_easing, ratio);
_current = Lerp(_from, _to, ratioWithEasing);
if (dt > 0 && ratio >= 1)
_invDuration = -_invDuration;
}
}
void Reset(float reverseTime)
{
_current = _from;
_time = reverseTime;
_invDuration = abs(_invDuration);
Update(0);
}
};
class Widget;
class Animator
{ {
struct Video if (_invDuration > 0)
{ {
int _columnCount = 1; if (_time >= 0)
int _rowCount = 1; _time += dt;
int _frameCount = 1; const float ratio = Math::Clamp<float>((_time - _delay) * _invDuration, 0, 1);
float _time = 0; const float ratioWithEasing = Math::ApplyEasing(_easing, ratio);
float _invDuration = 0; _current = Lerp(_from, _to, ratioWithEasing);
float _delay = 0; if (dt > 0 && ratio >= 1)
float _uScale = 1; _invDuration = -_invDuration;
float _vScale = 1; }
float _uBias = 0; }
float _vBias = 0;
void Update(float dt); void Reset(float reverseTime)
void Reset(float reverseTime); {
} _video; _current = _from;
_time = reverseTime;
_invDuration = abs(_invDuration);
Update(0);
}
};
Animated<Vector4> _animatedColor; class Widget;
Animated<Vector4> _animatedRect; class Animator
float _postAngle = 0; {
float _angle = 0; struct Video
float _angleSpeed = 0; {
float _pulseScale = 1; int _columnCount = 1;
float _pulseScaleAdd = 0; int _rowCount = 1;
float _pulseSpeed = 0; int _frameCount = 1;
float _timeout = 0; float _time = 0;
float _maxTimeout = -1; float _invDuration = 0;
float _originalW = 0; float _delay = 0;
bool _reverse = false; float _uScale = 1;
bool _preserveAspectRatio = false; float _vScale = 1;
float _uBias = 0;
float _vBias = 0;
public: void Update(float dt);
Animator(); void Reset(float reverseTime);
~Animator(); } _video;
bool Update(); Animated<Vector4> _animatedColor;
void Parse(pugi::xml_node node, const Widget* pWidget); Animated<Vector4> _animatedRect;
float _postAngle = 0;
float _angle = 0;
float _angleSpeed = 0;
float _pulseScale = 1;
float _pulseScaleAdd = 0;
float _pulseSpeed = 0;
float _timeout = 0;
float _maxTimeout = -1;
float _originalW = 0;
bool _reverse = false;
bool _preserveAspectRatio = false;
void Reset(float reverseTime = 0); public:
Animator();
~Animator();
RcVector4 GetColor(RcVector4 original) const; bool Update();
RcVector4 SetColor(RcVector4 color); void Parse(pugi::xml_node node, const Widget* pWidget);
RcVector4 SetFromColor(RcVector4 color);
float GetX(float original) const; void Reset(float reverseTime = 0);
float GetY(float original) const;
float GetW(float original) const;
float GetH(float original) const;
float SetX(float x); RcVector4 GetColor(RcVector4 original) const;
float SetY(float y); RcVector4 SetColor(RcVector4 color);
float SetW(float w); RcVector4 SetFromColor(RcVector4 color);
float SetH(float h);
bool GetVideoBias(float& ub, float& vb) const; float GetX(float original) const;
float GetY(float original) const;
float GetW(float original) const;
float GetH(float original) const;
float GetAngle() const { return _angle; } float SetX(float x);
void SetAngle(float a) { _angle = a; } float SetY(float y);
float GetPostAngle() const { return _postAngle; } float SetW(float w);
void SetPostAngle(float a) { _postAngle = a; } float SetH(float h);
float GetPulseScale() const { return _pulseScale; } bool GetVideoBias(float& ub, float& vb) const;
float GetPulseScaleAdd() const { return _pulseScaleAdd; }
void SetTimeout(float t); float GetAngle() const { return _angle; }
}; void SetAngle(float a) { _angle = a; }
VERUS_TYPEDEFS(Animator); float GetPostAngle() const { return _postAngle; }
} void SetPostAngle(float a) { _postAngle = a; }
float GetPulseScale() const { return _pulseScale; }
float GetPulseScaleAdd() const { return _pulseScaleAdd; }
void SetTimeout(float t);
};
VERUS_TYPEDEFS(Animator);
} }

View File

@ -1,24 +1,21 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::GUI
{ {
namespace GUI class Bars : public Widget
{ {
class Bars : public Widget float _aspectRatio = 21 / 9.f;
{
float _aspectRatio = 21 / 9.f;
public: public:
Bars(); Bars();
virtual ~Bars(); virtual ~Bars();
static PWidget Make(); static PWidget Make();
virtual void Update() override; virtual void Update() override;
virtual void Draw() override; virtual void Draw() override;
virtual void Parse(pugi::xml_node node) override; virtual void Parse(pugi::xml_node node) override;
}; };
VERUS_TYPEDEFS(Bars); VERUS_TYPEDEFS(Bars);
}
} }

View File

@ -1,27 +1,24 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved. // Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once #pragma once
namespace verus namespace verus::GUI
{ {
namespace GUI class Button : public Widget
{ {
class Button : public Widget Label _label;
{ Image _image;
Label _label; Image _icon;
Image _image; bool _hasIcon = false;
Image _icon;
bool _hasIcon = false;
public: public:
Button(); Button();
virtual ~Button(); virtual ~Button();
static PWidget Make(); static PWidget Make();
virtual void Update() override; virtual void Update() override;
virtual void Draw() override; virtual void Draw() override;
virtual void Parse(pugi::xml_node node) override; virtual void Parse(pugi::xml_node node) override;
}; };
VERUS_TYPEDEFS(Button); VERUS_TYPEDEFS(Button);
}
} }

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