基于Nokia S60的游戏开发之三
发布时间:2006-10-14 3:13:13   收集提供:gaoqian

  Symbian OS可以被理解为一个面向位图的操作系统。Symbian OS中所有的应用程序都可以使用位图,尤其是游戏程序。虽然使用基本绘图方法(例如DrawLine和DrawEllipse)能够画出更加小型的图形,但是位图能够更有效地画屏,而且输出的图形更加细腻。

  Symbian OS有自己的位图文件格式MBM,这是一种多位图文件。 窗口位图使用一个位图转化工具bmconv来创建MBM。 由于一个MBM文件可能包含多个位图,所以bmconv还产生一个位图头文件MBG,这个头文件提供了一个访问位图的ID。当从MBM文件加载一张位图的时候,应该包括相应的头文件,同时应当使用恰当的标识符作为加载位图的方法的参数。 位图可以在项目文件中定义:

START BITMAP [target-file]
HEADER
TARGETPATH [targetpath]
SOURCEPATH [sourcepath]
SOURCE [colour-depth] [source-bitmap]
END 

  bmconv可以创建两种不同类型的Symbian OS位图:只读存储位图和非只读存储位图。非只读存储位图,亦称文件存储位图,使用编码RLE压缩,它们在使用之前需要被装载到RAM中。为了提高描画速度,一般不压缩只读存储位图,并且可以直接从ROM中使用它们。默认情况下是bmconv建立文件存储位图(即非只读存储位图)。

  Symbian OS提供对蒙版(mask)的支持。蒙版是黑白位图,白色描画透明区--只有蒙版中的黑色区域上的像素是从原始位图上根据想要的图形描画来的。因为蒙版只需要两种颜色,所以它们应该被转化为1bit的位图以节省存储空间。图1说明了使用蒙版的示例。

图1 使用蒙版来描画透明位图的示例

  Series 60提供了一个名为makemask的命令行工具,用来从8 bit位图中创建1 bit的蒙版。 makemask使用原位图中的最后一个调色板索引作为透明色。

  虽然Symbian OS提供了设置位图调色板的应用程序编程接口,但是这些接口并没有实现。一旦补充这些应用程序编程接口,系统就支持彩色显示。当添加支持的时候,Symbian OS判定只支持Netscape调色板色彩立方校正。 Series 60提供它自己的8 bit位图调色板。Bmvconv被修改来把8 bit位图转换为使用Series 60调色板(提供216种颜色和10种灰色调)。 这能防止第三方开发者使用它们自己的调色板,因为使用它们自己的调色板经常会对位图输出造成影响。 尤其是需要一种颜色的多种色调的位图,例如创建一个颜色渐变位图,至少应该转化为12位的位图。 Series 60调色板定义在thirdpartybitmap.pal调色板文件中。

  位图的管理由CFbsBitmap类来完成,这个类提供了用于创建和装载位图的方法,并且定义它们的色深度和尺寸。它使用RFbsSession类来访问FBS,因此用户是接触不到会话类的。 CFbsBitmap还提供了直接访问位图图像数据的方法。 可以使用DataAddress方法获得一个指向数据地址的指针,并且可以使用GetScanLine方法访问一条指定的扫描线。

  根据位图的尺寸把位图分解到FBS中的两个不同的堆里。小于4kB的位图被保存到一个堆里,大于4kB的位图保存到另一个堆里。进行这种分解是为了防止存储碎片,存储碎片是大的位图被创建和销毁的时候经常出现的--大位图的堆能自动整理碎片。由于碎片整理的原因,当操作大位图的内容时,堆需要被锁定。为了防止碎片整理和操作同步进行,TBitmapUtil类提供了锁定堆和解锁堆的操作。只有在一个位图的图像数据被直接编辑的时候才需要锁定堆--描画和复制方法提供了自动锁定功能。 下面的示例在位图是大的位图并且使用颜色填充位图的情况下锁定FBS。它假定位图的每个象素都使用16位。这适用于12位和16位位图。

// Lock the heap if a large bitmap
if ( bitmap->IsLargeBitmap() )
{
 TBitmapUtil bitmapUtil( bitmap );
 bitmapUtil.Begin( TPoint(0,0) );
}
// Edit bitmap
TSize bitmapSize = bitmap->SizeInPixels();
TUint16* bitmapData = (TUint16*)bitmap->DataAddress();
TUint16 colour = 0;
for ( TInt y = 0; y < bitmapSize.iHeight; y++ );
{
 for ( TInt x = 0; x < bitmapSize.iWidth; x++ )
 {
  *bitmapData++ = colour++;
 }
}
// Release the heap
if ( bitmap->IsLargeBitmap() )
{
 BitmapUtil.End();

  为了使描画位图比使用CfbsBitmaps还快,窗口服务器提供它自己的位图类CWsBitmap。它通过取得位图处理的所有权来除去窗口服务器和FBS之间多余的上下文转换。CWsBitmap从CFbsBitmap继承而来,并且实现了其所有相同的方法。如果你在开发应用程序的时候很重视描画速度,那么你应该使用CWsBitmap来替代它的基类。

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50