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

  Юрий  | 

  Обновл. 30 Мар 2020  | 

 10007

 ǀ   6 

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

Что такое OpenGL?

OpenGL (англ. «Open Graphics Library») в основном рассматривается как API (англ. «Application Programming Interface» = «Интерфейс прикладного программирования»), который предоставляет большой набор функций, которые мы можем использовать для управления графикой и изображениями. Если конкретнее, то OpenGL является спецификацией, разработанной и поддерживаемой Khronos Group.

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

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

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

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

Core-profile vs. Непосредственный режим


В старые времена использование OpenGL означало разработку в непосредственном режиме (ещё называемом «конвейером фиксированных функций»), который был простым в использовании методом для рисования графики. Большая часть функционала OpenGL была скрыта внутри библиотеки, и разработчики не имели контроля над тем, как OpenGL выполняет свои вычисления. Поскольку разработчики жаждали большей гибкости, то со временем спецификации стали более гибкими; разработчики получили больше контроля над своей графикой. Непосредственный режим действительно прост в использовании и понимании, но он также крайне неэффективен. По этой причине, начиная со спецификации версии 3.2, функционал непосредственного режима начали считать устаревшим, мотивируя тем самым разработчиков перейти на разработку в режиме core-profile, который является разделом спецификации OpenGL, удаливший весь устаревший функционал.

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

Это также одна из причин, по которой этот туториал более ориентирован на core-profile в OpenGL версии 3.3. Хотя это сложнее, но оно того стоит.

На сегодняшний день доступны более новые версии OpenGL (на момент написания — 4.6), поэтому следует логичный вопрос: «Почему я должен изучать OpenGL 3.3, когда уже есть OpenGL 4.6?». Дело в том, что все последующие версии OpenGL, начиная с 3.3, добавляют дополнительные полезные фичи в OpenGL без изменения фундаментального ядра/базиса, используемого в OpenGL; более новые версии просто предоставляют несколько более эффективных или полезных способов решения одних и тех же задач. В результате все концепции и техники остаются неизменными при выходе новых версий OpenGL, поэтому изучение OpenGL 3.3 является совершенно справедливым.

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

Расширения в OpenGL

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

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

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

Состояния в OpenGL


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

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

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

Объекты в OpenGL

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

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

Всякий раз, когда мы хотим использовать объекты, они обычно выглядят следующим образом (с визуализацией контекста OpenGL как большой структуры):

Затем:

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

Преимуществом использования объектов является то, что мы можем определить более одного объекта в нашем приложении, установить их параметры и всякий раз, когда мы запускаем операцию, которая использует состояние OpenGL, мы связываем объект с нашими предпочтительными настройками. Например, есть объекты-контейнеры для хранения данных 3D-модели (Дом или Персонаж), и всякий раз, когда мы хотим нарисовать эту 3D-модель, мы связываем объект, содержащий данные модели, которую мы хотим нарисовать (перед этим создав и установив параметры для этих объектов). Наличие нескольких объектов позволяет нам указывать множество моделей, и всякий раз, когда мы хотим нарисовать конкретную модель, то перед рисованием мы просто связываем соответствующий объект (не устанавливая для него все параметры с нуля).

Заключение


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

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

   opengl.org: официальный сайт OpenGL.

   Реестр OpenGL: содержит спецификации и расширения OpenGL для всех версий OpenGL.

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (37 оценок, среднее: 5,00 из 5)
Загрузка...

Комментариев: 6

  1. Аватар Peter:

    Юрий, (OMG) OpenGL! В интернете почти нет информации об этой библиотеке, либо она очень плохо подана. А по SFML у вас на сайте уже есть гайды по тому что надо, а остальное вполне можно найти на оф. сайте, либо из туториалов (к примеру на youtube — канал Saraj Sharman — швед, но нормально на английском чё — то объясняет + делает игру на SFML ). И я хочу сказать, что если вы будете делать дальше гайды по этой трудной, но очень эффективной и мощной библиотекой (которая ещё и может работать адекватно с 3D графикой!), то это будет очень круто. Я надеюсь, что этот раздел вы тоже постараетесь завершить(как и главный раздел — уроки C++)! F

    1. Юрий Юрий:

      Спасибо за столь развёрнутый отзыв, мне приятно. + я тоже надеюсь, что смогу завершить этот туториал))

  2. Аватар Андрей:

    Спасибо огромное вам за то, что создали этот сайт. Сейчас в интернете конечно много ресурсов по программированию, но ваш — самый лучший.

    1. Юрий Юрий:

      Спасибо, мне приятно)

    2. Аватар Peter:

      Согласен. но я бы сказал не только лучший, но и вообще почти единственный, у которого всё на высшем качестве.

  3. Аватар Арбузик❤❤❤:

    Ура! Это именно то, чего я ждал!

Добавить комментарий для Андрей Отменить ответ

Ваш E-mail не будет опубликован. Обязательные поля помечены *