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

Двойная буферизация 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 ); //модель закрашивания - однородное закрашивание