Рендеринг SVG с OpenGL (и OpenGL ES) - PullRequest
54 голосов
/ 09 июня 2011

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

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

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

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

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

Ответы [ 6 ]

12 голосов
/ 06 августа 2014

Мой ответ будет касаться отображения векторной графики с 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 isтеперь используется библиотекой 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, которые приходили и уходили со временем, вы делаете большую ставку, используя что-то, что не поддерживается крупным поставщиком, по моему скромному мнению.

12 голосов
/ 23 июня 2011

Проверьте MonkVG реализацию API, подобную OpenVG, поверх OpenGL ES.

Также для рендеринга SVG поверх проверки OpenVG (MonkVG) MonkSVG .

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

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

7 голосов
/ 08 августа 2014

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

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

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

7 голосов
/ 08 ноября 2012

В настоящее время я изучаю возможность рендеринга векторной графики из файла 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 или Каир.- Это не вариант, учитывая, что я хочу управлять своим собственным контекстом OpenGL без раздутых библиотек (в контексте того, чего я пытаюсь достичь).Также это не подходит для Android.

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

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

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

3 голосов
/ 09 июня 2011

С 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.Может быть, не так больно, как вы могли себе представить.

Удачи!

1 голос
/ 08 марта 2015

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

...