Processing 当绘制到主上下文时,PGraphics似乎会被清除或冻结
我的最终目标是创建一个“隧道效应”,当我将一个矩形绘制到一个缓冲区时,将该缓冲区复制到另一个缓冲区,然后在后续的draw()中,将第二个缓冲区复制回第一个缓冲区,只是稍微小一点,然后在上面绘制并重复 我完全被这里发生的事情难住了Processing 当绘制到主上下文时,PGraphics似乎会被清除或冻结,processing,pgraphics,Processing,Pgraphics,我的最终目标是创建一个“隧道效应”,当我将一个矩形绘制到一个缓冲区时,将该缓冲区复制到另一个缓冲区,然后在后续的draw()中,将第二个缓冲区复制回第一个缓冲区,只是稍微小一点,然后在上面绘制并重复 我完全被这里发生的事情难住了 首先,考虑这个代码,它与预期的1次(不画循环)完全一致: PGraphics画布; 图形缓冲区; 无效设置(){ 大小(500500); 画布=createGraphics(宽度、高度); 缓冲区=createGraphics(canvas.width、canvas.h
首先,考虑这个代码,它与预期的1次(不画循环)完全一致:
PGraphics画布;
图形缓冲区;
无效设置(){
大小(500500);
画布=createGraphics(宽度、高度);
缓冲区=createGraphics(canvas.width、canvas.height);
canvas.beginDraw();
背景(255);
canvas.noFill();
画布笔划(0);
rect(100+随机(-50,50),100+随机(-50,50),350+随机(-50,50),350+随机(-50,50));
canvas.endDraw();
buffer.beginDraw();
图像(画布,0,0);
endDraw();
canvas.beginDraw();
画布图像(缓冲区,100,100,宽度-200,高度-200);
canvas.endDraw();
图像(画布,0,0);
noLoop();
}
这是一个相当愚蠢的例子,但它证明了这个概念是正确的:我画到canvas
,复制到buffer
,复制buffer
回到canvas
,缩小比例,然后输出到主上下文
但看看我在draw()循环中尝试这样做时会发生什么:
PGraphics画布;
图形缓冲区;
无效设置(){
大小(500500);
画布=createGraphics(宽度、高度);
缓冲区=createGraphics(canvas.width、canvas.height);
canvas.beginDraw();
背景(255);
canvas.noFill();
画布笔划(0);
rect(100+随机(-50,50),100+随机(-50,50),350+随机(-50,50),350+随机(-50,50));
canvas.endDraw();
buffer.beginDraw();
图像(画布,0,0);
endDraw();
}
作废提款(){
canvas.beginDraw();
图像(缓冲区,0,0);
rect(100+随机(-50,50),100+随机(-50,50),350+随机(-50,50),350+随机(-50,50));
canvas.endDraw();
图像(画布,0,0);
buffer.beginDraw();
图像(画布,0,0);
endDraw();
}
在这里,最终的结果是在setup()中创建的原始rect每帧都被复制到画布上。所以效果是有一个不移动的矩形,然后第二个矩形被绘制并替换每一帧
它变得更奇怪了。观察当我简单地移动绘制到主上下文的image()
函数时会发生什么:
PGraphics画布;
图形缓冲区;
无效设置(){
大小(500500);
画布=createGraphics(宽度、高度);
缓冲区=createGraphics(canvas.width、canvas.height);
canvas.beginDraw();
背景(255);
canvas.noFill();
画布笔划(0);
rect(100+随机(-50,50),100+随机(-50,50),350+随机(-50,50),350+随机(-50,50));
canvas.endDraw();
buffer.beginDraw();
图像(画布,0,0);
endDraw();
}
作废提款(){
canvas.beginDraw();
图像(缓冲区,0,0);
rect(100+随机(-50,50),100+随机(-50,50),350+随机(-50,50),350+随机(-50,50));
canvas.endDraw();
buffer.beginDraw();
图像(画布,0,0);
endDraw();
图像(画布,0,0);
}
这不应该改变任何事情,但结果是图像在屏幕上用两个矩形“冻结”。出于某种原因,它似乎一次又一次地画着同样的东西,即使每次都在重写canvas
将最后一行改为
图像(缓冲区,0,0);
相反,它返回到以前的“冻结”缓冲区的行为,但每次都在其上绘制一个新的rect
有人能解释一下发生了什么吗?仔细想想你在每张PGraphics
图像中到底有什么
每个PGraphics
都是一个500x500的图像,背景为白色,上面有一个黑色矩形
然后你拍摄一张图片,画在另一张上面。它们仍然是带有黑色矩形的白色图像。需要注意的重要一点是,由于它们都有白色背景,因此您将无法通过“新”图像看到“旧”图像。所以你只是来回画同一个矩形
可以通过删除第二个代码块中对canvas.background()
的调用来证明这一点。然后你会看到长方形堆叠在一起。这仍然不是隧道效应,因为每次只绘制相同的ish矩形,但这是一个单独的问题
所以,要解决你的问题,你需要准确地注意每张图片中的内容。尤其要注意背景是否透明
我还将注意到,您可能只需要绘制越来越小的单个缓冲区图像就可以实现这种效果,甚至可以通过对主画布执行相同的操作来完全不绘制缓冲区图像。查看源代码,问题在于image()
image()
通过调用imageImpl()
,设置PGraphics纹理,该纹理恰好在PGraphics
中被覆盖。通过设置纹理,而不是直接设置像素,可以保留和缓存纹理引用,这解释了(至少在一定程度上满足了我的好奇心)使用PGraphics.image()
(至少在主绘图上下文中)似乎“锁定”的原因将缓冲区PGraphics对象设置为对后续draw()操作无效的点
有两种解决方案可以避免这种情况:
仍然使用两个屏幕外缓冲区(在我的示例中为canvas
和buffer
),继续使用canvas.image()
,以便能够将缓冲区写入图像并可能对其进行缩放;但在将画布写入主绘图上下文时,请改用set(x,y,canvas)
PGraphics.set()
继承自P
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.background(255);
canvas.image(buffer, 10, 20, width-20, width-20);
canvas.rect(100 + random(-50, 50), 100 + random(-50, 50), 350 + random(-50, 50), 350 + random(-50, 50));
canvas.endDraw();
set(0, 0, canvas);
buffer.beginDraw();
buffer.image(canvas, 0, 0);
buffer.endDraw();
}
PImage buffer;
void setup(){
size(500, 500);
background(255);
noFill();
stroke(0);
buffer = g.copy();
}
void draw(){
background(255);
image(buffer, 10, 20, width-20, width-20);
rect(100 + random(-50, 50), 100 + random(-50, 50), 350 + random(-50, 50), 350 + random(-50, 50));
buffer = g.copy();
}