c++ opengl graphics svg

c++ - Visualización de SVG en OpenGL sin ráster intermedio



graphics (7)

Tengo algunas ilustraciones simples de SVG (íconos y glifos) que quiero mostrar en una aplicación OpenGL (desarrollándome en C ++ en Debian, usando Qt).

La solución obvia es utilizar las bibliotecas de ImageMagick para convert los archivos SVG en imágenes de mapa de bits y texturizarlos en algunos polígonos adecuados (o simplemente usar buenos viejos glDrawPixels).

Sin embargo, me pregunto si hay algo que traduzca el SVG directamente a una secuencia de llamadas OpenGL y lo renderice usando líneas, polígonos y elementos similares de OpenGL. Alguien sabe de algo que puede hacer esto?


Hice un programa de dibujo vectorial llamado Omber que tiene cierta capacidad para importar archivos SVG, y puede exportar dibujos vectoriales a un modelo 3D "aplanado" en formato glTF 2.0. El formato glTF es prácticamente solo datos brutos de OpenGL, por lo que puede leerlo y mostrarlo con un código mínimo. Escribí un pequeño plugin Pixi.js para mostrar archivos glTF que contenían vector art usando WebGL.

Blender también tiene soporte para importar archivos SVG. A continuación, puede exportar el resultado a un formato de archivo 3d, pero el soporte de Blender para SVG está destinado más a la importación de curvas simples en lugar de dibujos complejos.

Estoy seguro de que hay otras herramientas que también pueden hacer cosas como esta. Una cuestión es que SVG es anterior al hardware de gráficos moderno, por lo que muchas de sus características son un verdadero dolor para implementar con OpenGL, especialmente de una manera eficiente. Cosas como la opacidad en grupos, degradados de formas irregulares, operaciones de filtro basadas en ráster, etc. pueden complicarse, así que no estoy seguro si las características más esotéricas de SVG generalmente son compatibles con programas que pueden convertir cosas a formatos 3D.


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.

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:

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.

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.


Parece que Inkscape tiene algunas opciones de exportación interesantes que pueden serle útiles. Incluyen DXF, PovRay, EPS, PS (PostScript), XAML, Latex y OpenDocument Drawing (ODG). Tal vez haya un convertidor para uno de esos y podría usar Inkscape como intermediario.

DXF en particular es un candidato probable ya que ya es un formato 3D común. assimp es un buen candidato para cargar DXF.


también hay tkzinc como una posibilidad



SVGL parece abordar esto, pero ha estado inactivo durante varios años. Aún así, es posible que pueda encontrar algún código de valor allí.


Qt puede hacer esto.
QSvgRenderer puede tomar un SVG y pintarlo sobre un QGLWidget
Es posible que tengas que paintEvent() con paintEvent() abit si quieres dibujar cualquier cosa en el QGLWidget que no sea el SVG.