用OpenGL(和OpenGL ES)渲染SVG

我目前正在研究使用OpenGL和OpenGL ES从SVG文件渲染vectorgraphics的可能性。 我打算针对Windows和Android。 我的理想解决scheme是从一个给定的SVG文件生成一个多边形三angular剖分的最小C库。 然后这将生成标准的OpenGL或OpenGL ES调用,并在重绘时使用显示列表或vbo进行优化。 我只需绘制一个显示列表,在翻译和旋转之后绘制vector图,从而可以将其与其他OpenGL调用混合使用。

到目前为止,我看到的build议是首先使用QT或开罗。 – 这不是一个选项,因为我希望pipe理我自己的OpenGL上下文而不是臃肿的库(在我试图实现的上下文中)。 这也不适用于Android。

第二个select是使用渲染纹理的库。 虽然这对于静态vectorgraphics来说可能是好的,但对于经常出现缩放和旋转的游戏来说,这并不是一个有效或可行的select。

第三,有使用OpenVG的可能性。 OpenVG规范(ShivaVG等)的一些开源实现,但我还没有find一个能够在运行时从给定的SVG文件生成适当的OpenVG调用的库,我看不到如何优化我们不妨用显示列表或vbo。

所有三种方法都受到限制。 如果没有其他解决scheme,我认为最有希望的select是使用OpenVG实现。 所以我的问题是,有没有图书馆可以做我想要的,或者接近我想要的? 如果没有,为什么不呢? 试试从头开始做更好吗?

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。 所以我build议你制作自己的SVGparsing器/使用一个预制的parsing器,然后将调用转发给ShivaVG。

你仍然有问题,ShivaVG是在C(而不是Java),并创build一个opengl上下文(而不是opengles,如果我正确地读取代码)。 所以即使你使用Android的NDK进行编译,也必须修改代码(例如,我已经看到了几个glVertex3f,但是似乎并不需要太多的希望)。 另一个选项当然是将代码从C移植到Java。 也许不像你想象的那样痛苦。

祝你好运 !

我的答案是关于在一般情况下显示与OpenGL的vectorgraphics,因为这个问题的所有解决scheme,特别是可以支持SVG,虽然没有支持animationSVG(SMIL)。 由于没有什么关于animation的说法,我假设这个问题只包含静态的SVG。

首先,我不打扰任何OpenVG,甚至不用MonkVG,这可能是最现代的,尽pipe不完整的实现。 OpenVG委员会已经在2011年结束了,如果不是所有的实施都是弃用软件或者最好的遗留软件。

自2011年以来,最先进的技术是Mark Kilgard的宝贝, NV_path_rendering ,目前它只是一个供应商(Nvidia)的扩展,你可能已经从它的名字中猜到了。 这里有很多材料:

您当然可以加载SVG和https://www.youtube.com/watch?v=bCrohG6PJQE 。 它们也支持path的PostScript语法。 您也可以将path渲染与其他OpenGL(3D)的东西混合使用,如演示:

现在Google的Skia库在幕后使用NV_path_rendering。 (Nvidia在2013年底和2014年分别推出了该代码。)其中一位开拓者(也是英特尔员工)似乎也很喜欢它http://lists.cairographics.org/archives/cairo/2013-March/024134 .html ,尽pipe我还没有意识到cairo使用NV_path_rendering的具体工作。

NV_path_rendering在固定pipe道上有一些小的依赖关系,所以在OpenGL ES中使用它可能有些麻烦。 此问题logging在上面链接的官方扩展文档中。 有关解决方法,请参阅Skia / Chromium已完成的示例: https : //code.google.com/p/chromium/issues/detail ?id =344330

NanoVG目前正在开发和维护中,一个拥有更less(或彻头彻尾的)供应商支持或学术浮华的新贵 。 ( https://github.com/memononen/nanovg )考虑到随着时间的推移,OpenGL上2D库的数量已经来不断变化,我认为,使用不被主要供应商支持的东西,我们会大打赌。

在OpenGL ES之上查看MonkVG类似OpenVG的API实现。

另外,SVG在OpenVG(MonkVG)结算MonkSVG之上进行渲染。

MonkVG已经为iOS,OSX和Android平台构build。

我是这两个图书馆的作者,并会很乐意回答任何问题。

我目前正在研究使用OpenGL和OpenGL ES从SVG文件渲染vectorgraphics的可能性。 我打算针对Windows和Android。 我的理想解决scheme是从一个给定的SVG文件生成一个多边形三angular测量的最小C库。 然后这将生成标准的OpenGL或OpenGL ES调用,并在重绘时使用显示列表或vbo进行优化。 我只是简单的绘制一个显示列表来绘制翻译和旋转后的vector图,让我把它和其他的OpenGL调用混合在一起。

如果您只想将SVGvector形状转换为OpenGL | ES,那么我build议您自己完成parsing器和逻辑。 请注意,SVG是一个巨大的规范,具有不同的function,如绘制服务器(渐变,模式…),引用,filter,裁剪,字体处理,animation,脚本,链接等。

如果你想获得完整的svg支持,那么http://code.google.com/p/enesim上有一个名为egueb(尤其是esvg)的库,它使用enesim(一个具有软件和opengl后端的渲染库)来进行绘制。; 在大多数情况下,它使用着色器,一切都被渲染成一个纹理,图书馆是非常灵活的,让您适应您的特殊需要,如修改渲染的场景,转换等。因为gl绘图始终做到纹理。

到目前为止,我看到的build议是首先使用QT或开罗。 – 这不是一个选项,因为我希望pipe理我自己的OpenGL上下文而不是臃肿的库(在我试图实现的上下文中)。 这也不适用于Android。

第二个select是使用渲染纹理的库。 虽然这对于静态vectorgraphics来说可能是好的,但对于经常出现缩放和旋转的游戏来说,这并不是一个有效或可行的select。

在gl后端的特殊情况下,enesim不会创buildGLX(或任何其他依赖于窗口的上下文),所以您必须提供它,因此它完全适应您的情况,因为它只使用GL调用。

唯一的缺点是,该图书馆还没有完全支持gl或全面的SVG规范支持,但根据您的需求,在我看来,这是一个很好的select。

需要说的是,使用OpenGL或OpenGL ES来渲染SVG或OpenVG从根本上来说是一个坏主意。 OpenVG的实现是如此缓慢,很大程度上被放弃的原因。 根据OpenGL的要求,将path(所有SVG / OpenVG渲染的基础)镶嵌到三angular形列表中的过程基本上是缓慢而低效的。 它基本上要求在3D渲染stream水线中插入一个sorting/searchalgorithm,这会削弱性能。 还有一个问题是dynamic内存分配scheme是必需的,因为数据集的大小是未知的,因为SVG对path几何的复杂性没有限制。 一个非常糟糕的devise。

SVG和OpenVG是由对现代3Dgraphics硬件引擎实际工作不甚了解的开发人员创build的(三angular列表)。 它们被创build成为Adobe Flash的开放替代品,它也具有相同的有缺陷的体系结构,使得Flash在业界出现不可预知的性能。

我的build议是重新考虑你的devise,并直接使用OpenGL三angular列表。 您可能需要编写更多的代码,但是您的应用程序的性能会提高一千倍左右,而且比其他人更容易debugging代码。

你可以看看AmanithVG ,他们似乎已经实现了一条好的path – >三angular形pipe道。 我已经尝试了iOS GL虎的例子,似乎三angular测量不是一个真正的瓶颈。