第27章 抗锯齿实例讲解
本期教程主要是通过三个官方的抗锯齿实例跟大家讲解下抗锯齿的使用。
27. 1 例子一:AA_HiResAntialiasing
27. 2 例子二:AA_HiResPixels
27. 3 例子三:AA_Lines
27. 4 总结
27.1 例子一:AA_HiResAntialiasing
这个例子主要是演示了两个动态的指针,一个具有抗锯齿效果,另一个没有抗锯齿效果。例子所在的位置如下:
例子实际显示效果如下:
下面跟大家分析下这个程序的源码:
- #include "GUI.h"
-
- /*******************************************************************
- *
- * Defines
- *
- ********************************************************************
- */
- #define countof(Obj) (sizeof(Obj)/sizeof(Obj[0]))(1)
-
- /*******************************************************************
- *
- * static variables
- *
- ********************************************************************
- */
-
- static const GUI_POINT _aPointer[] = {(2)
- { 0, 3},
- {85, 1},
- {90, 0},
- {85, -1},
- { 0, -3}
- };
-
- static GUI_POINT _aPointerHiRes[countof(_aPointer)];
-
- typedef struct {
- GUI_AUTODEV_INFO AutoInfo;
- GUI_POINT aPoints[countof(_aPointer)];
- int Factor;
- } PARAM;
-
- /*******************************************************************
- *
- * Static functions
- *
- ********************************************************************
- */
- /*******************************************************************
- *
- * _DrawHiRes
- *
- * Function description
- * This function draws the high resolution pointer
- */
- static void _DrawHiRes(void * p) {
- PARAM * pParam = (PARAM *)p;
- if (pParam->AutoInfo.DrawFixed) {
- GUI_ClearRect(60, 60, 159, 159);
- }
- GUI_AA_FillPolygon(pParam->aPoints, (3)
- countof(_aPointer),
- 65 * pParam->Factor,
- 155 * pParam->Factor);
- }
-
- /*******************************************************************
- *
- * _Draw
- *
- * Function description
- * This function draws the non high resolution pointer
- */
- static void _Draw(void * p) {
- PARAM * pParam = (PARAM *)p;
- if (pParam->AutoInfo.DrawFixed) {
- GUI_ClearRect(160, 60, 259, 159);
- }
- GUI_AA_FillPolygon(pParam->aPoints, countof(_aPointer), 165, 155); (4)
- }
-
- /*******************************************************************
- *
- * _ShowHiresAntialiasing
- *
- * Function description
- * This function creates the memory auto devices and handle the
- * rotation of the pointers
- */
- static void _ShowHiresAntialiasing(void) {
- GUI_AUTODEV aAuto[2];
- PARAM Param;
- unsigned i;
-
- Param.Factor = 3;
- GUI_SetBkColor(GUI_BLACK);
- GUI_Clear();
- GUI_SetColor(GUI_WHITE);
- GUI_SetTextAlign(GUI_TA_HCENTER);
- GUI_SetFont(&GUI_Font24_ASCII);
- GUI_DispStringAt("AA_HiResAntialiasing - Sample", 160, 5);
- GUI_SetFont(&GUI_Font6x8);
- GUI_DispStringHCenterAt("Using\nhigh\nresolution\nmode", 110, 180);
- GUI_DispStringHCenterAt("Not using\nhigh\nresolution\nmode", 210, 180);
- //
- // Create GUI_AUTODEV objects
- //
- for (i = 0; i < countof(aAuto); i++) {(5)
- GUI_MEMDEV_CreateAuto(&aAuto[i]);
- }
- //
- // Calculate pointer for high resolution
- //
- for (i = 0; i < countof(_aPointer); i++) {
- _aPointerHiRes[i].x = _aPointer[i].x * Param.Factor;
- _aPointerHiRes[i].y = _aPointer[i].y * Param.Factor;
- }
- GUI_AA_SetFactor(Param.Factor); /* Set antialiasing factor */(6)
- while (1) {
- for (i = 0; i < 1800; i++) {
- float Angle = (i >= 900) ? 1800 - i : i;
- Angle *= 3.1415926f / 1800;
- //
- // Draw pointer with high resolution(7)
- //
- GUI_AA_EnableHiRes();
- GUI_RotatePolygon(Param.aPoints, _aPointerHiRes, countof(_aPointer), Angle);
- GUI_MEMDEV_DrawAuto(&aAuto[0], &Param.AutoInfo, _DrawHiRes, &Param);
- //
- // Draw pointer without high resolution(8)
- //
- GUI_AA_DisableHiRes();
- GUI_RotatePolygon(Param.aPoints, _aPointer, countof(_aPointer), Angle);
- GUI_MEMDEV_DrawAuto(&aAuto[1], &Param.AutoInfo, _Draw, &Param);
- GUI_Delay(2);
- }
- }
- }
-
- /*********************************************************************
- *
- * Public code
- *
- **********************************************************************
- */
- /*********************************************************************
- *
- * MainTask
- */
- void MainTask(void) {
- GUI_Init();
- _ShowHiresAntialiasing();
- }
1. 通过这种方式可以获得数组中元素的个数。
2. 指针的坐标点,注意这些坐标点的值是相对于函数中指定的X,Y来说说的。这些数组中的值是相对值。
3. 这个函数在26.2.6小节有讲解。
4. 同上,只是这里没有使用高分辨率。
5. 创建一个内存设备,这个函数会在后面教程中再跟大家详细讲解。
6. 设置抗锯齿因子。
7. 绘制指针,带抗锯齿效果。
8. 绘制指针,不带抗锯齿效果。
27.2 例子二:AA_HiResPixels
这个例子主要也是演示一下高分辨率,例子所在位置:
例子实际显示效果如下:
下面跟大家分析下这个程序的源码:
- #include "GUI.h"
- #include "WM.h"
-
- /*******************************************************************
- *
- * Defines
- *
- ********************************************************************
- */
- #define AA_FACTOR 4
- #define POLY_SIZE 19
- #define POLY_POINTS 3
-
- #define COORD_0(Plus, AA_Factor) (I16)(((I32)((Plus ? POLY_SIZE : -POLY_SIZE) * AA_Factor * 0.7071f * 10000)) / 10000)
- #define COORD_1(Plus, AA_Factor) (I16)(((I32)((Plus ? POLY_SIZE : -POLY_SIZE) * AA_Factor * 1.2247f * 10000)) / 10000)
- #define COORD_2(Plus, AA_Factor) (I16)(((I32)((Plus ? POLY_SIZE : -POLY_SIZE) * AA_Factor * 1.4142f * 10000)) / 10000)
-
- /*******************************************************************
- *
- * Static variables
- *
- ********************************************************************
- */
- static int _pos_x1 = 30;
- static int _pos_y1 = 30;
- static int _pos_x2 = 125;
- static int _pos_y2 = 30;
- static int _pos_x3 = 220 * AA_FACTOR;
- static int _pos_y3 = 30 * AA_FACTOR;
- static int _color_d = -1;
- static GUI_COLOR _color_a = 0xFF00FE;
- static GUI_COLOR _color_b = 0x00FEFF;
- static GUI_COLOR _color_c = 0xFEFFFE;
-
- static const GUI_POINT _aPolygon_src[] = { (1)
- { 0, COORD_2(0, 1) },
- { COORD_1(1, 1), COORD_0(1, 1) },
- { COORD_1(0, 1), COORD_0(1, 1) }
- };
-
- static const GUI_POINT _aPolygonHiRes_src[] = { (2)
- { 0, COORD_2(0, AA_FACTOR) },
- { COORD_1(1, AA_FACTOR), COORD_0(1, AA_FACTOR) },
- { COORD_1(0, AA_FACTOR), COORD_0(1, AA_FACTOR) }
- };
-
- static GUI_POINT _aPolygon[POLY_POINTS];
- static GUI_POINT _aPolygonHiRes[POLY_POINTS];
-
- /*******************************************************************
- *
- * Static code
- *
- ********************************************************************
- */
- /*******************************************************************
- *
- * _cbWindow
- *
- * Function description
- * This is the callback for the window. A callback was used
- * for memory devices.
- */
- static void _cbWindow(WM_MESSAGE * pMsg) {(3)
- switch (pMsg->MsgId) {
- case WM_PAINT:
- GUI_SetBkColor(_color_a); (4)
- GUI_ClearRect( 0, 0, 250, 14);
- GUI_SetBkColor(_color_b);
- GUI_ClearRect( 0, 15, 250, 29);
- GUI_SetBkColor(GUI_BLACK);
- GUI_ClearRect( 0, 30, 250, 60);
- GUI_SetColor(_color_c);
- GUI_FillPolygon(_aPolygon, POLY_POINTS, _pos_x1, _pos_y1);(5)
- GUI_AA_FillPolygon(_aPolygon, POLY_POINTS, _pos_x2, _pos_y2);(6)
- GUI_AA_EnableHiRes();
- GUI_AA_FillPolygon(_aPolygonHiRes, POLY_POINTS, _pos_x3, _pos_y3);(7)
- GUI_AA_DisableHiRes();
- break;
- default:
- WM_DefaultProc(pMsg);
- }
- }
-
- /*******************************************************************
- *
- * _CalcColor
- *
- * Function description
- * Calculates the color-fading.
- */
- static void _CalcColor(void) {
- _color_a += 0x000002 * _color_d;
- _color_b += 0x000200 * _color_d;
- _color_c += 0x020002 * _color_d;
- if (_color_c == 0xFEFFFE || _color_c == 0x00FF00) {
- _color_d = -_color_d;
- }
- }
-
- /*******************************************************************
- *
- * _ShowHiResPixels
- *
- * Function description
- * This is frame-function for the callback. It creates the window
- * and handles the rotation of polygons and colors.
- */
- static void _ShowHiResPixels(void) {
- const GUI_FONT * FontOld;
- WM_HWIN hWindow;
- float pi;
- float Step;
- float Angle;
- int i;
-
- pi = 3.1415926f;
- Step = pi / 180;
- GUI_SetBkColor(GUI_BLACK);
- GUI_Clear();
- GUI_SetColor(GUI_WHITE);
- GUI_SetTextAlign(GUI_TA_HCENTER);
- FontOld = GUI_SetFont(&GUI_Font24_ASCII);
- GUI_DispStringAt("AA_HiResPixels - Sample", 160, 5);
- GUI_SetFont(FontOld);
- GUI_SetColor(GUI_RED);
- GUI_DispStringHCenterAt("not\nantialised", 65, 100);
- GUI_SetColor(GUI_GREEN);
- GUI_DispStringHCenterAt("antialised", 160, 100);
- GUI_SetColor(GUI_BLUE);
- GUI_DispStringHCenterAt("antialised\nwith high\nresolution", 255, 100);
- hWindow = WM_CreateWindow(35, 140, 250, 60, WM_CF_SHOW | WM_CF_MEMDEV, _cbWindow, 0);
- WM_SelectWindow(hWindow);
- GUI_AA_SetFactor(AA_FACTOR);
- while (1) {
- for (i = 0, Angle = 0; i < 360; i++) {(8)
- Angle += Step;
- GUI_RotatePolygon(_aPolygonHiRes, _aPolygonHiRes_src, POLY_POINTS, Angle);(9)
- GUI_RotatePolygon(_aPolygon, _aPolygon_src, POLY_POINTS, Angle);
- _CalcColor();
- WM_InvalidateWindow(hWindow);(10)
- GUI_Delay(50);
- }
- }
- }
-
- /*********************************************************************
- *
- * Public code
- *
- **********************************************************************
- */
- /*********************************************************************
- *
- * MainTask
- */
- void MainTask(void) {
- GUI_Init();
- _ShowHiResPixels();
- }
1. 多边形的原始坐标。
2. 加入了高分辨率后的坐标点。
3. 所创建窗口的回调函数。
4. 这里主要是实现回调函数中的重绘消息。
5. 绘制多边形。
6. 绘制具有抗锯齿效果的多边形。
7. 绘制具有抗锯齿并支持高分辨率坐标的多边形。
8. 通过for循环实现图像的旋转。
9. 旋转多边形的原始坐标点,得到新的坐标点。详细可以看用户手册上面对这个函数的介绍
10. 通过使窗口无效来执行回调函数。从而实现多边形的旋转效果。
27.3 例子三:AA_HiResAntialiasing
这个例子给大家演示一下直线的抗锯齿效果,例子所在位置:
例子实际显示效果如下:
下面跟大家分析下这个程序的源码:
- #include "GUI.h"
-
- /*******************************************************************
- *
- * Static code
- *
- ********************************************************************
- */
- /*******************************************************************
- *
- * _DemoAntialiasing
- *
- * Function description
- * Draws lines with different antialiasing factors
- */
- static void _DemoAntialiasing(void) {
- const GUI_FONT * font_old;
- int i;
- int x1;
- int x2;
- int y1;
- int y2;
-
- y1 = 65;
- y2 = 5;
- //
- // Set drawing attributes
- //
- GUI_SetColor(GUI_WHITE);
- GUI_SetBkColor(GUI_BLACK);
- GUI_SetPenShape(GUI_PS_FLAT);(1)
- GUI_Clear();
- //
- // Draw headline
- //
- font_old = GUI_SetFont(&GUI_Font24_ASCII);
- GUI_SetTextAlign(GUI_TA_HCENTER);
- GUI_DispStringAt("AA_Lines - Sample", 160, 5);
- //
- // Draw lines without antialiased (2)
- //
- GUI_Delay(1000);
- GUI_SetFont(&GUI_Font8x16);
- GUI_SetTextAlign(GUI_TA_LEFT);
- GUI_DispStringAtCEOL("draw normal lines using", 5, 40);
- GUI_DispStringAtCEOL("GUI_DrawLine", 5, 55);
- GUI_Delay(2500);
- x1 = 20;
- x2 = 100;
- GUI_SetFont(font_old);
- GUI_DispStringHCenterAt("Normal", (x1 + x2) / 2, 30 + y1);
- for (i = 1; i < 8; i++) {
- GUI_SetPenSize(i);
- GUI_DrawLine(x1, 40 + i * 15 + y1, x2, 40 + i * 15 + y1 + y2);
- }
- //
- // Draw lines with antialiasing quality factor 2 (3)
- //
- GUI_Delay(3000);
- GUI_SetFont(&GUI_Font8x16);
- GUI_DispStringAtCEOL("", 5, 40);
- GUI_DispStringAtCEOL("", 5, 55);
- GUI_Delay(200);
- GUI_DispStringAtCEOL("draw antialiased lines using", 5, 40);
- GUI_DispStringAtCEOL("GUI_AA_DrawLine", 5, 55);
- GUI_Delay(3500);
- x1 = 120;
- x2 = 200;
- GUI_AA_SetFactor(2);
- GUI_SetFont(font_old);
- GUI_DispStringHCenterAt("Antialiased\nusing factor 2", (x1 + x2) / 2, 30 + y1);
- for (i = 1; i < 8; i++) {
- GUI_SetPenSize(i);
- GUI_AA_DrawLine(x1, 40 + i * 15 + y1, x2, 40 + i * 15 + y1 + y2);
- }
- //
- // Draw lines with antialiasing quality factor 6 (4)
- //
- GUI_Delay(1500);
- x1 = 220;
- x2 = 300;
- GUI_AA_SetFactor(6);
- GUI_SetFont(font_old);
- GUI_DispStringHCenterAt("Antialiased\nusing factor 6", (x1 + x2) / 2, 30 + y1);
- for (i = 1; i < 8; i++) {
- GUI_SetPenSize(i);
- GUI_AA_DrawLine(x1, 40 + i * 15 + y1, x2, 40 + i * 15 + y1 + y2);
- }
- GUI_Delay(7500);
- }
-
- /*********************************************************************
- *
- * Public code
- *
- **********************************************************************
- */
- /*********************************************************************
- *
- * MainTask
- */
- void MainTask(void) {
- GUI_Init();
- while (1) {
- _DemoAntialiasing();
- }
- }
1. 这个函数在手册上面没有查到相关的说明。
2. 绘制普通的直线,不具有抗锯齿效果。
3. 绘制具有抗锯齿效果的直线,抗锯齿因子取2.
4. 绘制具有抗锯齿效果的直线,抗锯齿因子取4。
27.4 总结
通过上面三个例子,大家要明白两点:
1、默认使用GUI_AA_XXX函数的时候,抗锯齿因子是1,也就是不使用抗锯齿效果。
2、上面说的抗锯齿和高分辨率是两码事,这个千万别搞混了。简单的理解就是通过高分辨率可以实现更好的显示效果。