Если игра предполагает отображение на экране множества различных движущихся объектов, которые нужно часто обновлять, буфер клиентской части экрана может быть заполнен, прежде чем все объекты успеют обновиться. В результате пользователь увидит мерцание на экране телефона. Подобные нежелательные эффекты могут возникнуть и в случае, если вид, на формирование которого уходит много времени, рисуется прежде чем завершилось его обновление. Эти проблемы легко решаются с помощью двойной буферизации. Создается вспомогательный буфер, в который производится рисование. После того как сцена в полностью сформирована, его содержание переносится на экран. Использование двойной буферизации особенно актуально для игр.
Рассмотрим порядок использования внеэкранного буфера:
Ниже приведен пример:
void CMyGameView::ConstructL(const TRect& aRect) { . . . // Создаем новое изображение совпадающее // по размеру и цветовой палитре м экраном TDisplayMode displayMode= CEikonEnv::Static()-> ScreenDevice()->DisplayMode(); iBackBufferBitmap=new(ELeave) CFbsBitmap(); User::LeaveIfError(iBackBufferBitmap-> Create(Rect().Size(), displayMode)); // Создаем устройство изображения iBackBufferDevice= CFbsBitmapDevice::NewL(iBackBufferBitmap); // Создаем графический контекст для буферного изображения User::LeaveIfError(iBackBufferDevice.CreateContext( iBackBufferGc)); } CMyGameView::~CMyGameView() { delete iBackBufferGc; delete iBackBufferDevice; delete iBackBufferBitmap; } // Вызываем таймер для периодического обновления экрана // Все отображение производится во внеэкранный буфер. void CMyGameView::UpdateDisplay() { // Рисуем фон iBackBufferGc->BitBlt(TPoint(0,0), iMyBackgroundBitmap); // Рисуем еще что-нибудь . . . // После того как все что нужно перенесено в буфер, обновлякм Вид DrawDeferred(); } void CMyGameView::Draw(const TRect&/*aRect*/)const { CWindowGc& gc= SystemGc(); // Просто переносим содержание буфера в Вид gc.BitBlt(Rect().iTl, iBackBufferBitmap); }
Перевод:aRix