Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ИГС / 5_i_poslednyaya / glopen10 / Labor_07.doc
Скачиваний:
24
Добавлен:
29.05.2018
Размер:
416.26 Кб
Скачать

Двойная буферизация.

Способ вывода изображения на экран, рассмотренный выше, называется двойной буферизацией (double buffering). Двойная буферизация позволяет убрать мерцание экрана в программах, моделирующих движение (анимацию) графических объектов.

Напомним, что в современных видеоадаптерах информация об изображении храниться в виде двухмерных массивов пикселей в области памяти видеоадаптера, в видеопамяти. Такая область называется кадровым буфером (frame buffer), или буфером кадра.

Каждый пиксель буфера кадра считывается с помощью цифро-аналогового преобразователя, и полученный сигнал подается на три электронные пушки. Далее, электронные пушки создают на экране изображение, соответствующее той информации, которая хранится в буфере кадра.

Сформированное на экране изображение остается видимым в течение очень короткого времени. Это время определяется качеством люминофоров, покрывающих экран, и не превышает нескольких миллисекунд. Поэтому изображение должно обновляться на экране с частотой не меньшей 50 Гц. Такое обновление называется регенерацией изображения.

В программе glopen03.cpp буферу кадра соответствует контекст окна hdcWin.

//получаем контекст окна

HDC hdcWin = GetDC(hwnd);

Когда программа рисует графический объект в контексте окна hdcWin, то одновременно информация о нем заносится в буфер кадра, и изображение объекта тут же появляется на экране.

Поэтому, если для анимации использовать только один буфер кадра, то перед пользователем на экране будет происходить как удаление предыдущего изображения, так и появление нового изображения. Это приводит к мерцанию движущегося объекта.

Для удаления эффекта мерцания в программе используется два буфера кадра. Первый буфер кадра находится в видеопамяти видеоадаптера, и называется передним буфером (front buffer). С этим буфером кадра связан контекст окна hdcWin.

Роль второго буфера кадра выполняет битовая карта hBitmap, которая располагается в операционной памяти. Этот буфер кадра называется задним буфером (back buffer).

//создаем битовую карту совместимую с контекстом окна

HBITMAP hBitmap = CreateCompatibleBitmap(hdcWin, .., ..);

С задним буфером кадра связан контекст памяти hdcMem.

//создаем контекст памяти связанный с контекстом окна

HDC hdcMem = CreateCompatibleDC(hdcWin);

//помещаем битовую карту в контекст памяти

HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMem, hBitmap);

Метод двойной буферизации сводится к следующему. Предыдущее изображение находится в переднем буфере кадра и с частотой 50 Гц обновляется на экране. С точки зрения программирования старое изображение находится в контексте окна hdcWin.

Пока старое изображение находится в переднем буфере кадра, новое изображение рисуется в заднем буфере кадра. С точки зрения программирования новое изображение рисуется на битовой плоскости в контексте памяти hdcMem.

Когда новое изображение будет полностью сформировано в заднем буфере кадра, оно практически мгновенно будет скопировано в передний буфер кадра, и тут же появится на экране. С точки зрения программирования копирование заднего буфера кадра в передний буфер кадра, означает копирование контекста памяти hdcMem в контекст окна hdcWin. Копирование осуществляется с помощью функции BitBlt().

//копируем контекст памяти в контекст окна

BitBlt(hdcWin, .., .., .., .., hdcMem, .., .., ..);

Далее процесс повторяется. Из-за того, что процесс копирования более быстрый, чем процесс рисования, эффект мерцания удается устранить.

Процесс копирования заднего буфера кадра в передний можно было бы ускорить, если бы задний буфер кадра располагался в видеопамяти видеоадаптера. Современные видеоадаптеры обладают такой возможностью, они могут работать в режиме двойной буферизации.

К сожалению, стандартные функции API не могут напрямую обращаться к заднему буферу кадра видеоадаптера. Единственное что они могут, это обращаться к переднему буферу кадра через контекст окна. Поэтому при программировании графики с помощью API-функций приходится в качестве заднего буфера кадра использовать область оперативной памяти в виде битовой карты контекста памяти.

Однако, функции графического пакета OpenGL могут работать в режиме двойной буферизации, напрямую обращаясь к буферам кадра видеоадаптера. Поэтому 3D графика OpenGL является очень быстрой. Правда, надо заметить, что быстрота рисования в OpenGL связана во многом с тем, что большинство операций функций OpenGL выполняются на аппаратном уровне с помощью графических процессоров и ускорителей.