[Перевод] OpenGL-Tutorial. Урок 1. Создание окна
Если появляется желание начать изучать OpenGL — то чаще всего натыкаешься на уроки NeHe и сразу начинаешь с устаревшего OpenGL. Но в интернете есть хороший набор уроков по новому OpenGL 3.3, поддерживаемый сообществом. Сам набор разделен на 3 группы: Базовые уроки, Продвинутые уроки и Всякое. Я постараюсь выпускать по статье на каждый урок, а в начале каждой статьи буду оставлять небольшое содержание. Спасибо.
Содержание
Базовые уроки:
- Урок 1. Создание окна
- Урок 2. Первый треугольник
- Урок 3. Матрицы
- Урок 4. Цветной куб
- Урок 5. Текстурированный куб
- Урок 6. Клавиатура и мышь
- Урок 7. Загрузка моделей
- Урок 8. Базовый шейдинг
Продвинутые уроки:
- Урок 9. VBO индексация
- Урок 10. Прозрачность
- Урок 11. 2D текст
- Урок 12. OpenGL расширения
- Урок 13. Normal Mapping
- Урок 14. Отрисовка на текстуру
- Урок 15. Lightmaps
- Урок 16. Shadow mapping
- Урок 17. Вращение
- Урок 18.1. «Билборды»
- Урок 18.2. Частицы
Всякое:
- Урок 9. VBO индексация
- Урок 10. Прозрачность
- Урок 11. 2D текст
- Урок 12. OpenGL расширения
- Урок 13. Normal Mapping
- Урок 14. Отрисовка на текстуру
- Урок 15. Lightmaps
- Урок 16. Shadow mapping
- Урок 17. Вращение
- Урок 18.1. «Билборды»
- Урок 18.2. Частицы
Вступление
Добро пожаловать в первый урок.
Прежде чем перейти к 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
#include
Далее подключаем GLEW. Эта библиотека предоставляет немного магии, но оставим это на потом:
// Подключение GLEW. Всегда подключайте его перед gl.h и glfw.h
#include
Мы решили, что будем использовать GLFW для работы с окном и клавиатурой, поэтому подключаем и ее:
// Подключение GLFW
#include
Следующая библиотека сейчас нам не понадобится, но она предоставляет функционал для работы с 3D математикой. Очень скоро она нам понадобится. В GLM нет никакой магии, если хотите — можете написать свою собственную библиотеку для работы с 3D математикой. Директива «using namespace» нужна для того, что бы можно было писать просто «vec3» вместо «glm: vec3»:
// Подключаем GLM
#include
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 уроке Вы научитесь рисовать треугольник.
Комментарии (9)
28 июля 2016 в 20:33
+3↑
↓
ВСем рекомендую использовать SDL, если уж вы решили писать движок, а не игру.
SDL поддерживается Steam, и SDL по сути единственный вариант, который позволит игре легко завестись практически на любом линуксе, где установлен Steam.Личный опыт:
зарелизились на стиме под виндой и макосом. Начали портировать на линукс, немного обалдели от того, насколько сложно протащить все зависимости чтобы на линуксе завелось… Перепробовали несколько разных фреймворков. SDL не использовали до последнего, потому что лично у меня к нему была неприязнь и как core программист — я максимальнор долго откладывал интеграцию с SDL.
Мы провозились неделю пробуя разные варианты.
ПОтом за несколько часов воткнули SDL и на всех ОС у нас игра завелась без бубна и шаманства.28 июля 2016 в 20:50
+1↑
↓
Частично соглашусь. SDL отличный фреймворк. Познакомился с ним, когда изучад Python (PyGame) и позже переехал на C++. Его архитектура сцен очень удобна. С тех пор упорно использовал SDL и даже попытался перейти на SDL 2. Позже решил посмотреть в сторону альтернатив. SFML слишком высокоуровневым для меня оказался. А комбинация, представленная в статье не просто дает возможность без шаманства делать какие-то очевидные вещи, но еще и предоставляем модули практически для всего. Начиная от матриц и функций, типа lookAt, заканчивая кватернионами.
28 июля 2016 в 20:49
+1↑
↓
Зачем публиковать перевод на хабр когда можно закомитить в репку на гитхабе и он будет доступен на сайте проекта среди остальных локализаций?28 июля 2016 в 20:51
+3↑
↓
Кстати говоря, переводы первых уроков уже есть (в частности, вот перевод этого) — лучше бы перевели один из более поздних, не локализованных.28 июля 2016 в 20:55
0↑
↓
Да, я думал об этом, но мне хотелось бы видеть набор всех уроков (я про переводы более поздних сталей). И не на каком-то сайте, который я за 2 года изучения OpenGL увидел впервые (скорее всего просто я криворукий), а на сайте, который имеет горздо больший обхват зрителей. И за 19 уроков явно много людей смогут ознакомится со всей серией уроков. Ну и наконец здесь есть комментарии, которые смогут дополнять статью или критиковать ее, что поможет «вставать на путь истинный»
28 июля 2016 в 20:50 (комментарий был изменён)
+2↑
↓
Вот также интереснейший сайт для изучения Modern OpenGL — learnopengl.com.
Также я не совсем понимаю почему для уроков по Modern OpenGL VBO стоит в «продвинутом» списке. Но всё равно спасибо за статью, она хоть может снизит желание у людей использовать glBegin/glEnd.
Хотелось бы увидеть подобные статьи о Vulkan.28 июля 2016 в 20:51
+1↑
↓
К слову GLFW поддерживает Vulkan API и возможно в будущем, если все удачно сложится напишу про Vulkan, но уже не перевод.28 июля 2016 в 23:08
0↑
↓
Да про вулкан хотелось бы почитать.
29 июля 2016 в 00:11 (комментарий был изменён)
0↑
↓
По глупости дропнул комментарий от Alex_GDI с текстом:
«Ну вот главное не забросьте), а то на хабре уже трое вот так начинали и бросили, у них правда поменьше уроков планировалось опубликовать чем у вас;)»Ответ:
Пока планирую выпускать по 2 — 3 выпуска в неделю. Второй перевод уже готов, сейчас проверяю.