2011-06-09 522 views
52

我目前正在调查从使用OpenGL和OpenGL ES SVG文件渲染矢量图形的可能性。我打算针对Windows和Android。我的理想解决方案是拥有一个最小的C库,可以从给定的SVG文件生成多边形三角剖分。这会生成标准的OpenGL或OpenGL ES调用,并在重绘时使用显示列表或vbo进行优化。我只需绘制一个显示列表,在翻译和旋转后绘制矢量图像,以便将其与其他OpenGL调用混合使用。渲染SVG支持OpenGL(和OpenGL ES)

到目前为止,我看到的建议是首先使用QT或开罗。 - 这不是一个选项,因为我希望管理自己的OpenGL上下文,而不需要膨胀的库(在我尝试实现的上下文中)。这也不适用于Android。

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

第三,有可能使用OpenVG。 OpenVG规范有一些开源实现(ShivaVG等),但我还没有找到一个能够在运行时从给定的SVG文件生成相应OpenVG调用的库,并且我无法看到如何将其优化为我们可能希望用显示列表或vbo。

所有三种方法都受到限制。如果没有其他解决方案存在,我认为最有希望的选择是使用OpenVG实现。所以我的问题是,有没有图书馆可以做我想要的,或接近我想要的?如果不是,有没有充分的理由为什么不呢?试图从头开始做这件事情会更好吗?

+0

解析路径的svg文件并不困难。检查以下绘制二次贝塞尔曲线。 //www.opengl.org/resources/code/samples/redbook/bezcurve.c – 2011-06-09 06:51:35

+0

@Grady glEvalCoord在OpenGL ES中不存在;而GLU,它的镶嵌器也不重要,例如凸多边形。 @ me232很好的问题,upvote'd&favorite'd – Calvin1602 2011-06-09 08:29:02

+0

+1良好的研究和很好的框架问题 – 2011-06-09 10:19:42

回答

4

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,如果我正确读取的代码)。所以,即使你使用Android的NDK进行编译,你也必须修改代码(例如,我已经看到了几个glVertex3f,但似乎并不太需要......希望最好)。当然,另一种选择是将代码从C移植到Java。也许并不像你想象的那么痛苦。

祝你好运!

+2

谢谢,我会看看这个,我感到惊讶的是,考虑到对硬件加速矢量图形的需求以及OpenVG设计时考虑到移动设备的事实,并没有一个可以实现的实现,我意识到用C#编写的项目,试图非常类似地做一些事情成功的结果[http://neuronspew.wordpress.com/category/svg-game-engine-project/](http://neuronspew.wordpress.com/category/svg-game-engine-project/)我会如果我能做到这一点,请务必公开我的代码。 – 2011-06-10 01:39:22

+1

谢谢!请在完成该任务后更新此主题? – Calvin1602 2011-06-10 08:56:03

11

退房MonkVG像的OpenGL ES的顶部API实现的OpenVG的。

另外,SVG呈现在OpenVG的(MonkVG)结帐MonkSVG的顶部。

MonkVG已建成的iOS,OSX和Android平台。

我这两个库的作者,并乐意回答任何问题。

+1

嗨弥迦。我找到了MonkVG的Windows项目,并设法使用VS2010进行构建。是否有任何适用于Windows的工作示例?我试图效法这个例子。我手动创建自己的窗口和上下文,但是我想如果你有一个基于GLUT的例子,那么基于GLUT的解决方案就没有问题。 – 2012-01-20 09:32:49

7

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

如果您只想将SVG矢量形状转换为OpenGL | ES,那么我建议您自己做解析器和逻辑。请注意,SVG是一个庞大的规格,具有不同的功能,如绘制服务器(渐变,图案...),参考,过滤器,剪裁,字体处理,动画,脚本,链接等。

如果你想要满svg支持,那么有一个名为egueb(尤其是esvg)的库,它使用enesim(一个具有软件和opengl后端的渲染库)来绘制。在大多数情况下,它使用着色器,并且所有东西都被渲染成纹理,该库非常灵活,可以让您适应特定的需求,例如修改渲染的场景,转换等等。因为gl绘图始终是在纹理中完成的。

到目前为止,我看到的建议是首先使用QT或开罗。 - 这不是一个选项 ,因为我希望管理自己的OpenGL上下文而不需要膨胀的库(在我尝试实现的 上下文中)。这也不适用于Android。

第二种选择是使用渲染到纹理的库。虽然对于 静态矢量图形来说这可能是好的,但对于经常出现缩放比例和旋转的游戏来说,这并不是一个有效或可行的选项。

在GL后端的特定情况下,enesim不会创建GLX(或任何其他窗口依赖于上下文),你必须提供它,所以它能够很好的满足您的情况,因为它仅使用GL调用。

唯一的缺点是该库在gl支持或全面的SVG规范支持方面尚未完成,但根据您的需求,在我看来,这是一个不错的选择。

+0

你用什么算法将三次贝塞尔曲线(路径)转换为OpenGL?怎么样消除锯齿 – Raks 2013-06-23 14:32:22

12

我的答案会关于显示矢量图形的OpenGL wtih一般,因为这个问题的解决方案都可以支持,而平凡SVG特别是,虽然没有支持动画SVGs(SMIL)。由于没有关于动画的说法,我假设这个问题只包含静态SVG。首先,我不打扰任何OpenVG,即使使用MonkVG,这可能是最现代的,尽管不完整的实现。 OpenVG委员会已于2011年结束,大多数(如果不是所有的话)实施都是弃用软件或最好的遗留软件。

2011年以来,技术状态是马克·基尔加德的婴儿,NV_path_rendering,这也是目前唯一的一个供应商(英伟达)你可能已经从它的名字已经猜到了扩展。还有一些对很多材料:

当然你也可以负载SVGs和这样https://www.youtube.com/watch?v=bCrohG6PJQE的。它们还支持路径的PostScript语法。你也可以混合路径与其他的OpenGL(3D)的东西呈现,作为全世界展示:

NV_path_rendering现在所使用的谷歌的场景,当可用的背后Skia的库。 (Nvidia在2013年底和2014年提供了代码。)其中一位开罗开发者(也是英特尔员工)似乎也很喜欢它http://lists.cairographics.org/archives/cairo/2013-March/024134.html,尽管我还没有意识到开罗使用任何具体措施NV_path_rendering。

NV_path_rendering在固定管道上有一些小的依赖关系,所以它在OpenGL ES中可能有点麻烦。此问题记录在上面链接的官方扩展文档中。有关解决方法参见例如什么Skia的/铬做:具有更小(或彻头彻尾的无)供应商的支持或学术浮华https://code.google.com/p/chromium/issues/detail?id=344330

一个暴发户是NanoVG,这是目前开发和维护。 (https://github.com/memononen/nanovg)考虑到随着时间的推移,OpenGL上2D库的数量已经逐渐增加,你用一种不被主要供应商支持的东西大打赌,以我的愚见。

5

需要说的是,使用OpenGL或OpenGL ES渲染SVG或OpenVG从根本上说是一个坏主意。 OpenVG的实现有如此缓慢和很大程度上被放弃的原因。根据OpenGL的要求,将路径(所有SVG/OpenVG渲染的基础)镶嵌到三角形列表中的过程基本上是缓慢而低效的。它基本上需要在3D渲染管道中插入排序/搜索算法,这会削弱性能。还有一个问题是动态内存分配方案是必需的,因为数据集的大小是未知的,因为SVG对路径几何的复杂性没有限制。一个非常糟糕的设计。

SVG和OpenVG由开发人员创建,他们对现代3D图形硬件引擎实际上的工作原理(三角列表)缺乏了解。它们被创建成为Adobe Flash的开放替代品,它也具有相同的有缺陷的架构,这使得Flash在业界出现难以预测的性能。

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

+0

只是一个说明:有很多方法可以用OpenGL绘制SVG,并且镶嵌到三角形的路径可能更糟糕。使用着色器怎么样? – 2016-11-11 07:54:58

1

你可以看看AmanithVG,他们似乎已经实现了一个好的路径 - >三角形管道。我已经尝试了iOS GL虎示例,并且似乎三角测量不是真正的瓶颈。