
- •Московский институт электронной техники
- •Введение.
- •Подключение графической библиотеки OpenGl в программах Win32.
- •Создание консольного приложения Windows для работы с библиотекой OpenGl.
- •Интерактивное взаимодействие с OpenGl в оконном режиме Windows.
- •Двойная буферизация.
- •Двойная буферизация OpenGl в оконном приложении Windows.
- •Двойная буферизация OpenGl в консольном приложении Windows.
- •Создание 2d объектов с помощью графической библиотеки OpenGl.
- •Пример создания 3d объектов с помощью графической библиотеки OpenGl.
- •Использование таймера для моделирования движения 3d-объектов OpenGl в оконном приложении Windows.
- •Моделирование движения 3d-объектов OpenGl без таймера в консольном приложении Windows.
- •Задание к работе.
- •Варианты к лабораторной работе.
Двойная буферизация.
Способ вывода изображения на экран, рассмотренный выше, называется двойной буферизацией (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выполняются на аппаратном уровне с помощью графических процессоров и ускорителей.