Why does background() not clear the display here?

I've been searching for how to clear the display, and the standard answer seems to be background(). But this hasn't been working in my sketch. I think it's because I was doing manipulation of pixels. Here's a small example that illustrates:

void setup() {
  size (600, 400);
  loadPixels();
  noStroke();
}

void draw() {
}

void circle_pixels(int cx, int cy, float rad, color c) {
  for (int x=0; x<600; x++) {
    for (int y=0; y<400; y++) {
      int idx = y*600+x;
      if (sq(x-cx) + sq(y-cy) <= sq(rad)) {
        pixels[idx] = c;
      }
    }
  }
  updatePixels();
}

void circle(int cx, int cy, float rad, color c) {
  fill(c);
  ellipse(cx, cy, rad, rad);
}

void mouseClicked() {
  background(128);
  color rand_color = color(int(random(255)), int(random(255)), int(random(255)));
  // This doesn't work. Old circles stick around.
  circle_pixels(300, 200, random(300), rand_color);
  // This works. Only shows one circle at once.
  //circle(300, 200, random(300), rand_color);
}

Can someone help me understand the difference in behaviour here?

If I am doing pixel manipulation, is the recommended way to clear the display just to set pixels[x,y] to grey for each (x,y) coordinate?

Answers

  • don't draw anything in mouseClicked. set a flag and handle it in the draw().

    (mouse events can occur at any time, the image only gets updated at the end of draw so this is the only way to guarantee anything)

  • Answer ✓

    you also need to loadPixels more than just the once. you're writing them but never reading them, which is why the background has no effect.

    is there a reason you aren't using ellipse but a much slower method instead?

  • edited April 2016

    you also need to loadPixels more than just the once. you're writing them but never reading them, which is why the background has no effect.

    Thanks, this fixed it. So is the idea that calling loadPixels() stores a snapshot of the current contents of the display window in pixels, and if I want a more up-to-date copy later, I need to call it again? I didn't quite get that from the docs:

    Loads the pixel data for the display window into the pixels[] array. This function must always be called before reading from or writing to pixels[].

    I had called this function before reading pixels[] - in setup()! :)

    I had sort of envisioned it as analogous to opening a file handle.

  • edited April 2016

    is there a reason you aren't using ellipse but a much slower method instead?

    This is just a toy program that I wrote for the sake of providing a minimal example.

    don't draw anything in mouseClicked. set a flag and handle it in the draw().

    FWIW, the docs take a somewhat softer stance on this.

    It is generally not a good idea to draw inside an event function, but it can be done under certain conditions.

    In this case I don't think it makes a difference, but it's good to know in case this trips me up in the future.

  • edited April 2016

    If not reading the contents of pixels[], it's enough to invoke loadPixels() only once just to create the array. And updatePixels() is only needed if modifying pixels[].

Sign In or Register to comment.