FAQ
Cover
This is the archive Discourse for the Processing (ALPHA) software.
Please visit the new Processing forum for current information.

   Processing 1.0 _ALPHA_
   Programming Questions & Help
   Programs
(Moderators: fry, REAS)
   water water everywhere
« Previous topic | Next topic »

Pages: 1 
   Author  Topic: water water everywhere  (Read 491 times)
rgovostes

rgovostes
water water everywhere
« on: Dec 21st, 2003, 4:22am »

I've been trying to implement this water-ish algorithm...
 
I think I've followed it pretty closely, but it doesn't want to work. Everything from the background not being drawn with the right dimensions, to the ripples being too wide...
 
If you'd like to have a peek and see if anything is horribly wrong, please download the .tgz archive here.
 
Everything worked pretty well while implementing pieces of it, but I had to go through and adjust it often, so it might have broken in the midst. The strangest problem is that the mouse position is awry (though, this must be due to something in the ripple code).
 
Arr.
Ryan Govostes
 
Glen Murphy

WWW Email
Re: water water everywhere
« Reply #1 on: Dec 21st, 2003, 6:39am »

I implemented a similar algorithm here: http://bodytag.org/nav.php?u=tp02/  
 
Source is there, perhaps it would give you some ideas?
 
rgovostes

rgovostes
Re: water water everywhere
« Reply #2 on: Dec 22nd, 2003, 8:22pm »

Hmm, Glen, I didn't have any luck with your code. However, I got mine to kind-of-work:
 
Code:
// Water v1.0, Dec 20 '03
// based on algorithm explained by Hugo Elias
//  http://freespace.virgin.net/hugo.elias/graphics/x_water.htm
// implemented by Ryan Govostes
 
int[] oldBuffer, newBuffer;
float damping = 0.5; // non-integer between 0 and 1
BImage backdrop, aqua;
 
void setup() {
  size(320, 200);
  colorMode(RGB, 255);
  
  oldBuffer = new int[width * height];
  newBuffer = new int[width * height];
  
  backdrop = loadImage("backdrop.gif");
  aqua = new BImage(width, height);
  
  background(backdrop);
}
 
void loop() {
  int i, x, y;
  int tempHeight, xOffset, yOffset;
  int[] tempBuffer = new int[width * height];
  color tempColor;
  float shading;
 
  for (i = 0; i < (width * height); i ++) {
    x = i % height;
    y = int(floor(i / width));
    if ((x > 0) && (x < (width - 1)) && (y > 0) && (y < (height - 1))) {
      tempHeight  = oldBuffer[i - 1] + oldBuffer[i + 1];
      tempHeight += oldBuffer[i - width] + oldBuffer[i + width];
      tempHeight  = (tempHeight / 2) - newBuffer[i];
      tempHeight *= damping;
      newBuffer[i] = tempHeight;
    }
  }
  
  for (i = 0; i < (width * height); i ++) {
    x = i % height;
    y = int(floor(i / width));
    if ((x > 0) && (x < (width - 1)) && (y > 0) && (y < (height - 1))) {
      xOffset = newBuffer[i - 1] - newBuffer[i + 1];
      yOffset = newBuffer[i - width] - newBuffer[i + width];
      shading = xOffset;
      tempColor = backdrop.pixels[getIndex((x + xOffset), (y + yOffset))];
      tempColor = color(red(tempColor) * shading, green(tempColor) * shading, blue(tempColor) * shading);
      pixels[i] = tempColor;
    }
  }
  
  tempBuffer = newBuffer;
  newBuffer = oldBuffer;
  oldBuffer = tempBuffer;
}
 
void mousePressed() {
  newBuffer[getIndex(mouseX, mouseY)] += 5000;
  oldBuffer[getIndex(mouseX, mouseY)] += 5000;
}
 
int getIndex(int x, int y) {
  return constrain(((y * width) + x), 0, (width * height - 1));
}

 
There are numerous problems, such as the background image not being drawn properly, and shading not being done right.
 
I'm getting tired of this.
Ryan Govostes
« Last Edit: Dec 23rd, 2003, 4:16am by rgovostes »  
rgovostes

rgovostes
Re: water water everywhere
« Reply #3 on: Dec 23rd, 2003, 4:12am »

I updated the code by separating it into multiple functions, mainly processWater() and renderWater(). The first calculates the change in the height map; the second applies the height map to the background image. If processWater() does not change any values, the water is not re-rendered.
 
Code:
// Water v1.0, Dec 20 '03
// based on algorithm explained by Hugo Elias
//  http://freespace.virgin.net/hugo.elias/graphics/x_water.htm
// implemented by Ryan Govostes
 
int[] oldBuffer, newBuffer;
float damping = 0.8; // non-integer between 0 and 1
BImage backdrop;
 
void setup() {
  size(320, 200);
  colorMode(RGB, 255);
   
  oldBuffer = new int[width * height];
  newBuffer = new int[width * height];
   
  backdrop = loadImage("backdrop.gif");
  background(backdrop);
}
 
void loop() {
  int[] tempBuffer = new int[width * height];
  boolean hasChanged;
 
  hasChanged = processWater();
  if (hasChanged == true) { renderWater(); }
   
 
  tempBuffer = newBuffer;
  newBuffer = oldBuffer;
  oldBuffer = tempBuffer;
}
 
void mousePressed() {
  newBuffer[getIndex(mouseX, mouseY)] += 5000;
  oldBuffer[getIndex(mouseX, mouseY)] += 5000;
}
 
boolean processWater() {
  int i, x, y, tempHeight;
  boolean hasChanged = false;
   
  for (i = 0; i < (width * height); i ++) {
    x = i % height;
    y = int(floor(i / width));
    if ((x > 0) && (x < (width - 1)) && (y > 0) && (y < (height - 1))) {
   tempHeight  = oldBuffer[i - 1] + oldBuffer[i + 1];
   tempHeight += oldBuffer[i - width] + oldBuffer[i + width];
   tempHeight  = (tempHeight / 2) - newBuffer[i];
   tempHeight *= damping;
   if (newBuffer[i] != tempHeight) {
     hasChanged = true;
     newBuffer[i] = tempHeight;
   }
    }
  }
   
  return hasChanged;
}
 
void renderWater() {
  int i, x, y, xOffset, yOffset;
  color tempColor;
  float shading;
   
  for (i = 0; i < (width * height); i ++) {
    x = i % height;
    y = int(floor(i / width));
    if ((x > 0) && (x < (width - 1)) && (y > 0) && (y < (height - 1))) {
 xOffset = newBuffer[i - 1] - newBuffer[i + 1];
 yOffset = newBuffer[i - width] - newBuffer[i + width];
 shading = 0;//xOffset;
 tempColor = backdrop.pixels[getIndex((x + xOffset), (y + yOffset))];
 tempColor = color(red(tempColor) - shading, green(tempColor) - shading, blue(tempColor) - shading);
 pixels[i] = tempColor;
    }
  }
}
 
int getIndex(int x, int y) {
  return constrain(((y * width) + x), 0, (width * height - 1));
}

 
Still, it's not looking too pretty. I also need a background image (the current one I have is greyscale) if anyone could provide a small, dark blue one, similar to this (without the ripples):
 
 
Pages: 1 

« Previous topic | Next topic »