您的位置:首页 > 其它

如何通过直接访问屏幕内存来直接绘制屏幕并更新

2010-05-09 13:34 363 查看
[打印本页]

--------------------------------------------------------------------------------
作者: freebird 时间: 2009-9-14 23:13 标题: 如何通过直接访问屏幕内存来直接绘制屏幕并更新

有三个方法可以跳过window server来直接绘制屏幕(这里称为Direct drawing),这通常用在游戏程序中使得屏幕绘制更加快速。
其中一个直接访问的方法就是直接访问屏幕内存,并通过编辑内存来绘制屏幕。
这里可以使用UserSvr::ScreenInfo()这个API来获取屏幕地址,结果放在TScreenInfoV01包中,下面的代码片段可以获得内存地址,并绘制一个简单的矩形到屏幕上:

TPckgBuf<TScreenInfoV01> infoPckg;
TScreenInfoV01& screenInfo = infoPckg();
UserSvr::ScreenInfo(infoPckg);
TUint16* screenMemory = (TUint16*) screenInfo.iScreenAddress + 16;

for (int j = 80; j < 140; j++)
{
for (int i = 0; i < 176; i++)
{
*(screenMemory + 2*(16 + i + j*176)) = i/8 + j;
}
}

当绘制完成后,屏幕将会被更新,变化后的内容直接反映在屏幕上,
我们可以通过向系统队列增加一个重绘事件来完成TRawEvent::ERedraw(通过UserSvr::AddEvent()),
它将立刻更新屏幕,下列代码演示了如何处理:

TRawEvent redraw;
redraw.Set(TRawEvent::ERedraw);
UserSvr::AddEvent(redraw);

但TRawEvent::ERedraw是由主机系统生成的,如模拟器环境的WM_PAINT事件。
S60第二版中,屏幕更新可以通过增加系统队列完成,但第三版中却无法立刻展现系统队列中重绘指令的效果。
屏幕只能通过手机屏幕关于超出数据区域的通知事件才能更新。 所以通过UserSvr::ScreenInfo()来修改显示内存的方法在S60第三版后是不建议使用的。
作为一个解决方案,可以通过使用老的绘制方法强制屏幕更新,
通过使用CFbsScreenDevice的Update()方法来指明超出数据区域,这个代码示例如下:

CFbsScreenDevice* iMyScreenDev = CFbsScreenDevice::NewL(0 ,EColor64K); // the screennumber will be 0 if phone supports single screen where as the
// displaymode can be as per your choice
RRegion iMyregion;
iMyregion.AddRect(TRect(0,0,240,320)); // the out of date rect region.
iMyScreenDev->Update(iMyregion);
iMyregion.Close();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐