Название: Архитектура VBO Отправлено: Igors от Декабрь 17, 2014, 10:32 Добрый день
VBO (vertex buffer object) - это данные хранящиеся на видеокарте (напр вертексы, нормали, полигоны, цвет). Использование VBO заметно ускоряет рисование. Приложение оперирует с индексами этих данных (фактически это хендлы). Сделал просто - храню хендл вместе с массивом данных. Напр контейнер вертексов имеет хендл VBO и.т.д. Это кажется очевидным - ведь исходная геометрия не меняется. А если вертексы изменились - тогда и данные VBO пере-создаются. Однако вылезла неприятная деталь - в одном из окон пользователь может указать так называемый "flat shading", в то время как в других должен показываться gourand, phong и др. К сожалению, для "flat" нужна др геометрия подаваемая в OpenGL, т.е. др полигоны, вертексы. Эту дыру я просто заткнул, для режима "flat" не использую VBO, а рисую по-старинке glBegin/glEnd. Это конечно позорно медленно, зато у меня нет никаких доп данных и минимум кода. Поскольку flat используется редко, в году раз - проконало. Но появилась новая фича - пользователь хочет иметь возможность показа измельченной (грубо говоря триангулированной) модели, причем "виртуально", деталированная модель должна храниться на видео (а не занимать память приложения). И тут моя простая организация данных стала трещать по всем швам. И почему-то вспомнилось: "кривая архитектура", "изменить архитектуру приложения" и.т.п. не раз звучавшие на этом форуме :) Поэтому внимательно слушаю Ваши рекомендации. Спасибо Название: Re: Архитектура VBO Отправлено: __Heaven__ от Декабрь 17, 2014, 11:40 Буфер с продублированными нормалями так и не появилось желание использовать?
Название: Re: Архитектура VBO Отправлено: __Heaven__ от Декабрь 17, 2014, 11:47 Ни разу не пробовал, но, возможно, прокатит следующее:
Хранить нормали к каждому треугольнику в текстуре. В вершинном шейдере смотреть id выводимой вершины, делить её на 3, тем самым получая id нормали в текстуре. Передавать этот id (нормали) в фрагментный шейдер. А в том извлекать нормаль и применять к цвету фрагмента. Название: Re: Архитектура VBO Отправлено: Igors от Декабрь 17, 2014, 12:26 Буфер с продублированными нормалями так и не появилось желание использовать? Ну вот за это меня точно выгонят и больше не возьмут :)Ни разу не пробовал, но, возможно, прокатит следующее: Утопия хотя бы потому что каждый фейсет может иметь любое вертексов от 1 до 4 включительно. Хранить нормали к каждому треугольнику в текстуре. В вершинном шейдере смотреть id выводимой вершины, делить её на 3, тем самым получая id нормали в текстуре. Передавать этот id (нормали) в фрагментный шейдер. А в том извлекать нормаль и применять к цвету фрагмента. Не надо сваливаться с специфику OpenGL (все равно без толку), а посмотрим с точки зрения пресловутой архитектуры. Примерная схема Исходные данные (RAM) ---> данные для "прямого" рисования (VBO) -----------------------------> данные для "фейсетного" рисования (???) -----------------------------> данные для "детального" рисования (должны быть в VBO) Понятно что я должен создать нужные буфера VBO, но где хранить их хендлы и как ими управлять? Название: Re: Архитектура VBO Отправлено: __Heaven__ от Декабрь 17, 2014, 13:51 У вас имеются точки и линии, которые нужно освещать?
Разбивать квадратики на треугольники тоже не вариант? (В 3.0 GL_QUADS deprecated). Передавать id нормали в текстуре для каждой вершины через VBO? Но тут мало что сэкономим. Буфер с продублированными нормалями так и не появилось желание использовать? Ну вот за это меня точно выгонят и больше не возьмут :)А чем это хуже, чем рисовать phong? Там такое же количество нормалей необходимо. Кстати, их можно подсчитать/продублировать налету (при включении режима flat) и засунуть в vbo, оставив только хэндл - данные из RAM можно удалить. Ну или рассчитывать нормали при каждой прорисовке и выводить их без участия VBO, по завершению прорисовки затирать. Название: Re: Архитектура VBO Отправлено: Igors от Декабрь 17, 2014, 16:18 У вас имеются точки и линии, которые нужно освещать? Точки и линии могут освещаться, как и wireframe (аттач).А чем это хуже, чем рисовать phong? Там такое же количество нормалей необходимо. Возьмем грубую модель сферы, она имеет напр 144 полигона (для простоты - все треугольники) и 74 вертекса. Теперь мы хотим рисовать с фейсетными нормалями. Значит у каждого треугольника "свои" 3 вертекса, итого 144 * 3 = 432. Что Вы скажете о программисте который увеличил число базовых данных в 432 / 74 = 5.83 раза? :)Не надо искать какие-то "железячные" решения, лезть в шейдеры, id и.т.п - все это мелко. Вопрос был об архитектуре. Поверьте, она есть даже с OpenGL :) Название: Re: Архитектура VBO Отправлено: __Heaven__ от Декабрь 17, 2014, 17:07 Может gl_InstanceID (https://www.opengl.org/sdk/docs/man/html/gl_InstanceID.xhtml) чем-то поможет. Только он доступен с OpenGL 3.1.
Название: Re: Архитектура VBO Отправлено: __Heaven__ от Январь 31, 2016, 12:18 Нашлось ли решение?
Название: Re: Архитектура VBO Отправлено: Igors от Январь 31, 2016, 12:35 Нашлось ли решение? Для режима "flat" нет, так и рисую glBegin/glEnd. Для показа деталированной модели - даНазвание: Re: Архитектура VBO Отправлено: Racheengel от Январь 31, 2016, 15:31 Нашлось ли решение? Для режима "flat" нет, так и рисую glBegin/glEnd. Для показа деталированной модели - давместо glBegin/glEnd можно хотя бы glDrawArrays заюзать, будет заметно быстее. Название: Re: Архитектура VBO Отправлено: Igors от Январь 31, 2016, 15:54 вместо glBegin/glEnd можно хотя бы glDrawArrays заюзать, будет заметно быстее. Ну вот такой я неграмотный, про glDrawArrays/glDrawElements мне ничего не известно :'( Вы тему-то читайте Название: Re: Архитектура VBO Отправлено: Racheengel от Январь 31, 2016, 23:48 Так а что надо пользователю? Видеть либо модель с текстурой, либо wireframe? Какая тогда разница в организации полигонов?
Название: Re: Архитектура VBO Отправлено: __Heaven__ от Февраль 01, 2016, 06:54 Racheengel, там проблема в нормалях. Требуется задавать нормаль для примитива, а не вершины. А opengl такого не позволяет сделать при glDrawArrays/glDrawElements не дублируя координаты, нормали.
Название: Re: Архитектура VBO Отправлено: Racheengel от Февраль 01, 2016, 11:36 Racheengel, там проблема в нормалях. Требуется задавать нормаль для примитива, а не вершины. А opengl такого не позволяет сделать при glDrawArrays/glDrawElements не дублируя координаты, нормали. То есть полигоны (их координаты) не меняются? Если да, то нормали я бы генерировал/хранил отдельно для каждого случая и переключался бы на нужные данные при смене view. Как вариант. Название: Re: Архитектура VBO Отправлено: Igors от Февраль 01, 2016, 12:03 То есть полигоны (их координаты) не меняются? Если да, то нормали я бы генерировал/хранил отдельно для каждого случая и переключался бы на нужные данные при смене view. Как вариант. Ладно, начнем "от печки". Сколько вертексов имеет простейший кубик? Человек знакомый с OpenGL ответит 24 (а не 8 как начинающий). Зачем 24 если углов-то всего 8? Потому что OpenGL рисует "по вертескам" (а не "по фейсам"). Один вертекс = одна нормаль и одна текстурная координата, счетчики должны совпадать во всех подаваемых рисованию массивах. Разные фейсы могут использовать разные вертексы, но при этом будут использовать и их нормали. Если мы хотим видеть "грани" (как у кубика) то вынуждены создать вертексы для каждой фейсы (грани). Итого 6 * 4 = 24. В каждом углу будут 3 вертекса с разными нормалями. Как говорят "все расшарено"Название: Re: Архитектура VBO Отправлено: Racheengel от Февраль 01, 2016, 12:39 Сколько вертексов имеет простейший кубик? Человек знакомый с OpenGL ответит 24 (а не 8 как начинающий). Сам по себе кубик имеет 8 вертексов, остальное - это представление модели, которая визуализируется. Зависит от того, как рисовать. Если квадами - то 24, если треугольниками - то, считаем, 36 (по 6 точек на грань, если без стрипов). А если индексами, то зададите вы все те же 8 вертексов, плюс массивы индексов. Как я понимаю, вы рисуете квадами. Понятно, что для различных методов шейдинга вам нужно различное представление модели визулизации. Но количество вертексов то у вас не изменяется. Задавайте вертексы отдельным массивом, и отдельными массивами - нормали для каждого из режимов. При отрисовке будете между ними переключаться. Если критичен расход памяти - то массивы нормалей придется перегенерировать заново. Название: Re: Архитектура VBO Отправлено: Igors от Февраль 01, 2016, 13:28 Зависит от того, как рисовать. Если квадами - то 24, если треугольниками - то, считаем, 36 (по 6 точек на грань, если без стрипов). А если индексами, то зададите вы все те же 8 вертексов, плюс массивы индексов. Кубик из тр-ков имеет 12 фейсов и те же самые 24 вертекса. Тут уже одни вертексы шарятся, другие нет. Просто берем квады и каждый бьем на 2 тр-ка, никакие новые вертексы не нужны. Создать 36 можно но бессмысленно.Сам по себе кубик имеет 8 вертексов, остальное - это представление модели, которая визуализируется. Рендерится конкретное представление, а не что там "само по себе/существу"Но количество вертексов то у вас не изменяется. Для кубика нет, у него и так все "расщарено", а в общем случае меняется (аттач)Что ж так плаваете в азах? Это же на уровне "популярных знаний" :'( Название: Re: Архитектура VBO Отправлено: Racheengel от Февраль 01, 2016, 14:05 Для кубика нет, у него и так все "расщарено", а в общем случае меняется (аттач) Так я про это и спрашивал - что меняется для каждого из представлений? Ну, теперь понятно, что "меняется все" - и нормали, и полигоны. Т.е. есть варианты с различной детализацией. О каких объемах данных идет речь? Играет ли роль скорость визуализации? Ну т.е. это live preview или пользователю пара секунд не критична при свитче отображений? В общем случае вам все равно нужно для каждого случая генерировать разные данные. Вопрос только в том, чем мы будем жертвовать - памятью или производительностью? Название: Re: Архитектура VBO Отправлено: Igors от Февраль 01, 2016, 14:53 Так я про это и спрашивал - что меняется для каждого из представлений? Полигоны никто не трогал, меняются только нормали. Оба варианта нормалей у меня в памяти всегда есть, они по-любому нужны. Но с гребаным OpenGL мне никак не удается просто "заменить нормали".Ну, теперь понятно, что "меняется все" - и нормали, и полигоны. О каких объемах данных идет речь? Играет ли роль скорость визуализации? Ну т.е. это live preview или пользователю пара секунд не критична при свитче отображений? Это все рассказано в первом же посте. Интересует решение без жертв, или, на худой конец, доказательство невозможности такового.В общем случае вам все равно нужно для каждого случая генерировать разные данные. Вопрос только в том, чем мы будем жертвовать - памятью или производительностью? [OFF]К сожалению, Вы взяли на вооружение стиль Верес'а, по-простому говоря "на шару". Цитировать Напишу-ка так. Не, я конечно не уверен, да и занимался этим немного и хз когда. Ну а вдруг прокатит? А если нет - не беда, вот мне и растолкуют почему. Так я и буду получать знания через ля-ля на форуме, без всяких усилий. Это не очень корректно по отношению к ТС - мне нетрудно разжевать, но не для чисто праздного любопытства. А главное - минимум 5-летний опыт Верес'а показывает что такой метод ничего не дает. Результаты ужасны, причем все хуже и хуже :'([/OFF] Название: Re: Архитектура VBO Отправлено: Racheengel от Февраль 01, 2016, 15:51 Полигоны никто не трогал, меняются только нормали. Оба варианта нормалей у меня в памяти всегда есть, они по-любому нужны. Но с гребаным OpenGL мне никак не удается просто "заменить нормали". У Вас на скриншоте 2 модели шара - высокополигональная слева и низкополигональная справа. Каким образом тогда Ваша цитата связана с Вашим скриншотом? Они взаимоисключающие. Либо Вы делаете higl-poly & low-poly model для разных случаев (естественно, и нормали в этом случае разные)... Либо, если меняются ТОЛЬКО нормали - то рисуйте через glDraw[Arrays|Elements], тогда у Вас будет возможность безболезненно переключаться между массивами нормалей :) Оффтоп: а при чем тут Верес и его стиль ??? Название: Re: Архитектура VBO Отправлено: __Heaven__ от Февраль 01, 2016, 16:06 Racheengel, в обоих вариантах одинаковое количество полигонов. Меняются только нормали. Это обман зрения.
Название: Re: Архитектура VBO Отправлено: Racheengel от Февраль 01, 2016, 16:29 Racheengel, в обоих вариантах одинаковое количество полигонов. Меняются только нормали. Это обман зрения. Да, но: Цитировать Но появилась новая фича - пользователь хочет иметь возможность показа измельченной (грубо говоря триангулированной) модели Я так понимаю, что тут не только в нормалях разница, а имеется в виду высокополигональная модель, которую Игорь не хочет хранить в памяти, а хочет запузырить на видеокарту через VBO :) Или опять не так? Название: Re: Архитектура VBO Отправлено: Igors от Февраль 02, 2016, 10:51 Либо, если меняются ТОЛЬКО нормали - то рисуйте через glDraw[Arrays|Elements], тогда у Вас будет возможность безболезненно переключаться между массивами нормалей :) 2 полигона модели сферы что выше1-й ссылается на вертексы (0, 1, 2, 3) 2-й ссылается на вертексы (4, 5, 1, 0) // т.е. вертексы 0 и 1 шарятся этими полигонами Все вертексы имеют нормали для левой картинки выше. Также меня есть предвычисленные нормали для обоих полигонов. Ну и как я их "подменю"? Название: Re: Архитектура VBO Отправлено: Racheengel от Февраль 02, 2016, 13:19 А как Вы нормали для каждой из сфер храните?
Я бы ожидал массивы такой же длины, как и для вертексов, с 4 нормалями на полигон. Т.е. для варианта 1 было бы: V = [v0, v1, v2, v3] [v4, v5, v1, v0] N1 = [n0, n1, n2, n3] [n4, n5, n6, n7] А для варианта 2: V = [v0, v1, v2, v3] [v4, v5, v1, v0] N2 = [m0, m1, m2, m3] [m4, m5, m6, m7] где n - нормали, рассчитанные для "модели 1", а m - нормали, рассчитанные для "модели 2". Далее с помощью glNormalPointer(N1) или glNormalPointer(N2) переключаетесь между ними. Надеюсь, написал понятно (Вы же используете glNormalPointer и glVertexPointer в коде?) Название: Re: Архитектура VBO Отправлено: Igors от Февраль 02, 2016, 13:35 Вы же используете glNormalPointer и glVertexPointer в коде? Вот как раз для них и не выходитА для варианта 2: Счетчики V и N(N2) должны быть одинаковы. Если 6 вертексов (v0..v5) то и нормалей будет использоваться 6 (а не 8 ). И если подаются одни и те же индексы v0, v1 для 2 полигонов, то и нормали будут юзаться одни и те же. Др словами у OpenGL ОДЫН индекс на все - про все. V = [v0, v1, v2, v3] [v4, v5, v1, v0] N2 = [m0, m1, m2, m3] [m4, m5, m6, m7] Пробовали учить человека играть в преферанс "на практике"? Цитировать .. а самая старшая черва ? Как это ужасно :).. а 6 пик - вистовать обязательно ? .. а мизер - это когда не брать взяток? ... ... Название: Re: Архитектура VBO Отправлено: Racheengel от Февраль 02, 2016, 13:54 Ок. Вроде я понял проблему. Похоже, ничего не остается, как дублировать вертексы. Имхо всяко лучше, чем тормозные glBegin/glEnd. Да, с одной стороны возрастет расход памяти на координаты вертексов, но с другой Вы можете тогда отказаться от массива индексов и использовать glDrawArrays.
Возможно, извращениями с шейдерами можно добиться лучших результатов, но тут я не советчик. Не юзал шейдеры ни разу. Но Вы так и не сказали, о каких объемах данных идет речь, насколько велики модели? Иногда лучше пожертвовать памятью ради производительности, перейти на 64-бит архитектуру, например. Название: Re: Архитектура VBO Отправлено: __Heaven__ от Февраль 02, 2016, 14:07 Я дополню. Если использовать буферы, то жертвовать придётся памятью GPU. Тем самым можно освободить ОЗУ.
Название: Re: Архитектура VBO Отправлено: Igors от Февраль 02, 2016, 15:11 Похоже, ничего не остается, как дублировать вертексы... Ну как-то Ваш вывод не блещет оригинальностью и/или свежими идеями :) И кроме банального "альтернатива скорость - расход памяти" напомню еще фактор "объем кода". Паршивенький glBegin/glEnd = один маленький метод, а вот "еще одно представление данных" - ой нетНо Вы так и не сказали, о каких объемах данных идет речь, "Общий случай" - юзер решает какие модели грузить и сколько. В общем мульены - дело давно рядовое.Возможно, извращениями с шейдерами можно добиться лучших результатов, но тут я не советчик. Не юзал шейдеры ни разу. В шейдере заставить использовать фейсетную нормаль - неск строк (если не одна). Но тут есть страшное НО - я не могу ограничиться только этим. Связавшись с фрагментным шейдером я должен выполнить ВСЕ операции (найти и отмапить все текстуры, обсчитать все источники света и.т.п.) и в конце-концов выдать на гора цвет (суб)пикселя. Др словами нормальной pipeline эта железяка не имеет, можно только перекрыть шейдинг целиком. Спрашивал на др форумах можно ли как-то найти дырочку чтобы туда вклиниться - ну пока без успеха :'(Название: Re: Архитектура VBO Отправлено: Igors от Февраль 02, 2016, 15:22 Я дополню. Если использовать буферы, то жертвовать придётся памятью GPU. Тем самым можно освободить ОЗУ. Так это собсно и есть тема для обсуждения. "Flat" рисование (правая сфера) было просто к слову (просто ситуевина принципиально та же). Обсуждение "кого же освобождать" лишено смысла - ясно что данные надо хранить на GPU. Итак вот у нас появилось "другое/альтернативное представление", в случае деталированной модели оно неизбежно, тут уже не заткнуть. И мы хотим "запузырить ее на видеокарту через VBO" :). Ваши действия? Название: Re: Архитектура VBO Отправлено: Racheengel от Февраль 02, 2016, 15:30 И кроме банального "альтернатива скорость - расход памяти" напомню еще фактор "объем кода". Паршивенький glBegin/glEnd = один маленький метод, а вот "еще одно представление данных" - ой нет Да ну, какой там объем то :) Пара вызовов glNormalPointer, glVertexPointer, да еще glDrawArrays в конце) Но если памяти жалко, можно фрагментами рендерить. Сгенерили часть данных в вектора - отрендерили - повторили. Других решений пока не вижу, тем более все равно у Вас нормали заранее просчитываются. А шейдеры, конечно, слишком уж узкоспециальное решение, согласен. Название: Re: Архитектура VBO Отправлено: Igors от Февраль 02, 2016, 16:01 Да ну, какой там объем то :) У Вас что там, Верес под капотом? :)Пара вызовов glNormalPointer, glVertexPointer, да еще glDrawArrays в конце) Ну да, ну да. А всю этажерку векторов позиция+нормаль+color+UV1+UV2..+UV8 папа Карло будет создавать и хранить? Но если памяти жалко, можно фрагментами рендерить. А не будет ли тогда glBegin/glEnd пошустрее?Сгенерили часть данных в вектора - отрендерили - повторили. Название: Re: Архитектура VBO Отправлено: Racheengel от Февраль 02, 2016, 16:26 А всю этажерку векторов позиция+нормаль+color+UV1+UV2..+UV8 папа Карло будет создавать и хранить? Но ведь между glBegin/glEnd у Вас тоже не пусто сейчас? :) А не будет ли тогда glBegin/glEnd пошустрее? Не уверен :) Когда мы от них на glDrawArrays переключились, получили как минимум 2х прироста. И это с создаванием этажерок в памяти и т.д. :) Название: Re: Архитектура VBO Отправлено: __Heaven__ от Февраль 02, 2016, 16:40 А вы случаем не тестили glDrawArrays против glDrawElements? По памяти второй экономичнее, а как по скорости отрисовки?
Название: Re: Архитектура VBO Отправлено: Igors от Февраль 02, 2016, 16:52 Но ведь между glBegin/glEnd у Вас тоже не пусто сейчас? :) Менее 50 строк, там никаких новых данных создавать не нужноА вы случаем не тестили glDrawArrays против glDrawElements? По памяти второй экономичнее, а как по скорости отрисовки? glDrawArrays побыстрее |