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

View File

@ -1,55 +1,52 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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;
};
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;
float _x, _y, _z;
UINT32 _color;
};
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()

View File

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

View File

@ -1,55 +1,52 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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
// "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
{
struct Vertex
{
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;
float _x, _y, _z;
UINT32 _color;
};
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()

View File

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

View File

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

View File

@ -1,65 +1,62 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once
namespace verus
namespace verus::CGI
{
namespace CGI
class CommandBufferD3D11 : public BaseCommandBuffer
{
class CommandBufferD3D11 : public BaseCommandBuffer
{
ComPtr<ID3D11DeviceContext> _pDeviceContext;
RP::PcD3DRenderPass _pRenderPass = nullptr;
RP::PcD3DFramebuffer _pFramebuffer = nullptr;
Vector<FLOAT> _vClearValues;
int _subpassIndex = 0;
float _blendFactor[4];
ComPtr<ID3D11DeviceContext> _pDeviceContext;
RP::PcD3DRenderPass _pRenderPass = nullptr;
RP::PcD3DFramebuffer _pFramebuffer = nullptr;
Vector<FLOAT> _vClearValues;
int _subpassIndex = 0;
float _blendFactor[4];
public:
CommandBufferD3D11();
virtual ~CommandBufferD3D11() override;
public:
CommandBufferD3D11();
virtual ~CommandBufferD3D11() override;
virtual void Init() override;
virtual void Done() override;
virtual void Init() override;
virtual void Done() override;
virtual void InitOneTimeSubmit() override;
virtual void DoneOneTimeSubmit() override;
virtual void InitOneTimeSubmit() override;
virtual void DoneOneTimeSubmit() override;
virtual void Begin() override;
virtual void End() override;
virtual void Begin() 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,
std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf) override;
virtual void NextSubpass() override;
virtual void EndRenderPass() override;
virtual void BeginRenderPass(RPHandle renderPassHandle, FBHandle framebufferHandle,
std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf) override;
virtual void NextSubpass() override;
virtual void EndRenderPass() override;
virtual void BindPipeline(PipelinePtr pipe) 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 SetBlendConstants(const float* p) override;
virtual void BindPipeline(PipelinePtr pipe) 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 SetBlendConstants(const float* p) override;
virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter) override;
virtual void BindIndexBuffer(GeometryPtr geo) override;
virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter) override;
virtual void BindIndexBuffer(GeometryPtr geo) override;
virtual bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle) 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 bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle) 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 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 Dispatch(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 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 Dispatch(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;
//
// D3D11
//
//
// D3D11
//
ID3D11DeviceContext* GetD3DDeviceContext() const;
ID3D11DeviceContext* GetD3DDeviceContext() const;
void PrepareSubpass();
};
VERUS_TYPEDEFS(CommandBufferD3D11);
}
void PrepareSubpass();
};
VERUS_TYPEDEFS(CommandBufferD3D11);
}

View File

@ -1,66 +1,63 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once
namespace verus
namespace verus::CGI
{
namespace CGI
class RendererD3D11;
class ExtRealityD3D11 : public BaseExtReality
{
class RendererD3D11;
class ExtRealityD3D11 : public BaseExtReality
struct SwapChainEx
{
struct SwapChainEx
{
XrSwapchain _handle = XR_NULL_HANDLE;
int32_t _width = 0;
int32_t _height = 0;
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;
XrSwapchain _handle = XR_NULL_HANDLE;
int32_t _width = 0;
int32_t _height = 0;
Vector<XrSwapchainImageD3D11KHR> _vImages;
Vector<ComPtr<ID3D11RenderTargetView>> _vImageViews;
};
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.
#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;
};
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(); }
ComPtr<ID3D11Buffer> _pBuffer;
UINT64 _bufferSize = 0;
};
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.
#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 ToNativeSampledDepthFormat(Format format);
DXGI_FORMAT ToNativeFormat(Format format, bool typeless);
DXGI_FORMAT ToNativeSampledDepthFormat(Format format);
CSZ ToNativeSemanticName(ViaUsage usage);
DXGI_FORMAT ToNativeFormat(ViaUsage usage, ViaType type, int components);
}
CSZ ToNativeSemanticName(ViaUsage usage);
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.
#pragma once
namespace verus
namespace verus::CGI
{
namespace CGI
class PipelineD3D11 : public BasePipeline
{
class PipelineD3D11 : public BasePipeline
{
ComPtr<ID3D11VertexShader> _pVS;
ComPtr<ID3D11HullShader> _pHS;
ComPtr<ID3D11DomainShader> _pDS;
ComPtr<ID3D11GeometryShader> _pGS;
ComPtr<ID3D11PixelShader> _pPS;
ComPtr<ID3D11ComputeShader> _pCS;
ComPtr<ID3D11BlendState> _pBlendState;
ComPtr<ID3D11RasterizerState> _pRasterizerState;
ComPtr<ID3D11DepthStencilState> _pDepthStencilState;
ComPtr<ID3D11InputLayout> _pInputLayout;
UINT _sampleMask = UINT_MAX;
UINT _stencilRef = 0;
D3D_PRIMITIVE_TOPOLOGY _topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
bool _compute = false;
ComPtr<ID3D11VertexShader> _pVS;
ComPtr<ID3D11HullShader> _pHS;
ComPtr<ID3D11DomainShader> _pDS;
ComPtr<ID3D11GeometryShader> _pGS;
ComPtr<ID3D11PixelShader> _pPS;
ComPtr<ID3D11ComputeShader> _pCS;
ComPtr<ID3D11BlendState> _pBlendState;
ComPtr<ID3D11RasterizerState> _pRasterizerState;
ComPtr<ID3D11DepthStencilState> _pDepthStencilState;
ComPtr<ID3D11InputLayout> _pInputLayout;
UINT _sampleMask = UINT_MAX;
UINT _stencilRef = 0;
D3D_PRIMITIVE_TOPOLOGY _topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
bool _compute = false;
public:
PipelineD3D11();
virtual ~PipelineD3D11() override;
public:
PipelineD3D11();
virtual ~PipelineD3D11() override;
virtual void Init(RcPipelineDesc desc) override;
virtual void Done() override;
virtual void Init(RcPipelineDesc desc) override;
virtual void Done() override;
//
// D3D11
//
//
// D3D11
//
VERUS_P(void InitCompute(RcPipelineDesc desc));
bool IsCompute() const { return _compute; }
ID3D11VertexShader* GetD3DVS() const { return _pVS.Get(); }
ID3D11HullShader* GetD3DHS() const { return _pHS.Get(); }
ID3D11DomainShader* GetD3DDS() const { return _pDS.Get(); }
ID3D11GeometryShader* GetD3DGS() const { return _pGS.Get(); }
ID3D11PixelShader* GetD3DPS() const { return _pPS.Get(); }
ID3D11ComputeShader* GetD3DCS() const { return _pCS.Get(); }
ID3D11BlendState* GetD3DBlendState() const { return _pBlendState.Get(); }
ID3D11RasterizerState* GetD3DRasterizerState() const { return _pRasterizerState.Get(); }
ID3D11DepthStencilState* GetD3DDepthStencilState() const { return _pDepthStencilState.Get(); }
ID3D11InputLayout* GetD3DInputLayout() const { return _pInputLayout.Get(); }
UINT GetSampleMask() const { return _sampleMask; }
UINT GetStencilRef() const { return _stencilRef; }
D3D_PRIMITIVE_TOPOLOGY GetD3DPrimitiveTopology() const { return _topology; }
void FillBlendStateRenderTargets(RcPipelineDesc desc, int attachmentCount, D3D11_BLEND_DESC& blendDesc);
};
VERUS_TYPEDEFS(PipelineD3D11);
}
VERUS_P(void InitCompute(RcPipelineDesc desc));
bool IsCompute() const { return _compute; }
ID3D11VertexShader* GetD3DVS() const { return _pVS.Get(); }
ID3D11HullShader* GetD3DHS() const { return _pHS.Get(); }
ID3D11DomainShader* GetD3DDS() const { return _pDS.Get(); }
ID3D11GeometryShader* GetD3DGS() const { return _pGS.Get(); }
ID3D11PixelShader* GetD3DPS() const { return _pPS.Get(); }
ID3D11ComputeShader* GetD3DCS() const { return _pCS.Get(); }
ID3D11BlendState* GetD3DBlendState() const { return _pBlendState.Get(); }
ID3D11RasterizerState* GetD3DRasterizerState() const { return _pRasterizerState.Get(); }
ID3D11DepthStencilState* GetD3DDepthStencilState() const { return _pDepthStencilState.Get(); }
ID3D11InputLayout* GetD3DInputLayout() const { return _pInputLayout.Get(); }
UINT GetSampleMask() const { return _sampleMask; }
UINT GetStencilRef() const { return _stencilRef; }
D3D_PRIMITIVE_TOPOLOGY GetD3DPrimitiveTopology() const { return _topology; }
void FillBlendStateRenderTargets(RcPipelineDesc desc, int attachmentCount, D3D11_BLEND_DESC& blendDesc);
};
VERUS_TYPEDEFS(PipelineD3D11);
}

View File

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

View File

@ -1,99 +1,96 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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;
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
{
ExtRealityD3D11 _extReality;
ComPtr<ID3D11Device> _pDevice;
ComPtr<ID3D11DeviceContext> _pDeviceContext;
ComPtr<IDXGISwapChain> _pSwapChain;
ComPtr<ID3D11Texture2D> _pSwapChainBuffer;
ComPtr<ID3D11RenderTargetView> _pSwapChainBufferRTV;
ExtRealityD3D11 _extReality;
ComPtr<ID3D11Device> _pDevice;
ComPtr<ID3D11DeviceContext> _pDeviceContext;
ComPtr<IDXGISwapChain> _pSwapChain;
ComPtr<ID3D11Texture2D> _pSwapChainBuffer;
ComPtr<ID3D11RenderTargetView> _pSwapChainBufferRTV;
Vector<ComPtr<ID3D11SamplerState>> _vSamplers;
Vector<RP::D3DRenderPass> _vRenderPasses;
Vector<RP::D3DFramebuffer> _vFramebuffers;
D3D_FEATURE_LEVEL _featureLevel = D3D_FEATURE_LEVEL_11_0;
DXGI_SWAP_CHAIN_DESC _swapChainDesc = {};
Vector<ComPtr<ID3D11SamplerState>> _vSamplers;
Vector<RP::D3DRenderPass> _vRenderPasses;
Vector<RP::D3DFramebuffer> _vFramebuffers;
D3D_FEATURE_LEVEL _featureLevel = D3D_FEATURE_LEVEL_11_0;
DXGI_SWAP_CHAIN_DESC _swapChainDesc = {};
public:
RendererD3D11();
~RendererD3D11();
public:
RendererD3D11();
~RendererD3D11();
virtual void ReleaseMe() override;
virtual void ReleaseMe() override;
void Init();
void Done();
void Init();
void Done();
private:
static ComPtr<IDXGIFactory1> CreateFactory();
ComPtr<IDXGIAdapter1> GetAdapter(ComPtr<IDXGIFactory1> pFactory) const;
void CreateSwapChainBufferRTV();
void InitD3D();
private:
static ComPtr<IDXGIFactory1> CreateFactory();
ComPtr<IDXGIAdapter1> GetAdapter(ComPtr<IDXGIFactory1> pFactory) const;
void CreateSwapChainBufferRTV();
void InitD3D();
public:
// <CreateAndGet>
void CreateSamplers();
public:
// <CreateAndGet>
void CreateSamplers();
ID3D11Device* GetD3DDevice() const { return _pDevice.Get(); }
ID3D11DeviceContext* GetD3DDeviceContext() const { return _pDeviceContext.Get(); }
ID3D11SamplerState* GetD3DSamplerState(Sampler s) const;
// </CreateAndGet>
ID3D11Device* GetD3DDevice() const { return _pDevice.Get(); }
ID3D11DeviceContext* GetD3DDeviceContext() const { return _pDeviceContext.Get(); }
ID3D11SamplerState* GetD3DSamplerState(Sampler s) const;
// </CreateAndGet>
virtual void ImGuiInit(RPHandle renderPassHandle) override;
virtual void ImGuiRenderDrawData() override;
virtual void ImGuiInit(RPHandle renderPassHandle) override;
virtual void ImGuiRenderDrawData() override;
virtual void ResizeSwapChain() override;
virtual void ResizeSwapChain() override;
virtual PBaseExtReality GetExtReality() override;
virtual PBaseExtReality GetExtReality() override;
// Which graphics API?
virtual Gapi GetGapi() override { return Gapi::direct3D11; }
// Which graphics API?
virtual Gapi GetGapi() override { return Gapi::direct3D11; }
// <FrameCycle>
virtual void BeginFrame() override;
virtual void AcquireSwapChainImage() override;
virtual void EndFrame() override;
virtual void WaitIdle() override;
virtual void OnMinimized() override;
// </FrameCycle>
// <FrameCycle>
virtual void BeginFrame() override;
virtual void AcquireSwapChainImage() override;
virtual void EndFrame() override;
virtual void WaitIdle() override;
virtual void OnMinimized() override;
// </FrameCycle>
// <Resources>
virtual PBaseCommandBuffer InsertCommandBuffer() override;
virtual PBaseGeometry InsertGeometry() override;
virtual PBasePipeline InsertPipeline() override;
virtual PBaseShader InsertShader() override;
virtual PBaseTexture InsertTexture() override;
// <Resources>
virtual PBaseCommandBuffer InsertCommandBuffer() override;
virtual PBaseGeometry InsertGeometry() override;
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 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;
RP::RcD3DRenderPass GetRenderPass(RPHandle handle) const;
RP::RcD3DFramebuffer GetFramebuffer(FBHandle handle) const;
// </Resources>
};
VERUS_TYPEDEFS(RendererD3D11);
}
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;
RP::RcD3DRenderPass GetRenderPass(RPHandle handle) const;
RP::RcD3DFramebuffer GetFramebuffer(FBHandle handle) const;
// </Resources>
};
VERUS_TYPEDEFS(RendererD3D11);
}
#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;
auto CheckErrorMsgs = [this](ComPtr<ID3DBlob>& pErrorMsgs)
{
if (pErrorMsgs)
{
OnError(static_cast<CSZ>(pErrorMsgs->GetBufferPointer()));
pErrorMsgs.Reset();
}
};
if (pErrorMsgs)
{
OnError(static_cast<CSZ>(pErrorMsgs->GetBufferPointer()));
pErrorMsgs.Reset();
}
};
while (*branches)
{
@ -191,10 +191,10 @@ void ShaderD3D11::Done()
for (auto& dsd : _vDescriptorSetDesc)
dsd._pConstantBuffer.Reset();
for (auto& x : _mapCompiled)
for (auto& [key, value] : _mapCompiled)
{
VERUS_FOR(i, +Stage::count)
x.second._pBlobs[i].Reset();
value._pBlobs[i].Reset();
}
VERUS_DONE(ShaderD3D11);

View File

@ -1,108 +1,105 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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:
virtual HRESULT STDMETHODCALLTYPE Open(
D3D_INCLUDE_TYPE IncludeType,
LPCSTR pFileName,
LPCVOID pParentData,
LPCVOID* ppData,
UINT* pBytes) override;
virtual HRESULT STDMETHODCALLTYPE Close(LPCVOID pData) override;
ComPtr<ID3DBlob> _pBlobs[+Stage::count];
String _entry;
int _stageCount = 0;
};
VERUS_TYPEDEFS(ShaderInclude);
VERUS_TYPEDEFS(Compiled);
struct ShaderResources
private:
typedef Map<String, Compiled> TMapCompiled;
struct DescriptorSetDesc
{
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];
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;
};
VERUS_TYPEDEFS(ShaderResources);
class ShaderD3D11 : public BaseShader
struct ComplexSet
{
public:
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<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;
Vector<TexturePtr> _vTextures;
Vector<ID3D11ShaderResourceView*> _vSRVs;
Vector<ID3D11UnorderedAccessView*> _vUAVs;
};
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.
#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> _pUaTexture;
Vector<ComPtr<ID3D11Texture2D>> _vReadbackTextures;
Vector<CSHandle> _vCshGenerateMips;
ComPtr<ID3D11ShaderResourceView> _pSRV;
Vector<ComPtr<ID3D11UnorderedAccessView>> _vUAVs;
Vector<ComPtr<ID3D11RenderTargetView>> _vRTVs;
ComPtr<ID3D11DepthStencilView> _pDSV[2];
ComPtr<ID3D11SamplerState> _pSamplerState;
ComPtr<ID3D11Texture2D> _pTexture2D;
ComPtr<ID3D11Texture3D> _pTexture3D;
ComPtr<ID3D11Texture2D> _pUaTexture;
Vector<ComPtr<ID3D11Texture2D>> _vReadbackTextures;
Vector<CSHandle> _vCshGenerateMips;
ComPtr<ID3D11ShaderResourceView> _pSRV;
Vector<ComPtr<ID3D11UnorderedAccessView>> _vUAVs;
Vector<ComPtr<ID3D11RenderTargetView>> _vRTVs;
ComPtr<ID3D11DepthStencilView> _pDSV[2];
ComPtr<ID3D11SamplerState> _pSamplerState;
public:
TextureD3D11();
virtual ~TextureD3D11() override;
public:
TextureD3D11();
virtual ~TextureD3D11() override;
virtual void Init(RcTextureDesc desc) override;
virtual void Done() 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 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 void GenerateMips(PBaseCommandBuffer pCB) override;
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(); }
ID3D11UnorderedAccessView* GetUAV(int index = 0) const { return _vUAVs[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(); }
ID3D11SamplerState* GetD3DSamplerState() const { return _pSamplerState.Get(); }
ID3D11ShaderResourceView* GetSRV() const { return _pSRV.Get(); }
ID3D11UnorderedAccessView* GetUAV(int index = 0) const { return _vUAVs[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(); }
ID3D11SamplerState* GetD3DSamplerState() const { return _pSamplerState.Get(); }
static DXGI_FORMAT RemoveSRGB(DXGI_FORMAT format);
};
VERUS_TYPEDEFS(TextureD3D11);
}
static DXGI_FORMAT RemoveSRGB(DXGI_FORMAT format);
};
VERUS_TYPEDEFS(TextureD3D11);
}

View File

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

View File

@ -1,71 +1,68 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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];
RP::PcD3DRenderPass _pRenderPass = nullptr;
RP::PcD3DFramebuffer _pFramebuffer = nullptr;
Vector<FLOAT> _vClearValues;
Vector<D3D12_RESOURCE_STATES> _vAttachmentStates;
Vector<D3D12_RESOURCE_BARRIER> _vBarriers;
int _subpassIndex = 0;
ComPtr<ID3D12CommandAllocator> _pOneTimeCommandAllocator;
ComPtr<ID3D12GraphicsCommandList3> _pCommandLists[BaseRenderer::s_ringBufferSize];
RP::PcD3DRenderPass _pRenderPass = nullptr;
RP::PcD3DFramebuffer _pFramebuffer = nullptr;
Vector<FLOAT> _vClearValues;
Vector<D3D12_RESOURCE_STATES> _vAttachmentStates;
Vector<D3D12_RESOURCE_BARRIER> _vBarriers;
int _subpassIndex = 0;
public:
CommandBufferD3D12();
virtual ~CommandBufferD3D12() override;
public:
CommandBufferD3D12();
virtual ~CommandBufferD3D12() override;
virtual void Init() override;
virtual void Done() override;
virtual void Init() override;
virtual void Done() override;
virtual void InitOneTimeSubmit() override;
virtual void DoneOneTimeSubmit() override;
virtual void InitOneTimeSubmit() override;
virtual void DoneOneTimeSubmit() override;
virtual void Begin() override;
virtual void End() override;
virtual void Begin() 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,
std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf) override;
virtual void NextSubpass() override;
virtual void EndRenderPass() override;
virtual void BeginRenderPass(RPHandle renderPassHandle, FBHandle framebufferHandle,
std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf) override;
virtual void NextSubpass() override;
virtual void EndRenderPass() override;
virtual void BindPipeline(PipelinePtr pipe) 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 SetBlendConstants(const float* p) override;
virtual void BindPipeline(PipelinePtr pipe) 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 SetBlendConstants(const float* p) override;
virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter) override;
virtual void BindIndexBuffer(GeometryPtr geo) override;
virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter) override;
virtual void BindIndexBuffer(GeometryPtr geo) override;
virtual bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle) 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 bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle) 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 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 Dispatch(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 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 Dispatch(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 ProfilerBeginEvent(UINT32 color, CSZ text) override;
virtual void ProfilerEndEvent() override;
virtual void ProfilerSetMarker(UINT32 color, CSZ text) override;
virtual void ProfilerBeginEvent(UINT32 color, CSZ text) override;
virtual void ProfilerEndEvent() override;
virtual void ProfilerSetMarker(UINT32 color, CSZ text) override;
//
// D3D12
//
//
// D3D12
//
ID3D12GraphicsCommandList3* GetD3DGraphicsCommandList() const;
ID3D12GraphicsCommandList3* GetD3DGraphicsCommandList() const;
void PrepareSubpass();
};
VERUS_TYPEDEFS(CommandBufferD3D12);
}
void PrepareSubpass();
};
VERUS_TYPEDEFS(CommandBufferD3D12);
}

View File

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

View File

@ -1,67 +1,64 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once
namespace verus
namespace verus::CGI
{
namespace CGI
class RendererD3D12;
class ExtRealityD3D12 : public BaseExtReality
{
class RendererD3D12;
class ExtRealityD3D12 : public BaseExtReality
struct SwapChainEx
{
struct SwapChainEx
{
XrSwapchain _handle = XR_NULL_HANDLE;
int32_t _width = 0;
int32_t _height = 0;
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;
XrSwapchain _handle = XR_NULL_HANDLE;
int32_t _width = 0;
int32_t _height = 0;
Vector<XrSwapchainImageD3D12KHR> _vImages;
DescriptorHeap _dhImageViews;
};
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.
#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;
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;
D3D12MA::Allocation* _pMaAllocation = nullptr;
ComPtr<ID3D12Resource> _pBuffer;
UINT64 _bufferSize = 0;
INT64 _utilization = -1;
};
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.
#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);
D3D12_PRIMITIVE_TOPOLOGY_TYPE ToNativePrimitiveTopologyType(PrimitiveTopology primitiveTopology);
D3D_PRIMITIVE_TOPOLOGY ToNativePrimitiveTopology(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 ToNativeSampledDepthFormat(Format format);
DXGI_FORMAT ToNativeFormat(Format format, bool typeless);
DXGI_FORMAT ToNativeSampledDepthFormat(Format format);
CSZ ToNativeSemanticName(ViaUsage usage);
DXGI_FORMAT ToNativeFormat(ViaUsage usage, ViaType type, int components);
}
CSZ ToNativeSemanticName(ViaUsage usage);
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.
#pragma once
namespace verus
namespace verus::CGI
{
namespace CGI
class PipelineD3D12 : public BasePipeline
{
class PipelineD3D12 : public BasePipeline
{
ComPtr<ID3D12PipelineState> _pPipelineState;
ID3D12RootSignature* _pRootSignature = nullptr;
D3D_PRIMITIVE_TOPOLOGY _topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
bool _compute = false;
ComPtr<ID3D12PipelineState> _pPipelineState;
ID3D12RootSignature* _pRootSignature = nullptr;
D3D_PRIMITIVE_TOPOLOGY _topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
bool _compute = false;
public:
PipelineD3D12();
virtual ~PipelineD3D12() override;
public:
PipelineD3D12();
virtual ~PipelineD3D12() override;
virtual void Init(RcPipelineDesc desc) override;
virtual void Done() override;
virtual void Init(RcPipelineDesc desc) override;
virtual void Done() override;
//
// D3D12
//
//
// D3D12
//
VERUS_P(void InitCompute(RcPipelineDesc desc));
VERUS_P(void InitMeshShading(RcPipelineDesc desc));
D3D12_SHADER_BYTECODE ToBytecode(ID3DBlob* pBlob);
bool IsCompute() const { return _compute; }
ID3D12PipelineState* GetD3DPipelineState() const { return _pPipelineState.Get(); }
ID3D12RootSignature* GetD3DRootSignature() const { return _pRootSignature; }
D3D_PRIMITIVE_TOPOLOGY GetD3DPrimitiveTopology() const { return _topology; }
void FillBlendStateRenderTargets(RcPipelineDesc desc, int attachmentCount, D3D12_BLEND_DESC& blendDesc);
};
VERUS_TYPEDEFS(PipelineD3D12);
}
VERUS_P(void InitCompute(RcPipelineDesc desc));
VERUS_P(void InitMeshShading(RcPipelineDesc desc));
D3D12_SHADER_BYTECODE ToBytecode(ID3DBlob* pBlob);
bool IsCompute() const { return _compute; }
ID3D12PipelineState* GetD3DPipelineState() const { return _pPipelineState.Get(); }
ID3D12RootSignature* GetD3DRootSignature() const { return _pRootSignature; }
D3D_PRIMITIVE_TOPOLOGY GetD3DPrimitiveTopology() const { return _topology; }
void FillBlendStateRenderTargets(RcPipelineDesc desc, int attachmentCount, D3D12_BLEND_DESC& blendDesc);
};
VERUS_TYPEDEFS(PipelineD3D12);
}

View File

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

View File

@ -1,129 +1,126 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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 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;
typedef Map<std::thread::id, ComPtr<ID3D12CommandAllocator>> TMapCommandAllocators;
D3D12MA::Allocator* _pMaAllocator = nullptr;
ExtRealityD3D12 _extReality;
ComPtr<ID3D12Device3> _pDevice;
ComPtr<ID3D12CommandQueue> _pCommandQueue;
ComPtr<IDXGISwapChain4> _pSwapChain;
Vector<ComPtr<ID3D12Resource>> _vSwapChainBuffers;
DescriptorHeap _dhSwapChainBuffersRTVs;
D3D12MA::Allocator* _pMaAllocator = nullptr;
ExtRealityD3D12 _extReality;
ComPtr<ID3D12Device3> _pDevice;
ComPtr<ID3D12CommandQueue> _pCommandQueue;
ComPtr<IDXGISwapChain4> _pSwapChain;
Vector<ComPtr<ID3D12Resource>> _vSwapChainBuffers;
DescriptorHeap _dhSwapChainBuffersRTVs;
DynamicDescriptorHeap _dhViews;
DynamicDescriptorHeap _dhSamplers;
TMapCommandAllocators _mapCommandAllocators[s_ringBufferSize];
ComPtr<ID3D12Fence> _pFence;
HANDLE _hFence = INVALID_HANDLE_VALUE;
HANDLE _hFrameLatencyWaitableObject = INVALID_HANDLE_VALUE;
UINT64 _nextFenceValue = 1;
UINT64 _fenceValues[s_ringBufferSize] = {};
DynamicDescriptorHeap _dhViews;
DynamicDescriptorHeap _dhSamplers;
TMapCommandAllocators _mapCommandAllocators[s_ringBufferSize];
ComPtr<ID3D12Fence> _pFence;
HANDLE _hFence = INVALID_HANDLE_VALUE;
HANDLE _hFrameLatencyWaitableObject = INVALID_HANDLE_VALUE;
UINT64 _nextFenceValue = 1;
UINT64 _fenceValues[s_ringBufferSize] = {};
Vector<D3D12_STATIC_SAMPLER_DESC> _vSamplers;
Vector<RP::D3DRenderPass> _vRenderPasses;
Vector<RP::D3DFramebuffer> _vFramebuffers;
D3D_FEATURE_LEVEL _featureLevel = D3D_FEATURE_LEVEL_11_0;
DXGI_SWAP_CHAIN_DESC1 _swapChainDesc = {};
Vector<D3D12_STATIC_SAMPLER_DESC> _vSamplers;
Vector<RP::D3DRenderPass> _vRenderPasses;
Vector<RP::D3DFramebuffer> _vFramebuffers;
D3D_FEATURE_LEVEL _featureLevel = D3D_FEATURE_LEVEL_11_0;
DXGI_SWAP_CHAIN_DESC1 _swapChainDesc = {};
public:
RendererD3D12();
~RendererD3D12();
public:
RendererD3D12();
~RendererD3D12();
virtual void ReleaseMe() override;
virtual void ReleaseMe() override;
void Init();
void Done();
void Init();
void Done();
private:
static void EnableDebugLayer();
static ComPtr<IDXGIFactory6> CreateFactory();
ComPtr<IDXGIAdapter4> GetAdapter(ComPtr<IDXGIFactory6> pFactory, D3D_FEATURE_LEVEL featureLevel) const;
static bool CheckFeatureSupportAllowTearing(ComPtr<IDXGIFactory6> pFactory);
void CreateSwapChainBuffersRTVs();
void InitD3D();
void WaitForFrameLatencyWaitableObject();
private:
static void EnableDebugLayer();
static ComPtr<IDXGIFactory6> CreateFactory();
ComPtr<IDXGIAdapter4> GetAdapter(ComPtr<IDXGIFactory6> pFactory, D3D_FEATURE_LEVEL featureLevel) const;
static bool CheckFeatureSupportAllowTearing(ComPtr<IDXGIFactory6> pFactory);
void CreateSwapChainBuffersRTVs();
void InitD3D();
void WaitForFrameLatencyWaitableObject();
public:
// <CreateAndGet>
ComPtr<ID3D12CommandQueue> CreateD3DCommandQueue(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<ID3D12Fence> CreateD3DFence();
UINT64 QueueSignal();
void WaitForFenceValue(UINT64 value);
void QueueWaitIdle();
void CreateSamplers();
public:
// <CreateAndGet>
ComPtr<ID3D12CommandQueue> CreateD3DCommandQueue(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<ID3D12Fence> CreateD3DFence();
UINT64 QueueSignal();
void WaitForFenceValue(UINT64 value);
void QueueWaitIdle();
void CreateSamplers();
ID3D12Device3* GetD3DDevice() const { return _pDevice.Get(); }
ID3D12CommandQueue* GetD3DCommandQueue() const { return _pCommandQueue.Get(); }
D3D12MA::Allocator* GetMaAllocator() const { return _pMaAllocator; }
ID3D12CommandAllocator* GetD3DCommandAllocator(int ringBufferIndex) const { return _mapCommandAllocators[ringBufferIndex].at(std::this_thread::get_id()).Get(); }
D3D12_STATIC_SAMPLER_DESC GetD3DStaticSamplerDesc(Sampler s) const;
// </CreateAndGet>
ID3D12Device3* GetD3DDevice() const { return _pDevice.Get(); }
ID3D12CommandQueue* GetD3DCommandQueue() const { return _pCommandQueue.Get(); }
D3D12MA::Allocator* GetMaAllocator() const { return _pMaAllocator; }
ID3D12CommandAllocator* GetD3DCommandAllocator(int ringBufferIndex) const { return _mapCommandAllocators[ringBufferIndex].at(std::this_thread::get_id()).Get(); }
D3D12_STATIC_SAMPLER_DESC GetD3DStaticSamplerDesc(Sampler s) const;
// </CreateAndGet>
virtual void ImGuiInit(RPHandle renderPassHandle) override;
virtual void ImGuiRenderDrawData() override;
virtual void ImGuiInit(RPHandle renderPassHandle) override;
virtual void ImGuiRenderDrawData() override;
virtual void ResizeSwapChain() override;
virtual void ResizeSwapChain() override;
virtual PBaseExtReality GetExtReality() override;
virtual PBaseExtReality GetExtReality() override;
// Which graphics API?
virtual Gapi GetGapi() override { return Gapi::direct3D12; }
// Which graphics API?
virtual Gapi GetGapi() override { return Gapi::direct3D12; }
// <FrameCycle>
virtual void BeginFrame() override;
virtual void AcquireSwapChainImage() override;
virtual void EndFrame() override;
virtual void WaitIdle() override;
virtual void OnMinimized() override;
// </FrameCycle>
// <FrameCycle>
virtual void BeginFrame() override;
virtual void AcquireSwapChainImage() override;
virtual void EndFrame() override;
virtual void WaitIdle() override;
virtual void OnMinimized() override;
// </FrameCycle>
// <Resources>
virtual PBaseCommandBuffer InsertCommandBuffer() override;
virtual PBaseGeometry InsertGeometry() override;
virtual PBasePipeline InsertPipeline() override;
virtual PBaseShader InsertShader() override;
virtual PBaseTexture InsertTexture() override;
// <Resources>
virtual PBaseCommandBuffer InsertCommandBuffer() override;
virtual PBaseGeometry InsertGeometry() override;
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 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;
RP::RcD3DRenderPass GetRenderPass(RPHandle handle) const;
RP::RcD3DFramebuffer GetFramebuffer(FBHandle handle) const;
// </Resources>
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;
RP::RcD3DRenderPass GetRenderPass(RPHandle handle) const;
RP::RcD3DFramebuffer GetFramebuffer(FBHandle handle) const;
// </Resources>
RDynamicDescriptorHeap GetViewHeap() { return _dhViews; }
RDynamicDescriptorHeap GetSamplerHeap() { return _dhSamplers; }
void SetDescriptorHeaps(PBaseCommandBuffer p);
RDynamicDescriptorHeap GetViewHeap() { return _dhViews; }
RDynamicDescriptorHeap GetSamplerHeap() { return _dhSamplers; }
void SetDescriptorHeaps(PBaseCommandBuffer p);
virtual void UpdateUtilization() override;
};
VERUS_TYPEDEFS(RendererD3D12);
}
virtual void UpdateUtilization() override;
};
VERUS_TYPEDEFS(RendererD3D12);
}
#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;
auto CheckErrorMsgs = [this](ComPtr<ID3DBlob>& pErrorMsgs)
{
if (pErrorMsgs)
{
OnError(static_cast<CSZ>(pErrorMsgs->GetBufferPointer()));
pErrorMsgs.Reset();
}
};
if (pErrorMsgs)
{
OnError(static_cast<CSZ>(pErrorMsgs->GetBufferPointer()));
pErrorMsgs.Reset();
}
};
while (*branches)
{
@ -197,12 +197,12 @@ void ShaderD3D12::Done()
_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_COM_RELEASE_CHECK(x.second._pBlobs[i].Get());
x.second._pBlobs[i].Reset();
VERUS_COM_RELEASE_CHECK(value._pBlobs[i].Get());
value._pBlobs[i].Reset();
}
}
@ -693,19 +693,19 @@ void ShaderD3D12::UpdateDebugInfo(
StringStream ss;
auto PrintShaderVisibility = [&ss](D3D12_SHADER_VISIBILITY shaderVisibility)
{
switch (shaderVisibility)
{
case D3D12_SHADER_VISIBILITY_ALL: ss << "All"; break;
case D3D12_SHADER_VISIBILITY_VERTEX: ss << "V"; break;
case D3D12_SHADER_VISIBILITY_HULL: ss << "H"; break;
case D3D12_SHADER_VISIBILITY_DOMAIN: ss << "D"; break;
case D3D12_SHADER_VISIBILITY_GEOMETRY: ss << "G"; 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;
}
};
switch (shaderVisibility)
{
case D3D12_SHADER_VISIBILITY_ALL: ss << "All"; break;
case D3D12_SHADER_VISIBILITY_VERTEX: ss << "V"; break;
case D3D12_SHADER_VISIBILITY_HULL: ss << "H"; break;
case D3D12_SHADER_VISIBILITY_DOMAIN: ss << "D"; break;
case D3D12_SHADER_VISIBILITY_GEOMETRY: ss << "G"; 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 index = 0;

View File

@ -1,117 +1,114 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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:
virtual HRESULT STDMETHODCALLTYPE Open(
D3D_INCLUDE_TYPE IncludeType,
LPCSTR pFileName,
LPCVOID pParentData,
LPCVOID* ppData,
UINT* pBytes) override;
virtual HRESULT STDMETHODCALLTYPE Close(LPCVOID pData) override;
SET_MOD_TO_VIEW_HEAP = 0x10000
};
VERUS_TYPEDEFS(ShaderInclude);
class ShaderD3D12 : public BaseShader
struct Compiled
{
public:
enum SET_MOD
{
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;
ComPtr<ID3DBlob> _pBlobs[+Stage::count];
String _entry;
int _stageCount = 0;
};
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.
#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;
};
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);
ComPtr<ID3D12Resource> _pResource;
D3D12MA::Allocation* _pMaAllocation = nullptr;
};
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>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{C9195A1C-9224-4B40-BBBC-AA90EF3BE3E0}</ProjectGuid>
<RootNamespace>RendererVulkan</RootNamespace>
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@ -45,12 +45,6 @@
<Import Project="..\Verus\Verus.props" />
</ImportGroup>
<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'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
@ -61,6 +55,7 @@
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<FloatingPointModel>Fast</FloatingPointModel>
<AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -80,6 +75,7 @@
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<FloatingPointModel>Fast</FloatingPointModel>
<AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>

View File

@ -1,58 +1,55 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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:
CommandBufferVulkan();
virtual ~CommandBufferVulkan() override;
public:
CommandBufferVulkan();
virtual ~CommandBufferVulkan() override;
virtual void Init() override;
virtual void Done() override;
virtual void Init() override;
virtual void Done() override;
virtual void InitOneTimeSubmit() override;
virtual void DoneOneTimeSubmit() override;
virtual void InitOneTimeSubmit() override;
virtual void DoneOneTimeSubmit() override;
virtual void Begin() override;
virtual void End() override;
virtual void Begin() 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,
std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf) override;
virtual void NextSubpass() override;
virtual void EndRenderPass() override;
virtual void BeginRenderPass(RPHandle renderPassHandle, FBHandle framebufferHandle,
std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf) override;
virtual void NextSubpass() override;
virtual void EndRenderPass() override;
virtual void BindPipeline(PipelinePtr pipe) 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 SetBlendConstants(const float* p) override;
virtual void BindPipeline(PipelinePtr pipe) 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 SetBlendConstants(const float* p) override;
virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter) override;
virtual void BindIndexBuffer(GeometryPtr geo) override;
virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter) override;
virtual void BindIndexBuffer(GeometryPtr geo) override;
virtual bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle) 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 bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle) 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 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 Dispatch(int groupCountX, int groupCountY, int groupCountZ) override;
virtual void TraceRays(int width, int height, int depth) 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 Dispatch(int groupCountX, int groupCountY, int groupCountZ) override;
virtual void TraceRays(int width, int height, int depth) override;
//
// Vulkan
//
//
// Vulkan
//
VkCommandBuffer GetVkCommandBuffer() const;
};
VERUS_TYPEDEFS(CommandBufferVulkan);
}
VkCommandBuffer GetVkCommandBuffer() const;
};
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;
Vector<VkDescriptorPoolSize> vDescriptorPoolSizes;
vDescriptorPoolSizes.reserve(_mapTypeCount.size());
for (const auto& kv : _mapTypeCount)
for (const auto& [key, value] : _mapTypeCount)
{
VkDescriptorPoolSize vkdps;
vkdps.type = kv.first;
vkdps.descriptorCount = kv.second;
vkdps.type = key;
vkdps.descriptorCount = value;
vDescriptorPoolSizes.push_back(vkdps);
switch (kv.first)
switch (key)
{
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
vkdpci.maxSets += kv.second;
vkdpci.maxSets += value;
}
}
vkdpci.poolSizeCount = Utils::Cast32(vDescriptorPoolSizes.size());

View File

@ -1,67 +1,64 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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;
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;
}
}
Vector<VkDescriptorSetLayoutBinding> _vSetLayoutBindings;
int _capacity = 0;
};
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.
#pragma once
namespace verus
namespace verus::CGI
{
namespace CGI
class RendererVulkan;
class ExtRealityVulkan : public BaseExtReality
{
class RendererVulkan;
class ExtRealityVulkan : public BaseExtReality
struct SwapChainEx
{
struct SwapChainEx
{
XrSwapchain _handle = XR_NULL_HANDLE;
int32_t _width = 0;
int32_t _height = 0;
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;
XrSwapchain _handle = XR_NULL_HANDLE;
int32_t _width = 0;
int32_t _height = 0;
Vector<XrSwapchainImageVulkan2KHR> _vImages;
Vector<VkImageView> _vImageViews;
};
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.
#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;
struct BufferEx
{
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;;
VmaAllocation _vmaAllocation = VK_NULL_HANDLE;
VkBuffer _buffer = VK_NULL_HANDLE;
VkDeviceSize _bufferSize = 0;
INT64 _utilization = -1;
};
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.
#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);
VkFormat ToNativeFormat(ViaUsage usage, ViaType type, int components);
}
int ToNativeLocation(ViaUsage usage, int usageIndex);
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.
#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:
PipelineVulkan();
virtual ~PipelineVulkan() override;
public:
PipelineVulkan();
virtual ~PipelineVulkan() override;
virtual void Init(RcPipelineDesc desc) override;
virtual void Done() override;
virtual void Init(RcPipelineDesc desc) override;
virtual void Done() override;
//
// Vulkan
//
//
// Vulkan
//
VERUS_P(void InitCompute(RcPipelineDesc desc));
bool IsCompute() const { return _compute; }
VkPipeline GetVkPipeline() const { return _pipeline; }
void FillColorBlendAttachmentStates(RcPipelineDesc desc, int attachmentCount, VkPipelineColorBlendAttachmentState vkpcbas[]);
};
VERUS_TYPEDEFS(PipelineVulkan);
}
VERUS_P(void InitCompute(RcPipelineDesc desc));
bool IsCompute() const { return _compute; }
VkPipeline GetVkPipeline() const { return _pipeline; }
void FillColorBlendAttachmentStates(RcPipelineDesc desc, int attachmentCount, VkPipelineColorBlendAttachmentState vkpcbas[]);
};
VERUS_TYPEDEFS(PipelineVulkan);
}

View File

@ -1,217 +1,214 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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,
sequentialWrite,
random
VkFramebuffer _framebuffer = VK_NULL_HANDLE;
int _width = 0;
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;
virtual void Close(void* pData) = 0;
VkSurfaceCapabilitiesKHR _surfaceCapabilities = {};
Vector<VkSurfaceFormatKHR> _vSurfaceFormats;
Vector<VkPresentModeKHR> _vSurfacePresentModes;
};
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
{
VkFramebuffer _framebuffer = VK_NULL_HANDLE;
int _width = 0;
int _height = 0;
};
VERUS_TYPEDEFS(Framebuffer);
static const uint32_t s_apiVersion = VK_API_VERSION_1_1;
private:
struct QueueFamilyIndices
{
int _graphicsFamilyIndex = -1;
int _presentFamilyIndex = -1;
static CSZ s_requiredValidationLayers[];
static CSZ s_requiredDeviceExtensions[];
bool IsComplete() const
{
return _graphicsFamilyIndex >= 0 && _presentFamilyIndex >= 0;
}
ExtRealityVulkan _extReality;
VkInstance _instance = VK_NULL_HANDLE;
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
{
return _graphicsFamilyIndex == _presentFamilyIndex;
}
};
public:
RendererVulkan();
~RendererVulkan();
struct SwapChainInfo
{
VkSurfaceCapabilitiesKHR _surfaceCapabilities = {};
Vector<VkSurfaceFormatKHR> _vSurfaceFormats;
Vector<VkPresentModeKHR> _vSurfacePresentModes;
};
virtual void ReleaseMe() override;
static const uint32_t s_apiVersion = VK_API_VERSION_1_1;
void Init();
void Done();
static CSZ s_requiredValidationLayers[];
static CSZ s_requiredDeviceExtensions[];
static void VulkanCompilerInit();
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;
VkInstance _instance = VK_NULL_HANDLE;
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;
private:
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:
RendererVulkan();
~RendererVulkan();
public:
// <CreateAndGet>
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();
void Done();
static void ImGuiCheckVkResultFn(VkResult res);
virtual void ImGuiInit(RPHandle renderPassHandle) override;
virtual void ImGuiRenderDrawData() override;
static void VulkanCompilerInit();
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);
virtual void ResizeSwapChain() override;
private:
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();
virtual PBaseExtReality GetExtReality() override;
public:
// <CreateAndGet>
VkCommandBuffer CreateVkCommandBuffer(VkCommandPool commandPool);
// Which graphics API?
virtual Gapi GetGapi() override { return Gapi::vulkan; }
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>
// <FrameCycle>
virtual void BeginFrame() override;
virtual void AcquireSwapChainImage() override;
virtual void EndFrame() override;
virtual void WaitIdle() override;
virtual void OnMinimized() override;
// </FrameCycle>
static void ImGuiCheckVkResultFn(VkResult res);
virtual void ImGuiInit(RPHandle renderPassHandle) override;
virtual void ImGuiRenderDrawData() override;
// <Resources>
virtual PBaseCommandBuffer InsertCommandBuffer() 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?
virtual Gapi GetGapi() override { return Gapi::vulkan; }
// <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>
// <FrameCycle>
virtual void BeginFrame() override;
virtual void AcquireSwapChainImage() override;
virtual void EndFrame() override;
virtual void WaitIdle() override;
virtual void OnMinimized() override;
// </FrameCycle>
virtual void UpdateUtilization() override;
// <Resources>
virtual PBaseCommandBuffer InsertCommandBuffer() override;
virtual PBaseGeometry InsertGeometry() override;
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);
}
bool IsAdvancedLineRasterizationSupported() const { return _advancedLineRasterization; }
};
VERUS_TYPEDEFS(RendererVulkan);
extern "C"
{

View File

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

View File

@ -1,86 +1,83 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once
namespace verus
namespace verus::CGI
{
namespace CGI
class ShaderVulkan : public BaseShader
{
class ShaderVulkan : public BaseShader
public:
struct Compiled
{
public:
struct Compiled
{
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;
VkShaderModule _shaderModules[+Stage::count] = {};
String _entry;
int _stageCount = 0;
};
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.
#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;
};
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);
VkBuffer _buffer = VK_NULL_HANDLE;
VmaAllocation _vmaAllocation = VK_NULL_HANDLE;
};
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>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}</ProjectGuid>
<RootNamespace>TextureTool</RootNamespace>
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
@ -45,18 +45,13 @@
<Import Project="..\Verus\Verus.props" />
</ImportGroup>
<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'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -71,6 +66,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>

View File

@ -1,25 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29613.14
# Visual Studio Version 17
VisualStudioVersion = 17.7.34003.232
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
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererDirect3D12", "RendererDirect3D12\RendererDirect3D12.vcxproj", "{53923514-84B2-4B78-889A-8709C6BFA3A5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererVulkan", "RendererVulkan\RendererVulkan.vcxproj", "{C9195A1C-9224-4B40-BBBC-AA90EF3BE3E0}"
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}"
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
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HelloTexturedCube", "HelloTexturedCube\HelloTexturedCube.vcxproj", "{26BD6E61-E36D-464A-A312-4110ADF10083}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RendererDirect3D11", "RendererDirect3D11\RendererDirect3D11.vcxproj", "{8269DCCE-E226-46E4-B9F6-290AB5DF2678}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VulkanShaderCompiler", "VulkanShaderCompiler\VulkanShaderCompiler.vcxproj", "{1EA5F5D1-9138-406D-871B-3CD75343E14C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -27,10 +27,22 @@ Global
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B154D670-E4B1-4D8A-885C-69546A5BD833}.Debug|x64.ActiveCfg = Debug|x64
{B154D670-E4B1-4D8A-885C-69546A5BD833}.Debug|x64.Build.0 = Debug|x64
{B154D670-E4B1-4D8A-885C-69546A5BD833}.Release|x64.ActiveCfg = Release|x64
{B154D670-E4B1-4D8A-885C-69546A5BD833}.Release|x64.Build.0 = Release|x64
{26BD6E61-E36D-464A-A312-4110ADF10083}.Debug|x64.ActiveCfg = Debug|x64
{26BD6E61-E36D-464A-A312-4110ADF10083}.Debug|x64.Build.0 = Debug|x64
{26BD6E61-E36D-464A-A312-4110ADF10083}.Release|x64.ActiveCfg = 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.Build.0 = Debug|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}.Release|x64.ActiveCfg = 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.Build.0 = Debug|x64
{5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}.Release|x64.ActiveCfg = Release|x64
{5A1A3E76-7F69-48B6-B1E3-F6BB281B7E73}.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
{26BD6E61-E36D-464A-A312-4110ADF10083}.Debug|x64.ActiveCfg = Debug|x64
{26BD6E61-E36D-464A-A312-4110ADF10083}.Debug|x64.Build.0 = Debug|x64
{26BD6E61-E36D-464A-A312-4110ADF10083}.Release|x64.ActiveCfg = Release|x64
{26BD6E61-E36D-464A-A312-4110ADF10083}.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
{B154D670-E4B1-4D8A-885C-69546A5BD833}.Debug|x64.ActiveCfg = Debug|x64
{B154D670-E4B1-4D8A-885C-69546A5BD833}.Debug|x64.Build.0 = Debug|x64
{B154D670-E4B1-4D8A-885C-69546A5BD833}.Release|x64.ActiveCfg = Release|x64
{B154D670-E4B1-4D8A-885C-69546A5BD833}.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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -3,8 +3,8 @@
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<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>
<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>
<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-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>
<ItemDefinitionGroup />
<ItemGroup />

View File

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

View File

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

View File

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

View File

@ -1,114 +1,111 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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) {}
virtual void Animation_OnTrigger(CSZ name, int state) {}
begin = (1 << 0),
end = (1 << 1)
};
VERUS_TYPEDEFS(AnimationDelegate);
// Objects of this type are stored in Collection.
struct MotionData
struct Layer
{
Motion _motion;
float _duration = 0;
bool _looping = true;
bool _fast = false; // For auto easing.
Animation* _pAnimation = nullptr;
CSZ _rootBone = nullptr;
};
VERUS_TYPEDEFS(MotionData);
VERUS_TYPEDEFS(Layer);
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;
private:
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:
Collection(bool useShortNames = true);
~Collection();
public:
Animation();
~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 DeleteAll();
PMotionData Find(CSZ name);
int GetMaxBones();
};
VERUS_TYPEDEFS(Collection);
void BindCollection(PCollection p);
void BindSkeleton(PSkeleton p);
PAnimationDelegate SetDelegate(PAnimationDelegate p) { return Utils::Swap(_pDelegate, p); }
// 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;
bool IsPlaying() const { return _playing; }
void Play();
void Stop();
void Pause();
enum class Edge : int
{
begin = (1 << 0),
end = (1 << 1)
};
Str GetCurrentMotionName() const { return _C(_currentMotion); }
struct Layer
{
Animation* _pAnimation = nullptr;
CSZ _rootBone = nullptr;
};
VERUS_TYPEDEFS(Layer);
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; }
private:
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;
virtual void Motion_OnTrigger(CSZ name, int state) override;
public:
Animation();
~Animation();
PMotion GetMotion();
float GetAlpha(CSZ name = nullptr) const;
float GetTime();
bool IsNearEdge(float t = 0.1f, Edge edge = Edge::begin | Edge::end);
void Update(int layerCount = 0, PLayer pLayers = nullptr);
void UpdateSkeleton(int layerCount = 0, PLayer pLayers = nullptr);
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);
}
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.
#pragma once
namespace verus
namespace verus::Anim
{
namespace Anim
template<typename T, bool angle = false>
class Elastic
{
template<typename T, bool angle = false>
class Elastic
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; }
float GetDelta() const { return angle ? Math::WrapAngle(_target - _actual) : _target - _actual; }
void Update()
{
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; }
float GetDelta() const { return angle ? Math::WrapAngle(_target - _actual) : _target - _actual; }
void Update()
const T d = _target - _actual;
if (angle)
{
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)
{
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);
}
_actual = Math::WrapAngle(_actual);
}
};
}
};
template<>
class Elastic<Vector3, false>
template<>
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;
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;
if (VMath::dot(d, d) < VERUS_FLOAT_THRESHOLD * VERUS_FLOAT_THRESHOLD)
{
const Vector3 d = _target - _actual;
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);
}
_actual = _target;
}
};
else
{
VERUS_QREF_TIMER;
const float ratio = 1 / exp(_speed * dt * _rate); // Exponential decay.
_actual = VMath::lerp(ratio, _target, _actual);
}
}
};
template<>
class Elastic<Point3, false>
template<>
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;
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;
if (VMath::dot(d, d) < VERUS_FLOAT_THRESHOLD * VERUS_FLOAT_THRESHOLD)
{
const Vector3 d = _target - _actual;
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);
}
_actual = _target;
}
};
}
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?
float leastError = threshold;
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)
continue;
_mapRot.clear();
for (const auto& kv2 : mapSaved)
for (const auto& [key2, value2] : mapSaved)
{
if (kv2.first != excludeFrame)
_mapRot[kv2.first] = kv2.second;
if (key2 != excludeFrame)
_mapRot[key2] = value2;
}
float accError = 0;
@ -523,16 +523,16 @@ void Motion::Bone::DeleteRedundantKeyframes(float boneAccLength)
// Which keyframe can be removed with the least error?
float leastError = threshold;
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)
continue;
_mapPos.clear();
for (const auto& kv2 : mapSaved)
for (const auto& [key2, value2] : mapSaved)
{
if (kv2.first != excludeFrame)
_mapPos[kv2.first] = kv2.second;
if (key2 != excludeFrame)
_mapPos[key2] = value2;
}
float accError = 0;
@ -584,16 +584,16 @@ void Motion::Bone::DeleteRedundantKeyframes(float boneAccLength)
// Which keyframe can be removed with the least error?
float leastError = threshold;
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)
continue;
_mapScale.clear();
for (const auto& kv2 : mapSaved)
for (const auto& [key2, value2] : mapSaved)
{
if (kv2.first != excludeFrame)
_mapScale[kv2.first] = kv2.second;
if (key2 != excludeFrame)
_mapScale[key2] = value2;
}
float accError = 0;
@ -927,10 +927,10 @@ void Motion::Done()
Motion::PBone Motion::GetBoneByIndex(int index)
{
int i = 0;
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
if (i == index)
return &kv.second;
return &value;
i++;
}
return nullptr;
@ -989,9 +989,9 @@ void Motion::Serialize(IO::RStream stream)
stream << _fps;
stream << GetBoneCount();
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
RBone bone = kv.second;
RBone bone = value;
stream.WriteString(_C(bone.GetName()));
bone.Serialize(stream, version);
}
@ -1078,27 +1078,27 @@ void Motion::DeleteRedundantKeyframes(Map<String, float>& mapBoneAccLengths)
void Motion::DeleteOddKeyframes()
{
for (auto& kv : _mapBones)
kv.second.DeleteOddKeyframes();
for (auto& [key, value] : _mapBones)
value.DeleteOddKeyframes();
}
void Motion::InsertLoopKeyframes()
{
for (auto& kv : _mapBones)
kv.second.InsertLoopKeyframes();
for (auto& [key, value] : _mapBones)
value.InsertLoopKeyframes();
}
void Motion::Cut(int frame, bool before)
{
for (auto& kv : _mapBones)
kv.second.Cut(frame, before);
for (auto& [key, value] : _mapBones)
value.Cut(frame, before);
_frameCount = before ? _frameCount - frame : frame + 1;
}
void Motion::Fix(bool speedLimit)
{
for (auto& kv : _mapBones)
kv.second.Fix(speedLimit);
for (auto& [key, value] : _mapBones)
value.Fix(speedLimit);
}
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;
int i = 0;
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
PBone pBone = &kv.second;
PBone pBone = &value;
int state = 0;
if (!(_reversed && nativeTime < _fpsInv * 0.5f)) // Avoid edge case for the first frame in reverse.
pBone->ComputeTriggerAt(nativeTime, state);
@ -1132,9 +1132,9 @@ void Motion::ProcessTriggers(float time, PMotionDelegate p, int* pUserTriggerSta
void Motion::ResetTriggers(int* pUserTriggerStates)
{
int i = 0;
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
PBone pBone = &kv.second;
PBone pBone = &value;
int state = 0;
if (_reversed)
pBone->ComputeTriggerAt(GetNativeDuration(), state);
@ -1153,9 +1153,9 @@ void Motion::SkipTriggers(float time, int* pUserTriggerStates)
nativeTime = GetNativeDuration() - nativeTime;
int i = 0;
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
PBone pBone = &kv.second;
PBone pBone = &value;
int state;
pBone->ComputeTriggerAt(nativeTime, state);
if (pUserTriggerStates)
@ -1242,14 +1242,14 @@ void Motion::Exec(CSZ code, PBone pBone, Bone::Channel channel)
}
else
{
for (auto& bone : _mapBones)
for (auto& [key, value] : _mapBones)
{
if (!strcmp(what, "rot"))
bone.second._mapRot.clear();
value._mapRot.clear();
if (!strcmp(what, "pos"))
bone.second._mapPos.clear();
value._mapPos.clear();
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.
#pragma once
namespace verus
namespace verus::Anim
{
namespace Anim
struct MotionDelegate
{
struct MotionDelegate
{
virtual void Motion_OnTrigger(CSZ name, int state) = 0;
};
VERUS_TYPEDEFS(MotionDelegate);
virtual void Motion_OnTrigger(CSZ name, int state) = 0;
};
VERUS_TYPEDEFS(MotionDelegate);
// Motion holds a series of keyframes and provides the ability to interpolate between them.
// Motion can be stored in XAN format.
// Motion's rate can be scaled and even reversed.
// Animation object can be used to handle multiple motion objects.
class Motion : public Object
// Motion holds a series of keyframes and provides the ability to interpolate between them.
// Motion can be stored in XAN format.
// Motion's rate can be scaled and even reversed.
// Animation object can be used to handle multiple motion objects.
class Motion : public Object
{
public:
class Bone : public AllocatorAware
{
public:
class Bone : public AllocatorAware
enum class Channel : int
{
public:
enum class Channel : int
{
rotation,
position,
scale,
trigger
};
enum class Flags : UINT32
{
none = 0,
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;
rotation,
position,
scale,
trigger
};
enum class Flags : UINT32
{
none = 0,
slerpRot = (1 << 0),
splinePos = (1 << 1),
splineScale = (1 << 2)
};
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;
friend class Motion;
typedef Map<String, Bone> TMapBones;
static const float s_magicValueForCircle;
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)
class Rotation
{
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))
break;
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;
}
void Serialize(IO::RStream stream);
void Deserialize(IO::RStream stream);
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;
void BakeMotionAt(float time, Motion& dest) const;
void BindBlendMotion(Motion* p, float alpha);
Motion* GetBlendMotion() const { return _pBlendMotion; }
float GetBlendAlpha() const { return _blendAlpha; }
const int totalFrames = toFrame - fromFrame;
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 InsertLoopKeyframes();
void Cut(int frame, bool before = true);
void Cut(int frame, bool before);
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(RcVector3 scale, RcVector3 bias);
void ApplyScaleBias(CSZ name, RcVector3 scale, RcVector3 bias);
void Scatter(int srcFrom, int srcTo, int dMin, int dMax);
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);
bool SpaceTimeSync(Channel channel, int fromFrame, int toFrame);
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.
#pragma once
namespace verus
namespace verus::Anim
{
namespace Anim
class Orbit
{
class Orbit
{
Matrix3 _matrix;
Elastic<float, true> _pitch;
Elastic<float, true> _yaw;
float _basePitch = 0;
float _baseYaw = 0;
float _speed = 1;
float _offsetStrength = 0;
float _maxPitch = 0.45f;
bool _locked = false;
Matrix3 _matrix;
Elastic<float, true> _pitch;
Elastic<float, true> _yaw;
float _basePitch = 0;
float _baseYaw = 0;
float _speed = 1;
float _offsetStrength = 0;
float _maxPitch = 0.45f;
bool _locked = false;
public:
Orbit();
~Orbit();
public:
Orbit();
~Orbit();
void Update(bool smoothRestore = true);
void Update(bool smoothRestore = true);
void Lock();
void Unlock();
bool IsLocked() const { return _locked; }
void Lock();
void Unlock();
bool IsLocked() const { return _locked; }
void AddPitch(float a);
void AddYaw(float a);
void AddPitchFree(float a);
void AddYawFree(float a);
void AddPitch(float a);
void AddYaw(float a);
void AddPitchFree(float a);
void AddYawFree(float a);
float GetPitch() const { return _pitch; }
float GetYaw() const { return _yaw; }
float GetPitch() const { return _pitch; }
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 SetMaxPitch(float a) { _maxPitch = a; }
};
VERUS_TYPEDEFS(Orbit);
}
void SetSpeed(float x) { _speed = x; }
void SetMaxPitch(float a) { _maxPitch = a; }
};
VERUS_TYPEDEFS(Orbit);
}

View File

@ -1,49 +1,46 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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.
// Works well for camera's shaking effects.
class Shaker
{
String _url;
Vector<float> _vData;
float _speed = 0;
float _offset = 0;
float _value = 0;
float _scale = 1;
float _bias = 0;
bool _looping = false;
String _url;
Vector<float> _vData;
float _speed = 0;
float _offset = 0;
float _value = 0;
float _scale = 1;
float _bias = 0;
bool _looping = false;
public:
Shaker(float speed = 400, bool looping = true) : _speed(speed), _looping(looping) {}
public:
Shaker(float speed = 400, bool looping = true) : _speed(speed), _looping(looping) {}
bool IsLoaded() const { return !_vData.empty(); }
void Load(CSZ url);
Str GetURL() const { return _C(_url); }
bool IsLoaded() const { return !_vData.empty(); }
void Load(CSZ url);
Str GetURL() const { return _C(_url); }
void Update();
void Update();
void Reset() { _offset = 0; }
void Randomize();
// Returns the current value in the range [-1 to 1].
float Get();
void Reset() { _offset = 0; }
void Randomize();
// Returns the current value in the range [-1 to 1].
float Get();
float GetSpeed() const { return _speed; }
void SetSpeed(float speed) { _speed = speed; }
float GetSpeed() const { return _speed; }
void SetSpeed(float speed) { _speed = speed; }
float GetScale() const { return _scale; }
void SetScale(float scale) { _scale = scale; }
float GetScale() const { return _scale; }
void SetScale(float scale) { _scale = scale; }
float GetBias() const { return _bias; }
void SetBias(float bias) { _bias = bias; }
float GetBias() const { return _bias; }
void SetBias(float bias) { _bias = bias; }
bool IsLooping() const { return _looping; }
void SetLooping(float looping) { _looping = looping; }
};
VERUS_TYPEDEFS(Shaker);
}
bool IsLooping() const { return _looping; }
void SetLooping(float looping) { _looping = looping; }
};
VERUS_TYPEDEFS(Shaker);
}

View File

@ -16,8 +16,8 @@ Skeleton::~Skeleton()
void Skeleton::operator=(RcSkeleton that)
{
Init();
for (const auto& kv : that._mapBones)
_mapBones[kv.first] = kv.second;
for (const auto& [key, value] : that._mapBones)
_mapBones[key] = value;
_primaryBoneCount = that._primaryBoneCount;
}
@ -36,9 +36,9 @@ void Skeleton::Draw(bool bindPose, PcTransform3 pMat, int selected)
{
VERUS_QREF_DD;
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));
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 float scale = 0.04f;
@ -122,10 +122,10 @@ Skeleton::PcBone Skeleton::FindBone(CSZ name) const
Skeleton::PBone Skeleton::FindBoneByIndex(int index)
{
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
if (kv.second._shaderIndex == index)
return &kv.second;
if (value._shaderIndex == index)
return &value;
}
return nullptr;
}
@ -134,9 +134,9 @@ void Skeleton::ApplyMotion(RMotion motion, float time, int layeredMotionCount, P
{
if (_ragdollMode)
{
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
RBone bone = kv.second;
RBone bone = value;
if (bone._pRigidBody)
{
btTransform btr;
@ -176,9 +176,9 @@ void Skeleton::ApplyMotion(RMotion motion, float time, int layeredMotionCount, P
_pLayeredMotions = pLayeredMotions;
ResetBones();
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
RBone bone = kv.second;
RBone bone = value;
if (!bone._ready)
{
_pCurrentBone = &bone;
@ -198,9 +198,9 @@ void Skeleton::ApplyMotion(RMotion motion, float time, int layeredMotionCount, P
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)
p[bone._shaderIndex] = bone._matFinal.UniformBufferFormat();
}
@ -208,17 +208,17 @@ void Skeleton::UpdateUniformBufferArray(mataff* p) const
void Skeleton::ResetFinalPose()
{
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
kv.second._matFinal = Transform3::identity();
kv.second._matFinalInv = Transform3::identity();
value._matFinal = Transform3::identity();
value._matFinalInv = Transform3::identity();
}
}
void Skeleton::ResetBones()
{
for (auto& kv : _mapBones)
kv.second._ready = false;
for (auto& [key, value] : _mapBones)
value._ready = false;
}
void Skeleton::RecursiveBoneUpdate()
@ -300,8 +300,8 @@ void Skeleton::RecursiveBoneUpdate()
void Skeleton::InsertBonesIntoMotion(RMotion motion) const
{
for (const auto& kv : _mapBones)
motion.InsertBone(_C(kv.first));
for (const auto& [key, value] : _mapBones)
motion.InsertBone(_C(key));
}
void Skeleton::DeleteOutsiders(RMotion motion) const
@ -332,9 +332,9 @@ void Skeleton::AdjustPrimaryBones(const Vector<String>& vPrimaryBones)
if (inverse)
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))
mapSort[bone._shaderIndex + addPri] = bone._name;
else
@ -343,11 +343,11 @@ void Skeleton::AdjustPrimaryBones(const Vector<String>& vPrimaryBones)
_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());
_mapPrimary[pBone->_shaderIndex] = newIndex;
pBone->_shaderIndex = newIndex;
@ -355,7 +355,7 @@ void Skeleton::AdjustPrimaryBones(const Vector<String>& vPrimaryBones)
}
else // Secondary bone:
{
PBone pBone = FindBone(_C(kv.second));
PBone pBone = FindBone(_C(value));
PcBone pParent = FindBone(_C(pBone->_parentName));
bool isPrimary = false;
while (!isPrimary)
@ -400,9 +400,9 @@ void Skeleton::LoadRigInfo(CSZ url)
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._cRot = Vector3(0);
bone._cLimits = Vector3(0);
@ -419,9 +419,9 @@ void Skeleton::LoadRigInfoFromPtr(SZ p)
float massCheck = 0;
if (p)
{
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
RBone bone = kv.second;
RBone bone = value;
bone._rigBone = false;
}
@ -498,12 +498,12 @@ void Skeleton::BeginRagdoll(RcTransform3 matW, RcVector3 impulse, CSZ bone)
const float sleepL = 1.6f;
const float sleepA = 2.5f;
for (auto& kv : _mapBones)
kv.second._ready = true;
for (auto& [key, value] : _mapBones)
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));
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));
// Create leaf actors and joints:
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
PBone pBone = &kv.second;
PBone pBone = &value;
PBone pParent = pBone;
do
{
@ -667,9 +667,9 @@ void Skeleton::EndRagdoll()
{
VERUS_QREF_BULLET;
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
RBone bone = kv.second;
RBone bone = value;
if (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)
{
bullet.GetWorld()->removeRigidBody(bone._pRigidBody);
@ -700,9 +700,9 @@ void Skeleton::EndRagdoll()
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)))
continue;
PcBone pParent = FindBone(_C(bone._parentName));
@ -792,9 +792,9 @@ void Skeleton::AdaptBindPoseOf(RcSkeleton that)
// TODO: improve.
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));
PcBone pBoneSrc = that.FindBone(_C(boneDst._name));
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)
{
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
kv.second._matFinal = Transform3::identity();
kv.second._matExternal = Transform3::identity();
value._matFinal = Transform3::identity();
value._matExternal = Transform3::identity();
}
UINT64 timestamp;
@ -925,9 +925,9 @@ void Skeleton::ProcessKinectData(const BYTE* p, RMotion motion, int frame)
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)))
continue;
#if 0
@ -970,9 +970,9 @@ void Skeleton::ProcessKinectData(const BYTE* p, RMotion motion, int frame)
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)))
continue;
PBone pParent = FindBone(_C(bone._parentName));
@ -985,10 +985,10 @@ void Skeleton::ProcessKinectData(const BYTE* p, RMotion motion, int frame)
BakeMotion(motion, frame, true);
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
kv.second._matFinal = Transform3::identity();
kv.second._matExternal = Transform3::identity();
value._matFinal = Transform3::identity();
value._matExternal = Transform3::identity();
}
}
@ -1033,9 +1033,9 @@ void Skeleton::LoadKinectBindPose(CSZ xml)
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)))
continue;
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)
{
for (auto& kv : _mapBones)
for (auto& [key, value] : _mapBones)
{
RcBone bone = kv.second;
RcBone bone = value;
PcBone pParentBone = FindBone(_C(bone._parentName));
float len = 0;
if (pParentBone)
@ -1261,7 +1261,7 @@ void Skeleton::ComputeBoneLengths(Map<String, float>& m, bool accumulated)
}
if (accumulated) // Add leaf bone lengths?
{
for (auto& kv : m)
kv.second += 0.02f;
for (auto& [key, value] : m)
value += 0.02f;
}
}

View File

@ -1,163 +1,160 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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.
// 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
public:
struct LayeredMotion
{
public:
struct LayeredMotion
{
PMotion _pMotion = nullptr;
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);
PMotion _pMotion = nullptr;
CSZ _rootBone = nullptr;
float _alpha = 0;
float _time = 0;
};
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.
#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.
// 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
public:
typedef Map<String, Vector3> TMapOffsets;
class Zone
{
public:
typedef Map<String, Vector3> TMapOffsets;
class Zone
{
public:
Point3 _pos = Point3(0);
Point3 _posW = Point3(0);
Vector3 _vel = Vector3(0);
Vector3 _off = Vector3(0);
String _name;
String _bone;
TMapOffsets _mapOffsets;
float _radius = 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; }
Point3 _pos = Point3(0);
Point3 _posW = Point3(0);
Vector3 _vel = Vector3(0);
Vector3 _off = Vector3(0);
String _name;
String _bone;
TMapOffsets _mapOffsets;
float _radius = 0;
float _spring = 0;
float _damping = 5;
float _maxOffset = 0;
char _type = 0;
};
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();
}
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.
#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,
windowed,
borderlessWindowed
custom,
low,
medium,
high,
ultra
};
class Info
enum class Quality : int
{
public:
CSZ _appName = nullptr;
UINT32 _appVersion = 0;
CSZ _engineName = nullptr;
UINT32 _engineVersion = 0;
low,
medium,
high,
ultra
};
VERUS_TYPEDEFS(Info);
class QualitySettings
enum class WaterQuality : int
{
public:
enum class OverallQuality : int
{
custom,
low,
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;
solidColor,
simpleReflection,
distortedReflection,
trueWavesReflection,
trueWavesRefraction
};
VERUS_TYPEDEFS(QualitySettings);
// Capacity is per frame. 3 frames are buffered.
class Limits
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.
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 _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;
int _gapi = -1;
int _openXR = -1;
float _xrHeight = -FLT_MAX;
bool _exclusiveFullscreen = false;
bool _windowed = false;
bool _borderlessWindowed = false;
bool _restarted = false;
};
VERUS_TYPEDEFS(Limits);
class Settings : public QualitySettings, public Singleton<Settings>, IO::Json
enum Platform : int
{
typedef Map<String, String> TMapLocalizedStrings;
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;
classic,
uwp
};
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.
#pragma once
namespace verus
namespace verus::App
{
namespace App
class UndoManager : public Object
{
class UndoManager : public Object
public:
class Command
{
public:
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;
bool _hasRedo = false;
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; }
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(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.
#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:
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; }
void ApplySettings();
};
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();
// Update every frame:
for (auto& x : TStoreSounds::_map)
x.second.Update();
for (auto& [key, value] : TStoreSounds::_map)
value.Update();
// Update ~15 times per second:
if (timer.IsEventEvery(67))
{
for (auto& x : TStoreSounds::_map)
x.second.UpdateHRTF();
for (auto& [key, value] : TStoreSounds::_map)
value.UpdateHRTF();
if (VMath::lengthSqr(_listenerDirection) > 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.
#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;
class AudioSystem : public Singleton<AudioSystem>, public Object, private TStoreSounds
{
Point3 _listenerPosition = Point3(0);
Vector3 _listenerDirection = Vector3(0, 0, 1);
Vector3 _listenerVelocity = Vector3(0);
Vector3 _listenerUp = Vector3(0, 1, 0);
ALCdevice* _pDevice = nullptr;
ALCcontext* _pContext = nullptr;
String _version;
String _deviceSpecifier;
StreamPlayer _streamPlayers[4];
Point3 _listenerPosition = Point3(0);
Vector3 _listenerDirection = Vector3(0, 0, 1);
Vector3 _listenerVelocity = Vector3(0);
Vector3 _listenerUp = Vector3(0, 1, 0);
ALCdevice* _pDevice = nullptr;
ALCcontext* _pContext = nullptr;
String _version;
String _deviceSpecifier;
StreamPlayer _streamPlayers[4];
public:
AudioSystem();
~AudioSystem();
public:
AudioSystem();
~AudioSystem();
void Init();
void Done();
void Init();
void Done();
void Update();
void Update();
RStreamPlayer GetStreamPlayer(int index) { return _streamPlayers[index]; }
void DeleteAllStreams();
RStreamPlayer GetStreamPlayer(int index) { return _streamPlayers[index]; }
void DeleteAllStreams();
PSound InsertSound(CSZ url);
PSound FindSound(CSZ url);
void DeleteSound(CSZ url);
void DeleteAllSounds();
PSound InsertSound(CSZ url);
PSound FindSound(CSZ url);
void DeleteSound(CSZ url);
void DeleteAllSounds();
void UpdateListener(RcPoint3 pos, RcVector3 dir, RcVector3 vel, RcVector3 up);
float ComputeTravelDelay(RcPoint3 pos) const;
void UpdateListener(RcPoint3 pos, RcVector3 dir, RcVector3 vel, RcVector3 up);
float ComputeTravelDelay(RcPoint3 pos) const;
static CSZ GetSingletonFailMessage() { return "Make_Audio(); // FAIL.\r\n"; }
};
VERUS_TYPEDEFS(AudioSystem);
}
static CSZ GetSingletonFailMessage() { return "Make_Audio(); // FAIL.\r\n"; }
};
VERUS_TYPEDEFS(AudioSystem);
}

View File

@ -1,47 +1,44 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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;
const INT64 maxLen = pDS->_size - pDS->_cursor;
if (readLen > maxLen)
readLen = maxLen;
memcpy(ptr, pDS->_p + pDS->_cursor, 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 };
POggDataSource pDS = static_cast<POggDataSource>(datasource);
INT64 readLen = size * nmemb;
const INT64 maxLen = pDS->_size - pDS->_cursor;
if (readLen > maxLen)
readLen = maxLen;
memcpy(ptr, pDS->_p + pDS->_cursor, 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 };
}

View File

@ -1,23 +1,20 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once
namespace verus
namespace verus::Audio
{
namespace Audio
struct OggDataSource
{
struct OggDataSource
{
const BYTE* _p = nullptr;
INT64 _size = 0;
INT64 _cursor = 0;
};
VERUS_TYPEDEFS(OggDataSource);
const BYTE* _p = nullptr;
INT64 _size = 0;
INT64 _cursor = 0;
};
VERUS_TYPEDEFS(OggDataSource);
size_t read_func(void*, size_t, size_t, void*);
int seek_func(void*, ogg_int64_t, int);
int close_func(void*);
long tell_func(void*);
size_t read_func(void*, size_t, size_t, void*);
int seek_func(void*, ogg_int64_t, int);
int close_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.
#pragma once
namespace verus
namespace verus::Audio
{
namespace Audio
struct SoundFlags
{
struct SoundFlags
enum
{
enum
{
loaded = (ObjectFlags::user << 0),
is3D = (ObjectFlags::user << 1),
looping = (ObjectFlags::user << 2),
randOff = (ObjectFlags::user << 3),
keepPcmBuffer = (ObjectFlags::user << 4),
user = (ObjectFlags::user << 5)
};
loaded = (ObjectFlags::user << 0),
is3D = (ObjectFlags::user << 1),
looping = (ObjectFlags::user << 2),
randOff = (ObjectFlags::user << 3),
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];
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;
CSZ _url = nullptr;
Interval _gain = 0.8f;
Interval _pitch = 1;
float _referenceDistance = 4;
bool _is3D = false;
bool _looping = false;
bool _randomOffset = false;
bool _keepPcmBuffer = false;
public:
// Note that this structure contains some default values for new sources, which can be changed per source.
struct Desc
{
CSZ _url = nullptr;
Interval _gain = 0.8f;
Interval _pitch = 1;
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;
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(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:
~SoundPwn() { Done(); }
void Done();
};
VERUS_TYPEDEFS(SoundPwn);
Done();
}
template<int COUNT>
class SoundPwns
void Init(Sound::RcDesc desc)
{
SoundPwn _sounds[COUNT];
int _prev = 0;
public:
SoundPwns()
char buffer[200];
VERUS_FOR(i, COUNT)
{
sprintf_s(buffer, desc._url, i);
Sound::Desc descs = desc;
descs._url = buffer;
_sounds[i].Init(descs);
}
}
~SoundPwns()
{
Done();
}
void Done()
{
VERUS_FOR(i, COUNT)
_sounds[i].Done();
}
void Init(Sound::RcDesc desc)
{
char buffer[200];
VERUS_FOR(i, COUNT)
{
sprintf_s(buffer, desc._url, i);
Sound::Desc descs = desc;
descs._url = buffer;
_sounds[i].Init(descs);
}
}
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];
}
};
}
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.
#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().
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
{
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);
float _secOffset = 0;
float _gain = 1;
float _pitch = 1;
bool _stopSource = true;
};
VERUS_TYPEDEFS(Source);
VERUS_TYPEDEFS(Desc);
class SourcePtr : public Ptr<Source>
{
public:
void Attach(Source* pSource, Sound* pSound);
void Done();
};
VERUS_TYPEDEFS(SourcePtr);
}
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);
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.
#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;
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; }
stopThread = (ObjectFlags::user << 0),
play = (ObjectFlags::user << 1),
noLock = (ObjectFlags::user << 2)
};
VERUS_TYPEDEFS(Track);
};
struct StreamPlayerFlags
{
enum
{
stopThread = (ObjectFlags::user << 0),
play = (ObjectFlags::user << 1),
noLock = (ObjectFlags::user << 2)
};
};
class StreamPlayer : public Object, public Lockable
{
Track _nativeTrack;
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;
class StreamPlayer : public Object, public Lockable
{
Track _nativeTrack;
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:
StreamPlayer();
~StreamPlayer();
public:
StreamPlayer();
~StreamPlayer();
void Init();
void Done();
void Init();
void Done();
void Update();
void Update();
void AddTrack(PTrack pTrack);
void DeleteTrack(PTrack pTrack);
void SwitchToTrack(PTrack pTrack);
void AddTrack(PTrack pTrack);
void DeleteTrack(PTrack pTrack);
void SwitchToTrack(PTrack pTrack);
void Play();
void Stop();
void Seek(int pos);
void Play();
void Stop();
void Seek(int pos);
VERUS_P(void ThreadProc());
VERUS_P(void StopThread());
VERUS_P(void FillBuffer(ALuint buffer));
VERUS_P(void ThreadProc());
VERUS_P(void StopThread());
VERUS_P(void FillBuffer(ALuint buffer));
void FadeIn(float time);
void FadeOut(float time);
void Mute();
void SetGain(float gain);
};
VERUS_TYPEDEFS(StreamPlayer);
}
void FadeIn(float time);
void FadeOut(float time);
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.
#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.
enum class ViewportScissorFlags : UINT32
{
none = 0,
setViewportForFramebuffer = (1 << 0),
setViewportForCurrentView = (1 << 1),
setScissorForFramebuffer = (1 << 2),
setScissorForCurrentView = (1 << 3),
applyOffscreenScale = (1 << 4),
applyHalfScale = (1 << 5),
setAllForFramebuffer = setViewportForFramebuffer | setScissorForFramebuffer,
setAllForCurrentView = setViewportForCurrentView | setScissorForCurrentView,
setAllForCurrentViewScaled = setAllForCurrentView | applyOffscreenScale
};
none = 0,
setViewportForFramebuffer = (1 << 0),
setViewportForCurrentView = (1 << 1),
setScissorForFramebuffer = (1 << 2),
setScissorForCurrentView = (1 << 3),
applyOffscreenScale = (1 << 4),
applyHalfScale = (1 << 5),
setAllForFramebuffer = setViewportForFramebuffer | setScissorForFramebuffer,
setAllForCurrentView = setViewportForCurrentView | setScissorForCurrentView,
setAllForCurrentViewScaled = setAllForCurrentView | applyOffscreenScale
};
class BaseCommandBuffer : public Object, public Scheduled
{
protected:
Vector4 _viewportSize = Vector4(0);
Vector4 _viewScaleBias = Vector4(0);
class BaseCommandBuffer : public Object, public Scheduled
{
protected:
Vector4 _viewportSize = Vector4(0);
Vector4 _viewScaleBias = Vector4(0);
void SetViewportAndScissor(ViewportScissorFlags vsf, int width, int height);
void SetViewportAndScissor(ViewportScissorFlags vsf, int width, int height);
BaseCommandBuffer() = default;
virtual ~BaseCommandBuffer() = default;
BaseCommandBuffer() = default;
virtual ~BaseCommandBuffer() = default;
public:
virtual void Init() = 0;
virtual void Done() = 0;
public:
virtual void Init() = 0;
virtual void Done() = 0;
virtual void InitOneTimeSubmit() = 0;
virtual void DoneOneTimeSubmit() = 0;
virtual void InitOneTimeSubmit() = 0;
virtual void DoneOneTimeSubmit() = 0;
virtual void Begin() = 0;
virtual void End() = 0;
virtual void Begin() = 0;
virtual void End() = 0;
virtual void PipelineImageMemoryBarrier(TexturePtr tex, ImageLayout oldLayout, ImageLayout newLayout,
Range mipLevels, Range arrayLayers = 0) = 0;
virtual void PipelineImageMemoryBarrier(TexturePtr tex, ImageLayout oldLayout, ImageLayout newLayout,
Range mipLevels, Range arrayLayers = 0) = 0;
// <RenderPass>
virtual void BeginRenderPass(RPHandle renderPassHandle, FBHandle framebufferHandle,
std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf = ViewportScissorFlags::setAllForCurrentViewScaled) = 0;
virtual void NextSubpass() = 0;
virtual void EndRenderPass() = 0;
// </RenderPass>
// <RenderPass>
virtual void BeginRenderPass(RPHandle renderPassHandle, FBHandle framebufferHandle,
std::initializer_list<Vector4> ilClearValues, ViewportScissorFlags vsf = ViewportScissorFlags::setAllForCurrentViewScaled) = 0;
virtual void NextSubpass() = 0;
virtual void EndRenderPass() = 0;
// </RenderPass>
// <Pipeline>
virtual void BindPipeline(PipelinePtr pipe) = 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 SetBlendConstants(const float* p) = 0;
// </Pipeline>
// <Pipeline>
virtual void BindPipeline(PipelinePtr pipe) = 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 SetBlendConstants(const float* p) = 0;
// </Pipeline>
// <VertexInput>
virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter = UINT32_MAX) = 0;
virtual void BindIndexBuffer(GeometryPtr geo) = 0;
// </VertexInput>
// <VertexInput>
virtual void BindVertexBuffers(GeometryPtr geo, UINT32 bindingsFilter = UINT32_MAX) = 0;
virtual void BindIndexBuffer(GeometryPtr geo) = 0;
// </VertexInput>
// <Descriptors>
virtual bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle = CSHandle()) = 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;
// </Descriptors>
// <Descriptors>
virtual bool BindDescriptors(ShaderPtr shader, int setNumber, CSHandle complexSetHandle = CSHandle()) = 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;
// </Descriptors>
// <Draw>
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 Dispatch(int groupCountX, int groupCountY, int groupCountZ = 1) = 0;
virtual void DispatchIndirect() {} // WIP.
virtual void DispatchMesh(int groupCountX, int groupCountY, int groupCountZ) {} // WIP.
virtual void TraceRays(int width, int height, int depth) {} // WIP.
// </Draw>
// <Draw>
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 Dispatch(int groupCountX, int groupCountY, int groupCountZ = 1) = 0;
virtual void DispatchIndirect() {} // WIP.
virtual void DispatchMesh(int groupCountX, int groupCountY, int groupCountZ) {} // WIP.
virtual void TraceRays(int width, int height, int depth) {} // WIP.
// </Draw>
// <Profiler>
virtual void ProfilerBeginEvent(UINT32 color, CSZ text) {}
virtual void ProfilerEndEvent() {}
virtual void ProfilerSetMarker(UINT32 color, CSZ text) {}
// </Profiler>
// <Profiler>
virtual void ProfilerBeginEvent(UINT32 color, CSZ text) {}
virtual void ProfilerEndEvent() {}
virtual void ProfilerSetMarker(UINT32 color, CSZ text) {}
// </Profiler>
RcVector4 GetViewportSize() const { return _viewportSize; }
RcVector4 GetViewScaleBias() const { return _viewScaleBias; }
};
VERUS_TYPEDEFS(BaseCommandBuffer);
RcVector4 GetViewportSize() const { return _viewportSize; }
RcVector4 GetViewScaleBias() const { return _viewScaleBias; }
};
VERUS_TYPEDEFS(BaseCommandBuffer);
class CommandBufferPtr : public Ptr<BaseCommandBuffer>
{
public:
void Init();
void InitOneTimeSubmit();
};
VERUS_TYPEDEFS(CommandBufferPtr);
class CommandBufferPtr : public Ptr<BaseCommandBuffer>
{
public:
void Init();
void InitOneTimeSubmit();
};
VERUS_TYPEDEFS(CommandBufferPtr);
class CommandBufferPwn : public CommandBufferPtr
{
public:
~CommandBufferPwn() { Done(); }
void Done();
};
VERUS_TYPEDEFS(CommandBufferPwn);
class CommandBufferPwn : public CommandBufferPtr
{
public:
~CommandBufferPwn() { Done(); }
void Done();
};
VERUS_TYPEDEFS(CommandBufferPwn);
template<int COUNT>
class CommandBufferPwns : public Pwns<CommandBufferPwn, COUNT>
{
};
}
template<int 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;}}
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;
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>
XrAction _handle = XR_NULL_HANDLE;
Vector<XrPath> _vSubactionPaths;
Vector<XrSpace> _vActionSpaces;
};
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.
#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
{
CSZ _name = nullptr;
PcVertexInputAttrDesc _pVertexInputAttrDesc = nullptr;
const int* _pStrides = nullptr;
UINT32 _dynBindingsMask = 0;
bool _32BitIndices = false;
};
VERUS_TYPEDEFS(GeometryDesc);
class BaseGeometry : public Object, public Scheduled
{
protected:
String _name;
UINT32 _instBindingsMask = 0;
UINT32 _dynBindingsMask = 0;
bool _32BitIndices = false;
class BaseGeometry : public Object, public Scheduled
{
protected:
String _name;
UINT32 _instBindingsMask = 0;
UINT32 _dynBindingsMask = 0;
bool _32BitIndices = false;
BaseGeometry() = default;
virtual ~BaseGeometry() = default;
BaseGeometry() = default;
virtual ~BaseGeometry() = default;
public:
virtual void Init(RcGeometryDesc desc) = 0;
virtual void Done() = 0;
public:
virtual void Init(RcGeometryDesc desc) = 0;
virtual void Done() = 0;
virtual void CreateVertexBuffer(int count, int binding) = 0;
virtual void UpdateVertexBuffer(const void* p, int binding, BaseCommandBuffer* pCB = nullptr, INT64 size = 0, INT64 offset = 0) = 0;
virtual void CreateVertexBuffer(int count, int binding) = 0;
virtual void UpdateVertexBuffer(const void* p, int binding, BaseCommandBuffer* pCB = nullptr, INT64 size = 0, INT64 offset = 0) = 0;
virtual void CreateIndexBuffer(int count) = 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 UpdateIndexBuffer(const void* p, BaseCommandBuffer* pCB = nullptr, INT64 size = 0, INT64 offset = 0) = 0;
virtual void CreateStorageBuffer(int count, int structSize, int sbIndex, ShaderStageFlags stageFlags) = 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;
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;
static int GetVertexInputAttrDescCount(PcVertexInputAttrDesc p);
static int GetBindingCount(PcVertexInputAttrDesc p);
static int GetVertexInputAttrDescCount(PcVertexInputAttrDesc p);
static int GetBindingCount(PcVertexInputAttrDesc p);
bool Has32BitIndices() const { return _32BitIndices; }
};
VERUS_TYPEDEFS(BaseGeometry);
bool Has32BitIndices() const { return _32BitIndices; }
};
VERUS_TYPEDEFS(BaseGeometry);
class GeometryPtr : public Ptr<BaseGeometry>
{
public:
void Init(RcGeometryDesc desc);
};
VERUS_TYPEDEFS(GeometryPtr);
class GeometryPtr : public Ptr<BaseGeometry>
{
public:
void Init(RcGeometryDesc desc);
};
VERUS_TYPEDEFS(GeometryPtr);
class GeometryPwn : public GeometryPtr
{
public:
~GeometryPwn() { Done(); }
void Done();
};
VERUS_TYPEDEFS(GeometryPwn);
class GeometryPwn : public GeometryPtr
{
public:
~GeometryPwn() { Done(); }
void Done();
};
VERUS_TYPEDEFS(GeometryPwn);
template<int COUNT>
class GeometryPwns : public Pwns<GeometryPwn, COUNT>
{
};
}
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.
#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;
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.
_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) {}
// 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)
{
_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
void DisableDepthTest()
{
protected:
UINT32 _vertexInputBindingsFilter = UINT32_MAX;
_depthTestEnable = false;
_depthWriteEnable = false;
}
BasePipeline() = default;
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>
void EnableDepthBias()
{
public:
void Init(RcPipelineDesc desc);
};
VERUS_TYPEDEFS(PipelinePtr);
_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 PipelinePwn : public PipelinePtr
{
public:
~PipelinePwn() { Done(); }
void Done();
};
VERUS_TYPEDEFS(PipelinePwn);
class BasePipeline : public Object, public Scheduled
{
protected:
UINT32 _vertexInputBindingsFilter = UINT32_MAX;
template<int COUNT>
class PipelinePwns : public Pwns<PipelinePwn, COUNT>
{
};
}
BasePipeline() = default;
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.
#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,
vulkan,
direct3D11,
direct3D12
};
_gvc.Copy();
}
};
VERUS_TYPEDEFS(BaseRendererDesc);
struct BaseRendererDesc
{
GlobalVarsClipboard _gvc;
class BaseRenderer : public Object
{
protected:
Vector<PScheduled> _vScheduled;
BaseRendererDesc _desc;
int _swapChainBufferCount = 0;
int _swapChainBufferIndex = 0;
int _ringBufferIndex = 0;
BaseRendererDesc()
{
_gvc.Copy();
}
};
VERUS_TYPEDEFS(BaseRendererDesc);
BaseRenderer();
virtual ~BaseRenderer();
class BaseRenderer : public Object
{
protected:
Vector<PScheduled> _vScheduled;
BaseRendererDesc _desc;
int _swapChainBufferCount = 0;
int _swapChainBufferIndex = 0;
int _ringBufferIndex = 0;
public:
static const int s_ringBufferSize = 3;
BaseRenderer();
virtual ~BaseRenderer();
static BaseRenderer* Load(CSZ dll, RBaseRendererDesc desc);
virtual void ReleaseMe() = 0;
public:
static const int s_ringBufferSize = 3;
void SetDesc(RBaseRendererDesc desc) { _desc = desc; }
static BaseRenderer* Load(CSZ dll, RBaseRendererDesc desc);
virtual void ReleaseMe() = 0;
int GetSwapChainBufferCount() const { return _swapChainBufferCount; }
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; }
int GetSwapChainBufferIndex() const { return _swapChainBufferIndex; }
int GetRingBufferIndex() const { return _ringBufferIndex; }
virtual void ImGuiInit(RPHandle renderPassHandle) = 0;
virtual void ImGuiRenderDrawData() = 0;
void Schedule(PScheduled p);
void Unschedule(PScheduled p);
void UpdateScheduled();
virtual void ResizeSwapChain() = 0;
virtual void ImGuiInit(RPHandle renderPassHandle) = 0;
virtual void ImGuiRenderDrawData() = 0;
virtual PBaseExtReality GetExtReality() { return nullptr; }
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?
virtual Gapi GetGapi() = 0;
// <Resources>
virtual PBaseCommandBuffer InsertCommandBuffer() = 0;
virtual PBaseGeometry InsertGeometry() = 0;
virtual PBasePipeline InsertPipeline() = 0;
virtual PBaseShader InsertShader() = 0;
virtual PBaseTexture InsertTexture() = 0;
// <FrameCycle>
virtual void BeginFrame() = 0;
virtual void AcquireSwapChainImage() = 0;
virtual void EndFrame() = 0;
virtual void WaitIdle() = 0;
virtual void OnMinimized() = 0;
// </FrameCycle>
virtual void DeleteCommandBuffer(PBaseCommandBuffer p) = 0;
virtual void DeleteGeometry(PBaseGeometry p) = 0;
virtual void DeletePipeline(PBasePipeline p) = 0;
virtual void DeleteShader(PBaseShader p) = 0;
virtual void DeleteTexture(PBaseTexture p) = 0;
// <Resources>
virtual PBaseCommandBuffer InsertCommandBuffer() = 0;
virtual PBaseGeometry InsertGeometry() = 0;
virtual PBasePipeline InsertPipeline() = 0;
virtual PBaseShader InsertShader() = 0;
virtual PBaseTexture InsertTexture() = 0;
RPHandle CreateSimpleRenderPass(Format format, RP::Attachment::LoadOp loadOp = RP::Attachment::LoadOp::dontCare, ImageLayout layout = ImageLayout::fsReadOnly);
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;
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>
virtual void DeleteCommandBuffer(PBaseCommandBuffer p) = 0;
virtual void DeleteGeometry(PBaseGeometry p) = 0;
virtual void DeletePipeline(PBasePipeline p) = 0;
virtual void DeleteShader(PBaseShader p) = 0;
virtual void DeleteTexture(PBaseTexture p) = 0;
static void SetAlphaBlendHelper(
CSZ sz,
int& colorBlendOp,
int& alphaBlendOp,
int& srcColorBlendFactor,
int& dstColorBlendFactor,
int& srcAlphaBlendFactor,
int& dstAlphaBlendFactor);
RPHandle CreateSimpleRenderPass(Format format, RP::Attachment::LoadOp loadOp = RP::Attachment::LoadOp::dontCare, ImageLayout layout = ImageLayout::fsReadOnly);
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;
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);
}
virtual void UpdateUtilization() {}
};
VERUS_TYPEDEFS(BaseRenderer);
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.
#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;
CSZ _source = nullptr;
CSZ* _branches = nullptr;
CSZ* _ignoreList = nullptr;
CSZ _userDefines = nullptr;
bool _saveCompiled = false;
ShaderDesc(CSZ url = nullptr) : _url(url) {}
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
};
VERUS_TYPEDEFS(ShaderDesc);
class BaseShader : public Object, public Scheduled
{
static CSZ s_branchCommentMarker;
protected:
String _sourceName;
CSZ* _ignoreList = nullptr;
CSZ _userDefines = nullptr;
bool _saveCompiled = false;
public:
enum class Stage : int
{
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
};
BaseShader() = default;
virtual ~BaseShader() = default;
protected:
String _sourceName;
CSZ* _ignoreList = nullptr;
CSZ _userDefines = nullptr;
bool _saveCompiled = false;
public:
virtual void Init(CSZ source, CSZ sourceName, CSZ* branches) = 0;
virtual void Done() = 0;
BaseShader() = default;
virtual ~BaseShader() = default;
void Load(CSZ url);
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 Init(CSZ source, CSZ sourceName, CSZ* branches) = 0;
virtual void Done() = 0;
virtual void CreateDescriptorSet(int setNumber, const void* pSrc, int size,
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;
void Load(CSZ url);
static String Parse(
CSZ branchDesc,
RString entry,
String stageEntries[],
RString stages,
Vector<String>& vMacroName,
Vector<String>& vMacroValue,
CSZ prefix);
static void TestParse();
virtual void BeginBindDescriptors() = 0;
virtual void EndBindDescriptors() = 0;
virtual void CreateDescriptorSet(int setNumber, const void* pSrc, int size,
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;
Str GetSourceName() const { return _C(_sourceName); }
virtual void BeginBindDescriptors() = 0;
virtual void EndBindDescriptors() = 0;
void SetIgnoreList(CSZ* list) { _ignoreList = list; }
bool IsInIgnoreList(CSZ name) const;
Str GetSourceName() const { return _C(_sourceName); }
void SetUserDefines(CSZ def) { _userDefines = def; }
void SetIgnoreList(CSZ* list) { _ignoreList = list; }
bool IsInIgnoreList(CSZ name) const;
void SetSaveCompiled(bool b) { _saveCompiled = b; }
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; }
static void SaveCompiled(CSZ code, CSZ filename);
};
VERUS_TYPEDEFS(BaseShader);
class ShaderPwn : public ShaderPtr
{
public:
~ShaderPwn() { Done(); }
void Done();
};
VERUS_TYPEDEFS(ShaderPwn);
class ShaderPtr : public Ptr<BaseShader>
{
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>
{
};
}
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.
#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);
char _filterMagMinMip[4];
char _addressModeUVW[4];
float _mipLodBias = 0;
float _minLod = 0;
float _maxLod = 15;
VERUS_ZERO_MEM(_filterMagMinMip);
VERUS_ZERO_MEM(_addressModeUVW);
}
SamplerDesc()
{
VERUS_ZERO_MEM(_filterMagMinMip);
VERUS_ZERO_MEM(_addressModeUVW);
}
void SetFilter(CSZ f) { strcpy(_filterMagMinMip, f); }
void SetAddressMode(CSZ a) { strcpy(_addressModeUVW, a); }
void Set(CSZ f, CSZ a) { SetFilter(f); SetAddressMode(a); }
};
VERUS_TYPEDEFS(SamplerDesc);
void SetFilter(CSZ f) { strcpy(_filterMagMinMip, f); }
void SetAddressMode(CSZ a) { strcpy(_addressModeUVW, a); }
void Set(CSZ f, CSZ a) { SetFilter(f); SetAddressMode(a); }
};
VERUS_TYPEDEFS(SamplerDesc);
struct TextureDesc
struct TextureDesc
{
enum class Flags : UINT32
{
enum class Flags : UINT32
{
none = 0,
colorAttachment = (1 << 0), // Texture can be used as a render target.
inputAttachment = (1 << 1), // Texture can be used as an input attachment in a framebuffer (optimization for tiled rendering).
depthSampledR = (1 << 2), // Depth can be sampled in a shader, initial layout will be depthStencilReadOnly.
depthSampledW = (1 << 3), // Depth can be sampled in a shader, initial layout will be depthStencilAttachment.
anyShaderResource = (1 << 4), // Will use xsReadOnly as main layout (any shader can sample this texture).
generateMips = (1 << 5), // Allows GenerateMips calls. Not compatible with BGRA format on some systems.
forceArrayTexture = (1 << 6), // Create array texture even if arrayLayers=1.
sync = (1 << 7), // Load image data synchronously.
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;
}
none = 0,
colorAttachment = (1 << 0), // Texture can be used as a render target.
inputAttachment = (1 << 1), // Texture can be used as an input attachment in a framebuffer (optimization for tiled rendering).
depthSampledR = (1 << 2), // Depth can be sampled in a shader, initial layout will be depthStencilReadOnly.
depthSampledW = (1 << 3), // Depth can be sampled in a shader, initial layout will be depthStencilAttachment.
anyShaderResource = (1 << 4), // Will use xsReadOnly as main layout (any shader can sample this texture).
generateMips = (1 << 5), // Allows GenerateMips calls. Not compatible with BGRA format on some systems.
forceArrayTexture = (1 << 6), // Create array texture even if arrayLayers=1.
sync = (1 << 7), // Load image data synchronously.
exposureMips = (1 << 8), // Internal flag for automatic exposure.
cubeMap = (1 << 9)
};
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:
Vector4 _size = Vector4(0);
String _name;
TextureDesc _desc;
UINT64 _initAtFrame = 0;
ImageLayout _mainLayout = ImageLayout::fsReadOnly;
int _part = 0;
int _bytesPerPixel = 0;
*this = TextureDesc();
_format = format;
_width = w;
_height = h;
}
};
VERUS_TYPEDEFS(TextureDesc);
BaseTexture();
virtual ~BaseTexture();
class BaseTexture : public Object, public IO::AsyncDelegate, public Scheduled
{
protected:
Vector4 _size = Vector4(0);
String _name;
TextureDesc _desc;
UINT64 _initAtFrame = 0;
ImageLayout _mainLayout = ImageLayout::fsReadOnly;
int _part = 0;
int _bytesPerPixel = 0;
public:
virtual void Init(RcTextureDesc desc) = 0;
virtual void Done() = 0;
BaseTexture();
virtual ~BaseTexture();
bool IsLoaded() const { return _desc._width != 0; }
Str GetName() const { return _C(_name); }
public:
virtual void Init(RcTextureDesc desc) = 0;
virtual void Done() = 0;
RcTextureDesc GetDesc() const { return _desc; }
RcVector4 GetClearValue() const { return _desc._clearValue; }
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; }
bool IsLoaded() const { return _desc._width != 0; }
Str GetName() const { return _C(_name); }
int GetPart() const { return _part; }
RcVector4 GetSize() const { return _size; }
bool IsSRGB() const;
Format ToTextureBcFormat(IO::RcDDSHeader header, IO::RcDDSHeaderDXT10 header10) const;
RcTextureDesc GetDesc() const { return _desc; }
RcVector4 GetClearValue() const { return _desc._clearValue; }
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; }
void SetLoadingFlags(TextureDesc::Flags flags) { _desc._flags = flags; }
void SetLoadingSamplerDesc(PcSamplerDesc pSamplerDesc) { _desc._pSamplerDesc = pSamplerDesc; }
int GetPart() const { return _part; }
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 LoadDDS(CSZ url, RcBlob blob);
void LoadDDSArray(CSZ* urls);
void SetLoadingFlags(TextureDesc::Flags flags) { _desc._flags = flags; }
void SetLoadingSamplerDesc(PcSamplerDesc pSamplerDesc) { _desc._pSamplerDesc = pSamplerDesc; }
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 bool ReadbackSubresource(void* p, bool recordCopyCommand = true, BaseCommandBuffer* pCB = nullptr) = 0;
virtual void Async_WhenLoaded(CSZ url, RcBlob blob) override;
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);
static bool IsSRGBFormat(Format format);
static bool IsBC(Format format);
static bool Is4BitsBC(Format format);
static bool IsDepthFormat(Format format);
};
VERUS_TYPEDEFS(BaseTexture);
virtual void GenerateMips(BaseCommandBuffer* pCB = nullptr) = 0;
class TexturePtr : public Ptr<BaseTexture>
{
public:
TexturePtr() = default;
TexturePtr(nullptr_t) : Ptr(nullptr) {}
static int FormatToBytesPerPixel(Format format);
static bool IsSRGBFormat(Format format);
static bool IsBC(Format format);
static bool Is4BitsBC(Format format);
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);
};
VERUS_TYPEDEFS(TexturePtr);
void Init(RcTextureDesc desc);
class TexturePwn : public TexturePtr
{
public:
~TexturePwn() { Done(); }
void Done();
};
VERUS_TYPEDEFS(TexturePwn);
static TexturePtr From(PBaseTexture p);
};
VERUS_TYPEDEFS(TexturePtr);
template<int COUNT>
class TexturePwns : public Pwns<TexturePwn, COUNT>
{
};
}
class TexturePwn : public TexturePtr
{
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.
#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"
enum PIPE
{
PIPE_POINTS,
PIPE_POINTS_NO_Z,
PIPE_LINES,
PIPE_LINES_NO_Z,
PIPE_POLY,
PIPE_POLY_NO_Z,
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);
enum PIPE
{
PIPE_POINTS,
PIPE_POINTS_NO_Z,
PIPE_LINES,
PIPE_LINES_NO_Z,
PIPE_POLY,
PIPE_POLY_NO_Z,
PIPE_COUNT
};
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.
#pragma once
namespace verus
namespace verus::CGI
{
namespace CGI
enum class LightType : int
{
enum class LightType : int
{
none,
dir,
omni,
spot
};
none,
dir,
omni,
spot
};
class DeferredShading : public Object
{
class DeferredShading : public Object
{
#include "../Shaders/DS.inc.hlsl"
#include "../Shaders/DS_Ambient.inc.hlsl"
#include "../Shaders/DS_AmbientNode.inc.hlsl"
@ -23,207 +21,206 @@ namespace verus
#include "../Shaders/DS_Reflection.inc.hlsl"
#include "../Shaders/DS_BakeSprites.inc.hlsl"
enum SHADER
{
SHADER_LIGHT,
SHADER_AMBIENT,
SHADER_AMBIENT_NODE,
SHADER_PROJECT_NODE,
SHADER_COMPOSE,
SHADER_REFLECTION,
SHADER_BAKE_SPRITES,
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();
enum SHADER
{
SHADER_LIGHT,
SHADER_AMBIENT,
SHADER_AMBIENT_NODE,
SHADER_PROJECT_NODE,
SHADER_COMPOSE,
SHADER_REFLECTION,
SHADER_BAKE_SPRITES,
SHADER_COUNT
};
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.
#pragma once
namespace verus
namespace verus::CGI
{
namespace CGI
template<typename T>
class DynamicBuffer : public GeometryPwn
{
template<typename T>
class DynamicBuffer : public GeometryPwn
Vector<T> _vVB;
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)
{
_maxVerts = maxVerts;
GeometryDesc dynDesc(desc);
dynDesc._dynBindingsMask = 0x1;
GeometryPwn::Init(dynDesc);
}
void CreateVertexBuffer()
{
_vVB.resize(_maxVerts);
(*this)->CreateVertexBuffer(_maxVerts, 0);
}
void CreateVertexBuffer()
{
_vVB.resize(_maxVerts);
(*this)->CreateVertexBuffer(_maxVerts, 0);
}
void Reset()
{
_vertCount = 0;
_firstVertex = 0;
}
void Reset()
{
_vertCount = 0;
_firstVertex = 0;
}
void Begin()
{
_firstVertex = _vertCount;
}
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)
{
VERUS_QREF_RENDERER;
const int vertCount = _vertCount - _firstVertex;
if (vertCount)
{
if (!pCB)
pCB = renderer.GetCommandBuffer().Get();
(*this)->UpdateVertexBuffer(&_vVB[_firstVertex], 0, pCB, vertCount, _firstVertex);
pCB->Draw(vertCount, 1, _firstVertex);
}
}
bool Add(const T& v)
{
if (_vertCount + 1 > _maxVerts)
return false;
_vVB[_vertCount++] = v;
return true;
}
bool Add(const T& v)
{
if (_vertCount + 1 > _maxVerts)
return false;
_vVB[_vertCount++] = v;
return true;
}
bool AddQuad(
const T& a0,
const T& a1,
const T& b0,
const T& b1)
{
if (_vertCount + 6 > _maxVerts)
return false;
_vVB[_vertCount++] = a0;
_vVB[_vertCount++] = b0;
_vVB[_vertCount++] = a1;
_vVB[_vertCount++] = a1;
_vVB[_vertCount++] = b0;
_vVB[_vertCount++] = b1;
return true;
}
};
}
bool AddQuad(
const T& a0,
const T& a1,
const T& b0,
const T& b1)
{
if (_vertCount + 6 > _maxVerts)
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.
#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
enum class Format : int
{
// Special Formats:
unormR10G10B10A2,
sintR16,
floatR11G11B10,
// Special Formats:
unormR10G10B10A2,
sintR16,
floatR11G11B10,
// Unsigned Formats:
unormR8,
unormR8G8,
unormR8G8B8A8,
unormB8G8R8A8,
srgbR8G8B8A8,
srgbB8G8R8A8,
// Unsigned Formats:
unormR8,
unormR8G8,
unormR8G8B8A8,
unormB8G8R8A8,
srgbR8G8B8A8,
srgbB8G8R8A8,
// Floating-Point Formats:
floatR16,
floatR16G16,
floatR16G16B16A16,
// Floating-Point Formats:
floatR16,
floatR16G16,
floatR16G16B16A16,
// IEEE Formats:
floatR32,
floatR32G32,
floatR32G32B32A32,
// IEEE Formats:
floatR32,
floatR32G32,
floatR32G32B32A32,
// Depth-Stencil:
unormD16,
unormD24uintS8,
floatD32,
// Depth-Stencil:
unormD16,
unormD24uintS8,
floatD32,
// Compressed Texture Formats:
unormBC1, // Deprecated RGBA.
unormBC2, // Deprecated RGBA.
unormBC3, // Deprecated RGBA.
unormBC4, // R.
unormBC5, // RG.
unormBC7, // RGBA.
snormBC4, // R.
snormBC5, // RG.
srgbBC1, // Deprecated RGBA.
srgbBC2, // Deprecated RGBA.
srgbBC3, // Deprecated RGBA.
srgbBC7 // RGBA.
};
}
// Compressed Texture Formats:
unormBC1, // Deprecated RGBA.
unormBC2, // Deprecated RGBA.
unormBC3, // Deprecated RGBA.
unormBC4, // R.
unormBC5, // RG.
unormBC7, // RGBA.
snormBC4, // R.
snormBC5, // RG.
srgbBC1, // Deprecated RGBA.
srgbBC2, // Deprecated RGBA.
srgbBC3, // Deprecated RGBA.
srgbBC7 // RGBA.
};
}

View File

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

View File

@ -1,209 +1,206 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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;
};
VERUS_TYPEDEFS(RendererDelegate);
virtual void Renderer_OnDraw() = 0;
virtual void Renderer_OnDrawView(RcViewDesc viewDesc) = 0;
};
VERUS_TYPEDEFS(RendererDelegate);
class Renderer : public Singleton<Renderer>, public Object
{
class Renderer : public Singleton<Renderer>, public Object
{
#include "../Shaders/GenerateMips.inc.hlsl"
#include "../Shaders/GenerateCubeMapMips.inc.hlsl"
#include "../Shaders/Quad.inc.hlsl"
enum SHADER
{
SHADER_GENERATE_MIPS,
SHADER_GENERATE_CUBE_MAP_MIPS,
SHADER_QUAD,
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);
enum SHADER
{
SHADER_GENERATE_MIPS,
SHADER_GENERATE_CUBE_MAP_MIPS,
SHADER_QUAD,
SHADER_COUNT
};
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.
#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:
static int Expect(CSZ& p, CSZ* ppOptions);
static int ExpectBlendOp(CSZ& p);
static int ExpectCompFunc(CSZ& p, char end, bool skipSpace);
static int ExpectStencilOp(CSZ& p, char end, bool skipSpace);
static int SkipSpace(CSZ& p);
};
}
public:
static int Expect(CSZ& p, CSZ* ppOptions);
static int ExpectBlendOp(CSZ& p);
static int ExpectCompFunc(CSZ& p, char end, bool skipSpace);
static int ExpectStencilOp(CSZ& p, char end, bool skipSpace);
static int SkipSpace(CSZ& p);
};
}

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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_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:
enum class Severity : int
{
error,
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);
error,
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);
};
}

View File

@ -1,33 +1,30 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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:
Recoverable(std::thread::id tid = std::this_thread::get_id(), CSZ file = "", UINT32 line = __LINE__) : RuntimeError(tid, file, line) {}
Recoverable(const Recoverable& that)
{
*this = that;
}
Recoverable& operator=(const Recoverable& that)
{
RuntimeError::operator=(that);
return *this;
}
*this = that;
}
Recoverable& operator=(const Recoverable& that)
{
RuntimeError::operator=(that);
return *this;
}
template<typename T>
Recoverable& operator<<(const T& t)
{
RuntimeError::operator<<(t);
return *this;
}
};
VERUS_TYPEDEFS(Recoverable);
}
template<typename T>
Recoverable& operator<<(const T& t)
{
RuntimeError::operator<<(t);
return *this;
}
};
VERUS_TYPEDEFS(Recoverable);
}
#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.
#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
class RuntimeError : public std::exception
mutable StringStream _ss;
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;
mutable String _what;
std::thread::id _tid;
String _file;
UINT32 _line = 0;
CSZ p = strrchr(file, '/');
if (!p)
p = strrchr(file, '\\');
_file = p ? p + 1 : file;
}
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:
RuntimeError(std::thread::id tid = std::this_thread::get_id(), CSZ file = "", UINT32 line = __LINE__) :
_tid(tid), _line(line)
virtual CSZ what() const throw()
{
if (_ss.str().size())
{
CSZ p = strrchr(file, '/');
if (!p)
p = strrchr(file, '\\');
_file = p ? p + 1 : file;
_what += _ss.str();
_ss.str("");
}
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() {}
return _C(_what);
}
virtual CSZ what() const throw()
{
if (_ss.str().size())
{
_what += _ss.str();
_ss.str("");
}
return _C(_what);
}
std::thread::id GetThreadID() const { return _tid; }
CSZ GetFile() const { return _C(_file); }
UINT32 GetLine() const { return _line; }
std::thread::id GetThreadID() const { return _tid; }
CSZ GetFile() const { return _C(_file); }
UINT32 GetLine() const { return _line; }
template<typename T>
RuntimeError& operator<<(const T& t)
{
_ss << t;
return *this;
}
template<typename T>
RuntimeError& operator<<(const T& t)
{
_ss << t;
return *this;
}
bool IsRaised() const { return !!strlen(what()); }
};
VERUS_TYPEDEFS(RuntimeError);
}
bool IsRaised() const { return !!strlen(what()); }
};
VERUS_TYPEDEFS(RuntimeError);
}
#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.
#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"
enum PIPE
{
PIPE_MAIN,
PIPE_LIGHT_SHAFTS,
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; }
enum PIPE
{
PIPE_MAIN,
PIPE_LIGHT_SHAFTS,
PIPE_COUNT
};
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.
#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"
enum PIPE
{
PIPE_U,
PIPE_V,
enum PIPE
{
PIPE_U,
PIPE_V,
PIPE_VSM_U,
PIPE_VSM_V,
PIPE_VSM_U,
PIPE_VSM_V,
PIPE_SSAO,
PIPE_SSAO,
PIPE_RESOLVE_DITHERING,
PIPE_SHARPEN,
PIPE_RESOLVE_DITHERING,
PIPE_SHARPEN,
PIPE_DOF_U,
PIPE_DOF_V,
PIPE_DOF_U,
PIPE_DOF_V,
PIPE_BLOOM_U,
PIPE_BLOOM_V,
PIPE_BLOOM_LIGHT_SHAFTS_U,
PIPE_BLOOM_LIGHT_SHAFTS_V,
PIPE_BLOOM_U,
PIPE_BLOOM_V,
PIPE_BLOOM_LIGHT_SHAFTS_U,
PIPE_BLOOM_LIGHT_SHAFTS_V,
PIPE_AA,
PIPE_AA_OFF,
PIPE_MOTION_BLUR,
PIPE_MOTION_BLUR_OFF,
PIPE_AA,
PIPE_AA_OFF,
PIPE_MOTION_BLUR,
PIPE_MOTION_BLUR_OFF,
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; }
PIPE_COUNT
};
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.
#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"
static UB_CinemaVS s_ubCinemaVS;
static UB_CinemaFS s_ubCinemaFS;
static UB_CinemaVS s_ubCinemaVS;
static UB_CinemaFS s_ubCinemaFS;
CGI::ShaderPwn _shader;
CGI::PipelinePwn _pipe;
CGI::TexturePwn _texFilmGrain;
CGI::CSHandle _csh;
float _uOffset = 0;
float _vOffset = 0;
float _brightness = 1;
float _flickerStrength = 0.02f;
float _noiseStrength = 0.2f;
bool _editMode = false;
CGI::ShaderPwn _shader;
CGI::PipelinePwn _pipe;
CGI::TexturePwn _texFilmGrain;
CGI::CSHandle _csh;
float _uOffset = 0;
float _vOffset = 0;
float _brightness = 1;
float _flickerStrength = 0.02f;
float _noiseStrength = 0.2f;
bool _editMode = false;
public:
Cinema();
~Cinema();
public:
Cinema();
~Cinema();
void Init();
void Done();
void Init();
void Done();
void Draw();
void Draw();
bool IsEditMode() const { return _editMode; }
void ToggleEditMode() { _editMode = !_editMode; }
};
VERUS_TYPEDEFS(Cinema);
}
bool IsEditMode() const { return _editMode; }
void ToggleEditMode() { _editMode = !_editMode; }
};
VERUS_TYPEDEFS(Cinema);
}

View File

@ -1,188 +1,185 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#pragma once
namespace verus
namespace verus::Effects
{
namespace Effects
enum class BillboardType : int
{
enum class BillboardType : int
{
none,
screenViewplaneOriented,
screenViewpointOriented,
worldViewplaneOriented,
worldViewpointOriented,
axial
};
none,
screenViewplaneOriented,
screenViewpointOriented,
worldViewplaneOriented,
worldViewpointOriented,
axial
};
class Particle
{
public:
Point3 _position = Point3(0);
Point3 _prevPosition = Point3(0);
Vector3 _velocity = Vector3(0, 1, 0);
Vector3 _axis = Vector3(0, 1, 0);
Vector4 _tcOffset = Vector4(0);
Vector4 _beginColor = Vector4::Replicate(1);
Vector4 _endColor = Vector4::Replicate(1);
void* _pUser = nullptr;
float _invTotalTime = 0;
float _timeLeft = -1;
float _beginAdditive = 0;
float _endAdditive = 0;
float _beginSize = 0;
float _endSize = 0;
float _beginSpin = 0;
float _endSpin = 0;
bool _inContact = false;
};
VERUS_TYPEDEFS(Particle);
class Particle
{
public:
Point3 _position = Point3(0);
Point3 _prevPosition = Point3(0);
Vector3 _velocity = Vector3(0, 1, 0);
Vector3 _axis = Vector3(0, 1, 0);
Vector4 _tcOffset = Vector4(0);
Vector4 _beginColor = Vector4::Replicate(1);
Vector4 _endColor = Vector4::Replicate(1);
void* _pUser = nullptr;
float _invTotalTime = 0;
float _timeLeft = -1;
float _beginAdditive = 0;
float _endAdditive = 0;
float _beginSize = 0;
float _endSize = 0;
float _beginSpin = 0;
float _endSpin = 0;
bool _inContact = false;
};
VERUS_TYPEDEFS(Particle);
class Particles;
class ParticlesDelegate
{
public:
virtual void Particles_OnUpdate(Particles& particles, int index, RParticle particle,
RVector3 up, RVector3 normal, RTransform3 matAim) = 0;
};
VERUS_TYPEDEFS(ParticlesDelegate);
class Particles;
class ParticlesDelegate
{
public:
virtual void Particles_OnUpdate(Particles& particles, int index, RParticle particle,
RVector3 up, RVector3 normal, RTransform3 matAim) = 0;
};
VERUS_TYPEDEFS(ParticlesDelegate);
class Particles : public Object
{
class Particles : public Object
{
#include "../Shaders/Particles.inc.hlsl"
enum PIPE
{
PIPE_MAIN,
PIPE_BILLBOARDS,
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);
enum PIPE
{
PIPE_MAIN,
PIPE_BILLBOARDS,
PIPE_COUNT
};
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.
#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"
static UB_SsaoVS s_ubSsaoVS;
static UB_SsaoFS s_ubSsaoFS;
static UB_SsaoVS s_ubSsaoVS;
static UB_SsaoFS s_ubSsaoFS;
CGI::ShaderPwn _shader;
CGI::PipelinePwn _pipe;
CGI::TexturePwn _texRandNormals;
CGI::RPHandle _rph;
CGI::FBHandle _fbh;
CGI::CSHandle _csh;
float _smallRad = 0.02f;
float _largeRad = 0.05f;
float _weightScale = 10;
float _weightBias = 2.5f;
bool _blur = true;
bool _editMode = false;
CGI::ShaderPwn _shader;
CGI::PipelinePwn _pipe;
CGI::TexturePwn _texRandNormals;
CGI::RPHandle _rph;
CGI::FBHandle _fbh;
CGI::CSHandle _csh;
float _smallRad = 0.02f;
float _largeRad = 0.05f;
float _weightScale = 10;
float _weightBias = 2.5f;
bool _blur = true;
bool _editMode = false;
public:
Ssao();
~Ssao();
public:
Ssao();
~Ssao();
void Init();
void InitCmd();
void Done();
void Init();
void InitCmd();
void Done();
void OnSwapChainResized();
void OnSwapChainResized();
void Generate();
void Generate();
void UpdateRandNormalsTexture();
void UpdateRandNormalsTexture();
bool IsEditMode() const { return _editMode; }
void ToggleEditMode() { _editMode = !_editMode; }
};
VERUS_TYPEDEFS(Ssao);
}
bool IsEditMode() const { return _editMode; }
void ToggleEditMode() { _editMode = !_editMode; }
};
VERUS_TYPEDEFS(Ssao);
}

View File

@ -1,55 +1,52 @@
// Copyright (C) 2021-2022, Dmitry Maluev (dmaluev@gmail.com). All rights reserved.
#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"
enum PIPE
{
PIPE_MAIN,
PIPE_DEBUG_CUBE_MAP,
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; }
enum PIPE
{
PIPE_MAIN,
PIPE_DEBUG_CUBE_MAP,
PIPE_COUNT
};
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.
#pragma once
namespace verus
namespace verus::Extra
{
namespace Extra
struct BaseConvertDelegate;
class BaseConvert
{
struct BaseConvertDelegate;
class BaseConvert
public:
class Mesh
{
public:
class Mesh
enum class Found : int
{
public:
enum class Found : int
{
null = 0,
faces = (1 << 0),
posAndTexCoord0 = (1 << 1),
normals = (1 << 2),
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;
null = 0,
faces = (1 << 0),
posAndTexCoord0 = (1 << 1),
normals = (1 << 2),
tangentSpace = (1 << 3),
skinning = (1 << 4),
texCoord1 = (1 << 5)
};
struct AnimationKey // Represents one bone's channel in motion file.
struct UberVertex
{
Vector<SubKey> _vFrame;
int _type = 0;
int _logicFrameCount = 0;
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;
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;
Vector<AnimationKey> _vAnimKeys;
short _u;
short _v;
};
struct AnimationSet // Represents one motion file.
struct Vec3Char
{
String _name;
Vector<Animation> _vAnimations;
void CleanUp();
char _x;
char _y;
char _z;
};
protected:
typedef Map<String, String> TMapBoneNames;
struct Aabb
{
glm::vec3 _mn = glm::vec3(+FLT_MAX);
glm::vec3 _mx = glm::vec3(-FLT_MAX);
TMapBoneNames _mapBoneNames;
BaseConvertDelegate* _pDelegate = nullptr;
Vector<PMesh> _vMeshes;
Vector<AnimationSet> _vAnimSets;
std::unique_ptr<Mesh> _pCurrentMesh;
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:
BaseConvert();
~BaseConvert();
Mesh(BaseConvert* pBaseConvert);
~Mesh();
void LoadBoneNames(CSZ pathname);
String RenameBone(CSZ name);
PBone FindBone(CSZ name);
protected:
PMesh AddMesh(PMesh pMesh);
PMesh FindMesh(CSZ name);
void DeleteAll();
VERUS_P(void CleanBones());
VERUS_P(void Optimize());
VERUS_P(void RecalculateTangentSpace());
VERUS_P(void Compress());
void SerializeX3D3(IO::RFile file);
void OnProgress(float percent);
void OnProgressText(CSZ txt);
RcString GetName() const { return _name; }
void SetName(CSZ name) { _name = name; }
virtual bool UseAreaBasedNormals() { return false; }
virtual bool UseRigidBones() { return false; }
virtual Str GetPathname() { return ""; }
const glm::mat4& GetBoneAxisMatrix() const { return _matBoneAxis; }
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;
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; }
Quat _q;
bool _redundant = false;
};
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.
#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:
struct Desc
{
glm::vec3 _bias = glm::vec3(0);
float _scaleFactor = 1;
float _angle = 0;
float _areaBasedNormals = 0;
bool _flipNormals = 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);
glm::vec3 _bias = glm::vec3(0);
float _scaleFactor = 1;
float _angle = 0;
float _areaBasedNormals = 0;
bool _flipNormals = false;
bool _flipFaces = false;
bool _useRigidBones = false;
bool _convertAsScene = false;
};
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.
#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:
struct Desc
{
glm::vec3 _bias = glm::vec3(0);
float _scaleFactor = 1;
float _angle = 0;
float _areaBasedNormals = 0;
bool _useRigidBones = false;
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);
glm::vec3 _bias = glm::vec3(0);
float _scaleFactor = 1;
float _angle = 0;
float _areaBasedNormals = 0;
bool _useRigidBones = false;
bool _convertAsScene = false;
bool _useDefaultMaterial = false;
bool _rightHanded = true;
};
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.
#pragma once
namespace verus
namespace verus::GUI
{
namespace GUI
template<typename T>
struct Animated
{
template<typename T>
struct Animated
T _from = 0;
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;
T _to = 0;
T _current = 0;
float _time = 0;
float _invDuration = 0;
float _delay = 0;
Easing _easing = Easing::none;
return Math::Lerp(a, b, ratio);
}
T Lerp(const T& a, const T& b, float ratio)
{
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
void Update(float dt)
{
struct Video
if (_invDuration > 0)
{
int _columnCount = 1;
int _rowCount = 1;
int _frameCount = 1;
float _time = 0;
float _invDuration = 0;
float _delay = 0;
float _uScale = 1;
float _vScale = 1;
float _uBias = 0;
float _vBias = 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 Update(float dt);
void Reset(float reverseTime);
} _video;
void Reset(float reverseTime)
{
_current = _from;
_time = reverseTime;
_invDuration = abs(_invDuration);
Update(0);
}
};
Animated<Vector4> _animatedColor;
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;
class Widget;
class Animator
{
struct Video
{
int _columnCount = 1;
int _rowCount = 1;
int _frameCount = 1;
float _time = 0;
float _invDuration = 0;
float _delay = 0;
float _uScale = 1;
float _vScale = 1;
float _uBias = 0;
float _vBias = 0;
public:
Animator();
~Animator();
void Update(float dt);
void Reset(float reverseTime);
} _video;
bool Update();
void Parse(pugi::xml_node node, const Widget* pWidget);
Animated<Vector4> _animatedColor;
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;
RcVector4 SetColor(RcVector4 color);
RcVector4 SetFromColor(RcVector4 color);
bool Update();
void Parse(pugi::xml_node node, const Widget* pWidget);
float GetX(float original) const;
float GetY(float original) const;
float GetW(float original) const;
float GetH(float original) const;
void Reset(float reverseTime = 0);
float SetX(float x);
float SetY(float y);
float SetW(float w);
float SetH(float h);
RcVector4 GetColor(RcVector4 original) const;
RcVector4 SetColor(RcVector4 color);
RcVector4 SetFromColor(RcVector4 color);
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; }
void SetAngle(float a) { _angle = a; }
float GetPostAngle() const { return _postAngle; }
void SetPostAngle(float a) { _postAngle = a; }
float SetX(float x);
float SetY(float y);
float SetW(float w);
float SetH(float h);
float GetPulseScale() const { return _pulseScale; }
float GetPulseScaleAdd() const { return _pulseScaleAdd; }
bool GetVideoBias(float& ub, float& vb) const;
void SetTimeout(float t);
};
VERUS_TYPEDEFS(Animator);
}
float GetAngle() const { return _angle; }
void SetAngle(float a) { _angle = a; }
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.
#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:
Bars();
virtual ~Bars();
public:
Bars();
virtual ~Bars();
static PWidget Make();
static PWidget Make();
virtual void Update() override;
virtual void Draw() override;
virtual void Parse(pugi::xml_node node) override;
};
VERUS_TYPEDEFS(Bars);
}
virtual void Update() override;
virtual void Draw() override;
virtual void Parse(pugi::xml_node node) override;
};
VERUS_TYPEDEFS(Bars);
}

View File

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

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