Рендеринг SVG с OpenGL (и OpenGL ES)
в настоящее время я изучаю возможность рендеринга векторной графики из SVG-файла с использованием OpenGL и OpenGL ES. Я намерен нацелиться на Windows и Android. Моим идеальным решением было бы иметь минимальную библиотеку C, которая генерирует полигональную триангуляцию из данного файла SVG. Затем он будет генерировать стандартные вызовы OpenGL или OpenGL ES и использовать список отображения или vbo для оптимизации при перерисовке. Я бы просто нарисовал список отображения, чтобы нарисовать векторное изображение после перевода и вращающийся, что позволяет мне смешивать это с другими вызовами OpenGL.
пока я вижу, что предложения в первую очередь использовать QT или Каир. - Это не вариант, учитывая, что я хочу управлять своим собственным контекстом OpenGL без раздутых библиотек (в контексте того, что я пытаюсь достичь). И это не подходит для Android.
второй вариант-использовать библиотеки, которые оказывают текстуру. Хотя это может быть нормально для статической векторной графики, это не эффективный или возможный вариант для игры, где масштабирование и вращения происходят часто.
В-третьих есть возможность использования OpenVG. Есть некоторые реализации opensource спецификации OpenVG (ShivaVG и т. д.), Но мне еще предстоит найти библиотеку, которая способна генерировать соответствующие вызовы OpenVG из данного файла SVG во время выполнения, и я не вижу, как оптимизировать это, как мы могли бы пожелать с помощью списка отображения или vbo.
все три метода имеют ограничения. Я считаю наиболее перспективным опция использует реализацию OpenVG, если другого решения не существует. Итак, мой вопрос в том, есть ли какие-либо библиотеки, которые делают то, что я хочу, или близко к тому, что я хочу? Если нет, то есть ли веская причина, почему нет? И было бы лучше, чтобы попытаться сделать это с нуля, а?
6 ответов:
From 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, если я правильно прочитал код). Поэтому, даже если вы скомпилируете его с помощью NDK Android, вы будете нужно изменить код ( например, я видел несколько glVertex3f вокруг, но они, похоже, не очень нужны... надеюсь на лучшее). Другой вариант, конечно, портировать код с C на Java. Может быть, не так больно, как вы могли себе представить.
удачи !
мой ответ будет касаться отображения векторной графики с OpenGL в целом, потому что все решения этой проблемы могут поддерживать довольно тривиально SVG в частности, хотя никто не поддерживает анимированные SVGs (SMIL). Поскольку ничего не было сказано об анимации, я предполагаю, что вопрос подразумевал только статические SVGs.
во-первых, я бы не стал беспокоиться ни о чем OpenVG, даже о MonkVG, который, вероятно, является самой современной, хотя и неполной реализацией. Комитет OpenVG имеет сложенный в 2011 году, и большинство, если не все реализации являются abandonware или в лучшем случае устаревшим программным обеспечением.
с 2011 года, состояние искусства Марк Kilgard ребенка, NV_path_rendering, который в настоящее время является только расширением поставщика (Nvidia), как вы уже могли догадаться из его названия. Есть много материалов по этому поводу:
- https://developer.nvidia.com/nv-path-rendering NVIDIA hub, но некоторые материалы на целевой странице не являются большинство до-чтобы-дата
- http://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/opengl/gpupathrender.pdf Сигграф 2012 бумага
- http://on-demand.gputechconf.com/gtc/2014/presentations/S4810-accelerating-vector-graphics-mobile-web.pdf презентация GTC 2014
- http://www.opengl.org/registry/specs/NV/path_rendering.txt официальное расширение doc
вы конечно можете загрузите SVGs и такие https://www.youtube.com/watch?v=bCrohG6PJQE. Они также поддерживают синтаксис PostScript для путей. Вы также можете смешивать рендеринг пути с другими материалами OpenGL (3D), как показано на:
NV_path_rendering теперь используется библиотекой Skia Google за кулисами, когда она доступна. (Nvidia внесла код в конце 2013 и 2014 годов.) Один из разработчиков Каира (который также является сотрудником Intel), похоже, тоже любит его http://lists.cairographics.org/archives/cairo/2013-March/024134.html, хотя я [пока] не знаю о каких-либо конкретных усилиях для Каира использовать 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, которые пришли и ушли с течением времени, вы делаете большую ставку, используя что-то не поддерживается крупным поставщиком, по моему скромному мнению.
в настоящее время я изучаю возможность рендеринга векторной графики из файла 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 backends) для рисования. В большинстве случаев он использует шейдеры и все визуализируется в текстуру, библиотека очень гибкая, что позволяет вам адаптироваться к вашим конкретным потребностям, таким как изменение визуализируемой сцены, ее преобразование и т. д. Потому что рисунок gl всегда делается в текстуру.
пока я вижу, что предложения должны сначала использовать QT или Каир. - Это не вариант учитывая, что я хочу управлять своим собственным контекстом OpenGL без раздутых библиотек (в контекст того, что я пытаюсь достичь). И это не подходит для Android.
второй вариант-использовать библиотеки, которые оказывают текстуру. Хотя это может быть нормально для статическая векторная графика, это не эффективный или возможный вариант для игр, где масштабирование и вращения происходят часто.
в частности в случае GL backend enesim не создает GLX (или любой другой контекст, зависящий от окна), вы должны предоставить его, поэтому он отлично адаптируется к вашей ситуации, поскольку он использует только вызовы GL.
единственным недостатком является то, что библиотека еще не завершена с точки зрения поддержки gl или полной поддержки SVG spec, но в зависимости от ваших потребностей, мне кажется, что это хороший вариант.
нужно сказать, что рендеринг SVG или OpenVG с OpenGL или OpenGL ES-это принципиально плохая идея. Есть причины, по которым реализации OpenVG все так медленно и в значительной степени заброшены. Процесс тесселяции путей (основа всего рендеринга SVG/OpenVG) в списки треугольников, как того требует OpenGL, принципиально медленный и неэффективный. Это в основном требует вставки алгоритма сортировки/поиска в конвейер 3D-рендеринга, что снижает производительность. Существует также проблема в том, что требуется схема динамического выделения памяти, поскольку размер набора данных неизвестен, поскольку SVG не ограничивает сложность геометрии пути. Очень плохой дизайн.
SVG и OpenVG были созданы разработчиками, которые мало понимали, как на самом деле работают современные 3D-графические аппаратные средства (списки треугольников). Они были созданы, чтобы быть открытой альтернативой Adobe Flash, которая также имеет ту же ошибочную архитектуру, которая сделала Flash оскорбленным в индустрия для непредсказуемой работы.
мой совет-переосмыслить свой дизайн и использовать списки треугольников OpenGL напрямую. Возможно, вам придется написать больше кода, но ваше приложение будет работать примерно в тысячу раз лучше, и вы можете легче отлаживать свой код, чем кто-то другой.
вы можете посмотреть на AmanithVG, Они, кажется, реализовали хорошие пути - > треугольники конвейера. Я пробовал пример iOS GL tiger, и кажется, что триангуляция не является реальным узким местом.
Comments