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

 [打印本页]

--------------------------------------------------------------------------------
作者: 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();

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值