WindML双缓冲(Double Buffering)总结

双缓冲的目的是为了不闪烁,下面是从C:\Tornado2.2\target\src\ugl\example\dbuf\wexdbuf.c改造而来的,顺便把键盘鼠标输入和JPEG操作整理了

在: http://www.pudn.com/downloads526/sourcecode/embedded/detail2180188.html 下载

WindML双缓冲(Double Buffering)总结_第1张图片

① 双缓冲:

		//
		// JPEG初始化
		//
		int ret = 0;
		ret = JpegInit();
		if(ret < 0)
		{
			uglBackgroundColorSet(gc, colorTable[BLACK].uglColor);
			uglForegroundColorSet(gc, colorTable[LIGHTGREEN].uglColor);
			uglTextDraw(gc, m0TextCoordinates.x, m0TextCoordinates.y, -1, "JpegInit Error\n");
			return ;
		}

		//
		// 装载第一幅JPEG图片
		//
		ret = JpegFrom("testimg1.jpg", &jpegDdbId1);
		if(ret < 0)
		{
			uglTextDraw(gc, m0TextCoordinates.x, m0TextCoordinates.y, -1, "JpegFrom Error\n");
			return;
		}

		//
		// 装载第二幅JPEG图片
		//
		ret = JpegFrom("testimg2.jpg", &jpegDdbId2);
		if(ret < 0)
		{
			uglTextDraw(gc, m0TextCoordinates.x, m0TextCoordinates.y, -1, "JpegFrom Error\n");
			return;
		}


		//
		// 创建两个要翻的页,并准备开始第二个页面上“画”——“活动页”
		//
		page[0] = UGL_PAGE_ZERO_ID;
		page[1] = uglPageCreate(devId);
		uglPageDrawSet(devId, page[1]);


		//
		// 死循环,里面不断画操作、“翻页”
		//
		while (1)
		{
			//将将加载的第一幅JPEG位图,画到“活动页”
			uglBitmapSizeGet(jpegDdbId1, &jpegWidth, &jpegHeight);
			uglBitmapBlt(gc, jpegDdbId1, 0, 0, jpegWidth - 1, jpegHeight - 1, 
					 UGL_DEFAULT_ID, 0, 0);


			//将将加载的第二幅JPEG位图,画到“活动页”
			uglBitmapSizeGet(jpegDdbId2, &jpegWidth, &jpegHeight);
			uglBitmapBlt(gc, jpegDdbId2, 0, 100, jpegWidth - 1, jpegHeight - 1, 
					 UGL_DEFAULT_ID, 100, 100);


			//画一个大绿色的矩形框到“活动页”
			uglBackgroundColorSet(gc, colorTable[GREEN].uglColor);
			uglForegroundColorSet(gc, colorTable[GREEN].uglColor);
			uglRectangle(gc, rect.left, rect.top,  rect.right, rect.bottom);

			//画一个小一点的黑色的矩形框到“活动页”
			uglBackgroundColorSet(gc, colorTable[BLACK].uglColor);
			uglForegroundColorSet(gc, colorTable[BLACK].uglColor);
			uglRectangle(gc, rect.left + 15, rect.top + 15, rect.right - 15, 
				 rect.bottom - 15);

			//画黄边蓝底的小球到“活动页”
			uglBackgroundColorSet(gc, colorTable[BLUE].uglColor);
			uglForegroundColorSet(gc, colorTable[YELLOW].uglColor);
			uglEllipse(gc, x, y, x + 32, y + 32, 0, 0, 0, 0);



			//
			// 文字显示“活动页”当前鼠标位置和键盘的状态
			//
			uglBackgroundColorSet(gc, colorTable[BLACK].uglColor);
			uglForegroundColorSet(gc, colorTable[LIGHTGREEN].uglColor);

			static char buf[100] = {0};
			static int  k = 0;
			sprintf(buf, "k= %d, mx= %d, my= %d, key= %d\n", k++, mouse_x, mouse_y, key);
			uglTextDraw(gc, 100, 100, -1, buf);


			//
			// 在循环中不断更新小球的位置,这一段不应该放在画线程中!!
			// 
			if (x + 32 >= rect.right - 15)				xinc = -1;
			else if (x <= rect.left + 15)				xinc = 1;

			if (y + 32 >= rect.bottom - 15)				yinc = -1;
			else if (y <= rect.top + 15)				yinc = 1;

			x += xinc;	y += yinc;




			//
			// 开始“翻页”,套用这个框架即可
			//
			if (pageIndex == 0)
			{
				uglPageVisibleSet(devId, page[1]);	//显示当前“活动页”
				uglPageDrawSet(devId, page[0]);		//切换到另一个页面为“活动页”
				pageIndex = 1;
			}
			else
			{
				uglPageVisibleSet(devId, page[0]);
				uglPageDrawSet(devId, page[1]);
				pageIndex = 0;
			}
			
		}//while 结束

② JPEG:

//
// 初始化JPEG
//
int JpegInit()
{
    UGL_JPEG_MODE jpegMode;
    int jpegVersion;

    jpegId = uglJpegInit(devId, &jpegVersion);
    if (jpegId == UGL_NULL) 
	{
		return -1;
	}

    jpegMode.quality = 75;
    jpegMode.smooth = 0;
    jpegMode.scale = 1;
    uglJpegModeSet(jpegId, &jpegMode);

	return 1;
}

//
// 从文件中加载JPEG,到一副位图中
//
int JpegFrom(const char *filename, UGL_DDB_ID *pDdbId)
{
    FILE *fp = fopen(filename, "rb");
    if (fp == NULL)
	{
		return -1;
	}
    else
	{
        uglJpegToDDBFromFile (jpegId, fp, pDdbId, UGL_NULL, 0, 0);
        fclose (fp);
	}

	return 1;
}

③ 键盘和鼠标输入线程:

//
// 键盘和鼠标输入作为一个线程来处理
//
UGL_LOCAL int getInput(void)
{
    UGL_MSG msg;
    UGL_STATUS status;
    int retVal = 0;
	static int kk = 0;
	printf("--%d\n", kk++);

	while(1)
	{
		status = uglInputMsgGet (inputServiceId, &msg, UGL_NO_WAIT);
		printf("--%d\n", kk++);

		if (status != UGL_STATUS_Q_EMPTY)
		{
				switch(msg.type)
				{
					case MSG_POINTER:
						//logMsg("Mouse: %d, %d\n", msg.data.pointer.position.x, msg.data.pointer.position.y, 0, 0, 0, 0);
						mouse_x = msg.data.pointer.position.x;
						mouse_y = msg.data.pointer.position.y;
						break;
					case MSG_KEYBOARD:
						//logMsg("Keyborad: %04x\n", msg.data.keyboard.key, 0, 0, 0, 0, 0);
						key = msg.data.keyboard.key;
						
						break;
				}
		}

		uglOSTaskDelay (2);	//一定要有个延时,否则该线程优先级高于界面画线程时,界面画线程将得不到执行!!
	}
    return(retVal);
}

④ 最后为启动:(因为在cpp文件中,声明时一定要: extern "C" void wexdbuf();

void wexdbuf (void)
{
    stopWex = UGL_FALSE;

	//创建画线程
    uglOSTaskCreate("tWindMLDBuf", (UGL_FPTR)windMLExampleDBuf, 110, 
		    0, 10240, 0,0,0,0,0);

	//等待输入设备创建完毕!!
	taskDelay(sysClkRateGet());//延时1s


	//创建输入多线程——该线程优先级高于“画线程”,因为“画线程”为死循环且循环中无延时
    taskSpawn("tInput", 105, 0, 10000, (FUNCPTR)getInput, 
		    0, 1, 2, 3, 4, 5, 6, 7, 8, 9);

}



你可能感兴趣的:(WindML双缓冲(Double Buffering)总结)