首 页 | 新 闻 | Symbian | Android| Windows Mobile | J2ME | 下载中心 | 游戏策划招聘与求职 | 购书指南 | 视频教程
您现在的位置: 开发视界 >> 专家专栏 >> 剑走偏锋 >> 正文
Graphics(8)
作者:剑走偏锋    文章来源:本站原创    更新时间:2005-8-9 15:12:51
Graphics(8)

    Direct Draw.

    试用窗口服务在屏幕上Draw需要一个连接文件来转换,这样大大降低了速度.绕过窗口服务,丢弃连接文件的转换,让应用程序自己来直接存取屏幕,这就叫做Direct Draw.

    在Symbian系统中,有三种方法来实现Direct Draw:
    1.创建和试用CfbsScreenDevice
    2.直接读取屏幕内存
    3.试用CdirectScreenAccess

    CFbsScreenDevice是一个图形驱动,可以用来取屏幕设备的地址,SCDV.DLL.在为其创建一个CFbsBitGc的连接以后,他就可以象其他图形驱动一样被使用了.

    最快的访问屏幕的方法是直接存取屏幕设备的内存地址,直接通过一个指针对地址进行操作.示例代码:
以下内容为程序代码:
void CMyGameView::FillScreenDirectly() const

   {

   TPckgBuf infoPckg;

   TScreenInfoV01& screenInfo = infoPckg();

   UserSvr::ScreenInfo(infoPckg);

   TUint16* screenMemory = (TUint16*) screenInfo.iScreenAddress + 16;

 

   for(TInt y = 0; y < screenInfo.iScreenSize.iHeight; y++)

      {

      for(TInt x = 0; x < screenInfo.iScreenSize.iWidth; x++)

         {

            *screenMemory++ = 0;

         }

      }

   }

    屏幕的内存有32位字节头部,在直接写入内存的时候要注意.

    虽然直接写入内存比CFbsScreenDevice速度快很多,但是对于不同的Symbian OS终端,功能型缺不尽相同.有的Symbian OS终端在屏幕内存改写以后自动更新,有的则需要激活才可以.

    而且屏幕内存地址只是对于目标设备是有效的,因此,目标代码应该分成实际设备代码和模拟器代码.你可以试用一个临时的Bitmap在模拟器上面调试,在设备上面运行的时候则直接存取内存地址就可以了.示例代码:
以下内容为程序代码:
void CMyGameView::MyDrawing()

   {

   [img]http://images.blogcn.comf __WINS__

   // Draw to bitmap

   TUint16* myScreenPointer = iMyBitmap.DataAddress();

   [/img]else // Hardware environment

   // Draw directly to the screen memory

   TUint16* myScreenPointer = GetMyScreenAddress();

   [img]http://images.blogcn.comf

 

   DoMyDrawing(myScreenPointer);

}


    使用Direct Draw一个常见的问题是,因为他没有试用窗口服务,因此,如果其他窗口或者窗口组被提前,他不能够通知应用程序.即使应用程序在失去焦点的时候会获得一个事件,但是仍然不能停止快速的Direct Draw,而且屏幕很可能会变得很粗糙.例如,接到一个电话,电话应用程序被提前.

    Symbian OS提供了CDirectScreenAccess,即安全又快的方法来直接访问屏幕.当使用CDirectScreenAccess来控制与窗口服务的交互时,两个消息通过接口的回调被接收.
    1.MDirectScreenAccess::AbortNow在直接访问屏幕被停止时候被调用.例如,Dialog在屏幕上被取出.(出栈操作)
    2.MDirectScreenAccess::Restart在安全的前提下,继续进行对屏幕的直接访问.

    下面代码演示如何建立CDirectScreenAccess的一个实例,以及direct draw如何激活.
以下内容为程序代码:
// Inherited from MDirectScreenAccess

void CMyGameView::Restart(

   RDirectScreenAccess::TTerminationReasons aReason)

   {

   // Usually just restart direct screen accessing

   TRAPD(err, iMyDrawer->StartL());

   if(err != KErrNone) 

      {

         // Error; cannot restart

      }

   }

 

// Inherited from MDirectScreenAccess; called when it?s needed to 

// abort direct screen access immediately

void CMyGameView::AbortNow(

   RDirectScreenAccess::TTerminationReasons aReason)

   {

      // Stop direct screen access immediately

      // e.g. dialog has become visible on screen

   }

 

// Construct CDirectScreenAccess

void CHelloWorldBasicAppView::CreateMyDrawerL()

   {

   delete iMyDrawer;

   iMyDrawer = NULL;

   iMyDrawer = CDirectScreenAccess::NewL( iEikonEnv->WsSession(), 

      *iEikonEnv->ScreenDevice(), Window(), *this);

   iEikonEnv->WsSession().Flush();

   iMyDrawer->StartL();

   iMyDrawer->ScreenDevice()->SetAutoUpdate(ETrue);

   }

 

// Draw backbuffer bitmap to screen using CDirectScreenAccess

void CMyGameView:[img]/images/biggrin.gif[/img]isplayBackBuffer() const

   {

   iMyDrawer->Gc()->BitBlt( TPoint(0,0), iMyBackBuffer [img]/images/wink.gif[/img];

   }

    在CDirectScreenAccess::StartL被调用激活direct draw支持以前,客户端一面窗口服务缓冲区应该被溢出.为了可以自动更新屏幕,屏幕驱动程序的SetAutoUpdate方法需要随一个Etrue参数被调用.当direct draw支持被激活,CDirectScreenAccess创建一个CFbsBitGc的图片连接,且被应用程序用于在屏幕上输出.

    当另外一个窗口被放在应用程序窗口之上的时候,CDirectScreenAccess从窗口服务获得一个事件,并中断屏幕输出.CDirectScreenAccess然后调用MDirectScreenAccess,起源类--AbortNow方法,被应用程序反复停止图形输出.防止屏幕变粗糙,窗口服务停止显示重叠的窗口,直到中断图形输出的事件被处理完后.
相关文章:
Symbian屏幕双缓冲&&DSA
Using Theme in an Application
Making TimeLine Control
Symbian sdk帮助-术语表D
Symbian sdk帮助-术语表O
Symbian sdk帮助-术语表W
深入hellogui.app
控制与复合控制
 

站点地图 | 加入收藏 | 联系站长 | 广告服务 |
QQ:280529124  Tel:0592-8271361 辽ICP备05021703号