Урок 1. Введение

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

Что нужно знать


Данные уроки ориентируются на читателя без особых познаний в программировании. Конечно, знание какого-либо языка программирования(C, Java, Lisp, JavaSript) будет огромным плюсом, но это не обязательно, просто вам придется изучать два предмета одновременно – 3д графику и программирование.
Весь код в данных уроках написан на C++ в максимально простом стиле. Никаких шаблонов, классов и арифметики с указателями. Поэтому глядя на код вы сможете понять что он делает, даже если знакомы лишь с JavaSript.

Забудьте все, что знали про OpenGL 1/2


Данные уроки предполагают, что вы ничего не знаете про 3д графику. Но если вы читали уроки по OpenGL и встречали что-то наподобие glBegin(),то забудьте это. Тут мы будем изучать OpenGL 3 и 4, а то, что вы читали относиться к OpenGL 1 или 2. Поэтому рекомендую вам забыть все, что вы знали раньше, иначе ваши мозги начнут плавиться от нестыковок.


Сборка проекта


Код из данных уроков можно скомпилировать под Windows, Linux. Чтобы начать компилировать код под любую из платформ, нужно сделать следующее:
  1. Обновите драйвера на вашу видеокарту!! Я вас предупредил:)
  2. Скачайте компилятор, если у вас его еще нет.
  3. Установите CMake
  4. Скачайте готовые исходники уроков.
  5. Сгенерируйте проект с помощью CMake
  6. Соберите проект.
  7. Поэкспериментируйте с кодом для лучшего понимания, что там происходит.

Ниже я привел более детализированное описание сборки проектов под каждую из платформ. Но в зависимости от версии ОС скриншоты могут слегка отличатся от того, что будет у вас на экране, но в целом, все должно быть приблизительно таким.


 Сборка под Windows


  1. Обновление драйверов для видеокарты под Windows обычно не представляет больших проблем. Вам просто нужно перейти на сайт NVIDIA или AMD и скачать драйвера оттуда. Если вы не знаете какая у вас видеокарта, просто щелкните правой кнопкой мыши на Мой Компьютер, и выберите там «Свойства», оттуда зайдите в «Диспетчер устройств», и в разделе «Видеоадаптеры» будет модель вашей видеокарты.
  2. В качестве компилятора и IDE рекомендую Visual Studio 2010 Express, её можно закачать отсюда. Если вы предпочитаете MinGW, рекомендую вам QT Creator. Вы можете установить любую IDE какую захотите, но подробное описание что да как будет лишь для Visual Studio.
  3. Закачайте CMake и установите его.
  4. Скачайте исходники и распакуйте их в любую папку, например C:\Users\XYZ\Projects\OpenGLTutorials\.
  5. Запустите CMake. В первое поле ввода впишите путь к разархивированной папке. Если вы неуверенны, выберите папку, которая содержит файл CMakeLists.txt. Во второй строчке нужно указать папку, где будут храниться временные файлы созданные компилятором при компилировании наших исходных кодов. Вы можете указать любую папку.
  6. Кликните на кнопке «Configure». Так как это первая конфигурация проекта, CMake спросит вас какой компилятор вы хотите использовать. Выбор зависит от шага 2. Если у вас Windows x64, вы можете выбрать 64bits, если вы не уверены, то выбирайте 32.
  7. Щелкайте на кнопке «Configure» пока не пропадут все красные линии. Потом кликните на кнопке Generate. После этого у вас будет сгенерирован проект для Visual Studio. На этом этапе можно забыть про CMake или даже удалить его.
  8. В папке со сгенерированным проектом найдите файл Tutorials.sln и откройте его с помощью Visual Studio.
  9. В меню Build кликните на Build All. После этого должны будут скомпилироваться(надеюсь:) ) все примеры со всеми зависимостями. После этого можно попробовать запустить C:\Users\XYZ\Projects\OpenGLTutorials\playground\playground.exe. И вы увидите окно с черным фоном


Сборка под Linux


В мире существует громадное число разных вариаций линукса, поэтому мне совсем не хочется приводить примеры сборки проекта под каждую. Если что-то не получается, как написано ниже, почитайте документацию, или поищите в интернете.

  1. Установите последние драйвера на вашу видеокарту. Очень рекомендую не опенсорсные драйвера. Они не входят в состав GNU, но они часто работают гораздо лучше. Если ваша сборка линукса не предоставляет автоматического  инсталлятора, попробуйте почитать Ubuntu's guide.
  2. Поставьте компилятор со всеми необходимыми библиотеками и инструментами. Вот список того, что вам нужно: cmake make g++ libx11-dev libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxext-dev. Используйте sudo apt-get install ***** или su/yum install ******
  3. Скачайте исходники примеров и разархивируйте их в папку, например, ~/Projects/OpenGLTutorials/
  4. Зайдите в папку ~/Projects/OpenGLTutorials/ и введите следующие команды:
  •   mkdir build
  • cd build
  • cmake .. 

  1. Если предыдущие команды были выполнены успешно, то в папке build/ будет создан makefile
  2. введите «make all» и после этого будут скомпилированы все примеры и их зависимости. Если не будет никаких ошибок, то готовые исполняемые файлы будут помещены в папку ~/Projects/OpenGLTutorials/

Мне очень нравится использовать IDE QtCreator. Данная IDE умеет из коробки работать с CMake и предоставляет кучу других плюшек, таких как отладка автодополнение итд.

Инструкция по сборке проекта в QtCreator:

1.      В QtCreator нажмите File->Tools->Options->Compile&Execute->CMake
2.      Укажите путь к CMake. Скорее всего, это будет /usr/bin/cmake
3.      File->Open Project и выберите tutorials/CMakeLists.txt
4.      Укажите build папку, папка желательно должна быть вне папки tutorials.
5.      Опционально установите –DCMAKE_BUILD_TYPE=Debug в поле параметры.
6.      Щелкните на молоток внизу. После этого примеры можно будет запустить из папки tutorials/
7.      Чтобы запустить примеры из QtCreator выберите Projects->Execution parameters->Working Directory, и выберите каталог где лежат шэйдеры текстуры и модели. Для урока 2 это будет ~/opengl-tutorial/tutorial02_red_triangle/


Запуск примеров

После того, как проект будет скомпилирован, приложения можно будет запускать прямо из каталога.
Если нужно запускать примеры прямо из-под IDE, воспользуйтесь инструкцией приведенной выше, чтобы правильно установить рабочий каталог.

Как проходить эти уроки


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

Пока вы будете читать эти уроки, вам везде будут попадаться кусочки кода. Не стесняйтесь и копируйте их в playground.cpp чтобы пощупать их в действии – эксперименты, это всегда хорошо. Повторю еще раз, не просто читайте готовый код, а пробуйте его запустить. Просто читая исходники, вы не научитесь многому. Даже с простым копипастингом вы получите свой ковш проблем, решая которые, приобретете необходимый опыт.


Открываем окно


Наконец-то! OpenGL!
Хотя, придется еще немного подождать. Во всех уроках 3д операции будут выполнятся на очень низком уровне, поэтому там не будет для вас никакой магии. Однако работа с окнами и сообщениями системы не интересная и скучная, поэтому мы позволим библиотеке GLFW сделать всю грязную работу за нас. Если вам конечно очень сильно хочется, вы можете использовать Win32 Api для Windows или X11 API для Linux, или использовать что-нибудь другое, типа SFML, FreeGLUT, SDL, … почитайте страничку ссылки.
Ладно, давайте уже начнем. Начнем с того, что нам нужно подключить зависимости. Так как нам необходимо выводить сообщения на консоль, мы напишем следующее:

// Подключаем стандартные заголовки
#include <stdio.h>
#include <stdlib.h>
Потом подключаем GLEW
// Нужно не забывать, что  GLEW обязательно необходимо подключать перед gl.h или glfw.h
#include <GL/glew.h>

Потом подключаем GLFW. Эта библиотека будет делать всю магию управления окнами.
#include <GL/glfw.h>

На данном этапе нам не нужна эта библиотека, но она содержит математические функции и вскоре нам понадобится. Никакой магии в GLM нет, и если вам сильно хочется, вы можете использовать любую другую библиотеку по работе с матрицами и векторами. Мы подключаем «using namespace» для того, чтобы писать «vec3», а не «glm::vec3»
#include <glm/glm.hpp>
using namespace glm;

Если вы скопируете эти куски кода в playground.cpp, то компилятор начнет возмущаться, что нет функции main(). Поэтому давайте добавим:
int main(){

Сначала лучше бы инициализировать GLFW:
// Инициализируем GLFW
if( !glfwInit() )
{
    fprintf( stderr, "Failed to initialize GLFW\n" );
    return -1;
}

А теперь создадим наше OpenGL окошко:
glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 4); // 4x сглаживание
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); // нам нужен OpenGL 3.3
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);
glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //нам не нужен старый OpenGL
// Откроем окно и создадим контекст
if( !glfwOpenWindow( 1024, 768, 0,0,0,0, 32,0, GLFW_WINDOW ) )
{
    fprintf( stderr, "Failed to open GLFW window\n" );
    glfwTerminate();
    return -1;
}

// Инициализируем GLEW
glewExperimental=true; 
if (glewInit() != GLEW_OK) {
    fprintf(stderr, "Не удается инициализировать GLEW\n");
    return -1;
}

glfwSetWindowTitle( "Урок 01" );

Соберите проект и запустите. Должно появится окошко и тут же закрыться. Ну конечно же! Нам нужно подождать пока пользователь не нажмет кнопку Escape.
// Включим обработку кнопок
glfwEnable( GLFW_STICKY_KEYS );

do{
    // Ничего не рисуем !
    // Меняем буффер
    glfwSwapBuffers();

} // Проверяем Escape на нажатие, или пользователь вручную закрыл окно
while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS &&
glfwGetWindowParam( GLFW_OPENED ) );

На этом наш урок заканчивается. В уроке 2 я покажу вам как нарисовать ваш первый OpenGL треугольник.

21 комментарий:

  1. подскажите, пожалуйста, где найти исходники??

    ОтветитьУдалить
  2. Исходники можно скачать с оригинального сайта:
    http://www.opengl-tutorial.org/download/

    ОтветитьУдалить
  3. Спасибо за проделанную работу!
    Но есть вопрос.
    Я скомпилировал уроки и они работают.
    Но мне б хотелось создать проект с нуля в vs2012
    как я делаю Файл-создать-проект-с++-пустое приложение-добавляю файл main.cpp в него копирую код первого урока библиотеки он находит подгружает зависимости.
    но скомпилировать не удается
    main.obj : error LNK2019: ссылка на неразрешенный внешний символ __imp__glClearColor@16 в функции _main
    1>main.obj : error LNK2019: ссылка на неразрешенный внешний символ __imp__glewInit@0 в функции _main
    1>main.obj : error LNK2019: ссылка на неразрешенный внешний символ _glfwInit в функции _main
    1>main.obj : error LNK2019: ссылка на неразрешенный внешний символ _glfwTerminate в функции _main
    1>main.obj : error LNK2019: ссылка на неразрешенный внешний символ _glfwOpenWindow в функции _main
    1>main.obj : error LNK2019: ссылка на неразрешенный внешний символ _glfwOpenWindowHint в функции _main
    1>main.obj : error LNK2019: ссылка на неразрешенный внешний символ _glfwSetWindowTitle в функции _main
    1>main.obj : error LNK2019: ссылка на неразрешенный внешний символ _glfwSwapBuffers в функции _main
    1>main.obj : error LNK2019: ссылка на неразрешенный внешний символ _glfwGetWindowParam в функции _main
    1>main.obj : error LNK2019: ссылка на неразрешенный внешний символ _glfwGetKey в функции _main
    1>main.obj : error LNK2019: ссылка на неразрешенный внешний символ _glfwEnable в функции _main
    выдает такие ошибки
    посмотрев свойства проекта 1 урока
    добавлял в свой зависимости в линкер либы и что еще только не делал
    помогите пожалуйста

    ОтветитьУдалить
  4. Можно попробовать добавить где-нибудь вначалеЖ
    #pragma comment(lib, "opengl32.lib")

    ОтветитьУдалить
  5. Дмитрий Савченко
    спасибо стало лучше но не до конца
    >main.obj : error LNK2019: ссылка на неразрешенный внешний символ __imp__glewInit@0 в функции _main
    1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.CppCommon.targets(611,5): error MSB6006: "link.exe" завершилась с кодом 1120.
    1>D:\OpenGL\FeerstBlood\fb\Debug\fb.exe : fatal error LNK1120: неразрешенных внешних элементов: 1

    ОтветитьУдалить
  6. я добавил в линкер kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;glu32.lib;opengl32.lib;external\Debug\GLFW_276.lib;external\Debug\GLEW_190.lib;glu32.lib;opengl32.lib эти либы взял из 1ого урока

    ОтветитьУдалить
  7. тебе нужно еще прилинковать glew32.lib, или glew32s.lib, если не хочется тянуть за собой зависимость glew32.dll

    ОтветитьУдалить
  8. Огромнейшее спасибо заработало!!!
    извините за наглость еще 2 вопроса
    1 как Вы определяете зависимости какие либы надо добавлять
    2 можно будет ли задавать вам еще вопросы ?

    ОтветитьУдалить
  9. 1. Элементарно
    Вот у нас есть ошибка линковки ">main.obj : error LNK2019: ссылка на неразрешенный внешний символ __imp__glewInit@0 в функции _main."
    Гораздо лучше использовать вижл студию на английском, а потом тупо копировать ошибку в гугл. Но даже так "__imp__glewInit" подойдет. Очень часто помогает.
    Вариант 2. Посмотреть поближе на функцию "__imp__glewInit". Очевидно, что что-то связанное с glew. значит ищем где у нас есть либы и просто сделать полнотекстовый поиск по папке с файлами .lib, и файлы которые содержат искомое слово, скорее всего есть необходимыми нам либами.

    2. Можно:) Но реально я в OpenGL не так уж и шарю. Я вообще программист Java, а тут приглянулись статейки по Оглю вот и перевел все

    ОтветитьУдалить
  10. Подскажите пожалуйста, какие нужны зависимости и откуда их скачать?

    ОтветитьУдалить
  11. А никто не подскажет где можно найти хорошего репетитора по OpenGL?

    ОтветитьУдалить
  12. что делать в данной ситуации

    LINK : fatal error LNK1104: не удается открыть файл "external\glfw-3.1.2\src\Debug\glfw3.lib"

    ОтветитьУдалить
  13. посмотри наличие файла по даному адресу

    ОтветитьУдалить
  14. Этот комментарий был удален автором.

    ОтветитьУдалить
  15. Привет всем, я проделал всё, как тут сказано, но у меня не работают эти строки:glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 4); // 4x сглаживание
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); // нам нужен OpenGL 3.3
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);
    glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //нам не нужен старый OpenGL
    // Откроем окно и создадим контекст.
    как я понял, нужно подключить файл glfw3.h, но студия не находит его. подскажите пожалуйста, уже второй час бьюсь

    ОтветитьУдалить
  16. Здравствуйте! Не могли бы посоветовать литературу по GLFW/GLEW/GLM?

    ОтветитьУдалить