《Windows游戏编程大师技巧》学习笔记(八)
图形设备描述表
作者在书中对其阐释:
画笔和画刷
- 画笔:用于画线条和轮廓,具有颜色、粗细和线型;
- 画刷:用于填充任何封闭对象,具有颜色、样式,甚至本身可以是位图;
GDI一般只使用一个画笔和一个画刷,即当前的图形设备描述表中每次只有一个画笔或画刷被激活;
所以在绘图前,要先选定一个画笔/画刷,需要注意的是,一旦选定后,直到被修改或程序结束,该画笔/画刷会一直被使用;
GDI关于画笔和画刷句柄的存取位置有限,且创建的画笔和画刷占用系统资源,完成绘图之后务必删除该画笔/画刷;
使用画笔
首先获取画笔对象,使用系统存储的画笔或创建用户自定义的画笔:
1 | HPEN black_pen = (HPEN)GetStockObject(BLACK_PEN); |
GetStockObject
函数用于获取Windows中存储的对象,原型如下:
1 | HGDIOBJ WINAPI GetStockObject(int i); |
Windows中存储对象类型如下表:
CreatePen
函数用于创建用户自定义的画笔,原型如下:
1 | HPEN WINAPI CreatePen( |
画笔样式的可选值如下表:
使用画刷
与画笔的使用相似,可以直接获取系统中存储的画刷对象,或创建用户自定义的画刷;
使用GetStockObject
函数获取和画笔的使用相同,此处不再赘述;
用户自定义的画刷分为两类:实心的(Solid)和阴影线的(Hatched),创建方式分别如下:
1 | HBRUSH green_brush = CreateSolidBrush(RGB(0, 255, 0)); |
CreateSolidBrush
函数原型如下:
1 | HBRUSH WINAPI CreateSolidBrush(COLORREF color); |
CreateHatchBrush
函数原型如下:
1 | HBRUSH WINAPI CreateHatchBrush( |
画刷样式可选值如下表:
选取对象
使用SelectObject
函数选中指定的画笔/画刷对象为当前GDI绘图所使用的对象,函数原型如下:
1 | HGDIOBJ WINAPI SelectObject( |
选中新对象时函数返回旧对象的句柄,可以保存备用;
使用DeleteObject
销毁绘图对象,函数原型如下:
1 | BOOL WINAPI DeleteObject(HGDIOBJ ho); |
销毁画笔等对象时一定要多加小心,删除正在被选中使用的对象将发生严重的错误;
简单的图元绘制
使用画笔和画刷对点、线、平面多边形和圆进行绘制;
绘制点
使用SetPixel
函数绘制点,原型如下:
1 | COLORREF WINAPI SetPixel( |
默认模式下,窗口的坐标系为上下颠倒的第一象限笛卡尔坐标系,笛卡尔坐标系和Windows窗口坐标系对比图如下:
GetWindowDC
和GetDC
都可以用来获取窗口的HDC
,区别在于:GetWindowDC
获取的HDC
覆盖了整个窗口,包含标题栏、菜单、滚动条等内容;而GetDC
获取到的内容仅指定窗口用户区的设备环境;
绘制线段
GDI用一个不可见的小光标,来跟踪将要被绘制的线段当前的起始位置,所以绘制线段需要先设定线段起点,然后移动“光标”到终点,完成绘制;MoveToEx
函数可以设置线段起点位置,原型如下:
1 | BOOL WINAPI MoveToEx( |
lppt
用于保存“光标”在移动前的位置坐标,不需要记录时可以传递NULL
,点坐标的结构体定义如下:
1 | typedef struct tagPOINT |
设定完线段的初始位置后,使用LineTo
函数绘制一条线段,原型如下:
1 | BOOL WINAPI LineTo( |
如下代码可以绘制三个顶点分别为(20, 10)、(30, 20)、(10, 20)的三角形:
1 | MoveToEx(hdc, 20, 10, NULL); |
绘制矩形
有如下三种方式绘制矩形:
Rectangle
函数:使用当前的画笔和画刷绘制矩形,并且会自动填充,原型如下:传递到1
2
3
4
5BOOL WINAPI Rectangle(
HDC hdc,
int left, int top,
int right, int bottom
);Rectangle
函数的坐标为矩形边框,也就是说如果当前画笔线性为NULL
的话,会得到一个在四个方向各短一个像素的实心矩形;FillRect
函数:不使用边界画笔绘制一个填充矩形,包括左上角定点,但不包括右下角定点,原型如下:1
2
3
4
5int WINAPI FillRect(
HDC hDC, // 设备上下文句柄
CONST RECT *lprc, // 矩形结构体指针
HBRUSH hbr // 画刷句柄
);FrameRect
函数:只使用画刷绘制仅有边界的中空矩形,原型如下:1
2
3
4
5int WINAPI FrameRect(
HDC hDC, // 设备上下文句柄
CONST RECT *lprc, // 矩形结构体指针
HBRUSH hbr // 画刷句柄
);
绘制圆
Ellipse
函数用于绘制圆和椭圆,原型如下:
1 | BOOL WINAPI Ellipse( |
绘制多边形
Polygon
函数用于绘制凸多边形,原型如下:
1 | BOOL WINAPI Polygon( |
如果传递的多边形顶点并不能完全使用以绘制凸多边形,那么GDI会尽最大可能将其拆分为多个凸多边形进行绘制,但并不能保证绘制质量。
文本和字体
可以使用GetStockObject
函数获取Windows内预存的字体对象,具体见前文表格所述;
也可以使用CreateFont
函数创建字体对象,使用细节较为复杂,此处不做过多讲述,具体查看Win32文档-CreateFontA function;
Windows系统内置的TrueType字体如下表:
《Windows游戏编程大师技巧》学习笔记(八)