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

Двойная буферизация OpenGl в оконном приложении Windows.

Изменим программу glopen03.cppубрав в ней графику созданнуюAPI-функциями, и оставим графику созданнуюOpenGL. Кроме того, будем использовать двойную буферизацию, предоставляемую видеоадаптером, поэтому уберем из программы контекст памяти.

Новую программу назовем glopen04.cpp. В определении формата пикселя уберем флагPFD_DRAW_TO_BITMAPи заменим его на флагPFD_DOUBLEBUFFER.

pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL;

Далее функцию glFinish()заменим на функцию SwapBuffers(hdcWin), которая переключает буферы кадра, делая задний буфер передним и наоборот.

//переключает буферы кадра видеоадаптера

SwapBuffers(hdcWin);

Результат работы программы glopen04.cppпоказан на Рис.5.

Рис.5.

Интерактивная графика OpenGLс двойной буферизацией. Оконное приложениеWindows.

(Изображение на Рис.5 создано программой glopen04.cpp.)

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

Контекст устройства hdcWin, связанный с окном приложения, позволяет рисовать только в границах клиентской части окна. Выше этот контекст назывался контекстом окна. С контекстом окна hdcWinв программе связан контекст отображенияhglrcбиблиотекиOpenGL. Это позволяет рисовать в клиентской части окна графические объекты с помощью функций библиотекиOpenGL.

Двойная буферизация OpenGl в консольном приложении Windows.

Двойную буферизацию OpenGLможно использовать так же и в консольном приложении. Поместим код новой программы в файлglopen05.cpp. Возьмем за основу программы glopen02.cppиglopen04.cpp.

Вращать нарисованные 3D-объекты будем с помощью мышки и стрелок клавиатуры. Соответствующие сообщения будут обрабатывать функции библиотекиGLAUX. Поэтому эту библиотеку надо подключить к программе.

Ниже приведен код главной функции main().

void main()

{

// расположение окна OpenGL на экране

auxInitPosition(100, 50, 600, 450);

// установка основных параметров работы OpenGL

// цветовой режим RGB | включение Z-буфера для сортировки по глубине

//| двойная буферизация

auxInitDisplayMode( AUX_RGB | AUX_DEPTH | AUX_DOUBLE);

// инициализация окна OpenGL с заголовком

auxInitWindow("Console Application "

" rotation by mouse and keyboard (arrows) ");

auxMouseFunc(AUX_LEFTBUTTON, AUX_MOUSEDOWN,

(AUXMOUSEPROC)mouse_left_down);

auxMouseFunc(AUX_LEFTBUTTON, AUX_MOUSELOC,

(AUXMOUSEPROC)mouse_left_loc);

auxMouseFunc(AUX_LEFTBUTTON, AUX_MOUSEUP,

(AUXMOUSEPROC)mouse_left_up);

auxKeyFunc(AUX_DOWN, (AUXKEYPROC)Key_DOWN);

auxKeyFunc(AUX_LEFT, (AUXKEYPROC)Key_LEFT);

auxKeyFunc(AUX_RIGHT, (AUXKEYPROC)Key_RIGHT);

auxKeyFunc(AUX_UP, (AUXKEYPROC)Key_UP);

// регистрация функции, которая вызывается при перерисовке

// и запуск цикла обработки событий

// Draw() - функция пользователя

auxMainLoop((AUXMAINPROC)Draw);

}

Здесь обратим внимание на следующие особенности кода.

В функции auxInitDisplayMode(), устанавливающей режим работы появились новые флагиAUX_DEPTH ,AUX_DOUBLE, означающие, что используется механизмz-буфера для сортировки по глубине, и механизм двойной буферизации.

Далее, сообщение, приходящее при нажатии левой клавиши мышки будет обрабатывать функция mouse_left_down. Сообщение, приходящее при отпускании левой клавиши мышки будет обрабатывать функцияmouse_left_up. Сообщение, приходящее при нажатии левой клавиши и одновременном движении мышки будет обрабатывать функцияmouse_left_loc.

Затем, сообщение, приходящее при нажатии клавиши «стрелка налево», будет обрабатывать функция Key_LEFT. Сообщение, приходящее при нажатии клавиши «стрелка направо», будет обрабатывать функцияKey_RIGHT. Сообщение, приходящее при нажатии клавиши «стрелка вниз», будет обрабатывать функцияKey_DOWN. Сообщение, приходящее при нажатии клавиши «стрелка вверх», будет обрабатывать функцияKey_UP.

И, наконец, функцией объединяющей все функции рисования, будет функция Draw.

Отметим некоторые особенности кода функции Draw. Кроме шахматного поля и координатных осей в сцене присутствует волнистая поверхность голубого оттенка. Сплошной вариант этой поверхности создается следующим фрагментом кода:

glBegin(GL_TRIANGLE_STRIP);

for( i=0; i<N*2; i++)

glVertex3fv(vert[i]);

glEnd();

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

glBegin(GL_LINE_STRIP);

for( i=0; i<N*2; i++)

glVertex3fv(vert[i]);

glEnd();

Для того чтобы переключать задний и передний буферы кадра видеоадаптера в режиме двойной буферизации, надо в функцию Drawдобавить следующий фрагмент кода:

//переключаем буферы в режиме двойной буферизации

auxSwapBuffers();

Результат работы программы glopen05.cppпоказан на Рис.6 и Рис.7.

Рис.6.

Интерактивная графика OpenGLс двойной буферизацией. Консольное приложениеWindows. Сплошная закраска поверхности.

Рис.7.

Интерактивная графика OpenGLс двойной буферизацией. Консольное приложениеWindows. Полигональная модель поверхности.

(Изображения на Рис.6,7 созданы программой glopen05.cpp.)

На Рис. 6 показана поверхность, закрашенная методом Гуро. На Рис. 7 показана полигональная модель той же поверхности.

Для включения способа окраски методом Гуро используется функция glShadeModelсо следующим аргументомGL_SMOOTH:

glShadeModel(GL_SMOOTH ); //модель закрашивания - модель Гуро

Для включения однородной закраски используется другой аргумент GL_FLATэтой же функции:

glShadeModel(GL_FLAT ); //модель закрашивания - однородное закрашивание

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