- #include <windows.h>
- #include <d2d1.h>
- #include <d2d1helper.h>
- #include "atlbase.h"
- #include "cvideo.h"
- #include <stdint.h>
- template <typename T>
- inline void SafeRelease(T& p)
- {
- if (NULL != p)
- {
- p.Release();
- p = NULL;
- }
- }
- class CD2D : public cvideo
- {
- protected:
- HWND window_hwnd;
- int scwidth;
- int scheight;
- int prevwidth;
- int prevheight;
- ID2D1Factory * m_d2dFactory;
- HMODULE m_hD2D1Lib;
- CComPtr<ID2D1HwndRenderTarget> m_hWndTarget;
- CComPtr<ID2D1Bitmap> m_bitmap;
- BITMAPINFOHEADER m_pBitmapInfo;
- int createrendbmp(int width, int height)
- {
- if (prevwidth == width && prevheight == height)
- return 0;
- D2D1_PIXEL_FORMAT pixelFormat =
- {
- DXGI_FORMAT_B8G8R8A8_UNORM ,
- D2D1_ALPHA_MODE_IGNORE
- };
- D2D1_RENDER_TARGET_PROPERTIES renderTargetProps =
- {
- D2D1_RENDER_TARGET_TYPE_DEFAULT,
- pixelFormat,
- 0,
- 0,
- D2D1_RENDER_TARGET_USAGE_NONE,
- D2D1_FEATURE_LEVEL_DEFAULT
- };
- RECT rect;
- GetClientRect(window_hwnd, &rect);
- HRESULT hr;
- D2D1_SIZE_U windowSize =
- {
- rect.right - rect.left,
- rect.bottom - rect.top
- };
- D2D1_HWND_RENDER_TARGET_PROPERTIES hWndRenderTargetProps =
- {
- window_hwnd,
- windowSize,
- D2D1_PRESENT_OPTIONS_IMMEDIATELY
- };
- hr = m_d2dFactory->CreateHwndRenderTarget(renderTargetProps, hWndRenderTargetProps, &m_hWndTarget);
- if (hr != S_OK) return -1;
- FLOAT dpiX, dpiY;
- m_d2dFactory->GetDesktopDpi(&dpiX, &dpiY);
- D2D1_BITMAP_PROPERTIES bitmapProps =
- {
- pixelFormat,
- dpiX,
- dpiY
- };
- D2D1_SIZE_U bitmapSize =
- {
- width,
- height
- };
- prevwidth=width;
- prevheight=height;
- hr = m_hWndTarget->CreateBitmap(bitmapSize, bitmapProps, &m_bitmap);
- if (hr != S_OK) return -1;
- return 0;
- }
- public:
- CD2D()
- {
- }
- virtual ~CD2D()
- {
- kill();
- }
- virtual bool init (int width, int height, HWND hwnd)
- {
- m_bitmap = NULL, m_d2dFactory = NULL, m_hWndTarget = NULL, m_hD2D1Lib = NULL;
- m_hD2D1Lib = LoadLibrary(L"D2D1.DLL");
- if (m_hD2D1Lib)
- {
- typedef HRESULT(STDAPICALLTYPE* FPCF)(D2D1_FACTORY_TYPE, REFIID, CONST D2D1_FACTORY_OPTIONS *, void**);
- FPCF pfn = (FPCF) GetProcAddress(m_hD2D1Lib, "D2D1CreateFactory");
- if (pfn == NULL || FAILED(pfn(D2D1_FACTORY_TYPE_SINGLE_THREADED,IID_ID2D1Factory, NULL, (void**)&m_d2dFactory)))
- {
- return false;
- }
- }
- else
- {
- return false;
- }
- window_hwnd = hwnd;
- scwidth = width, scheight = height;
- prevheight = prevwidth = 0;
- return true;
- }
- virtual int blit(int width,int height,void *buffer)
- {
- HRESULT hr;
- if (createrendbmp(scwidth, scheight) == -1)
- return -1;
- hr = m_bitmap->CopyFromMemory(NULL, buffer, width*4);
- if (hr != S_OK) return -1;
- if (!(m_hWndTarget->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED))
- {
- RECT rect;
- GetClientRect(window_hwnd, &rect);
- D2D1_SIZE_U newSize = { rect.right, rect.bottom };
- D2D1_SIZE_U size = m_hWndTarget->GetPixelSize();
- if(newSize.height != size.height || newSize.width != size.width)
- {
- m_hWndTarget->Resize(newSize);
- }
- D2D1_RECT_F rectangle = D2D1::RectF(0, 0, newSize.width, newSize.height);
- m_hWndTarget->BeginDraw();
- m_hWndTarget->Clear(D2D1::ColorF(D2D1::ColorF::Black));
- m_hWndTarget->DrawBitmap(m_bitmap, rectangle,1.0f,D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
- hr = m_hWndTarget->EndDraw();
- ValidateRect(window_hwnd,NULL);
- }
- }
- virtual void kill()
- {
- SafeRelease(m_bitmap);
- SafeRelease(m_hWndTarget);
- if (m_d2dFactory)
- m_d2dFactory->Release();
- FreeLibrary(m_hD2D1Lib);
- }
- };
- cvideo * create_video_d2d()
- {
- return new CD2D;
- }