Opengl на с руководством

Время на прочтение
7 мин

Количество просмотров 294K

Здравствуйте. Несколько недель назад я начинал серию переводов статей по изучению OpenGL. Но на 4 статье один хабровчанин заметил, что мои переводы могут нарушать лицензию, по которой распространяются учебные материалы, предоставленные в исходной статье. И действительно, мои переводы нарушали лицензию. Для разрешения этой проблемы я обратился к авторам того набора уроков, но так и не смог добиться нормального ответа. По этой причине я связался с автором другого, не менее (а возможно даже и более) крутого, набора уроков по OpenGL: Joey de Vries. И он дал полное разрешение на перевод его набора уроков. Его уроки гораздо более обширные, чем прошлый набор, поэтому эти переводы растянутся на долго. И я обещаю, будет интересно. Заинтересовавшихся прошу под кат.

Также я встал на распутье: либо я опишу все основы вроде создания окна и контекста в одной статье, чтобы не плодить статьи, но в таком случае такую огромную статью не всякий осилит; либо я также как и раньше буду переводить, опираясь на иерархию оригинала. Я решил выбрать второй вариант.

На счет уроков по Vulkan: к сожалению мне тяжело сейчас написать уроки по данному API по причине скудной видеокарты на данный момент, которая просто не поддерживает Vulkan API, поэтому уроки по данному API будут только после обновления видеокарты.

Часть 1.1 — OpenGL

Вступление

Прежде чем мы начнем наше путешествие нам стоило бы разобраться что такое OpenGL. В основном под OpenGL понимают API (Интерфейс Программирования Приложений), который предоставляет большой набор функций, которые мы можем использовать для управления графикой и изображениями. Но на самом деле OpenGL это скорее спецификация, разработанная и поддерживаемая Khronos Group.

Спецификация OpenGL описывает каким будет результат выполнения каждой конкретной функции и что она должна делать. А уже реализация этих спецификаций лежит на плечах разработчиков. И поскольку спецификация не описывает детали реализации, соответственно имеют право на существование различные реализации OpenGL, по крайней мере пока они соответствуют спецификациям.

Люди, разрабатывающие OpenGL библиотеки, зачастую, являются производителями видеокарт. Каждая видеокарта, которую вы покупаете, поддерживает конкретные версии OpenGL из набора библиотек, разработанных для данной серии видеокарт. При использовании Apple системы, OpenGL библиотеки поддерживаются Apple, под Linux существуют комбинации версий от поставщиков и пользовательских адаптаций этих библиотек. Это также означает, что если используемая вами версия OpenGL показывает странное поведение, значит, с большой вероятностью — это ошибка производителей видеокарт.

Так как большинство реализаций разрабатываются производителями видеокарт, для исправления багов требуется обновить драйвера видеокарты. Это одна из причин, почему почти все уроки рекомендуют обновлять драйвера на видеокарту.

Khronos выложила в публичный доступ все спецификации для всех версий OpenGL. Заинтересовавшийся читатель может найти спецификации OpenGL 3.3 (именно эту версию OpenGL мы будем использовать) здесь. Спецификации отлично показывают правила работы всех функций.

Core-profile и Immediate mode (Мгновенный режим)

Раньше, использование OpenGL предполагало разработку в Immediate mode (также известен как фиксированный конвейер (fixed function pipeline)), которая была проста в использовании для рисования графики. Большинство функционала OpenGL было скрыто в библиотеках и у разработчиков не было свободы в понимании вычислений, производимых OpenGL.

Разработчики требовали большей гибкости в разработке и позже спецификация стала более гибкой, а разработчики получили больше контроля над процессом отрисовки их графики. Immediate mode был прост в использовании и понимании, но он был крайне неэффективным. По этой причине спецификация указала Immediate mode как устаревший, и начиная с версии 3.2 начала мотивировать программистов использовать Core-profile режим, который исключал весь устаревший функционал.

При использовании core-profile, OpenGL заставляет нас пользоваться современными практиками. Когда мы пытаемся использовать устаревшие функции, OpenGL выбрасывает ошибку и прекращает отрисовку. Преимущества использования современных практик — это гибкость и эффективность, но к сожалению бОльшая сложность в изучении. Immediate mode является бОльшей абстракцией и он скрывает большое количество реальной работы, выполняемой OpenGL и поэтому его было легко изучать, но трудно разобраться, как OpenGL на самом деле работает. Современный подход требует от разработчика полного понимания OpenGL и графического программирования в целом и хоть это немного сложнее, такая схема позволяет добиться большей гибкости, эффективности.

Это причина, почему наши уроки основаны на Core-Profile OpenGL версии 3.3.
Хоть он немного и сложнее, но это того стоит.

Сейчас уже вышли гораздо более новые версии OpenGL (на момент написания 4.5) и вы можете спросить: зачем мы должны изучать OpenGL 3.3, когда уже вышел 4.5? Ответ довольно прост. Все старшие версии OpenGL, начиная от версии 3.3 не добавляют различные полезные возможности без изменения основной механики. Новые версии просто предоставляют немного более эффективные или более удобные способы выполнения одних и тех же операций. В результате все концепты и техники, применимые к OpenGL 3.3 можно применить к новым версиям OpenGL.

Использование новейших версий OpenGL сопряжено с одной проблемой. Исполнять новейшие API смогут только современные видеокарты.

Расширения

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

Разработчику надо лишь проверить доступность расширения (или использовать библиотеку расширения). Такой подход позволяет программисту выполнять действия более эффективно, основываясь на имеющихся у него расширениях:

if(GL_ARB_extension_name)
{
    // Можно использовать новый функционал. Он поддерживается железом
}
else
{
    // Расширение не поддерживается: делаем по-старинке.
}

C OpenGL 3.3 нам редко будут нужны расширения, но когда будут нужны, необходимые инструкции будут предоставлены.

Конечный автомат

OpenGL по своей сути — это большой конечный автомат: набор переменных, определяющий поведение OpenGL. Под состоянием OpenGL в основном имеется ввиду контекст OpenGL. В процессе использования OpenGL, мы часто изменяем состояния, устанавливая некоторых опции, управляем буферами, а затем отрисовываем, используя текущий контекст.

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

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

Объекты

Библиотеки OpenGL написаны на C и имеют множественные ответвления, но в основном это C библиотека. Поскольку большинство конструкций из языка C не транслируется в высокоуровневые языки OpenGL был разработан с использованием большого количества абстракций. Одной из таких абстракций является система объектов в OpenGL.

Объект в OpenGL — это набор опций, которые представляют подмножество состояний OpenGL. К примеру мы можем создать объект, описывающий конфигурацию отрисовки окна; мы можем задать размер, количество цветов и так далее. Такой объект можно представить C-подобной структурой:


struct object_name {
    GLfloat  option1;
    GLuint   option2;
    GLchar[] name;
};

Примитивные типы
Заметьте, что при использовании OpenGL рекомендуется использовать примитивы, заданные OpenGL. Вместо использования float записывать его с приставной GL. Тоже самое для int, uint char, bool и так далее. OpenGL определяет разметку памяти для его GL примитивов для обеспечения кроссплатформенности, поскольку некоторые операционные системы могут иметь иную разметку. Использования OpenGL примитивов позволяет добиться полной кроссплатформенности вашего приложения.

Каждый раз, когда мы хотим использовать объекты в основном мы запишем это как-то так:

// OpenGL состояние
struct OpenGL_Context {
  	...
  	object* object_Window_Target;
  	...  	
};

// Создание объекта
GLuint objectId = 0;
glGenObject(1, &objectId);
// Привязка объекта к контексту
glBindObject(GL_WINDOW_TARGET, objectId);
// Установка значений опции объекта, привязанного к GL_WINDOW_TARGET
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH, 800);
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600);
// Установка цели контекста в значение по умолчанию
glBindObject(GL_WINDOW_TARGET, 0);

Этот небольшой участок кода — то, что вы будете часто встречать во время работы с OpenGL. В начале мы создаем объект и сохраняем ссылку на него в виде идентификационного номера (id). (Реальные данные объекта спрятаны в реализации). Затем мы привязываем объект к требуемой части контекста (Расположение целевого объекта окна из примера задано, как `GL_WINDOW_TARGET`). Затем мы устанавливаем значения опций окна и, в конце концов, отвязываем объект, установив id в 0. Значения, установленные нами продолжают храниться в объекте, доступ к которому мы можем получить через objectId и восстановить их снова привязав объект к GL_WINDOW_TARGET.

Данный код лишь показывает пример того, как работает OpenGL. В последствии будут представлены реальные примеры.

Основная фишка этих объектов состоит в том, что мы можем объявлять множество объектов в нашем приложении, задавать их опции и когда бы мы не запускали операции с использованием состояния OpenGL мы можем просто привязать объект с нашими предпочитаемыми настройками. К примеру этом могут быть объекты с данными 3D модели или нечто, что мы хотим на этой модели отрисовать. Владение несколькими объектами позволяет просто переключаться между ними в процессе отрисовки.

Давайте начнем

Теперь вы немного узнали про OpenGL как о спецификации, так и о библиотеке. Узнали примерный алгоритм работы и несколько особенностей, используемых OpenGL. Не расстраивайтесь, если что-то недопоняли, далее мы пошагово пройдемся по всем этапам и вы увидите достаточно примеров, чтобы разобраться во всех хитросплетениях OpenGL. Если вы уже готовы начать — то мы можем начать создавать OpenGL контекст и наше первое окно прямо тут.

Дополнительные ресурсы

  • opengl.org: оффициальный сайт OpenGL;
  • OpenGL registry: хранилище спецификаций OpenGL и всех его расширений для всех версий OpenGL.

Решили изучить OpenGL, но знаете, с чего начать? Сделали подборку материалов.

OpenGL (открытая графическая библиотека) — один из наиболее популярных графических стандартов для работы с графикой. Программы, написанные с её помощью можно переносить практически на любые платформы, получая одинаковый результат. OpenGL позволяет не писать программы под оборудование, а воспользоваться существующими разработками. Разрабатывает OpenGL компания Silicon Graphics, при сотрудничестве с другим технологическими гигантами.

С точки зрения программирования, OpenGL — это программный интерфейс для растровой графики, таких как графические ускорители. Он включает в себя около 150 различных команд, с помощью которых программист может определять различные объекты и производить рендеринг.

Материалы для изучения

Туториалы

  • Мини-курс от MIT;
  • Пособие от МГУ;
  • Туториалы от Gamedev.ru;
  • Переведённые туториалы от NeHe;
  • Туториал от learnopengl.com;
  • Туториалы с разделением на уровни.

Онлайн-курсы

  • Lynda — «Курс по OpenGL»;
  • Токийский университет — «Интерактивная компьютерная графика»;
  • Университет Сан-Диего — «Основы компьютерной графики».

Книги

На русском

1. Д. Шрайнер — OpenGL Redbook — скачать;

Книга — официальное руководство по изучению OpenGL. Последние издания практически полностью отличаются от первоначальных вариантов, автор обновляет её в соответствии с изменениями версий. По мнению сотен специалистов, работающих с Open GL, эта книга является первым, что должен взять в руки желающий изучить технологию.

2. Д. Вольф — Open GL 4. Язык шейдеров. Книга рецептов (2015) — скачать;

«OpenGL»

В этой книге рассматривается весь спектр приемов программирования на GLSL, начиная с базовых видов шейдеров – вершинных и фрагментных, – и заканчивая геометрическими, вычислительными и шейдерами тесселяции. Прочтя ее, вы сможете задействовать GPU для решения самых разных задач.

3. Д. Гинсбург — OpenGL ES 3.0. Руководство разработчика (2014) — купить;

В данной книге автор рассматривает весь API и язык для написания шейдеров. Также вы найдете советы по оптимизации быстродействия, максимизации эффективности работы API и GPU и полном использовании OpenGL ES в широком спектре приложений.

4. В. Порев — Компьютерная графика (2002) — скачать;

«Порев»

В книге рассмотрены способы работы с компьютерной графикой, частые проблемы, приведены примеры программ на C++.

На английском

1. П. Ширли — Основы компьютерной графики (2009) — скачать;

Книга предназначена для введение в компьютерную графику на базовом уровне. Авторы рассказывают про математические основы компьютерной графики с акцентом на то, как применять эти основы для разработки эффективного кода.

2. Э. Ангел — Интерактивная компьютерная графика — купить;

Эта книга предназначена для всех студентов, изучающих информатику и программирование углубленно. Компьютерная анимация и графика — уже не так сложно, как раньше. Следуя своему утверждению, автор написал книгу максимально понятным языком.

3. Г. Селлерс — Супербиблия Open GL (2015) — купить.

Последнее издание книги является полноценным учебником по Open GL 4.5. Это руководство затрагивает полный аспект современной разработки и является одним из наиболее рекомендуемых профессионалами.

Дополнительно

По ссылке книги по теме с популярного форума.

Полезные ресурсы

  • Примеры;
  • Исходники и описания;
  • Документация;
  • Движок для разработки;
  • Библиотеки.

Возможно вас заинтересует следующая статья:

  • Разработка игр – это просто: 12 этапов изучения геймдева

Уроки по OpenGL

Независимо от того, пытаетесь ли вы изучить OpenGL в образовательных/карьерных целях или просто ищете новое хобби, эти бесплатные уроки по графическому программированию научат вас основам и всем необходимым деталям работы с OpenGL. Цель этого туториала — показать вам всё, что есть в современном OpenGL, простым для понимания способом с наглядными примерами, а также предоставить бэкграунд для ваших последующих исследований/углублений в эту тему.

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

Все уроки по OpenGL/C++ — https://ravesli.com/uroki-po-opengl/.

Чему вы научитесь?

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

Поскольку OpenGL является графическим API, а не, собственно, платформой, то для работы с ним потребуется язык программирования. В нашем случае, это язык C++, поэтому вам понадобятся знания по C++. Вам не обязательно быть экспертом по C++, но вы должны уметь написать что-то большее, чем программу «Hello, world!». Для получения дополнительных знаний отлично подойдут уроки по С++ на Ravesli — https://ravesli.com/uroki-cpp/, где каждая тема объясняется отдельным уроком и куда вы всегда сможете обратиться за детальным разъяснением.

Структура уроков

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

Удачи!

Введение в OpenGL на Qt/C++. Часть 1.

В данном уроке мне хотелось бы изложить основы программирование графики с использованием OpenGL на платформе Qt/C++.
Первая часть является вводной, и для понимания материала читателю достаточно понимать основы программирования на С++.

Чтобы подключить OpenGL в Qt достаточно в файле проекта (*.pro) прописать

Мы создадим класс Widget, в котором и будет производится отрисовка.
Рисовать мы будем квадрат в 3d пространстве. В следующей части мы научимся его вращать и приближать.

Создаваемый класс должен наследоваться от QGLWidget.

class Widget: public QGLWidget
{
};

Теперь нам надо переобпределить некоторые методы:
1) void initializeGL();
2) void resizeGL(int nWidth, int nHeight);
3) void paintGL();

Первый метод инициализирует само окно, второй вызывается при изменении размеров окна, а в третьем реализовывается сама отрисовка.

Так как кода получается не очень много, приведу сразу весь:

#include "widget.h"
 
Widget::Widget(QWidget *parent) // конструктор
    : QGLWidget(parent)
{
    resize(300,300); // задаем размеры окна
}
 
void Widget::initializeGL()
{
   qglClearColor(Qt::white); // заполняем экран белым цветом
   glEnable(GL_DEPTH_TEST); // задаем глубину проверки пикселей
   glShadeModel(GL_FLAT); // убираем режим сглаживания цветов
   glEnable(GL_CULL_FACE); // говорим, что будем строить только внешние поверхности
   glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); // фигуры будут закрашены с обеих сторон
}
 
void Widget::resizeGL(int nWidth, int nHeight)
{
    glViewport(0, 0, nHeight, nHeight); // установка точки обзора
    glMatrixMode(GL_PROJECTION); // установка режима матрицы
    glLoadIdentity(); // загрузка матрицы
}
 
void Widget::paintGL() // рисование
{
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // очистка экрана
   glMatrixMode(GL_MODELVIEW); // задаем модельно-видовую матрицу
   glLoadIdentity();           // загрузка единичную матрицу
 
   QColor halfGreen(0, 128, 0, 255); // устанавливаем цвет квадрата
   qglColor(halfGreen); // задаем цвет
   glBegin(GL_QUADS); // говорим, что рисовать будем прямоугольник
   // задаем вершины многоугольника
   glVertex3f(0.5, 0.5, 0.5);
   glVertex3f(-0.5, 0.5, 0.5);
   glVertex3f(-0.5, -0.5, 0.5);
   glVertex3f(0.5, -0.5, 0.5);
   glEnd();
 
}

Вот и всё, несложными манипуляциями мы отрисовали квадрат в 3d пространстве с помощью OpenGL.
Теперь в файле main.cpp создаем экземпляр нашего класса и вызываем метод отображения.
Все исходники можно скачать в прикрепленных к статье материалах.

Пример работы программы:

Прикрепленный файл Размер
KatyaOGL_pt1.zip 1.53 кб

Понравилась статья? Поделить с друзьями:
  • Сириус 21л руководство по эксплуатации
  • Милур 107 инструкция по снятию показаний
  • Сириус омп руководство по эксплуатации
  • Частотник shihlin инструкция на русском языке
  • Поздравление руководства с днем текст