atz_2085 ([info]atz_2085) wrote,

OpenGL


Предыстория: В повседневной жизни работе программиста используется чаще всего лишь самый минимум возможностей языка C++. Причем выглядит это так, что код, который не использует ни шаблонов, ни полиморфизма, ни даже перегруженных операторов доступа, по сути своей соответствует некому весьма усредненному уровню всех программистов вместе взятых (и сильных, и слабых), и более всего похож на Дельфи, а скорее вообще на Turbo Pascal. В таком коде даже слой объектов - чаще всего линеен, и нет ни серьезной архитектуры, ни нормальной инкапсуляции (в том смысле, когда использующиеся вместе данные собирают в один класс, а не когда что-то прячут). Причем основная масса не очень сильных программистов экстенсивно суппортит раздвигает в ширину это (что C++ ом назвать трудно), однако в отдельных местах оно соседствует с чем-нибудь с другого конца палки: например, практически нечитаемыми конструкциями сделанными на основе Boost (с ее слотами-сигналами, и коннектами в виде функций, передаваемыми как параметры другим функциям через три слоя абстракций типа всяких контроллеров и менеджеров с характеристиками "дай доступ к объекту С++ вот с таким интерфейсом, взятым из SQL-базы данных").

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

В очередной раз мне захотелось написать такой класс матриц, чтобы он оказался бинарно-совместимым с четырехмерными матрицами OpenGL. Ну и заодно я решил поизучать плотнее тему под названием "специализации классов и функций C++". Однако - как выяснилось - в инете (ну, во всяком случае на русском) почему-то затруднительно найти подробное описание того, как именно OpenGL совершает внутри себя - при всей их очевидности - свои сакральные действия типа glRotate (а пионеры повсюду задают на эту тему одни и те же вопросы, т.к. матрицы там 4D, и действительно существуют некоторые хинты). Но все-таки пары найденных статей с кратко изложенной математикой хватило, чтобы написать код. Четырехмерные матрицы заработали, и пожалуй единственное, что меня в них не устраивало - это чисто софтверный код внутри их операторов умножения на векторы (и т.п. действия).

Ну а чтобы тестировать правильность работы библиотеки, пришлось создать небольшое приложение на OpenGL, которое, пользуясь этими матрицами, рисует призмы (нечто вроде "Quake Brushes") в небольшом окошке. И вот дальше началось самое интересное.

Куда ни сунься в инет на тему OpenGL - повсюду разложены красивые и подробные переводы на русский документации по функциям типа glTranslate() и уже давно доступные где угодно книжки, в которых повсеместно советуют написать несколько glVertex3f посреди между glBegin/glEnd. Все это нужно, что нарисовать чуть более, чем одну призму в чуть более, чем наипростейшей тривиальной модели геометрических объектов.

Углубление процесса Internet Data Mining обнаружило, что не более 10% от вышеуказанного массива информации составляет то, что на этом уровне (в самых лучших книгах и кое-где на форумах продвинутых перцев) подается как профессиональный уровень. Суть в том, что если не выводить точки за точкой, каждый раз делая вывод функции glVertex, а создать массив, то для массивов в OpenGL есть специальные вызовы массивного вывода. Ну и утверждается, что по сравнению с примитивным такой способ быстрее (кто бы сомневался) в 10 раз.

Но я не остановился на этом, и продолжая упорно серфить, таки пролез на внезапно обнаружившийся третий уровень, который - в свою очередь - тоже составлял всего 10% от предыдущего. Там было написано: вы что, массивы в обычной ОЗУ создаете? Их надо делать в видеопамяти! И это дает прирост скорости рендеринга сцены... еще в 100(!!!) раз.

При этом было замечено, что чем дальше в лес, тем толще партизаныбольше версия OpenGL (1.2 -> 1.4 -> 1.5 и т.д.), тем удобнее эти самые пакетные функции вывода. И останавливалось оно все на чем-то вроде glInterleavedArrays. Но везде, где висели списки этих API, почему-то ничего не говорилось о боле старших версиях OpenGL - 2.x, 3.x и - уже доступная в этом году - 4.x. Поэтому я полез копать дальше.

И тут начались приколы, так сказать, "back to the universe". Дело в том, что с версии 2.0 в OpenGL появились шейдеры. Для тех кто не в танке (хотя я пишу этот пост скорее для тех, для кого как, для меня, OpenGL - пускай в силу причин малых - оказался в стадии изучения, а не пренебрежения или наоборот, полного знания) шейдеры -это маленькие программы, которыми можно стало делать что-то внутри самого OpenGL. Но вот что именно ими делать (и нужно ли это мне), как-то ускользало от понимания... Пока я не стал смотреть, что именно менялось от версии к версии.

Итак, изначально был glBegin/glEnd и между ними - рендеринг по одной точке функциями glVertex.
Потом добавили glVertexPointer (на буфер), и другие pointer-ы (на всякие там цвета, текстуры и нормали).
Закончилась эта стадия, как я писал чуть выше, функцией glInterleavedArrays и работой с буферами в видеопамяти (OpenGL 1.5).

В следующей версии (уже 2.0) буфера выкинули из основной памяти - они теперь только в video-RAM, и выкатили пробный шар - в виде чуточки шейдеров.

А дальше (по мере развития версий 2.x) Пятачку так понравились шейдеры, что он стал давить кнопку delete непрерывно.

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

А потом удалили... glRotate, glTranslate и вообще все те вещи, по которым неподготовленный программист узнает OpenGL на всех этих сайтах с документацией и книжками! Т.е. теперь чтобы умножить матрицы, надо тоже написать шейдерную функцию, которая это делает, скомпилировать ее, и дернуть откуда-то посередине из скоего кода (скажем, как у меня - внутри операторов матриц на C++).

В итоге к версии 3.3 сформировалось уже ДВА OpenGL'я: [модер]новый (где все исключительно на шейдерах плюс совсем немножко утилитных функций для их загрузки, вызова и компиляции) и специально оставленная дырка для новичков: compatibility+depricated режим.

Ну и окончательно это завершилось выходом OpenGL 4.0/4.1 в совсем недавно закончившемся 2010-том году, который соответствует видеокартам уровня "DirectX 10/11".

Получились занятными ровно три факта:

1. OpenGL надо изучать уже не так, как везде написано!
2. Если следовать классическим путем, то лишь одна тысячная доля информации в интернете по современному использованию OpenGL дает прирост производительности в тысячу раз!!! Надо сразу лезть изучать GLSL (The OpenGL Shading Language).
3. Мне чрезвычайно понравилось, что когда-нибудь в следующий раз я смогу доделать свои матрицы, оптимизируя их умножения и другие операции не на ассемблере, а на шейдерном языке.

Ну и наконец, никто не мешает реализовать на шейдерах скажем, функцию нейросети или обработку фильтров видео... что уж вам больше нравится.
Tags: c++, glsl, opengl, матрицы, шейдеры

  • Post a new comment

    Error

  • 4 comments

[info]teewoon

January 8 2011, 03:28:03 UTC 1 year ago

Фанаты распределенных вычислений одними из первых запользовали возможности видеокарт. Практически как только появилось.

[info]atz_2085

January 8 2011, 14:34:05 UTC 1 year ago

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

[info]Denis Gorodetskiy

July 5 2011, 01:27:40 UTC 10 months ago

Хорошо б посмотреть на это чудо

[info]atz_2085

July 5 2011, 19:11:32 UTC 10 months ago

Почему бы и нет?

Можно уже не только почитать или посмотреть, но уже и купить:

http://nvworld.ru/files/old/docs/3dmon.html

http://www.hifi-install.ru/news/Kompaniya_NeyrOK_obyavlyaet_o_zavershenii_etapa_razrabotki_3D-displeya_i_perehodu_k_ego_proizvodstvu_i_prodazham

http://old.osp.ru/text/print/302/3140.html
Create an Account
Forgot your login or password?
Facebook Twitter More login options
English • Español • Deutsch • Русский…