双缓冲技术
代码:
void CMyView::Draw(const TRect& aRect) const
{
CWindowGc& gc = SystemGc();
TRect rect = Rect();
gc.Clear(rect);
for (int i=0; i<100; i+=2) {
gc.DrawRect(TRect(TPoint(i,i), TSize(50,50)));
}
}
怎么会这样呢?很简单,直接往屏幕上画图的速度是很慢的。这个问题在制作动画的时候尤其明显,因为我们可能要在一秒中之内刷新屏幕几十次。如果按每秒二十五屏的速度来刷新的话,就意味着我们要在一秒中之内画一千多个小方块!
Profx通过中央电脑查到古时候有一种叫做Double Buffering的办法可以解决这个问题。其实很简单:
一、在内存里生成一个和屏幕同样大小的buffer
二、在内存里(Off-screen Buffer)画图
三、把Off-screen Buffer画到屏幕上
这样做的好处有二:
一、写内存远比写屏(IO)快多了
二、无论所画图形有多复杂,我们只需要做一次IO操作!
下面我们来看看具体做法:
一、在你的mmp文件里加这么几行:
代码:
LIBRARY fbscli.lib
LIBRARY bitgdi.lib
二、假设你的View class叫做CMyView。在MyView.h里加入:
代码:
#include
...
private:
CFbsBitmap* iOffScrnBmp;
CFbsBitmapDevice* iOffScrnBmpDevice;
CFbsBitGc* iOffScrnContext;
三、在MyView.cpp里加入:
代码:
void CMyView::ConstructL(const TRect& aRect)
{
...
iOffScrnBmp = new (ELeave) CFbsBitmap;
User::LeaveIfError(iOffScrnBmp->Create(Size(), EColor4K));
iOffScrnBmpDevice = CFbsBitmapDevice::NewL(iOffScrnBmp);
User::LeaveIfError(iOffScrnBmpDevice->CreateContext(iOffScrnContext));
}
说明一下。上面的代码除了生成了我们所需的Off-screen Buffer,即一个4096色的CFbsBitmap之外,还在它上面加了一个iOffScrnContext。这个东西(CFbsBitGc)是我们用来往我们的buffer上面画图用的工具。
继续:
代码:
CMyView::~CMyView()
{
delete iOffScrnBmp;
delete iOffScrnBmpDevice;
delete iOffScrnContext;
}
void CMyView::Draw(const TRect& aRect) const
{
// 把我们的buffer清空
iOffScrnContext->Clear(Rect());
// 在buffer里画方块,而不是在屏幕上
for (int i=0; i<100; i+=2) {
iOffScrnContext->DrawRect(TRect(TPoint(i,i), TSize(50,50)));
}
// 一次性把buffer画到屏幕上
CWindowGc& gc = SystemGc();
gc.BitBlt(TPoint(0,0), iOffScrnBmp);
void CMyView::Draw(const TRect& aRect) const
{
CWindowGc& gc = SystemGc();
TRect rect = Rect();
gc.Clear(rect);
for (int i=0; i<100; i+=2) {
gc.DrawRect(TRect(TPoint(i,i), TSize(50,50)));
}
}
怎么会这样呢?很简单,直接往屏幕上画图的速度是很慢的。这个问题在制作动画的时候尤其明显,因为我们可能要在一秒中之内刷新屏幕几十次。如果按每秒二十五屏的速度来刷新的话,就意味着我们要在一秒中之内画一千多个小方块!
Profx通过中央电脑查到古时候有一种叫做Double Buffering的办法可以解决这个问题。其实很简单:
一、在内存里生成一个和屏幕同样大小的buffer
二、在内存里(Off-screen Buffer)画图
三、把Off-screen Buffer画到屏幕上
这样做的好处有二:
一、写内存远比写屏(IO)快多了
二、无论所画图形有多复杂,我们只需要做一次IO操作!
下面我们来看看具体做法:
一、在你的mmp文件里加这么几行:
代码:
LIBRARY fbscli.lib
LIBRARY bitgdi.lib
二、假设你的View class叫做CMyView。在MyView.h里加入:
代码:
#include
...
private:
CFbsBitmap* iOffScrnBmp;
CFbsBitmapDevice* iOffScrnBmpDevice;
CFbsBitGc* iOffScrnContext;
三、在MyView.cpp里加入:
代码:
void CMyView::ConstructL(const TRect& aRect)
{
...
iOffScrnBmp = new (ELeave) CFbsBitmap;
User::LeaveIfError(iOffScrnBmp->Create(Size(), EColor4K));
iOffScrnBmpDevice = CFbsBitmapDevice::NewL(iOffScrnBmp);
User::LeaveIfError(iOffScrnBmpDevice->CreateContext(iOffScrnContext));
}
说明一下。上面的代码除了生成了我们所需的Off-screen Buffer,即一个4096色的CFbsBitmap之外,还在它上面加了一个iOffScrnContext。这个东西(CFbsBitGc)是我们用来往我们的buffer上面画图用的工具。
继续:
代码:
CMyView::~CMyView()
{
delete iOffScrnBmp;
delete iOffScrnBmpDevice;
delete iOffScrnContext;
}
void CMyView::Draw(const TRect& aRect) const
{
// 把我们的buffer清空
iOffScrnContext->Clear(Rect());
// 在buffer里画方块,而不是在屏幕上
for (int i=0; i<100; i+=2) {
iOffScrnContext->DrawRect(TRect(TPoint(i,i), TSize(50,50)));
}
// 一次性把buffer画到屏幕上
CWindowGc& gc = SystemGc();
gc.BitBlt(TPoint(0,0), iOffScrnBmp);