Renderizando SVG con OpenGL (y OpenGL ES)


Actualmente estoy investigando la posibilidad de renderizar gráficos vectoriales desde un archivo SVG usando OpenGL y OpenGL ES. Tengo la intención de apuntar a Windows y Android. Mi solución ideal sería tener una biblioteca C mínima que genere una triangulación de polígonos a partir de un archivo SVG dado. Esto generaría llamadas OpenGL u OpenGL ES estándar, y usaría una lista de visualización o vbo para la optimización al redibujar. Simplemente dibujaría una lista de visualización para dibujar la imagen vectorial después de traducir y rotando, lo que me permite mezclar esto con otras llamadas OpenGL.

Hasta ahora veo que las sugerencias son usar primero QT o Cairo. - Esta no es una opción dado que deseo administrar mi propio contexto OpenGL sin bibliotecas hinchadas (en el contexto de lo que estoy tratando de lograr). Tampoco es adecuado para Android.

La segunda opción es usar bibliotecas que representen una textura. Si bien esto podría estar bien para gráficos vectoriales estáticos, no es una opción eficiente o factible para juegos donde el escalamiento y las rotaciones ocurren con frecuencia.

En tercer lugar existe la posibilidad de usar OpenVG. Hay algunas implementaciones de código abierto de la especificación OpenVG (ShivaVG, etc.), pero todavía no he encontrado una biblioteca que sea capaz de generar las llamadas OpenVG apropiadas desde un archivo SVG dado en tiempo de ejecución, y no puedo ver cómo optimizar esto como podríamos desear con una lista de visualización o vbo.

Los tres métodos sufren limitaciones. Creo que la opción más prometedora es usar un OpenVG implementación si no existe otra solución. Así que mi pregunta es, ¿hay alguna biblioteca por ahí que haga lo que quiero, o cerca de lo que quiero? Si no, ¿ hay una buena razón por la que no? ¿Y sería mejor intentar hacer esto desde cero?

Author: Matt Esch, 2011-06-09

6 answers

Desde 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);
}

Así que usa un VBO. Así que sugeriría hacer su propio analizador SVG / usar uno pre-hecho, y reenviar las llamadas a ShivaVG.

Todavía tiene el problema de que ShivaVG está en C (y no en Java) y crea un contexto opengl (y no opengles, si leo el código correctamente). Así que incluso si lo compilas usando NDK de Android, tendrás que modificar el código ( por ejemplo, he visto algunos glVertex3f alrededor, pero no parecen ser muy necesarios... espero lo mejor). La otra opción, por supuesto, es portar el código de C a Java. Tal vez no tan doloroso como puedas imaginar.

¡Buena suerte !

 3
Author: Calvin1602,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-09 08:45:15

Echa un vistazo a MonkVG una implementación de OpenVG como API sobre OpenGL ES.

También, para el renderizado SVG encima de OpenVG (MonkVG) checkout MonkSVG.

MonkVG se ha creado para plataformas iOS, OSX y Android.

Soy el autor de ambas bibliotecas y estaré encantado de responder cualquier pregunta.

 12
Author: micahp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-06 00:50:01

Mi respuesta va a mostrar gráficos vectoriales con OpenGL en general, porque todas las soluciones para este problema pueden soportar SVG en particular, aunque ninguna soporta SVG animados (SMIL). Dado que no se dijo nada sobre la animación, asumo que la pregunta implicaba solo SVGS estáticos.

Primero, no me molestaría con nada OpenVG, ni siquiera con MonkVG, que es probablemente la implementación más moderna, aunque incompleta. El comité de OpenVG se ha plegado 2011 y la mayoría si no todas las implementaciones son abandonware o, en el mejor de los casos, software heredado.

Desde 2011, el estado del arte es Mark Kilgard's baby, NV_path_rendering, que actualmente es solo una extensión vendor (Nvidia) como ya habrás adivinado por su nombre. Hay muchos materiales sobre eso:

Por supuesto, puede cargar SVGs y tal https://www.youtube.com/watch?v=bCrohG6PJQE . También soportan la sintaxis PostScript para rutas. También puede mezclar el renderizado de rutas con otras cosas de OpenGL (3D), como se muestra en:

NV_path_rendering ahora es utilizado por la biblioteca Skia de Google detrás de las escenas, cuando está disponible. (Nvidia contribuyó con el código a finales de 2013 y 2014.) Uno de los cairo devs (que también es un empleado de Intel) parece gustarle también http://lists.cairographics.org/archives/cairo/2013-March/024134.html , aunque no estoy [todavía] al tanto de ningún esfuerzo concreto para que cairo use NV_path_rendering.

NV_path_rendering tiene algunas dependencias menores en la canalización fija, por lo que puede ser un poco molesto para usar en OpenGL ES. Este problema está documentado en el documento oficial de extensión vinculado anteriormente. Para obtener una solución alternativa, consulte, por ejemplo, lo que Skia / Chromium ha hecho: https://code.google.com/p/chromium/issues/detail?id=344330

Un advenedizo que tiene aún menos (o francamente ningún) soporte de proveedor o brillo académico es NanoVG, que actualmente se desarrolla y mantiene. ( https://github.com/memononen/nanovg ) Dado el número de bibliotecas 2D sobre OpenGL que han ido y venido con el tiempo, estás haciendo una gran apuesta usando algo que no es compatible con un proveedor importante, en mi humilde opinión.

 12
Author: Fizz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-06 15:19:51

Actualmente estoy investigando la posibilidad de renderizar gráficos vectoriales desde un archivo SVG > usando OpenGL y OpenGL ES. Tengo la intención de apuntar a Windows y Android. Mi solución ideal sería tener una biblioteca C mínima que genera una triangulación de polígonos a partir de un Archivo SVG. Esto generaría llamadas OpenGL u OpenGL ES estándar, y usaría una pantalla lista o vbo para la optimización al volver a dibujar. Simplemente dibujaría una lista de visualización para dibujar la imagen vectorial después traducir y rotar, lo que me permite mezclar esto con otras llamadas OpenGL>.

Si solo desea transformar formas vectoriales SVG en OpenGL|ES, entonces le sugiero que haga el analizador y la lógica usted mismo. Tenga en cuenta que SVG es una gran especificación, con diferentes características como servidores de pintura (degradados, patrones ...), referencias, filtros, recorte, manejo de fuentes, animaciones, scripting, enlaces, etc, etc.

Si desea soporte svg completo, entonces hay una biblioteca en http://code.google.com/p/enesim llamado egueb (y particularmente esvg) que usa enesim (una biblioteca de renderizado que tiene software y motores opengl) para el dibujo. En la mayoría de los casos utiliza shaders y todo se renderiza en una textura, la biblioteca es muy flexible lo que le permite adaptarse a sus necesidades particulares como modificar la escena renderizada, transformarla, etc. Porque el dibujo gl se hace siempre en una textura.

Hasta ahora veo que las sugerencias son en primer lugar usa QT o Cairo. - Esto no es una opción dado que deseo administrar mi propio contexto OpenGL sin bibliotecas hinchadas (en el contexto de lo que estoy tratando de lograr). Tampoco es adecuado para Android.

La segunda opción es usar bibliotecas que representen una textura. Mientras que esto podría estar bien para gráficos vectoriales estáticos, no es una opción eficiente o factible para juegos donde el escalado y las rotaciones ocurren con frecuencia.

En el caso particular del motor gl, enesim no crea un GLX (o cualquier otro contexto dependiente de la ventana), tienes que proporcionarlo, por lo que se adapta perfectamente a tu situación ya que solo usa llamadas GL.

El único inconveniente es que la biblioteca aún no está completa en términos de soporte gl o soporte completo SVG spec, pero dependiendo de sus necesidades, me parece una buena opción.

 7
Author: turran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-07 22:10:00

Hay que decir que renderizar SVG o OpenVG con OpenGL u OpenGL ES es fundamentalmente una mala idea. Hay razones por las que las implementaciones de OpenVG son tan lentas y en gran parte abandonadas. El proceso de teselar rutas (la base de todo el renderizado SVG/OpenVG) en listas triangulares como lo requiere OpenGL es fundamentalmente lento e ineficiente. Básicamente requiere insertar un algoritmo de ordenación / búsqueda en la canalización de renderizado 3D, lo que reduce el rendimiento. También está el problema que se requiere un esquema de asignación de memoria dinámica porque el tamaño del conjunto de datos es desconocido ya que SVG no pone límites a la complejidad de la geometría de la ruta. Un diseño realmente pobre.

SVG y OpenVG fueron creados por desarrolladores que tenían poca comprensión de cómo funcionan realmente los motores de hardware de gráficos 3D modernos (listas triangulares). Fueron creados para ser una alternativa abierta a Adobe Flash, que también tiene la misma arquitectura defectuosa que ha hecho Flash vilipendiado en la industria para rendimiento impredecible.

Mi consejo es repensar tu diseño y usar listas triangulares de OpenGL directamente. Es posible que tenga que escribir más código, pero su aplicación funcionará alrededor de mil veces mejor y puede depurar su código más fácilmente que alguien elses.

 5
Author: ClayMontgomery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-08 17:06:49

Puedes echar un vistazo a AmanithVG, parecen haber implementado una buena tubería de caminos -> triángulos. He probado el ejemplo de iOS GL tiger, y parece que la triangulación no es un cuello de botella real.

 1
Author: mirknac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-08 10:14:54