How to adapt my existing methods that write to the screen to work with PGraphics instead - when required?

I’m able to successfully draw to the screen using standard methods such as : stroke, line & fill.

Similarly I’m able to draw to a graphics buffer, thus:

PGraphics buff;
buff = createGraphics( 200, 200 );
buff.beginDraw();
buff.background( 0 );
buff.fill ......
buff.rect .....
buff.endDraw();

Both of those cases work fine. Well done me.

My question is this - How could I refactor my existing methods that draw to the screen so that they are able to draw to the graphics buffer when required ?

ie I want to achieve something like below but without the conditional, as that would requires me to double up all the drawing commands just to prefix them with buff. :

PGraphics buff;
buff = createGraphics( 200, 200 );

public void myMethodthatDrawsStuff( PGraphics buff,  int x, int y, int w, int h ) {
    // this method would have multiple rects, lines, fills, strokes etc in reality

    if (buff == null)
        rect (x, y, w, h);
    else
        buff.rect (x, y, w, h);
}

I’m recalling the ‘with … do’ from Pascal… but I think we’ve all moved on a bit from those days :wink:

Hope I could describe the issue adequately. Grateful for any assistance.
Cheers!

1 Like

Processing.GitHub.io/processing-javadocs/core/processing/core/PApplet.html#getGraphics--

// https://Discourse.Processing.org/t/
// how-to-adapt-my-existing-methods-that-write-to-the-screen-
// to-work-with-pgraphics-instead-when-required/10609/2

// 2019-04-24

PGraphics buff;

void setup() {
  size(300, 200);
  noLoop();

  background(#FFFF00);
  fill(#0000FF);

  myMethodThatDrawsStuff(width>>2, height>>3, width>>1, height>>2);

  buff = createGraphics(width, height>>1);

  buff.beginDraw();
  buff.background(#00FFFF);
  buff.fill(#FF0000);
  buff.endDraw();

  myMethodThatDrawsStuff(buff, width>>2, height>>3, width>>1, height>>2);
  set(0, height>>1, buff);
}

void myMethodThatDrawsStuff(int x, int y, int w, int h) {
  myMethodThatDrawsStuff(null, x, y, w, h);
}

void myMethodThatDrawsStuff(PGraphics pg, int x, int y, int w, int h) {
  if (pg == null)  pg = getGraphics();

  pg.beginDraw();
  pg.rect(x, y, w, h);
  pg.endDraw();
}
1 Like

Spot on. Thanks so much for a quik response @GoToLoop :+1:
its getting late here - will test this out tomorrow for sure.

Just what I needed and makes total sense.
Plus, I bonus-learned ‘set’ ‘>>’ and ‘noLoop()’
Thanks again.

In general this solution that @GoToLoop shared (optional PGraphics, default canvas) is a great pattern for libraries that draw, to make them work with either a PGraphics or the main canvas. In the case of libraries that draw onto their own buffer (like a HUD) you can also use this pattern for the render method, or make it part of the constructor, so that the final composited output can be redirected to either the main canvas or a PGraphics in this way.

An example of that approach is Peasycam, which draws to the canvas by default but has an alternate constructor for an optional PGraphics.

http://mrfeinberg.com/peasycam/reference/peasy/PeasyCam.html

1 Like