FreeGLUT - це бібліотека, що допомагає зосередитись на реалізації системи з використанням графічної бібліотеки OpenGL і відкинути деталі створення середовища для програми в залежності від використовуваної операційної системи.

За допомогою стеку FreeGLUT/OpenGL можна створювати ігри, і різні додатки візуалізації як і у 2D так і в 3D, не турбуючись про відмінності між операційними системами.

FreeGLUT також несе у собі декілька допоміжних функцій, наприклад, функції відмальовування деяких геометричних примітивів на подобі сфери, торуса, конуса, циліндра, куба, тетрагедрона, октагедрона, чайника і інших. Також є функції відмальовування тексту з обмеженого набору шрифтів. Наявні функції можна поглянути за посиланнями нижче у репозиторії проекту або на домашній сторінці документації.

Додаткові функції FreeGLUT не поставляються разом з OpenGL!

Для ефективного використовування графічної бібліотеки OpenGL бажано ознайомитись з статтею http://www.kytok.org.ua/post/vstup-do-opengl-open-graphics-library-vidkryta-hrafichna-biblioteka і іншими перекладами документації по функціям OpenGL на сайті за адресою http://www.kytok.org.ua/tag/open_graphical_library_tag.

Коротка історія і опис

FreeGLUT являється альтернативною бібліотекою до OpenGL Utility Toolkit (GLUT) з відкритим вихідним кодом. GLUT оригінально написав Марк Кілґард (Mark Kilgard) для підтримки програм прикладів у другій частині Червоної Книги OpenGL. Відтоді, GLUT використовувалась у широкому спектрі практичних програм через її простоту, широкодоступність і високу переносимість.

GLUT (і відповідно FreeGLUT) бере на себе усі системно залежні турботи, які необхідні для створення вікон, ініціалізації контекстів OpenGL, і опрацювання подій вводу, щоб забезпечити справжню портованість програм написаних з використанням графічної бібліотеки OpenGL.

FreeGLUT випускається під ліцензією X-Consortium.

Оригінальна бібліотека GLUT є закинутою з найостаннішою версією (3.7) котра датується серпнем 1998 року. Її ліцензія забороняє розповсюджувати модифікований код бібліотеки. Це справді прикро, оскільки бібліотека GLUT є старою і вимагає покращень. Також ліцензія GLUT є несумісною з деякими дистрибутивами ПЗ (наприклад XFree86).

Павло В. Ольшта (Pawel W. Olszta) розпочав проект FreeGLUT 1-го грудня 1999 року. Проект на даний момент являється 100% заміною оригінальної бібліотеки GLUT з деяким закинутим функціоналом (відносно SGI) і набором помилок, які поступово зменшуються.

FreeGLUT впроваджує деякі додаткові можливості поверх базової функціональності бібліотеки GLUT, на подобі деякого набору наперед визначених об'єктів для використання, можливість виконувати одинарні проходження подійного циклу, або елегантного виходу з нього, функції вводу коліщатка миші, необов'язкове створення профілю сумісності OpenGL ядра, множинний ввід доторків/кліків, і підтримка більшої кількості платформ.

Підтримувані платформи

На даний момент підтримується наступний список платформ:
  • UNIX системи з X11 або Wayland (на подобі GNU/Linux, FreeBSD, IRIX, тощо)
  • MS Windows
  • macOS з XQuartz (Cocoa ще не підтримується)
  • Android (NDK)
  • BlackBerry

Основні посилання

Детальніше за адресою оригіналу: https://freeglut.sourceforge.net/

Документація знаходиться за адресою: https://freeglut.sourceforge.net/docs/api.php

GitHub репозиторій проекту за адресою https://github.com/freeglut/freeglut

Встановлення FreeGLUT

Встановлення на Debian/Ubuntu або подібних системах

Щоб встановити файли для розробки з використанням FreeGLUT і OpenGL, можна скористатись наперед скомпільованими файлами за допомогою команди apt на подобі:

sudo apt-get install freeglut3 freeglut3-dev mesa-common-dev libglew-dev libglm-dev

Встановлення на ОС MS Windows

Інструкції по встановленню на ОС MS Windows лежать в офіційному репозиторію FreeGLUT за адресою https://github.com/freeglut/freeglut/blob/master/README.cmake або https://github.com/freeglut/freeglut/blob/master/README.win32

Отримання джерельного коду на комп'ютер

Щоб отримати джерельний вихідний код бібліотеки FreeGLUT можна скористатись командою git:

git clone https://github.com/freeglut/freeglut.git

Після виконання якої з'явиться можливість вручну зібрати усі необхідні файли бібліотеки на будь-якій з підтримуваних систем.

Також можна завантажити ZIP-архів з Веб-інтерфейсу GitHub репозиторію за адресою: https://github.com/freeglut/freeglut/archive/refs/heads/master.zip

Приклади

Репозиторій з прикладами розміщений за адресою https://github.com/yuriysydor1991/freeglut-fast-start-article-resources.git.

Щоб отримати його на власний комп'ютер, необхідно виконати наступні команди:

git clone https://github.com/yuriysydor1991/freeglut-fast-start-article-resources.git

Якщо системи версіювання Git ще не має - необхідно встановити її. Є можливість завантажити проект у вигляді ZIP-архіву з GitHub веб-інтерфейсу, або за посиланням: https://github.com/yuriysydor1991/freeglut-fast-start-article-resources/archive/refs/heads/main.zip

Використовується система для збору - CMake. Якщо її ще немає на комп'ютері - необхідно встановити з офіційно сайту. Деталі у статті за посиланням.

Приклад №1

Розглянемо приклад найпростішої FreeGLUT/OpenGL програми. А саме вікно з чорним фоном. На даному прикладі можна поглянути на "мінімальний" необхідний код для побудови FreeGLUT/OpenGL програми.

// головні заголовкові файли GLUT і OpenGL
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

// деякі константи
// ширини і висоти вікна за замовчуванням
constexpr const unsigned int W_DEFAULT_WIDTH = 500;
constexpr const unsigned int W_DEFAULT_HEIGHT = 500;

// функція ініціалізації параметрів OpenGL
void init()
{
    // встановлюємо колір очищення пікселів екрану
    glClearColor (0.0, 0.0, 0.0, 0.0);
    // вмикаємо розпізнавання глибини
    glEnable(GL_DEPTH_TEST);
}

// Процедура відображення OpenGL сцени
void display()
{
    // очищуємо буфер пікселів екрану
    // раніше встановленим за допомогою glClearColor
    // і буферу глибини
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // зберігаємо поточну матрицю у стеку матриць
    // і дублюємо її для редагування
    glPushMatrix();

    // ось тут відображення об'єктів і сцени

    // витягуємо оригінальну матрицю зі стеку матриць
    glPopMatrix();
    // підміняємо буфер для нових команд
    glutSwapBuffers();
}

// Процедура зміни розміру вікна
void reshape(int w, int h)
{
    // встановлюємо розмір вікна OpenGL
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    // встановлюємо режим матриці у GL_PROJECTION
    glMatrixMode(GL_PROJECTION);
    // Встановлюємо матрицю ідентичності
    glLoadIdentity();

    // Встановлюємо параметри проекції
    glOrtho(-w/2.f, w/2.f, -h/2.f, h/2.f, -1.0, 100.0);
    // Встановлюємо режим огляду моделі
    glMatrixMode(GL_MODELVIEW);
    // завантажуємо матрицю ідентичності
    glLoadIdentity();
}

// Головна функція програми
int main(int argc, char** argv)
{
    // Ініціалізація FreeGLUT бібліотеки
    glutInit(&argc, argv);
    // Встановлення параметрів відображення
    // для подвійної буферизації і RGB кольорової схеми
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
    // Встановлення розмірів вікна
    glutInitWindowSize (W_DEFAULT_WIDTH, W_DEFAULT_HEIGHT);
    // Створення вікна з назвою у якості шляху до виконуваного файлу
    glutCreateWindow (argv[0]);

    // Виклик процедури ініціалізації
    init ();

    // Встановлення головних процедур
    // для відображення схеми
    glutDisplayFunc(display);
    // для зміни розміру вікна
    glutReshapeFunc(reshape);

    // Головний цикл FreeGLUT бібліотеки
    // у якому обробляються події
    // і відбувається інша магія
    glutMainLoop();

    return 0;
}
Повну версію даного main.cpp файлу можна знайти за адресою https://github.com/yuriysydor1991/freeglut-fast-start-article-resources/blob/main/blank-window/main.cpp

Щоб побудувати вихідний код за допомогою CMake. необхідно відкрити термінал, пройти у директорію завантаженого проекту і виконати наступні команди:

rm -fr build
mkdir -vp build
cd build
cmake ../ 
cmake --build blank-window 
./blank-window/blank-window

Вивід може виглядати наступним чином:

/resources/uploads/img/FreeGLUT-blank-window-example-buildup.png

Після компіляції і запуску виконуваного файлу можна побачити вікно подібне наступному:

/resources/uploads/img/FreeGLUT-blank-window-example-startup-view.png

Приклад №2

Даний приклад призначений продемонструвати функцію відмальовування фігури, яка поставляється з FreeGLUT. Повний файл можна переглянути за посиланням: https://github.com/yuriysydor1991/freeglut-fast-start-article-resources/blob/main/torus-window/main.cpp

Код відрізняється від попереднього тільки декількома рядками.

Потрібно підключити новий заголовковий файл chrono:

// системні підключення
#include <chrono>

Також необхідно додатково оголосити пару глобальних змінних і функцій:

long int getMillisecondsTime();

// глобальна змінна для обертання бублика
// градуси обертання бублика
long int spin = 0;
// змінна для зберігання часу пройденого від
// останнього намальованого кадру.
long int timestart = getMillisecondsTime();

// функція яка повертає поточні мілісекунди пройденого часу
long int getMillisecondsTime()
{
    // отримуємо поточний час
    auto currentTime = std::chrono::system_clock::now();

    // Перетворюємо поточний час у мілісекунди від початку відліку
    auto currentTimeMillis = std::chrono::time_point_cast<std::chrono::milliseconds>(currentTime);

    // отримуємо значення мілісекунд
    return currentTimeMillis.time_since_epoch().count();
}

// процедура перераховування обертання фігури в залежності від часу
void recalculateSpin()
{
    // отримуємо поточний час у локальну змінну
    auto ctime = getMillisecondsTime();
    // обраховуємо пройдений час від попереднього кадру
    auto deltaTime =  ctime - timestart;

    // якщо змінити дільник тоді зміниться швидкість обертання
    spin += deltaTime / 10;

    // обрізаємо значення обертання у проміжок [0,360]
    if (spin > 360) { spin -= 360; }

    // зберігаємо поточне значення часу
    timestart = ctime;
}

І фінально внести відповідні зміни у функцію відмальовування сцени display:

// Процедура відображення OpenGL сцени
void display()
{
    // очищуємо буфер пікселів екрану
    // раніше встановленим за допомогою glClearColor
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // зберігаємо поточну матрицю у стеку матриць
    // і дублюємо її для редагування
    glPushMatrix();

    // обертаємо поточну матрицю
    glRotatef(spin, 1.0, 0.0, 0.0);

    // встановлюємо колір який буде використовуватися для малювання
    glColor3f(.7f, .7f, .9f);
    // використовуємо функцію FreeGLUT для відмальовування бублика
    glutWireTorus (50.0, 200.0, 20, 20);

    // витягуємо оригінальну матрицю зі стеку матриць
    glPopMatrix();
    // підміняємо буфер для нових команд
    glutSwapBuffers();

    // перераховуємо кут обертання фігури в залежності від часу
    // пройденого між кадрами
    recalculateSpin();

    // примусово перемальовуємо екран
    glutPostRedisplay();
}

Після будування даного прикладу командами:

Можна отримати торус або бублик який обертається навколо своєї осі (x, можна змінити вісь у виклику функції glRotatef):

Детальніше про наявні наперед визначені функції відмальовування бібліотеки FreeGLUT можна переглянути за посиланням https://freeglut.sourceforge.net/docs/api.php#GeometricObject.

Приклад №3

Розглянемо приклад відмальовування примітиву але замість каркасу, використаємо функцію для побудови чайника з площин.

Від попереднього прикладу він відрізняється тільки використанням функції glutSolidTeapot замість glutWireTorus у оголошеній функції display. Функція glutSolidTeapot приймає тільки один параметр - це розмір самого чайника.

Повний файл прикладу можна знайти за посиланням: https://github.com/yuriysydor1991/freeglut-fast-start-article-resources/blob/main/teapot-window/main.cpp.

Щоб побудувати даний приклад необхідно виконати наступні команди з кореня проекту:

mkdir -vp build
сd build
cmake ../
cmake --build teapot-window
./teapot-window/teapot-window

Після їхнього виконання на екрані можна побачити наступне:

FreeGLUT-intro-teapot-window-demo-startup-example.png

Офіційні приклади від розробників

Щоб переглянути офіційні приклади використання від розробників FreeGLUT можна скористатись GitHub репозиторієм за адресою https://github.com/freeglut/freeglut/tree/master/progs/demos.