Игры на c уроки opengl. История противостояния OpenGL и Direct3D. Один язык чтобы всё разрушить

Я не буду подробно останавливаться на работе со сбербанком, о комиссиях и т.п. Все это я уже достаточно подробно описал в цикле статей про сбербанк.



В этой статье я хочу упомянуть небольшую особенность при переводе крупных сумм (300 000р и более) через сбербанк онл@йн.

!!!Авторство текста подтверждено!!!
Будьте уверены в том, что сейчас читаете «уникальный» текст, которого еще нет в интернете. Если где бы то ни было в сети интернет вы обнаружите этот текст, кроме сайта

ЗНАЙТЕ — это всего лишь копия, за достоверность которой barbados-fs ответственности не несет и нести не может

А особенность эта заключается в том, что непосредственно руководство по работе с интернет банкингом сбербанка пользователи читать не хотят, но неизбежно «этот» вопрос возникает. «Этот» вопрос — почему перевод не отправляется как обычно, а статус его становится «ожидает дополнительного подтверждения»

На самом деле все просто. На одном из этапов оформления перевода Вас предупреждают, что суммы 500 000р и более необходимо подтверждать в контактном центе (это сообщение появляется в верху страницы, по центру), хотя на практике сумму уже в *300 000 р. вас отправят подтверждать в КЦ).
Поэтому, после того, как вы оформили перевод и подтвердили правильность введенных вами данных, на последнем этапе, когда уже перевод должен быть отправлен, вам следует позвонить в контактный центр сбербанка по бесплатному номеру 8 800 555 5550 (на момент написания статьи, позвонив по этому номеру и дождавшись соединения, не забыв перевести ваш телефон в режим тонального набора, нажав клавишу «звездочка» (*), можно было не слушая автоинформатор набрать цифры 321 (три, два, один), после чего вы сразу попадаете к оператору, для подтверждения операции перевода или создания шаблона, разумеется, подождав, пока оператор освободится) и подтвердить свою личность побеседовав с оператором. Будьте готовы предоставить оператору ваши полные паспортные данные, кодовое слово и номер карты . Если вы захотите перевести сумму превышающую 300 000р за одни сутки, либо создать шаблон перевода/платежа на сумму 300 000 и более, то ко всему вышесказанному вы должны будите назвать оператору номер последней операции которую вы провели в банкомате банка или непосредственно через кассира операциониста . Т.е. если вы собираетесь переводить крупную сумму денег (300 000 и более) или создать шаблон на крупную сумму, то потрудитесь заранее сходить к банкомату и получить чек с запросом, ну скажем вашего остатка средств по карте. Иначе «жестокий оператор» из службы технической поддержки вам откажет в переводе.

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

*Сразу хочу отметить, что приведенные в данном материалы суммы ограничений, так же, как и условия применения этих ограничений, могут со временем измениться и были актуальны только на момент написания данной статьи.

Конечно, Go не задумывался как язык для написания игр. Но чем еще заняться холодными осенними вечерами? Давайте попробуем запустить несколько игровых движков и посмотреть, как в Go-мире обстоят дела с геймдевом.

GarageEngine

Наш первый экземпляр - это 2d игровой движок для Go, который работает на OpenGL. Он состоит из модулей/компонентов. Сейчас уже есть приличное количество таких модулей для шрифтов, спрайтов, текстур, физики, сцен и так далее. Очень сильно ощущается влияние Unity3d. Особенно в названиях компонентов: Scene, Coroutines, Components, Transform, GameObjects и т.д.

К сожалению это проект для обучения. Не стоит ожидать от него супер-килер-фич и обратной совместимости.

Установка

Нам нужно установить либы glfw и glew

Sudo apt-get update sudo apt-get install build-essential binutils-gold \ freeglut3 freeglut3-dev libalut-dev libglew-dev \ libglfw-dev libxrandr2 libxrandr-dev

Если вы используете windows вам нужно юзать mingw и собрать glew.

Go get github.com/vova616/GarageEngine

Примеры

SpaceCookies - Небольшой пример для тестирования движка. Есть несколько нюансов, чтобы нормально запустить этот пример.

Прежде всего заходим в папку src/github.com/vova616/GarageEngine и собираем все руками:

Go build main.go

Если появилась ошибка вида:

# github.com/vova616/GarageEngine/engine/audio .godeps/src/github.com/vova616/GarageEngine/engine/audio/AudioSource.go:129: undefined: openal.DistanceModel

Комментируем строки 128-130 в файле src/github.com/vova616/GarageEngine/engine/audio/AudioSource.go

If currentDistanceModel != this.distanceModel { openal.SetDistanceModel(openal.DistanceModel(this.distanceModel)) }

Пытаемся запустить и получаем ошибку listen tcp 0.0.0.0:123: bind: permission denied . Меняем номера портов в файле src/github.com/vova616/GarageEngine/spaceCookies/server/Server.go на строке 88

Addr, err:= net.ResolveTCPAddr("tcp", "0.0.0.0:12345")

и в файле src/github.com/vova616/GarageEngine/spaceCookies/game/Client.go строки 19 и 20

Const ServerIP = "localhost:12345" const ServerLocalIP = "localhost:12345"

Опять пробуем запустить и ничего не получается. Рядом с нашим бинарником лежит файл log.txt c примерно таким содержимым:

Enginge started! GLFW Initialized! Opengl Initialized! open ./data/spaceCookies/background.png: no such file or directory open ./data/spaceCookies/button.png: no such file or directory runtime error: invalid memory address or nil pointer dereference panic.c:482, os_linux.c:234, Sprite.go:42, LoginScene.go:83, Engine.go:96, main.go:78, main.go:44, proc.c:220, proc.c:1394

Видим, что программа пытается найти файлы./data/spaceCookies/background.png и./data/spaceCookies/button.png . А папка, на самом деле, называется./data/SpaceCookies . Переименовываем папку и снова запускаем. Ура! Теперь все работает.

☣ Azul3D

Azul3D это 3D движок написанный полностью с нуля на языке программирования Go. Azul3D подходит для создания 2D и 3D игр. Так же, его можно использовать для создания не игровых, а просто интерактивных приложений. В отличии от большинства современных движков(таких как Unity, JMonkey) у Azul3D нет дополнительных фич типа редакторов уровней, IDE. Это просто набор необходимых разработчику пакетов.

Это игровой движок от программистов для программистов. Он очень минималистичен, но легко расширяется в отличии от других движков.

Azul3D предоставляет самые необходимые инструменты, которые будут использоваться изо дня в день. И делает это действительно хорошо.

Установка

Начинаем с зависимостей для Ubuntu 14.04. Для других систем .

Sudo apt-get install build-essential git mesa-common-dev \ libx11-dev libx11-xcb-dev libxcb-icccm4-dev \ libxcb-image0-dev libxcb-randr0-dev libxcb-render-util0-dev \ libxcb-xkb-dev libfreetype6-dev libbz2-dev \ libxxf86vm-dev libgl1-mesa-dev

Примеры

Теперь пробуем установить примеры. Они вынесены в отдельный пакет.

Go get azul3d.org/examples.v1

нам понадобится куча других пакетов:

Go get azul3d.org/keyboard.v1 go get azul3d.org/lmath.v1 go get azul3d.org/gfx.v1 go get azul3d.org/gfx/window.v2 go get azul3d.org/mouse.v1 go get azul3d.org/tmx.dev

Теперь можем посмотреть примеры. Заходим в src/azul3d.org/examples.v1/azul3d_tmx и запускаем пример

Go run azul3d_tmx.go

Вы увидите что-то такое:

Были проблемы с версией Go ниже 1.3. Обновился до самой последней и все отлично заработало на моей ubuntu 14.04.

gosfml

Возможность использовать C-код в Go приложениях - это просто прекрасно. Мы можем использовать кучу готовых библиотек.

И конечно же, нельзя обойти стороной Go биндинги к популярной библиотеке SFML . Есть несколько вариантов, но я смог запустить только этот .

SFML - это кросплатформенная библиотека для мультимедиа. Она написана на C++, но есть куча привязок к разным языкам и к Go в том числе.

Кроме работы с мультимедиа в этой либе есть несколько пакетов для программирования простых игр.

Модули, которые нам доступны в этой библиотеке:

  • System - управление временем и потоками.
  • Window - управление окнами и взаимодействием с пользователем.
  • Graphics - делает простым отображение графических примитивов и изображений.
  • Audio - предоставляет интерфейс для управления звуком.
  • Network - для сетевых приложений.

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

За основу давайте возьмем проект из предыдущего урока (), как и тогда, для построения изображения мы сегодня будем использовать массивы вершин, индексов и цветов . Давайте разберем нашу задачу…

Что из себя представляет куб? Ответ прост – 6 граней (квадратов) и 8 вершин 😉 Именно так мы и будем строить фигуру – построим по отдельности 6 его граней, а эта задача для нас уже не представляет никакой сложности.

Но прежде, чем приступать к рисованию, добавим в функцию initializeGL() следующее:

glShadeModel(GL_FLAT) ; glEnable(GL_CULL_FACE) ;

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

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

Собственно, с приготовлениями на этом заканчиваем, начинаем отрисовку. Нам понадобятся три массива:

GLfloat cubeVertexArray[ 8 ] [ 3 ] ; GLfloat cubeColorArray[ 8 ] [ 3 ] ; GLubyte cubeIndexArray[ 6 ] [ 4 ] ;

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

cubeVertexArray[ 0 ] [ 0 ] = 0.0 ; cubeVertexArray[ 0 ] [ 1 ] = 0.0 ; cubeVertexArray[ 0 ] [ 2 ] = 1.0 ; cubeVertexArray[ 1 ] [ 0 ] = 0.0 ; cubeVertexArray[ 1 ] [ 1 ] = 1.0 ; cubeVertexArray[ 1 ] [ 2 ] = 1.0 ; cubeVertexArray[ 2 ] [ 0 ] = 1.0 ; cubeVertexArray[ 2 ] [ 1 ] = 1.0 ; cubeVertexArray[ 2 ] [ 2 ] = 1.0 ; cubeVertexArray[ 3 ] [ 0 ] = 1.0 ; cubeVertexArray[ 3 ] [ 1 ] = 0.0 ; cubeVertexArray[ 3 ] [ 2 ] = 1.0 ; cubeVertexArray[ 4 ] [ 0 ] = 0.0 ; cubeVertexArray[ 4 ] [ 1 ] = 0.0 ; cubeVertexArray[ 4 ] [ 2 ] = 0.0 ; cubeVertexArray[ 5 ] [ 0 ] = 0.0 ; cubeVertexArray[ 5 ] [ 1 ] = 1.0 ; cubeVertexArray[ 5 ] [ 2 ] = 0.0 ; cubeVertexArray[ 6 ] [ 0 ] = 1.0 ; cubeVertexArray[ 6 ] [ 1 ] = 1.0 ; cubeVertexArray[ 6 ] [ 2 ] = 0.0 ; cubeVertexArray[ 7 ] [ 0 ] = 1.0 ; cubeVertexArray[ 7 ] [ 1 ] = 0.0 ; cubeVertexArray[ 7 ] [ 2 ] = 0.0 ; cubeColorArray[ 0 ] [ 0 ] = 0.0 ; cubeColorArray[ 0 ] [ 1 ] = 0.0 ; cubeColorArray[ 0 ] [ 2 ] = 1.0 ; cubeColorArray[ 1 ] [ 0 ] = 0.6 ; cubeColorArray[ 1 ] [ 1 ] = 0.98 ; cubeColorArray[ 1 ] [ 2 ] = 0.6 ; cubeColorArray[ 2 ] [ 0 ] = 1.0 ; cubeColorArray[ 2 ] [ 1 ] = 0.84 ; cubeColorArray[ 2 ] [ 2 ] = 0.8 ; cubeColorArray[ 3 ] [ 0 ] = 0.8 ; cubeColorArray[ 3 ] [ 1 ] = 0.36 ; cubeColorArray[ 3 ] [ 2 ] = 0.36 ; cubeColorArray[ 4 ] [ 0 ] = 1.0 ; cubeColorArray[ 4 ] [ 1 ] = 0.27 ; cubeColorArray[ 4 ] [ 2 ] = 0.0 ; cubeColorArray[ 5 ] [ 0 ] = 0.82 ; cubeColorArray[ 5 ] [ 1 ] = 0.13 ; cubeColorArray[ 5 ] [ 2 ] = 0.56 ; cubeColorArray[ 6 ] [ 0 ] = 0.54 ; cubeColorArray[ 6 ] [ 1 ] = 0.17 ; cubeColorArray[ 6 ] [ 2 ] = 0.89 ; cubeColorArray[ 7 ] [ 0 ] = 0.0 ; cubeColorArray[ 7 ] [ 1 ] = 1.0 ; cubeColorArray[ 7 ] [ 2 ] = 1.0 ;

Мы задали координаты и цвета вершин куба. Давайте для наглядности посмотрим на рисунок:

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

  • Грань 1 – вершины 0, 3, 2, 1
  • Грань 2 – вершины 0, 1, 5, 4
  • Грань 3 – вершины 7, 4, 5, 6
  • Грань 4 – вершины 3, 7, 6, 2
  • Грань 5 – вершины 1, 2, 6, 5
  • Грань 6 – вершины 0, 4, 7, 3

Теперь тоже самое делаем в программе =)

cubeIndexArray[ 0 ] [ 0 ] = 0 ; cubeIndexArray[ 0 ] [ 1 ] = 3 ; cubeIndexArray[ 0 ] [ 2 ] = 2 ; cubeIndexArray[ 0 ] [ 3 ] = 1 ; cubeIndexArray[ 1 ] [ 0 ] = 0 ; cubeIndexArray[ 1 ] [ 1 ] = 1 ; cubeIndexArray[ 1 ] [ 2 ] = 5 ; cubeIndexArray[ 1 ] [ 3 ] = 4 ; cubeIndexArray[ 2 ] [ 0 ] = 7 ; cubeIndexArray[ 2 ] [ 1 ] = 4 ; cubeIndexArray[ 2 ] [ 2 ] = 5 ; cubeIndexArray[ 2 ] [ 3 ] = 6 ; cubeIndexArray[ 3 ] [ 0 ] = 3 ; cubeIndexArray[ 3 ] [ 1 ] = 7 ; cubeIndexArray[ 3 ] [ 2 ] = 6 ; cubeIndexArray[ 3 ] [ 3 ] = 2 ; cubeIndexArray[ 4 ] [ 0 ] = 1 ; cubeIndexArray[ 4 ] [ 1 ] = 2 ; cubeIndexArray[ 4 ] [ 2 ] = 6 ; cubeIndexArray[ 4 ] [ 3 ] = 5 ; cubeIndexArray[ 5 ] [ 0 ] = 0 ; cubeIndexArray[ 5 ] [ 1 ] = 4 ; cubeIndexArray[ 5 ] [ 2 ] = 7 ; cubeIndexArray[ 5 ] [ 3 ] = 3 ;

Теперь осталось только вызвать функцию рисования:

glVertexPointer(3 , GL_FLOAT, 0 , cubeVertexArray) ; glColorPointer(3 , GL_FLOAT, 0 , cubeColorArray) ; glDrawElements(GL_QUADS, 24 , GL_UNSIGNED_BYTE, cubeIndexArray) ;

Запускаем программу и видим наш куб!

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

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

yAngle = 180 * d / w;

Здесь d – это расстояние, на которое мы переместили курсор, w – ширина нашего окна. Обратите внимание, что при движении мыши вдоль оси x поворот будет осуществляться вокруг оси y , и наоборот, перемещение вдоль y – поворот вокруг x .

Итак, сейчас нам нужно получить в программе данные о перемещениях мыши. Для этого переопределим методы:

void MainScene:: mousePressEvent (QMouseEvent * event) { pressPosition = event-> pos() ; } void MainScene:: mouseMoveEvent (QMouseEvent * event) { xAxisRotation += (180 * ((GLfloat) event-> y() - (GLfloat) pressPosition.y () ) ) / (currentHeight) ; yAxisRotation += (180 * ((GLfloat) event-> x() - (GLfloat) pressPosition.x () ) ) / (currentWidth) ; pressPosition = event-> pos() ; updateGL() ; }

При нажатии кнопки мыши (mousePressEvent() ) сохраняем в переменную pressPosition текущие координаты курсора. При перемещениях указателя производим расчет углов поворота, на которые необходимо развернуть куб, а затем вызываем функцию updateGL() для перерисовки сцены в соответствии с полученными данными. Не забываем объявить все используемые методы и переменные в файле MainScene.h.

Функцию updateGL() то мы вызвали, но само собой ничего, естественно, не повернется)

Для поворота фигуры предлагает нам следующую функцию:

То фигура повернется вокруг оси x на 45 градусов.

С этим все понятно, осталось только добавить вызов этой функций к нам в программу, а точнее в функцию paintGL() :

Как видите, все оказалось довольно-таки просто)

Теперь нам предстоит собрать проект и проверить результат:

На этом заканчиваем сегодняшнюю статью! А уже скоро, а именно в следующем уроке, мы разберемся с текстурами в – создадим собственные текстуры и нанесем их на 3D объекты, так что до скорого, не пропустите новую статью 😉

Мне нужно сделать что-то вроде рейтресинга, но существенно проще - просто найти депт по лучу из каждой руки, т.е. определить расстояние до обьекта от контроллера (в руке).
Что бы не делать дурную работу, я для черновой отбраковки использовал BoundingBox::Intersects.
Все работало отлично, пока я не стал вращать предметы. Сейчас у меня данный метод работает только для оригинальных обьектов. Положив предмет "на бок" находится только точка строго по оси вращения, т.е все остальное отбрасывается, что совершенно неверно. Наверно надо как-то повернуть BoundingBox, но у него нет такого метода.
Кто-то может дать совет как с этим бороться?

4 апр. 2019 18:30 Suslik

Я методом тыка нашёл ответ, но ума не приложу, почему он такой. Хочу понять, что происходит.

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

4 апр. 2019 1:52 zombihello

Привет народ!

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

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

Во-вторых , как вообще посоветуете организовывать работу с инстансингом, как Вы данную вещь делали? Опишу как у меня сейчас. Для модели (без повторений) формирую один VBO для вершин, другой VBO для инстансиг информации (по началу выделяю на 10.000 байт) и EBO для индексов вершин. При создании копии модели я в буфер инстансинга записываю матрицу трансформации с проверкой на кол-во используемой памяти в буфере, если уже нужно больше чем выделено - копирую во временный буфер все содержимое, с помощью glBufferData(.., useSize + 10000, NULL, ...) выделяю для рабочего буфера на 10.000 байт больше (учитывая текущий размер + новый элемент), копирую с временного буфера всю информацию в рабочий и с помощью glBufferSubData дописываю новый элемент. Но мне что-то подсказывает что это все можно решить куда проще)

Буду благодарен вашим советам.

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

Координаты текстуры меняются так (cell - передается из вершинного шейдера и представляет собой кординаты ячейки):

float PHI = 1.61803398874989484820459; // Golden Ratio vec2 uv = PHI*fragTexCoord + floor(cell)*PHI;

Хотелось бы в общих чертах понять почему эта линия на стыках вообще возникает и как от нее избавится.

Update: Отключение фильтрации в семплере не помогает.

Update2: Если ликвидировать функцию floor - линия на стыках исчезает, но мне нужна целая часть от числа и без floor я обойтись не могу.

Правка: 6:55

OpenGL (Open Graphics Library - открытая графическая библиотека) - спецификация, определяющая независимый от языка программирования кросс-платформенный программный интерфейс для написания приложений, использующих двумерную и трехмерную компьютерную графику.
Включает более 250-ти функций для рисования сложных трехмерных сцен из простых примитивов. Используется при создании видео-игр, САПР, виртуальной реальности, визуализации в научных исследованиях. Под Windows конкурирует с DirectX.
Спецификация
На базовом уровне, OpenGL - это просто спецификация, то есть документ, описывающий набор функций и их точное поведение. Производители оборудования на основе этой спецификации создают реализации - библиотеки функций, соответствующих набору функций спецификации. Реализация использует возможности оборудования, там где это возможно. Если аппаратура не позволяет реализовать какую-либо возможность, она должна быть эмулирована программно. Производители должны пройти специфические тесты (conformance tests - тесты на соответствие) прежде чем реализация будет классифицирована как OpenGL реализация. Таким образом, разработчикам программного обеспечения достаточно научиться использовать функции, описанные в спецификации, оставив эффективную реализацию последних разработчикам аппаратного обеспечения.
Эффективные реализации OpenGL существуют для Windows, Unix платформ, PlayStation 3 и Mac OS. Эти реализации обычно предоставляются изготовителями видеоадаптеров и активно используют возможности последних. Существуют также чисто программные реализации спецификации OpenGL, одной из которых является библиотека Mesa. Из лицензионных соображений Mesa является «неофициальной» реализацией OpenGL, хотя полностью с ней совместима на уровне кода.
Спецификация OpenGL пересматривается Консорциумом ARB (Architecture Review Board), который был сформирован в 1992 году. Консорциум состоит из компаний, заинтересованных в создании широко распространенного и доступного API. Согласно официальному сайту OpenGL, членами ARB с решающим голосом на ноябрь 2004 года являются производители профессиональных графических аппаратных средств SGI, 3Dlabs, Matrox и Evans & Sutherland (военные приложения), производители потребительских графических аппаратных средств ATI и NVIDIA, производитель процессоров Intel, и изготовители компьютеров и компьютерного оборудования IBM, Apple, Dell, Hewlett-Packard и Sun Microsystems, а также один из лидеров компьютерной игровой индустрии id Software. Microsoft, один из основоположников Консорциума, покинула его в марте 2003 года. Помимо постоянных членов, каждый год приглашается большое количество других компаний, становящихся частью OpenGL ARB в течение одного года. Такое большое число компаний, вовлеченных в разнообразный круг интересов, позволило OpenGL стать прикладным интерфейсом широкого назначения с большим количеством возможностей.
Курт Экелей (Kurt Akeley) и Марк Сегал (Mark Segal) являются авторами оригинальной спецификации OpenGL. Крис Фрэзиер (Chris Frazier) редактировал версию 1.1. Йон Лич (Jon Leech) редактировал версии с 1.2 по настоящую версию 2.0.
Архитектура
OpenGL ориентируется на следующие две задачи:
скрыть сложности адаптации различных 3D-ускорителей предоставляя разработчику единый API
скрыть различия в возможностях аппаратных платформ, требуя имплементации недостающей функциональности с помощью софтверной эмуляции
Основным принципом работы OpenGL является получение наборов векторных графических примитивов в виде точек, линий и многоугольников с последующей математической обработкой полученных данных и построением растровой картинки на экране и/или в памяти. Векторные транформации и растеризация выполняются графическим конвейером (graphics pipeline), который по сути представляет из себя дискретный автомат. Абсолютное большинство команд OpenGL попадают в одну из двух групп: либо они добавляют графические примитивы на вход в конвейер, либо конфигурируют конвейер на различное исполнение транформаций.
OpenGL является низкоуровневым, процедурным API, что вынуждает программиста диктовать точную последовательность шагов, чтобы построить результирующую растровую графику (императивный подход). Это является основным отличием от дескрипторных подходов, когда вся сцена передается в виде структуры данных (чаще всего дерева), которое обрабатывается и строится на экране. С одной стороны императивный подход требует от программиста глубокого знания законов трёхмерной графики и математических моделей, с другой стороны даёт свободу внедрения различных инноваций.
Расширения
Стандарт OpenGL, с появлением новых технологий, позволяет отдельным производителям добавлять в библиотеку функциональность через механизм расширений. Расширения распространяются с помощью двух составляющих: заголовочный файл, в котором находятся прототипы новых функций и констант, а также драйвер устройства, поставляемого разработчиком. Каждый производитель имеет аббревиатуру, которая используется при именовании его новых функций и констант. Например, компания NVIDIA имеет аббревиатуру NV, которая используется при именовании ее новых функций, как, например, glCombinerParameterfvNV(), а также констант, GL_NORMAL_MAP_NV. Может случиться так, что определенное расширение могут реализовать несколько производителей. В этом случае используется аббревиатура EXT, например, glDeleteRenderbuffersEXT. В случае же, когда расширение одобряется Консорциумом ARB, оно приобретает аббревиатуру ARB и становится стандартным расширением. Обычно, расширения, одобренные Консорциумом ARB включаются в одну из последующих спецификаций OpenGL.
Список зарегистрированных расширений можно найти в официальной базе расширений.
Дополнительные библиотеки
Существует ряд библиотек, созданных поверх или в дополнение к OpenGL. Например, библиотека GLU, являющаяся практически стандартным дополнением OpenGL и всегда её сопровождающая, построена поверх последней, то есть использует её функции для реализации своих возможностей. Другие библиотеки, как, например, GLUT и SDL, созданы для реализации возможностей, недоступных в OpenGL. К таким возможностям относятся создание интерфейса пользователя (окна, кнопки, меню и др.), настройка контекста рисования (область рисования, использующаяся OpenGL), обработка сообщений от устройств ввода/вывода (клавиатура, мышь и др.), а также работа с файлами. Обычно, каждый оконный менеджер имеет собственную библиотеку-расширение для реализации вышеописанных возможностей, например, WGL в Windows или GLX в X Window System, однако библиотеки GLUT и SDL являются кросс-платформенными, что облегчает перенос написанных приложений на другие платформы.
Библиотеки, как GLEW (>) и GLEE (>) созданы для облегчения работы с расширениями и различными версиями OpenGL. Это особенно актуально для программистов в Windows, так как, заголовочные и библиотечные файлы, поставляемые с Visual Studio, находятся на уровне версии OpenGL 1.1.
OpenGL имеет только набор геометрических примитивов (точки, линии, многоугольники) из которых создаются все трехмерные объекты. Порой подобный уровень детализации не всегда удобен при создании сцен. Поэтому поверх OpenGL были созданы более высокоуровневые библиотеки, такие как Open Inventor и VTK. Данные библиотеки позволяют оперировать более сложными трехмерными объектами, что облегчает и ускоряет создание трехмерной сцены.
Независимость от языка программирования
Для подтверждения независимости от языка программирования были разработаны различные варианты привязки (binding) функций OpenGL или полностью перенесены на другие языки. Одним из примеров может служить библиотека Java 3D, которая может использовать аппаратное ускорение OpenGL. Прямая привязка функций реализована в Lightweight Java Game Library, которая имеет прямую привязку OpenGL для Java. Sun также выпустила версию JOGL, которая предоставляет прямую привязку к C-функциям OpenGL, в отличие от Java 3D, которая не имеет столь низкоуровневой поддержки. Официальный сайт OpenGL имеет ссылки на привязки для языков Java, Fortran 90, Perl, Pike, Python, Ada и Visual Basic. Имеются также варианты привязки OpenGL для языков C++ и C#, смотрите.
История
Сегодня компьютерная графика нашла широкое распространение и применение в повседневной жизни. Ученые используют компьютерную графику для анализа результатов моделирования. Инженеры и архитекторы используют трехмерную графику для создания виртуальных моделей. Кинематографы создают удивительные спецэффекты или полностью анимированные фильмы (Shrek, Toy Story и др.). В последние годы широкое распространение получили также компьютерные игры, максимально использующие трехмерную графику для создания виртуальных миров.
Распространению компьютерной графики сопутствовали свои трудности. Лет 15 назад, разработка программного продукта, способного работать на большом количестве графического оборудования было сопряжено с большими временными и финансовыми затратами. Было необходимо отдельно создавать модули для каждого типа графических адаптеров, что порой приводило к большой дупликации исходного кода. Это сильно тормозило развитие и распространение компьютерной графики.
Silicon Graphics Incorporated специализировалась на создании высокотехнологического графического оборудования и программных средств. Являясь в то время лидером в трехмерной графике, SGI видела проблемы и барьеры в росте рынка. Поэтому было принято решение стандартизировать метод доступа к графической аппаратуре на уровне программного интерфейса.
Таким образом появился программный интерфейс OpenGL, который стандартизирует доступ к графической аппаратуре, путем смещения ответственности за создание аппаратного драйвера на производителя графического устройства. Это позволило разработчикам программного обеспечения использовать более высокий уровень абстракции от графического оборудования, что значительно ускорило создание новых программных продуктов и снизило на них затраты.
В 1992 году компания SGI возглавила OpenGL ARB - группу компаний по разработке спецификации OpenGL. OpenGL эволюционировал из 3D-интерфейса SGI - IRIS GL. Одним из ограничений IRIS GL было то, что он позволял использовать только возможности, поддерживаемые оборудованием; если возможность не была реализована аппаратно, приложение не могло её использовать. OpenGL преодолевает эту проблему за счёт программной реализации возможностей, не предоставляемых аппаратно, что позволяет приложениям использовать этот интерфейс на относительно маломощных системах…
Когда в 1995 году была выпущена библиотека Direct3D, Microsoft, SGI и Hewlett-Packard начали проект под названием Fahrenheit, который предусматривал создание более универсального программного интерфейса на основе Direct3D и OpenGL. Идея казалась достаточно обещающей, призванной навести порядок в области интерактивной трехмерной графики, однако в результате финансовых трудностей в SGI и отсутствии должной индустриальной поддержки проект был закрыт.
OpenGL 2.0
По сравнению с DirectX, говорили что главной проблемой OpenGL является Консорциум, в который входит большое количество компаний с различными интересами, что приводит к длительному периоду принятия новой версии спецификации. OpenGL версии 2.0 была представлена 3Dlabs в ответ на беспокойства относительно медленного развития и нечеткого направления OpenGL. 3Dlabs предложила ряд существенных дополнений к стандарту, наиболее значимым из которого был GLSL (OpenGL Shading Language). Это позволяет программисту заменить фиксированный конвейер OpenGL небольшими программами на специальном языке, GLSL, для создания таких эффектов, как «рельефные текстуры» («bump mapping»), волны и водная рябь. Финальная версия спецификации OpenGL 2.0 включает в себя поддержку GLSL. Однако, еще до введения в стандарт OpenGL языка GLSL существовала возможность разрабатывать спецэффекты на языках: assembler (расширения vertex_program, fragment_program) и Cg (NVidia C for Graphics). К сожалению многие предложенные возможности пока отсутствуют в версии OpenGL 2.0, хотя некоторые из них реализованы многими производителями в виде расширений.
Официальный сайт OpenGL
сайт 3Dlabs для разработчиков использующих OpenGL
сайт программирования для GPU
Neon Helium - Уроки по OpenGL
Теория 3D графики с примерами на OpenGL
Уроки с примерами для разработчиков игр.