Graphics example 1 关于本例子(Abou this example) 本例子演示了两个画位图到屏幕的函数。通常,任何位图都可以使用窗口服务 (Window Server)直接拷贝位图显示到屏幕。这些操作使用任何应用程序都 能访问到的CWindowGC 类。该类拥有很多操作位图的有效的函数,诸如BitBlt() 和BitBltMasked()。
使用窗口服务直接操作位图这个方法会出现如下问题: --一些位图的建立(加载)需要很长一段时间。显示图像可能不整齐,对用户造成混乱。 --如果很多正在移动的对象画到屏幕,屏幕会闪烁。在所有的对象都画到屏幕之前, 窗口服务变得泛滥就会发生闪烁。(get flushed 不知道怎么解释)
要解决这些问题,可以使用“off-screen bitmap”(离屏位图),这个位图和真实的显示 屏幕尺寸相同。替代使用窗口服务直接画图到屏幕的方法,他们(图像)被画到离屏 位图。一旦所有图像画完,窗口服务拷贝已经被修改过的离屏位图到屏幕。因此,所 有的图像都被一次性操作写到屏幕,因此也完全消除闪烁。本例子演示使用了这两种 方法实现了几个精灵的动画。
下面部分解释了在画图中,颜色深度和掩模的重要性。
1.1 颜色深度(Colour Depth) 颜色深度参考为每一个像素存储颜色信息的位数。当需要快速的显示图片效果 的时候,对一张图片使用正确的颜色深度是非常重要的。如果图片使用的颜色深度 和显示屏幕的颜色深度不同,图像在画之前必须转换成和显示屏幕一样的颜色深度。 这个转换降低了画图处理过程速度。图片通常以压缩格式存储在MBM文件中。MBM 文件使用Symbian OS 中bmconv工具生成。当运行这个工具压缩位图的时候,需要 为每一张位图指定颜色深度。通常应该把颜色深度设置成12bit色,这个和显示屏幕 的颜色深度相同;因此,当显示图片的时候,不需要转换。
1.2 淡化(Masking) 淡化通常被使用于选择要画位图的某部分,通过使用窗口服务BitBltMasked函数。如 果掩模中的像素是黑色,相应的像素就从位图中拷贝;如果掩模中的像素是白色,那 么相应的像素就不从位图拷贝。这种方法用来显示像素所在的背景是非常有效率的。 本例子使用掩模画圆到屏幕。没有掩模,这个圆将出现在一个白色的巨型区域中,当 图像闪动移过屏幕的时候。注意的是掩模没有被拷贝到屏幕,只是简单的用来判断 哪个像素需要拷贝到屏幕。因此,为了减少内存需求,掩模应该使用2bit的颜色深度 ,而不是12bit颜色深度。
2 预先要求(Pre-requisites) 本例子使用标准的Symbian OS应用程序框架,由应用程序类,文档类,用户界面类, 视图类组成。要理解这个例子读者首先应该知道这个架构。
本例子使用了一些其它的Symbian OS概念,读者也应该事先知道。概念如下: --窗口服务(windows server) --图形上下文(graphics context) --位图(bitmaps) --定时器时钟(Timers)
3 在模拟器上编译运行 本例子程序在D:\Symbian\6.1\Series60\Series60Ex\graphics
4 设计和实现 本例子逻辑都包含在CGraphicsAppView类中。这个类控制图像在屏幕上的显示。
在接下来的章节中,将要描述以下内容: --CGraphicsAppView对象的构造 --使用periodic周期性时钟运行periodic周期性事件 --直接画所有图像到屏幕 --间接画一些图像到屏幕 --标准的屏幕重画
本例子页使用了一些“helper functions”辅助功能(函数)。这些函数完成简单的任务,诸如 创建一个位图。因为这些函数对很多应用程序都是很有用的,所以他们被移动到他们自己的 名称空间。任何需要使用它们的程序,都不需要重新实现它们。这些有用的函数在helper functions 文档都有讨论。
4.1 构造 CGraphicsAppView 类加载所有需要的位图,创建设备和位图需要的设备上下文,包含一个 用来支持动画的时钟和初始化精灵sprite对象(三个滚动的球)。
消息描述 --CGraphicsAppView 实例化 --为每一个位图调用CreateBitmapL,从磁盘加载位图。这些位图文件包括background ,ball ,ball mask --调用CreateBitmapL创建一个离屏位图。 --调用CreateBitmapDeviceL创建位图图形设备,该设备用来完成在内存中位图的画图。 --调用CreateGraphicsContextL创建位图图形设备上下文,用来把位图画到屏幕。 --调用CPeriodic::NewL 实例化一个时钟对象。这个时钟用来周期性更新屏幕。 --调用SetUpSpritest初始化三个sprite对象
4.2 动画 当用户开启一个动画类型的时候,CGraphicsAppView对象打开CPeriodic时钟。一旦运行, 就周期性的调用Period周期性的函数。这将更新精灵的位置,并且直接更新到屏幕。这种 周期性的中断会持续到用户停止该时钟。动画使用Activate,Deactivate管理它自己的上下文, 而不是使用DrawNow函数。这样做是因为DrawNow函数将重画屏幕事件不能在真实地时间 被预先通知。
4.2.1 屏幕画图 UpdateDisplay函数根据画屏幕类型完成不同的动作。当不使用离屏位图时,所有的位图直接 写到屏幕。如果非常多的图像需要画到屏幕的时候,这将导致闪烁。
4.2.2 使用离屏位图画图 当使用离屏位图时,所有的图像都被画到离屏位图。一旦所有的图像都在离屏位图画好,该位 图被直接拷贝到屏幕。这就避免了闪烁,就算是很多对象在屏幕上画看起来也是非常的平滑。
4.3 标准的重画(Standard re-drawing) 偶尔的,动画屏幕可能被其他的窗口或者对话框覆盖。当这些窗口或者对话框清除的时候, 动画屏幕需要被重画。为了重画请求,框架自动调用Draw函数,该函数需要应用程序视图 实现。在这里,Draw函数仅仅简单使用了标准的和周期性时钟调用相同的UpdateDisplay函数。
5 总结(Summary) 本例子显示了: --如何使用窗口服务画屏幕 --有效使用离屏位图避免闪烁,并且平滑的更新屏幕。 --如何通过周期性的时钟建立图像 --在应用程序中如何使用多种颜色深度位图
|
|
|
| |