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