Вступ

Ласкаво просимо до першого туторіала!

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

Передумови

Ніяких спеціальних знань не потрібно, що б йти цим туторіалом. Досвід в будь якій мові програмування ( C, Java, Lisp, Javascript, чи щось інше ) буде допомагати зрозуміти цей код, але не є потрібним, це навіть буде дещо складно вивчати дві речі одночасно.

Всі туторіали написанні з використанням “простого с++” : багато зусиль було направлено на те, що б зробити код якомога простіше. Ніяких шаблонів, класів та вказівників. Тому, ви зможете все зрозуміти навіть якщо ви знаєте тільки Java.

Забудьте все

Ви нічого не знали, та забудьте все, що ви знали про OpenGL. Якщо ви знаєте щось схоже на glBegin() - забудьте. Тут ми будемо вивчати сучасний OpenGL (OpenGL 3 та 4) і багато туторіалів в інтернеті вчать “старий” OpenGL (OpenGL 1 та 2). Отже, забудьте все, що ви могли знати до цього, інакше ваші мізки вибухнуть від суміші.

Збирання (компіляція та лінковка) туторіала

Всі туторіали можуть бути побудовані на Windows, Linux та Mac. Для всіх них процедура в основному однакова :

  • Оновіть Ваші драйвера !! ЗРОБІТЬ ЦЕ. Ви попередженні.
  • Завантажте компілятор, якщо у вас не має ще його.
  • Встановіть CMake
  • Завантажте код цього туторіала
  • Згенеруйте проект, використовуючи CMake
  • Побудуйте проект, використовуючи ваш компілятор
  • Пограйтесь з прикладами !

Нижче ви знайдете детальні інструкції для різних платформ. Можливо, потрібно буде їх трішки адаптувати. Якщо не впевнені, читайте інструкцію для Windows та адаптуйте її.

Збираємо в Windows

  • Оновлення ваших драйверів достатньо проста процедура. Просто відвідайте сайт NVIDIA чи AMD та завантажте їх. Якщо ви не впевнені що до моделі GPU, просто відкрийте Панель керування - Система та безпека - Система - Менеджер пристроїв - Адаптер дисплея. Якщо у вас інтегроване відео від Intel, драйвер буде від виробника комп’ютера/ноутбука.

  • Ми пропонуємо використовувати Visual Studio 2017 Express for Desktop як компілятор. Ви маєте змогу завантажити його безкоштовно тут. Переконайтесь, що ви обрали “вибіркове встановлення” і відмітили С++. Якщо вам більше до вподоби MinGW, ми рекомендуємо використовувати Qt Creator. Встановіть те, що ви хочете. Послідовність кроків буде пояснюватись для Visual Studio, але вони будуть подібні для більшості середовищ для програмування (IDE).
  • Завантажте CMake та встановіть його.
  • Завантажте код та розпакуйте його, наприклад в C:\Users\XYZ\Projects\OpenGLTutorials\
  • Запустіть CMake. В першому рядку вкажіть каталог, куди ви розпакували код. Якщо не впевнені, оберіть каталог, що містить файл CMakeLists.txt. В наступному рядку введіть ім’я каталогу, де компілятор збереже всі свої файли. Наприклад C:\Users\XYZ\Projects\OpenGLTutorials-build-Visual2017-64bits\, чи C:\Users\XYZ\Projects\OpenGLTutorials\build\Visual2017-32bits. Зверніть увагу, що ви можете обрати будь який каталог, не обов’язково в цьому.

  • Натисніть на кнопку Configure. Так як ви робите це вперше, CMake запитає вас про компілятор, який ви хочете використовувати. Обирайте згідно першого пункту. Якщо у вас 64бітна Windows, ви можете обрати 64бітний компілятор. Якщо є сумніви - обирайте 32бітний.
  • Натискайте кнопку Configure до тих пір, поки всі червоні поля не зникнуть. Натисніть Generate (Згенерувати). Ваш проект в Visual Studio буде створено. Тепер можна забути про CMake.
  • Відкрийте C:\Users\XYZ\Projects\OpenGLTutorials-build-Visual2010-32bits. Знайдіть там Tutorials.sln file і відкрийте в Visual Studio.

В меню Build, натисніть Build All. Кожний туторіал і залежності будуть скомпільовані. Кожний виконуваний файл буде скопійовано в C:\Users\XYZ\Projects\OpenGLTutorials\ . Сподіваюсь, помилок не буде.

  • Відкрийте C:\Users\XYZ\Projects\OpenGLTutorials\playground, запустіть playground.exe. З’явиться вікно з чорним вмістом.

Ви можете запустити будь який туторіал з Visual Studio. Натисніть правою кнопкою мишки на Playground один раз та оберіть “Choose as startup project”. Тепер ви маєте змогу відлагоджувати код після того, як натиснете F5.

Збираємо в Linux

В світі дуже багато різних Linux-дистрибутивів, так що неможливо дати одну єдину інструкцію. Адаптація може бути потрібною, так що не вагаючись, читайте документацію по вашому дистрибутиву.

  • Встановіть останні драйвера. Ми наполегливо рекомендуємо використовувати “пропрієтарні драйвера”. Так, це не GNU, але вони працюють. Якщо Ваш дистрибутив не вміє автоматично встановлювати їх, подивіться на документацію Ubuntu.
  • Встановіть всі потрібні компілятори, інструменти та бібліотеки. Повний список cmake make g++ libx11-dev libxi-dev libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxext-dev libxcursor-dev libxinerama-dev libxi-dev. Для встановлення використовуйте sudo apt-get install ***** чи su && yum install ******
  • Завантажте вихідний код та розпакуйте його, наприклад сюди ~/Projects/OpenGLTutorials/
  • перейдіть в цей каталог (куди було розпаковано код) ~/Projects/OpenGLTutorials/ , і введіть наступне:

  • mkdir build
  • cd build
  • cmake ..

  • makefile було створено в каталозі build/.
  • Введіть “make all”. Всі туторіали і залежності будуть скомпільовані. Всі файли, які можна запустити, будуть скопійовані в каталог ~/Projects/OpenGLTutorials/. Сподіваємось, що помилок не буде.
  • Відкрийте ~/Projects/OpenGLTutorials/playground, і запустіть ./playground. Повинно з’явитись “чорне вікно”.

Також рекомендується використовувати IDE, наприклад, Qt Creator. До речі, Qt Creator має вбудовану підтримку CMake і забезпечує комфортні умови для налагодження програми. Ось інструкції для нього:

  • В QtCreator, перейдіть по меню File->Tools->Options->Compile&Execute->CMake
  • Встановіть шлях до CMake. Скоріше за все це буде щось виду /usr/bin/cmake
  • В File->Open Project; виберіть tutorials/CMakeLists.txt
  • Виберіть build каталог, краще за межами каталогу tutorials
  • За бажанням додайте -DCMAKE_BUILD_TYPE=Debug` в параметрах. Перевірте.
  • Натисніть на “молоток” внизу. Туторіал буде запущено з каталогу tutorials/.
  • Що б запустити туторіал з QtCreator, натисніть Projects->Execution parameters->Working Directory, і оберіть каталог з шейдерами, текстурами і моделями. Наприклад, для туторіалу номер 2 це ~/opengl-tutorial/tutorial02_red_triangle/

Збираємо на Mac

Ця процедура дуже подібна до Windows (можна використовувати і Makefile, але про них тут не буде пояснень):

  • Встановіть XCode з Mac App Store
  • Завантажте CMake, і встановіть .dmg . Вам не потрібно встановлювати інструменти командного рядка.
  • Завантажте вихідний код і розпакуйте його, наприклад, сюди ~/Projects/OpenGLTutorials/ .
  • Запустіть CMake (Applications->CMake). В першому рядку перейдіть в каталог з розпакованими файлами (там повинен бути файл CMakeLists.txt). В другому рядку вкажіть, де буде розміщено весь вивід, потрібний компілятору. Наприклад, можна взяти каталог ~/Projects/OpenGLTutorials_bin_XCode/. Зауважте, це може бути будь-який каталог, не обов’язково в цім самім.
  • Натисніть кнопку Configure. Так як це перший раз конфігурується проект, CMake запитає, який компілятор використовувати. Оберіть XCode.
  • Продовжуйте натискати Configure до тих пір, коли всі червоні рядки не зникнуть. Потім натисніть Generate. Ващ Xcode проект було створено. Можна забути про CMake.
  • Відкрийте ~/Projects/OpenGLTutorials_bin_XCode/ . Ви знайдете там файл Tutorials.xcodeproj - відкривайте його.
  • Оберіть бажаний туторіал для запуску в панелі Xcode’s Scheme і натисніть кнопку Run для компіляції та запуску:

Замітки Code::Blocks

Через те, що є дві бажини (один в C::B, один в CMake), Вам потрібно відредагувати командний рядок в Project->Build Options->Make commands, наступним чином :

Також потрібно встановити робочий каталог: Project->Properties -> Build targets -> tutorial N -> execution working dir ( це src_dir/tutorial_N/ ).

Як запустити цей туторіал

Ви повинні запускати туторіали безпосередньо з правильного каталогу - просто подвійним кліком на файлі. Якщо Вам подобається командний рядок, перейдіть в потрібний каталог.

Якщо Ви хочете запускати туторіал з IDE, не забудьте почитати інструкції вище і встановити правильний робочий каталог.

Як користуватись цим туторіалом

Кожний туторіал містить код і дані, які можуть бути знайденими в каталозі tutorialXX/. Проте, Вам не слід модифікувати ці проекти - вони для довідки. Відкрийте playground/playground.cpp і модифікуйте його. Знущайтесь з нього так, як Вам заманеться. Якщо з ним щось трапиться, просто скопіюйте будь-який туторіал в нього і все повернеться до норми.

Ми будемо надавати шматки коду по ходу туторіалів. Не бійтесь копіювати їх напряму в “ігровий майданчик” (playground) під час читання - експерименти це добре. Уникайте простого читання кінцевого коду - так Ви багато не вивчите. Навіть просто копіюючи собі код ви отримаєте купу проблем.

Відкриваємо вікно

На кінець! Код на OpenGL! Ну, добре, не зовсім. Багато туторіалів показують Вам “низькорівневі деталі”, що б Ви могли побачити, що магії немає. Але “створити вікно” - це дійсно нудна і непотрібна робота, тому ми будемо використовувати GLFW - зовнішню бібліотеку для цього. Якщо Вам дійсно хочеться, ви можете використовувати Win32 API для Windows, X11 для Linux чи Cocoa API дл Mac, чи якусь іншу високорівневу бібліотеку - SFML, FreeGLUT, SDL … подивіться цю сторінку.

Отже, поїхали. Спочатку розберемося з залежностями: нам потрібні деякі базові речі для друку повідомлень в консолі:

// Стандартні заголовки
#include <stdio.h>
#include <stdlib.h>

По перше, GLEW. Цей рядочок - трішки маленької магії, обговоримо пізніше.

// Підключимо GLEW. Завжди робіть це перед gl.h та glfw3.h, тому що тут трішки магії.
#include <GL/glew.h>

Ми вирішили дозволити GLFW керувати вікном і клавіатурою, тому включимо і це:

// Підключимо GLFW
#include <GLFW/glfw3.h>

Нам поки це не потрібно, але це бібліотека для роботи з 3D математикою. Але дуже швидко нам це знадобиться. В бібліотеці GLM немає магії, Ви можете написати свою, просто ця бібліотека зручна. Ми використовуємо using namespace що б замість glm::vec3 писати просто vec3.

// Підключимо GLM
#include <glm/glm.hpp>
using namespace glm;

Якщо просто скопіювати і вставити ці всі #include в файл playground.cpp, компілятор буде жалітись на відсутність функції main(). Отже, створимо її:

int main(){

І спочатку ініціалізуємо GLFW:

// Ініціалізуємо GLFW
glewExperimental = true; // Потрібно для core профілю
if( !glfwInit() )
{
    fprintf( stderr, "Failed to initialize GLFW\n" );
    return -1;
}

Тепер ми можемо створити наше перше OpenGL вікно!

glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Ми хочемо OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Що б MacOS була щаслива
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Нам не потрібен старий OpenGL 

// Відкриємо вікно та створимо OpenGL контекст
GLFWwindow* window; // (In the accompanying source code, this variable is global for simplicity)
window = glfwCreateWindow( 1024, 768, "Tutorial 01", NULL, NULL);
if( window == NULL ){
    fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
    glfwTerminate();
    return -1;
}
glfwMakeContextCurrent(window); // Ініціалізуємо GLEW
glewExperimental=true; // Потрібно для core профілю
if (glewInit() != GLEW_OK) {
    fprintf(stderr, "Failed to initialize GLEW\n");
    return -1;
}

Зберемо і запустимо. Вікно повинно з’явитись і відразу закритись. Звичайно! Зробімо так, що б програма чекала поки користувач не натисне Escape.

// Переконаємося, що ми можемо зафіксувати факт натиснення кнопки нижче 
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

do{
    // Очистимо екран. Це не згадувалось до туторіла 2, проте це може спричинити мерехтіння, тим не менш воно є.
    glClear( GL_COLOR_BUFFER_BIT );

    // Нічого малювати, побачимось в туторіалі 2 !

    // обміняємо буфери
    glfwSwapBuffers(window);
    glfwPollEvents();

} // Перевіримо, чи натиснули ESC що б закрити вікно
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
       glfwWindowShouldClose(window) == 0 );

І зробіть висновки з нашого першого туторіла. В туторіалі 2 ви навчитесь малювати свій перший трикутник.