Rendering Vector Graphics in OpenGL? [duplicate]

2019-01-16 20:26发布

问题:

This question already has an answer here:

  • Displaying SVG in OpenGL without intermediate raster 6 answers

Is there a way to load a vector graphics file and then render it using OpenGL? This is a vague question as I don't know much about file formats for vector graphics. I know of SVG, though.

Turning it to raster isn't really helpful as I want to do real time zooming in on the objects.

回答1:

Let me expand on Greg's answer.

It's true that Qt has a SVG renderer class, QSvgRenderer. Also, any drawing that you do in Qt can be done on any "QPaintDevice", where we're interested in the following "paint devices":

  • A Qt widget;
  • In particular, a GL-based Qt widget (QGLWidget);
  • A Qt image

So, if you decide to use Qt, your options are:

  1. Stop using your current method of setting up the window (and GL context), and start using QGLWidget for all your rendering, including the SVG rendering. This might be a pretty small change, depending on your needs. QGLWidget isn't particularly limiting in its capabilities.
  2. Use QSvgRenderer to render to a QImage, then put the data from that QImage into a GL texture (as you normally would), and render it any way you want (e.g. into a rectangular GL_QUAD). Might have worse performance than the other method but requires the least change to your code.

Wondering what QGLWidget does exactly? Well, when you issue Qt rendering commands to a QGLWidget, they're translated to GL calls for you. And this also happens when the rendering commands are issued by the SVG renderer. So in the end, your SVG is going to end up being rendered via a bunch of GL primitives (lines, polygons, etc).

This has a disadvantage. Different videocards implement OpenGL slightly differently, and Qt does not (and can not) account for all those differences. So, for example, if your user has a cheap on-board Intel videocard, then his videocard doesn't support OpenGL antialiasing, and this means your SVG will also look aliased (jaggy), if you render it directly to a QGLWidget. Going through a QImage avoids such problems.

You can use the QImage method when you're zooming in realtime, too. It just depends on how fast you need it to be. You may need careful optimizations such as reusing the same QImage, and enabling clipping for your QPainter.



回答2:

I see most of the answers are about Qt somehow, even though the original question doesn't mention it. Here's my answer in terms of OpenGL alone (which also benefits greatly from the passage of time, as it could not have been given in 2010):

Since 2011, the state of the art is Mark Kilgard's baby, NV_path_rendering, which is currently only a vendor (Nvidia) extension as you might have guessed already from its name. There are a lot of materials on that:

  • https://developer.nvidia.com/nv-path-rendering Nvidia hub, but some material on the landing page is not the most up-to-date
  • 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 GTC 2014 presentation
  • http://www.opengl.org/registry/specs/NV/path_rendering.txt official extension doc

NV_path_rendering is now used by Google's Skia library behind the scenes, when available. (Nvidia contributed the code in late 2013 and 2014.)

You can of course load SVGs and such https://www.youtube.com/watch?v=bCrohG6PJQE. They also support the PostScript syntax for paths. You can also mix path rendering with other OpenGL (3D) stuff, as demoed at:

  • https://www.youtube.com/watch?v=FVYl4o1rgIs
  • https://www.youtube.com/watch?v=yZBXGLlmg2U

An upstart having even less (or downright no) vendor support or academic glitz is NanoVG, which is currently developed and maintained. (https://github.com/memononen/nanovg) Given the number of 2D libraries over OpenGL that have come and gone over time, you're taking a big bet using something not supported by a major vendor, in my humble opinion.



回答3:

This isn't an implementation, but very relevant to your question and viewers.

Chapter 25. Rendering Vector Art on the GPU https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch25.html



回答4:

Qt has good support for directly rendering SVG images using OpenGL functionality (see the documentation for QSvgRenderer).

I hope that helps.



回答5:

It has primitives like GL_LINES and GL_LINE_STRIP for drawing lines in space if that's what you mean. Edit: This site has some information: http://www.falloutsoftware.com/tutorials/gl/gl2p5.htm