DirectX技术----D2D基础篇(一)

这一篇主要谈谈如何创建简单的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移动矩形出来)

/***************************************************************
功能:简单的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);
}

需要注意的是,SUCCEEDED或FAILD宏是用来检测创建的对象是否成功的。

最后的效果如下:



你可能感兴趣的:(DirectX技术----D2D基础篇(一))