3#include "DirectX11.hpp"
4#include <glm/glm.force.hpp>
5#include <alicorn/std/vector.hpp>
6#include <alicorn/boost/lexical-cast.hpp>
9#include <Covellite/Api/Vertex.hpp>
12#pragma comment(lib, "d3d11.lib")
14#include "Shaders/Shaders.hpp"
15#include <Covellite/Api/Defines.hpp>
16#include "Component.hpp"
17#include "GraphicApi.Constants.hpp"
19namespace covellite::api::renderer
24class DirectX11::Buffer final
31 static constexpr UINT Flag = D3D11_BIND_VERTEX_BUFFER;
38 static constexpr UINT Flag = D3D11_BIND_CONSTANT_BUFFER;
39 static constexpr UINT Index = TIndex;
43 class Support<::Camera> :
public Constant<COVELLITE_BUFFER_INDEX_CAMERA> { };
46 class Support<::Object> :
public Constant<COVELLITE_BUFFER_INDEX_OBJECT> { };
49 class Support<uint8_t> :
public Constant<COVELLITE_BUFFER_INDEX_USER> { };
55 static constexpr UINT Flag = D3D11_BIND_INDEX_BUFFER;
60 static ComPtr_t<ID3D11Buffer> Create(
61 const ComPtr_t<ID3D11Device> & _pDevice,
62 const bool _IsDynamic,
66 D3D11_BUFFER_DESC Desc = { 0 };
67 Desc.Usage = _IsDynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
68 Desc.CPUAccessFlags =
static_cast<UINT
>(_IsDynamic ? D3D11_CPU_ACCESS_WRITE : 0);
69 Desc.ByteWidth =
static_cast<decltype(Desc.ByteWidth)
>(
sizeof(T) * _Count);
70 Desc.BindFlags = Support<T>::Flag;
72 D3D11_SUBRESOURCE_DATA InitData = { 0 };
73 InitData.pSysMem = _pData;
75 const auto *
const pInitData = (_pData ==
nullptr) ? nullptr : &InitData;
77 ComPtr_t<ID3D11Buffer> pBuffer;
78 DX_CHECK _pDevice->CreateBuffer(&Desc, pInitData, &pBuffer);
83 static ComPtr_t<ID3D11Buffer> Create(
84 const ComPtr_t<ID3D11Device> & _pDevice,
85 const ComPtr_t<ID3D11DeviceContext> & _pImmediateContext,
88 const auto pResult = Create(_pDevice,
false, _pData, 1);
90 constexpr auto Index = Support<T>::Index;
91 _pImmediateContext->VSSetConstantBuffers(Index, 1, pResult.GetAddressOf());
92 _pImmediateContext->PSSetConstantBuffers(Index, 1, pResult.GetAddressOf());
99class DirectX11::ConstantBuffer final :
100 public Constants::Data<T>
103 void Update(
void)
const override
105 m_pImmediateContext->UpdateSubresource(
106 m_pBuffer.Get(), 0, NULL, &m_Data, 0, 0);
110 const ComPtr_t<ID3D11DeviceContext> m_pImmediateContext;
111 const ComPtr_t<ID3D11Buffer> m_pBuffer;
115 const ComPtr_t<ID3D11Device> & _pDevice,
116 const ComPtr_t<ID3D11DeviceContext> & _pImmediateContext) :
117 m_pImmediateContext{ _pImmediateContext },
118 m_pBuffer{ Buffer::Create(_pDevice, _pImmediateContext, &m_Data) }
125DirectX11::DirectX11(
const Data_t & _Data)
127 CreateDeviceAndSwapChain(_Data);
129 MakeConstants<ConstantBuffer>(m_pDevice, m_pImmediateContext);
132DirectX11::~DirectX11(
void)
141 m_pSwapChain->SetFullscreenState(FALSE,
nullptr);
144DirectX11::String_t DirectX11::GetUsingApi(
void)
const
146 return uT(
"DirectX 11");
149void DirectX11::PresentFrame(
void)
151 m_pSwapChain->Present(0, 0);
153 GraphicApi::PresentFrame();
156void DirectX11::ResizeWindow(
const Rect & _ClientRect)
158 m_IsResizeWindow =
true;
159 SetRenderTargetSize(
static_cast<UINT
>(_ClientRect.Width),
static_cast<UINT
>(_ClientRect.Height));
162void DirectX11::CreateDeviceAndSwapChain(
const Data_t & _Data)
164 const D3D_FEATURE_LEVEL FeatureLevels[] =
166 D3D_FEATURE_LEVEL_11_1,
167 D3D_FEATURE_LEVEL_11_0
170 DXGI_SWAP_CHAIN_DESC sd = { 0 };
171 sd.OutputWindow = ::covellite::any_cast<HWND>(_Data.Handle);
172 sd.Windowed = (_Data.IsFullScreen) ? FALSE : TRUE;
174 sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
175 sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
176 sd.SampleDesc.Count = 1;
177 sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
180 using ::alicorn::extension::cpp::IS_RELEASE_CONFIGURATION;
182 DX_CHECK D3D11CreateDeviceAndSwapChain(
184 D3D_DRIVER_TYPE_HARDWARE,
186 (IS_RELEASE_CONFIGURATION) ? 0 : D3D11_CREATE_DEVICE_DEBUG,
187 FeatureLevels,
sizeof(FeatureLevels) /
sizeof(FeatureLevels[0]),
193 &m_pImmediateContext);
195 SetRenderTargetSize(
static_cast<UINT
>(_Data.ClientRect.Width),
196 static_cast<UINT
>(_Data.ClientRect.Height));
199void DirectX11::SetRenderTargetSize(
const UINT _Width,
const UINT _Height)
201 CreateRenderTargetView(_Width, _Height);
202 CreateDepthStencilView(_Width, _Height);
205void DirectX11::CreateRenderTargetView(
const UINT _Width,
const UINT _Height)
207 if (m_pScreenRenderTargetView !=
nullptr)
209 m_pScreenRenderTargetView.Reset();
211 DX_CHECK m_pSwapChain->ResizeBuffers(2, _Width, _Height,
212 DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
215 ComPtr_t<ID3D11Texture2D> pBackBuffer;
216 DX_CHECK m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
217 (
void **)pBackBuffer.GetAddressOf());
219 DX_CHECK m_pDevice->CreateRenderTargetView(pBackBuffer.Get(), NULL,
220 &m_pScreenRenderTargetView);
223void DirectX11::CreateDepthStencilView(
const UINT _Width,
const UINT _Height)
225 m_pScreenDepthStencilView.Reset();
227 const DXGI_FORMAT DeptBufferFormat = DXGI_FORMAT_D32_FLOAT;
229 D3D11_TEXTURE2D_DESC TextureDesc = { 0 };
230 TextureDesc.Width = _Width;
231 TextureDesc.Height = _Height;
232 TextureDesc.MipLevels = 1;
233 TextureDesc.ArraySize = 1;
234 TextureDesc.Format = DeptBufferFormat;
235 TextureDesc.SampleDesc.Count = 1;
236 TextureDesc.SampleDesc.Quality = 0;
237 TextureDesc.Usage = D3D11_USAGE_DEFAULT;
238 TextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
240 ComPtr_t<ID3D11Texture2D> pDepthBuffer;
241 DX_CHECK m_pDevice->CreateTexture2D(&TextureDesc, NULL, &pDepthBuffer);
243 D3D11_DEPTH_STENCIL_VIEW_DESC DeptStencilViewDesc = { 0 };
244 DeptStencilViewDesc.Format = DeptBufferFormat;
245 DeptStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
247 DX_CHECK m_pDevice->CreateDepthStencilView(pDepthBuffer.Get(),
248 &DeptStencilViewDesc, &m_pScreenDepthStencilView);
251auto DirectX11::CreateCamera(
const ComponentPtr_t & _pComponent) -> Render_t
253 const auto CameraId = _pComponent->Id;
255 using Size_t = ::std::tuple<UINT, UINT>;
256 using fnBkSurfaceSize_t = ::std::function<Size_t(
void)>;
258 const auto pCamera = _pComponent;
260 const fnBkSurfaceSize_t GetScaleBkSurfaceSize = [=](void)
262 DXGI_SWAP_CHAIN_DESC Desc = { 0 };
263 DX_CHECK m_pSwapChain->GetDesc(&Desc);
265 const float Scale = (*pCamera)[uT(
"scale")];
267 return Size_t{
static_cast<UINT
>(Scale * Desc.BufferDesc.Width),
268 static_cast<UINT
>(Scale * Desc.BufferDesc.Height) };
271 const fnBkSurfaceSize_t GetWindowBkSurfaceSize = [=](void)
273 DXGI_SWAP_CHAIN_DESC Desc = { 0 };
274 DX_CHECK m_pSwapChain->GetDesc(&Desc);
276 return Size_t{ Desc.BufferDesc.Width, Desc.BufferDesc.Height };
279 const fnBkSurfaceSize_t GetUserBkSurfaceSize = [=](void)
281 DXGI_SWAP_CHAIN_DESC Desc = { 0 };
282 DX_CHECK m_pSwapChain->GetDesc(&Desc);
285 const int Width = (*pCamera)[uT(
"width")];
286 const int Height = (*pCamera)[uT(
"height")];
288 return Size_t{
static_cast<UINT
>(Width),
static_cast<UINT
>(Height) };
291 const auto IsScaleBkSurfaceSize =
292 (*pCamera)[uT(
"scale")].IsType<
float>();
293 const auto IsUserBkSurfaceSize =
294 (*pCamera)[uT(
"width")].IsType<
int>() &&
295 (*pCamera)[uT(
"height")].IsType<
int>();
297 const auto GetBkSurfaceSize =
298 (IsScaleBkSurfaceSize) ? GetScaleBkSurfaceSize :
299 (IsUserBkSurfaceSize) ? GetUserBkSurfaceSize :
300 GetWindowBkSurfaceSize;
302 D3D11_VIEWPORT ViewPort = { 0 };
303 ViewPort.TopLeftX = 0;
304 ViewPort.TopLeftY = 0;
305 ::std::tie(ViewPort.Width, ViewPort.Height) = GetBkSurfaceSize();
306 ViewPort.MinDepth = 0.0f;
307 ViewPort.MaxDepth = 1.0f;
308 m_pImmediateContext->RSSetViewports(1, &ViewPort);
310 const auto SetDefaultRenderTarget = [=](void)
312 m_CurrentRenderTargets = { m_pScreenRenderTargetView.Get() };
313 m_pCurrentDepthStencilView = m_pScreenDepthStencilView;
315 D3D11_VIEWPORT ViewPort = { 0 };
316 ViewPort.TopLeftX = 0;
317 ViewPort.TopLeftY = 0;
318 ::std::tie(ViewPort.Width, ViewPort.Height) = GetBkSurfaceSize();
319 ViewPort.MinDepth = 0.0f;
320 ViewPort.MaxDepth = 1.0f;
321 m_pImmediateContext->RSSetViewports(1, &ViewPort);
324 const auto DisabledBlendRender = CreateBlendState(
false);
325 const auto DisableDepthRender = GetDepthState(
false,
false,
false);
327 const auto ServiceComponents = CapturingServiceComponent::Get(_pComponent,
333 const Render_t CameraOptographic = [=](void)
335 const Component::Position Pos{ *ServiceComponents[0] };
337 SetDefaultRenderTarget();
338 DisabledBlendRender();
339 DisableDepthRender();
341 UINT ViewportCount = 1;
342 D3D11_VIEWPORT Viewport = { 0 };
343 m_pImmediateContext->RSGetViewports(&ViewportCount, &Viewport);
345 auto & CameraMatrices = m_pConstants->Get<::Camera>();
347 CameraMatrices.Projection = ::glm::transpose(::glm::ortho(
348 Pos.X, Pos.X + Viewport.Width,
349 Pos.Y + Viewport.Height, Pos.Y,
352 const auto View = ::glm::identity<::glm::mat4>();
353 CameraMatrices.View = ::glm::transpose(View);
354 CameraMatrices.ViewInverse = ::glm::transpose(::glm::inverse(View));
355 m_pConstants->Update<::Camera>();
357 (*_pComponent)[uT(
"view")] = CameraMatrices.View;
358 (*_pComponent)[uT(
"projection")] = CameraMatrices.Projection;
361 const Render_t CameraPerspective = [=](void)
363 SetDefaultRenderTarget();
364 DisabledBlendRender();
365 DisableDepthRender();
367 UINT ViewportCount = 1;
368 D3D11_VIEWPORT Viewport = { 0 };
369 m_pImmediateContext->RSGetViewports(&ViewportCount, &Viewport);
371 auto & CameraMatrices = m_pConstants->Get<::Camera>();
375 const auto AngleY = (float)(*_pComponent)[uT(
"fov")].Default(90.0f) *
376 ::alicorn::extension::cpp::math::Constant<float>::DegreeToRadian;
377 const float zNear = (*_pComponent)[uT(
"znear")].Default(0.01f);
378 const float zFar = (*_pComponent)[uT(
"zfar")].Default(200.0f);
380 CameraMatrices.Projection = ::glm::transpose(::glm::perspectiveFovRH(AngleY,
381 (
float)Viewport.Width, (
float)Viewport.Height, zFar, zNear));
386 const Component::Position Look{ *ServiceComponents[0] };
388 const auto GetEye = [&](void) -> ::glm::vec3
391 const float Distance = (*_pComponent)[uT(
"distance")].Default(0.0f);
396 const Component::Position Rot{ *ServiceComponents[1] };
398 ::glm::mat4 Transform = ::glm::identity<::glm::mat4>();
400 Transform = ::glm::translate(Transform,
401 ::glm::vec3{ Look.X, Look.Y, Look.Z });
402 Transform = ::glm::rotate(Transform,
403 Rot.Z, ::glm::vec3{ 0.0f, 0.0f, 1.0f });
404 Transform = ::glm::rotate(Transform,
405 Rot.Y, ::glm::vec3{ 0.0f, 1.0f, 0.0f });
406 Transform = ::glm::rotate(Transform,
407 Rot.X, ::glm::vec3{ 1.0f, 0.0f, 0.0f });
409 return Transform * ::glm::vec4{ Distance + 0.1f, 0.0f, 0.0f, 1.0f };
412 const auto View = ::glm::lookAtRH(
414 ::glm::vec3{ Look.X, Look.Y, Look.Z },
415 ::glm::vec3{ 0.0f, 0.0f, 1.0f });
417 CameraMatrices.View = ::glm::transpose(View);
418 CameraMatrices.ViewInverse = ::glm::transpose(::glm::inverse(View));
419 m_pConstants->Update<::Camera>();
421 (*_pComponent)[uT(
"view")] = CameraMatrices.View;
422 (*_pComponent)[uT(
"projection")] = CameraMatrices.Projection;
425 return (_pComponent->Kind == uT(
"Perspective")) ?
426 CameraPerspective : CameraOptographic;
429class DirectX11::Texture final
432 using Ptr_t = ::std::shared_ptr<Texture>;
435 const ComponentPtr_t m_pDataTexture;
436 const String_t m_Destination;
437 const UINT m_iDestination;
438 const bool m_IsUseMapper;
439 const DXGI_FORMAT m_Format;
440 ComPtr_t<ID3D11Texture2D> m_pTexture;
441 ComPtr_t<ID3D11Texture2D> m_pReadDataTexture;
442 ComPtr_t<ID3D11RenderTargetView> m_pRenderTargetView;
443 ComPtr_t<ID3D11DepthStencilView> m_pDepthStencilView;
444 ComPtr_t<ID3D11ShaderResourceView> m_pShaderResourceView;
448 const ComPtr_t<ID3D11Device> & _pDevice,
452 m_pTexture = (m_Destination != uT(
"depth")) ?
453 MakeRGBATarget(_pDevice, _Width, _Height) :
454 MakeDepthTarget(_pDevice, _Width, _Height);
456 (*m_pDataTexture)[uT(
"width")] =
static_cast<int>(_Width);
457 (*m_pDataTexture)[uT(
"height")] =
static_cast<int>(_Height);
461 m_pReadDataTexture = MakeRGBACopy(_pDevice, _Width, _Height);
466 const ComPtr_t<ID3D11Device> & _pDevice,
467 const ComPtr_t<ID3D11DeviceContext> & _pImmediateContext,
471 const bool _IsMipmapping)
473 m_pTexture = (_IsMipmapping) ?
474 MakeRGBAMipSource(_pDevice, _pImmediateContext, _Width, _Height, _pData) :
475 MakeRGBASource(_pDevice, _pImmediateContext, _Width, _Height, _pData);
478 ComPtr_t<ID3D11Texture2D> MakeRGBACopy(
479 const ComPtr_t<ID3D11Device> & _pDevice,
480 const UINT _Width,
const UINT _Height)
const
482 D3D11_TEXTURE2D_DESC textureDesc = { 0 };
483 textureDesc.Width = _Width;
484 textureDesc.Height = _Height;
485 textureDesc.MipLevels = 1;
486 textureDesc.ArraySize = 1;
487 textureDesc.Format = m_Format;
488 textureDesc.Usage = D3D11_USAGE_STAGING;
489 textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
490 textureDesc.SampleDesc.Count = 1;
492 ComPtr_t<ID3D11Texture2D> pTexture;
493 DX_CHECK _pDevice->CreateTexture2D(&textureDesc,
nullptr, &pTexture);
498 ComPtr_t<ID3D11Texture2D> MakeRGBASource(
499 const ComPtr_t<ID3D11Device> & _pDevice,
500 const ComPtr_t<ID3D11DeviceContext> & _pImmediateContext,
505 D3D11_TEXTURE2D_DESC TextureDesc = { 0 };
506 TextureDesc.Width = _Width;
507 TextureDesc.Height = _Height;
508 TextureDesc.MipLevels = 1;
509 TextureDesc.ArraySize = 1;
510 TextureDesc.Format = m_Format;
511 TextureDesc.Usage = D3D11_USAGE_DEFAULT;
512 TextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
513 TextureDesc.MiscFlags = 0;
514 TextureDesc.SampleDesc.Count = 1;
515 TextureDesc.SampleDesc.Quality = 0;
517 ComPtr_t<ID3D11Texture2D> pTexture2D;
518 DX_CHECK _pDevice->CreateTexture2D(&TextureDesc,
nullptr, &pTexture2D);
520 _pImmediateContext->UpdateSubresource(pTexture2D.Get(), 0, NULL,
521 _pData, _Width * 4, 0);
523 D3D11_SHADER_RESOURCE_VIEW_DESC SrvDesc = { 0 };
524 SrvDesc.Format = TextureDesc.Format;
525 SrvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
526 SrvDesc.Texture2D.MipLevels = TextureDesc.MipLevels;
528 DX_CHECK _pDevice->CreateShaderResourceView(pTexture2D.Get(), &SrvDesc,
529 &m_pShaderResourceView);
534 ComPtr_t<ID3D11Texture2D> MakeRGBAMipSource(
535 const ComPtr_t<ID3D11Device> & _pDevice,
536 const ComPtr_t<ID3D11DeviceContext> & _pImmediateContext,
541 D3D11_TEXTURE2D_DESC TextureDesc = { 0 };
542 TextureDesc.Width = _Width;
543 TextureDesc.Height = _Height;
544 TextureDesc.MipLevels = 0;
545 TextureDesc.ArraySize = 1;
546 TextureDesc.Format = m_Format;
547 TextureDesc.Usage = D3D11_USAGE_DEFAULT;
548 TextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
549 TextureDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
550 TextureDesc.SampleDesc.Count = 1;
551 TextureDesc.SampleDesc.Quality = 0;
553 ComPtr_t<ID3D11Texture2D> pTexture2D;
554 DX_CHECK _pDevice->CreateTexture2D(&TextureDesc,
nullptr, &pTexture2D);
556 _pImmediateContext->UpdateSubresource(pTexture2D.Get(), 0, NULL,
557 _pData, _Width * 4, 0);
559 D3D11_SHADER_RESOURCE_VIEW_DESC SrvDesc = { 0 };
560 SrvDesc.Format = TextureDesc.Format;
561 SrvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
562 SrvDesc.Texture2D.MipLevels =
static_cast<UINT
>(-1);
564 DX_CHECK _pDevice->CreateShaderResourceView(pTexture2D.Get(), &SrvDesc,
565 &m_pShaderResourceView);
567 _pImmediateContext->GenerateMips(m_pShaderResourceView.Get());
573 ComPtr_t<ID3D11Texture2D> MakeRGBATarget(
574 const ComPtr_t<ID3D11Device> & _pDevice,
575 const UINT _Width,
const UINT _Height)
577 D3D11_TEXTURE2D_DESC TextureDesc = { 0 };
578 TextureDesc.Width = _Width;
579 TextureDesc.Height = _Height;
580 TextureDesc.MipLevels = 1;
581 TextureDesc.ArraySize = 1;
582 TextureDesc.Format = m_Format;
583 TextureDesc.Usage = D3D11_USAGE_DEFAULT;
584 TextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
585 TextureDesc.MiscFlags = 0;
586 TextureDesc.SampleDesc.Count = 1;
587 TextureDesc.SampleDesc.Quality = 0;
589 ComPtr_t<ID3D11Texture2D> pTexture2D;
590 DX_CHECK _pDevice->CreateTexture2D(&TextureDesc,
nullptr, &pTexture2D);
592 D3D11_SHADER_RESOURCE_VIEW_DESC SrvDesc = { 0 };
593 SrvDesc.Format = TextureDesc.Format;
594 SrvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
595 SrvDesc.Texture2D.MipLevels = TextureDesc.MipLevels;
597 DX_CHECK _pDevice->CreateShaderResourceView(pTexture2D.Get(), &SrvDesc,
598 &m_pShaderResourceView);
600 D3D11_RENDER_TARGET_VIEW_DESC TargetDesc = { 0 };
601 TargetDesc.Format = TextureDesc.Format;
602 TargetDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
604 ComPtr_t<ID3D11RenderTargetView> pRenderTargetView;
605 DX_CHECK _pDevice->CreateRenderTargetView(pTexture2D.Get(),
606 &TargetDesc, &m_pRenderTargetView);
611 ComPtr_t<ID3D11Texture2D> MakeDepthTarget(
612 const ComPtr_t<ID3D11Device> & _pDevice,
613 const UINT _Width,
const UINT _Height)
615 D3D11_TEXTURE2D_DESC TextureDesc = { 0 };
616 TextureDesc.Width = _Width;
617 TextureDesc.Height = _Height;
618 TextureDesc.MipLevels = 1;
619 TextureDesc.ArraySize = 1;
620 TextureDesc.Format = DXGI_FORMAT_R24G8_TYPELESS;
621 TextureDesc.Usage = D3D11_USAGE_DEFAULT;
622 TextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
623 TextureDesc.MiscFlags = 0;
624 TextureDesc.SampleDesc.Count = 1;
625 TextureDesc.SampleDesc.Quality = 0;
627 ComPtr_t<ID3D11Texture2D> pTexture2D;
628 DX_CHECK _pDevice->CreateTexture2D(&TextureDesc,
nullptr, &pTexture2D);
630 D3D11_SHADER_RESOURCE_VIEW_DESC SrvDesc = { 0 };
631 SrvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
632 SrvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
633 SrvDesc.Texture2D.MipLevels = TextureDesc.MipLevels;
635 DX_CHECK _pDevice->CreateShaderResourceView(pTexture2D.Get(), &SrvDesc,
636 &m_pShaderResourceView);
638 D3D11_DEPTH_STENCIL_VIEW_DESC Desc = { 0 };
639 Desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
640 Desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
642 ComPtr_t<ID3D11DepthStencilView> pDepthStencilView;
643 DX_CHECK _pDevice->CreateDepthStencilView(pTexture2D.Get(),
644 &Desc, &m_pDepthStencilView);
650 static UINT GetDestinationIndex(
const ComponentPtr_t & _pData)
652 const int Index = (*_pData)[uT(
"index")].Default(-1);
653 if (Index >= 0)
return static_cast<UINT
>(Index);
655 static const ::std::vector<String_t> Destinations =
665 const String_t Destination =
666 (*_pData)[uT(
"destination")].Default(uT(
"albedo"));
668 const auto itDestination =
669 ::std::find(Destinations.cbegin(), Destinations.cend(), Destination);
670 if (itDestination == Destinations.cend())
672 throw STD_EXCEPTION <<
"Unexpected destination texture: " << Destination;
675 return static_cast<UINT
>(
676 ::std::distance(Destinations.cbegin(), itDestination));
679 static DXGI_FORMAT GetFormat(
const ComponentPtr_t & _pData)
681 const int Capacity = (*_pData)[uT(
"capacity")].Default(8);
684 (Capacity == 32) ? DXGI_FORMAT_R32G32B32A32_FLOAT :
685 (Capacity == 16) ? DXGI_FORMAT_R16G16B16A16_FLOAT :
686 DXGI_FORMAT_R8G8B8A8_UNORM;
690 explicit Texture(
const ComponentPtr_t & _pDataTexture) :
691 m_pDataTexture{ _pDataTexture },
692 m_Destination{ (*_pDataTexture)[uT(
"destination")].Default(uT(
"albedo")) },
693 m_iDestination{ GetDestinationIndex(_pDataTexture) },
694 m_IsUseMapper{ (*_pDataTexture)[uT(
"mapper")].IsType<const cbBufferMap_t<const void> &>() },
695 m_Format{ GetFormat(_pDataTexture) }
699 Texture(
const Texture &) =
delete;
700 Texture(Texture &&) =
delete;
701 Texture & operator= (
const Texture &) =
delete;
702 Texture & operator= (Texture &&) =
delete;
703 ~Texture(
void) =
default;
708 using Size_t = ::std::tuple<UINT, UINT>;
709 using fnBkSurfaceSize_t = ::std::function<Size_t(
void)>;
711 const auto pBkSurface = _pComponent;
713 const fnBkSurfaceSize_t GetBkSurfaceSize = [=](void)
715 UINT ViewportCount = 1;
716 D3D11_VIEWPORT Viewport = { 0 };
717 m_pImmediateContext->RSGetViewports(&ViewportCount, &Viewport);
719 const int Width =
static_cast<int>(Viewport.Width);
720 const int Height =
static_cast<int>(Viewport.Height);
722 (*pBkSurface)[uT(
"width")] = Width;
723 (*pBkSurface)[uT(
"height")] = Height;
725 return Size_t{
static_cast<UINT
>(Width),
static_cast<UINT
>(Height) };
728 const auto [Width, Height] = GetBkSurfaceSize();
730 const auto pBkSurfaceTextures =
731 ::std::make_shared<::std::vector<Texture::Ptr_t>>();
733 const auto DoDataTexture = [&](
const ComponentPtr_t & _pDataTexture)
735 auto pTexture = ::std::make_shared<Texture>(_pDataTexture);
736 pTexture->MakeTarget(m_pDevice, Width, Height);
742 (*_pDataTexture)[uT(
"entity")] = ::std::weak_ptr<Texture>(pTexture);
744 pBkSurfaceTextures->push_back(pTexture);
747 CapturingServiceComponent::Process(_pComponent,
749 { uT(
"Texture"), DoDataTexture },
754 const auto [Width, Height] = GetBkSurfaceSize();
757 TODO(
"Хранить размеры текстур в них самих и пересоздавать при расхождении размеров");
761 if (m_IsResizeWindow)
763 for (
auto & pTexture : *pBkSurfaceTextures)
765 pTexture->MakeTarget(m_pDevice, Width, Height);
769 m_CurrentRenderTargets.clear();
771 for (
auto & pTexture : *pBkSurfaceTextures)
773 if (pTexture->m_pRenderTargetView)
775 m_CurrentRenderTargets.push_back(pTexture->m_pRenderTargetView.Get());
778 if (pTexture->m_pDepthStencilView)
780 m_pCurrentDepthStencilView = pTexture->m_pDepthStencilView;
783 static ID3D11ShaderResourceView * NullResourceView[1] = {
nullptr };
784 m_pImmediateContext->PSSetShaderResources(
785 pTexture->m_iDestination, 1, NullResourceView);
788 if (m_CurrentRenderTargets.empty())
790 m_CurrentRenderTargets = {
nullptr };
793 m_pImmediateContext->OMSetRenderTargets(
794 static_cast<UINT
>(m_CurrentRenderTargets.size()),
795 &m_CurrentRenderTargets[0],
nullptr);
799auto DirectX11::CreateState(
const ComponentPtr_t & _pComponent) -> Render_t
801 const auto CreateSamplerState = [&](void)
803 D3D11_SAMPLER_DESC SamplerDesc = { 0 };
804 SamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
805 SamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
806 SamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
807 SamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
808 SamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
809 SamplerDesc.MinLOD = 0;
810 SamplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
812 ComPtr_t<ID3D11SamplerState> pSamplerState;
813 DX_CHECK m_pDevice->CreateSamplerState(&SamplerDesc, &pSamplerState);
817 m_pImmediateContext->PSSetSamplers(0, 1, pSamplerState.GetAddressOf());
821 const auto CreateScissorState = [&](void)
823 const Component::Scissor ScissorData{ *_pComponent };
825 D3D11_RASTERIZER_DESC rasterDesc = { 0 };
826 rasterDesc.FillMode = D3D11_FILL_SOLID;
827 rasterDesc.CullMode = D3D11_CULL_BACK;
828 rasterDesc.FrontCounterClockwise = TRUE;
829 rasterDesc.ScissorEnable = (ScissorData.IsEnabled) ? TRUE : FALSE;
831 ComPtr_t<ID3D11RasterizerState> pScissor;
832 DX_CHECK m_pDevice->CreateRasterizerState(&rasterDesc, &pScissor);
834 const auto pScissorRect = CapturingServiceComponent::Get(_pComponent,
835 { {uT(
"Rect"), _pComponent} })[0];
837 Render_t ScissorEnabled = [=](void)
839 const Component::Scissor ScissorRect{ *pScissorRect };
841 D3D11_RECT Rect = { 0 };
842 Rect.left = ScissorRect.Left;
843 Rect.right = ScissorRect.Right;
844 Rect.top = ScissorRect.Top;
845 Rect.bottom = ScissorRect.Bottom;
847 m_pImmediateContext->RSSetScissorRects(1, &Rect);
848 m_pImmediateContext->RSSetState(pScissor.Get());
851 Render_t ScissorDisabled = [=](void)
853 m_pImmediateContext->RSSetState(pScissor.Get());
856 return (ScissorData.IsEnabled) ? ScissorEnabled : ScissorDisabled;
859 const auto CreateDepthState = [&](void)
861 return GetDepthState(
862 (*_pComponent)[uT(
"enabled")].Default(
false),
863 (*_pComponent)[uT(
"clear")].Default(
false),
864 (*_pComponent)[uT(
"overwrite")].Default(
true));
867 const auto CreateClearState = [&](void)
869 const auto ARGBtoFloat4 = [](
const uint32_t _HexColor)
871 return ::std::vector<FLOAT>
873 ((_HexColor & 0x00FF0000) >> 16) / 255.0f,
874 ((_HexColor & 0x0000FF00) >> 8) / 255.0f,
875 ((_HexColor & 0x000000FF) >> 0) / 255.0f,
876 ((_HexColor & 0xFF000000) >> 24) / 255.0f,
879 const auto BackgroundColor =
880 ARGBtoFloat4((*_pComponent)[uT(
"color")].Default(0xFF000000));
884 for (
auto * pRenderTargetView : m_CurrentRenderTargets)
886 m_pImmediateContext->ClearRenderTargetView(
887 pRenderTargetView, BackgroundColor.data());
892 const auto CreateAlphaTestState = [&](void)
897 ::std::map<String_t, ::std::function<Render_t(
void)>> Creators =
899 { uT(
"Blend"), [&](void) {
return CreateBlendState(
true); } },
900 { uT(
"Sampler"), CreateSamplerState },
901 { uT(
"Scissor"), CreateScissorState },
902 { uT(
"Depth"), CreateDepthState },
903 { uT(
"Clear"), CreateClearState },
904 { uT(
"AlphaTest"), CreateAlphaTestState },
907 return Creators[_pComponent->Kind]();
910auto DirectX11::CreateTexture(
const ComponentPtr_t & _pComponent) -> Render_t
912 using BufferMapper_t = cbBufferMap_t<const void>;
914 const auto pTextureData = CapturingServiceComponent::Get(_pComponent,
915 { { uT(
"Texture"), _pComponent } })[0];
917 const Component::Texture TextureData{ *pTextureData, uT(
"albedo") };
919 Texture::Ptr_t pTexture;
921 ::std::weak_ptr<Texture> wpTexture = (*pTextureData)[uT(
"entity")]
922 .Default(::std::weak_ptr<Texture>{});
923 if (wpTexture.lock() ==
nullptr)
925 pTexture = ::std::make_shared<Texture>(pTextureData);
926 pTexture->MakeSource(m_pDevice, m_pImmediateContext,
927 static_cast<UINT
>(TextureData.Width),
static_cast<UINT
>(TextureData.Height),
928 TextureData.Data.data(), TextureData.IsUsingMipmapping);
932 pTexture = wpTexture.lock();
933 (*pTextureData)[uT(
"entity")] = ::std::weak_ptr<Texture>{};
936 if (pTexture->m_pReadDataTexture ==
nullptr)
940 m_pImmediateContext->PSSetShaderResources(pTexture->m_iDestination, 1,
941 pTexture->m_pShaderResourceView.GetAddressOf());
945 const BufferMapper_t cbBufferMapper =
946 (*pTextureData)[uT(
"mapper")].Default(BufferMapper_t{});
950 if (cbBufferMapper(
nullptr))
952 m_pImmediateContext->CopyResource(
953 pTexture->m_pReadDataTexture.Get(), pTexture->m_pTexture.Get());
955 D3D11_MAPPED_SUBRESOURCE Resource = { 0 };
956 DX_CHECK m_pImmediateContext->Map(pTexture->m_pReadDataTexture.Get(), 0,
957 D3D11_MAP_READ, 0, &Resource);
958 cbBufferMapper(Resource.pData);
959 m_pImmediateContext->Unmap(pTexture->m_pReadDataTexture.Get(), 0);
962 m_pImmediateContext->PSSetShaderResources(pTexture->m_iDestination, 1,
963 pTexture->m_pShaderResourceView.GetAddressOf());
967auto DirectX11::CreateTextureArray(
const ComponentPtr_t & _pComponent) -> Render_t
969 using Buffers_t = ::std::vector<::alicorn::extension::std::memory::BinaryData_t>;
971 const auto pTextureArrayData = CapturingServiceComponent::Get(_pComponent,
972 { { uT(
"TextureArray"), _pComponent } })[0];
974 const Buffers_t ArrayData =
975 ::std::move((Buffers_t &)(*pTextureArrayData)[uT(
"content")]);
977 const Component::Texture TextureArrayData{ *pTextureArrayData, uT(
"albedo") };
979 ::std::vector<::std::shared_ptr<Texture>> Textures;
980 ::std::vector<ID3D11ShaderResourceView *> ShaderResourceViews;
982 for (
const auto & TextureData : ArrayData)
984 auto pTexture = ::std::make_shared<Texture>(pTextureArrayData);
985 pTexture->MakeSource(m_pDevice, m_pImmediateContext,
986 static_cast<UINT
>(TextureArrayData.Width),
987 static_cast<UINT
>(TextureArrayData.Height),
988 ::std::data(TextureData), TextureArrayData.IsUsingMipmapping);
990 Textures.push_back(pTexture);
991 ShaderResourceViews.push_back(pTexture->m_pShaderResourceView.Get());
996 m_pImmediateContext->PSSetShaderResources(
997 Textures[0]->m_iDestination,
998 ::std::size(ShaderResourceViews),
999 ::std::data(ShaderResourceViews));
1003auto DirectX11::CreateShader(
const ComponentPtr_t & _pComponent) -> Render_t
1005 using namespace ::alicorn::extension::std;
1007 const auto pShaderDataComponent = CapturingServiceComponent::Get(_pComponent,
1008 { { uT(
"Shader"), _pComponent } })[0];
1010 const Component::Shader ShaderData{ *pShaderDataComponent, ::Default };
1012 ::std::string Define =
1013 "#define COVELLITE_SHADER_DESKTOP\r\n"
1014 "#define COVELLITE_SHADER_HLSL\r\n"
1015 "#define COVELLITE_SHADER_VERTEX\r\n";
1016 const auto HeaderShaderText = ::Predefined + ::Data +
1017 ShaderData.GetInstanceInput(::Input);
1018 auto ShaderText = ShaderData.Data;
1019 ::std::string Entry = ShaderData.Entry;
1021 if (ShaderData.Kind == uT(
"Pixel"))
1024 "#define COVELLITE_SHADER_DESKTOP\r\n"
1025 "#define COVELLITE_SHADER_HLSL\r\n"
1026 "#define COVELLITE_SHADER_PIXEL\r\n";
1028 if (ShaderData.ReturnType ==
"float4" ||
1029 ShaderData.ReturnType ==
"vec4")
1031 ShaderText += DirectX::Shader::Convert(
1032 "float4 psMain(Pixel _Value) : SV_Target\r\n"
1034 " return " + Entry +
"(_Value);\r\n"
1040 const auto pCompiledShader = DirectX::Shader::Compile(
1041 DirectX::Shader::Convert(Define) + HeaderShaderText, ShaderText,
1042 Entry.c_str(), DirectX::Shader::GetVersion(ShaderData.Kind).c_str());
1044 const auto VertexShader =
1045 [&](const ::std::vector<D3D11_INPUT_ELEMENT_DESC> & _LayoutDesc)
1047 const auto *
const pData = pCompiledShader->GetBufferPointer();
1048 const auto DataSize = pCompiledShader->GetBufferSize();
1050 ComPtr_t<ID3D11InputLayout> pVertexLayout;
1051 DX_CHECK m_pDevice->CreateInputLayout(
1052 _LayoutDesc.data(),
static_cast<UINT
>(_LayoutDesc.size()),
1056 ComPtr_t<ID3D11VertexShader> pVertexShader;
1057 DX_CHECK m_pDevice->CreateVertexShader(
1059 NULL, &pVertexShader);
1063 m_pImmediateContext->IASetInputLayout(pVertexLayout.Get());
1064 m_pImmediateContext->VSSetShader(pVertexShader.Get(), NULL, 0);
1068 if (ShaderData.Kind == uT(
"Polygon"))
1070 return VertexShader(
1072 {
"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1073 {
"COLOR", 0, DXGI_FORMAT_R32_UINT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1074 {
"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1077 else if (ShaderData.Kind == uT(
"Polyhedron"))
1079 return VertexShader(
1081 {
"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1082 {
"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1083 {
"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1086 else if (ShaderData.Kind == uT(
"Vertex"))
1088 ::std::vector<D3D11_INPUT_ELEMENT_DESC> LayoutDesc =
1090 {
"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1091 {
"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1092 {
"NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1095 for (UINT i = 0; i < static_cast<UINT>(ShaderData.Instance.size()); i++)
1097 const auto Type = ShaderData.Instance[i];
1099 (Type == uT(
"f")) ? DXGI_FORMAT_R32G32B32A32_FLOAT :
1100 (Type == uT(
"i")) ? DXGI_FORMAT_R32G32B32A32_SINT :
1101 DXGI_FORMAT_UNKNOWN;
1102 const auto Size = i * 4 *
static_cast<UINT
>(
1103 (Type == uT(
"f")) ?
sizeof(float) :
1105 (Type == uT(
"i")) ?
sizeof(int) :
1108 LayoutDesc.push_back(
1110 "TEXCOORD", i + 1, Format, 1, Size, D3D11_INPUT_PER_INSTANCE_DATA, 1
1114 return VertexShader(LayoutDesc);
1117 ComPtr_t<ID3D11PixelShader> pPixelShader;
1118 DX_CHECK m_pDevice->CreatePixelShader(
1119 pCompiledShader->GetBufferPointer(), pCompiledShader->GetBufferSize(),
1120 NULL, &pPixelShader);
1124 m_pImmediateContext->PSSetShader(pPixelShader.Get(), NULL, 0);
1128auto DirectX11::CreateBuffer(
const ComponentPtr_t & _pComponent) -> Render_t
1130 const auto pBufferData = CapturingServiceComponent::Get(_pComponent,
1131 { { uT(
"Buffer"), _pComponent } })[0];
1133 if ((*pBufferData)[uT(
"content")].IsType<Buffer_t<::covellite::api::Vertex>>())
1135 using BufferMapper_t = cbBufferMap_t<::covellite::api::Vertex>;
1137 const Component::Buffer<::covellite::api::Vertex> VertexData{ *pBufferData };
1139 const BufferMapper_t & cbBufferMapper =
1140 (*_pComponent)[uT(
"mapper")].Default(BufferMapper_t{});
1142 auto pBuffer = Buffer::Create(m_pDevice, (cbBufferMapper !=
nullptr),
1143 VertexData.Data.data(), VertexData.Data.size());
1145 const Render_t StaticRender = [=](void)
1148 constexpr UINT Offset = 0;
1149 m_pImmediateContext->IASetVertexBuffers(0, 1,
1150 pBuffer.GetAddressOf(), &Stride, &Offset);
1153 const Render_t DynamicRender = [=](void)
1155 const auto IsDirty = cbBufferMapper(
nullptr);
1158 D3D11_MAPPED_SUBRESOURCE Resource = { 0 };
1159 DX_CHECK m_pImmediateContext->Map(pBuffer.Get(), 0,
1160 D3D11_MAP_WRITE_NO_OVERWRITE, 0, &Resource);
1162 m_pImmediateContext->Unmap(pBuffer.Get(), 0);
1168 return (cbBufferMapper ==
nullptr) ? StaticRender : DynamicRender;
1170 else if ((*_pComponent)[uT(
"mapper")].IsType<
const cbBufferMap_t<void> &>())
1172 using BufferMap_t = cbBufferMap_t<void>;
1174 const BufferMap_t cbBufferMapper =
1175 (*_pComponent)[uT(
"mapper")].Default(BufferMap_t{});
1176 if (!cbBufferMapper)
1178 throw STD_EXCEPTION <<
"Unexpected empty mapper: " << _pComponent->Id;
1181 const ::std::size_t BufferSize =
1182 (*pBufferData)[uT(
"size")].Default((::std::size_t)0);
1183 if (BufferSize == 0)
1185 throw STD_EXCEPTION <<
"Unexpected zero size: " << _pComponent->Id;
1189 ::std::make_shared<BinaryData_t>(BufferSize, (uint8_t)0x00);
1190 const auto pBuffer = Buffer::Create(
1191 m_pDevice,
false, pData->data(), pData->size());
1192 constexpr auto BufferIndex =
1193 Buffer::Support<BinaryData_t::value_type>::Index;
1198 cbBufferMapper(pData->data());
1202 m_pImmediateContext->VSSetConstantBuffers(
1203 BufferIndex, 1, pBuffer.GetAddressOf());
1204 m_pImmediateContext->PSSetConstantBuffers(
1205 BufferIndex, 1, pBuffer.GetAddressOf());
1207 m_pImmediateContext->UpdateSubresource(
1208 pBuffer.Get(), 0, NULL, pData->data(), 0, 0);
1212 throw STD_EXCEPTION <<
"Unexpected buffer type: " << _pComponent->Id;
1215auto DirectX11::CreateTransform(
const ComponentPtr_t & _pComponent) -> Render_t
1217 const auto BuildTransformMatrix =
1218 (_pComponent->Kind == uT(
"Unknown")) ? CreateDefaultTransformRender<::Object>(_pComponent) :
1219 (_pComponent->Kind == uT(
"Static")) ? CreateStaticTransformRender<::Object>(_pComponent) :
1220 (_pComponent->Kind == uT(
"Billboard")) ? CreateBillboardTransformRender<::Camera, ::Object>(_pComponent) :
1221 throw STD_EXCEPTION <<
"Unexpected transform component: " <<
1222 " [id=" << _pComponent->Id <<
", kind=" << _pComponent->Kind <<
"].";
1226 BuildTransformMatrix();
1227 m_pConstants->Update<::Object>();
1231auto DirectX11::CreatePresentBuffer(
const ComponentPtr_t & _pComponent) ->Render_t
1233 using BufferMapperMaxSize_t = ::std::function<bool(
void *)>;
1234 using BufferMapperChangeSize_t = ::std::function<bool(
void *, ::std::size_t &)>;
1236 ComponentPtr_t pIndexBufferData = _pComponent;
1237 ComponentPtr_t pInstanceBufferData =
nullptr;
1239 const auto SaveBuffer = [&](
const ComponentPtr_t & _pBufferData)
1241 if ((*_pBufferData)[uT(
"content")].IsType<Buffer_t<int>>())
1243 pIndexBufferData = _pBufferData;
1245 else if ((*_pBufferData)[uT(
"mapper")].IsType<const BufferMapperMaxSize_t &>())
1247 pInstanceBufferData = _pBufferData;
1249 else if ((*_pBufferData)[uT(
"mapper")].IsType<const BufferMapperChangeSize_t &>())
1251 pInstanceBufferData = _pBufferData;
1255 throw STD_EXCEPTION <<
"Unexpected buffer data component.";
1259 CapturingServiceComponent::Process(_pComponent,
1261 { uT(
"Buffer"), SaveBuffer },
1264 const Component::Buffer<int> IndexBufferData{ *pIndexBufferData };
1266 const auto pIndexBuffer = Buffer::Create(m_pDevice,
false,
1267 IndexBufferData.Data.data(), IndexBufferData.Data.size());
1268 const auto IndexCount =
static_cast<DWORD
>(IndexBufferData.Data.size());
1270 if (pInstanceBufferData ==
nullptr)
1274 m_pImmediateContext->IASetIndexBuffer(
1275 pIndexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
1276 m_pImmediateContext->IASetPrimitiveTopology(
1277 D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
1278 m_pImmediateContext->DrawIndexed(IndexCount, 0, 0);
1282 const ::std::size_t BufferSize = (*pInstanceBufferData)[uT(
"size")];
1283 if (BufferSize % 16 != 0)
1285 throw STD_EXCEPTION << _pComponent->Id <<
": size % 16 != 0";
1288 const ::std::size_t MaxInstanceCount = (*pInstanceBufferData)[uT(
"count")];
1289 if (BufferSize % MaxInstanceCount != 0)
1291 throw STD_EXCEPTION << _pComponent->Id <<
": size % count != 0";
1294 const auto Stride =
static_cast<UINT
>(BufferSize / MaxInstanceCount);
1296 const auto pInstanceBuffer =
1297 Buffer::Create<int8_t>(m_pDevice,
true,
nullptr, BufferSize);
1299 if ((*pInstanceBufferData)[uT(
"mapper")].IsType<BufferMapperMaxSize_t>())
1301 const BufferMapperMaxSize_t cbBufferMapper =
1302 (*pInstanceBufferData)[uT(
"mapper")];
1306 const auto IsDirty = cbBufferMapper(
nullptr);
1309 D3D11_MAPPED_SUBRESOURCE Resource = { 0 };
1310 DX_CHECK m_pImmediateContext->Map(pInstanceBuffer.Get(), 0,
1311 D3D11_MAP_WRITE_NO_OVERWRITE, 0, &Resource);
1312 cbBufferMapper(Resource.pData);
1313 m_pImmediateContext->Unmap(pInstanceBuffer.Get(), 0);
1316 constexpr UINT Offset = 0;
1317 m_pImmediateContext->IASetVertexBuffers(
1318 1, 1, pInstanceBuffer.GetAddressOf(), &Stride, &Offset);
1319 m_pImmediateContext->IASetIndexBuffer(
1320 pIndexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
1321 m_pImmediateContext->IASetPrimitiveTopology(
1322 D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
1323 m_pImmediateContext->DrawIndexedInstanced(
1324 IndexCount,
static_cast<UINT
>(MaxInstanceCount), 0, 0, 0);
1328 const BufferMapperChangeSize_t cbBufferMapper =
1329 (*pInstanceBufferData)[uT(
"mapper")];
1333 auto InstanceCount = MaxInstanceCount;
1335 const auto IsDirty = cbBufferMapper(
nullptr, InstanceCount);
1338 D3D11_MAPPED_SUBRESOURCE Resource = { 0 };
1339 DX_CHECK m_pImmediateContext->Map(pInstanceBuffer.Get(), 0,
1340 D3D11_MAP_WRITE_NO_OVERWRITE, 0, &Resource);
1341 cbBufferMapper(Resource.pData, InstanceCount);
1342 m_pImmediateContext->Unmap(pInstanceBuffer.Get(), 0);
1345 InstanceCount = ::std::min(InstanceCount, MaxInstanceCount);
1347 constexpr UINT Offset = 0;
1348 m_pImmediateContext->IASetVertexBuffers(
1349 1, 1, pInstanceBuffer.GetAddressOf(), &Stride, &Offset);
1350 m_pImmediateContext->IASetIndexBuffer(
1351 pIndexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
1352 m_pImmediateContext->IASetPrimitiveTopology(
1353 D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
1354 m_pImmediateContext->DrawIndexedInstanced(
1355 IndexCount,
static_cast<UINT
>(InstanceCount), 0, 0, 0);
1359auto DirectX11::CreateBlendState(
bool _IsEnabled) -> Render_t
1361 ComPtr_t<ID3D11BlendState> pBlendState;
1365 D3D11_BLEND_DESC BlendDesc = { 0 };
1366 BlendDesc.AlphaToCoverageEnable = FALSE;
1367 BlendDesc.IndependentBlendEnable = FALSE;
1369 for (
auto & RenderTarget : BlendDesc.RenderTarget)
1371 RenderTarget.BlendEnable = TRUE;
1372 RenderTarget.SrcBlend = D3D11_BLEND_SRC_ALPHA;
1373 RenderTarget.DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
1374 RenderTarget.BlendOp = D3D11_BLEND_OP_ADD;
1375 RenderTarget.SrcBlendAlpha = D3D11_BLEND_ONE;
1376 RenderTarget.DestBlendAlpha = D3D11_BLEND_ZERO;
1377 RenderTarget.BlendOpAlpha = D3D11_BLEND_OP_ADD;
1378 RenderTarget.RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
1381 DX_CHECK m_pDevice->CreateBlendState(&BlendDesc, &pBlendState);
1386 const FLOAT BlendFactor[] = { 0.0f, 0.0f, 0.0f, 0.0f };
1387 m_pImmediateContext->OMSetBlendState(
1388 pBlendState.Get(), BlendFactor, 0xFFFFFFFF);
1393 const bool _IsEnabled,
1394 const bool _IsClear,
1395 const bool _IsOverwrite) -> Render_t
1401 m_pImmediateContext->OMSetRenderTargets(
1402 static_cast<UINT
>(m_CurrentRenderTargets.size()),
1403 &m_CurrentRenderTargets[0],
nullptr);
1407 D3D11_DEPTH_STENCIL_DESC DeptStencilDesc = { 0 };
1408 DeptStencilDesc.DepthEnable =
true;
1409 DeptStencilDesc.DepthWriteMask = _IsOverwrite ?
1410 D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
1411 DeptStencilDesc.DepthFunc = D3D11_COMPARISON_GREATER;
1412 DeptStencilDesc.StencilEnable =
false;
1414 ComPtr_t<ID3D11DepthStencilState> pDSState;
1415 DX_CHECK m_pDevice->CreateDepthStencilState(&DeptStencilDesc, &pDSState);
1417 Render_t RenderDepthEnabled = [=](void)
1420 TODO(
"Тест того, что если BkSurface не устанавливает буфер глубины, то используется буфер глубины экрана");
1422 m_pImmediateContext->OMSetDepthStencilState(pDSState.Get(), 1);
1423 m_pImmediateContext->OMSetRenderTargets(
1424 static_cast<UINT
>(m_CurrentRenderTargets.size()),
1425 &m_CurrentRenderTargets[0], m_pCurrentDepthStencilView.Get());
1428 Render_t RenderDepthClear = [=](void)
1431 TODO(
"Тест того, что если BkSurface не устанавливает буфер глубины, то используется буфер глубины экрана");
1433 m_pImmediateContext->OMSetDepthStencilState(pDSState.Get(), 1);
1434 m_pImmediateContext->OMSetRenderTargets(
1435 static_cast<UINT
>(m_CurrentRenderTargets.size()),
1436 &m_CurrentRenderTargets[0], m_pCurrentDepthStencilView.Get());
1437 m_pImmediateContext->ClearDepthStencilView(m_pCurrentDepthStencilView.Get(),
1438 D3D11_CLEAR_DEPTH, 0.0f, 0);
1441 return _IsClear ? RenderDepthClear : RenderDepthEnabled;
1444template<
class TConstantBuffer>
1445auto DirectX11::CreateDefaultTransformRender(
1446 const ComponentPtr_t & _pComponent) -> Render_t
1448 ::std::deque<Render_t> PreRenders;
1450 auto CreatePosition = [&](
const ComponentPtr_t & _pPosition)
1452 PreRenders.push_front([=](
void)
1454 auto & World = m_pConstants->Get<TConstantBuffer>().World;
1456 const Component::Position Position{ *_pPosition };
1458 World = ::glm::translate(World,
1459 ::glm::vec3{ Position.X, Position.Y, Position.Z });
1463 auto CreateRotation = [&](
const ComponentPtr_t & _pRotation)
1465 PreRenders.push_front([=](
void)
1467 auto & World = m_pConstants->Get<::Object>().World;
1469 const Component::Rotation Rotation{ *_pRotation };
1471 World = ::glm::rotate(World, Rotation.Z, ::glm::vec3{ 0.0f, 0.0f, 1.0f });
1472 World = ::glm::rotate(World, Rotation.Y, ::glm::vec3{ 0.0f, 1.0f, 0.0f });
1473 World = ::glm::rotate(World, Rotation.X, ::glm::vec3{ 1.0f, 0.0f, 0.0f });
1477 auto CreateScale = [&](
const ComponentPtr_t & _pScale)
1479 PreRenders.push_front([=](
void)
1481 auto & World = m_pConstants->Get<::Object>().World;
1483 const Component::Scale Scale{ *_pScale };
1485 World = ::glm::scale(World, ::glm::vec3{ Scale.X, Scale.Y, Scale.Z });
1489 PreRenders.push_front([=](
void)
1491 m_pConstants->Get<::Object>().World =
1492 ::glm::transpose(m_pConstants->Get<::Object>().World);
1495 CapturingServiceComponent::Process(_pComponent,
1497 { uT(
"Position"), CreatePosition },
1498 { uT(
"Rotation"), CreateRotation },
1499 { uT(
"Scale"), CreateScale },
1502 PreRenders.push_front([=](
void)
1504 m_pConstants->Get<::Object>().World = ::glm::identity<::glm::mat4>();
1507 return [PreRenders](void)
1509 for (
auto & Render : PreRenders) Render();
1513template<
class TConstantBuffer>
1514auto DirectX11::CreateStaticTransformRender(
const ComponentPtr_t & _pComponent) -> Render_t
1516 CreateDefaultTransformRender<TConstantBuffer>(_pComponent)();
1517 const auto World = m_pConstants->Get<TConstantBuffer>().World;
1521 m_pConstants->Get<TConstantBuffer>().World = World;
1525template<
class TCamera,
class TConstantBuffer>
1526auto DirectX11::CreateBillboardTransformRender(
const ComponentPtr_t & _pComponent) -> Render_t
1528 ::std::deque<Render_t> PreRenders;
1530 auto CreatePosition = [&](
const ComponentPtr_t & _pPosition)
1532 PreRenders.push_front([=](
void)
1534 auto & World = m_pConstants->Get<TConstantBuffer>().World;
1536 const Component::Position Position{ *_pPosition };
1538 World = ::glm::translate(World,
1539 ::glm::vec3{ Position.X, Position.Y, Position.Z });
1543 PreRenders.push_front([=](
void)
1545 m_pConstants->Get<TConstantBuffer>().World =
1546 ::glm::transpose(m_pConstants->Get<TConstantBuffer>().World);
1549 CapturingServiceComponent::Process(_pComponent,
1550 { { uT(
"Position"), CreatePosition } });
1552 PreRenders.push_front([=](
void)
1554 auto & World = m_pConstants->Get<TConstantBuffer>().World;
1557 World = m_pConstants->Get<::Camera>().View;
1568 return [PreRenders](void)
1570 for (
auto & Render : PreRenders) Render();
#define DX_CHECK
Класс входит в проект Covellite.Api Макрос проверок вызова функций DirectX.
Definition DxCheck.hpp:59
static ComponentPtr_t Make(const SourceParams_t &)
Функция создания объектов компонентов.
Definition Component.inl:29
Render_t GetDepthState(const bool, const bool, const bool)
Definition DirectX11.cpp:1392
Render_t CreateBkSurface(const ComponentPtr_t &) override
Definition DirectX11.cpp:706
Класс входит в проект Covellite.Api Класс формата вертексного буфера.
Definition Vertex.hpp:34