第四章 Windows游戏图形基础

本文详细介绍了GDI的基本概念、绘图、文字输出及位图绘制的实现方法,包括DC的使用、画笔与画刷的创建与选择、随机数应用以及位图的加载与贴图。通过实例代码展示了如何在窗口中绘制不同风格的线条、填充矩形、输出文字以及贴图。

关键字:HPEN、HBRUSH、HFONT、HBITMAP

        在本章中,主要讲述了一些GDI的基本操作。其中有:DC的基本概念、GDI基本绘图(线条、矩形)、文字输出、位图绘制。除了GDI的基本操作之外,还讲了一些随机数的有关概念和函数。

        GDI,即Graphics Device Interface,它是Windows图形显示程序与物理设备(显示屏)之间的桥梁,在程序中,物理设备被简化为DC,程序只需直接对DC进行操作即可。

        一.DC的基本概念

        DC,即Device Context。在计算机上,如果要进行绘图,那么Device就是屏幕,而Device Context就是屏幕上的显示层,程序中显示的任何操作都是在DC上实现的。如果程序要利用GDI进行绘图,首先要获得DC的句柄,当绘图完成之后需要释放DC的句柄。

        获取HDC有两种方式,即BeginPaint()和GetDC():

        1.      BeginPaint():

        BeginPaint()有两个参数,第一个为窗口句柄,第二个为创建的PAINTSTRUCT的指针,即BeginPaint(hwnd,&PAINTSTRUCT)。BeginPaint()返回HDC,当BeginPaint()完成后,由EndPaint()释放句柄完成。

g_hdc = BeginPaint(hwnd, &PAINTSTRUCT);
Game_Paint(hwnd);
EndPaint(hwnd, &PAINTSTRUCT);

        2.      GetDC():

        GetDC(hwnd)返回HDC,完成后由ReleaseDC(hwnd, g_hdc)释放句柄。

g_hdc = GetDC(hwnd);
Game_Paint(hwnd);
ReleaseDC(hwnd, g_hdc);

        二、GDI基本绘图

        GDI基本绘图包括三个步骤:创建绘图工具­(Create***)-> 选中工具(SelectObject)->删除工具(DeleteObject)

        绘图工具包括画笔(HPEN)、画刷(HBRUSH)。

        当选中工具时,需注意在同一设备环境中,只能同时存在一种画笔对象或画刷对象,当已存在时继续选中就只会选中最新的对象,之前所创建的画笔或画刷对象会被替换掉。

        绘制线条通过LineTo和MoveToEX两个函数实现。MoveToEx(g_hdc, x1, y1, LPOINT)将画笔当前点移动到(x1,y1)处,而LineTo(g_hdc, x2, y2)将从画笔当前点到(x2,y2)画出一条直线(即从(x1,y1)到(x2,y2)的直线)。

        绘制矩形通过Rectangle(g_hdc, x1, y1, x2, y2)函数实现,矩形坐上角坐标为(x1,y1),右下角坐标为(x2,y2)。当绘制矩形后,如果通过SelectObject()选中画刷后,会在矩形内用画刷填充满矩形。

        附上对应代码:

        首先定义相关的句柄:

HPEN g_Hpen[7] = { 0 };//定义画笔句柄的数组
HBRUSH g_Brush[7] = { 0 };//定义画刷句柄的数组
int g_iPenStyle[7] = { PS_SOLID, PS_DOT, PS_DASH, PS_DASHDOT, PS_DASHDOTDOT, PS_NULL,
			PS_INSIDEFRAME };//定义画笔样式数组并初始化
int g_iBrushStyle[7] = { HS_VERTICAL, HS_HORIZONTAL, HS_CROSS, HS_DIAGCROSS, HS_FDIAGONAL, 
			HS_BDIAGONAL };//定义画刷样式数组并初始化

        接下来是Game_Init()、Game_Paint()和Game_CleanUp():

BOOL Game_Init(HWND hwnd)
{
	g_hdc = GetDC(hwnd);//获取DC
	//srand((unsigned)time(NULL));
	srand(timeGetTime());//初始化时间种子

	//随机初始化画笔和画刷的颜色值
	for (int i = 0; i <= 6; i++)
	{
		g_Hpen[i] = CreatePen(g_iPenStyle[i], 1, RGB(rand() % 256, rand() % 256, rand() % 256));
		if (i == 6)
			//g_Brush[i] = CreateSolidBrush(RGB(rand() % 256));
			g_Brush[i] = CreateSolidBrush(RGB(rand() % 256, rand() % 256, rand() % 256));
		else
			g_Brush[i] = CreateHatchBrush(g_iBrushStyle[i], RGB(rand() % 256, rand() % 256, rand() % 256));
	}
	Game_Paint(hwnd);
	ReleaseDC(hwnd, g_hdc);
	return TRUE;
}

VOID Game_Paint(HWND hwnd)
{
	int y = 0;//定义一个y坐标

	//一个for循环,用7种不同的画笔绘制线条
	for (int i = 0; i <= 6; i++)
	{
		y = (i + 1) * 70;
		SelectObject(g_hdc, g_Hpen[i]);//选择对应的画笔
		MoveToEx(g_hdc, 30, y, NULL);//光标移动到坐标(30,y)处
		LineTo(g_hdc, 100, y);//从(30,y)到(100,y)绘制线条
	}

	int x1 = 120;//定义两个x坐标
	int x2 = 190;

	//用7种不同的画刷填充矩形
	for (int i = 0; i <= 6; i++)
	{
		SelectObject(g_hdc, g_Brush[i]);//选择对应的画刷
		Rectangle(g_hdc, x1, 70, x2, y);//画出一个封闭的矩形,矩形左上角为(x1,50),右下角为(x2,y)
		x1 += 90;
		x2 += 90;
	}
}

BOOL Game_CleanUp(HWND hwnd)
{
	for (int i = 0; i <= 6; i++)
	{
		DeleteObject(g_Hpen[i]);
		DeleteObject(g_Brush[i]);
	}
	return true;
}

        三、文字输出

        文字输出主要有三种方法,即TextOut()、DrawText()、DrawTextEX(),一般选中TextOut()即可。

        输出的文字主要有三种属性,均可以设置:

        通过SetTextColor(g_hdc, RGB())设置文字颜色。

        通过SetBkMode(g_hdc, iBkMode)设置文字背景颜色。

        通过CreateFont(***)设置文字字体。

        文字输出的Game_Init()、Game_Paint()和Game_CleanUp():

BOOL Game_Init(HWND hwnd)
{
	g_hdc = GetDC(hwnd);
	Game_Paint(hwnd);
	ReleaseDC(hwnd, g_hdc);
	return TRUE;
}

VOID Game_Paint(HWND hwnd)
{
	HFONT hFont = CreateFont(30, 0, 0, 0, 0, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, 0, L"字体");//创建一种字体
	SelectObject(g_hdc, hFont);//将字体选入设备环境中
	SetBkMode(g_hdc, TRANSPARENT);//设置文字输出背景为透明

	wchar_t text1[] = L"Hello,World!";
	wchar_t text2[] = L"Hello, Game!";
	wchar_t text3[] = L"Hello, GTA5!";

	srand(timeGetTime());
	SetTextColor(g_hdc, RGB(rand() % 256, rand() % 256, rand() % 256));//随机设置文字颜色
	TextOut(g_hdc, 30, 150, text1, wcslen(text1));                     //输出文字

	SetTextColor(g_hdc, RGB(rand() % 256, rand() % 256, rand() % 256));
	TextOut(g_hdc, 30, 180, text2, wcslen(text2));

	SetTextColor(g_hdc, RGB(rand() % 256, rand() % 256, rand() % 256));
	TextOut(g_hdc, 30, 210, text3, wcslen(text3));

	DeleteObject(hFont);
}

BOOL Game_CleanUp(HWND hwnd)
{
	return TRUE;
}

        四、位图绘制

        位图绘制主要有四个步骤:

        1.      将位图加载到位图句柄中(LoadImage())。

g_bitmap = (HBITMAP)LoadImage(NULL, L"Naruto.bmp", IMAGE_BITMAP, WINDOW_WIDTH, WINDOW_HEIGHT, LR_LOADFROMFILE);
        2.      建立与屏幕DC相容的内存DC(CreateCompatibleDC())。

g_mdc = CreateCompatibleDC(g_hdc);

3.      将位图对象选中到内存DC中(SelectObject())。

SelectObject(g_mdc, g_bitmap);

4.      将贴图由内存DC贴到屏幕DC中(BitBlt())。

BitBlt(g_hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_mdc, 0, 0, SRCCOPY);

最后附上加载位图的Game_Init()、Game_Paint()和Game_CleanUp():

BOOL Game_Init(HWND hwnd)
{
	g_hdc = GetDC(hwnd);
	
	//位图绘制步骤一:加载位图
	g_bitmap = (HBITMAP)LoadImage(NULL, L"Naruto.bmp", IMAGE_BITMAP, WINDOW_WIDTH, WINDOW_HEIGHT, LR_LOADFROMFILE);

	//步骤四:建立相容DC
	g_mdc = CreateCompatibleDC(g_hdc);

	Game_Paint(hwnd);
	ReleaseDC(hwnd, g_hdc);
	return TRUE;
}

VOID Game_Paint(HWND hwnd)
{
	//步骤三:选用位图对象
	SelectObject(g_mdc, g_bitmap);

	//步骤四:进行贴图
	BitBlt(g_hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_mdc, 0, 0, SRCCOPY);
}

BOOL Game_CleanUp(HWND hwnd)
{
	DeleteObject(g_bitmap);
	DeleteDC(g_mdc);
	return TRUE;
}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值