diff --git a/src/graphics/CMakeLists.txt b/src/graphics/CMakeLists.txt index 2af8a78..79a582f 100644 --- a/src/graphics/CMakeLists.txt +++ b/src/graphics/CMakeLists.txt @@ -48,6 +48,7 @@ if(UNIX) else() list(APPEND graphics_LIB_INCLUDES directx/DirectXInterface.cpp + directx/DirectX2dInterface.cpp directx/DirectXMesh.cpp directx/DirectXPainter.cpp directx/DirectX2dPainter.cpp @@ -56,7 +57,8 @@ else() directx/DirectXShaderProgram.cpp ) list(APPEND graphics_HEADERS - directx/DirectXInterface.h + directx/DirectXInterface.h + directx/DirectX2dInterface.h directx/DirectXMesh.h directx/DirectXPainter.h directx/DirectX2dPainter.h diff --git a/src/graphics/directx/DirectX2dInterface.cpp b/src/graphics/directx/DirectX2dInterface.cpp new file mode 100644 index 0000000..4c359f4 --- /dev/null +++ b/src/graphics/directx/DirectX2dInterface.cpp @@ -0,0 +1,67 @@ +#include "DirectX2dInterface.h" + +#include "DirectXInterface.h" + +#include "FileLogger.h" + +#include +#include +#include +#include + +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)); +} \ No newline at end of file diff --git a/src/graphics/directx/DirectX2dInterface.h b/src/graphics/directx/DirectX2dInterface.h new file mode 100644 index 0000000..84f0e22 --- /dev/null +++ b/src/graphics/directx/DirectX2dInterface.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include +#include + +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 mFactory; + Microsoft::WRL::ComPtr mDevice; + Microsoft::WRL::ComPtr mDeviceContext; + Microsoft::WRL::ComPtr mDWriteFactory; + Microsoft::WRL::ComPtr mRenderTarget; +}; \ No newline at end of file diff --git a/src/graphics/directx/DirectX2dPainter.cpp b/src/graphics/directx/DirectX2dPainter.cpp index fae0082..84f92dd 100644 --- a/src/graphics/directx/DirectX2dPainter.cpp +++ b/src/graphics/directx/DirectX2dPainter.cpp @@ -1,6 +1,13 @@ #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; } \ No newline at end of file diff --git a/src/graphics/directx/DirectX2dPainter.h b/src/graphics/directx/DirectX2dPainter.h index fe8f36e..be46954 100644 --- a/src/graphics/directx/DirectX2dPainter.h +++ b/src/graphics/directx/DirectX2dPainter.h @@ -1,11 +1,15 @@ #pragma once class AbstractGeometricItem; - -struct ID2D1DeviceContext2; +class DirectX2dInterface; class DirectX2dPainter { public: - void paint(ID2D1DeviceContext2* context, AbstractGeometricItem* item); + void paint(AbstractGeometricItem* item); + + void setD2dInterface(DirectX2dInterface* d2dIterface); + +private: + DirectX2dInterface* mD2dInterface{ nullptr }; }; \ No newline at end of file diff --git a/src/graphics/directx/DirectXInterface.cpp b/src/graphics/directx/DirectXInterface.cpp index b77360d..45fd097 100644 --- a/src/graphics/directx/DirectXInterface.cpp +++ b/src/graphics/directx/DirectXInterface.cpp @@ -1,5 +1,6 @@ #include "DirectXInterface.h" +#include "DirectX2dInterface.h" #include "FileLogger.h" #include @@ -9,10 +10,11 @@ #include #include -#include -#include +DirectXInterface::DirectXInterface() + : mD2dInterface(std::make_unique(this)) +{ -#include +} void DirectXInterface::getHardwareAdapter(IDXGIAdapter1** ppAdapter) { @@ -53,21 +55,6 @@ IDXGIFactory7* DirectXInterface::getDxgiFactory() const 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 { return mCommandQueue.Get(); @@ -78,6 +65,11 @@ ID3D11DeviceContext* DirectXInterface::getD3d11DeviceContext() const return mD3d11DeviceContext.Get(); } +DirectX2dInterface* DirectXInterface::getD2dInterface() const +{ + return mD2dInterface.get(); +} + void DirectXInterface::initialize() { MLOG_INFO("Initialize DirectX"); @@ -89,15 +81,15 @@ void DirectXInterface::initialize() createCommandQueue(); - mIsValid = initializeD2d(); -} - -void DirectXInterface::initializeD2dStandalone() -{ - D2D1_FACTORY_OPTIONS d2dFactoryOptions = {}; - D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory3), &d2dFactoryOptions, &mD2dFactory); - + if (!initializeD11on12()) + { + mIsValid = false; + return; + } + Microsoft::WRL::ComPtr dxgiDevice; + mD3d11On12Device.As(&dxgiDevice); + mIsValid = mD2dInterface->initialize(dxgiDevice.Get()); } bool DirectXInterface::createD3dFactory() @@ -161,26 +153,6 @@ bool DirectXInterface::createCommandQueue() 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 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() { Microsoft::WRL::ComPtr d3d11Device; @@ -193,9 +165,4 @@ bool DirectXInterface::initializeD11on12() } d3d11Device.As(&mD3d11On12Device); return true; -} - -bool DirectXInterface::initializeDirectWrite() -{ - return SUCCEEDED(::DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), &mDWriteFactory)); } \ No newline at end of file diff --git a/src/graphics/directx/DirectXInterface.h b/src/graphics/directx/DirectXInterface.h index d1c542f..0073601 100644 --- a/src/graphics/directx/DirectXInterface.h +++ b/src/graphics/directx/DirectXInterface.h @@ -1,11 +1,13 @@ #pragma once #include -#include -#include #include #include +#include + +class DirectX2dInterface; + struct ID3D12Device; struct IDXGIFactory7; struct IDXGIAdapter1; @@ -14,27 +16,21 @@ struct ID3D12CommandQueue; struct ID3D11DeviceContext; struct ID3D11On12Device; -struct IDWriteFactory; -struct ID2D1Factory3; -struct ID2D1Device2; -struct ID2D1DeviceContext2; - class DirectXInterface { public: + DirectXInterface(); + IDXGIFactory7* getDxgiFactory() const; ID3D12Device* getD3dDevice() const; ID3D12CommandQueue* getCommandQueue() const; ID3D11On12Device* get11On12Device() const; ID3D11DeviceContext* getD3d11DeviceContext() const; - ID2D1Factory3* getD2dFactory() const; - ID2D1DeviceContext2* getD2dContext() const; - IDWriteFactory* getDirectWriteFactory() const; + + DirectX2dInterface* getD2dInterface() const; void initialize(); - void initializeD2dStandalone(); - bool isValid() const; private: @@ -44,9 +40,7 @@ private: void getHardwareAdapter(IDXGIAdapter1** ppAdapter); - bool initializeD2d(); bool initializeD11on12(); - bool initializeDirectWrite(); bool mIsValid{ false }; @@ -54,11 +48,8 @@ private: Microsoft::WRL::ComPtr mD3dDevice; Microsoft::WRL::ComPtr mCommandQueue; - // 2D Rendering - e.g. text Microsoft::WRL::ComPtr mD3d11DeviceContext; Microsoft::WRL::ComPtr mD3d11On12Device; - Microsoft::WRL::ComPtr mD2dFactory; - Microsoft::WRL::ComPtr mD2dDevice; - Microsoft::WRL::ComPtr mD2dDeviceContext; - Microsoft::WRL::ComPtr mDWriteFactory; + + std::unique_ptr mD2dInterface; }; \ No newline at end of file diff --git a/src/graphics/directx/DirectXMeshPainter.cpp b/src/graphics/directx/DirectXMeshPainter.cpp index 646485c..4d42cd5 100644 --- a/src/graphics/directx/DirectXMeshPainter.cpp +++ b/src/graphics/directx/DirectXMeshPainter.cpp @@ -10,6 +10,7 @@ #include "DirectXShaderProgram.h" #include "DirectXMesh.h" +#include "DirectXInterface.h" #include #include @@ -23,18 +24,23 @@ DirectXMeshPainter::DirectXMeshPainter() mShaderProgram = std::make_unique(shader_path, shader_path); } +void DirectXMeshPainter::setDxInterface(DirectXInterface* dxInterface) +{ + mDxInterface = dxInterface; +} + void DirectXMeshPainter::initializeShader() { } -void DirectXMeshPainter::initializeD3d(ID3D12Device* device) +void DirectXMeshPainter::initializeD3d() { - createRootSignature(device); - createPipelineStateObject(device); + createRootSignature(); + createPipelineStateObject(); } -void DirectXMeshPainter::createRootSignature(ID3D12Device* device) +void DirectXMeshPainter::createRootSignature() { CD3DX12_ROOT_SIGNATURE_DESC rootSignatureDesc; 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 signature; Microsoft::WRL::ComPtr 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 pixel_shader = mShaderProgram->getPixelShader(); @@ -70,7 +76,7 @@ void DirectXMeshPainter::createPipelineStateObject(ID3D12Device* device) psoDesc.NumRenderTargets = 1; psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; psoDesc.SampleDesc.Count = 1; - device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&mPipelineState)); + mDxInterface->getD3dDevice()->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&mPipelineState)); } 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(); auto scene = context->getSurface()->getScene(); @@ -106,7 +112,7 @@ void DirectXMeshPainter::updateBuffers(DrawingContext* context, ID3D12Device* de { auto model = dynamic_cast(item); auto dx_mesh = std::make_unique(model); - dx_mesh->update(context, device); + dx_mesh->update(context, mDxInterface->getD3dDevice()); mDxMeshes.push_back(std::move(dx_mesh)); } } diff --git a/src/graphics/directx/DirectXMeshPainter.h b/src/graphics/directx/DirectXMeshPainter.h index 956f9af..4dcf96a 100644 --- a/src/graphics/directx/DirectXMeshPainter.h +++ b/src/graphics/directx/DirectXMeshPainter.h @@ -9,6 +9,7 @@ class DrawingContext; class DirectXShaderProgram; class DirectXMesh; +class DirectXInterface; class DirectXMeshPainter { @@ -18,14 +19,18 @@ public: ID3D12PipelineState* getPipelineState() 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); private: void initializeShader(); - void createRootSignature(ID3D12Device* device); - void createPipelineStateObject(ID3D12Device* device); + void createRootSignature(); + void createPipelineStateObject(); + + DirectXInterface* mDxInterface{ nullptr }; std::vector > mDxMeshes; diff --git a/src/graphics/directx/DirectXPainter.cpp b/src/graphics/directx/DirectXPainter.cpp index d355b74..5f8fd71 100644 --- a/src/graphics/directx/DirectXPainter.cpp +++ b/src/graphics/directx/DirectXPainter.cpp @@ -19,6 +19,10 @@ #include "DirectX2dPainter.h" #include "DirectXMesh.h" #include "DirectXInterface.h" +#include "DirectX2dInterface.h" + +#include +#include "Win32WicImage.h" #include "File.h" @@ -45,27 +49,63 @@ DirectXTextPainter* DirectXPainter::getTextPainter() const 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(); + + auto backing_image = mDrawingContext->getSurface()->getImage(); + auto wic_bitmap = dynamic_cast(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() { if (!mDxInterface) { - mDxInterface = std::make_unique(); - mDxInterface->initializeD2dStandalone(); + initializeDxInterface(); } auto scene = mDrawingContext->getSurface()->getScene(); @@ -76,7 +116,7 @@ void DirectXPainter::paint() auto model = dynamic_cast(item); 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); } -void DirectXPainter::paintText(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory) +void DirectXPainter::paintText() { auto scene = mDrawingContext->getSurface()->getScene(); for (const auto item : scene->getItems()) @@ -101,7 +141,7 @@ void DirectXPainter::paintText(ID2D1DeviceContext2* d2dContext, IDWriteFactory* if (item->getType() == SceneItem::Type::TEXT && item->isVisible()) { auto text = dynamic_cast(item); - mTextPainter->paint(text, mDrawingContext, d2dContext, directWriteFactory); + mTextPainter->paint(text, mDrawingContext); } } } diff --git a/src/graphics/directx/DirectXPainter.h b/src/graphics/directx/DirectXPainter.h index 5073785..5891045 100644 --- a/src/graphics/directx/DirectXPainter.h +++ b/src/graphics/directx/DirectXPainter.h @@ -19,29 +19,36 @@ class DirectXPainter : public AbstractPainter { public: DirectXPainter(DrawingContext* context); - void paint() override; - + DirectXMeshPainter* getMeshPainter() 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 paintMesh(ID3D12GraphicsCommandList* commandList); + void paintText(); - void paintText(ID2D1DeviceContext2* d2dContext, IDWriteFactory* directWriteFactory); + void setDxInterface(DirectXInterface* dxInterface); bool supportsGeometryPrimitives() const override; - void updateMesh(ID3D12Device* device); + void updateMesh(); private: + DirectXInterface* getDxInterface() const; + + void initializeDxInterface(); + void resetPainters(); + std::unique_ptr mMeshPainter; std::unique_ptr mTextPainter; std::unique_ptr m2dPainter; + DirectXInterface* mRawDxInterface{ nullptr }; std::unique_ptr mDxInterface; }; \ No newline at end of file diff --git a/src/graphics/directx/DirectXTextPainter.cpp b/src/graphics/directx/DirectXTextPainter.cpp index 02ebbb2..02b2b42 100644 --- a/src/graphics/directx/DirectXTextPainter.cpp +++ b/src/graphics/directx/DirectXTextPainter.cpp @@ -7,9 +7,10 @@ #include "FontGlyph.h" #include "DirectXShaderProgram.h" -#include "TextData.h" +#include "TextData.h" #include "SceneText.h" +#include "DirectX2dInterface.h" #include "StringUtils.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", NULL, DWRITE_FONT_WEIGHT_NORMAL, @@ -51,19 +57,19 @@ void DirectXTextPainter::updateTextFormat(IDWriteFactory* directWriteFactory, fl //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(); D2D1_RECT_F textRect = D2D1::RectF(static_cast(location.getX()), static_cast(location.getY()), static_cast(location.getX() + 200), static_cast(location.getY() + 100)); - updateTextFormat(directWriteFactory, static_cast(text->getTextData().mFont.getSize())); + updateTextFormat(static_cast(text->getTextData().mFont.getSize())); auto content = StringUtils::convert(text->getTextData().mContent); - d2dContext->BeginDraw(); - d2dContext->SetTransform(D2D1::Matrix3x2F::Identity()); - d2dContext->DrawText(content.c_str(), static_cast(content.size()), mTextFormat.Get(), &textRect, mTextBrush.Get()); - d2dContext->EndDraw(); + mD2dInterface->getContext()->BeginDraw(); + mD2dInterface->getContext()->SetTransform(D2D1::Matrix3x2F::Identity()); + mD2dInterface->getContext()->DrawText(content.c_str(), static_cast(content.size()), mTextFormat.Get(), &textRect, mTextBrush.Get()); + mD2dInterface->getContext()->EndDraw(); } diff --git a/src/graphics/directx/DirectXTextPainter.h b/src/graphics/directx/DirectXTextPainter.h index 7038604..f29c08c 100644 --- a/src/graphics/directx/DirectXTextPainter.h +++ b/src/graphics/directx/DirectXTextPainter.h @@ -11,6 +11,7 @@ class DrawingContext; class DirectXShaderProgram; +class DirectX2dInterface; class TextData; class SceneText; @@ -24,14 +25,17 @@ class DirectXTextPainter public: 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: - void initializeBrush(ID2D1DeviceContext2* d2dContext); - void updateTextFormat(IDWriteFactory* directWriteFactory, float fontSize); + void initializeBrush(); + void updateTextFormat(float fontSize); + DirectX2dInterface* mD2dInterface{ nullptr }; Microsoft::WRL::ComPtr mTextBrush; Microsoft::WRL::ComPtr mTextFormat; }; diff --git a/src/image/Image.cpp b/src/image/Image.cpp index 2d0b6f6..2d0ea1c 100644 --- a/src/image/Image.cpp +++ b/src/image/Image.cpp @@ -2,10 +2,14 @@ #include "Color.h" +#ifdef _WIN32 +#include "Win32WicImage.h" +#endif + Image::Image(unsigned width, unsigned height, ImageData::Type dataType) : mWidth(width), mHeight(height), - mDataType(mDataType) + mDataType(dataType) { } @@ -70,8 +74,12 @@ unsigned Image::getBitDepth() const return mBitDepth; } -PlatformImage* Image::getPlatformImage() const +PlatformImage* Image::getPlatformImage() { + if (!mPlatformImage) + { + mPlatformImage = std::make_unique(this); + } return mPlatformImage.get(); } diff --git a/src/image/Image.h b/src/image/Image.h index c0f3707..94139e9 100644 --- a/src/image/Image.h +++ b/src/image/Image.h @@ -23,7 +23,7 @@ public: ImageData* getData(); unsigned char getAsUnsignedChar(unsigned idx, unsigned jdx) const; - PlatformImage* getPlatformImage() const; + PlatformImage* getPlatformImage(); void setPixelValue(unsigned idx, unsigned jdx, const Color& color); void setWidth(unsigned width); diff --git a/src/image/PlatformImage.cpp b/src/image/PlatformImage.cpp index a2cacb4..aeaf3fb 100644 --- a/src/image/PlatformImage.cpp +++ b/src/image/PlatformImage.cpp @@ -1,13 +1,14 @@ -#pragma once +#include "PlatformImage.h" -template -class Image; +#include "Image.h" -template -class PlatformImage +PlatformImage::PlatformImage(Image* image) + : mImage(image) { -public: - PlatformImage(Image* image); -private: - Image* mImage{ nullptr }; -}; \ No newline at end of file + +} + +PlatformImage::~PlatformImage() +{ + +} diff --git a/src/image/PlatformImage.h b/src/image/PlatformImage.h index 637e55d..a26fb55 100644 --- a/src/image/PlatformImage.h +++ b/src/image/PlatformImage.h @@ -5,11 +5,9 @@ class Image; class PlatformImage { public: - PlatformImage(Image* image) - : mImage(image) - { + PlatformImage(Image* image); - } -private: + virtual ~PlatformImage(); +protected: Image* mImage{ nullptr }; }; \ No newline at end of file diff --git a/src/image/win32/Win32WicImage.cpp b/src/image/win32/Win32WicImage.cpp index bf80630..e6968b7 100644 --- a/src/image/win32/Win32WicImage.cpp +++ b/src/image/win32/Win32WicImage.cpp @@ -1 +1,28 @@ -#include "Win32WicImage.h" \ No newline at end of file +#include "Win32WicImage.h" + +#include "Image.h" +#include "Win32WicInterface.h" + +#include + +Win32WicImage::Win32WicImage(Image* image) + : PlatformImage(image) +{ + mWicInterface = std::make_unique(); +} + +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(); +} \ No newline at end of file diff --git a/src/image/win32/Win32WicImage.h b/src/image/win32/Win32WicImage.h index 7b258bb..7f4e5fc 100644 --- a/src/image/win32/Win32WicImage.h +++ b/src/image/win32/Win32WicImage.h @@ -2,7 +2,24 @@ #include "PlatformImage.h" +#include + +#include + +class Win32WicInterface; + +struct IWICBitmap; + class Win32WicImage : public PlatformImage { +public: + Win32WicImage(Image* image); + virtual ~Win32WicImage(); + + IWICBitmap* getBitmap(); + +private: + Microsoft::WRL::ComPtr mWicImage; + std::unique_ptr mWicInterface; }; \ No newline at end of file diff --git a/src/image/win32/Win32WicInterface.h b/src/image/win32/Win32WicInterface.h index bddc692..de2618f 100644 --- a/src/image/win32/Win32WicInterface.h +++ b/src/image/win32/Win32WicInterface.h @@ -6,6 +6,7 @@ struct IWICImagingFactory; class Win32WicInterface { +public: Win32WicInterface(); IWICImagingFactory* getFactory() const; diff --git a/src/windows/ui_interfaces/win32/Win32UIInterface.cpp b/src/windows/ui_interfaces/win32/Win32UIInterface.cpp index 886bfab..f0b1fe7 100644 --- a/src/windows/ui_interfaces/win32/Win32UIInterface.cpp +++ b/src/windows/ui_interfaces/win32/Win32UIInterface.cpp @@ -3,6 +3,7 @@ #include "Widget.h" #include "DesktopManager.h" #include "DirectXInterface.h" +#include "DirectX2dInterface.h" #include #include @@ -11,7 +12,7 @@ Win32UIInterface::Win32UIInterface(DesktopManager* desktopManager, std::unique_ptr fontsManager, bool useHardware) : AbstractUIInterface(desktopManager, std::move(fontsManager), useHardware), - mWindowInterface(std::make_unique()) + mWindowInterface(std::make_unique()) { } diff --git a/src/windows/ui_interfaces/win32/Win32Window.cpp b/src/windows/ui_interfaces/win32/Win32Window.cpp index 36bba72..28e90f0 100644 --- a/src/windows/ui_interfaces/win32/Win32Window.cpp +++ b/src/windows/ui_interfaces/win32/Win32Window.cpp @@ -7,6 +7,8 @@ #include "FileLogger.h" #include "StringUtils.h" #include "Widget.h" +#include "DrawingContext.h" +#include "DirectXPainter.h" #include "KeyboardEvent.h" #include "DesktopManager.h" @@ -21,6 +23,7 @@ Win32Window::Win32Window(mt::Window* window, DirectXInterface* dxInterface) if (dxInterface) { mDxInterface = std::make_unique(window, dxInterface); + dynamic_cast(window->getDrawingContent()->getPainter())->setDxInterface(dxInterface); } } diff --git a/src/windows/ui_interfaces/win32/directx/DirectX2dIntegration.cpp b/src/windows/ui_interfaces/win32/directx/DirectX2dIntegration.cpp index cad8003..45bf07f 100644 --- a/src/windows/ui_interfaces/win32/directx/DirectX2dIntegration.cpp +++ b/src/windows/ui_interfaces/win32/directx/DirectX2dIntegration.cpp @@ -6,6 +6,7 @@ #include "DrawingContext.h" #include "DirectXInterface.h" +#include "DirectX2dInterface.h" #include #include @@ -17,7 +18,7 @@ DirectX2dIntegration::DirectX2dIntegration(mt::Window* window, DirectXInterface* mWindow(window), mFrameCount(frameCount) { - + mDx2dInterface = dxInterface->getD2dInterface(); } ID3D11Resource* const* DirectX2dIntegration::getD11on12WrappedBackBuffer() const @@ -36,10 +37,10 @@ void DirectX2dIntegration::render() mDxInterface->get11On12Device()->AcquireWrappedResources(getD11on12WrappedBackBuffer(), 1); // Render text directly to the back buffer. - mDxInterface->getD2dContext()->SetTarget(getD2dRenderTarget()); + mDx2dInterface->getContext()->SetTarget(getD2dRenderTarget()); auto painter = dynamic_cast(mWindow->getDrawingContent()->getPainter()); - painter->paintText(mDxInterface->getD2dContext(), mDxInterface->getDirectWriteFactory()); + painter->paintText(); // Release our wrapped render target resource. Releasing // transitions the back buffer resource to the state specified @@ -64,7 +65,7 @@ void DirectX2dIntegration::clearBuffers() } mD2dRenderTargets.clear(); - mDxInterface->getD2dContext()->SetTarget(nullptr); + mDx2dInterface->getContext()->SetTarget(nullptr); mDxInterface->getD3d11DeviceContext()->Flush(); } @@ -78,14 +79,14 @@ void DirectX2dIntegration::wrapBuffer(ID3D12Resource* renderTarget) float dpiX{ 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 bitmap_props = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, pixel_format, dpiX, dpiY); mD2dRenderTargets.push_back(Microsoft::WRL::ComPtr()); Microsoft::WRL::ComPtr 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) diff --git a/src/windows/ui_interfaces/win32/directx/DirectX2dIntegration.h b/src/windows/ui_interfaces/win32/directx/DirectX2dIntegration.h index f1c4b95..fa93f17 100644 --- a/src/windows/ui_interfaces/win32/directx/DirectX2dIntegration.h +++ b/src/windows/ui_interfaces/win32/directx/DirectX2dIntegration.h @@ -5,6 +5,8 @@ #include class DirectXInterface; +class DirectX2dInterface; + namespace mt { class Window; @@ -31,6 +33,7 @@ private: ID2D1Bitmap1* getD2dRenderTarget() const; DirectXInterface* mDxInterface{ nullptr }; + DirectX2dInterface* mDx2dInterface{ nullptr }; mt::Window* mWindow{ nullptr }; UINT mFrameCount{ 2 }; diff --git a/src/windows/ui_interfaces/win32/directx/Win32DxWindowInterface.cpp b/src/windows/ui_interfaces/win32/directx/Win32DxWindowInterface.cpp index defc9a2..bb24848 100644 --- a/src/windows/ui_interfaces/win32/directx/Win32DxWindowInterface.cpp +++ b/src/windows/ui_interfaces/win32/directx/Win32DxWindowInterface.cpp @@ -14,16 +14,12 @@ #include "DrawingContext.h" #include "DirectXPainter.h" #include "DirectXMeshPainter.h" -#include "DirectXTextPainter.h" -#include "DirectXShaderProgram.h" #include #include #include #include -#include - Win32DxWindowInterface::Win32DxWindowInterface(mt::Window* window, DirectXInterface* dxInterface) : mWindow(window), mDxInterface(dxInterface) @@ -259,10 +255,10 @@ void Win32DxWindowInterface::updateBackbufferIndex(UINT index) bool Win32DxWindowInterface::loadAssets() { auto painter = dynamic_cast(mWindow->getDrawingContent()->getPainter()); - painter->initializeMesh(mDxInterface->getD3dDevice()); - painter->initializeText(mDxInterface->getD2dContext(), mDxInterface->getDirectWriteFactory()); + painter->initializeMesh(); + painter->initializeText(); - painter->updateMesh(mDxInterface->getD3dDevice()); + painter->updateMesh(); return true; }