2633
.pdfgluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,10
0.0f);
glMatrixMode(GL_MODELVIEW);
Выбор матрицы вида модели
glLoadIdentity();
Сброс матрицы вида модели
}
int InitGL(GLvoid)
Все установки касаемо OpenGL происходят здесь
{
if (!LoadGLTextures())
Переход на процедуру загрузки текстуры
{
return FALSE;
Если текстура не загружена возвращаем FALSE
}
glEnable(GL_TEXTURE_2D);
Разрешение наложение текстуры
glShadeModel(GL_SMOOTH);
Разрешить плавное цветовое сглаживание
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
Очистка экрана в черный цвет
glClearDepth(1.0f);
Разрешить очистку буфера глубины
glEnable(GL_DEPTH_TEST);
Разрешить тест глубины glDepthFunc(GL_LEQUAL);
Тип теста глубины
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
Улучшение в вычислении перспективы
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
Установка Фонового Света
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
Установка Диффузного Света
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);
Позициясвета
glEnable(GL_LIGHT1);
Разрешение источника света номер один
173
quadratic=gluNewQuadric();
Создаем указатель на квадратичный объект
gluQuadricNormals(quadratic, GLU_SMOOTH);
Создаем плавные нормали
gluQuadricTexture(quadratic, GL_TRUE);
Создаем координаты текстуры ( НОВОЕ )
return TRUE;
Инициализация прошла успешно
}
int DrawGLScene(GLvoid)
Здесь мы все рисуем
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Здесь мы все рисуем
glLoadIdentity();
Сбрасываем вид
glTranslatef(0.0f,0.0f,z);
Перемещаемся в глубь экрана
glRotatef(xrot,1.0f,0.0f,0.0f);
Вращение по оси X glRotatef(yrot,0.0f,1.0f,0.0f);
Вращение по оси
glBindTexture(GL_TEXTURE_2D,texture[filter]);
Выбираем фильтрацию текстуре
glTranslatef(0.0f,0.0f,1.5f);
Рисуем центр цилиндра
gluCylinder(quadratic,0.5f,0.9f,3.0f,32,32);
Рисуем цилиндр
gluDisk(quadratic,0.0f,0.5f,32,32);
Рисуем дно xrot+=xspeed; yrot+=yspeed; return TRUE;
Продолжаем
}
GLvoid KillGLWindow(GLvoid)
Корректное разрушение окна
174
{
gluDeleteQuadric(quadratic); if (fullscreen)
Мы в полноэкранном режиме?
{
ChangeDisplaySettings(NULL,0);
Если да, то переключаемся обратно в оконный режим
ShowCursor(TRUE);
Показать курсор мышки
}
if (hRC)
Существует ли Контекст Рендеринга?
{
if (!wglMakeCurrent(NULL,NULL))
Возможно ли освободить RC и DC?
{
MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC))
Возможно ли удалить RC?
{
MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
hRC=NULL;
Установить RC в NULL
}
if (hDC&&!ReleaseDC(hWnd,hDC))
Возможно ли уничтожить DC?
{
MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hDC=NULL;
Установить DC в NULL
}
if (hWnd&&!DestroyWindow(hWnd))
Возможно ли уничтожить окно?
{
MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hWnd=NULL;
Установить hWnd в NULL
}
if (!UnregisterClass("OpenGL",hInstance))
175
Возможно ли разрегистрировать класс
{
MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hInstance=NULL; Установить hInstance в NULL
}
}
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat;
Хранит результат после поиска
WNDCLASS wc;
Структура класса окна
DWORD |
dwExStyle; |
Расширенный стиль окна |
|
DWORD |
dwStyle; |
Обычный стиль окна |
|
RECT |
WindowRect; |
Grabs Rectangle Upper Left / Lower Right Values
WindowRect.left=(long)0;
Установить левую составляющую в 0
WindowRect.right=(long)width;
Установить правую составляющую в Width WindowRect.top=(long)0;
Установить верхнюю составляющую в 0
WindowRect.bottom=(long)height;
Установить нижнюю составляющую в Height
fullscreen=fullscreenflag;
Устанавливаем значение глобальной переменной fullscreen
hInstance |
= GetModuleHandle(NULL); |
Считаем дескриптор нашего приложения |
|
wc.style |
= CS_HREDRAW | CS_VREDRAW | CS_OWNDC; |
Перерисуем при перемещении и создаём скрытый DC |
|
wc.lpfnWndProc |
= (WNDPROC) WndProc; |
Процедура обработки сообщений |
|
wc.cbClsExtra |
= 0; |
Нет дополнительной информации для окна
176
wc.cbWndExtra |
= 0; |
Нет дополнительной информации для окна |
|
wc.hInstance |
= hInstance; |
Устанавливаем дескриптор |
|
wc.hIcon |
= LoadIcon(NULL, IDI_WINLOGO); |
Загружаем иконку по умолчанию |
|
wc.hCursor |
= LoadCursor(NULL, IDC_ARROW); |
Загружаем указатель мышки |
|
wc.hbrBackground |
= NULL; |
Фон не требуется для GL |
|
wc.lpszMenuName |
= NULL; |
Меню в окне не будет |
|
wc.lpszClassName |
= "OpenGL"; |
Устанавливаем имя классу
if (!RegisterClass(&wc))
Пытаемся зарегистрировать класс окна
{
MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
Выход и возвращение функцией значения false
}
if (fullscreen)
Полноэкранный режим?
{
DEVMODE dmScreenSettings;
Режим устройства
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
Очистка для хранения установок dmScreenSettings.dmSize=sizeof(dmScreenSettings);
Размер структуры Devmode dmScreenSettings.dmPelsWidth = width;
Ширина экрана
dmScreenSettings.dmPelsHeight = height;
Высотаэкрана
dmScreenSettings.dmBitsPerPel = bits;
Глубина цвета
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PEL SHEIGHT;
Режим Пикселя
177
Пытаемся установить выбранный режим и получить результат. Примечание: CDS_FULLSCREEN убирает панель управления.
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=D ISP_CHANGE_SUCCESSFUL)
{
Если переключение в полноэкранный режим невозможно, будет предложено два варианта: оконный режим или выход.
if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","Приер GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
fullscreen=FALSE; Выбороконногорежима
(fullscreen = false)
}
else
{
Выскакивающее окно, сообщающее пользователю о закрытие окна.
MessageBox(NULL,"Program Will Now
Close.","ERROR",MB_OK|MB_ICONSTOP); return FALSE;
Выход и возвращение функцией false
}
}
}
if (fullscreen)
Мы остались в полноэкранном режиме?
{
dwExStyle=WS_EX_APPWINDOW;
Расширенный стиль окна
dwStyle=WS_POPUP;
Обычный стиль окна
ShowCursor(FALSE);
Скрыть указатель мышки
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
Расширенный стиль окна
178
dwStyle=WS_OVERLAPPEDWINDOW;
Обычный стиль окна
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
Подбирает окну подходящие размеры
Создаём окно
if (!(hWnd=CreateWindowEx( dwExStyle, // Расширенный стиль для окна
"OpenGL"
Имя класса title,
Заголовок окна
dwStyle |
Выбираемые стили для окна
WS_CLIPSIBLINGS | /
Требуемый стиль для окна
WS_CLIPCHILDREN,
Требуемый стиль для окна
0, 0,
Позиция окна
WindowRect.rightWindowRect.left,
Вычисление подходящей ширины
WindowRect.bottomWindowRect.top,
Вычисление подходящей высоты
NULL,
Нет родительского
NULL,
Нет меню
hInstance,
Дескриптор приложения
NULL)))
Не передаём ничего до WM_CREATE (???)
{
KillGLWindow();
Восстановитьэкран
MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
179
Вернуть false
}
static PIXELFORMATDESCRIPTOR pfd=
pfd сообщает Windows каким будет вывод на экран каждого пикселя
{
sizeof(PIXELFORMATDESCRIPTOR),
Размер дескриптора данного формата пикселей
1,
Номер версии
PFD_DRAW_TO_WINDOW |
ФорматдляОкна
PFD_SUPPORT_OPENGL |
Форматдля OpenGL PFD_DOUBLEBUFFER,
Формат для двойного буфера
PFD_TYPE_RGBA,
Требуется RGBA формат bits,
Выбирается бит глубины цвета
0, 0, 0, 0, 0, 0,
Игнорирование цветовых битов
0,
Нет буфера прозрачности
0,
Сдвиговый бит игнорируется
0,
Нет буфера накопления
0, 0, 0, 0,
Биты накопления игнорируются
32,
32 битный Zбуфер (буфер глубины) 0,
Нет буфера трафарета
0,
Нет вспомогательных буферов
PFD_MAIN_PLANE,
Главный слой рисования
0,
Зарезервировано
0, 0, 0
Маски слоя игнорируются
};
if (!(hDC=GetDC(hWnd)))
Можем ли мы получить Контекст Устройства?
{
KillGLWindow();
Восстановить экран
180
MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
Вернуть false
}
if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))
Найден ли подходящий формат пикселя?
{
KillGLWindow();
Восстановить экран
MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
Вернуть false
}
if(!SetPixelFormat(hDC,PixelFormat,&pfd))
Возможно ли установить Формат Пикселя?
{
KillGLWindow();
Восстановить экран
MessageBox(NULL,"Can't Set The
PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE;
Вернуть false
}
if (!(hRC=wglCreateContext(hDC)))
Возможно ли установить Контекст Рендеринга?
{
KillGLWindow();
Восстановить экран
MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
Вернуть false
}
if(!wglMakeCurrent(hDC,hRC))
Попробовать активировать Контекст Рендеринга
{
KillGLWindow();
Восстановить экран
MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
Вернуть false
}
ShowWindow(hWnd,SW_SHOW);
Показать окно
SetForegroundWindow(hWnd);
181
Слегка повысим приоритет
SetFocus(hWnd);
Установить фокус клавиатуры на наше окно
ReSizeGLScene(width, height);
Настроим перспективу для нашего OpenGL экрана.
if (!InitGL())
Инициализация только что созданного окна
{
KillGLWindow();
Восстановить экран
MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
Вернуть false
}
return TRUE;
Всё в порядке!
}
LRESULT CALLBACK WndProc( HWND hWnd,
Дескриптор нужного окна
UINT uMsg,
Сообщение для этого окна
WPARAM wParam,
Дополнительная информация
LPARAM lParam)
Дополнительная информация
{
switch (uMsg)
Проверка сообщения для окна
{
case WM_ACTIVATE:
Проверка сообщения активности окна
{
if (!HIWORD(wParam))
Проверить состояние минимизации
{
active=TRUE;
Программа активна
}
else
{
182