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"
30class DirectX11::Buffer final
37 static constexpr UINT Flag = D3D11_BIND_VERTEX_BUFFER;
44 static constexpr UINT Flag = D3D11_BIND_CONSTANT_BUFFER;
45 static constexpr UINT Index = TIndex;
49 class Support<::Camera> :
public Constant<COVELLITE_BUFFER_INDEX_CAMERA> { };
52 class Support<::Object> :
public Constant<COVELLITE_BUFFER_INDEX_OBJECT> { };
55 class Support<uint8_t> :
public Constant<COVELLITE_BUFFER_INDEX_USER> { };
61 static constexpr UINT Flag = D3D11_BIND_INDEX_BUFFER;
66 static ComPtr_t<ID3D11Buffer> Create(
67 const ComPtr_t<ID3D11Device> & _pDevice,
68 const bool _IsDynamic,
72 D3D11_BUFFER_DESC Desc = { 0 };
73 Desc.Usage = _IsDynamic ? D3D11_USAGE_DYNAMIC : D3D11_USAGE_DEFAULT;
74 Desc.CPUAccessFlags =
static_cast<UINT
>(_IsDynamic ? D3D11_CPU_ACCESS_WRITE : 0);
75 Desc.ByteWidth =
static_cast<decltype(Desc.ByteWidth)
>(
sizeof(T) * _Count);
76 Desc.BindFlags = Support<T>::Flag;
78 D3D11_SUBRESOURCE_DATA InitData = { 0 };
79 InitData.pSysMem = _pData;
81 const auto *
const pInitData = (_pData ==
nullptr) ? nullptr : &InitData;
83 ComPtr_t<ID3D11Buffer> pBuffer;
84 DX_CHECK _pDevice->CreateBuffer(&Desc, pInitData, &pBuffer);
89 static ComPtr_t<ID3D11Buffer> Create(
90 const ComPtr_t<ID3D11Device> & _pDevice,
91 const ComPtr_t<ID3D11DeviceContext> & _pImmediateContext,
94 const auto pResult = Create(_pDevice,
false, _pData, 1);
96 constexpr auto Index = Support<T>::Index;
97 _pImmediateContext->VSSetConstantBuffers(Index, 1, pResult.GetAddressOf());
98 _pImmediateContext->PSSetConstantBuffers(Index, 1, pResult.GetAddressOf());
105class DirectX11::ConstantBuffer final :
106 public Constants::Data<T>
109 void Update(
void)
const override
111 m_pImmediateContext->UpdateSubresource(
112 m_pBuffer.Get(), 0, NULL, &m_Data, 0, 0);
116 const ComPtr_t<ID3D11DeviceContext> m_pImmediateContext;
117 const ComPtr_t<ID3D11Buffer> m_pBuffer;
121 const ComPtr_t<ID3D11Device> & _pDevice,
122 const ComPtr_t<ID3D11DeviceContext> & _pImmediateContext) :
123 m_pImmediateContext{ _pImmediateContext },
124 m_pBuffer{ Buffer::Create(_pDevice, _pImmediateContext, &m_Data) }
131DirectX11::DirectX11(
const Data_t & _Data)
133 CreateDeviceAndSwapChain(_Data);
135 MakeConstants<ConstantBuffer>(m_pDevice, m_pImmediateContext);
138DirectX11::~DirectX11(
void) =
default;
140DirectX11::String_t DirectX11::GetUsingApi(
void)
const
142 return uT(
"DirectX 11");
145void DirectX11::PresentFrame(
void)
147 m_pSwapChain->Present(0, 0);
149 GraphicApi::PresentFrame();
152void DirectX11::ResizeWindow(
const Rect & _ClientRect)
154 m_IsResizeWindow =
true;
155 SetRenderTargetSize(
static_cast<UINT
>(_ClientRect.Width),
static_cast<UINT
>(_ClientRect.Height));
158void DirectX11::CreateDeviceAndSwapChain(
const Data_t & _Data)
160 const D3D_FEATURE_LEVEL FeatureLevels[] =
162 D3D_FEATURE_LEVEL_11_1,
163 D3D_FEATURE_LEVEL_11_0
166 DXGI_SWAP_CHAIN_DESC sd = { 0 };
167 sd.OutputWindow = ::covellite::any_cast<HWND>(_Data.Handle);
168 sd.Windowed = (_Data.IsFullScreen) ? FALSE : TRUE;
170 sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
171 sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
172 sd.SampleDesc.Count = 1;
175 using ::alicorn::extension::cpp::IS_RELEASE_CONFIGURATION;
177 DX_CHECK D3D11CreateDeviceAndSwapChain(
179 D3D_DRIVER_TYPE_HARDWARE,
181 (IS_RELEASE_CONFIGURATION) ? 0 : D3D11_CREATE_DEVICE_DEBUG,
182 FeatureLevels,
sizeof(FeatureLevels) /
sizeof(FeatureLevels[0]),
188 &m_pImmediateContext);
190 SetRenderTargetSize(
static_cast<UINT
>(_Data.ClientRect.Width),
191 static_cast<UINT
>(_Data.ClientRect.Height));
194void DirectX11::SetRenderTargetSize(
const UINT _Width,
const UINT _Height)
196 CreateRenderTargetView(_Width, _Height);
197 CreateDepthStencilView(_Width, _Height);
200void DirectX11::CreateRenderTargetView(
const UINT _Width,
const UINT _Height)
202 if (m_pScreenRenderTargetView !=
nullptr)
204 m_pScreenRenderTargetView.Reset();
206 DX_CHECK m_pSwapChain->ResizeBuffers(2, _Width, _Height,
207 DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
210 ComPtr_t<ID3D11Texture2D> pBackBuffer;
211 DX_CHECK m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
212 (
void **)pBackBuffer.GetAddressOf());
214 DX_CHECK m_pDevice->CreateRenderTargetView(pBackBuffer.Get(), NULL,
215 &m_pScreenRenderTargetView);
218void DirectX11::CreateDepthStencilView(
const UINT _Width,
const UINT _Height)
220 m_pScreenDepthStencilView.Reset();
222 const DXGI_FORMAT DeptBufferFormat = DXGI_FORMAT_D32_FLOAT;
224 D3D11_TEXTURE2D_DESC TextureDesc = { 0 };
225 TextureDesc.Width = _Width;
226 TextureDesc.Height = _Height;
227 TextureDesc.MipLevels = 1;
228 TextureDesc.ArraySize = 1;
229 TextureDesc.Format = DeptBufferFormat;
230 TextureDesc.SampleDesc.Count = 1;
231 TextureDesc.SampleDesc.Quality = 0;
232 TextureDesc.Usage = D3D11_USAGE_DEFAULT;
233 TextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
235 ComPtr_t<ID3D11Texture2D> pDepthBuffer;
236 DX_CHECK m_pDevice->CreateTexture2D(&TextureDesc, NULL, &pDepthBuffer);
238 D3D11_DEPTH_STENCIL_VIEW_DESC DeptStencilViewDesc = { 0 };
239 DeptStencilViewDesc.Format = DeptBufferFormat;
240 DeptStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
242 DX_CHECK m_pDevice->CreateDepthStencilView(pDepthBuffer.Get(),
243 &DeptStencilViewDesc, &m_pScreenDepthStencilView);
246auto DirectX11::CreateCamera(
const ComponentPtr_t & _pComponent) -> Render_t
248 const auto CameraId = _pComponent->Id;
250 using Size_t = ::std::tuple<UINT, UINT>;
251 using fnBkSurfaceSize_t = ::std::function<Size_t(
void)>;
253 const auto pCamera = _pComponent;
255 const fnBkSurfaceSize_t GetScaleBkSurfaceSize = [=](void)
257 DXGI_SWAP_CHAIN_DESC Desc = { 0 };
258 DX_CHECK m_pSwapChain->GetDesc(&Desc);
260 const float Scale = (*pCamera)[uT(
"scale")];
262 return Size_t{
static_cast<UINT
>(Scale * Desc.BufferDesc.Width),
263 static_cast<UINT
>(Scale * Desc.BufferDesc.Height) };
266 const fnBkSurfaceSize_t GetWindowBkSurfaceSize = [=](void)
268 DXGI_SWAP_CHAIN_DESC Desc = { 0 };
269 DX_CHECK m_pSwapChain->GetDesc(&Desc);
271 return Size_t{ Desc.BufferDesc.Width, Desc.BufferDesc.Height };
274 const fnBkSurfaceSize_t GetUserBkSurfaceSize = [=](void)
276 DXGI_SWAP_CHAIN_DESC Desc = { 0 };
277 DX_CHECK m_pSwapChain->GetDesc(&Desc);
280 const int Width = (*pCamera)[uT(
"width")];
281 const int Height = (*pCamera)[uT(
"height")];
283 return Size_t{
static_cast<UINT
>(Width),
static_cast<UINT
>(Height) };
286 const auto IsScaleBkSurfaceSize =
287 (*pCamera)[uT(
"scale")].IsType<
float>();
288 const auto IsUserBkSurfaceSize =
289 (*pCamera)[uT(
"width")].IsType<
int>() &&
290 (*pCamera)[uT(
"height")].IsType<
int>();
292 const auto GetBkSurfaceSize =
293 (IsScaleBkSurfaceSize) ? GetScaleBkSurfaceSize :
294 (IsUserBkSurfaceSize) ? GetUserBkSurfaceSize :
295 GetWindowBkSurfaceSize;
297 D3D11_VIEWPORT ViewPort = { 0 };
298 ViewPort.TopLeftX = 0;
299 ViewPort.TopLeftY = 0;
300 ::std::tie(ViewPort.Width, ViewPort.Height) = GetBkSurfaceSize();
301 ViewPort.MinDepth = 0.0f;
302 ViewPort.MaxDepth = 1.0f;
303 m_pImmediateContext->RSSetViewports(1, &ViewPort);
305 const auto SetDefaultRenderTarget = [=](void)
307 m_CurrentRenderTargets = { m_pScreenRenderTargetView.Get() };
308 m_pCurrentDepthStencilView = m_pScreenDepthStencilView;
310 D3D11_VIEWPORT ViewPort = { 0 };
311 ViewPort.TopLeftX = 0;
312 ViewPort.TopLeftY = 0;
313 ::std::tie(ViewPort.Width, ViewPort.Height) = GetBkSurfaceSize();
314 ViewPort.MinDepth = 0.0f;
315 ViewPort.MaxDepth = 1.0f;
316 m_pImmediateContext->RSSetViewports(1, &ViewPort);
319 const auto DisabledBlendRender = CreateBlendState(
false);
320 const auto DisableDepthRender = GetDepthState(
false,
false,
false);
322 const auto ServiceComponents = CapturingServiceComponent::Get(_pComponent,
328 const Render_t CameraOptographic = [=](void)
330 const Component::Position Pos{ *ServiceComponents[0] };
332 SetDefaultRenderTarget();
333 DisabledBlendRender();
334 DisableDepthRender();
336 UINT ViewportCount = 1;
337 D3D11_VIEWPORT Viewport = { 0 };
338 m_pImmediateContext->RSGetViewports(&ViewportCount, &Viewport);
340 auto & CameraMatrices = m_pConstants->Get<::Camera>();
342 CameraMatrices.Projection = ::glm::transpose(::glm::ortho(
343 Pos.X, Pos.X + Viewport.Width,
344 Pos.Y + Viewport.Height, Pos.Y,
347 const auto View = ::glm::identity<::glm::mat4>();
348 CameraMatrices.View = ::glm::transpose(View);
349 CameraMatrices.ViewInverse = ::glm::transpose(::glm::inverse(View));
350 m_pConstants->Update<::Camera>();
352 (*_pComponent)[uT(
"view")] = CameraMatrices.View;
353 (*_pComponent)[uT(
"projection")] = CameraMatrices.Projection;
356 const Render_t CameraPerspective = [=](void)
358 SetDefaultRenderTarget();
359 DisabledBlendRender();
360 DisableDepthRender();
362 UINT ViewportCount = 1;
363 D3D11_VIEWPORT Viewport = { 0 };
364 m_pImmediateContext->RSGetViewports(&ViewportCount, &Viewport);
366 auto & CameraMatrices = m_pConstants->Get<::Camera>();
370 const auto AngleY = (float)(*_pComponent)[uT(
"fov")].Default(90.0f) *
371 ::alicorn::extension::cpp::math::Constant<float>::DegreeToRadian;
372 const float zNear = (*_pComponent)[uT(
"znear")].Default(0.01f);
373 const float zFar = (*_pComponent)[uT(
"zfar")].Default(200.0f);
375 CameraMatrices.Projection = ::glm::transpose(::glm::perspectiveFovRH(AngleY,
376 (
float)Viewport.Width, (
float)Viewport.Height, zFar, zNear));
381 const Component::Position Look{ *ServiceComponents[0] };
383 const auto GetEye = [&](void) -> ::glm::vec3
386 const float Distance = (*_pComponent)[uT(
"distance")].Default(0.0f);
391 const Component::Position Rot{ *ServiceComponents[1] };
393 ::glm::mat4 Transform = ::glm::identity<::glm::mat4>();
395 Transform = ::glm::translate(Transform,
396 ::glm::vec3{ Look.X, Look.Y, Look.Z });
397 Transform = ::glm::rotate(Transform,
398 Rot.Z, ::glm::vec3{ 0.0f, 0.0f, 1.0f });
399 Transform = ::glm::rotate(Transform,
400 Rot.Y, ::glm::vec3{ 0.0f, 1.0f, 0.0f });
401 Transform = ::glm::rotate(Transform,
402 Rot.X, ::glm::vec3{ 1.0f, 0.0f, 0.0f });
404 return Transform * ::glm::vec4{ Distance + 0.1f, 0.0f, 0.0f, 1.0f };
407 const auto View = ::glm::lookAtRH(
409 ::glm::vec3{ Look.X, Look.Y, Look.Z },
410 ::glm::vec3{ 0.0f, 0.0f, 1.0f });
412 CameraMatrices.View = ::glm::transpose(View);
413 CameraMatrices.ViewInverse = ::glm::transpose(::glm::inverse(View));
414 m_pConstants->Update<::Camera>();
416 (*_pComponent)[uT(
"view")] = CameraMatrices.View;
417 (*_pComponent)[uT(
"projection")] = CameraMatrices.Projection;
420 return (_pComponent->Kind == uT(
"Perspective")) ?
421 CameraPerspective : CameraOptographic;
424class DirectX11::Texture final
427 using Ptr_t = ::std::shared_ptr<Texture>;
430 const ComponentPtr_t m_pDataTexture;
431 const String_t m_Destination;
432 const UINT m_iDestination;
433 const bool m_IsUseMapper;
434 const DXGI_FORMAT m_Format;
435 ComPtr_t<ID3D11Texture2D> m_pTexture;
436 ComPtr_t<ID3D11Texture2D> m_pReadDataTexture;
437 ComPtr_t<ID3D11RenderTargetView> m_pRenderTargetView;
438 ComPtr_t<ID3D11DepthStencilView> m_pDepthStencilView;
439 ComPtr_t<ID3D11ShaderResourceView> m_pShaderResourceView;
443 const ComPtr_t<ID3D11Device> & _pDevice,
447 m_pTexture = (m_Destination != uT(
"depth")) ?
448 MakeRGBATarget(_pDevice, _Width, _Height) :
449 MakeDepthTarget(_pDevice, _Width, _Height);
451 (*m_pDataTexture)[uT(
"width")] =
static_cast<int>(_Width);
452 (*m_pDataTexture)[uT(
"height")] =
static_cast<int>(_Height);
456 m_pReadDataTexture = MakeRGBACopy(_pDevice, _Width, _Height);
461 const ComPtr_t<ID3D11Device> & _pDevice,
462 const ComPtr_t<ID3D11DeviceContext> & _pImmediateContext,
466 const bool _IsMipmapping)
468 m_pTexture = (_IsMipmapping) ?
469 MakeRGBAMipSource(_pDevice, _pImmediateContext, _Width, _Height, _pData) :
470 MakeRGBASource(_pDevice, _pImmediateContext, _Width, _Height, _pData);
473 ComPtr_t<ID3D11Texture2D> MakeRGBACopy(
474 const ComPtr_t<ID3D11Device> & _pDevice,
475 const UINT _Width,
const UINT _Height)
const
477 D3D11_TEXTURE2D_DESC textureDesc = { 0 };
478 textureDesc.Width = _Width;
479 textureDesc.Height = _Height;
480 textureDesc.MipLevels = 1;
481 textureDesc.ArraySize = 1;
482 textureDesc.Format = m_Format;
483 textureDesc.Usage = D3D11_USAGE_STAGING;
484 textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
485 textureDesc.SampleDesc.Count = 1;
487 ComPtr_t<ID3D11Texture2D> pTexture;
488 DX_CHECK _pDevice->CreateTexture2D(&textureDesc,
nullptr, &pTexture);
493 ComPtr_t<ID3D11Texture2D> MakeRGBASource(
494 const ComPtr_t<ID3D11Device> & _pDevice,
495 const ComPtr_t<ID3D11DeviceContext> & _pImmediateContext,
500 D3D11_TEXTURE2D_DESC TextureDesc = { 0 };
501 TextureDesc.Width = _Width;
502 TextureDesc.Height = _Height;
503 TextureDesc.MipLevels = 1;
504 TextureDesc.ArraySize = 1;
505 TextureDesc.Format = m_Format;
506 TextureDesc.Usage = D3D11_USAGE_DEFAULT;
507 TextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
508 TextureDesc.MiscFlags = 0;
509 TextureDesc.SampleDesc.Count = 1;
510 TextureDesc.SampleDesc.Quality = 0;
512 ComPtr_t<ID3D11Texture2D> pTexture2D;
513 DX_CHECK _pDevice->CreateTexture2D(&TextureDesc,
nullptr, &pTexture2D);
515 _pImmediateContext->UpdateSubresource(pTexture2D.Get(), 0, NULL,
516 _pData, _Width * 4, 0);
518 D3D11_SHADER_RESOURCE_VIEW_DESC SrvDesc = { 0 };
519 SrvDesc.Format = TextureDesc.Format;
520 SrvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
521 SrvDesc.Texture2D.MipLevels = TextureDesc.MipLevels;
523 DX_CHECK _pDevice->CreateShaderResourceView(pTexture2D.Get(), &SrvDesc,
524 &m_pShaderResourceView);
529 ComPtr_t<ID3D11Texture2D> MakeRGBAMipSource(
530 const ComPtr_t<ID3D11Device> & _pDevice,
531 const ComPtr_t<ID3D11DeviceContext> & _pImmediateContext,
536 D3D11_TEXTURE2D_DESC TextureDesc = { 0 };
537 TextureDesc.Width = _Width;
538 TextureDesc.Height = _Height;
539 TextureDesc.MipLevels = 0;
540 TextureDesc.ArraySize = 1;
541 TextureDesc.Format = m_Format;
542 TextureDesc.Usage = D3D11_USAGE_DEFAULT;
543 TextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
544 TextureDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;
545 TextureDesc.SampleDesc.Count = 1;
546 TextureDesc.SampleDesc.Quality = 0;
548 ComPtr_t<ID3D11Texture2D> pTexture2D;
549 DX_CHECK _pDevice->CreateTexture2D(&TextureDesc,
nullptr, &pTexture2D);
551 _pImmediateContext->UpdateSubresource(pTexture2D.Get(), 0, NULL,
552 _pData, _Width * 4, 0);
554 D3D11_SHADER_RESOURCE_VIEW_DESC SrvDesc = { 0 };
555 SrvDesc.Format = TextureDesc.Format;
556 SrvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
557 SrvDesc.Texture2D.MipLevels =
static_cast<UINT
>(-1);
559 DX_CHECK _pDevice->CreateShaderResourceView(pTexture2D.Get(), &SrvDesc,
560 &m_pShaderResourceView);
562 _pImmediateContext->GenerateMips(m_pShaderResourceView.Get());
568 ComPtr_t<ID3D11Texture2D> MakeRGBATarget(
569 const ComPtr_t<ID3D11Device> & _pDevice,
570 const UINT _Width,
const UINT _Height)
572 D3D11_TEXTURE2D_DESC TextureDesc = { 0 };
573 TextureDesc.Width = _Width;
574 TextureDesc.Height = _Height;
575 TextureDesc.MipLevels = 1;
576 TextureDesc.ArraySize = 1;
577 TextureDesc.Format = m_Format;
578 TextureDesc.Usage = D3D11_USAGE_DEFAULT;
579 TextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
580 TextureDesc.MiscFlags = 0;
581 TextureDesc.SampleDesc.Count = 1;
582 TextureDesc.SampleDesc.Quality = 0;
584 ComPtr_t<ID3D11Texture2D> pTexture2D;
585 DX_CHECK _pDevice->CreateTexture2D(&TextureDesc,
nullptr, &pTexture2D);
587 D3D11_SHADER_RESOURCE_VIEW_DESC SrvDesc = { 0 };
588 SrvDesc.Format = TextureDesc.Format;
589 SrvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
590 SrvDesc.Texture2D.MipLevels = TextureDesc.MipLevels;
592 DX_CHECK _pDevice->CreateShaderResourceView(pTexture2D.Get(), &SrvDesc,
593 &m_pShaderResourceView);
595 D3D11_RENDER_TARGET_VIEW_DESC TargetDesc = { 0 };
596 TargetDesc.Format = TextureDesc.Format;
597 TargetDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
599 ComPtr_t<ID3D11RenderTargetView> pRenderTargetView;
600 DX_CHECK _pDevice->CreateRenderTargetView(pTexture2D.Get(),
601 &TargetDesc, &m_pRenderTargetView);
606 ComPtr_t<ID3D11Texture2D> MakeDepthTarget(
607 const ComPtr_t<ID3D11Device> & _pDevice,
608 const UINT _Width,
const UINT _Height)
610 D3D11_TEXTURE2D_DESC TextureDesc = { 0 };
611 TextureDesc.Width = _Width;
612 TextureDesc.Height = _Height;
613 TextureDesc.MipLevels = 1;
614 TextureDesc.ArraySize = 1;
615 TextureDesc.Format = DXGI_FORMAT_R24G8_TYPELESS;
616 TextureDesc.Usage = D3D11_USAGE_DEFAULT;
617 TextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
618 TextureDesc.MiscFlags = 0;
619 TextureDesc.SampleDesc.Count = 1;
620 TextureDesc.SampleDesc.Quality = 0;
622 ComPtr_t<ID3D11Texture2D> pTexture2D;
623 DX_CHECK _pDevice->CreateTexture2D(&TextureDesc,
nullptr, &pTexture2D);
625 D3D11_SHADER_RESOURCE_VIEW_DESC SrvDesc = { 0 };
626 SrvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
627 SrvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
628 SrvDesc.Texture2D.MipLevels = TextureDesc.MipLevels;
630 DX_CHECK _pDevice->CreateShaderResourceView(pTexture2D.Get(), &SrvDesc,
631 &m_pShaderResourceView);
633 D3D11_DEPTH_STENCIL_VIEW_DESC Desc = { 0 };
634 Desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
635 Desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
637 ComPtr_t<ID3D11DepthStencilView> pDepthStencilView;
638 DX_CHECK _pDevice->CreateDepthStencilView(pTexture2D.Get(),
639 &Desc, &m_pDepthStencilView);
645 static UINT GetDestinationIndex(
const ComponentPtr_t & _pData)
647 const int Index = (*_pData)[uT(
"index")].Default(-1);
648 if (Index >= 0)
return static_cast<UINT
>(Index);
650 static const ::std::vector<String_t> Destinations =
660 const String_t Destination =
661 (*_pData)[uT(
"destination")].Default(uT(
"albedo"));
663 const auto itDestination =
664 ::std::find(Destinations.cbegin(), Destinations.cend(), Destination);
665 if (itDestination == Destinations.cend())
667 throw STD_EXCEPTION <<
"Unexpected destination texture: " << Destination;
670 return static_cast<UINT
>(
671 ::std::distance(Destinations.cbegin(), itDestination));
674 static DXGI_FORMAT GetFormat(
const ComponentPtr_t & _pData)
676 const int Capacity = (*_pData)[uT(
"capacity")].Default(8);
679 (Capacity == 32) ? DXGI_FORMAT_R32G32B32A32_FLOAT :
680 (Capacity == 16) ? DXGI_FORMAT_R16G16B16A16_FLOAT :
681 DXGI_FORMAT_R8G8B8A8_UNORM;
685 explicit Texture(
const ComponentPtr_t & _pDataTexture) :
686 m_pDataTexture{ _pDataTexture },
687 m_Destination{ (*_pDataTexture)[uT(
"destination")].Default(uT(
"albedo")) },
688 m_iDestination{ GetDestinationIndex(_pDataTexture) },
689 m_IsUseMapper{ (*_pDataTexture)[uT(
"mapper")].IsType<const cbBufferMap_t<const void> &>() },
690 m_Format{ GetFormat(_pDataTexture) }
694 Texture(
const Texture &) =
delete;
695 Texture(Texture &&) =
delete;
696 Texture & operator= (
const Texture &) =
delete;
697 Texture & operator= (Texture &&) =
delete;
698 ~Texture(
void) =
default;
703 using Size_t = ::std::tuple<UINT, UINT>;
704 using fnBkSurfaceSize_t = ::std::function<Size_t(
void)>;
706 const auto pBkSurface = _pComponent;
708 const fnBkSurfaceSize_t GetBkSurfaceSize = [=](void)
710 UINT ViewportCount = 1;
711 D3D11_VIEWPORT Viewport = { 0 };
712 m_pImmediateContext->RSGetViewports(&ViewportCount, &Viewport);
714 const int Width =
static_cast<int>(Viewport.Width);
715 const int Height =
static_cast<int>(Viewport.Height);
717 (*pBkSurface)[uT(
"width")] = Width;
718 (*pBkSurface)[uT(
"height")] = Height;
720 return Size_t{
static_cast<UINT
>(Width),
static_cast<UINT
>(Height) };
723 const auto [Width, Height] = GetBkSurfaceSize();
725 const auto pBkSurfaceTextures =
726 ::std::make_shared<::std::vector<Texture::Ptr_t>>();
728 const auto DoDataTexture = [&](
const ComponentPtr_t & _pDataTexture)
730 auto pTexture = ::std::make_shared<Texture>(_pDataTexture);
731 pTexture->MakeTarget(m_pDevice, Width, Height);
737 (*_pDataTexture)[uT(
"entity")] = ::std::weak_ptr<Texture>(pTexture);
739 pBkSurfaceTextures->push_back(pTexture);
742 CapturingServiceComponent::Process(_pComponent,
744 { uT(
"Texture"), DoDataTexture },
749 const auto [Width, Height] = GetBkSurfaceSize();
752 TODO(
"Хранить размеры текстур в них самих и пересоздавать при расхождении размеров");
756 if (m_IsResizeWindow)
758 for (
auto & pTexture : *pBkSurfaceTextures)
760 pTexture->MakeTarget(m_pDevice, Width, Height);
764 m_CurrentRenderTargets.clear();
766 for (
auto & pTexture : *pBkSurfaceTextures)
768 if (pTexture->m_pRenderTargetView)
770 m_CurrentRenderTargets.push_back(pTexture->m_pRenderTargetView.Get());
773 if (pTexture->m_pDepthStencilView)
775 m_pCurrentDepthStencilView = pTexture->m_pDepthStencilView;
778 static ID3D11ShaderResourceView * NullResourceView[1] = {
nullptr };
779 m_pImmediateContext->PSSetShaderResources(
780 pTexture->m_iDestination, 1, NullResourceView);
783 if (m_CurrentRenderTargets.empty())
785 m_CurrentRenderTargets = {
nullptr };
788 m_pImmediateContext->OMSetRenderTargets(
789 static_cast<UINT
>(m_CurrentRenderTargets.size()),
790 &m_CurrentRenderTargets[0],
nullptr);
794auto DirectX11::CreateState(
const ComponentPtr_t & _pComponent) -> Render_t
796 const auto CreateSamplerState = [&](void)
798 D3D11_SAMPLER_DESC SamplerDesc = { 0 };
799 SamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
800 SamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
801 SamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
802 SamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
803 SamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
804 SamplerDesc.MinLOD = 0;
805 SamplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
807 ComPtr_t<ID3D11SamplerState> pSamplerState;
808 DX_CHECK m_pDevice->CreateSamplerState(&SamplerDesc, &pSamplerState);
812 m_pImmediateContext->PSSetSamplers(0, 1, pSamplerState.GetAddressOf());
816 const auto CreateScissorState = [&](void)
818 const Component::Scissor ScissorData{ *_pComponent };
820 D3D11_RASTERIZER_DESC rasterDesc = { 0 };
821 rasterDesc.FillMode = D3D11_FILL_SOLID;
822 rasterDesc.CullMode = D3D11_CULL_BACK;
823 rasterDesc.FrontCounterClockwise = TRUE;
824 rasterDesc.ScissorEnable = (ScissorData.IsEnabled) ? TRUE : FALSE;
826 ComPtr_t<ID3D11RasterizerState> pScissor;
827 DX_CHECK m_pDevice->CreateRasterizerState(&rasterDesc, &pScissor);
829 const auto pScissorRect = CapturingServiceComponent::Get(_pComponent,
830 { {uT(
"Rect"), _pComponent} })[0];
832 Render_t ScissorEnabled = [=](void)
834 const Component::Scissor ScissorRect{ *pScissorRect };
836 D3D11_RECT Rect = { 0 };
837 Rect.left = ScissorRect.Left;
838 Rect.right = ScissorRect.Right;
839 Rect.top = ScissorRect.Top;
840 Rect.bottom = ScissorRect.Bottom;
842 m_pImmediateContext->RSSetScissorRects(1, &Rect);
843 m_pImmediateContext->RSSetState(pScissor.Get());
846 Render_t ScissorDisabled = [=](void)
848 m_pImmediateContext->RSSetState(pScissor.Get());
851 return (ScissorData.IsEnabled) ? ScissorEnabled : ScissorDisabled;
854 const auto CreateDepthState = [&](void)
856 return GetDepthState(
857 (*_pComponent)[uT(
"enabled")].Default(
false),
858 (*_pComponent)[uT(
"clear")].Default(
false),
859 (*_pComponent)[uT(
"overwrite")].Default(
true));
862 const auto CreateClearState = [&](void)
864 const auto ARGBtoFloat4 = [](
const uint32_t _HexColor)
866 return ::std::vector<FLOAT>
868 ((_HexColor & 0x00FF0000) >> 16) / 255.0f,
869 ((_HexColor & 0x0000FF00) >> 8) / 255.0f,
870 ((_HexColor & 0x000000FF) >> 0) / 255.0f,
871 ((_HexColor & 0xFF000000) >> 24) / 255.0f,
874 const auto BackgroundColor =
875 ARGBtoFloat4((*_pComponent)[uT(
"color")].Default(0xFF000000));
879 for (
auto * pRenderTargetView : m_CurrentRenderTargets)
881 m_pImmediateContext->ClearRenderTargetView(
882 pRenderTargetView, BackgroundColor.data());
887 const auto CreateAlphaTestState = [&](void)
892 ::std::map<String_t, ::std::function<Render_t(
void)>> Creators =
894 { uT(
"Blend"), [&](void) {
return CreateBlendState(
true); } },
895 { uT(
"Sampler"), CreateSamplerState },
896 { uT(
"Scissor"), CreateScissorState },
897 { uT(
"Depth"), CreateDepthState },
898 { uT(
"Clear"), CreateClearState },
899 { uT(
"AlphaTest"), CreateAlphaTestState },
902 return Creators[_pComponent->Kind]();
905auto DirectX11::CreateTexture(
const ComponentPtr_t & _pComponent) -> Render_t
907 using BufferMapper_t = cbBufferMap_t<const void>;
909 const auto pTextureData = CapturingServiceComponent::Get(_pComponent,
910 { { uT(
"Texture"), _pComponent } })[0];
912 const Component::Texture TextureData{ *pTextureData, uT(
"albedo") };
914 Texture::Ptr_t pTexture;
916 ::std::weak_ptr<Texture> wpTexture = (*pTextureData)[uT(
"entity")]
917 .Default(::std::weak_ptr<Texture>{});
918 if (wpTexture.lock() ==
nullptr)
920 pTexture = ::std::make_shared<Texture>(pTextureData);
921 pTexture->MakeSource(m_pDevice, m_pImmediateContext,
922 static_cast<UINT
>(TextureData.Width),
static_cast<UINT
>(TextureData.Height),
923 TextureData.Data.data(), TextureData.IsUsingMipmapping);
927 pTexture = wpTexture.lock();
928 (*pTextureData)[uT(
"entity")] = ::std::weak_ptr<Texture>{};
931 if (pTexture->m_pReadDataTexture ==
nullptr)
935 m_pImmediateContext->PSSetShaderResources(pTexture->m_iDestination, 1,
936 pTexture->m_pShaderResourceView.GetAddressOf());
940 const BufferMapper_t cbBufferMapper =
941 (*pTextureData)[uT(
"mapper")].Default(BufferMapper_t{});
945 if (cbBufferMapper(
nullptr))
947 m_pImmediateContext->CopyResource(
948 pTexture->m_pReadDataTexture.Get(), pTexture->m_pTexture.Get());
950 D3D11_MAPPED_SUBRESOURCE Resource = { 0 };
951 DX_CHECK m_pImmediateContext->Map(pTexture->m_pReadDataTexture.Get(), 0,
952 D3D11_MAP_READ, 0, &Resource);
953 cbBufferMapper(Resource.pData);
954 m_pImmediateContext->Unmap(pTexture->m_pReadDataTexture.Get(), 0);
957 m_pImmediateContext->PSSetShaderResources(pTexture->m_iDestination, 1,
958 pTexture->m_pShaderResourceView.GetAddressOf());
962auto DirectX11::CreateShader(
const ComponentPtr_t & _pComponent) -> Render_t
964 using namespace ::alicorn::extension::std;
966 const auto pShaderDataComponent = CapturingServiceComponent::Get(_pComponent,
967 { { uT(
"Shader"), _pComponent } })[0];
969 const Component::Shader ShaderData{ *pShaderDataComponent, ::Default };
971 ::std::string Define =
972 "#define COVELLITE_SHADER_DESKTOP\r\n"
973 "#define COVELLITE_SHADER_HLSL\r\n"
974 "#define COVELLITE_SHADER_VERTEX\r\n";
975 const auto HeaderShaderText = ::Predefined + ::Data +
976 ShaderData.GetInstanceInput(::Input);
977 auto ShaderText = ShaderData.Data;
978 ::std::string Entry = ShaderData.Entry;
980 if (ShaderData.Kind == uT(
"Pixel"))
983 "#define COVELLITE_SHADER_DESKTOP\r\n"
984 "#define COVELLITE_SHADER_HLSL\r\n"
985 "#define COVELLITE_SHADER_PIXEL\r\n";
987 if (ShaderData.ReturnType ==
"float4" ||
988 ShaderData.ReturnType ==
"vec4")
990 ShaderText += DirectX::Shader::Convert(
991 "float4 psMain(Pixel _Value) : SV_Target\r\n"
993 " return " + Entry +
"(_Value);\r\n"
999 const auto pCompiledShader = DirectX::Shader::Compile(
1000 DirectX::Shader::Convert(Define) + HeaderShaderText, ShaderText,
1001 Entry.c_str(), DirectX::Shader::GetVersion(ShaderData.Kind).c_str());
1003 const auto VertexShader =
1004 [&](const ::std::vector<D3D11_INPUT_ELEMENT_DESC> & _LayoutDesc)
1006 const auto *
const pData = pCompiledShader->GetBufferPointer();
1007 const auto DataSize = pCompiledShader->GetBufferSize();
1009 ComPtr_t<ID3D11InputLayout> pVertexLayout;
1010 DX_CHECK m_pDevice->CreateInputLayout(
1011 _LayoutDesc.data(),
static_cast<UINT
>(_LayoutDesc.size()),
1015 ComPtr_t<ID3D11VertexShader> pVertexShader;
1016 DX_CHECK m_pDevice->CreateVertexShader(
1018 NULL, &pVertexShader);
1022 m_pImmediateContext->IASetInputLayout(pVertexLayout.Get());
1023 m_pImmediateContext->VSSetShader(pVertexShader.Get(), NULL, 0);
1027 if (ShaderData.Kind == uT(
"Polygon"))
1029 return VertexShader(
1031 {
"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1032 {
"COLOR", 0, DXGI_FORMAT_R32_UINT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1033 {
"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1036 else if (ShaderData.Kind == uT(
"Polyhedron"))
1038 return VertexShader(
1040 {
"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1041 {
"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1042 {
"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1045 else if (ShaderData.Kind == uT(
"Vertex"))
1047 ::std::vector<D3D11_INPUT_ELEMENT_DESC> LayoutDesc =
1049 {
"POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1050 {
"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1051 {
"NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
1054 for (UINT i = 0; i < static_cast<UINT>(ShaderData.Instance.size()); i++)
1056 const auto Type = ShaderData.Instance[i];
1058 (Type == uT(
"f")) ? DXGI_FORMAT_R32G32B32A32_FLOAT :
1059 (Type == uT(
"i")) ? DXGI_FORMAT_R32G32B32A32_SINT :
1060 DXGI_FORMAT_UNKNOWN;
1061 const auto Size = i * 4 *
static_cast<UINT
>(
1062 (Type == uT(
"f")) ?
sizeof(float) :
1064 (Type == uT(
"i")) ?
sizeof(int) :
1067 LayoutDesc.push_back(
1069 "TEXCOORD", i + 1, Format, 1, Size, D3D11_INPUT_PER_INSTANCE_DATA, 1
1073 return VertexShader(LayoutDesc);
1076 ComPtr_t<ID3D11PixelShader> pPixelShader;
1077 DX_CHECK m_pDevice->CreatePixelShader(
1078 pCompiledShader->GetBufferPointer(), pCompiledShader->GetBufferSize(),
1079 NULL, &pPixelShader);
1083 m_pImmediateContext->PSSetShader(pPixelShader.Get(), NULL, 0);
1087auto DirectX11::CreateBuffer(
const ComponentPtr_t & _pComponent) -> Render_t
1089 const auto pBufferData = CapturingServiceComponent::Get(_pComponent,
1090 { { uT(
"Buffer"), _pComponent } })[0];
1092 if ((*pBufferData)[uT(
"content")].IsType<Buffer_t<::covellite::api::Vertex>>())
1094 using BufferMapper_t = cbBufferMap_t<::covellite::api::Vertex>;
1096 const Component::Buffer<::covellite::api::Vertex> VertexData{ *pBufferData };
1098 const BufferMapper_t & cbBufferMapper =
1099 (*_pComponent)[uT(
"mapper")].Default(BufferMapper_t{});
1101 auto pBuffer = Buffer::Create(m_pDevice, (cbBufferMapper !=
nullptr),
1102 VertexData.Data.data(), VertexData.Data.size());
1104 const Render_t StaticRender = [=](void)
1107 constexpr UINT Offset = 0;
1108 m_pImmediateContext->IASetVertexBuffers(0, 1,
1109 pBuffer.GetAddressOf(), &Stride, &Offset);
1112 const Render_t DynamicRender = [=](void)
1114 const auto IsDirty = cbBufferMapper(
nullptr);
1117 D3D11_MAPPED_SUBRESOURCE Resource = { 0 };
1118 DX_CHECK m_pImmediateContext->Map(pBuffer.Get(), 0,
1119 D3D11_MAP_WRITE_NO_OVERWRITE, 0, &Resource);
1121 m_pImmediateContext->Unmap(pBuffer.Get(), 0);
1127 return (cbBufferMapper ==
nullptr) ? StaticRender : DynamicRender;
1129 else if ((*_pComponent)[uT(
"mapper")].IsType<
const cbBufferMap_t<void> &>())
1131 using BufferMap_t = cbBufferMap_t<void>;
1133 const BufferMap_t cbBufferMapper =
1134 (*_pComponent)[uT(
"mapper")].Default(BufferMap_t{});
1135 if (!cbBufferMapper)
1137 throw STD_EXCEPTION <<
"Unexpected empty mapper: " << _pComponent->Id;
1140 const ::std::size_t BufferSize =
1141 (*pBufferData)[uT(
"size")].Default((::std::size_t)0);
1142 if (BufferSize == 0)
1144 throw STD_EXCEPTION <<
"Unexpected zero size: " << _pComponent->Id;
1148 ::std::make_shared<BinaryData_t>(BufferSize, (uint8_t)0x00);
1149 const auto pBuffer = Buffer::Create(
1150 m_pDevice,
false, pData->data(), pData->size());
1151 constexpr auto BufferIndex =
1152 Buffer::Support<BinaryData_t::value_type>::Index;
1157 cbBufferMapper(pData->data());
1161 m_pImmediateContext->VSSetConstantBuffers(
1162 BufferIndex, 1, pBuffer.GetAddressOf());
1163 m_pImmediateContext->PSSetConstantBuffers(
1164 BufferIndex, 1, pBuffer.GetAddressOf());
1166 m_pImmediateContext->UpdateSubresource(
1167 pBuffer.Get(), 0, NULL, pData->data(), 0, 0);
1171 throw STD_EXCEPTION <<
"Unexpected buffer type: " << _pComponent->Id;
1174auto DirectX11::CreateTransform(
const ComponentPtr_t & _pComponent) -> Render_t
1176 const auto BuildTransformMatrix =
1177 (_pComponent->Kind == uT(
"Unknown")) ? CreateDefaultTransformRender<::Object>(_pComponent) :
1178 (_pComponent->Kind == uT(
"Static")) ? CreateStaticTransformRender<::Object>(_pComponent) :
1179 (_pComponent->Kind == uT(
"Billboard")) ? CreateBillboardTransformRender<::Camera, ::Object>(_pComponent) :
1180 throw STD_EXCEPTION <<
"Unexpected transform component: " <<
1181 " [id=" << _pComponent->Id <<
", kind=" << _pComponent->Kind <<
"].";
1185 BuildTransformMatrix();
1186 m_pConstants->Update<::Object>();
1190auto DirectX11::CreatePresentBuffer(
const ComponentPtr_t & _pComponent) ->Render_t
1192 using BufferMapperMaxSize_t = ::std::function<bool(
void *)>;
1193 using BufferMapperChangeSize_t = ::std::function<bool(
void *, ::std::size_t &)>;
1195 ComponentPtr_t pIndexBufferData = _pComponent;
1196 ComponentPtr_t pInstanceBufferData =
nullptr;
1198 const auto SaveBuffer = [&](
const ComponentPtr_t & _pBufferData)
1200 if ((*_pBufferData)[uT(
"content")].IsType<Buffer_t<int>>())
1202 pIndexBufferData = _pBufferData;
1204 else if ((*_pBufferData)[uT(
"mapper")].IsType<const BufferMapperMaxSize_t &>())
1206 pInstanceBufferData = _pBufferData;
1208 else if ((*_pBufferData)[uT(
"mapper")].IsType<const BufferMapperChangeSize_t &>())
1210 pInstanceBufferData = _pBufferData;
1214 throw STD_EXCEPTION <<
"Unexpected buffer data component.";
1218 CapturingServiceComponent::Process(_pComponent,
1220 { uT(
"Buffer"), SaveBuffer },
1223 const Component::Buffer<int> IndexBufferData{ *pIndexBufferData };
1225 const auto pIndexBuffer = Buffer::Create(m_pDevice,
false,
1226 IndexBufferData.Data.data(), IndexBufferData.Data.size());
1227 const auto IndexCount =
static_cast<DWORD
>(IndexBufferData.Data.size());
1229 if (pInstanceBufferData ==
nullptr)
1233 m_pImmediateContext->IASetIndexBuffer(
1234 pIndexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
1235 m_pImmediateContext->IASetPrimitiveTopology(
1236 D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
1237 m_pImmediateContext->DrawIndexed(IndexCount, 0, 0);
1241 const ::std::size_t BufferSize = (*pInstanceBufferData)[uT(
"size")];
1242 if (BufferSize % 16 != 0)
1244 throw STD_EXCEPTION << _pComponent->Id <<
": size % 16 != 0";
1247 const ::std::size_t MaxInstanceCount = (*pInstanceBufferData)[uT(
"count")];
1248 if (BufferSize % MaxInstanceCount != 0)
1250 throw STD_EXCEPTION << _pComponent->Id <<
": size % count != 0";
1253 const auto Stride =
static_cast<UINT
>(BufferSize / MaxInstanceCount);
1255 const auto pInstanceBuffer =
1256 Buffer::Create<int8_t>(m_pDevice,
true,
nullptr, BufferSize);
1258 if ((*pInstanceBufferData)[uT(
"mapper")].IsType<BufferMapperMaxSize_t>())
1260 const BufferMapperMaxSize_t cbBufferMapper =
1261 (*pInstanceBufferData)[uT(
"mapper")];
1265 const auto IsDirty = cbBufferMapper(
nullptr);
1268 D3D11_MAPPED_SUBRESOURCE Resource = { 0 };
1269 DX_CHECK m_pImmediateContext->Map(pInstanceBuffer.Get(), 0,
1270 D3D11_MAP_WRITE_NO_OVERWRITE, 0, &Resource);
1271 cbBufferMapper(Resource.pData);
1272 m_pImmediateContext->Unmap(pInstanceBuffer.Get(), 0);
1275 constexpr UINT Offset = 0;
1276 m_pImmediateContext->IASetVertexBuffers(
1277 1, 1, pInstanceBuffer.GetAddressOf(), &Stride, &Offset);
1278 m_pImmediateContext->IASetIndexBuffer(
1279 pIndexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
1280 m_pImmediateContext->IASetPrimitiveTopology(
1281 D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
1282 m_pImmediateContext->DrawIndexedInstanced(
1283 IndexCount,
static_cast<UINT
>(MaxInstanceCount), 0, 0, 0);
1287 const BufferMapperChangeSize_t cbBufferMapper =
1288 (*pInstanceBufferData)[uT(
"mapper")];
1292 auto InstanceCount = MaxInstanceCount;
1294 const auto IsDirty = cbBufferMapper(
nullptr, InstanceCount);
1297 D3D11_MAPPED_SUBRESOURCE Resource = { 0 };
1298 DX_CHECK m_pImmediateContext->Map(pInstanceBuffer.Get(), 0,
1299 D3D11_MAP_WRITE_NO_OVERWRITE, 0, &Resource);
1300 cbBufferMapper(Resource.pData, InstanceCount);
1301 m_pImmediateContext->Unmap(pInstanceBuffer.Get(), 0);
1304 InstanceCount = ::std::min(InstanceCount, MaxInstanceCount);
1306 constexpr UINT Offset = 0;
1307 m_pImmediateContext->IASetVertexBuffers(
1308 1, 1, pInstanceBuffer.GetAddressOf(), &Stride, &Offset);
1309 m_pImmediateContext->IASetIndexBuffer(
1310 pIndexBuffer.Get(), DXGI_FORMAT_R32_UINT, 0);
1311 m_pImmediateContext->IASetPrimitiveTopology(
1312 D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
1313 m_pImmediateContext->DrawIndexedInstanced(
1314 IndexCount,
static_cast<UINT
>(InstanceCount), 0, 0, 0);
1318auto DirectX11::CreateBlendState(
bool _IsEnabled) -> Render_t
1320 ComPtr_t<ID3D11BlendState> pBlendState;
1324 D3D11_BLEND_DESC BlendDesc = { 0 };
1325 BlendDesc.AlphaToCoverageEnable = FALSE;
1326 BlendDesc.IndependentBlendEnable = FALSE;
1328 for (
auto & RenderTarget : BlendDesc.RenderTarget)
1330 RenderTarget.BlendEnable = TRUE;
1331 RenderTarget.SrcBlend = D3D11_BLEND_SRC_ALPHA;
1332 RenderTarget.DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
1333 RenderTarget.BlendOp = D3D11_BLEND_OP_ADD;
1334 RenderTarget.SrcBlendAlpha = D3D11_BLEND_ONE;
1335 RenderTarget.DestBlendAlpha = D3D11_BLEND_ZERO;
1336 RenderTarget.BlendOpAlpha = D3D11_BLEND_OP_ADD;
1337 RenderTarget.RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
1340 DX_CHECK m_pDevice->CreateBlendState(&BlendDesc, &pBlendState);
1345 const FLOAT BlendFactor[] = { 0.0f, 0.0f, 0.0f, 0.0f };
1346 m_pImmediateContext->OMSetBlendState(
1347 pBlendState.Get(), BlendFactor, 0xFFFFFFFF);
1352 const bool _IsEnabled,
1353 const bool _IsClear,
1354 const bool _IsOverwrite) -> Render_t
1360 m_pImmediateContext->OMSetRenderTargets(
1361 static_cast<UINT
>(m_CurrentRenderTargets.size()),
1362 &m_CurrentRenderTargets[0],
nullptr);
1366 D3D11_DEPTH_STENCIL_DESC DeptStencilDesc = { 0 };
1367 DeptStencilDesc.DepthEnable =
true;
1368 DeptStencilDesc.DepthWriteMask = _IsOverwrite ?
1369 D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
1370 DeptStencilDesc.DepthFunc = D3D11_COMPARISON_GREATER;
1371 DeptStencilDesc.StencilEnable =
false;
1373 ComPtr_t<ID3D11DepthStencilState> pDSState;
1374 DX_CHECK m_pDevice->CreateDepthStencilState(&DeptStencilDesc, &pDSState);
1376 Render_t RenderDepthEnabled = [=](void)
1379 TODO(
"Тест того, что если BkSurface не устанавливает буфер глубины, то используется буфер глубины экрана");
1381 m_pImmediateContext->OMSetDepthStencilState(pDSState.Get(), 1);
1382 m_pImmediateContext->OMSetRenderTargets(
1383 static_cast<UINT
>(m_CurrentRenderTargets.size()),
1384 &m_CurrentRenderTargets[0], m_pCurrentDepthStencilView.Get());
1387 Render_t RenderDepthClear = [=](void)
1390 TODO(
"Тест того, что если BkSurface не устанавливает буфер глубины, то используется буфер глубины экрана");
1392 m_pImmediateContext->OMSetDepthStencilState(pDSState.Get(), 1);
1393 m_pImmediateContext->OMSetRenderTargets(
1394 static_cast<UINT
>(m_CurrentRenderTargets.size()),
1395 &m_CurrentRenderTargets[0], m_pCurrentDepthStencilView.Get());
1396 m_pImmediateContext->ClearDepthStencilView(m_pCurrentDepthStencilView.Get(),
1397 D3D11_CLEAR_DEPTH, 0.0f, 0);
1400 return _IsClear ? RenderDepthClear : RenderDepthEnabled;
1403template<
class TConstantBuffer>
1404auto DirectX11::CreateDefaultTransformRender(
1405 const ComponentPtr_t & _pComponent) -> Render_t
1407 ::std::deque<Render_t> PreRenders;
1409 auto CreatePosition = [&](
const ComponentPtr_t & _pPosition)
1411 PreRenders.push_front([=](
void)
1413 auto & World = m_pConstants->Get<TConstantBuffer>().World;
1415 const Component::Position Position{ *_pPosition };
1417 World = ::glm::translate(World,
1418 ::glm::vec3{ Position.X, Position.Y, Position.Z });
1422 auto CreateRotation = [&](
const ComponentPtr_t & _pRotation)
1424 PreRenders.push_front([=](
void)
1426 auto & World = m_pConstants->Get<::Object>().World;
1428 const Component::Rotation Rotation{ *_pRotation };
1430 World = ::glm::rotate(World, Rotation.Z, ::glm::vec3{ 0.0f, 0.0f, 1.0f });
1431 World = ::glm::rotate(World, Rotation.Y, ::glm::vec3{ 0.0f, 1.0f, 0.0f });
1432 World = ::glm::rotate(World, Rotation.X, ::glm::vec3{ 1.0f, 0.0f, 0.0f });
1436 auto CreateScale = [&](
const ComponentPtr_t & _pScale)
1438 PreRenders.push_front([=](
void)
1440 auto & World = m_pConstants->Get<::Object>().World;
1442 const Component::Scale Scale{ *_pScale };
1444 World = ::glm::scale(World, ::glm::vec3{ Scale.X, Scale.Y, Scale.Z });
1448 PreRenders.push_front([=](
void)
1450 m_pConstants->Get<::Object>().World =
1451 ::glm::transpose(m_pConstants->Get<::Object>().World);
1454 CapturingServiceComponent::Process(_pComponent,
1456 { uT(
"Position"), CreatePosition },
1457 { uT(
"Rotation"), CreateRotation },
1458 { uT(
"Scale"), CreateScale },
1461 PreRenders.push_front([=](
void)
1463 m_pConstants->Get<::Object>().World = ::glm::identity<::glm::mat4>();
1466 return [PreRenders](void)
1468 for (
auto & Render : PreRenders) Render();
1472template<
class TConstantBuffer>
1473auto DirectX11::CreateStaticTransformRender(
const ComponentPtr_t & _pComponent) -> Render_t
1475 CreateDefaultTransformRender<TConstantBuffer>(_pComponent)();
1476 const auto World = m_pConstants->Get<TConstantBuffer>().World;
1480 m_pConstants->Get<TConstantBuffer>().World = World;
1484template<
class TCamera,
class TConstantBuffer>
1485auto DirectX11::CreateBillboardTransformRender(
const ComponentPtr_t & _pComponent) -> Render_t
1487 ::std::deque<Render_t> PreRenders;
1489 auto CreatePosition = [&](
const ComponentPtr_t & _pPosition)
1491 PreRenders.push_front([=](
void)
1493 auto & World = m_pConstants->Get<TConstantBuffer>().World;
1495 const Component::Position Position{ *_pPosition };
1497 World = ::glm::translate(World,
1498 ::glm::vec3{ Position.X, Position.Y, Position.Z });
1502 PreRenders.push_front([=](
void)
1504 m_pConstants->Get<TConstantBuffer>().World =
1505 ::glm::transpose(m_pConstants->Get<TConstantBuffer>().World);
1508 CapturingServiceComponent::Process(_pComponent,
1509 { { uT(
"Position"), CreatePosition } });
1511 PreRenders.push_front([=](
void)
1513 auto & World = m_pConstants->Get<TConstantBuffer>().World;
1516 World = m_pConstants->Get<::Camera>().View;
1527 return [PreRenders](void)
1529 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:1351
Render_t CreateBkSurface(const ComponentPtr_t &) override
Definition DirectX11.cpp:701
Класс входит в проект Covellite.Api Класс формата вертексного буфера.
Definition Vertex.hpp:34