Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ИГС / IGS_2014-2015 / Lab_04 / labor_04.doc
Скачиваний:
22
Добавлен:
17.04.2018
Размер:
303.62 Кб
Скачать

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

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

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

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

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

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

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

HDC hdcWin = GetDC(hwnd);

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

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

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

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

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

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выполняются на аппаратном уровне с помощью графических процессоров и ускорителей.

Соседние файлы в папке Lab_04