Underwater effect

Posted by Ariya Hidayat on July 13, 2008 · 12 comments

Distorting the geometry of an image with a specific periodic pattern can give the illusion of being underwater. This trick was for example employed in the very first version of Quake, either to oscillate the water surface or to modify the view when you jump inside the water. Apparently, it is not difficult to do that, even with pixel-per-pixel manipulation of QImage.

Check out the code from the usual place:

svn checkout svn://labs.trolltech.com/svn/graphics/dojo/underwater

It is recommended to build the program and see the effect by yourself, the following screenshot can hardly describe the animation. As usual, once the example is running (it would show the included bridge picture), you can change the picture by dragging an image (from local disk or a web browser, e.g. Flickr or Picasa Web) and dropping it on the main window.

Qt for doing underwater effect

Note: the snappers picture is from james_wicks, distributed under the Creative Commons Attribution 2.0 Generic.

QShare(this)

No related posts.


12 comments

1 Giuseppe July 13, 2008 at 4:58 pm
 

Please, can you check the code on that repository? Revision 681 doesn’t compile:

underwater.cpp: In function ‘void applyUnderwater(const QImage*, QImage*, QImage*, int, qreal)’:
underwater.cpp:29: error: ‘result’ was not declared in this scope

thanks ;)

2 ariya July 13, 2008 at 7:33 pm
 

@Giuseppe: Check it again, please. Thanks for noticing!

3 Nikolaj Hald Nielsen July 13, 2008 at 7:43 pm
 

Builds fine here, but I get a

ASSERT: “img->size() != result1->size()” in file underwater.cpp, line 31

as soon as I run it

4 ariya July 13, 2008 at 9:01 pm
 

@Nikolaj: I just committed a couple more bug fixes, check it again. Thanks!

5 Nikolaj Hald Nielsen July 13, 2008 at 9:48 pm
 

@ariya

Works like a charm now, thanks! :-)

6 Mocky July 13, 2008 at 9:59 pm
 

Now I get “ASSERT: “img->size() == result1->size()” in file underwater.cpp, line 36″ (Rev 683). Specifying the picture on the commandline does not help, either.
I commented out the widget.loadImage() in main. The widget shows but it still dies after dragging and dropping a picture into it with “ASSERT: “img->size() == result1->size()” in file underwater.cpp, line 36″.

If I comment out the Q_ASSERTS I only get “Bus error”.
I’m on OS X btw.

7 Axel July 14, 2008 at 9:33 am
 

Same here on OSX:

surface:underwater axeljager$ underwater.app/Contents/MacOS/underwater
ASSERT: “img->size() == result1->size()” in file underwater.cpp, line 36
surface:underwater axeljager$

8 andre July 14, 2008 at 9:52 am
 

if you set change m_enableEffect->setChecked(true); to m_enableEffect->setChecked(false); then the app comes up on mac os x

andre

9 ariya July 14, 2008 at 1:03 pm
 

@Mocky, @Axel: should be fixed now. Try it again and many thanks!

10 David Johnson July 14, 2008 at 8:53 pm
 

I’m amazed at how little CPU this effect is using!

11 Hugo July 14, 2008 at 10:00 pm
 

It would be very usefull to see how to implement a image effect using GPU (GLSL) and Qt !

12 Giuseppe July 15, 2008 at 12:29 am
 

> It would be very usefull to see how to implement a image effect using GPU (GLSL) and Qt !

to read as: it would be very useful to have QtCoreImage :-)

Comments on this entry are closed.

Previous post:

Next post: