Предисловие


Если появляется желание начать изучать OpenGL — то чаще всего натыкаешься на уроки NeHe и сразу начинаешь с устаревшего OpenGL. Но в интернете есть хороший набор уроков по новому OpenGL 3.3, поддерживаемый сообществом. Сам набор разделен на 3 группы: Базовые уроки, Продвинутые уроки и Всякое. Я постараюсь выпускать по статье на каждый урок, а в начале каждой статьи буду оставлять небольшое содержание. Спасибо.

Содержание


Базовые уроки:

Продвинутые уроки:
  • Урок 9. VBO индексация
  • Урок 10. Прозрачность
  • Урок 11. 2D текст
  • Урок 12. OpenGL расширения
  • Урок 13. Normal Mapping
  • Урок 14. Отрисовка на текстуру
  • Урок 15. Lightmaps
  • Урок 16. Shadow mapping
  • Урок 17. Вращение
  • Урок 18.1. «Билборды»
  • Урок 18.2. Частицы

Всякое:
  • Урок 19. FPS счетчик
  • Урок 20.1. Нажатие на объекты с помощью OpenGL хака
  • Урок 20.2. Нажатие на объекты с помощью физического движка
  • Урок 20.3. Нажатие на объекты с помощью собственного raycastingа


Статья


Вступление


Добро пожаловать в первый урок.

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

Требования


Никаких особых требований для этих уроков не требуется. Желательно иметь опыт работы с любым языком программирования (C, Java, Lisp, Javascript и т.д.), для того, что бы полностью понимать код, но это не обязательно. Просто будет сложнее учить сразу 2 вещи.

Все уроки написаны на «Легком С++»: Множество усилий было приложено для того, что бы сделать код максимально простым. Нет шаблонов, нет классов, нет указателей. Так Вы сможете понять все, даже если знаете только Java.

Забудьте все


Вам не нужно ничего знать, но если Вы что-то знаете про OpenGL, забудьте это. Если Вы знаете что-то про glBegin(), забудьте это. Здесь Вы будете изучать современный OpenGL (OpenGL 3 и 4), а большинство уроков, которые Вы можете найти в интернете — по старому OpenGL (OpenGL 1 и 2).
Так что забудьте все, что Вы можете знать про OpenGL, иначе у вас мозг вскипит от смешивания разных стандартов.

Сборка


Все уроки могут быть собраны на Windows, Linux и Mac. Для всех этих платформ, процедура одна и та же:
  • Обновите драйвера. Вас предупредили
  • Скачайте компилятор, если у вас еще нет его
  • Установите CMake
  • Скачайте исходный код уроков
  • Сгенерируйте проект с помощью CMake
  • Соберите его
  • Поиграйтесь с примерами!


Детальнее, алгоритмы сборки под разные платформы представлены ниже:

Сборка под Windows


  • Обновить драйвера должно быть просто. Просто скачайте драйвера с сайта AMD или NVidia, в зависимости от вашей видеокарты. Если вы не уверены в том, GPU какой компании у вас стоит: Панель управления -> Система и Безопасность -> Система -> Диспетчер устройств -> Видеочип. Если у вас интегрированная Intel видеокарта — то драйвера зачастую предоставляются производителем (Dell, HP и т.д.)
  • Мы советуем использовать Visual Studio 2015 Express for Desktop в качестве компилятора. Вы можете скачать его бесплатно отсюда. Если Вы предпочитаете MinGW, тогда рекомендуем использовать QtCreator. Устанавливайте ПО в зависимости от ваших предпочтений. Дальнейшее указания будут даны для Visual Studio. Адаптируйте их для вашей IDE.
  • Скачайте CMake и установите его.
  • Скачайте исходный код и разархивирейте его к примеру в C:\Users\XYZ\Projects\OpenGLTutorials\
  • Запустите CMake. В первой строке введите путь до папки с исходниками. В указанной Вами папке должен находиться CMakeLists.txt. Во второй строке укажите путь, в который будут сохранены результаты работы CMake.
  • Нажмите на кнопку «Configure». Поскольку это первая настройка проекта, CMake спросит, какой компилятор Вы хотите использовать. Выбирайте мудро, основываясь на первом шаге. Если у вас 64 битная версия Windows, Вы можете выбрать 64 битный компилятор. Если Вы не уверены, выбирайте 32 битный.
  • Нажимайте на кнопку «Configure» до тех пор, пока все красные строки не пропадут. Далее нажмите на кнопку «Generate». Проект Visual Studio создан. Теперь Вы можете забыть про CMake.
  • Откройте папку, которую Вы указали во второй строке. Найдите там файл Tutorials.sln. Откройте его с помощью Visual Studio.
  • В меню «Build» нажмите «Build All». Все уроки и зависимости скомпилированы. Все исполняемые файлы были скопированы в папку с уроком. Надеюсь ошибок не возникло.
  • Откройте файл playground.exe и появится черное окно.

Вы также можете запустить каждый урок прямо из Visual Studio. Для этого нажмите правой кнопкой мыши на уроке, выберите «Choose as startup project». Теперь можете отлаживать его с помощью F5.


Сборка под Linux


Существует очень большое количество различных дистрибутивов Linux и просто невозможно описать процесс сборки для каждой конкретной платформы. Вот общая процедура. Адаптируйте ее для своего дистрибутива:
  • Установите последние драйвера. Мы крайне рекомендуем бинарные драйвера с закрытым исходным кодом. Они не открытые, но они работают. Если ваш дистрибутив не предоставляет автоматическую установку, попробуйте урок с сайта Ubuntu.
  • Установите необходимые компиляторы, инструменты и библиотеки. Полный список: cmake make g++ libx11-dev libxi-dev libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxext-dev libxi-dev.
    sudo apt-get install *****
    или
    su && yum install ******
  • Скачайте исходный код и разархивируйте его.
  • Перейдите в папку с проектом и выполните следующие команды:
  • mkdir build
  • cd build
  • cmake ..
  • Makefile был создан в build папке.
  • Команда «make all» соберет все уроки и их зависимости. Все исполняемые файлы будут скопированы в папку с проектом.
  • Запустите файла ./playground. Должно появиться черное окно.


Заметьте, что Вы также можете использовать IDE, вроде QtCreator. Главное, что бы она поддерживала CMake. Вот инструкция для QtCreator:
  • В QtCreator откройте File -> Tools -> Options -> Compile&Execute -> CMake
  • Установите путь до CMake. Зачастую это /usr/bin/cmake
  • File -> Open Project; Выберите tutorials/CMakeLists.txt
  • Выберите папку для сборки. Желательно она должна быть вне папки tutorials.
  • Можете установить флаг -DCMAKE_BUILD_TYPE=Debug в параметрах.
  • Нажмите на Молот внизу. Все уроки будут собраны
  • Для запуска уроков из QtCreator, нажмите на Projects -> Execution parameters -> Working Directory и выберите папку, где находятся шейдеры, текстуры и модели.


Сборка под Mac


Процесс очень схож со сборкой под Windows. (Makefile также поддерживаются, но здесь они не описаны).
  • Установите XCode из Mac App Store
  • Скачайте CMake и установите .dmg файл. Вам не надо устанавливать инструменты коммандной строки
  • Скачайте исходные коды и разархивируйте их
  • Запустите CMake (Applications -> CMake). А первой строке укажите путь до проекта. В этой папке должен находиться файл CMakeLists.txtю Во второй строке укажите путь до папки в которую будут сохранены результаты работы CMake.
  • Нажмите на кнопку «Configure». Поскольку это первая настройка проекта, CMake спросит, какой компилятор Вы хотите использовать. Выберите XCode.
  • Нажимайте на кнопку «Configure» до тех пор, пока не пропадут все красные строки. Нажмите на «Generate». Все, ваш проект XCode создан. Можете забыть про CMake.
  • Откройте папку, путь до которой Вы прописывали во второй строке. Найдите там файл Tutorials.xcodeproj. Откройте его.
  • Выберите какой-нибудь урок и запустите его с помощью кнопки Run


Заметка к Code::Blocks


В связи с 2 багами (один в Code::Blocks, один в CMake), Вам потребуется изменить настройки в Project->Build Options->Make commands следующим образом:


Также Вам придется настроить рабочую директорию самостоятельно: Project -> Properties -> Build targets -> tutorial N -> Рабочая папка.

Запуск уроков


Рабочими директориями всех скомпилированных уроков должны быть папки с исполняемыми файлами.

Как следовать урокам


Каждый урок содержит исходный код и другие файлы, которые могут быть найдены в tutorialXX/ директории. Однако Вы не должны изменять эти проекты, они поставляются только в качестве примеров. Для изменений есть файл playground/playground.cpp. Если что-то пойдет не так в этом файле, просто скопируйте код из требуемого урока.

Открытие окна


Вот мы и добрались до OpenGL кода! Ну то есть не совсем. Все другие уроки показывают низкоуровневый путь для выполнения тех или иных действий, для того, что бы Вы видели, что никакой магии не происходит. Но это скучно и бесполезно, поэтому мы будем использовать стороннюю библиотеку GLFW для предоставления магии. Если Вам очень хочется — Вы можете использовать Win32 API под Windows, X11 API под Linux и Cocoa API под Mac; ну или воспользоваться другой высокоуровневой библиотекой, вроде SFML, FreeGLUT, SDL и т.д.

Что же, начем. В начале разберемся с зависимостями: нам потребуется некоторый базовый функционал для вывода сообщений в консоль:
// Подключение стандартных заголовков
#include <stdio.h>
#include <stdlib.h>

Далее подключаем GLEW. Эта библиотека предоставляет немного магии, но оставим это на потом:
// Подключение GLEW. Всегда подключайте его перед gl.h и glfw.h
#include <GL/glew.h>

Мы решили, что будем использовать GLFW для работы с окном и клавиатурой, поэтому подключаем и ее:
// Подключение GLFW
#include <GL/glfw3.h>

Следующая библиотека сейчас нам не понадобится, но она предоставляет функционал для работы с 3D математикой. Очень скоро она нам понадобится. В GLM нет никакой магии, если хотите — можете написать свою собственную библиотеку для работы с 3D математикой. Директива «using namespace» нужна для того, что бы можно было писать просто «vec3» вместо «glm::vec3»:
// Подключаем GLM
#include <glm/glm.hpp>
using namespace glm;

Если Вы скопировали вышеуказанный код в playground и попытались его запустить — то компилятор Вам сообщит, что нет функции main. Что же, давайте добавим ее:
int main() {

Для начала инициализируем GLFW:
// Инициализация GLFW
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; // В поставляемом исходном коде, эта переменная глобальная.
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; // Требуется при отладке ядра
if (glewInit() != GLEW_OK) {
    fprintf(stderr, "Failed to initialize GLEW\n");
    return -1;
}

Соберите этот код и запустите. Должно появиться черное окно и сразу закрыться. Ну конечно! Нам требуется подождать пока пользователь не нажмет Escape:

// Удостоверимся, что мы можем ловить нажатые клавиши
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

do{
    // Ничего не отрисовываем. Увидимся во 2 уроке!

    // Обновляем буффер
    glfwSwapBuffers(window);
    glfwPollEvents();

} // Проверяем, была ли нажата кнопка Esc или было закрыто окно?
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );

На этом заканчивается первый урок! Во 2 уроке Вы научитесь рисовать треугольник.
Поделиться с друзьями
-->

Комментарии (23)


  1. AllexIn
    28.07.2016 20:33
    +4

    ВСем рекомендую использовать SDL, если уж вы решили писать движок, а не игру.
    SDL поддерживается Steam, и SDL по сути единственный вариант, который позволит игре легко завестись практически на любом линуксе, где установлен Steam.

    Личный опыт:
    зарелизились на стиме под виндой и макосом. Начали портировать на линукс, немного обалдели от того, насколько сложно протащить все зависимости чтобы на линуксе завелось… Перепробовали несколько разных фреймворков. SDL не использовали до последнего, потому что лично у меня к нему была неприязнь и как core программист — я максимальнор долго откладывал интеграцию с SDL.
    Мы провозились неделю пробуя разные варианты.
    ПОтом за несколько часов воткнули SDL и на всех ОС у нас игра завелась без бубна и шаманства.


    1. Megaxela
      28.07.2016 20:50
      +1

      Частично соглашусь. SDL отличный фреймворк. Познакомился с ним, когда изучад Python (PyGame) и позже переехал на C++. Его архитектура сцен очень удобна. С тех пор упорно использовал SDL и даже попытался перейти на SDL 2. Позже решил посмотреть в сторону альтернатив. SFML слишком высокоуровневым для меня оказался. А комбинация, представленная в статье не просто дает возможность без шаманства делать какие-то очевидные вещи, но еще и предоставляем модули практически для всего. Начиная от матриц и функций, типа lookAt, заканчивая кватернионами.


      1. ozkriff
        29.07.2016 13:37

        SDL
        Его архитектура сцен очень удобна.

        У SDL есть понятие сцены? О.о


        1. Megaxela
          29.07.2016 13:55

          У самого SDL такого понятия, конечно же нет. Он слишком низкоуровневый для этого. Я подразумевал, что сцены используются в большинстве реализаций, использующих SDL.


    1. stavenko
      29.07.2016 10:01

      Для релизов под винду и мак вы использовали какие-то нативные библиотеки, или GLFW, как это делается статье?


      1. AllexIn
        29.07.2016 10:32

        Qt использовали.
        Я наивно полагал что его легко везде деплоить. :)


        1. stavenko
          29.07.2016 12:15

          Ого, я тоже оказывается наивный парень…
          Я удивлен, что именно под линукс у Вас появились проблемы…


    1. playermet
      29.07.2016 13:27

      SDL по сути единственный вариант, который позволит игре легко завестись практически на любом линуксе, где установлен Steam
      А какие есть проблемы с заведением glfw?


      1. AllexIn
        30.07.2016 15:58

        Не могу ответить на этот вопрос. Проблемы с деплоем не конспектировал.


    1. DmitryMry
      30.07.2016 15:49

      Напишите плиз, какие именно фреймворки вы пробовали. И SFML был среди них?


      1. AllexIn
        30.07.2016 15:55

        да почти всё что было известного на рынке на тот момент(три года назад). В том числе и SFML.


  1. bak
    28.07.2016 20:49
    +1

    Зачем публиковать перевод на хабр когда можно закомитить в репку на гитхабе и он будет доступен на сайте проекта среди остальных локализаций?


    1. bak
      28.07.2016 20:51
      +3

      Кстати говоря, переводы первых уроков уже есть (в частности, вот перевод этого) — лучше бы перевели один из более поздних, не локализованных.


      1. Megaxela
        28.07.2016 20:55

        Да, я думал об этом, но мне хотелось бы видеть набор всех уроков (я про переводы более поздних сталей). И не на каком-то сайте, который я за 2 года изучения OpenGL увидел впервые (скорее всего просто я криворукий), а на сайте, который имеет горздо больший обхват зрителей. И за 19 уроков явно много людей смогут ознакомится со всей серией уроков. Ну и наконец здесь есть комментарии, которые смогут дополнять статью или критиковать ее, что поможет «вставать на путь истинный»


  1. alexez
    28.07.2016 20:50
    +5

    Вот также интереснейший сайт для изучения Modern OpenGL — learnopengl.com.
    Также я не совсем понимаю почему для уроков по Modern OpenGL VBO стоит в «продвинутом» списке. Но всё равно спасибо за статью, она хоть может снизит желание у людей использовать glBegin/glEnd.
    Хотелось бы увидеть подобные статьи о Vulkan.


    1. Megaxela
      28.07.2016 20:51
      +1

      К слову GLFW поддерживает Vulkan API и возможно в будущем, если все удачно сложится напишу про Vulkan, но уже не перевод.


      1. snuk182
        29.07.2016 12:10
        +1

        Очень жду. Вменяемой инфы по вулкану почти нет. Попадаются даже фразы «Хотите разбираться в Vulkan — читайте Mantle, все взято оттуда».


    1. VBKesha
      28.07.2016 23:08

      Да про вулкан хотелось бы почитать.


  1. Megaxela
    29.07.2016 00:11

    По глупости дропнул комментарий от Alex_GDI с текстом:
    «Ну вот главное не забросьте) а то на хабре уже трое вот так начинали и бросили, у них правда поменьше уроков планировалось опубликовать чем у вас;)»

    Ответ:
    Пока планирую выпускать по 2 — 3 выпуска в неделю. Второй перевод уже готов, сейчас проверяю.


    1. TrueRiddik
      29.07.2016 15:09

      Присоединюсь к просьбе — только не забросьте, пожалуйста)


  1. Torvald3d
    29.07.2016 09:52
    +1

    По Vulkan API бы такие уроки…


  1. snuk182
    29.07.2016 14:39

    Кстати, а так и должно быть, что в содержании в Продвинутом и Всяком одни и те же пункты?


    1. Megaxela
      29.07.2016 16:39

      А, нет, так не должно быть. Моя слепота не заметила этого на 3 переводах. Исправил. Спасибо.