Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef UNICODE
- #define UNICODE
- #endif
- #include <Windows.h>
- #include <d2d1_1.h>
- #include <dwrite_1.h>
- #include <d3d11_1.h>
- #include <d2d1effects.h>
- #pragma comment(lib, "d2d1.lib")
- #pragma comment(lib, "dwrite.lib")
- #pragma comment(lib, "d3d11.lib")
- #pragma comment(lib, "dxguid.lib")
- #define DEBUG
- template <class T> void SafeRelease(T** ppT) {
- if (*ppT) {
- (*ppT)->Release();
- *ppT = nullptr;
- }
- }
- class MainWindow {
- public:
- struct {
- HWND hwnd;
- ID2D1Factory1* d2dFactory;
- IDWriteFactory1* dwriteFactory;
- ID3D11Device1* d3dDevice;
- ID3D11DeviceContext1* d3dDeviceContext;
- ID2D1Device* d2dDevice;
- ID2D1DeviceContext* d2dDeviceContext;
- ID2D1Bitmap1* d2dTargetBitmap;
- IDXGIDevice1* dxgiDevice;
- IDXGISwapChain1* dxgiSwapChain;
- ID2D1BitmapRenderTarget* d2dBitmapRenderTarget;
- ID2D1Bitmap* d2dBitmap;
- ID2D1Effect* d2dEffect;
- IDWriteTextFormat* textFormat;
- PCWSTR text;
- ID2D1SolidColorBrush* defaultBrush;
- } state;
- PCWSTR w_className = L"direct2d_template_MainWindow_class";
- PCWSTR w_title = L"Direct2D Template";
- MainWindow() : state({ }) {
- ZeroMemory(&state, sizeof(state));
- }
- static LRESULT CALLBACK WindowProcedure(
- HWND hwnd,
- UINT msg,
- WPARAM wparam,
- LPARAM lparam
- ) {
- MainWindow* win = nullptr;
- if (msg == WM_CREATE) {
- CREATESTRUCT* pCreate = (CREATESTRUCT*) lparam;
- win = (MainWindow*) pCreate->lpCreateParams;
- SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) win);
- if (FAILED(D2D1CreateFactory(
- D2D1_FACTORY_TYPE_SINGLE_THREADED,
- __uuidof(ID2D1Factory1),
- reinterpret_cast<void**>(&win->state.d2dFactory)
- ))) return -1;
- if (FAILED(DWriteCreateFactory(
- DWRITE_FACTORY_TYPE_SHARED,
- __uuidof(IDWriteFactory1),
- reinterpret_cast<IUnknown**>(&win->state.dwriteFactory)
- ))) return -1;
- if (!win->CreateDirect3DDevice()) return -1;
- if (!win->CreateDirect2DDevice()) return -1;
- if (!win->CreateSwapChain(hwnd)) return -1;
- if (!win->ConfigureSwapChain(hwnd)) return -1;
- if (FAILED(win->state.dwriteFactory->CreateTextFormat(
- L"Work Sans",
- nullptr,
- DWRITE_FONT_WEIGHT_NORMAL,
- DWRITE_FONT_STYLE_NORMAL,
- DWRITE_FONT_STRETCH_NORMAL,
- 13.2f,
- L"en-us",
- &win->state.textFormat
- ))) return -1;
- if (!win->CreateBrushes()) return -1;
- if (FAILED(win->state.d2dDeviceContext->CreateEffect(
- CLSID_D2D1GaussianBlur, &win->state.d2dEffect
- ))) return -1;
- return 0;
- } else {
- win = (MainWindow*) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
- }
- switch (msg) {
- case WM_PAINT: {
- if (!win->HandlePaint()) {
- #ifdef DEBUG
- OutputDebugStringW(L"Error: Failed to handle WM_PAINT.\n");
- #endif
- return 1;
- }
- return 0;
- }
- case WM_SIZE: {
- if (!win->HandleResize(LOWORD(lparam), HIWORD(lparam))) {
- #ifdef DEBUG
- OutputDebugStringW(L"Error: Failed to handle WM_PAINT.\n");
- #endif
- return 1;
- }
- return 0;
- }
- case WM_DESTROY: {
- PostQuitMessage(0);
- return 0;
- }
- default:
- return DefWindowProcW(hwnd, msg, wparam, lparam);
- }
- }
- bool Init(HINSTANCE hInstance, int nCmdShow) {
- WNDCLASSEXW wclass = { };
- ZeroMemory(&wclass, sizeof(wclass));
- wclass.cbSize = sizeof(WNDCLASSEX);
- wclass.hInstance = hInstance;
- wclass.lpszClassName = w_className;
- wclass.lpfnWndProc = MainWindow::WindowProcedure;
- if (RegisterClassExW(&wclass) == 0) {
- #ifdef DEBUG
- OutputDebugStringW(L"Error: Failed to register window class.\n");
- #endif
- return false;
- }
- state.hwnd = CreateWindowExW(
- 0,
- w_className,
- w_title,
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT,
- 420, 320,
- NULL,
- NULL,
- hInstance,
- this
- );
- if (state.hwnd == NULL) {
- #ifdef DEBUG
- OutputDebugStringW(L"Error: Failed to create window.\n");
- #endif
- return false;
- }
- ShowWindow(state.hwnd, nCmdShow);
- return true;
- }
- void MainLoop() {
- MSG msg = { };
- while (true) {
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- if (msg.message == WM_QUIT)
- break;
- TranslateMessage(&msg);
- DispatchMessageW(&msg);
- }
- }
- };
- bool CreateDirect3DDevice() {
- if (!state.d3dDevice || !state.d3dDeviceContext) {
- D3D_FEATURE_LEVEL d3dFeatureLevels[] = {
- D3D_FEATURE_LEVEL_11_1,
- D3D_FEATURE_LEVEL_11_0,
- D3D_FEATURE_LEVEL_10_1,
- D3D_FEATURE_LEVEL_10_0,
- D3D_FEATURE_LEVEL_9_3,
- D3D_FEATURE_LEVEL_9_2,
- D3D_FEATURE_LEVEL_9_1
- };
- D3D_FEATURE_LEVEL d3dSupportedFeatureLevel;
- ID3D11Device* temp_d3dDevice;
- ID3D11DeviceContext* temp_d3dDeviceContext;
- if (FAILED(D3D11CreateDevice(
- nullptr,
- D3D_DRIVER_TYPE_HARDWARE,
- NULL,
- D3D11_CREATE_DEVICE_BGRA_SUPPORT,
- d3dFeatureLevels,
- ARRAYSIZE(d3dFeatureLevels),
- D3D11_SDK_VERSION,
- &temp_d3dDevice,
- &d3dSupportedFeatureLevel,
- &temp_d3dDeviceContext
- ))) return false;
- if (FAILED(temp_d3dDevice->QueryInterface(
- IID_PPV_ARGS(&state.d3dDevice)
- ))) return false;
- if (FAILED(temp_d3dDeviceContext->QueryInterface(
- IID_PPV_ARGS(&state.d3dDeviceContext)
- ))) return false;
- }
- return true;
- }
- bool CreateDirect2DDevice() {
- if (!state.dxgiDevice) {
- if (!state.d3dDevice) return false;
- if (FAILED(state.d3dDevice->QueryInterface(
- IID_PPV_ARGS(&state.dxgiDevice)
- ))) return false;
- }
- if (!state.d2dDevice) {
- if (FAILED(state.d2dFactory->CreateDevice(
- state.dxgiDevice,
- &state.d2dDevice
- ))) return false;
- }
- if (!state.d2dDeviceContext) {
- if (FAILED(state.d2dDevice->CreateDeviceContext(
- D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
- &state.d2dDeviceContext
- ))) return false;
- state.d2dDeviceContext->SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
- state.d2dDeviceContext->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_DEFAULT);
- }
- return true;
- }
- bool CreateSwapChain(HWND hwnd) {
- if (!state.dxgiSwapChain) {
- DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { };
- swapChainDesc.Width = 0;
- swapChainDesc.Height = 0;
- swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
- swapChainDesc.BufferCount = 2;
- swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
- swapChainDesc.SampleDesc.Count = 1;
- swapChainDesc.SampleDesc.Quality = 0;
- swapChainDesc.Stereo = false;
- swapChainDesc.Flags = 0;
- swapChainDesc.Scaling = DXGI_SCALING_NONE;
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
- IDXGIAdapter* dxgiAdapter;
- if (FAILED(state.dxgiDevice->GetAdapter(&dxgiAdapter))) return false;
- IDXGIFactory2* dxgiFactory;
- if (FAILED(dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory)))) return false;
- if (FAILED(dxgiFactory->CreateSwapChainForHwnd(
- state.d3dDevice,
- hwnd,
- &swapChainDesc,
- nullptr,
- nullptr,
- &state.dxgiSwapChain
- ))) return false;
- state.dxgiDevice->SetMaximumFrameLatency(1);
- SafeRelease(&dxgiFactory);
- SafeRelease(&dxgiAdapter);
- }
- return true;
- }
- bool ConfigureSwapChain(HWND hwnd) {
- if (state.dxgiSwapChain) {
- UINT dpi = GetDpiForWindow(hwnd);
- D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(
- D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
- D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE),
- dpi,
- dpi,
- nullptr
- );
- IDXGISurface* dxgiSurface = nullptr;
- if (FAILED(state.dxgiSwapChain->GetBuffer(
- 0,
- IID_PPV_ARGS(&dxgiSurface)
- ))) return false;
- if (FAILED(state.d2dDeviceContext->CreateBitmapFromDxgiSurface(
- dxgiSurface,
- bitmapProperties,
- &state.d2dTargetBitmap
- ))) return false;
- state.d2dDeviceContext->SetTarget(state.d2dTargetBitmap);
- SafeRelease(&dxgiSurface);
- }
- return true;
- }
- bool HandlePaint() {
- PAINTSTRUCT ps;
- BeginPaint(state.hwnd, &ps);
- if (state.d2dDeviceContext && state.dxgiSwapChain) {
- state.d2dDeviceContext->BeginDraw();
- // Begin Draw
- state.d2dDeviceContext->Clear(D2D1::ColorF(1, 1, 1, 1));
- PCWSTR text = L"ใในใ";
- D2D1_SIZE_F clientSize = state.d2dDeviceContext->GetSize();
- state.d2dDeviceContext->DrawTextW(
- text,
- wcslen(text),
- state.textFormat,
- D2D1::RectF(10, 10, 100, 100),
- state.defaultBrush
- );
- if (FAILED(state.d2dDeviceContext->CreateCompatibleRenderTarget(
- &state.d2dBitmapRenderTarget
- ))) return false;
- if (FAILED(state.d2dBitmapRenderTarget->GetBitmap(
- &state.d2dBitmap
- ))) return false;
- state.d2dEffect->SetInput(0, state.d2dBitmap);
- state.d2dEffect->SetValue(D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, 32.0f);
- state.d2dDeviceContext->DrawImage(state.d2dEffect);
- // End Draw
- HRESULT hresult = state.d2dDeviceContext->EndDraw();
- SafeRelease(&state.d2dBitmapRenderTarget);
- if (FAILED(hresult)) {
- if (hresult == D2DERR_RECREATE_TARGET) {
- state.d2dDeviceContext->SetTarget(nullptr);
- SafeRelease(&state.d2dDeviceContext);
- if (!CreateDirect2DDevice()) return false;
- if (!CreateSwapChain(state.hwnd)) return false;
- if (!ConfigureSwapChain(state.hwnd)) return false;
- }
- return false;
- }
- state.dxgiSwapChain->Present(1, 0);
- }
- EndPaint(state.hwnd, &ps);
- return true;
- }
- bool HandleResize(UINT nwidth, UINT nheight) {
- if (state.dxgiSwapChain) {
- state.d2dDeviceContext->SetTarget(nullptr);
- SafeRelease(&state.d2dTargetBitmap);
- HRESULT hresult = state.dxgiSwapChain->ResizeBuffers(
- 2,
- nwidth,
- nheight,
- DXGI_FORMAT_B8G8R8A8_UNORM,
- 0
- );
- if (hresult == DXGI_ERROR_DEVICE_REMOVED || hresult == DXGI_ERROR_DEVICE_RESET) {
- if (!CreateDirect3DDevice()) return false;
- if (!CreateDirect2DDevice()) return false;
- if (!CreateSwapChain(state.hwnd)) return false;
- }
- ConfigureSwapChain(state.hwnd);
- InvalidateRect(state.hwnd, NULL, FALSE);
- }
- return true;
- }
- bool CreateBrushes() {
- if (FAILED(state.d2dDeviceContext->CreateSolidColorBrush(
- D2D1::ColorF(0, 0, 0, 1),
- &state.defaultBrush
- ))) return false;
- return true;
- }
- void DiscardBrushes() {
- SafeRelease(&state.defaultBrush);
- }
- };
- int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR, int nCmdShow) {
- MainWindow* win = new MainWindow;
- if (!win->Init(hInstance, nCmdShow)) {
- #ifdef DEBUG
- OutputDebugStringW(L"Error: Failed to initialize window.\n");
- #endif
- return 1;
- }
- win->MainLoop();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement