We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I first copied the exercise from section 6.4 (document page 166) of Algorithms for Visual Design using the Processing Language.The code works, but it is slow to draw, obviously.
I then tried to use createGraphics as a kind of 'buffer' as outlined on the next section of the book, section 6.5 (document page 168). I've pasted my attempt below, which doesn't quite work.
My question is how does one integrate already working code with an off-screen buffer (something like this)? Is there a general method, or do off-screen buffers use entirely different methods?
It can't be as simple as adding an extra line to the setup and draw functions, can it? What is the purpose of using elements like pg.background
, if they seem to merely duplicate the information already in background
?
Thanks,
frustrated guy new to processing
my attempt to replicate the example with a buffer:
PGraphics pg; void setup() { noSmooth(); size(300,300, P2D); pg = createGraphics(150,120, P2D); } float px[] = new float [300]; float py[] = new float [300]; float pr[] = new float [360]; void draw() { for(int i=0; i<mouseY; i++){ px[i] = random(width); py[i] = random(height); pr[i] = random(360); } background(255); for(int i=0; i<mouseY; i++){ pushMatrix(); rectMode(CENTER); translate(px[i],py[i]); rotate(radians(pr[i] + mouseX)); rect(0,0,5,500); popMatrix(); } pg.beginDraw(); pg.endDraw(); image(pg, 0, 0, width, height); }
Answers
I can't really run that code above, but maybe a little explanaiton can help.
When you use a PGraphics-object then you usually want this "buffer" to be independent from your main-window drawing and its settings. So you can decide if you want to set a background for the window or the buffe for example.
These instructions affect the main window:
When you want them to work on you buffer, you have to do it like this:
So i regret, but there's no simple one-liner.
A PApplet actually uses a PGraphics object for its underlying rendering operations. When you call, for instance
background(255);
what's really happening is something like this
this.graphics.background(255);
So to use a PGraphics buffer, all you need to do is to initialize a new PGraphics object:
Then you change all your drawing function calls to execute on the buffer object rather than the PApplet:
/*this.graphics*/pg.background(255);
Don't call PGraphics.endDraw() until you're ready to display the buffer contents on screen, because that "finalize" the PGraphics object until you call PGraphics.beginDraw() again.
after pg.endDraw(); use image(pg.....
There's a curious caveat: if we need to call smooth() or noSmooth() in P3, it gotta be called before beginDraw()! @-)
We can also use set() & background() to display PImage objects too! O:-)
P.S.: PGraphics
extends
PImage. ;;) Movie & Capture idem. :>This is a very general question, since there are so many possible applications of image buffers. I haven't read the linked book; but I'm assuming the intent in this case is to use the buffer to store the result of expensive drawing operations...
If you're drawing something that requires a lot of slow calculations, and especially if you then want to draw lots of copies of this object, do the drawing to a buffer image in setup(); then use image(bufferIMage, x, y) in draw() (example refactored from the reference):
This does have limitations: for example the image is fixed; but you might want it to update with user interaction. In this case the buffer approach is probably only worth applying if you're creating lots of copies of the object that all change in unison. You'd also have to move the drawing operation into its own function, call this from setup() and again when you get user interaction...
PGraphics is the only safe way to draw outside the "Animation" Thread.
PGraphics allows us to draw in some speed different than draw()'s frameRate() too.