- •Московский институт электронной техники
- •Введение.
- •Подключение графической библиотеки OpenGl в программах Win32.
- •Создание консольного приложения Windows для работы с библиотекой OpenGl.
- •Интерактивное взаимодействие с OpenGl в оконном режиме Windows.
- •Двойная буферизация.
- •Двойная буферизация OpenGl в оконном приложении Windows.
- •Двойная буферизация OpenGl в консольном приложении Windows.
- •Создание 2d объектов с помощью графической библиотеки OpenGl.
- •Пример создания 3d объектов с помощью графической библиотеки OpenGl.
- •Использование таймера для моделирования движения 3d-объектов OpenGl в оконном приложении Windows.
- •Моделирование движения 3d-объектов OpenGl без таймера в консольном приложении Windows.
- •Задание к работе.
- •Варианты к лабораторной работе.
Интерактивное взаимодействие с OpenGl в оконном режиме Windows.
Использование мыши и клавиатуры для движения 3D-графических объектов, созданныхOpenGL, аналогично случаю, когда 3D-объекты создаются с помощьюAPI-функций. Основным моментом здесь является рисование в контексте памяти. Рассмотрим применение мыши и клавиатуры на примере программыglopen03.cpp.
В этой программе одновременно используется как библиотека OpenGL, так и графические функцииGDIсистемыWindows. Контекст отображения (renderingcontext) библиотекиOpenGLсвязывается с контекстом памяти. При выборе подходящего формата пикселя надо обратить внимание на одну особенность. Подходящий формат пикселя ищется сначала в контексте окна. А затем, найденный формат пикселя устанавливается в контексте памяти.
Ниже показан соответствующий код программы.
//получаем контекст окна
HDC hdcWin = GetDC(hwnd);
//создаем контекст памяти связанный с контекстом окна
HDC hdcMem = CreateCompatibleDC(hdcWin);
//создаем битовую карту совместимую с контекстом окна
HBITMAP hBitmap = CreateCompatibleBitmap(hdcWin, ne2, me1);
//помещаем битовую карту в контекст памяти
HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMem, hBitmap);
//структура описания формата пикселя
PIXELFORMATDESCRIPTOR pfd;
//зануляем все поля структуры pfd
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
//заполняем некоторые поля структуры
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP |
PFD_SUPPORT_OPENGL;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 32;
//выбираем наиболее подходящий формат пикселей в контексте окна
int iPixelFormat = ChoosePixelFormat(hdcWin, &pfd);
//устанавливаем найденный формат пикселей в контексте памяти
SetPixelFormat(hdcMem, iPixelFormat, &pfd);
//получаем контекст отображения OpenGL
HGLRC hglrc = wglCreateContext(hdcMem);
//устанавливаем текущий контекст отображения OpenGL
wglMakeCurrent(hdcMem, hglrc);
Обратим внимание еще на одну особенность приведенного выше кода. В поле pfd.dwFlagsструктурыpfdдобавлен флагPFD_DRAW_TO_BITMAP, чтобыOpenGLмогла рисовать в битовой карте контекста памяти.
После того как функции библиотеки OpenGLнарисуют в контексте памяти 3G-объекты, освобождается контекст отображенияOpenGL.
//завершаем работу с текущим контекстом отображения
wglMakeCurrent(NULL, NULL);
//освобождаем контекст отображения OpenGL
wglDeleteContext(hglrc);
После этого начинают рисовать API-функции системыWindows, в битовой карте контекста памяти. Новые графические объекты рисуются поверх графических объектов, нарисованныхOpenGL, потому что иOpenGLиAPI-функции рисуют на одной и той же битовой карте.
После завершения процесса рисования, графические объекты, нарисованные на битовой карте, выбрасываются на экран с помощью функции BitBlt().
//копируем контекст памяти в контекст окна
BitBlt(hdcWin,ne1,me2-30,ne2,me1,hdcMem,ne1,me2-30,SRCCOPY);
Затем освобождаются контексты памяти и окна.
DeleteDC(hdcMem); // освобождаем контекст памяти
//освобождаем контекст окна
ReleaseDC(hwnd, hdcWin);
Чтобы заставить графические объекты вращаться при движении мышки или нажатии стрелок на клавиатуре используется следующий прием. Движение мышки или нажатие клавиши связывается с изменением углов, определяющих положение графических объектов в пространстве. Затем эти новые углы передаются графическим функциям для рисования объектов в новом положении.
Ниже приводится код для функций OpenGL, описывающий поворот вокруг двух осей на заданные углыangl.teta,angl.fi.
//умножение текущей матрицы на матрицу поворота
glRotatef(90-(GLfloat)angl.teta, 1, 0, 0);
glRotatef(-(GLfloat)angl.fi, 0, 1, 0);
Результат работы программы glopen03.cppпоказан на Рис.4.
Рис.4. Изображение создано с помощью OpenGLи функцийGDIв контексте памяти. |
(Изображение на Рис.4 создано программой glopen03.cpp.)