#include "Factory.h" #pragma comment(lib, "d2d1.lib") #pragma comment(lib, "dxgi.lib") #pragma comment(lib, "d3d11.lib") #pragma comment(lib, "Dwrite.lib") #pragma comment(lib, "windowscodecs.lib") IDXGIFactory1* Factory::dxgiFactory = NULL; ID2D1Device* Factory::pD2DDevice = NULL; ID2D1Factory1* Factory::pD2DFactory = NULL; IDWriteFactory* Factory::pDWriteFactory = NULL; IWICImagingFactory* Factory::_pImageFactory = NULL; IDXGIDevice1* Factory::dxgiDevice = NULL; ID3D11Device* Factory::pd3dDevice = NULL; ID3D11DeviceContext* Factory::pd3dDeviceContext = NULL; ID3D11DeviceContext* Factory::D3DDeviceContext() { if (!pd3dDevice) { UINT createDeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; #if defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, }; D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevels, 1, D3D11_SDK_VERSION, &pd3dDevice, NULL, &pd3dDeviceContext); } return pd3dDeviceContext; } ID3D11Device* Factory::D3DDevice() { if (!pd3dDevice) { UINT createDeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; #if defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, }; D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevels, 1, D3D11_SDK_VERSION, &pd3dDevice, NULL, &pd3dDeviceContext); } return pd3dDevice; } IDXGIDevice1* Factory::DxgiDevice() { if (dxgiDevice == NULL) D3DDevice()->QueryInterface(&dxgiDevice); return dxgiDevice; } IDXGIFactory1* Factory::DxgiFactory() { if (dxgiFactory == NULL) { IDXGIAdapter* adapter = NULL; DxgiDevice()->GetAdapter(&adapter); adapter->GetParent(__uuidof(IDXGIFactory1), (void**)&dxgiFactory); } return dxgiFactory; } ID2D1Device* Factory::D2DDevice() { if (pD2DDevice == NULL) { _D2DFactory->CreateDevice(DxgiDevice(), &pD2DDevice); } return pD2DDevice; } ID2D1Factory1* Factory::D2DFactory() { if (!pD2DFactory) { D2D1_FACTORY_OPTIONS factoryOptions = {}; #if defined(_DEBUG) factoryOptions.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION; #endif D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, __uuidof(ID2D1Factory1), &factoryOptions, reinterpret_cast(&pD2DFactory)); } return pD2DFactory; } IDWriteFactory* Factory::DWriteFactory() { if (!pDWriteFactory) DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast(&pDWriteFactory)); return pDWriteFactory; } IWICImagingFactory* Factory::ImageFactory() { if (!_pImageFactory) { auto m = LoadLibraryA("Ole32.dll"); if (m) { HRESULT hr = ((decltype(CoInitialize)*)GetProcAddress(m, "CoInitialize"))(NULL); hr = ((decltype(CoCreateInstance)*)GetProcAddress(m, "CoCreateInstance"))(CLSID_WICImagingFactory1, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (LPVOID*)&_pImageFactory); } } return _pImageFactory; } IWICBitmap* Factory::CreateWICBitmap(std::wstring path) { IWICBitmap* wb = NULL; IWICBitmapDecoder* bitmapdecoder = NULL; HRESULT hr = _ImageFactory->CreateDecoderFromFilename(path.c_str(), NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &bitmapdecoder); if SUCCEEDED(hr) { IWICBitmapFrameDecode* pframe = NULL; bitmapdecoder->GetFrame(0, &pframe); IWICFormatConverter* fmtcovter = NULL; _ImageFactory->CreateFormatConverter(&fmtcovter); fmtcovter->Initialize(pframe, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeCustom); pframe->Release(); bitmapdecoder->Release(); return (IWICBitmap*)fmtcovter; } return wb; } IWICBitmap* Factory::CreateWICBitmap(unsigned char* data, int size) { ID2D1Bitmap* bmp = NULL; IWICBitmapDecoder* bitmapdecoder = NULL; IWICStream* pStream = NULL; HRESULT hr = _ImageFactory->CreateStream(&pStream); if (!SUCCEEDED(hr)) { return NULL; } hr = pStream->InitializeFromMemory(data, size); if (!SUCCEEDED(hr)) { return NULL; } hr = _ImageFactory->CreateDecoderFromStream(pStream, NULL, WICDecodeMetadataCacheOnDemand, &bitmapdecoder); if (!SUCCEEDED(hr)) { return NULL; } if (bitmapdecoder) { IWICBitmapFrameDecode* pframe = NULL; bitmapdecoder->GetFrame(0, &pframe); IWICFormatConverter* fmtcovter = NULL; _ImageFactory->CreateFormatConverter(&fmtcovter); fmtcovter->Initialize(pframe, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeCustom); pframe->Release(); bitmapdecoder->Release(); return (IWICBitmap*)fmtcovter; } return NULL; } IWICBitmap* Factory::CreateWICBitmap(HBITMAP hb) { IWICBitmap* wb = NULL; _ImageFactory->CreateBitmapFromHBITMAP(hb, 0, WICBitmapUsePremultipliedAlpha, &wb); return wb; } IWICBitmap* Factory::CreateWICBitmap(int width, int height) { IWICBitmap* wb = NULL; _ImageFactory->CreateBitmap(width, height, GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wb); return wb; } IWICBitmap* Factory::CreateWICBitmap(HICON hb) { IWICBitmap* wb = NULL; _ImageFactory->CreateBitmapFromHICON(hb, &wb); return wb; } void Factory::SaveBitmap(IWICBitmap* bmp, const wchar_t* path) { UINT w, h; bmp->GetSize(&w, &h); IWICBitmapEncoder* pEncoder = NULL; IWICStream* pStream = NULL; IWICBitmapFrameEncode* pFrameEncode = NULL; WICPixelFormatGUID format = GUID_WICPixelFormat32bppPBGRA; _ImageFactory->CreateStream(&pStream); _ImageFactory->CreateEncoder(GUID_ContainerFormatPng, NULL, &pEncoder); pStream->InitializeFromFilename(path, GENERIC_WRITE); pEncoder->Initialize(pStream, WICBitmapEncoderNoCache); pEncoder->CreateNewFrame(&pFrameEncode, NULL); pFrameEncode->Initialize(NULL); pFrameEncode->SetSize(w, h); pFrameEncode->SetPixelFormat(&format); pFrameEncode->WriteSource(bmp, NULL); pFrameEncode->Commit(); pEncoder->Commit(); pFrameEncode->Release(); pStream->Release(); pEncoder->Release(); } ID2D1PathGeometry* Factory::CreateGeomtry() { ID2D1PathGeometry* geo = NULL; HRESULT hr = _D2DFactory->CreatePathGeometry(&geo); if (SUCCEEDED(hr)) return geo; return NULL; } IDWriteTextLayout* Factory::CreateStringLayout(std::wstring str, float width, float height, IDWriteTextFormat* font) { IDWriteTextLayout* textLayout = NULL; _DWriteFactory->CreateTextLayout(str.c_str(), str.size(), font, width, height, &textLayout); return textLayout; } HRESULT Factory::ExtractID2D1Bitmap1ToIWICBitmap( ID2D1DeviceContext* pDeviceContext, ID2D1Bitmap1* pSourceBitmap, IWICImagingFactory* pWICFactory, IWICBitmap** ppWICBitmap) { if (!pDeviceContext || !pSourceBitmap || !pWICFactory || !ppWICBitmap) return E_INVALIDARG; HRESULT hr = S_OK; D2D1_SIZE_U size = pSourceBitmap->GetPixelSize(); D2D1_PIXEL_FORMAT pixelFormat = pSourceBitmap->GetPixelFormat(); D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1( D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, pixelFormat); ID2D1Bitmap1* pCPUBitmap = NULL; hr = pDeviceContext->CreateBitmap( size, NULL, 0, &bitmapProperties, &pCPUBitmap); if (SUCCEEDED(hr)) { hr = pCPUBitmap->CopyFromBitmap(NULL, pSourceBitmap, NULL); if (SUCCEEDED(hr)) { D2D1_MAPPED_RECT mappedRect; hr = pCPUBitmap->Map(D2D1_MAP_OPTIONS_READ, &mappedRect); if (SUCCEEDED(hr)) { hr = pWICFactory->CreateBitmap( size.width, size.height, GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnLoad, ppWICBitmap); if (SUCCEEDED(hr)) { IWICBitmapLock* pLock = NULL; WICRect rect = { 0, 0, static_cast(size.width), static_cast(size.height) }; hr = (*ppWICBitmap)->Lock(&rect, WICBitmapLockWrite, &pLock); if (SUCCEEDED(hr)) { UINT bufferSize = 0; BYTE* pBuffer = NULL; UINT stride = 0; hr = pLock->GetDataPointer(&bufferSize, &pBuffer); if (SUCCEEDED(hr)) { hr = pLock->GetStride(&stride); if (SUCCEEDED(hr)) { for (UINT y = 0; y < size.height; y++) { memcpy( pBuffer + y * stride, mappedRect.bits + y * mappedRect.pitch, min(stride, mappedRect.pitch)); } } } pLock->Release(); } } pCPUBitmap->Unmap(); } } pCPUBitmap->Release(); } return hr; }