Water is a really nice effect, one of the better tricks around. It's also pretty simple to code, should take no more than an afternoons work to get a good water routine.
[size="5"]Basics
First thing you'll need is 2 buffers, for the water. This needs to be an array of ints, same size as destination buffer. Arrange these in a 2-element array, to ease the flipping. Clear these to zero, and you're ready to start.
[size="5"]Calculate The New Water
Calculating the new water is pretty simple. You'll need a loop that execute from 1 to height-1, then 1 to width - 1. At each element for the water, you'll need to sum the North, South, East, West points from the current water, and divide by 2 Not 4, 2. Then subtract the new water for [y][x] from this. This is your basic smooth function. Now you need to add the 'harmonic motion' to it. Take the new-water[y][x], shift it right x places (x could be 4) and subtract it from the new-water[y][x]. Pseudo-code for this might look like:
for y := 1 to height - 1
for x := 1 to width - 1
new-water[y][x] = ((old-water[y-1][x] +
old-water[y+1][x] +
old-water[y][x-1] +
old-water[y][x+1]) / 2) -
new-water[y][x])
new-water[y][x] -= new-water[y][x] shr x
end
end
[size="5"]Paint The Water
Water is also pretty straightforward to paint. In fact some of the techniques here, you will see later on in the bump-mapping. Back to the task in hand. We will again need a loop for every pixel on the screen. What we need to do is calculate a kind-of normal at each pixel. This is simply:
offsetx = water[y][x] - water[y+1][x]
offsety = water[y][x] - water[y][x+1]
offsetx /= 3;
offsety /= 8;
indexu = offsetx + x;
indexv = offsety + y;
MulTable[backdrop[indexv*256+indexu]*256+colour];
For y := 1 to height - 1
For x := 1 to width - 1
offsetx = water[y][x] - water[y+1][x]
offsety = water[y][x] - water[y][x+1]
colour = 128 - offsetx
trim colour to 0..255
divide offsetx and offsety by 8
add offsetx to x giving indexu
add offsety to y giving indexv
Plot (backdrop*colour) >> 8, lookup in table
End
End
[size="5"]The Water Loop
Note it makes a difference what order you do calculations in. It's pretty simple though. You need to:
- Draw to the water
- Paint it
- Calculate new water
- Page flip the water
Tom Hammersley, [email="tomh@globalnet.co.uk"]tomh@globalnet.co.uk[/email]