My ultimate goal is to create a "tunnel effect" as I draw a rect to a buffer, copy the buffer to another buffer, and on subsequent draw(), copy the second buffer back to the first, only slightly smaller, then draw over top of that and repeat.
I'm completely stumped by what is going on here.
First, consider this code, which works exactly as expected 1 time (no draw loop):
PGraphics canvas;
PGraphics buffer;
void setup(){
size(500, 500);
canvas = createGraphics(width, height);
buffer = createGraphics(canvas.width, canvas.height);
canvas.beginDraw();
canvas.background(255);
canvas.noFill();
canvas.stroke(0);
canvas.rect(100 + random(-50, 50), 100 + random(-50, 50), 350 + random(-50, 50), 350 + random(-50, 50));
canvas.endDraw();
buffer.beginDraw();
buffer.image(canvas, 0, 0);
buffer.endDraw();
canvas.beginDraw();
canvas.image(buffer, 100, 100, width-200, height-200);
canvas.endDraw();
image(canvas, 0, 0);
noLoop();
}
It's a pretty dumb example, but it proves that the concept is sound: I draw to canvas
, copy to buffer
, copy buffer
back to canvas
with a reduced scale then output to main context.
But look what happens when I try to do this in the draw() loop:
PGraphics canvas;
PGraphics buffer;
void setup(){
size(500, 500);
canvas = createGraphics(width, height);
buffer = createGraphics(canvas.width, canvas.height);
canvas.beginDraw();
canvas.background(255);
canvas.noFill();
canvas.stroke(0);
canvas.rect(100 + random(-50, 50), 100 + random(-50, 50), 350 + random(-50, 50), 350 + random(-50, 50));
canvas.endDraw();
buffer.beginDraw();
buffer.image(canvas, 0, 0);
buffer.endDraw();
}
void draw(){
canvas.beginDraw();
canvas.image(buffer, 0, 0);
canvas.rect(100 + random(-50, 50), 100 + random(-50, 50), 350 + random(-50, 50), 350 + random(-50, 50));
canvas.endDraw();
image(canvas, 0, 0);
buffer.beginDraw();
buffer.image(canvas, 0, 0);
buffer.endDraw();
}
Here, what ends up happening is that the original rect that was created in setup() gets copied every frame to canvas
. So the effect is that there's a rect that doesn't move and then a second rect that gets drawn and replaced every frame.
It gets weirder. Watch what happens when I simply move the image()
function that draws to the main context:
PGraphics canvas;
PGraphics buffer;
void setup(){
size(500, 500);
canvas = createGraphics(width, height);
buffer = createGraphics(canvas.width, canvas.height);
canvas.beginDraw();
canvas.background(255);
canvas.noFill();
canvas.stroke(0);
canvas.rect(100 + random(-50, 50), 100 + random(-50, 50), 350 + random(-50, 50), 350 + random(-50, 50));
canvas.endDraw();
buffer.beginDraw();
buffer.image(canvas, 0, 0);
buffer.endDraw();
}
void draw(){
canvas.beginDraw();
canvas.image(buffer, 0, 0);
canvas.rect(100 + random(-50, 50), 100 + random(-50, 50), 350 + random(-50, 50), 350 + random(-50, 50));
canvas.endDraw();
buffer.beginDraw();
buffer.image(canvas, 0, 0);
buffer.endDraw();
image(canvas, 0, 0);
}
This ought not to change a thing, and yet the result is that the image "freezes" with two rects on the screen. For some reason it just seems to draw the same thing over and over again, even though canvas
is being re-written every time.
Changing that last line to read
image(buffer, 0, 0);
instead, goes back to the previous behaviour of "freezing" buffer, but drawing a new rect over top of it every time.
Can anyone shed some light on what is happening?