这一篇主要谈谈如何创建简单的D2D窗口并绘制一个进行sin移动矩形出来。
首先,我们需要有个比较清楚的思路来进行D2D的开发。
开发Direct2D程序的一般步骤
l 包含 Direct2D 头文件
l 创建 D2D1Factory
l 创建 RenderTarget
l 创建画刷
l 渲染
l 释放资源
以上就是做Direct2D开发的一般步骤,具体的我们可以暂时不管它,到时候可发的时候可以慢慢领会。
不过我们需要记住的是,微软给我们提供了很多库供我们使用开发,那么,我们就需要根据他们的思路来进行开发,很多时候没有那么多为什么的。
好,现在我们就来开始实现出一个简单的D2D窗口并画出一个矩形出来。
步骤过程如下:
第一步:
包含头文件
#include<d2d1.h>
创建D2D1Factory
ID2D1Factory *pFactory = NULL; HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory);
创建RenderTarget
ID2D1HwndRenderTarget *pRenderTarget = NULL; RECT rtClient = { 0 };//定义一个矩形 GetClientRect(hwnd, &rtClient);//获得窗口大小 HRESULT hr = pFactory->CreateHwndRenderTarget( D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties( hwnd, D2D1::SizeU( rtClient.right - rtClient.left, rtClient.bottom - rtClient.top)), &pRenderTarget);
创建画刷
ID2D1SolidColorBrush *pBrush = NULL; HRESULT hr = pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Red), &pBrush);
渲染
pRenderTarget->BeginDraw(); //需要渲染的内容都应该写在BeginDraw()和EndDraw()之间 pRenderTarget->EndDraw();
释放资源
(释放的资源指针)->Release();
/*************************************************************** 功能:简单的D2D窗口创建、矩形的sin曲线移动 作者:*** 版本:1.0 日期:2016.4 ****************************************************************/ #include <Windows.h> #include<d2d1.h> #include<cmath> //函数声明 void CreateResource(); //变量声明 ID2D1Factory *pFactory = NULL; ID2D1HwndRenderTarget *pRenderTarget = NULL; ID2D1SolidColorBrush *pBrush = NULL; HWND hwnd = 0; RECT rt = { 0 }, rtClient = { 0 }; int num = 1; void init() { if (!hwnd) { return; } GetClientRect(hwnd, &rtClient); CreateResource(); } void CreateResource() { HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pFactory); if (SUCCEEDED(hr)) { hr = pFactory->CreateHwndRenderTarget( D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties( hwnd, D2D1::SizeU( rtClient.right - rtClient.left, rtClient.bottom - rtClient.top)), &pRenderTarget); if (SUCCEEDED(hr)) { hr = pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Red), &pBrush); if (FAILED(hr)) { MessageBox(hwnd, TEXT("Create Resource Fail!"), TEXT("Error"), MB_OK); return; } } } } void DrawRectangle() { if (pRenderTarget){ pRenderTarget->BeginDraw(); pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::Black)); pRenderTarget->DrawRectangle(D2D1::RectF(rt.left + 0.0f, rt.top + 200.0f, rt.right + 50.0f, rt.bottom + 250.0f), pBrush); pRenderTarget->EndDraw(); } } void Render() { DrawRectangle(); num += 5; rt.right += 2; rt.left += 2; rt.top = (100 * sin(num * 3.14 / 180)); rt.bottom = (100 * sin(num * 3.14 / 180)); if (rt.right == 1000) { rt = { 0 }; num = 0; } } template<class Interface> inline void SafeRelease(Interface **ppinterfaceToRelease) { if (NULL != *ppinterfaceToRelease) { (*ppinterfaceToRelease)->Release(); (*ppinterfaceToRelease) = NULL; } } void CleanUp() { SafeRelease(&pBrush); SafeRelease(&pRenderTarget); SafeRelease(&pFactory); } LRESULT CALLBACK WndProc(HWND Hwnd, UINT message, WPARAM wParam, LPARAM iParam); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow) { MSG Msg; WNDCLASS wndclass; TCHAR lpszTitle[] = TEXT("MyDemo001"); wndclass.style = CS_HREDRAW|CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = TEXT("MyClass"); wndclass.hbrBackground = 0; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("RegisterClass fail!"), TEXT("error"), MB_ICONERROR); return 0; } hwnd = CreateWindow( TEXT("MyClass"), lpszTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); init(); BOOL bRet; PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE); while (Msg.message != WM_QUIT) { bRet = PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE); if (bRet) { TranslateMessage(&Msg); DispatchMessage(&Msg); } else { Render(); } } CleanUp(); return Msg.wParam; } LRESULT CALLBACK WndProc(HWND Hwnd, UINT message, WPARAM wParam, LPARAM iParam) { switch (message) { case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(Hwnd, message, wParam, iParam); }
最后的效果如下: