Direct3D10 support
This commit is contained in:
parent
074af87127
commit
0ae0ba63c0
|
|
@ -51,6 +51,7 @@
|
|||
<ClInclude Include="..\..\src\core\Transition.h" />
|
||||
<ClInclude Include="..\..\src\core\window.h" />
|
||||
<ClInclude Include="..\..\src\dx\D2DDeviceResources.h" />
|
||||
<ClInclude Include="..\..\src\dx\D3D10DeviceResources.h" />
|
||||
<ClInclude Include="..\..\src\dx\D3D11DeviceResources.h" />
|
||||
<ClInclude Include="..\..\src\dx\DeviceResources.h" />
|
||||
<ClInclude Include="..\..\src\dx\helper.hpp" />
|
||||
|
|
@ -107,6 +108,7 @@
|
|||
<ClCompile Include="..\..\src\core\Transition.cpp" />
|
||||
<ClCompile Include="..\..\src\core\window.cpp" />
|
||||
<ClCompile Include="..\..\src\dx\D2DDeviceResources.cpp" />
|
||||
<ClCompile Include="..\..\src\dx\D3D10DeviceResources.cpp" />
|
||||
<ClCompile Include="..\..\src\dx\D3D11DeviceResources.cpp" />
|
||||
<ClCompile Include="..\..\src\dx\TextRenderer.cpp" />
|
||||
<ClCompile Include="..\..\src\math\rand.cpp" />
|
||||
|
|
|
|||
|
|
@ -229,6 +229,9 @@
|
|||
<ClInclude Include="..\..\src\dx\TextRenderer.h">
|
||||
<Filter>dx</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\dx\D3D10DeviceResources.h">
|
||||
<Filter>dx</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\core\Animation.cpp">
|
||||
|
|
@ -366,5 +369,8 @@
|
|||
<ClCompile Include="..\..\src\dx\TextRenderer.cpp">
|
||||
<Filter>dx</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\dx\D3D10DeviceResources.cpp">
|
||||
<Filter>dx</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -43,7 +43,7 @@ namespace easy2d
|
|||
}
|
||||
|
||||
// Class that will implement the singleton mode,
|
||||
// must use the macro in it's delare file
|
||||
// must use the macro in its delare file
|
||||
|
||||
#ifndef E2D_DECLARE_SINGLETON
|
||||
#define E2D_DECLARE_SINGLETON( type ) \
|
||||
|
|
|
|||
|
|
@ -21,3 +21,5 @@
|
|||
//#define E2D_API __declspec( dllexport )
|
||||
//#define E2D_API __declspec( dllimport )
|
||||
|
||||
//---- Define DirectX version. Defaults to using Direct3D11
|
||||
//#define E2D_USE_DIRECTX10
|
||||
|
|
|
|||
|
|
@ -42,42 +42,6 @@ namespace easy2d
|
|||
}
|
||||
}
|
||||
|
||||
DirectX::DirectX()
|
||||
{
|
||||
d2d = LoadLibraryW(L"d2d1.dll");
|
||||
if (d2d)
|
||||
{
|
||||
D2D1CreateFactory = (PFN_D2D1CreateFactory)
|
||||
GetProcAddress(d2d, "D2D1CreateFactory");
|
||||
}
|
||||
else
|
||||
{
|
||||
E2D_LOG(L"load d2d.dll failed");
|
||||
}
|
||||
|
||||
dwrite = LoadLibraryW(L"dwrite.dll");
|
||||
if (dwrite)
|
||||
{
|
||||
DWriteCreateFactory = (PFN_DWriteCreateFactory)
|
||||
GetProcAddress(dwrite, "DWriteCreateFactory");
|
||||
}
|
||||
else
|
||||
{
|
||||
E2D_LOG(L"load dwrite.dll failed");
|
||||
}
|
||||
|
||||
d3d11 = LoadLibraryW(L"d3d11.dll");
|
||||
if (d3d11)
|
||||
{
|
||||
D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)
|
||||
GetProcAddress(d3d11, "D3D11CreateDevice");
|
||||
}
|
||||
else
|
||||
{
|
||||
E2D_LOG(L"load d3d11.dll failed");
|
||||
}
|
||||
}
|
||||
|
||||
XAudio2::XAudio2()
|
||||
{
|
||||
const auto xaudio2_dll_names =
|
||||
|
|
|
|||
|
|
@ -20,13 +20,10 @@
|
|||
|
||||
#pragma once
|
||||
#include "macros.h"
|
||||
#include <d2d1.h>
|
||||
#include <dwrite.h>
|
||||
#include <xaudio2.h>
|
||||
#include <mfapi.h>
|
||||
#include <mfidl.h>
|
||||
#include <mfreadwrite.h>
|
||||
#include <d3d11.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
|
@ -54,31 +51,6 @@ namespace easy2d
|
|||
};
|
||||
|
||||
|
||||
class E2D_API DirectX
|
||||
{
|
||||
DirectX();
|
||||
|
||||
HMODULE d3d11;
|
||||
HMODULE d2d;
|
||||
HMODULE dwrite;
|
||||
|
||||
// DirectX functions
|
||||
typedef HRESULT(WINAPI *PFN_D2D1CreateFactory)(D2D1_FACTORY_TYPE, const IID&, const D2D1_FACTORY_OPTIONS*, void **);
|
||||
typedef HRESULT(WINAPI *PFN_DWriteCreateFactory)(DWRITE_FACTORY_TYPE, const IID&, IUnknown **);
|
||||
|
||||
public:
|
||||
static DirectX& Get()
|
||||
{
|
||||
static DirectX instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
PFN_D2D1CreateFactory D2D1CreateFactory;
|
||||
PFN_DWriteCreateFactory DWriteCreateFactory;
|
||||
PFN_D3D11_CREATE_DEVICE D3D11CreateDevice;
|
||||
};
|
||||
|
||||
|
||||
class E2D_API XAudio2
|
||||
{
|
||||
XAudio2();
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@
|
|||
#include "../DX/DeviceResources.h"
|
||||
#include "../DX/TextRenderer.h"
|
||||
#include "time.h"
|
||||
#include <d2d1.h>
|
||||
#include <d2d1_1.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,11 +18,14 @@
|
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "DeviceResources.h"
|
||||
#include "D2DDeviceResources.h"
|
||||
#include "../core/Image.h"
|
||||
#include "../core/modules.h"
|
||||
#include "../core/logs.h"
|
||||
|
||||
#pragma comment(lib, "d2d1.lib")
|
||||
#pragma comment(lib, "dwrite.lib")
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
||||
|
|
@ -106,7 +109,7 @@ namespace easy2d
|
|||
options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
|
||||
#endif
|
||||
|
||||
hr = modules::DirectX::Get().D2D1CreateFactory(
|
||||
hr = D2D1CreateFactory(
|
||||
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||
__uuidof(ID2D1Factory1),
|
||||
&options,
|
||||
|
|
@ -117,7 +120,7 @@ namespace easy2d
|
|||
{
|
||||
d2d_factory_ = d2d_factory;
|
||||
|
||||
CoCreateInstance(
|
||||
hr = CoCreateInstance(
|
||||
CLSID_WICImagingFactory,
|
||||
nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
|
|
@ -130,7 +133,7 @@ namespace easy2d
|
|||
{
|
||||
imaging_factory_ = imaging_factory;
|
||||
|
||||
modules::DirectX::Get().DWriteCreateFactory(
|
||||
hr = DWriteCreateFactory(
|
||||
DWRITE_FACTORY_TYPE_SHARED,
|
||||
__uuidof(IDWriteFactory),
|
||||
reinterpret_cast<IUnknown**>(&dwrite_factory)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "../core/Resource.h"
|
||||
#include "../core/Font.hpp"
|
||||
#include "../core/TextStyle.hpp"
|
||||
#include <dwrite.h>
|
||||
#include <d2d1.h>
|
||||
#include <d2d1_1.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,434 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "D3D10DeviceResources.h"
|
||||
|
||||
#ifdef E2D_USE_DIRECTX10
|
||||
|
||||
#include "../core/Image.h"
|
||||
#include "../core/logs.h"
|
||||
|
||||
#pragma comment(lib, "d3d10_1.lib")
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
namespace DX
|
||||
{
|
||||
HRESULT CreateD3DDevice(IDXGIAdapter *adapter, D3D10_DRIVER_TYPE driver_type, UINT flags, ID3D10Device1 **device)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
static const D3D10_FEATURE_LEVEL1 levels[] =
|
||||
{
|
||||
D3D10_FEATURE_LEVEL_10_1,
|
||||
D3D10_FEATURE_LEVEL_10_0,
|
||||
D3D10_FEATURE_LEVEL_9_3,
|
||||
D3D10_FEATURE_LEVEL_9_2,
|
||||
D3D10_FEATURE_LEVEL_9_1,
|
||||
};
|
||||
|
||||
for (UINT level = 0; level < ARRAYSIZE(levels); level++)
|
||||
{
|
||||
hr = D3D10CreateDevice1(
|
||||
adapter,
|
||||
driver_type,
|
||||
NULL,
|
||||
flags,
|
||||
levels[level],
|
||||
D3D10_1_SDK_VERSION,
|
||||
device
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
break;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
inline bool SdkLayersAvailable()
|
||||
{
|
||||
HRESULT hr = CreateD3DDevice(
|
||||
NULL,
|
||||
D3D10_DRIVER_TYPE_NULL, // There is no need to create a real hardware device.
|
||||
D3D10_CREATE_DEVICE_DEBUG, // Check for the SDK layers.
|
||||
nullptr // No need to keep the D3D device reference.
|
||||
);
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
D3D10DeviceResources::D3D10DeviceResources()
|
||||
: hwnd_(nullptr)
|
||||
{
|
||||
dpi_ = 96.f; // dpi_ = (float)GetDpiForWindow(hwnd);
|
||||
}
|
||||
|
||||
D3D10DeviceResources::~D3D10DeviceResources()
|
||||
{
|
||||
DiscardResources();
|
||||
}
|
||||
|
||||
HRESULT D3D10DeviceResources::Create(D3D10DeviceResources** device_resources, HWND hwnd)
|
||||
{
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
if (device_resources)
|
||||
{
|
||||
D3D10DeviceResources* res = new (std::nothrow) D3D10DeviceResources;
|
||||
if (res)
|
||||
{
|
||||
hr = res->CreateDeviceIndependentResources();
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(hwnd, &rc);
|
||||
|
||||
res->hwnd_ = hwnd;
|
||||
res->logical_size_.x = float(rc.right - rc.left);
|
||||
res->logical_size_.y = float(rc.bottom - rc.top);
|
||||
|
||||
hr = res->CreateDeviceResources();
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = res->CreateWindowSizeDependentResources();
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
res->AddRef();
|
||||
|
||||
DX::SafeRelease(*device_resources);
|
||||
(*device_resources) = res;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete res;
|
||||
res = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
void D3D10DeviceResources::DiscardResources()
|
||||
{
|
||||
d3d_device_.Reset();
|
||||
d3d_rt_view_.Reset();
|
||||
d3d_ds_view_.Reset();
|
||||
dxgi_swap_chain_.Reset();
|
||||
dxgi_factory_.Reset();
|
||||
|
||||
hwnd_ = nullptr;
|
||||
}
|
||||
|
||||
HRESULT D3D10DeviceResources::CreateDeviceResources()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// This flag adds support for surfaces with a different color channel ordering
|
||||
// than the API default. It is required for compatibility with Direct2D.
|
||||
UINT creation_flags = D3D10_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
|
||||
#if defined(E2D_DEBUG)
|
||||
if (DX::SdkLayersAvailable())
|
||||
{
|
||||
creation_flags |= D3D10_CREATE_DEVICE_DEBUG;
|
||||
}
|
||||
#endif
|
||||
|
||||
ComPtr<ID3D10Device1> device;
|
||||
hr = DX::CreateD3DDevice(
|
||||
NULL,
|
||||
D3D10_DRIVER_TYPE_HARDWARE,
|
||||
creation_flags,
|
||||
&device
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
d3d_device_ = device;
|
||||
|
||||
ComPtr<IDXGIAdapter> dxgi_adapter;
|
||||
ComPtr<IDXGIDevice> dxgi_device;
|
||||
ComPtr<IDXGIFactory> dxgi_factory;
|
||||
ComPtr<ID2D1Device> d2d_device;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = d3d_device_->QueryInterface(IID_PPV_ARGS(&dxgi_device));
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = dxgi_device->GetAdapter(&dxgi_adapter);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory));
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
dxgi_factory_ = dxgi_factory;
|
||||
}
|
||||
|
||||
// Create the Direct2D device object and a corresponding context.
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = GetD2DFactory()->CreateDevice(dxgi_device.Get(), &d2d_device);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = SetD2DDevice(d2d_device);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// Setup swap chain
|
||||
DXGI_SWAP_CHAIN_DESC swap_chain_desc = { 0 };
|
||||
|
||||
swap_chain_desc.BufferCount = 2;
|
||||
swap_chain_desc.BufferDesc.Width = ::lround(output_size_.x);
|
||||
swap_chain_desc.BufferDesc.Height = ::lround(output_size_.y);
|
||||
swap_chain_desc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
swap_chain_desc.BufferDesc.RefreshRate.Numerator = 60;
|
||||
swap_chain_desc.BufferDesc.RefreshRate.Denominator = 1;
|
||||
swap_chain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swap_chain_desc.OutputWindow = hwnd_;
|
||||
swap_chain_desc.SampleDesc.Count = 1;
|
||||
swap_chain_desc.SampleDesc.Quality = 0;
|
||||
swap_chain_desc.Windowed = TRUE;
|
||||
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
|
||||
ComPtr<IDXGIDevice> dxgi_device;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = d3d_device_->QueryInterface(&dxgi_device);
|
||||
}
|
||||
|
||||
ComPtr<IDXGIAdapter> dxgi_adapter;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = dxgi_device->GetAdapter(&dxgi_adapter);
|
||||
}
|
||||
|
||||
ComPtr<IDXGIFactory> dxgi_factory;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory));
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = dxgi_factory->CreateSwapChain(
|
||||
d3d_device_.Get(),
|
||||
&swap_chain_desc,
|
||||
&dxgi_swap_chain_);
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT D3D10DeviceResources::CreateWindowSizeDependentResources()
|
||||
{
|
||||
if (!dxgi_swap_chain_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// Clear the previous window size specific context.
|
||||
ID3D10RenderTargetView* null_views[] = { nullptr };
|
||||
SetTargetBitmap(nullptr);
|
||||
d3d_device_->OMSetRenderTargets(ARRAYSIZE(null_views), null_views, nullptr);
|
||||
d3d_device_->Flush();
|
||||
|
||||
// Calculate the necessary render target size in pixels.
|
||||
output_size_.x = DX::ConvertDipsToPixels(logical_size_.x, dpi_);
|
||||
output_size_.y = DX::ConvertDipsToPixels(logical_size_.y, dpi_);
|
||||
|
||||
// Prevent zero size DirectX content from being created.
|
||||
output_size_.x = std::max(output_size_.x, 1.f);
|
||||
output_size_.y = std::max(output_size_.y, 1.f);
|
||||
|
||||
// If the swap chain already exists, resize it.
|
||||
hr = dxgi_swap_chain_->ResizeBuffers(
|
||||
2, // Double-buffered swap chain.
|
||||
::lround(output_size_.x),
|
||||
::lround(output_size_.y),
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
0);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// Create the render target view and set it on the device
|
||||
ComPtr<ID3D10Resource> dxgi_back_buffer;
|
||||
|
||||
hr = dxgi_swap_chain_->GetBuffer(
|
||||
0,
|
||||
IID_PPV_ARGS(&dxgi_back_buffer)
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
D3D10_RENDER_TARGET_VIEW_DESC renderDesc;
|
||||
renderDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
renderDesc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D;
|
||||
renderDesc.Texture2D.MipSlice = 0;
|
||||
|
||||
d3d_rt_view_ = nullptr;
|
||||
hr = d3d_device_->CreateRenderTargetView(dxgi_back_buffer.Get(), &renderDesc, &d3d_rt_view_);
|
||||
}
|
||||
|
||||
ComPtr<ID3D10Texture2D> depth_stencil;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
D3D10_TEXTURE2D_DESC tex_desc;
|
||||
tex_desc.ArraySize = 1;
|
||||
tex_desc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
|
||||
tex_desc.CPUAccessFlags = 0;
|
||||
tex_desc.Format = DXGI_FORMAT_D16_UNORM;
|
||||
tex_desc.Width = static_cast<UINT>(output_size_.x);
|
||||
tex_desc.Height = static_cast<UINT>(output_size_.y);
|
||||
tex_desc.MipLevels = 1;
|
||||
tex_desc.MiscFlags = 0;
|
||||
tex_desc.SampleDesc.Count = 1;
|
||||
tex_desc.SampleDesc.Quality = 0;
|
||||
tex_desc.Usage = D3D10_USAGE_DEFAULT;
|
||||
|
||||
hr = d3d_device_->CreateTexture2D(&tex_desc, NULL, &depth_stencil);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
D3D10_DEPTH_STENCIL_VIEW_DESC desc;
|
||||
desc.Format = DXGI_FORMAT_D16_UNORM;
|
||||
desc.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
|
||||
desc.Texture2D.MipSlice = 0;
|
||||
|
||||
d3d_ds_view_.Reset();
|
||||
hr = d3d_device_->CreateDepthStencilView(depth_stencil.Get(), &desc, &d3d_ds_view_);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ID3D10RenderTargetView* views[] = { d3d_rt_view_.Get() };
|
||||
d3d_device_->OMSetRenderTargets(1, views, d3d_ds_view_.Get());
|
||||
|
||||
// Set a new viewport based on the new dimensions
|
||||
D3D10_VIEWPORT viewport;
|
||||
viewport.Width = static_cast<UINT>(output_size_.x);
|
||||
viewport.Height = static_cast<UINT>(output_size_.y);
|
||||
viewport.TopLeftX = 0;
|
||||
viewport.TopLeftY = 0;
|
||||
viewport.MinDepth = 0;
|
||||
viewport.MaxDepth = 1;
|
||||
|
||||
d3d_device_->RSSetViewports(1, &viewport);
|
||||
}
|
||||
|
||||
// Create a Direct2D target bitmap associated with the
|
||||
// swap chain back buffer and set it as the current target.
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ComPtr<IDXGISurface> dxgi_back_buffer;
|
||||
hr = dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer));
|
||||
|
||||
ComPtr<ID2D1Bitmap1> target;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = GetD2DDeviceContext()->CreateBitmapFromDxgiSurface(
|
||||
dxgi_back_buffer.Get(),
|
||||
D2D1::BitmapProperties1(
|
||||
D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
|
||||
D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
|
||||
dpi_,
|
||||
dpi_),
|
||||
&target);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
SetTargetBitmap(target);
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT D3D10DeviceResources::HandleDeviceLost()
|
||||
{
|
||||
dxgi_swap_chain_ = nullptr;
|
||||
|
||||
HRESULT hr = CreateDeviceResources();
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = CreateWindowSizeDependentResources();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
void D3D10DeviceResources::SetLogicalSize(Size logical_size)
|
||||
{
|
||||
if (logical_size_ != logical_size)
|
||||
{
|
||||
logical_size_ = logical_size;
|
||||
|
||||
ThrowIfFailed(
|
||||
CreateWindowSizeDependentResources()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void D3D10DeviceResources::SetDpi(float dpi)
|
||||
{
|
||||
if (dpi != dpi_)
|
||||
{
|
||||
dpi_ = dpi;
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(hwnd_, &rc);
|
||||
|
||||
logical_size_.x = float(rc.right - rc.left);
|
||||
logical_size_.y = float(rc.bottom - rc.top);
|
||||
|
||||
GetD2DDeviceContext()->SetDpi(dpi_, dpi_);
|
||||
|
||||
ThrowIfFailed(
|
||||
CreateWindowSizeDependentResources()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // !E2D_USE_DIRECTX10
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - Nomango
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef E2D_USE_DIRECTX10
|
||||
|
||||
#include "helper.hpp"
|
||||
#include "D2DDeviceResources.h"
|
||||
#include <d3d10_1.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API D3D10DeviceResources
|
||||
: public D2DDeviceResources
|
||||
{
|
||||
public:
|
||||
static HRESULT Create(
|
||||
D3D10DeviceResources** device_resources,
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
HRESULT HandleDeviceLost();
|
||||
|
||||
void SetLogicalSize(
|
||||
Size logical_size
|
||||
);
|
||||
|
||||
void SetDpi(
|
||||
float dpi
|
||||
);
|
||||
|
||||
void DiscardResources();
|
||||
|
||||
inline ID3D10Device* GetD3DDevice() const { return d3d_device_.Get(); }
|
||||
inline ID3D10RenderTargetView* GetD3DRenderTargetView() const { return d3d_rt_view_.Get(); }
|
||||
inline ID3D10DepthStencilView* GetD3DDepthStencilView() const { return d3d_ds_view_.Get(); }
|
||||
inline IDXGIFactory* GetDXGIFactory() const { return dxgi_factory_.Get(); }
|
||||
inline IDXGISwapChain* GetDXGISwapChain() const { return dxgi_swap_chain_.Get(); }
|
||||
|
||||
inline Size const& GetLogicalSize() const { return logical_size_; }
|
||||
inline Size const& GetOutputSize() const { return output_size_; }
|
||||
inline float GetDpi() const { return dpi_; }
|
||||
|
||||
protected:
|
||||
D3D10DeviceResources();
|
||||
|
||||
virtual ~D3D10DeviceResources();
|
||||
|
||||
protected:
|
||||
HRESULT CreateDeviceResources();
|
||||
|
||||
HRESULT CreateWindowSizeDependentResources();
|
||||
|
||||
private:
|
||||
HWND hwnd_;
|
||||
float dpi_;
|
||||
Size logical_size_;
|
||||
Size output_size_;
|
||||
|
||||
ComPtr<ID3D10Device> d3d_device_;
|
||||
ComPtr<ID3D10RenderTargetView> d3d_rt_view_;
|
||||
ComPtr<ID3D10DepthStencilView> d3d_ds_view_;
|
||||
ComPtr<IDXGISwapChain> dxgi_swap_chain_;
|
||||
ComPtr<IDXGIFactory> dxgi_factory_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // !E2D_USE_DIRECTX10
|
||||
|
|
@ -18,11 +18,15 @@
|
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "DeviceResources.h"
|
||||
#include "D3D11DeviceResources.h"
|
||||
|
||||
#ifndef E2D_USE_DIRECTX10
|
||||
|
||||
#include "../core/Image.h"
|
||||
#include "../core/modules.h"
|
||||
#include "../core/logs.h"
|
||||
|
||||
#pragma comment(lib, "d3d11.lib")
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
|
|
@ -30,14 +34,14 @@ namespace easy2d
|
|||
{
|
||||
inline bool SdkLayersAvailable()
|
||||
{
|
||||
HRESULT hr = modules::DirectX::Get().D3D11CreateDevice(
|
||||
HRESULT hr = D3D11CreateDevice(
|
||||
nullptr,
|
||||
D3D_DRIVER_TYPE_NULL, // There is no need to create a real hardware device.
|
||||
0,
|
||||
D3D11_CREATE_DEVICE_DEBUG, // Check for the SDK layers.
|
||||
nullptr, // Any feature level will do.
|
||||
0,
|
||||
D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Runtime apps.
|
||||
D3D11_SDK_VERSION,
|
||||
nullptr, // No need to keep the D3D device reference.
|
||||
nullptr, // No need to know the feature level.
|
||||
nullptr // No need to keep the D3D device context reference.
|
||||
|
|
@ -109,6 +113,8 @@ namespace easy2d
|
|||
{
|
||||
d3d_device_.Reset();
|
||||
d3d_device_context_.Reset();
|
||||
d3d_rt_view_.Reset();
|
||||
d3d_ds_view_.Reset();
|
||||
dxgi_swap_chain_.Reset();
|
||||
dxgi_factory_.Reset();
|
||||
|
||||
|
|
@ -119,7 +125,7 @@ namespace easy2d
|
|||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
D3D_FEATURE_LEVEL feature_levels[] =
|
||||
static const D3D_FEATURE_LEVEL feature_levels[] =
|
||||
{
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
|
|
@ -144,7 +150,7 @@ namespace easy2d
|
|||
}
|
||||
#endif
|
||||
|
||||
hr = modules::DirectX::Get().D3D11CreateDevice(
|
||||
hr = D3D11CreateDevice(
|
||||
nullptr, // Specify nullptr to use the default adapter.
|
||||
D3D_DRIVER_TYPE_HARDWARE,
|
||||
0, // Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE.
|
||||
|
|
@ -162,7 +168,7 @@ namespace easy2d
|
|||
// If the initialization fails, fall back to the WARP device.
|
||||
// For more information on WARP, see:
|
||||
// http://go.microsoft.com/fwlink/?LinkId=286690
|
||||
hr = modules::DirectX::Get().D3D11CreateDevice(
|
||||
hr = D3D11CreateDevice(
|
||||
nullptr,
|
||||
D3D_DRIVER_TYPE_WARP, // Create a WARP device instead of a hardware device.
|
||||
0,
|
||||
|
|
@ -218,38 +224,7 @@ namespace easy2d
|
|||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT D3D11DeviceResources::CreateWindowSizeDependentResources()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// Clear the previous window size specific context.
|
||||
ID3D11RenderTargetView* null_views[] = { nullptr };
|
||||
SetTargetBitmap(nullptr);
|
||||
d3d_device_context_->OMSetRenderTargets(ARRAYSIZE(null_views), null_views, nullptr);
|
||||
d3d_device_context_->Flush();
|
||||
|
||||
// Calculate the necessary render target size in pixels.
|
||||
output_size_.x = DX::ConvertDipsToPixels(logical_size_.x, dpi_);
|
||||
output_size_.y = DX::ConvertDipsToPixels(logical_size_.y, dpi_);
|
||||
|
||||
// Prevent zero size DirectX content from being created.
|
||||
output_size_.x = std::max(output_size_.x, 1.f);
|
||||
output_size_.y = std::max(output_size_.y, 1.f);
|
||||
|
||||
if (dxgi_swap_chain_)
|
||||
{
|
||||
// If the swap chain already exists, resize it.
|
||||
hr = dxgi_swap_chain_->ResizeBuffers(
|
||||
2, // Double-buffered swap chain.
|
||||
::lround(output_size_.x),
|
||||
::lround(output_size_.y),
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
0);
|
||||
}
|
||||
else
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// Setup swap chain
|
||||
DXGI_SWAP_CHAIN_DESC swap_chain_desc = { 0 };
|
||||
|
|
@ -295,8 +270,80 @@ namespace easy2d
|
|||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT D3D11DeviceResources::CreateWindowSizeDependentResources()
|
||||
{
|
||||
if (!dxgi_swap_chain_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// Clear the previous window size specific context.
|
||||
ID3D11RenderTargetView* null_views[] = { nullptr };
|
||||
SetTargetBitmap(nullptr);
|
||||
d3d_device_context_->OMSetRenderTargets(ARRAYSIZE(null_views), null_views, nullptr);
|
||||
d3d_device_context_->Flush();
|
||||
|
||||
// Calculate the necessary render target size in pixels.
|
||||
output_size_.x = DX::ConvertDipsToPixels(logical_size_.x, dpi_);
|
||||
output_size_.y = DX::ConvertDipsToPixels(logical_size_.y, dpi_);
|
||||
|
||||
// Prevent zero size DirectX content from being created.
|
||||
output_size_.x = std::max(output_size_.x, 1.f);
|
||||
output_size_.y = std::max(output_size_.y, 1.f);
|
||||
|
||||
// If the swap chain already exists, resize it.
|
||||
hr = dxgi_swap_chain_->ResizeBuffers(
|
||||
2, // Double-buffered swap chain.
|
||||
::lround(output_size_.x),
|
||||
::lround(output_size_.y),
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
0);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// Create the render target view and set it on the device
|
||||
ComPtr<ID3D11Resource> dxgi_back_buffer;
|
||||
|
||||
hr = dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer));
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
d3d_rt_view_ = nullptr;
|
||||
hr = d3d_device_->CreateRenderTargetView(dxgi_back_buffer.Get(), nullptr, &d3d_rt_view_);
|
||||
}
|
||||
|
||||
ComPtr<ID3D11Texture2D> depth_stencil;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
CD3D11_TEXTURE2D_DESC tex_desc(
|
||||
DXGI_FORMAT_D24_UNORM_S8_UINT,
|
||||
static_cast<UINT>(output_size_.x),
|
||||
static_cast<UINT>(output_size_.y),
|
||||
1, // This depth stencil view has only one texture.
|
||||
1, // Use a single mipmap level.
|
||||
D3D11_BIND_DEPTH_STENCIL
|
||||
);
|
||||
|
||||
hr = d3d_device_->CreateTexture2D(&tex_desc, nullptr, &depth_stencil);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
CD3D11_DEPTH_STENCIL_VIEW_DESC desc(D3D11_DSV_DIMENSION_TEXTURE2D);
|
||||
|
||||
d3d_ds_view_.Reset();
|
||||
hr = d3d_device_->CreateDepthStencilView(depth_stencil.Get(), &desc, &d3d_ds_view_);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ID3D11RenderTargetView* views[] = { d3d_rt_view_.Get() };
|
||||
d3d_device_context_->OMSetRenderTargets(1, views, d3d_ds_view_.Get());
|
||||
|
||||
// Set the 3D rendering viewport to target the entire window.
|
||||
CD3D11_VIEWPORT screen_viewport(
|
||||
0.0f,
|
||||
|
|
@ -311,13 +358,6 @@ namespace easy2d
|
|||
// swap chain back buffer and set it as the current target.
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
D2D1_BITMAP_PROPERTIES1 bitmap_props =
|
||||
D2D1::BitmapProperties1(
|
||||
D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
|
||||
D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
|
||||
dpi_,
|
||||
dpi_);
|
||||
|
||||
ComPtr<IDXGISurface> dxgi_back_buffer;
|
||||
hr = dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer));
|
||||
|
||||
|
|
@ -326,7 +366,11 @@ namespace easy2d
|
|||
{
|
||||
hr = GetD2DDeviceContext()->CreateBitmapFromDxgiSurface(
|
||||
dxgi_back_buffer.Get(),
|
||||
&bitmap_props,
|
||||
D2D1::BitmapProperties1(
|
||||
D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
|
||||
D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
|
||||
dpi_,
|
||||
dpi_),
|
||||
&target);
|
||||
}
|
||||
|
||||
|
|
@ -385,3 +429,5 @@ namespace easy2d
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // !E2D_USE_DIRECTX10
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef E2D_USE_DIRECTX10
|
||||
|
||||
#include "helper.hpp"
|
||||
#include "D2DDeviceResources.h"
|
||||
#include <d3d11.h>
|
||||
|
|
@ -48,6 +51,8 @@ namespace easy2d
|
|||
|
||||
inline ID3D11Device* GetD3DDevice() const { return d3d_device_.Get(); }
|
||||
inline ID3D11DeviceContext* GetD3DDeviceContext() const { return d3d_device_context_.Get(); }
|
||||
inline ID3D11RenderTargetView* GetD3DRenderTargetView() const { return d3d_rt_view_.Get(); }
|
||||
inline ID3D11DepthStencilView* GetD3DDepthStencilView() const { return d3d_ds_view_.Get(); }
|
||||
inline IDXGIFactory* GetDXGIFactory() const { return dxgi_factory_.Get(); }
|
||||
inline IDXGISwapChain* GetDXGISwapChain() const { return dxgi_swap_chain_.Get(); }
|
||||
|
||||
|
|
@ -67,16 +72,21 @@ namespace easy2d
|
|||
HRESULT CreateWindowSizeDependentResources();
|
||||
|
||||
private:
|
||||
HWND hwnd_;
|
||||
float dpi_;
|
||||
Size logical_size_;
|
||||
Size output_size_;
|
||||
HWND hwnd_;
|
||||
float dpi_;
|
||||
Size logical_size_;
|
||||
Size output_size_;
|
||||
|
||||
D3D_FEATURE_LEVEL d3d_feature_level_;
|
||||
|
||||
ComPtr<ID3D11Device> d3d_device_;
|
||||
ComPtr<ID3D11DeviceContext> d3d_device_context_;
|
||||
ComPtr<IDXGISwapChain> dxgi_swap_chain_;
|
||||
ComPtr<IDXGIFactory> dxgi_factory_;
|
||||
ComPtr<ID3D11Device> d3d_device_;
|
||||
ComPtr<ID3D11DeviceContext> d3d_device_context_;
|
||||
ComPtr<ID3D11RenderTargetView> d3d_rt_view_;
|
||||
ComPtr<ID3D11DepthStencilView> d3d_ds_view_;
|
||||
ComPtr<IDXGISwapChain> dxgi_swap_chain_;
|
||||
ComPtr<IDXGIFactory> dxgi_factory_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // !E2D_USE_DIRECTX10
|
||||
|
|
|
|||
|
|
@ -19,9 +19,21 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "D3D11DeviceResources.h"
|
||||
#include "../core/macros.h"
|
||||
|
||||
#ifdef E2D_USE_DIRECTX10
|
||||
# include "D3D10DeviceResources.h"
|
||||
#else
|
||||
# include "D3D11DeviceResources.h"
|
||||
#endif
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
||||
#ifdef E2D_USE_DIRECTX10
|
||||
using DeviceResources = D3D10DeviceResources;
|
||||
#else
|
||||
using DeviceResources = D3D11DeviceResources;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ namespace easy2d
|
|||
{
|
||||
}
|
||||
|
||||
Matrix(const float* p)
|
||||
explicit Matrix(const float* p)
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
m[i] = p[i];
|
||||
|
|
|
|||
Loading…
Reference in New Issue