Робота з opengl за допомогою glut
Як ви вже знаєте, OpenGL є мультиплатформенной бібліотекою, тобто програми написані за допомогою OpenGL можна легко переносити на різні операційні системи, при цьому отримуючи один і той же візуальний результат. Єдине що погано - це те, що для конкретної операційної системи необхідно за своїм робити настроювання OpenGL. Тобто, припустимо, ви написали OpenGL програму під Windows і захотіли перенести її в Linux, код OpenGL повинен перенестися без проблем, але ось операції з вікнами, інтерфейс управління, операції з пристроями введення / виведення потрібно заново переписати вже під іншу операційну систему - Linux .
На щастя, існує спеціальна мультиплатформенна бібліотека, що дозволяє вирішити вищеописані проблеми. І називається ця бібліотека - GLUT.
Перш за все необхідно навчитися найголовнішого - це створення вікна, в якому можна буде малювати за допомогою OpenGL. Мінімальна програма, яка створює вікно і що-небудь малює там складається з наступних кроків:
Установка параметрів вікна.
Установка функцій, що відповідають за малювання у вікні і зміні форми вікна.
Отже, розглянемо всі 5 пунктів детальніше:
1. Ініціалізація GLUT виробляється командою:
void glutInit (int * argcp, char ** argv);
Перший параметр представляє з себе покажчик на кількість аргументів у командному рядку, а другий - покажчик на масив аргументів. Зазвичай ці значення беруться з головної функції програми: int main (int argc, char * argv []).
2. Встановлення параметрів вікна містить в собі кілька етапів. Перш за все необхідно вказати розміри вікна:
void glutInitWindowSize (int width, int height);
Перший параметр width - ширина вікна в пікселях, другий height - висота вікна в пікселях. Зазначу також, що якщо цю команду опустити, то GLUT сам встановить розміри вікна за замовчуванням, зазвичай це 300x300.
Далі можна задати положення створюваного вікна щодо верхнього лівого кута екрана. Робиться це командою:
void glutInitWindowPosition (int x, int y);
Необхідно також встановити для вікна режим відображення інформації. Тобто встановити для вікна такі параметри як: використовувана колірна модель, кількість різних буферів, і т.д. Для цього в GLUT існує команда:
void glutInitDisplayMode (unsigned int mode);
У команди є єдиний параметр, який може бути представлений однією з наступних констант або комбінацією цих констант за допомогою побітового АБО.
Розгорнути вікно на весь екран. При цьому прибираються з екрану заголовок вікна і його інші частини, крім вмісту вікна, тобто ваше додаток стає весь екран.
Існує ще одна цікава функція, яка дозволяє встановлювати у вікні форму курсора:
void glutSetCursor (int cursor);
Параметр cursor може приймати одне з наступних значень: GLUT_CURSOR_RIGHT_ARROW, GLUT_CURSOR_LEFT_ARROW, GLUT_CURSOR_INFO, GLUT_CURSOR_DESTROY, GLUT_CURSOR_HELP, GLUT_CURSOR_CYCLE, GLUT_CURSOR_SPRAY, GLUT_CURSOR_WAIT, GLUT_CURSOR_TEXT, GLUT_CURSOR_CROSSHAIR, GLUT_CURSOR_UP_DOWN, GLUT_CURSOR_LEFT_RIGHT, GLUT_CURSOR_TOP_SIDE, GLUT_CURSOR_BOTTOM_SIDE, GLUT_CURSOR_LEFT_SIDE, GLUT_CURSOR_RIGHT_SIDE, GLUT_CURSOR_TOP_LEFT_CORNER, GLUT_CURSOR_TOP_RIGHT_CORNER, GLUT_CURSOR_BOTTOM_RIGHT_CORNER, GLUT_CURSOR_BOTTOM_LEFT_CORNER, GLUT_CURSOR_INHERIT , GLUT_CURSOR_NONE, GLUT_CURSOR_FULL_CROSSHAIR.
У GLUT існує спеціальний режим, що дозволяє вам використовувати режим гри для вашої OpenGL програми, тобто коли ваше додаток займає весь екран.
Для цього в GLUT існують спеціальні команди для управління цим режимом.
void glutGameModeString (const char * string);
Ця функція визначає параметри встановлюваного дозволу екрану, глибину кольору і частоту оновлення екрану (в герцах). Формат вхідного параметра такий:
Наприклад: glutGameModeString ( "640x480: 16 @ 72"); - Чи означає, що необхідно вибрати дозвіл екрану 640 на 480 пікселів при глибині кольору в 16 біт і частотою оновлення екрану 72 герца.
Щоб перейти в режим GAME MODE необхідно викликати функцію:
А щоб вийти з режиму GAME MODE необхідно викликати функцію:
Ну і щоб було зрозуміліше приведу приклад використання цього режиму:
Повний вихідний код програми можна взяти звідси: game_mode.zip
Зазначу також що можна викликати функцію glutGameModeString і таким чином:
Тобто НЕ вказуючи частоту оновлення екрану. При цьому GLUT сама вибере відповідну частоту.
У цій частині я розповім про те, яким чином відбувається взаємодія вашої OpenGL програми і GLUT.
Найпершою за значимістю (без якої не обійтися ні в одній програмі) йде функція відповідає за перерисовку вмісту вікна:
void glutDisplayFunc (void (* func) (void));
Ця функція встановлює функцію у вашій програмі, яка буде відповідати за перерисовку вікна. Це потрібно для того, що коли системі буде потрібно перемалювати ваше вікно (наприклад коли ви з згорнутого стану розгорнули вікно), то вона викличе відповідну функцію у вашій програмі, яка відповідальна за перерисовку вмісту вікна. Також функція перемальовування вікна викликається при найпершому запуску вашого застосування. Зазначу, що якщо ви створюєте вікно в GLUT, то визначати функцію перемальовування вікна потрібно обов'язково! З іншого боку, ви самі можете змусити систему перемалювати вікно, це потрібно наприклад тоді, коли ви змінили стану об'єктів або змінили їх зовнішність, то вам знадобиться перемалювати вміст вікна, щоб відобразити зроблені зміни. Тому в GLUT існує спеціальна функція glutPostRedisplay (). яка змушує систему перемалювати поточне вікно. Якщо раптом вам захочеться перемалювати не поточні вікно, а якесь інше, то передбачена наступна функція: glutPostWindowRedisplay (int win). яка перемальовує вміст win вікна.
void glutReshapeFunc (void (* func) (int width, int height));
Як вже говорилося, це функція встановлює іншу функцію у вашій програмі, яка буде відповідальна за зміну розмірів вікна. Як тільки у вікна змінилися розміри, необхідно перебудувати виведення графічної інформації вже в нове вікно з іншими розмірами. Для цього в функцію, що викликається (тобто функцію у вашій програмі) передаються 2 параметри width і height. тобто ширина і висота зміненого вікна. Зазвичай на самому початку функції, викликається функція glViewport. наприклад так: glViewport (0, 0, width, height). щоб перебудувати виведення зображення вже в вікно з іншими розмірами.
Ще одна цікава функція, яка встановлює процедуру у вашій програмі, яка буде викликатися системою щоразу, коли вікно ставати видимим або навпаки ставати невидимим.
void glutVisibilityFunc (void (* func) (int state));
Єдиний параметр, який передається в спричинюється системою функцію: state. Порівнюючи цей параметр з константами GLUT_NOT_VISIBLE і GLUT_VISIBLE можна визначити, що сталося з вікном, або воно стало невидимим або навпаки - видимим.
void glutIdleFunc (void (* func) (void));
Функція, яка встановлює процедуру у вашій програмі, яка буде викликатися системою щоразу, коли ваше додаток простоює, тобто нічого не робить. Часто цю функцію використовують для анімації.
Ну і остання функція, яку ми розглянемо:
void glutTimerFunc (unsigned int millis, void (* func) (int value), int value);
Ця функція встановлює таймер. Перший параметр millis задає час в мілісекундах, після закінчення яких викликається функція, яка вказана як другий параметр. Третій параметр value вказує індентіфікатор таймера, тобто таймерів може бути одночасно запущено кілька. Те ж саме значення value є і в функції, яка викликається таймером. Це потрібно для того, щоб визначити, який таймер спрацював, тобто якщо ваша функція обробляє кілька таймерів.
Далі привожу приклад невеликої програмки, яка малює обертається лінію. Оригінальний текст програми можна взяти і звідси: animation.zip
Спробуйте згорнути вікно, а потім розгорнути і подивіться на консоль, це спрацювала процедура Visibility.
[An error occurred while processing this directive]
[An error occurred while processing this directive]