android - Representación de SVG con OpenGL(y OpenGL ES)
opengl-es vector-graphics (6)
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ígono a partir de un archivo SVG determinado. Esto generaría llamadas estándar de OpenGL o OpenGL ES, y usaría una lista de visualización o vbo para la optimización al volver a dibujar. Simplemente dibujaba una lista de visualización para dibujar la imagen vectorial después de traducir y girar, permitiéndome mezclar esto con otras llamadas OpenGL.
Hasta ahora veo que las sugerencias son usar QT o Cairo en primer lugar. - Esta no es una opción dado que deseo administrar mi propio contexto de OpenGL sin bibliotecas infladas (en el contexto de lo que intento lograr). Tampoco es adecuado para Android.
La segunda opción es usar bibliotecas que se procesen en 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 la escala 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 determinado en tiempo de ejecución, y no veo cómo optimizar esto como es posible que deseemos con una lista de visualización o vbo.
Los tres métodos sufren limitaciones. Creo que la opción más prometedora es usar una implementación de OpenVG si no existe otra solución. Entonces mi pregunta es, ¿hay bibliotecas por ahí que hagan lo que yo 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 en su lugar?
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ígono a partir de un archivo SVG determinado. Esto generaría llamadas estándar de OpenGL o OpenGL ES, y usaría una lista de visualización 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 de traducir y rotar, lo que me permite mezclar esto con otras llamadas OpenGL>.
Si solo quieres transformar las formas de vectores SVG en OpenGL | ES, te sugiero que hagas el analizador y la lógica tú 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, scripts, enlaces, etc., etc.
Si quieres soporte completo de svg, entonces hay una biblioteca en http://code.google.com/p/enesim llamada egueb (y particularmente esvg) que usa enesim (una biblioteca de renderizado que tiene software y backends opengl) para el dibujo. En la mayoría de los casos utiliza sombreadores y todo se procesa en una textura, la biblioteca es muy flexible y le permite adaptarse a sus necesidades particulares, como modificar la escena renderizada, transformarla, etc. Porque el dibujo gl se realiza siempre en una textura.
Hasta ahora veo que las sugerencias son usar QT o Cairo en primer lugar. - Esta no es una opción dado que deseo administrar mi propio contexto de OpenGL sin bibliotecas infladas (en el contexto de lo que intento lograr). Tampoco es adecuado para Android.
La segunda opción es usar bibliotecas que se procesen en 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 la escala y las rotaciones ocurren con frecuencia.
En el caso particular del backend gl, enesim no crea un GLX (o cualquier otro contexto dependiente de la ventana), debe proporcionarlo, por lo que se adapta perfectamente a su situación, ya que solo utiliza llamadas GL.
El único inconveniente es que la biblioteca aún no está completa en cuanto a soporte de gl o soporte completo de especificaciones SVG, pero según sus necesidades, me parece una buena opción.
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);
}
Entonces usa una VBO. Así que sugeriría hacer tu 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 de apertura (y no abre, si leo el código correctamente). Entonces, incluso si compila con el NDK de Android, tendrá que modificar el código (por ejemplo, he visto algunos glVertex3f, pero no parecen ser muy necesarios ... espero lo mejor). La otra opción, por supuesto, es portar el código de C a Java. Quizás no sea tan doloroso como podrías imaginar.
Buena suerte !
Echa un vistazo a MonkVG una implementación de OpenVG like API en la parte superior de OpenGL ES.
Además, para el renderizado SVG en la parte superior de OpenVG (MonkVG) pago MonkSVG .
MonkVG se ha creado para plataformas iOS, OSX y Android.
Soy el autor de ambas bibliotecas y estaría encantado de responder cualquier pregunta.
Es necesario decir que renderizar SVG o OpenVG con OpenGL o OpenGL ES es fundamentalmente una mala idea. Hay razones por las que las implementaciones de OpenVG son tan lentas y están en gran parte abandonadas. El proceso de las rutas de teselación (la base de todas las representaciones de SVG / OpenVG) en listas de triángulos según lo requerido por OpenGL es fundamentalmente lento e ineficiente. Básicamente, requiere insertar un algoritmo de ordenación / búsqueda en el canal de renderizado 3D, lo que paraliza el rendimiento. También existe el problema de 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 establece límites en la complejidad de la geometría del camino. 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 de triángulos). Fueron creados para ser una alternativa abierta a Adobe Flash, que también tiene la misma arquitectura defectuosa que ha hecho que Flash se vilipendie en la industria por su desempeño impredecible.
Mi consejo es replantear tu diseño y usar las listas de triángulos OpenGL directamente. Puede que tenga que escribir más código, pero su aplicación tendrá un rendimiento mil veces mejor y podrá depurar su código más fácilmente que otras personas.
Mi respuesta es sobre la visualización de gráficos vectoriales con OpenGL en general, ya que todas las soluciones para este problema pueden soportar, en particular, SVG de forma trivial, aunque ninguna admite archivos SVG animados (SMIL). Como no se dijo nada acerca de la animación, supongo que la pregunta solo implica SVG 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é OpenVG se ha cerrado en 2011 y la mayoría de las implementaciones, si no todas, son abandonadas o, como máximo, software heredado.
Desde 2011, el estado del arte es el bebé de Mark Kilgard, NV_path_rendering , que actualmente solo es una extensión de proveedor (Nvidia) como ya habrás adivinado por su nombre. Hay muchos materiales sobre eso:
- https://developer.nvidia.com/nv-path-rendering Nvidia hub, pero algunos materiales en la página de destino no son los más actualizados
- http://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/opengl/gpupathrender.pdf Siggraph 2012 paper
- http://on-demand.gputechconf.com/gtc/2014/presentations/S4810-accelerating-vector-graphics-mobile-web.pdf Presentación de GTC 2014
- http://www.opengl.org/registry/specs/NV/path_rendering.txt extensión oficial doc
Por supuesto, puede cargar archivos SVG y https://www.youtube.com/watch?v=bCrohG6PJQE . También son compatibles con la sintaxis de PostScript para las rutas. También puede mezclar la representación 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). A uno de los desarrolladores de cairo (que también es empleado de Intel) también parece gustarle http://lists.cairographics.org/archives/cairo/2013-March/024134.html , aunque todavía no conozco ningún esfuerzo concreto para que Cairo use NV_path_rendering.
NV_path_rendering tiene algunas dependencias menores en la tubería fija, por lo que puede ser un poco molesto utilizarlo en OpenGL ES. Este problema se documentó en el documento de extensión oficial vinculado anteriormente. Para una solución, vea por ejemplo lo que Skia / Chromium ha hecho: https://code.google.com/p/chromium/issues/detail?id=344330
Un advenedizo que tiene incluso menos (o francamente sin) soporte de proveedor o brillo académico es NanoVG , que actualmente está desarrollado y mantenido. ( https://github.com/memononen/nanovg ) Dada la cantidad de librerías en 2D sobre OpenGL que han ido y venido con el tiempo, está tomando una gran apuesta utilizando algo que no es respaldado por un proveedor importante, en mi humilde opinión.
Puedes echarle un vistazo a AmanithVG , parece que han implementado un buen camino -> triángulos en tramitación. He probado el ejemplo de iOS GL Tiger, y parece que la triangulación no es un verdadero cuello de botella.