Подтвердить что ты не робот

Рендеринг SVG с OpenGL (и OpenGL ES)

В настоящее время я изучаю возможность рендеринга векторной графики из файла SVG с использованием OpenGL и OpenGL ES. Я намерен настроить таргетинг на Windows и Android. Моим идеальным решением было бы иметь минимальную библиотеку C, которая генерирует триангуляцию многоугольника из данного SVG файла. Затем он будет генерировать стандартные вызовы OpenGL или OpenGL ES, а также использовать список отображения или vbo для оптимизации при перерисовке. Я бы просто рисовал список отображения, чтобы нарисовать векторное изображение после перевода и поворота, что позволило мне смешать это с другими вызовами OpenGL.

До сих пор я вижу, что предложения состоят в том, чтобы сначала использовать QT или Cairo. - Это не вариант, учитывая, что я хочу управлять своим собственным контекстом OpenGL без раздутых библиотек (в контексте того, чего я пытаюсь достичь). И это не подходит для Android.

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

В-третьих, существует возможность использования OpenVG. Существуют некоторые версии OpenVG для OpenVG (ShivaVG и т.д.), Но я еще не нашел библиотеку, которая способна генерировать соответствующие вызовы OpenVG из данного SVG файла во время выполнения, и я не вижу, как оптимизировать это как мы могли бы пожелать со списком отображения или vbo.

Все три метода имеют ограничения. Я думаю, что наиболее перспективным вариантом является использование OpenVG-реализации, если не существует другого решения. Поэтому мой вопрос: есть ли там библиотеки, которые делают то, что я хочу, или близкие к тому, что я хочу? Если нет, есть ли веская причина, почему нет? И было бы лучше попытаться сделать это с нуля?

4b9b3361

Ответ 1

Из http://shivavg.svn.sourceforge.net/viewvc/shivavg/trunk/src/shPipeline.c?revision=14&view=markup:

static void shDrawVertices(SHPath *p, GLenum mode)
{
int start = 0;
int size = 0;

/* We separate vertex arrays by contours to properly
handle the fill modes */
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, sizeof(SHVertex), p->vertices.items);

while (start < p->vertices.size) {
size = p->vertices.items[start].flags;
glDrawArrays(mode, start, size);
start += size;
}

glDisableClientState(GL_VERTEX_ARRAY);
}

Поэтому он использует VBO. Поэтому я предлагаю создать собственный синтаксический анализатор SVG/использовать предварительно сделанный и переадресовывать вызовы в ShivaVG.

У вас все еще есть проблема, что ShivaVG находится в C (а не на Java) и создает контекст opengl (а не opengles, если я правильно прочитал код). Поэтому, даже если вы скомпилируете его с помощью Android NDK, вам придется изменить код (например, я видел несколько glVertex3f, но они, похоже, не очень нужны... надеюсь на лучшее). Другим вариантом, конечно же, является перенос кода с C на Java. Может быть, не так больно, как вы могли себе представить.

Удачи!

Ответ 2

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

Во-первых, я бы ни на что не потрудился ни с чем OpenVG, даже с MonkVG, который, вероятно, является самой современной, хотя и неполной. Комитет OpenVG сложен в 2011 году, и большинство, если не все реализации, являются отказоустойчивыми или в лучшем случае устаревшим программным обеспечением.

С 2011 года современное состояние - ребенок Марка Килгарда, NV_path_rendering, который в настоящее время является только расширением поставщика (Nvidia), как вы уже догадались с его имени. На нем много материалов:

Конечно, вы можете загружать SVG и такие https://www.youtube.com/watch?v=bCrohG6PJQE. Они также поддерживают синтаксис PostScript для путей. Вы также можете смешивать рендеринг маршрута с другими материалами OpenGL (3D), как показано на странице:

NV_path_rendering теперь используется библиотекой Google Skia за кулисами, когда это доступно. (Nvidia внесла свой код в конце 2013 и 2014 годах.) Кажется, что один из разработчиков Cairo (который также является сотрудником Intel) http://lists.cairographics.org/archives/cairo/2013-March/024134.html, хотя я еще не знаю каких-либо конкретных попыток использовать cairo для NV_path_rendering.

NV_path_rendering имеет несколько незначительных зависимостей от фиксированного конвейера, поэтому в OpenGL ES может возникнуть неприятность. Этот вопрос зафиксирован в официальном документе расширения, указанном выше. Для обхода см., Например, что сделал Skia/Chromium: https://code.google.com/p/chromium/issues/detail?id=344330

У выскочки, имеющей еще меньшую (или совершенно нет) поддержку поставщика или академический блеск, NanoVG, который в настоящее время разрабатывается и поддерживается. (https://github.com/memononen/nanovg) Учитывая количество 2D-библиотек поверх OpenGL, которые приходят и уходят со временем, вы делаете большую ставку, используя что-то не поддержанный крупным поставщиком, по моему скромному мнению.

Ответ 3

Отметьте MonkVG реализацию OpenVG как API поверх OpenGL ES.

Кроме того, для SVG-рендеринга поверх проверки OpenVG (MonkVG) MonkSVG.

MonkVG был создан для платформ iOS, OSX и Android.

Я являюсь автором обеих библиотек и буду рад ответить на любые вопросы.

Ответ 4

В настоящее время я изучаю возможность рендеринга векторной графики из файла SVG > с использованием OpenGL и OpenGL ES. Я намерен настроить таргетинг на Windows и Android. Мое идеальное решение было бы иметь минимальную библиотеку C, которая генерирует триангуляцию многоугольника из заданного SVG файл. Затем он будет генерировать стандартные вызовы OpenGL или OpenGL ES и использовать дисплей список или vbo для оптимизации при перерисовке. Я бы просто нарисовал список отображения, чтобы нарисовать векторное изображение после перевода и поворота, что позволяет мне смешивать это с другими вызовами OpenGL > .

Если вы хотите преобразовать векторные фигуры SVG в OpenGL | ES, я предлагаю сделать парсер и логику самостоятельно. Обратите внимание, что SVG - это огромная спецификация с различными функциями, такими как серверы рисования (градиенты, шаблоны...), ссылки, фильтры, обрезка, обработка шрифтов, анимация, сценарии, ссылки и т.д.

Если вам нужна полная поддержка svg, тогда есть библиотека http://code.google.com/p/enesim, называемая egueb (и особенно esvg), которая использует enesim (библиотека рендеринга, в которой есть программное обеспечение и opengl) для чертежа. В большинстве случаев он использует шейдеры, и все визуализируется в текстуре, библиотека очень гибкая, позволяя вам адаптироваться к вашим конкретным потребностям, например, изменять визуализированную сцену, преобразовывать ее и т.д. Поскольку чертеж gl всегда делается в текстуре.

До сих пор я вижу, что предложения состоят в том, чтобы сначала использовать QT или Cairo. - Это не вариант учитывая, что я хочу управлять своим собственным контекстом OpenGL без раздутых библиотек (в контекст того, чего я пытаюсь достичь). И это не подходит для Android.

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

В частном случае gl backend enesim не создает GLX (или любой другой зависимый от окна контекст), вы должны его предоставить, поэтому он отлично адаптируется к вашей ситуации, поскольку он использует только вызовы GL.

Единственный недостаток заключается в том, что библиотека еще не завершена с точки зрения поддержки gl или полной поддержки спецификации SVG, но в зависимости от ваших потребностей мне кажется хорошим вариантом.

Ответ 5

Нужно сказать, что рендеринг SVG или OpenVG с OpenGL или OpenGL ES в корне плохая идея. Есть основания, что реализация OpenVG настолько медленная и в значительной степени заброшена. Процесс тесселирующих путей (основы всех SVG/OpenVG-рендеринга) в списки треугольников, как требуется OpenGL, в корне медленный и неэффективный. В основном это требует вставки алгоритма сортировки/поиска в конвейер 3D-рендеринга, который снижает производительность. Существует также проблема, что требуется схема распределения динамической памяти, поскольку размер набора данных неизвестен, поскольку SVG не ограничивает сложность геометрии пути. Очень плохой дизайн.

SVG и OpenVG были созданы разработчиками, которые мало понимали, как работают современные аппаратные средства 3D-графики (списки треугольников). Они были созданы, чтобы быть открытой альтернативой Adobe Flash, которая также имеет ту же ошибочную архитектуру, которая сделала Flash оскорбленным в отрасли для непредсказуемой производительности.

Мой совет - переосмыслить свой дизайн и использовать списки треугольников OpenGL. Возможно, вам придется написать больше кода, но ваше приложение будет работать примерно в тысячу раз лучше, и вы сможете более легко отлаживать свой код, чем кто-либо.

Ответ 6

Вы можете взглянуть на AmanithVG, они, похоже, реализовали хороший путь → треугольник. Я пробовал пример тигра iOS GL, и кажется, что триангуляция не является настоящим узким местом.