Author Topic: [C/ Win32 GDI] How to make a bitmap 'wobble'?  (Read 137 times)

0 Members and 1 Guest are viewing this topic.

Offline SilentWorld

  • ZX 81
  • *
  • Posts: 2
  • Karma: 0
    • View Profile
[C/ Win32 GDI] How to make a bitmap 'wobble'?
« on: September 29, 2020 »
The wobble effect is one of my all-time favourites. It is simple but always nice and hypnotic to look at. I am using C and plain GDI for my projects and want to learn how to apply this effect to a bitmap. From my basic understanding, each column or row of pixels moves using sine modulation. I've heard that this probably isn't the best way to do it, but I'm admittedly terrible at math. My programming ability is that of a beginner, however I've been hacking around with the GDI and managed to learn a thing or two. Any help is appreciated!

Offline Optimus

  • DBF Aficionado
  • ******
  • Posts: 2453
  • Karma: 128
    • View Profile
    • Optimouse Demo Site
Re: [C/ Win32 GDI] How to make a bitmap 'wobble'?
« Reply #1 on: October 02, 2020 »
There are many ways to do wobble. There is wobble only on X and wobble both on X and Y. The later is the yummie one :)

Sines would do it but used as look up tables (depending on the system your are working, in my opinion in modern GPUs with shaders, just go pure math,. but in software rendering even in modern PCs integer LUTs for sines would still be faster).

It's going to be a regular loop over X,Y bitmap pixels. Pseudocode
for (int y=0; y<height; ++y) {
  int offsetY = sin(x * freq) * offsetHeight;
  for (int x=0; x<width; ++x) {
    int offsetX = sin(y * freq) * offsetWidth;
    putpixel(x,y, bitmap[x + offsetX][y + offsetY]);
  }
}

Of course don't use putpixel or sin directly,. that's just pseudo code. You can do more complex sines on the offsets, like offset = sin(x * freq1) + sin(x * freq2)

The other way, if you don't want to do per pixel offset is to split the screen into a grid of quad polygons, e.g. every 16*16 pixels, then offset the vertices (or the texture coordinates alternativelly). Interpolate texture between grid points. This way you could use float maths only for few point and not per pixel and still be fast enough, if you don't want to use LUTs. But I think the first per pixel method with some precalc of the sines in LUTs could be much easier, unless you are on a system with a texture rendering engine already.
Challenge Trophies Won:

Offline va!n

  • Pentium
  • *****
  • Posts: 1420
  • Karma: 109
    • View Profile
    • http://www.secretly.de
Re: [C/ Win32 GDI] How to make a bitmap 'wobble'?
« Reply #2 on: October 10, 2020 »
Thanks for explaining Optimus!
Here is a small test done in purebasic, which is probaly not the same effect as you guys are talking about and the result is a bit wired. (Image is mirrored a special point)
Move mouse hoizontal to change frequence... move mouse vertical to change offsetHeight.

Code: [Select]
; Small bitmap effect example - va!n in 10/2020

InitSprite()
InitKeyboard()
InitMouse()
OpenScreen(640,480,32,"")

LoadSprite(1,"d:\Unbenannt.bmp",0)

sprH = SpriteHeight(1)

Repeat
  ExamineKeyboard()
  ExamineMouse()
 
 
  ClearScreen(0)
   
;   For (int y=0; y<height; ++y) {
;   int offsetY = Sin(x * freq) * offsetHeight;
;   For (int x=0; x<width; ++x) {
;     int offsetX = Sin(y * freq) * offsetWidth;
;     putpixel(x,y, bitmap[x + offsetX][y + offsetY]);
;   }
; }
 
 
  offsetHeight = MouseY()   
  freq.f =   MouseX() / 10000  ; 0.004;MouseX() / 1000
 
  For y = 0 To sprH
    offsetY = Sin(y * freq) * offsetHeight
    ClipSprite(1,0,offsetY,SpriteWidth(1),1)
    DisplaySprite(1, 0, y)
  Next
 
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)

End
- hp EliteBook 8540p, 4 GB RAM, Windows 8.1 x64
- Asus P5Q, Intel Q8200, 6 GB DDR2, Radeon 4870, Windows 8.1 x64
http://www.secretly.de
Challenge Trophies Won: