Split d2d integration into own class.

This commit is contained in:
jmsgrogan 2023-01-11 16:27:25 +00:00
parent 0d3674faac
commit 0c84a53643
25 changed files with 361 additions and 155 deletions

View file

@ -48,6 +48,7 @@ if(UNIX)
else() else()
list(APPEND graphics_LIB_INCLUDES list(APPEND graphics_LIB_INCLUDES
directx/DirectXInterface.cpp directx/DirectXInterface.cpp
directx/DirectX2dInterface.cpp
directx/DirectXMesh.cpp directx/DirectXMesh.cpp
directx/DirectXPainter.cpp directx/DirectXPainter.cpp
directx/DirectX2dPainter.cpp directx/DirectX2dPainter.cpp
@ -57,6 +58,7 @@ else()
) )
list(APPEND graphics_HEADERS list(APPEND graphics_HEADERS
directx/DirectXInterface.h directx/DirectXInterface.h
directx/DirectX2dInterface.h
directx/DirectXMesh.h directx/DirectXMesh.h
directx/DirectXPainter.h directx/DirectXPainter.h
directx/DirectX2dPainter.h directx/DirectX2dPainter.h

View file

@ -0,0 +1,67 @@
#include "DirectX2dInterface.h"
#include "DirectXInterface.h"
#include "FileLogger.h"
#include <dxgi.h>
#include <d2d1_3.h>
#include <d2d1_1.h>
#include <dwrite.h>
DirectX2dInterface::DirectX2dInterface(DirectXInterface* dxInterface)
: mDxInterface(dxInterface)
{
}
bool DirectX2dInterface::isValid() const
{
return mIsValid;
}
ID2D1Factory3* DirectX2dInterface::getFactory() const
{
return mFactory.Get();
}
IDWriteFactory* DirectX2dInterface::getDirectWriteFactory() const
{
return mDWriteFactory.Get();
}
ID2D1DeviceContext2* DirectX2dInterface::getContext() const
{
return mDeviceContext.Get();
}
void DirectX2dInterface::initializeStandalone(IWICBitmap* bitmap, bool useSoftware)
{
D2D1_FACTORY_OPTIONS d2dFactoryOptions = {};
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory3), &d2dFactoryOptions, &mFactory);
auto hr = mFactory->CreateWicBitmapRenderTarget(bitmap, D2D1::RenderTargetProperties(), &mRenderTarget);
}
ID2D1RenderTarget* DirectX2dInterface::getRenderTarget() const
{
return mRenderTarget.Get();
}
bool DirectX2dInterface::initialize(IDXGIDevice* device)
{
D2D1_FACTORY_OPTIONS d2dFactoryOptions = {};
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory3), &d2dFactoryOptions, &mFactory);
mFactory->CreateDevice(device, &mDevice);
D2D1_DEVICE_CONTEXT_OPTIONS deviceOptions = D2D1_DEVICE_CONTEXT_OPTIONS_NONE;
mDevice->CreateDeviceContext(deviceOptions, &mDeviceContext);
return initializeDirectWrite();
}
bool DirectX2dInterface::initializeDirectWrite()
{
return SUCCEEDED(::DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), &mDWriteFactory));
}

View file

@ -0,0 +1,44 @@
#pragma once
#include <wrl.h>
#include <dwrite.h>
#include <d2d1_3.h>
class DirectXInterface;
struct IDWriteFactory;
struct ID2D1Factory3;
struct ID2D1Device2;
struct ID2D1DeviceContext2;
struct ID2D1RenderTarget;
struct IWICBitmap;
struct IDXGIDevice;
class DirectX2dInterface
{
public:
DirectX2dInterface(DirectXInterface* dxInterface);
ID2D1Factory3* getFactory() const;
ID2D1DeviceContext2* getContext() const;
IDWriteFactory* getDirectWriteFactory() const;
ID2D1RenderTarget* getRenderTarget() const;
bool initialize(IDXGIDevice* device);
void initializeStandalone(IWICBitmap* bitmap, bool useSoftware = true);
bool isValid() const;
private:
bool initializeDirectWrite();
bool mIsValid{ false };
DirectXInterface* mDxInterface{ nullptr };
Microsoft::WRL::ComPtr<ID2D1Factory3> mFactory;
Microsoft::WRL::ComPtr<ID2D1Device2> mDevice;
Microsoft::WRL::ComPtr<ID2D1DeviceContext2> mDeviceContext;
Microsoft::WRL::ComPtr<IDWriteFactory> mDWriteFactory;
Microsoft::WRL::ComPtr<ID2D1RenderTarget> mRenderTarget;
};

View file

@ -1,6 +1,13 @@
#include "DirectX2dPainter.h" #include "DirectX2dPainter.h"
void DirectX2dPainter::paint(ID2D1DeviceContext2* context, AbstractGeometricItem* item) #include "DirectX2dInterface.h"
void DirectX2dPainter::paint(AbstractGeometricItem* item)
{ {
} }
void DirectX2dPainter::setD2dInterface(DirectX2dInterface* d2dIterface)
{
mD2dInterface = d2dIterface;
}

View file

@ -1,11 +1,15 @@
#pragma once #pragma once
class AbstractGeometricItem; class AbstractGeometricItem;
class DirectX2dInterface;
struct ID2D1DeviceContext2;
class DirectX2dPainter class DirectX2dPainter
{ {
public: public:
void paint(ID2D1DeviceContext2* context, AbstractGeometricItem* item); void paint(AbstractGeometricItem* item);
void setD2dInterface(DirectX2dInterface* d2dIterface);
private:
DirectX2dInterface* mD2dInterface{ nullptr };
}; };

View file

@ -1,5 +1,6 @@
#include "DirectXInterface.h" #include "DirectXInterface.h"
#include "DirectX2dInterface.h"
#include "FileLogger.h" #include "FileLogger.h"
#include <dxgi.h> #include <dxgi.h>
@ -9,10 +10,11 @@
#include <d3d12.h> #include <d3d12.h>
#include <d3d12sdklayers.h> #include <d3d12sdklayers.h>
#include <d2d1_3.h> DirectXInterface::DirectXInterface()
#include <d2d1_1.h> : mD2dInterface(std::make_unique<DirectX2dInterface>(this))
{
#include <dwrite.h> }
void DirectXInterface::getHardwareAdapter(IDXGIAdapter1** ppAdapter) void DirectXInterface::getHardwareAdapter(IDXGIAdapter1** ppAdapter)
{ {
@ -53,21 +55,6 @@ IDXGIFactory7* DirectXInterface::getDxgiFactory() const
return mDxgiFactory.Get(); return mDxgiFactory.Get();
} }
ID2D1Factory3* DirectXInterface::getD2dFactory() const
{
return mD2dFactory.Get();
}
IDWriteFactory* DirectXInterface::getDirectWriteFactory() const
{
return mDWriteFactory.Get();
}
ID2D1DeviceContext2* DirectXInterface::getD2dContext() const
{
return mD2dDeviceContext.Get();
}
ID3D12CommandQueue* DirectXInterface::getCommandQueue() const ID3D12CommandQueue* DirectXInterface::getCommandQueue() const
{ {
return mCommandQueue.Get(); return mCommandQueue.Get();
@ -78,6 +65,11 @@ ID3D11DeviceContext* DirectXInterface::getD3d11DeviceContext() const
return mD3d11DeviceContext.Get(); return mD3d11DeviceContext.Get();
} }
DirectX2dInterface* DirectXInterface::getD2dInterface() const
{
return mD2dInterface.get();
}
void DirectXInterface::initialize() void DirectXInterface::initialize()
{ {
MLOG_INFO("Initialize DirectX"); MLOG_INFO("Initialize DirectX");
@ -89,15 +81,15 @@ void DirectXInterface::initialize()
createCommandQueue(); createCommandQueue();
mIsValid = initializeD2d(); if (!initializeD11on12())
} {
mIsValid = false;
void DirectXInterface::initializeD2dStandalone() return;
{ }
D2D1_FACTORY_OPTIONS d2dFactoryOptions = {};
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory3), &d2dFactoryOptions, &mD2dFactory);
Microsoft::WRL::ComPtr<IDXGIDevice> dxgiDevice;
mD3d11On12Device.As(&dxgiDevice);
mIsValid = mD2dInterface->initialize(dxgiDevice.Get());
} }
bool DirectXInterface::createD3dFactory() bool DirectXInterface::createD3dFactory()
@ -161,26 +153,6 @@ bool DirectXInterface::createCommandQueue()
return true; return true;
} }
bool DirectXInterface::initializeD2d()
{
if (!initializeD11on12())
{
return false;
}
D2D1_FACTORY_OPTIONS d2dFactoryOptions = {};
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory3), &d2dFactoryOptions, &mD2dFactory);
Microsoft::WRL::ComPtr<IDXGIDevice> dxgiDevice;
mD3d11On12Device.As(&dxgiDevice);
mD2dFactory->CreateDevice(dxgiDevice.Get(), &mD2dDevice);
D2D1_DEVICE_CONTEXT_OPTIONS deviceOptions = D2D1_DEVICE_CONTEXT_OPTIONS_NONE;
mD2dDevice->CreateDeviceContext(deviceOptions, &mD2dDeviceContext);
return initializeDirectWrite();
}
bool DirectXInterface::initializeD11on12() bool DirectXInterface::initializeD11on12()
{ {
Microsoft::WRL::ComPtr<ID3D11Device> d3d11Device; Microsoft::WRL::ComPtr<ID3D11Device> d3d11Device;
@ -194,8 +166,3 @@ bool DirectXInterface::initializeD11on12()
d3d11Device.As(&mD3d11On12Device); d3d11Device.As(&mD3d11On12Device);
return true; return true;
} }
bool DirectXInterface::initializeDirectWrite()
{
return SUCCEEDED(::DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), &mDWriteFactory));
}

View file

@ -1,11 +1,13 @@
#pragma once #pragma once
#include <wrl.h> #include <wrl.h>
#include <dwrite.h>
#include <d2d1_3.h>
#include <d3d11on12.h> #include <d3d11on12.h>
#include <dxgi1_6.h> #include <dxgi1_6.h>
#include <memory>
class DirectX2dInterface;
struct ID3D12Device; struct ID3D12Device;
struct IDXGIFactory7; struct IDXGIFactory7;
struct IDXGIAdapter1; struct IDXGIAdapter1;
@ -14,27 +16,21 @@ struct ID3D12CommandQueue;
struct ID3D11DeviceContext; struct ID3D11DeviceContext;
struct ID3D11On12Device; struct ID3D11On12Device;
struct IDWriteFactory;
struct ID2D1Factory3;
struct ID2D1Device2;
struct ID2D1DeviceContext2;
class DirectXInterface class DirectXInterface
{ {
public: public:
DirectXInterface();
IDXGIFactory7* getDxgiFactory() const; IDXGIFactory7* getDxgiFactory() const;
ID3D12Device* getD3dDevice() const; ID3D12Device* getD3dDevice() const;
ID3D12CommandQueue* getCommandQueue() const; ID3D12CommandQueue* getCommandQueue() const;
ID3D11On12Device* get11On12Device() const; ID3D11On12Device* get11On12Device() const;
ID3D11DeviceContext* getD3d11DeviceContext() const; ID3D11DeviceContext* getD3d11DeviceContext() const;
ID2D1Factory3* getD2dFactory() const;
ID2D1DeviceContext2* getD2dContext() const; DirectX2dInterface* getD2dInterface() const;
IDWriteFactory* getDirectWriteFactory() const;
void initialize(); void initialize();
void initializeD2dStandalone();
bool isValid() const; bool isValid() const;
private: private:
@ -44,9 +40,7 @@ private:
void getHardwareAdapter(IDXGIAdapter1** ppAdapter); void getHardwareAdapter(IDXGIAdapter1** ppAdapter);
bool initializeD2d();
bool initializeD11on12(); bool initializeD11on12();
bool initializeDirectWrite();
bool mIsValid{ false }; bool mIsValid{ false };
@ -54,11 +48,8 @@ private:
Microsoft::WRL::ComPtr<ID3D12Device> mD3dDevice; Microsoft::WRL::ComPtr<ID3D12Device> mD3dDevice;
Microsoft::WRL::ComPtr<ID3D12CommandQueue> mCommandQueue; Microsoft::WRL::ComPtr<ID3D12CommandQueue> mCommandQueue;
// 2D Rendering - e.g. text
Microsoft::WRL::ComPtr<ID3D11DeviceContext> mD3d11DeviceContext; Microsoft::WRL::ComPtr<ID3D11DeviceContext> mD3d11DeviceContext;
Microsoft::WRL::ComPtr<ID3D11On12Device> mD3d11On12Device; Microsoft::WRL::ComPtr<ID3D11On12Device> mD3d11On12Device;
Microsoft::WRL::ComPtr<ID2D1Factory3> mD2dFactory;
Microsoft::WRL::ComPtr<ID2D1Device2> mD2dDevice; std::unique_ptr<DirectX2dInterface> mD2dInterface;
Microsoft::WRL::ComPtr<ID2D1DeviceContext2> mD2dDeviceContext;
Microsoft::WRL::ComPtr<IDWriteFactory> mDWriteFactory;
}; };

View file

@ -10,6 +10,7 @@
#include "DirectXShaderProgram.h" #include "DirectXShaderProgram.h"
#include "DirectXMesh.h" #include "DirectXMesh.h"
#include "DirectXInterface.h"
#include <windows.h> #include <windows.h>
#include <iostream> #include <iostream>
@ -23,18 +24,23 @@ DirectXMeshPainter::DirectXMeshPainter()
mShaderProgram = std::make_unique<DirectXShaderProgram>(shader_path, shader_path); mShaderProgram = std::make_unique<DirectXShaderProgram>(shader_path, shader_path);
} }
void DirectXMeshPainter::setDxInterface(DirectXInterface* dxInterface)
{
mDxInterface = dxInterface;
}
void DirectXMeshPainter::initializeShader() void DirectXMeshPainter::initializeShader()
{ {
} }
void DirectXMeshPainter::initializeD3d(ID3D12Device* device) void DirectXMeshPainter::initializeD3d()
{ {
createRootSignature(device); createRootSignature();
createPipelineStateObject(device); createPipelineStateObject();
} }
void DirectXMeshPainter::createRootSignature(ID3D12Device* device) void DirectXMeshPainter::createRootSignature()
{ {
CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc;
rootSignatureDesc.Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); rootSignatureDesc.Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
@ -42,10 +48,10 @@ void DirectXMeshPainter::createRootSignature(ID3D12Device* device)
Microsoft::WRL::ComPtr<ID3DBlob> signature; Microsoft::WRL::ComPtr<ID3DBlob> signature;
Microsoft::WRL::ComPtr<ID3DBlob> error; Microsoft::WRL::ComPtr<ID3DBlob> error;
D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error); D3D12SerializeRootSignature(&rootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, &error);
device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&mRootSignature)); mDxInterface->getD3dDevice()->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&mRootSignature));
} }
void DirectXMeshPainter::createPipelineStateObject(ID3D12Device* device) void DirectXMeshPainter::createPipelineStateObject()
{ {
auto vert_shader = mShaderProgram->getVertexShader(); auto vert_shader = mShaderProgram->getVertexShader();
auto pixel_shader = mShaderProgram->getPixelShader(); auto pixel_shader = mShaderProgram->getPixelShader();
@ -70,7 +76,7 @@ void DirectXMeshPainter::createPipelineStateObject(ID3D12Device* device)
psoDesc.NumRenderTargets = 1; psoDesc.NumRenderTargets = 1;
psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
psoDesc.SampleDesc.Count = 1; psoDesc.SampleDesc.Count = 1;
device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&mPipelineState)); mDxInterface->getD3dDevice()->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&mPipelineState));
} }
ID3D12PipelineState* DirectXMeshPainter::getPipelineState() const ID3D12PipelineState* DirectXMeshPainter::getPipelineState() const
@ -96,7 +102,7 @@ void DirectXMeshPainter::updateCommandList(ID3D12GraphicsCommandList* commandLis
} }
} }
void DirectXMeshPainter::updateBuffers(DrawingContext* context, ID3D12Device* device) void DirectXMeshPainter::updateBuffers(DrawingContext* context)
{ {
mDxMeshes.clear(); mDxMeshes.clear();
auto scene = context->getSurface()->getScene(); auto scene = context->getSurface()->getScene();
@ -106,7 +112,7 @@ void DirectXMeshPainter::updateBuffers(DrawingContext* context, ID3D12Device* de
{ {
auto model = dynamic_cast<SceneModel*>(item); auto model = dynamic_cast<SceneModel*>(item);
auto dx_mesh = std::make_unique<DirectXMesh>(model); auto dx_mesh = std::make_unique<DirectXMesh>(model);
dx_mesh->update(context, device); dx_mesh->update(context, mDxInterface->getD3dDevice());
mDxMeshes.push_back(std::move(dx_mesh)); mDxMeshes.push_back(std::move(dx_mesh));
} }
} }

View file

@ -9,6 +9,7 @@
class DrawingContext; class DrawingContext;
class DirectXShaderProgram; class DirectXShaderProgram;
class DirectXMesh; class DirectXMesh;
class DirectXInterface;
class DirectXMeshPainter class DirectXMeshPainter
{ {
@ -18,14 +19,18 @@ public:
ID3D12PipelineState* getPipelineState() const; ID3D12PipelineState* getPipelineState() const;
ID3D12RootSignature* getRootSignature() const; ID3D12RootSignature* getRootSignature() const;
void initializeD3d(ID3D12Device* device); void initializeD3d();
void updateBuffers(DrawingContext* context, ID3D12Device* device); void setDxInterface(DirectXInterface* dxInterface);
void updateBuffers(DrawingContext* context);
void updateCommandList(ID3D12GraphicsCommandList* commandList); void updateCommandList(ID3D12GraphicsCommandList* commandList);
private: private:
void initializeShader(); void initializeShader();
void createRootSignature(ID3D12Device* device); void createRootSignature();
void createPipelineStateObject(ID3D12Device* device); void createPipelineStateObject();
DirectXInterface* mDxInterface{ nullptr };
std::vector<std::unique_ptr<DirectXMesh> > mDxMeshes; std::vector<std::unique_ptr<DirectXMesh> > mDxMeshes;

View file

@ -19,6 +19,10 @@
#include "DirectX2dPainter.h" #include "DirectX2dPainter.h"
#include "DirectXMesh.h" #include "DirectXMesh.h"
#include "DirectXInterface.h" #include "DirectXInterface.h"
#include "DirectX2dInterface.h"
#include <wincodec.h>
#include "Win32WicImage.h"
#include "File.h" #include "File.h"
@ -45,27 +49,63 @@ DirectXTextPainter* DirectXPainter::getTextPainter() const
return mTextPainter.get(); return mTextPainter.get();
} }
void DirectXPainter::initializeMesh(ID3D12Device* device) void DirectXPainter::setDxInterface(DirectXInterface* dxInterface)
{ {
mMeshPainter->initializeD3d(device); mRawDxInterface = dxInterface;
resetPainters();
} }
void DirectXPainter::initializeText(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory) DirectXInterface* DirectXPainter::getDxInterface() const
{ {
mTextPainter->initialize(d2dContext, directWriteFactory); if (mDxInterface)
{
return mDxInterface.get();
}
else
{
return mRawDxInterface;
}
} }
void DirectXPainter::updateMesh(ID3D12Device* device) void DirectXPainter::initializeMesh()
{ {
mMeshPainter->updateBuffers(mDrawingContext, device); mMeshPainter->initializeD3d();
}
void DirectXPainter::initializeText()
{
mTextPainter->initialize();
}
void DirectXPainter::updateMesh()
{
mMeshPainter->updateBuffers(mDrawingContext);
}
void DirectXPainter::initializeDxInterface()
{
mDxInterface = std::make_unique<DirectXInterface>();
auto backing_image = mDrawingContext->getSurface()->getImage();
auto wic_bitmap = dynamic_cast<Win32WicImage*>(backing_image->getPlatformImage())->getBitmap();
mDxInterface->getD2dInterface()->initializeStandalone(wic_bitmap);
resetPainters();
}
void DirectXPainter::resetPainters()
{
m2dPainter->setD2dInterface(mDxInterface->getD2dInterface());
mTextPainter->setD2dInterface(mDxInterface->getD2dInterface());
mMeshPainter->setDxInterface(getDxInterface());
} }
void DirectXPainter::paint() void DirectXPainter::paint()
{ {
if (!mDxInterface) if (!mDxInterface)
{ {
mDxInterface = std::make_unique<DirectXInterface>(); initializeDxInterface();
mDxInterface->initializeD2dStandalone();
} }
auto scene = mDrawingContext->getSurface()->getScene(); auto scene = mDrawingContext->getSurface()->getScene();
@ -76,7 +116,7 @@ void DirectXPainter::paint()
auto model = dynamic_cast<SceneModel*>(item); auto model = dynamic_cast<SceneModel*>(item);
if (model->getGeometry()) if (model->getGeometry())
{ {
m2dPainter->paint(mDxInterface->getD2dContext(), model->getGeometry()); m2dPainter->paint(model->getGeometry());
} }
} }
} }
@ -93,7 +133,7 @@ void DirectXPainter::paintMesh(ID3D12GraphicsCommandList* commandList)
mMeshPainter->updateCommandList(commandList); mMeshPainter->updateCommandList(commandList);
} }
void DirectXPainter::paintText(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory) void DirectXPainter::paintText()
{ {
auto scene = mDrawingContext->getSurface()->getScene(); auto scene = mDrawingContext->getSurface()->getScene();
for (const auto item : scene->getItems()) for (const auto item : scene->getItems())
@ -101,7 +141,7 @@ void DirectXPainter::paintText(ID2D1DeviceContext2* d2dContext, IDWriteFactory*
if (item->getType() == SceneItem::Type::TEXT && item->isVisible()) if (item->getType() == SceneItem::Type::TEXT && item->isVisible())
{ {
auto text = dynamic_cast<SceneText*>(item); auto text = dynamic_cast<SceneText*>(item);
mTextPainter->paint(text, mDrawingContext, d2dContext, directWriteFactory); mTextPainter->paint(text, mDrawingContext);
} }
} }
} }

View file

@ -19,29 +19,36 @@ class DirectXPainter : public AbstractPainter
{ {
public: public:
DirectXPainter(DrawingContext* context); DirectXPainter(DrawingContext* context);
void paint() override;
DirectXMeshPainter* getMeshPainter() const; DirectXMeshPainter* getMeshPainter() const;
DirectXTextPainter* getTextPainter() const; DirectXTextPainter* getTextPainter() const;
void initializeMesh(ID3D12Device* device); void initializeMesh();
void initializeText();
void initializeText(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory); void paint() override;
void paintBackground(const D3D12_CPU_DESCRIPTOR_HANDLE& rtvHandle, ID3D12GraphicsCommandList* commandList); void paintBackground(const D3D12_CPU_DESCRIPTOR_HANDLE& rtvHandle, ID3D12GraphicsCommandList* commandList);
void paintMesh(ID3D12GraphicsCommandList* commandList); void paintMesh(ID3D12GraphicsCommandList* commandList);
void paintText();
void paintText(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory); void setDxInterface(DirectXInterface* dxInterface);
bool supportsGeometryPrimitives() const override; bool supportsGeometryPrimitives() const override;
void updateMesh(ID3D12Device* device); void updateMesh();
private: private:
DirectXInterface* getDxInterface() const;
void initializeDxInterface();
void resetPainters();
std::unique_ptr<DirectXMeshPainter> mMeshPainter; std::unique_ptr<DirectXMeshPainter> mMeshPainter;
std::unique_ptr<DirectXTextPainter> mTextPainter; std::unique_ptr<DirectXTextPainter> mTextPainter;
std::unique_ptr<DirectX2dPainter> m2dPainter; std::unique_ptr<DirectX2dPainter> m2dPainter;
DirectXInterface* mRawDxInterface{ nullptr };
std::unique_ptr<DirectXInterface> mDxInterface; std::unique_ptr<DirectXInterface> mDxInterface;
}; };

View file

@ -7,9 +7,10 @@
#include "FontGlyph.h" #include "FontGlyph.h"
#include "DirectXShaderProgram.h" #include "DirectXShaderProgram.h"
#include "TextData.h"
#include "TextData.h"
#include "SceneText.h" #include "SceneText.h"
#include "DirectX2dInterface.h"
#include "StringUtils.h" #include "StringUtils.h"
#include "File.h" #include "File.h"
@ -25,19 +26,24 @@ DirectXTextPainter::DirectXTextPainter()
} }
void DirectXTextPainter::initialize(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory) void DirectXTextPainter::setD2dInterface(DirectX2dInterface* d2dIterface)
{ {
initializeBrush(d2dContext); mD2dInterface = d2dIterface;
} }
void DirectXTextPainter::initializeBrush(ID2D1DeviceContext2* d2dContext) void DirectXTextPainter::initialize()
{ {
d2dContext->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &mTextBrush); initializeBrush();
} }
void DirectXTextPainter::updateTextFormat(IDWriteFactory* directWriteFactory, float fontSize) void DirectXTextPainter::initializeBrush()
{ {
directWriteFactory->CreateTextFormat( mD2dInterface->getContext()->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &mTextBrush);
}
void DirectXTextPainter::updateTextFormat(float fontSize)
{
mD2dInterface->getDirectWriteFactory()->CreateTextFormat(
L"Verdana", L"Verdana",
NULL, NULL,
DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_WEIGHT_NORMAL,
@ -51,19 +57,19 @@ void DirectXTextPainter::updateTextFormat(IDWriteFactory* directWriteFactory, fl
//mTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER); //mTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
} }
void DirectXTextPainter::paint(SceneText* text, DrawingContext* context, ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory) void DirectXTextPainter::paint(SceneText* text, DrawingContext* context)
{ {
const auto location = text->getTransform().getLocation(); const auto location = text->getTransform().getLocation();
D2D1_RECT_F textRect = D2D1::RectF(static_cast<float>(location.getX()), static_cast<float>(location.getY()), static_cast<float>(location.getX() + 200), static_cast<float>(location.getY() + 100)); D2D1_RECT_F textRect = D2D1::RectF(static_cast<float>(location.getX()), static_cast<float>(location.getY()), static_cast<float>(location.getX() + 200), static_cast<float>(location.getY() + 100));
updateTextFormat(directWriteFactory, static_cast<float>(text->getTextData().mFont.getSize())); updateTextFormat(static_cast<float>(text->getTextData().mFont.getSize()));
auto content = StringUtils::convert(text->getTextData().mContent); auto content = StringUtils::convert(text->getTextData().mContent);
d2dContext->BeginDraw(); mD2dInterface->getContext()->BeginDraw();
d2dContext->SetTransform(D2D1::Matrix3x2F::Identity()); mD2dInterface->getContext()->SetTransform(D2D1::Matrix3x2F::Identity());
d2dContext->DrawText(content.c_str(), static_cast<UINT32>(content.size()), mTextFormat.Get(), &textRect, mTextBrush.Get()); mD2dInterface->getContext()->DrawText(content.c_str(), static_cast<UINT32>(content.size()), mTextFormat.Get(), &textRect, mTextBrush.Get());
d2dContext->EndDraw(); mD2dInterface->getContext()->EndDraw();
} }

View file

@ -11,6 +11,7 @@
class DrawingContext; class DrawingContext;
class DirectXShaderProgram; class DirectXShaderProgram;
class DirectX2dInterface;
class TextData; class TextData;
class SceneText; class SceneText;
@ -24,14 +25,17 @@ class DirectXTextPainter
public: public:
DirectXTextPainter(); DirectXTextPainter();
void initialize(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory); void initialize();
void paint(SceneText* text, DrawingContext* context, ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory); void paint(SceneText* text, DrawingContext* context);
void setD2dInterface(DirectX2dInterface* d2dIterface);
private: private:
void initializeBrush(ID2D1DeviceContext2* d2dContext); void initializeBrush();
void updateTextFormat(IDWriteFactory* directWriteFactory, float fontSize); void updateTextFormat(float fontSize);
DirectX2dInterface* mD2dInterface{ nullptr };
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mTextBrush; Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> mTextBrush;
Microsoft::WRL::ComPtr<IDWriteTextFormat> mTextFormat; Microsoft::WRL::ComPtr<IDWriteTextFormat> mTextFormat;
}; };

View file

@ -2,10 +2,14 @@
#include "Color.h" #include "Color.h"
#ifdef _WIN32
#include "Win32WicImage.h"
#endif
Image::Image(unsigned width, unsigned height, ImageData::Type dataType) Image::Image(unsigned width, unsigned height, ImageData::Type dataType)
: mWidth(width), : mWidth(width),
mHeight(height), mHeight(height),
mDataType(mDataType) mDataType(dataType)
{ {
} }
@ -70,8 +74,12 @@ unsigned Image::getBitDepth() const
return mBitDepth; return mBitDepth;
} }
PlatformImage* Image::getPlatformImage() const PlatformImage* Image::getPlatformImage()
{ {
if (!mPlatformImage)
{
mPlatformImage = std::make_unique<Win32WicImage>(this);
}
return mPlatformImage.get(); return mPlatformImage.get();
} }

View file

@ -23,7 +23,7 @@ public:
ImageData* getData(); ImageData* getData();
unsigned char getAsUnsignedChar(unsigned idx, unsigned jdx) const; unsigned char getAsUnsignedChar(unsigned idx, unsigned jdx) const;
PlatformImage* getPlatformImage() const; PlatformImage* getPlatformImage();
void setPixelValue(unsigned idx, unsigned jdx, const Color& color); void setPixelValue(unsigned idx, unsigned jdx, const Color& color);
void setWidth(unsigned width); void setWidth(unsigned width);

View file

@ -1,13 +1,14 @@
#pragma once #include "PlatformImage.h"
template<typename T> #include "Image.h"
class Image;
template<typename T> PlatformImage::PlatformImage(Image* image)
class PlatformImage : mImage(image)
{ {
public:
PlatformImage(Image<T>* image); }
private:
Image<T>* mImage{ nullptr }; PlatformImage::~PlatformImage()
}; {
}

View file

@ -5,11 +5,9 @@ class Image;
class PlatformImage class PlatformImage
{ {
public: public:
PlatformImage(Image* image) PlatformImage(Image* image);
: mImage(image)
{
} virtual ~PlatformImage();
private: protected:
Image* mImage{ nullptr }; Image* mImage{ nullptr };
}; };

View file

@ -1 +1,28 @@
#include "Win32WicImage.h" #include "Win32WicImage.h"
#include "Image.h"
#include "Win32WicInterface.h"
#include <wincodec.h>
Win32WicImage::Win32WicImage(Image* image)
: PlatformImage(image)
{
mWicInterface = std::make_unique<Win32WicInterface>();
}
Win32WicImage::~Win32WicImage()
{
}
IWICBitmap* Win32WicImage::getBitmap()
{
if (!mWicImage)
{
const auto width = mImage->getWidth();
const auto height = mImage->getHeight();
auto hr = mWicInterface->getFactory()->CreateBitmap(width, height, GUID_WICPixelFormat32bppBGR, WICBitmapCacheOnLoad, &mWicImage);
}
return mWicImage.Get();
}

View file

@ -2,7 +2,24 @@
#include "PlatformImage.h" #include "PlatformImage.h"
#include <wrl.h>
#include <memory>
class Win32WicInterface;
struct IWICBitmap;
class Win32WicImage : public PlatformImage class Win32WicImage : public PlatformImage
{ {
public:
Win32WicImage(Image* image);
virtual ~Win32WicImage();
IWICBitmap* getBitmap();
private:
Microsoft::WRL::ComPtr<IWICBitmap> mWicImage;
std::unique_ptr<Win32WicInterface> mWicInterface;
}; };

View file

@ -6,6 +6,7 @@ struct IWICImagingFactory;
class Win32WicInterface class Win32WicInterface
{ {
public:
Win32WicInterface(); Win32WicInterface();
IWICImagingFactory* getFactory() const; IWICImagingFactory* getFactory() const;

View file

@ -3,6 +3,7 @@
#include "Widget.h" #include "Widget.h"
#include "DesktopManager.h" #include "DesktopManager.h"
#include "DirectXInterface.h" #include "DirectXInterface.h"
#include "DirectX2dInterface.h"
#include <d3d12.h> #include <d3d12.h>
#include <dxgi.h> #include <dxgi.h>

View file

@ -7,6 +7,8 @@
#include "FileLogger.h" #include "FileLogger.h"
#include "StringUtils.h" #include "StringUtils.h"
#include "Widget.h" #include "Widget.h"
#include "DrawingContext.h"
#include "DirectXPainter.h"
#include "KeyboardEvent.h" #include "KeyboardEvent.h"
#include "DesktopManager.h" #include "DesktopManager.h"
@ -21,6 +23,7 @@ Win32Window::Win32Window(mt::Window* window, DirectXInterface* dxInterface)
if (dxInterface) if (dxInterface)
{ {
mDxInterface = std::make_unique<Win32DxWindowInterface>(window, dxInterface); mDxInterface = std::make_unique<Win32DxWindowInterface>(window, dxInterface);
dynamic_cast<DirectXPainter*>(window->getDrawingContent()->getPainter())->setDxInterface(dxInterface);
} }
} }

View file

@ -6,6 +6,7 @@
#include "DrawingContext.h" #include "DrawingContext.h"
#include "DirectXInterface.h" #include "DirectXInterface.h"
#include "DirectX2dInterface.h"
#include <d3d11.h> #include <d3d11.h>
#include <d3d11on12.h> #include <d3d11on12.h>
@ -17,7 +18,7 @@ DirectX2dIntegration::DirectX2dIntegration(mt::Window* window, DirectXInterface*
mWindow(window), mWindow(window),
mFrameCount(frameCount) mFrameCount(frameCount)
{ {
mDx2dInterface = dxInterface->getD2dInterface();
} }
ID3D11Resource* const* DirectX2dIntegration::getD11on12WrappedBackBuffer() const ID3D11Resource* const* DirectX2dIntegration::getD11on12WrappedBackBuffer() const
@ -36,10 +37,10 @@ void DirectX2dIntegration::render()
mDxInterface->get11On12Device()->AcquireWrappedResources(getD11on12WrappedBackBuffer(), 1); mDxInterface->get11On12Device()->AcquireWrappedResources(getD11on12WrappedBackBuffer(), 1);
// Render text directly to the back buffer. // Render text directly to the back buffer.
mDxInterface->getD2dContext()->SetTarget(getD2dRenderTarget()); mDx2dInterface->getContext()->SetTarget(getD2dRenderTarget());
auto painter = dynamic_cast<DirectXPainter*>(mWindow->getDrawingContent()->getPainter()); auto painter = dynamic_cast<DirectXPainter*>(mWindow->getDrawingContent()->getPainter());
painter->paintText(mDxInterface->getD2dContext(), mDxInterface->getDirectWriteFactory()); painter->paintText();
// Release our wrapped render target resource. Releasing // Release our wrapped render target resource. Releasing
// transitions the back buffer resource to the state specified // transitions the back buffer resource to the state specified
@ -64,7 +65,7 @@ void DirectX2dIntegration::clearBuffers()
} }
mD2dRenderTargets.clear(); mD2dRenderTargets.clear();
mDxInterface->getD2dContext()->SetTarget(nullptr); mDx2dInterface->getContext()->SetTarget(nullptr);
mDxInterface->getD3d11DeviceContext()->Flush(); mDxInterface->getD3d11DeviceContext()->Flush();
} }
@ -78,14 +79,14 @@ void DirectX2dIntegration::wrapBuffer(ID3D12Resource* renderTarget)
float dpiX{ 0.0 }; float dpiX{ 0.0 };
float dpiY{ 0.0 }; float dpiY{ 0.0 };
mDxInterface->getD2dFactory()->GetDesktopDpi(&dpiX, &dpiY); mDx2dInterface->getFactory()->GetDesktopDpi(&dpiX, &dpiY);
const auto pixel_format = D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED); const auto pixel_format = D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED);
const auto bitmap_props = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, pixel_format, dpiX, dpiY); const auto bitmap_props = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, pixel_format, dpiX, dpiY);
mD2dRenderTargets.push_back(Microsoft::WRL::ComPtr<ID2D1Bitmap1>()); mD2dRenderTargets.push_back(Microsoft::WRL::ComPtr<ID2D1Bitmap1>());
Microsoft::WRL::ComPtr<IDXGISurface> surface; Microsoft::WRL::ComPtr<IDXGISurface> surface;
mWrappedBackBuffers[mWrappedBackBuffers.size() - 1].As(&surface); mWrappedBackBuffers[mWrappedBackBuffers.size() - 1].As(&surface);
mDxInterface->getD2dContext()->CreateBitmapFromDxgiSurface(surface.Get(), &bitmap_props, &mD2dRenderTargets[mD2dRenderTargets.size()-1]); mDx2dInterface->getContext()->CreateBitmapFromDxgiSurface(surface.Get(), &bitmap_props, &mD2dRenderTargets[mD2dRenderTargets.size()-1]);
} }
void DirectX2dIntegration::updateBackbufferIndex(UINT idx) void DirectX2dIntegration::updateBackbufferIndex(UINT idx)

View file

@ -5,6 +5,8 @@
#include <vector> #include <vector>
class DirectXInterface; class DirectXInterface;
class DirectX2dInterface;
namespace mt namespace mt
{ {
class Window; class Window;
@ -31,6 +33,7 @@ private:
ID2D1Bitmap1* getD2dRenderTarget() const; ID2D1Bitmap1* getD2dRenderTarget() const;
DirectXInterface* mDxInterface{ nullptr }; DirectXInterface* mDxInterface{ nullptr };
DirectX2dInterface* mDx2dInterface{ nullptr };
mt::Window* mWindow{ nullptr }; mt::Window* mWindow{ nullptr };
UINT mFrameCount{ 2 }; UINT mFrameCount{ 2 };

View file

@ -14,16 +14,12 @@
#include "DrawingContext.h" #include "DrawingContext.h"
#include "DirectXPainter.h" #include "DirectXPainter.h"
#include "DirectXMeshPainter.h" #include "DirectXMeshPainter.h"
#include "DirectXTextPainter.h"
#include "DirectXShaderProgram.h"
#include <dxgi.h> #include <dxgi.h>
#include <dxgi1_6.h> #include <dxgi1_6.h>
#include <d3d12sdklayers.h> #include <d3d12sdklayers.h>
#include <D3Dcommon.h> #include <D3Dcommon.h>
#include <dwrite.h>
Win32DxWindowInterface::Win32DxWindowInterface(mt::Window* window, DirectXInterface* dxInterface) Win32DxWindowInterface::Win32DxWindowInterface(mt::Window* window, DirectXInterface* dxInterface)
: mWindow(window), : mWindow(window),
mDxInterface(dxInterface) mDxInterface(dxInterface)
@ -259,10 +255,10 @@ void Win32DxWindowInterface::updateBackbufferIndex(UINT index)
bool Win32DxWindowInterface::loadAssets() bool Win32DxWindowInterface::loadAssets()
{ {
auto painter = dynamic_cast<DirectXPainter*>(mWindow->getDrawingContent()->getPainter()); auto painter = dynamic_cast<DirectXPainter*>(mWindow->getDrawingContent()->getPainter());
painter->initializeMesh(mDxInterface->getD3dDevice()); painter->initializeMesh();
painter->initializeText(mDxInterface->getD2dContext(), mDxInterface->getDirectWriteFactory()); painter->initializeText();
painter->updateMesh(mDxInterface->getD3dDevice()); painter->updateMesh();
return true; return true;
} }