Is there any way to Blit a zoomed (in) version of a certain image/sprite using SDL? (Besides manually saving a zoomed version of the image..)
Thanks :-)
Not with the SDL API itself.
I think there exist libraries (for SDL) who support zooming (so called resizing).
EDIT: http://www.ferzkopp.net/joomla/content/view/19/14/
Generally speaking, SDL isn't suitable for graphics that require real-time rotations and zooming. For that, you'd need an library based around an accelerated API such as DirectX or OpenGL. I understand that SFML meets this requirement.
Related
I started working at this company that uses an 2D OpenGL implementation to show our system's data (which runs on Windows.) The whole system was built with C++ (using C++Builder 2007). Thing is, all the text they print there are pixelized when you zoom in, which I think happens because the text is a bitmap:
From what I know they use the same font files as Windows does. I asked around here on why this happens and the answer I got is that the guy who implemented it (which doesn't work at the company anymore) said fonts on OpenGL are hard and this was the best he could do or something like it.
My question is: is there any simple and effective way to make the text also a vector (the same way those lines in the picture are?) So when I zoom the camera, which happens a lot, they don't pixelize. I have little knowledge of OpenGL and if you have some guide and/or tutorial related to this to point me towards the right direction I'd be very thankful. Basically any material would be great.
Most of OpenGL text rendering libraries come to this: creating bitmaps for the fonts. This means you are going to have problems with scaling and aliasing unless you do some hacks.
One of the popular hacks is Valve's approach: Chris Green. 2007. "Improved Alpha-Tested Magnification for Vector Textures and Special Effects.". You use signed distance field algo to generate your fonts bitmap which then helps you to smooth the text outlines on scale during rendering. Wikidot has the C++ implementation for Distance field generation.
If you stick to NVidia specific hardware, you can try the NVidia Path extension which allows you to render graphics directly on GPU. Remember, it is a NVidia only thing.
But in general, signed distance field based approach is the smoothest and easiest to implement.
BTW, freetype-gl uses Valve's approach and also the modern pipeline.
You can try freetype-gl its a library for font rendering in OpenGL.
The issue with using fonts in OpenGL is that they are handled inconsistently across platforms, and that they have minimal support. If you're willing to go with a helper library for OpenGL (SDL comes to mind), then this behaviour will likely be wrapped, meaning that you merely need to provide a suitable font file for them to use.
You may try out FTOGL4 , the fonts for OpenGL4
I need to smoothly zoom in/out and pan an image (for a slideshow) with the sdl library.
I've tried rotozoom from the SDL GFX library but it's far away from smooth.
What would be the best approach here?
If "vanilla" SDL seems too slow for you I'd suggest switching your drawing code to OpenGL. That way you'll get hardwareaccelleration and your issues should go away:)
Using OpenGL coupled with SDL is very easy and there are lots of tutorials on how to do it.
By this I mean, does Cairo draw lines, shapes and everything using opengl acelerated primitives or no? and if not, a library that does this?
The OpenGL backend certainly accelerates some functions. But there are many it can't accelerate. The fact that it's written against GL 2.1 (and thus can't use more advanced features of 3.x or 4.x hardware) means that there is a lot that it simply cannot accelerate.
If you are willing to limit yourself to NVIDIA hardware, NVIDIA just came out with the NV_path_rendering extension, which provides a lot of the 2D functionality you would find with Cairo. Indeed, it's possible that you could write a Cairo backend for it. The path rendering extension is only available on GeForce 8xxx hardware and above.
It's nifty in that it's focused on the vertex pipeline. It doesn't do things like gradients or colors or whatever. That's good, because it still allows you the use of a fragment shader. Which means you get to do pretty much whatever you want ;)
Cairo is designed to have a flexible backend for rendering. It can use OpenGL for rendering, though support is still listed as "experimental" at this point. For details, see using cairo with OpenGL.
It can also output to the X Window System, Quartz, Win32, image buffers, PostScript, PDF, and SVG, and more.
I've played around with GLUT, but I've also read about SDL and one or two other graphics libraries. All I want to do at this point is 2D work. For what I'm doing right now, pixel by pixel plotting is all I need (say, plot(x,y,color) or something of the sort), but in the future I would appreciate the use of sprites. I've given point plotting a go with GLUT but it's rather non-intuitive coming from a B.A.S.I.C. background.
I work on both Ubuntu and Windows, so solutions for both systems are welcome.
SDL is probably a good choice; another option to look at would be Qt (just subclass a QWidget and override its paintEvent() method and do your pixel plotting inside that). Qt can also provide windowing/infrastructure support for OpenGL graphics if that's your preference.
This question already has answers here:
Displaying SVG in OpenGL without intermediate raster
(5 answers)
Closed 5 years ago.
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.
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.
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
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:
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.
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.
Qt has good support for directly rendering SVG images using OpenGL functionality (see the documentation for QSvgRenderer).
I hope that helps.
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