Another no-time-yet-to-finish-it pet project of mine is a media player, something like for media center or portable device. I code it in SDL, in a hope that targeting platforms like GP2x and Nokia N800 are easy. But knowing that Qtopia (soon) runs also on N800, I am thinking of moving the code to pure Qt for ease of maintenance.
Unless you live under the rocks, CoverFlow should sound familiar. For the said media player, I have an efficient implementation of CoverFlow effect, called PictureFlow. Last weekend I decided to port the code to sane C++ and Qt and here is what I get now:
or, like the trend nowadays, in the following short screencast (if it is not visible, go to
You can see that the typical “flowing” ala CoverFlow is implemented already. Even, the first and last covers always fades in and fades out during the animation (so a cover just doesn’t come in out of nowhere). Reflection is also there, done by crude-blending the cover with black (that’s why black background is so sweet!) and then placing it in the surface cache.
The important feature of PictureFlow is that it does not need 3-d accelerated graphics system. Everything is done in a software renderer. This is not so surprising, consider that I target the original media player for portable device(s). Even the latest sub-GHz iPod can have CoverFlow, so there is no reason to demand fast OpenGL implementation just to enjoy this little piece of eye candy. As long as blitting to screen is fast, you’re set. Moreover, no floating-point operation is carried out so that it’s fast enough even on ARM-like platforms.
On the other, using pure software renderer has a major drawback, namely the rather lower rendering quality (traded for optimal speed). As you witness from the screenshot, the edges of the tilted images are jaggy. However, with 225 dpi screen like in N800, these jaggy lines (hopefully) won’t be noticeable. This can’t be avoided without causing too much performance penalty. In fact, technically there is not even a perspective-correct texture mapper. It is just the same hack like the texture mapper done in raycasting-based game, e.g. the classic Wolfenstein 3-D ages ago. This is also the reason to bypass Qt own rasterizer, as we can do some sort of “cheating” and map the texture really fast. Texturing is done more like nearest neighbor approach rather than bilinear filtering, which gives less pleasant result if you stare at the rendering result too long.
Also, software renderer is much slower than hardware-assisted one. Thus, the trick is to keep the widget as small as possible, but not smaller. With reasonable size like 800×350 pixels, on fairly modern machines, you’d get something like 45 fps, which is quite satisfactory. I even tested on old 800Mhz box, it is not as smooth as in a dual-core system, but runs nevertheless well enough.
Overall, this widget is still very basic though already functional. For example, there is no text nor fancy scrollbar which are typically superimposed on bottom side. I guess, in this case, you can subclass PictureFlow widget and add the extra gimmicks by yourself. In addition, as trade-off, covers with alpha channel and covers with non-uniform size won’t be supported, this is to minimize texture overdraw.
Anyway, this widget is released as open-source (under MIT license), see http://pictureflow.googlecode.com. So, just grab it while it’s hot.
Some ideas where it could be useful elsewhere:
- For album browsing in Amarok. At the moment, Amarok for KDE4 has its own CoverFlow-like feature, but last time I check it requires OpenGL so it works well only when the graphics system is 3-d accelerated.
- Choosing a slide in a presentation (so maybe it could be integrated into KPresenter?). Imagine you’re running your presentation and one of your audience ask you to show some previous slides, wouldn’t be cool when you flip through the slides with this flowing effect?
- Quickly skim through photos, useful in Digikam, Gwenview, or similar imaging tools. Since it’s used as a chooser, not full-fledged slide show, the size could be kept small and thus the performance should be acceptable.
Any more ideas?