D2D实例

//#include<windows.h>
//#include<D2D1.h>
//
/*
配置:C++附加包含目录D:\Windows Kits\10\Include\10.0.17763.0\um(D2d1.h
附加库目录D:\Windows Kits\10\Lib\10.0.17134.0\um\x86 (D2d1.lib
附加依赖项:D2d1.lib
子系统:窗口(/ SUBSYSTEM:WINDOWS) 
*/

#include <windows.h>
#include <D2D1.h>

#define SAFE_RELEASE(P) if(P){P->Release() ; P = NULL ;}

ID2D1Factory*			g_pD2DFactory = NULL;	// Direct2D factory
ID2D1HwndRenderTarget*	g_pRenderTarget = NULL;	// Render target
ID2D1SolidColorBrush*	g_pBlackBrush = NULL;	// A black brush, reflect the line color

VOID CreateD2DResource(HWND hWnd)
{
	if (!g_pRenderTarget)
	{
		HRESULT hr;
		//创建工厂 凭空创造  不需要对象 直接产生一个工厂
		hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &g_pD2DFactory);
		if (FAILED(hr))
		{
			MessageBox(hWnd, "Create D2D factory failed!", "Error", 0);
			return;
		}

		// Obtain the size of the drawing area
		RECT rc;
		GetClientRect(hWnd, &rc);

		// Create a Direct2D render target
		//通过工厂创建RenderTarget渲染对象
		hr = g_pD2DFactory->CreateHwndRenderTarget(
			D2D1::RenderTargetProperties(),
			D2D1::HwndRenderTargetProperties(
				hWnd,
				D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top)
			),
			&g_pRenderTarget
		);
		if (FAILED(hr))
		{
			MessageBox(hWnd, "Create render target failed!", "Error", 0);
			return;
		}

		// Create a brush
		//通过渲染对象发 创建一个固定颜色的画刷
		hr = g_pRenderTarget->CreateSolidColorBrush(
			D2D1::ColorF(D2D1::ColorF::Pink),
			&g_pBlackBrush
		);
		if (FAILED(hr))
		{
			MessageBox(hWnd, "Create brush failed!", "Error", 0);
			return;
		}
	}
}

VOID DrawRectangle(HWND hwnd)
{
	CreateD2DResource(hwnd);
	//绘制的代码要放在BeginDraw和EndDraw函数之间
	g_pRenderTarget->BeginDraw();
	//调用Clear函数可以将Render target清除为指定的背景色
	// Clear background color to White
	g_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
	//使用画刷来 DrawRectangle函数用来绘制矩形
	g_pRenderTarget->DrawRectangle(
		D2D1::RectF(10.f, 100.f, 500.f, 500.f),
		g_pBlackBrush
	);

	g_pRenderTarget->DrawLine(
		D2D1::Point2F(100.f, 100.f),
		D2D1::Point2F(500.f, 500.f),
		g_pBlackBrush);

	D2D1_ROUNDED_RECT roundedRect = D2D1::RoundedRect(
		D2D1::RectF(100.f, 100.f, 500.f, 500.f),
		30.0f,
		50.0f
	);
	g_pRenderTarget->DrawRoundedRectangle(roundedRect, g_pBlackBrush, 1.0f);

	D2D1_ELLIPSE ellipse = D2D1::Ellipse(D2D1::Point2F(100.0f, 100.0f), 100.0f, 50.0f);
	g_pRenderTarget->DrawEllipse(ellipse, g_pBlackBrush);

	ellipse = D2D1::Ellipse(D2D1::Point2F(50.0f, 50.0f), 50.0f, 50.0f);
	g_pRenderTarget->DrawEllipse(ellipse, g_pBlackBrush);
	ID2D1PathGeometry* g_pLeftMountainGeometry = NULL;
	//创建Path geometry路径图形

	HRESULT hr2 = g_pD2DFactory->CreatePathGeometry(&g_pLeftMountainGeometry);
	if (SUCCEEDED(hr2))
	{
		//ID2D1GeometrySink用来绘画
		ID2D1GeometrySink *pSink = NULL;
		HRESULT hr3 = g_pLeftMountainGeometry->Open(&pSink); // 获取Sink对象
		if (SUCCEEDED(hr3))
		{
			pSink->BeginFigure(D2D1::Point2F(346,255), D2D1_FIGURE_BEGIN_FILLED);
			// 添加图形 

			D2D1_POINT_2F points[5] = {
				D2D1::Point2F(267, 177),
				D2D1::Point2F(236, 192),
				D2D1::Point2F(212, 160),
				D2D1::Point2F(156, 255),
				D2D1::Point2F(346, 255),
			};

			pSink->AddLines(points, ARRAYSIZE(points));


			pSink->EndFigure(D2D1_FIGURE_END_CLOSED);
		}
		pSink->Close(); // 关闭Sink对象
	}

	//轮廓
	g_pRenderTarget->DrawGeometry(g_pLeftMountainGeometry, g_pBlackBrush, 1.f);
	//填充
	g_pBlackBrush->SetColor(D2D1::ColorF(D2D1::ColorF::OliveDrab, 1.f));
	g_pRenderTarget->FillGeometry(g_pLeftMountainGeometry, g_pBlackBrush);




	//enddraw返回是否画成功了

	HRESULT hr = g_pRenderTarget->EndDraw();
	if (FAILED(hr))
	{
		MessageBox(NULL, "Draw failed!", "Error", 0);
		return;
	}
}
//每个COM对象都有一个Release方法,用来释放自己,这里我们定义一个宏来释放COM对象。
VOID Cleanup()
{
	SAFE_RELEASE(g_pRenderTarget);
	SAFE_RELEASE(g_pBlackBrush);
	SAFE_RELEASE(g_pD2DFactory);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	//D2D响应WM_PAINT消息进行渲染
	case   WM_PAINT:
		DrawRectangle(hwnd);
		return 0;

	case WM_KEYDOWN:
	{
		switch (wParam)
		{
		case VK_ESCAPE:
			SendMessage(hwnd, WM_CLOSE, 0, 0);
			break;
		default:
			break;
		}
	}
	break;

	case WM_DESTROY:
		Cleanup();
		PostQuitMessage(0);
		return 0;
	}

	return DefWindowProc(hwnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{

	WNDCLASSEX winClass;

	winClass.lpszClassName = "Direct2D";
	winClass.cbSize = sizeof(WNDCLASSEX);
	winClass.style = CS_HREDRAW | CS_VREDRAW;
	winClass.lpfnWndProc = WndProc;//函数调用 lpfn (long point function)消息处理
	winClass.hInstance = hInstance;
	winClass.hIcon = NULL;
	winClass.hIconSm = NULL;
	winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	winClass.hbrBackground = NULL;
	winClass.lpszMenuName = NULL;
	winClass.cbClsExtra = 0;
	winClass.cbWndExtra = 0;

	if (!RegisterClassEx(&winClass))
	{
		MessageBox(NULL, TEXT("This program requires Windows NT!"), "error", MB_ICONERROR);
		return 0;
	}

	HWND hwnd = CreateWindowEx(NULL,
		"Direct2D",					// window class name
		"Draw Rectangle",			// window caption
		WS_OVERLAPPEDWINDOW, 		// window style
		CW_USEDEFAULT,				// initial x position
		CW_USEDEFAULT,				// initial y position
		600,						// initial x size
		600,						// initial y size
		NULL,						// parent window handle
		NULL,						// window menu handle
		hInstance,					// program instance handle
		NULL);						// creation parameters

	ShowWindow(hwnd, iCmdShow);
	UpdateWindow(hwnd);

	MSG    msg;
	ZeroMemory(&msg, sizeof(msg));

	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

猜你喜欢

转载自blog.csdn.net/baidu_39486224/article/details/105639030