Opengl руководство по программированию библиотека

Файл «OpenGL. Руководство по программированию (Библиотека программиста) (2006). Ву М., Девис Т., Нейдер Дж., Шрайнер Д» внутри архива находится в папке «Раздаточные материалы». PDF-файл из архива «Раздаточные материалы»,
который расположен в категории «».
Всё это находится в предмете «инженерная графика» из 5 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова.
Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .

° ~ ° М.:Ву, Т. Девис, Дж. Нейдер, Д. Шрайнер ‘;е Базовые и донелнителыме методы компыптерней графики Повышение производительности программ ~»; Расширения, создание кросс-платфпрмпых приложений е Последние обновления языка Ореп6Е е иклипте ж п~ пп с ммист М. Ву, Т. Девис, Дж. Нейдер, Д. Шрейнер 4. Рцкаведатва -. -в па пюегваммиДеванив Москва ° Санкт-Петербург Нижний Новгород ° Воронеж Ростов-на-Дону ° Екатеринбург ° Самара Новосибирск Киев Харьков Минск 2006 ББК 32.973-018.3 УДК 004.92 Шбб ВУ Мм ДЕВИС Тм НЕйДЕР Джм ШРайНЕР Д. Ш85 Ореола.

Руководство по программированию. Библиотека программиста, 4-е издание. — СПбх Питер, 2006. — 624 сл ил. 1ЗВМ 8-94723-827-8 Зто 4-с юдание признанного бестселлера, посвященного ОрелОБ и его библиотеке инструментов. В книге описаны все возможности ОрепОБ и самые значительные приложения, содержится описание бмовых методов компьютерной графики, таких как построение и воспроизведение трехмерных модедей, интерактивный просмотр объектов с различных точек наблюдения, использование тонирования, освещения и эффектов текстурирования. Прелставлсно углубленное описание дополнительных методов компьютерной графики: наложение текстур, сглаживание, «туман» и имитация других атмосферных эффектов, сплайны, конвейерная обработка изображений и другие ключевые темы, такие как повышение производительности программ, расширения ОрепОВ и создание кросс-платформных приложений.

ББК 32.973-018 3 УДК 004.92 Права на издание полу сны по соглашению с Асфзопштвзшу со«сшил все права заимщены. Ни«виан шст«двиной «нити не меже~ быть воспроизведена в шкод бы пз ни было форме без пис»менного рвзрешеню влацельцев авторсиих прав. Информация, ссдеркшщаяся е данной книге, получена из источников. рассматриваемых издагеп«от«ем иак падежные тем нв менее. имея в виду возможные челове««сине или твкничвские ошибки, издательство не может гврвнтироват«абсолютную то«ноет«н полноту прнводиммк сведений и не «есет ответственности за возможныв ошибии, связанные с испопыоввнием книги О 2004 Оу Масон Огарюса, 1пс. Гав 0321173481 (англ ) О Перевод на русский язык, ЗАО Издательский дом «Питер», 2006 ГВВН 6-04723-827-6 О Издание на русс«ом языке, оформление.

ЗАО Издательский дом «Питер», 2006 Краткое содержание Об этой книге Благодарности …. Глава 1. Введение в Орепб~ Глава 2. Управление состоянием и рисование геометрических объектов ……, . Глава 3. Визуализация Глава 4. Цвет Глава 5. Освещение Глава б. Смешивание, сглаживание, туман и отклонение …. Глава 7. Списки отображения Глава 8. Вывод пикселов, битовых образов, шрифтов и изображений . Глава 9. Наложение текстур Глава 10. Буфер кадров…

Глава 11. Мозаичное представление и поверхности второго порядка ………… Глава 12. Вычислители и МОйВ5… Глава 13. Выбор и обратная связь .. Глава 14. Теперь, когда вы знаете многое………… Приложения. Приложение А. Порядок выполнения операций……… Приложение Б. Параметры состояния Приложение В.

ОрепЯ и оконные системы………, . Приложение Г. Основы бШТ: инструментальный набор пакета разработчика ОрепБ…. Приложение Д. Вычисление векторов нормалей ……., . Приложение Е. Однородные координаты и матричные преобразования ….., ……. Приложение Ж. Приемы программирования …, …., ..

Приложение 3. Орепб~ и инвариантность ……,, …. Словарь терминов .. Алфавитный указатель……..,………… 15 21 22 43 96 145 160 198 238 259 309 386 416 438 466 492 519 520 525 553 572 577 582 588 593 595 610 Содержание Об этой книге Что нового в этом издании . Что необходимо знать перед прочтением , Как получить примеры программ . Обучающие программы по Ореп6~ от Нэйта Робинса Используемые стили От издателя перевода .. Благодарности Глава 1.

Введение в Орели., Что такое Ореп68 .. Немного программного кода, . Синтаксис команд Ореп61. Ореп60 как конечный автомат Конвейер рисования Ореп60 . Списки отображения.. Вычислители Операции над вершинами . Компоновка примитивов .. Операции над пикселами Компоновка текстур .. Растеризация . Операции над фрагментами . Библиотеки, связанные с Ореп60 .. Включаемые файлы ..

6ШТ, набор инструментов ОрепИ. Анимация Обновление с задержкой Движение = Перерисовка + Обмен Глава 2. Управление состоянием и рисование геометрических объектов, . Основы рисования Очистка окна Установка цвета . Ускорение завершения рисования . Управление системой координат.. Описание точек, линий и многоугольников Что такое точки, линии и многоугольники?.

Задание вершин . 15 17 . 18 19 . 20 . 20 . 20 21 . 22 . 23 . 28 27 . 29 . 30 . 31 . 31 . 31 , 31 . 32 . 32 . 32 . 33 . 33 . 34 . 35 . 38 . 40 . 43 . 45 . 45 . 48 . 49 50 . 51 51 55 Содержание Рисование графических примитивов в Ореола Управление основными состояниями Отображение точек, линий и многоугольников Подробно о точках Подробно о линиях Подробно о многоугольниках Векторы нормали . Массивы вершин . Шаг 1: активация массивов Шаг 2: помещение данных в массивы Шаг 3: разыменование и рисование . Смешанные массивы ..

Группы атрибутов. Несколько советов по построению полигональных моделей поверхностей . Пример: построение икосаэдра Глава 3. Визуализация, Обзор: аналогия с камерой Пример: рисование куба . Команды преобразования общего назначения Модельно-видовые преобразования . Размышления о преобразованиях. Модельные преобразования Видовые преобразования . Преобразования проецирования . Перспективное проецирование Ортогональное проецирование Отсечение объемом видимости Преобразование окна просмотра .

Определение окна просмотра. Измененная координата глубины, Проблемы преобразований.. Управление стеком матриц.. Стек модельно-видовых матриц. Стек матриц проекций .. Дополнительные плоскости отсечения . Примеры объединения нескольких преобразований Солнечная система . Сочлененная рука робота. Обратные, или имитационные, преобразования Глава 4. Цвет ..

цветовосприятие Вычисление цвета . йбВА в сравнении с индексированным цветом, Режим РОВА .. Режим индексации цвета . Выбор между режимами КОВА и индексации цвета Переключение между режимами . Задание цветовой и полутоновой моделей . Задание цвета в режиме КОВА , . . 56 . 61 . 61 . 62 .

72 . 73 75 . 76 . 78 . 84 . 86 . 89 90 96 . 98 101 105 107 107 110 114 119 120 122 124 124 124 126 127 129 132 132 133 . 135 135 138 141 145 146 147 150 150 152 . 153 154 155 155 8 Содержание Задание цвета в режиме индексации цвета . Задание модели закрашивания .. Глава 5. Освещение Удаление невидимых поверхностей Реальный мир и освещение в Орепб~ Фоновый, рассеянный, отраженный и излучаемый свет……… Цвета материала, . Значения кбв для источников света и материалов ………..

Пример: рисование освещенной сферы. Задание векторов нормалей для каждой вершины каждого объекта… Создание, размещение и включение одного или нескольких источников света Выбор модели освещения. Задание свойств материала для объектов в сцене Замечания на память. Создание источников света Цвет Положение и ослабление . Прожекторы .. Несколько источников света . Управление положением и направлением источников света……. Выбор модели освещения , .

Общее фоновое освещение Локальная или бесконечно удаленная точка обзора Двухстороннее освещение .. Вторичный отраженный цвет . Включение источников света . Задание свойств материала . Рассеянное и фоновое отражение Зеркальное отражение .. Излучение . Изменение свойств материала Режим цвета материала Математика освещения Излучение материала Масштабированный общий фоновый свет Вклады от источников света Вторичный отраженный цвет . Освещение в режиме индексации цвета .. Математика освещения в режиме индексации цвета Глава 6.

Время на прочтение
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. Руководство по программированию

, Т. Девис, Дж. Нейдер, Д. Шрайнер

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

Ваша первая программа

Введение[править]

Большинство документаций по OpenGL описывают функции, которые в настоящее время устарели, в частности «фиксированный конвейер».
OpenGL 2.0 и поздние версии содержат программируемый конвейер, где программируемая часть осуществляет шейдеры, написан в GLSL , базируемый на языке ANSI C.

Этот документ предназначен для людей, которые только начали изучать OpenGL и хотят использовать его с самого начала изучения.
Программируемые конвейеры более гибкие, но менее удобные в использовании, чем фиксируемые конвейеры. Вы однако убедитесь, что мы начнем с простого кода в первую очередь. Мы будем использовать подход похожий на подход NeHe’s в учебнике OpenGL 1.x, с примерами и учебными материалами, чтобы лучше понять теорию программируемых конвейеров позднее.

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

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

Распространяйте этот документ среди своих друзей! Викиучебник заслуживает большего вклада и признания:)

Заметки:

  • Вероятно можно смешать фиксированный конвейер и программируемый конвейер до некоторой степени, но фиксированный конвейер является устаревшим и недоступен во всех OpenGL ES 2.0 (или его производной WebGL), таким образом мы не будем использовать это.
  • В настоящие время OpenGL 3 и 4, в которые внедрили особенность геометрических шейдеров, но на этот раз это всего лишь эволюция света по сравнению с предыдущей версией. Поскольку он недоступен на мобильных платформах от 2012, сейчас мы сконцентрируемся на OpenGL 2.0.

Основные библиотеки[править]

Мы установим и используем следующие библиотеки:

  • OpenGL
  • GLEW (OpenGL Extension Wrangler) : действующие прототипы на C (и позже загружаемые расширение OpenGL)
  • GLUT (OpenGL Utility Toolkit) : создает окно OpenGL достаточно простым и кроссплатформенным способом

Под Debian and Ubuntu GNU/Linux, есть подходящие пакеты:

  • libgl1-mesa-dev (ищите в репозитории вашего линукс по «mesa»)
  • libglew1.5-dev (… «glew»)
  • freeglut3-dev (… «glut»)

Удостоверьтесь, что вы установили основные инструменты компилятора, используйте этот мета-пакет:

  • build-essential

Т.к. вам придется подключать эти библиотеки непосредственно к вашей OpenGL-программе, проверьте APIs, Libraries and acronyms, чтобы понять, как именно могут называться отличающиеся названия пакетов с ними.

Заметка: Мы выбрали GLUT, потому что это минимальный портативный пакет, который мы смогли достать. Мы не будем использовать продвинутые особенности какого-либо продукта, и почти весь наш код будет построен на OpenGL, таким образом вы не должны иметь трудностей при переходе на другие, более сложные или не-кроссплатформенные библиотеки — такие как Qt, WGL, GLFW, SDL и SFML впоследствие.

Отображения треугольника в 2D[править]

Давайте начнем с простого  :) Вместо того что бы пытаться разобраться со сложной программой (что займет большое количество времени), займёмся написанием простой, но функцианальной программы, которую мы сможем улучшать шаг за шагом.

Треугольник самая базовая единица в 3D програмировании. На самом деле всё что вы видите в видео играх состоит из треугольников! Маленькие, текстурированные треугольники, но треугольники тем не менее  :)

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

  • Создать ‘Makefile’, чтобы собрать наше приложение.
  • Инициализировать OpenGL и вспомогательные библиотеки
  • Заполнить массив с координатами 3-х вершин (т.е. 3D точек) треугольника
  • В программе GLSL для:
    • вершинного шейдера: передать каждую вершину индивидуально, и он будет вычислять на экране 2D координаты
    • фрагментный (пиксельный) шейдер: OpenGL пройдет каждый пиксель, который содержится в нашем треугольнике, и будет вычислять его цвет.
  • пройти вершины ‘вершинного шейдера’

Сборка приложения[править]

Очень легко настроить ‘Make’ для нашего примера. Запишите это в файле ‘Makefile’:

LDLIBS=-lglut -lGLEW -lGL
all: triangle

Для компиляции приложения, наберите в терминале:

make

Если применить немного больше фантазии, то Makefile будет выгядеть следующим образом:

CC=g++
  1. прим: на Mac OS X, начиная с версии Xcode 5.0, вместо gcc/g++ поставляется другой компилятор:
  2. CC=llvm
LDLIBS=-lglut -lGLEW -lGL
all: triangle
clean:
        rm -f *.o triangle
.PHONY: all clean

Это позволяет использовать команду ‘make clean», которая удаляет все промежуточные файлы, которые могут быть сгенерированны.

The .PHONY rule is there to tell make that «all» and «clean» are not files, so it will not get confused if you actually have files named like that in the same directory.

If you want to use a different programming environment, see the Настройка OpenGL section.

Например под FreeBSD 12

clang `pkg-config —libs —cflags glew freeglut` triangle.c

Инициализация[править]

Давайте создадим файл triangle.c:

/* Использование стандартного вывода for fprintf */
#include <stdio.h>
#include <stdlib.h>
/* Используйте glew.h вместо gl.h, чтобы иметь доступ ко всем объявленным GL прототипам */
#include <GL/glew.h>
/* Использабание GLUT библиотеки для базовой настройки окна */
#include <GL/glut.h>
/* ПОЗЖЕ ЗДЕСЬ ДОБАВИМ ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ*/

int init_resources(void)
{
  /* ЗАПОЛНИМ ПОЗЖЕ */
  return 1;
}

void onDisplay()
{
  /* ЗАПОЛНИМ ПОЗЖЕ */
}

void free_resources()
{
  /* ЗАПОЛНИМ ПОЗЖЕ */
}

int main(int argc, char* argv[])
{
  /* Glut-related инициализация функции */
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
  glutInitWindowSize(640, 480);
  glutCreateWindow("My First Triangle");

  /* Extension wrangler initialising */
  GLenum glew_status = glewInit();
  if (glew_status != GLEW_OK)
  {
    fprintf(stderr, "Error: %sn", glewGetErrorString(glew_status));
    return EXIT_FAILURE;
  }

  /* Когда все init функции выполняться без ошибок,
      программе можно инициализировать ресурсы */
  if (1 == init_resources())
  {
    /* Мы можем выводить на дисплей it, если всё пойдёт хорошо*/
    glutDisplayFunc(onDisplay);
    glutMainLoop();
  }

  /* Если выход из программы осуществляется обычным путём,
       то освободим ресурсы и успешно завершим выполнение программы */
  free_resources();
  return EXIT_SUCCESS;
}

В init_resources, мы создадим нашу GLSL программу.
В onDisplay, мы будем рисовать треугольник.
В free_resources, мы уничтожим GLSL программу (прим. переводчика деструктор).

Массив вершин[править]

Наш первый треугольник будет отображаться в 2D — мы будем рассматривать нечто более сложное в ближайшее время.
Мы описываем 2D (x,y) координаты треугольник для 3-х точек.
По умолчанию, OpenGL координаты изменяются в диапазоне [-1, 1] .

  GLfloat triangle_vertices[] = {
     0.0,  0.8,
    -0.8, -0.8,
     0.8, -0.8
  };

Сейчас давайте просто запомним этот код, а запишем его в программу чуть позже.

Примечание: координаты находятся между -1 и +1, но наше окно не квадрат!В следующих уроках мы увидим, как исправить пропорции.

Вершинный шейдер[править]

(вольный перевод)Эта GLSL программа, которая поможет каждой точке нашего массива, по очереди, найти своё место на экране.
В нашем случае точки и так имеют 2D координаты, так что мы не будем их изменять.
Наша программа GLSL, выглядит так:

#version 120
attribute vec2 coord2d;
void main(void) {
  gl_Position = vec4(coord2d, 0.0, 1.0);
}
  • #version 120 означает GLSL v1.20 в OpenGL 2.1.
  • OpenGL ES 2 GLSL также основан на GLSL v1.20, но его версия 1.00 (#version 100). [1].
  • coord2d — это текущая вершина; Это входная переменная и нам нужно её объявить в нашем Си коде.
  • gl_Position — это окончательная позиция экрана; Это built-in(т.е. встроенная) выходная переменная.
  • vec4 берёт наши координаты x и y, а так же 0 для координаты z. Последняя, w=1.0 для однородных координат (используется для трансформационных матриц).

Теперь нам нужно скомпилировать OpenGL шейдер. Начните init_resources с вышеупомянутого main:

/*
Функция: init_resources
Получает: void
Возвращает: int
Эта функция создает все GLSL related stuff
explained in this example.
Возвращает 1, если все в порядке, или 0 с отображаемой ошибкой.
*/
int init_resources(void)
{
  GLint compile_ok = GL_FALSE, link_ok = GL_FALSE;

  GLuint vs = glCreateShader(GL_VERTEX_SHADER);
  const char *vs_source = 
#ifdef GL_ES_VERSION_2_0
    "#version 100n"  // OpenGL ES 2.0
#else
    "#version 120n"  // OpenGL 2.1
#endif
    "attribute vec2 coord2d;                  "
    "void main(void) {                        "
    "  gl_Position = vec4(coord2d, 0.0, 1.0); "
    "}";
  glShaderSource(vs, 1, &vs_source, NULL);
  glCompileShader(vs);
  glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_ok);
  if (0 == compile_ok)
  {
    fprintf(stderr, "Error in vertex shadern");
    return 0;
  }

Мы передаем в качестве источника строку в glShaderSource (позже мы будем читать код шейдеров иначе и удобнее).
Мы указываем тип GL_VERTEX_SHADER.

Фрагментный шейдер[править]

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

#version 120
void main(void) {
  gl_FragColor[0] = 0.0;
  gl_FragColor[1] = 0.0;
  gl_FragColor[2] = 1.0;
}

Мы должны собрать его аналогичным образом с типом GL_FRAGMENT_SHADER. Давайте продолжим нашу процедуру init_resources:

  GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
  const char *fs_source =
    "#version 120           n"
    "void main(void) {        "
    "  gl_FragColor[0] = 0.0; "
    "  gl_FragColor[1] = 0.0; "
    "  gl_FragColor[2] = 1.0; "
    "}";
  glShaderSource(fs, 1, &fs_source, NULL);
  glCompileShader(fs);
  glGetShaderiv(fs, GL_COMPILE_STATUS, &compile_ok);
  if (!compile_ok) {
    fprintf(stderr, "Error in fragment shadern");
    return 0;
  }

GLSL программа[править]

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

Вот как связать вершиный и фрагментный шейдер в программе. Продолжаем процедуру init_resources:

  program = glCreateProgram();
  glAttachShader(program, vs);
  glAttachShader(program, fs);
  glLinkProgram(program);
  glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
  if (!link_ok) {
    fprintf(stderr, "glLinkProgram:");
    return 0;
  }

Перебор вершин треугольника в вершинном шейдере[править]

Мы упоминали, что мы проходим каждую вершину треугольника вершинным шейдером с помощью атрибута coord2d.
Вот как объявить его в коде C.

Во-первых, давайте создадим вторую глобальную переменную:

Вот так будет выглядеть конец нашей процедуры init_resources:

  const char* attribute_name = "coord2d";
  attribute_coord2d = glGetAttribLocation(program, attribute_name);
  if (attribute_coord2d == -1) {
    fprintf(stderr, "Could not bind attribute %sn", attribute_name);
    return 0;
  }

  return 1;
}

Теперь мы можем передать вершины нашего треугольника в вершинный шейдер.
Давайте напишем процедуру onDisplay. Каждая секция объясняется в комментариях:

void onDisplay()
{
  /* Создаём белый фон */
  glClearColor(1.0, 1.0, 1.0, 1.0);
  glClear(GL_COLOR_BUFFER_BIT);

  glUseProgram(program);
  glEnableVertexAttribArray(attribute_coord2d);
  GLfloat triangle_vertices[] = {
     0.0,  0.8,
    -0.8, -0.8,
     0.8, -0.8,
  };
  /* Опишем наш массив вершин OpenGL (формат не определяется автоматически) */
  glVertexAttribPointer(
    attribute_coord2d, // атрибут
    2,                 // количество элементов на вершине, здесь две - (х, у).
    GL_FLOAT,          // тип каждого элемента
    GL_FALSE,          // принять наши параметры как есть
    0,                 // никаких дополнительных данных между каждой позицией
    triangle_vertices  // указатель на массив C.
  );


  /* Вставьте каждый элемент в buffer_vertices для вершинных шейдеров */
  glDrawArrays(GL_TRIANGLES, 0, 3);
  glDisableVertexAttribArray(attribute_coord2d);

  /* Вывести результат */
  glutSwapBuffers();
}

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

Примечание: в следующем уроке мы введем Vertex Buffer Objects, чуть более сложный и более новый способ хранения вершин графической карты.

Остаётся только часть free_resources, для чистки ресурсов, когда мы вышли из программы.
Это не критично в данном конкретном случае, но хорошо бы структурировать приложение как-то так:

void free_resources()
{
  glDeleteProgram(program);
}

Наша первая OpenGL 2.0 программа завершена!

В случае неудачи[править]

Следующий урок добавляет большую устойчивость к нашему первому минималистичному коду.
Можете попробовать код tut02 (см ссылку на код, приведенный ниже).

Эксперимент![править]

Другой пиксельный шейдер для нашей первой программы

Не стесняйтесь экспериментировать с этим кодом:

  • попробуйте сделать квадрат, используя 2 треугольника
  • попробуйте изменить цвета
  • можете почитать справочные страницы OpenGL для каждой функции, которую мы использовали:
    • OpenGL (ES 2.0)
    • GLUT
  • попробуйте использовать этот код в пиксельном шейдере — для чего это нужно?
gl_FragColor[0] = gl_FragCoord.x/640.0;
gl_FragColor[1] = gl_FragCoord.y/480.0;
gl_FragColor[2] = 0.5;

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

Примечания[править]

  1. Cf. OpenGL ES Shading Language 1.0.17 Specification. Khronos.org. Проверено 2011-09-10 г.The OpenGL ES Shading Language (also known as GLSL ES or ESSL) is based on the OpenGL Shading Language (GLSL) version 1.20

Шаблон:OpenGL Programming BottomNav

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