вторник, 7 сентября 2010 г.

VBO state reduction

Я всё же придерживаюсь мнения, что правильный способ разгона рендера - это уменьшение state changes. Я реализовал наиболее оптимальную загрузку всех костей в bindable buffers (всё-таки DX 10 фича на Mac!), на очереди встала оптимизация VBO.

Т. к. каждая часть модели (голова, туловище, руки и т. д.) в портируемом проекте находится в отдельном буфере вершин/индексов (в терминологии движка - vertex/index stream), то приходится делать множество вызовов glBindBuffer() плюс делать setup вершинных атрибутов через glVertexAttribArrayPointer(), и я вам скажу, что количества вызовов получаются страшными |(o_0)| Поэтому вполне закономерно меня посетила такая идея: рассортировать всю геометрию по типам формата вершины и загнать все кусочки VB/IB в один большой буфер вершин. Тогда достаточно лишь один раз установить VB/IB и задать смещения для атрибутов, а дальше уже рисовать нужную геометрию - экономия state changes немалая.

К сожалению, в GlukoGL 2.0 отсутствует возможность указать base vertex location непосредственно в DIP-e, а только через смещение во всё той же злополучной glVertexAttribArrayPointer(). Если мы объединяем все VB в один, то очевидно что индексы во всех индексных буферах (кроме первого) становятся невалидными. Поэтому при сливании индексов в общий IB к ним добавлялся текущий base vertex location общего VB. Кроме того, индексы в "обрезках" IB хранились в формате USHORT (что очевидно), для общего IB они преобразовывались в UINT, т. к. адресация запросто вылезает за 2^16 вершин. Также skinned модели содержали свои LOD-ы в "обрезках", поэтому дополнительно пришлось повозиться с оффсетами по памяти и другой подобной белибердой.

Не буду описывать все проблемы, которые возникли у меня с GlukoGL на NVIDIA, пока я реализовывал "склейку". Скажу только, что схема заработала и геометрия успешно рисуется через новый codepath. State changes, такие как glBindBuffer / glVertexAttribArrayPointer / glEnableVertexAttribArray уменьшились существенно - в несколько раз.

Что до производительности - в случае небольшого кол-ва видимой геометрии есть видимый прирост fps, в случае тяжёлых сцен прирост держится "на честном слове" и частенько уходит в 0. Мы всё ещё упираемся во всякие гадкие вызовы GlukoGL, которые просаживают произодительность. Ну и как оптимизировать кучу DIP-ов при текущем data set-е - тоже неясно :(

1 комментарий:

  1. Откуда это уничижительное отношение к OpenGL? Ведь были же времена, когда Joe был в наших рядах...

    ОтветитьУдалить