Can't image() between PGraphics with default renderer?

Using P2D, I can use image() to copy an image from one PGraphics to another many times. With the default renderer, I can copy only once. Is this a known behavior? Is this logical behavior?

Tagged:

Answers

  • Can you please post a MCVE that demonstrates the behavior?

  • When running this sketch, press 1 thru 4. 2 looks like 1, 4 is supposed to look like 3 but doesn't unless P2D is added. The second pg2.image() does not work.

    PGraphics pg1;
    PGraphics pg2;
    
    void setup() {
      size(640, 480); // adding P2D fixes it
    
      pg1 = createGraphics(width, height);// adding P2D fixes it
      pg2 = createGraphics(width, height); // adding P2D fixes it
    }
    
    void draw() {
    }
    
    void keyPressed() { 
      switch (key) {
      case '1':
        pg1.beginDraw();
        pg1.fill(128);
        pg1.rect(100, 100, 100, 50);
        pg1.endDraw();
    
        background(0);
        image(pg1, 0, 0, width/2, height/2);
    
        break;
    
      case '2':
        pg2.beginDraw();
        pg2.image(pg1, 0, 0, width, height);
        pg2.endDraw();
    
        background(0);
        image(pg2, width/2, 0, width/2, height/2);
    
        break;
    
      case '3':
        pg1.beginDraw();
        pg1.fill(128);
        pg1.rect(100, 100, 100, 50);
        pg1.rect(100, 300, 100, 50);
        pg1.endDraw();
    
        background(0);
        image(pg1, 0, height/2, width/2, height/2);
    
        break;
    
      case '4':
        pg2.beginDraw();
        pg2.image(pg1, 0, 0, width, height);
        pg2.endDraw();
    
        background(0);
        image(pg2, width/2, height/2, width/2, height/2);
    
        break;
      }
    }
    
  • Thank you for making an MCVE.

    This was a bit confusing for me because you are layering content into buffers and then referencing them for your cases -- so the whole thing is full of side-effects that are dependent on pushing keys in a specific order and then stopping.

    Here is a working example based on yours (only with the interactivity and variable reuse removed). It uses only PGraphics.image() to copy from one PGraphics to another with correct results -- without using the P2D renderer.

    PGraphics pg1r_orig;
    PGraphics pg1r_move;
    PGraphics pg2r_orig;
    PGraphics pg2r_move;
    
    void setup() {
      size(640, 480);
    
      pg1r_orig = createGraphics(width, height);
      pg1r_move = createGraphics(width, height);
      pg2r_orig = createGraphics(width, height);
      pg2r_move = createGraphics(width, height);
    
      pg1r_orig.beginDraw();
      pg1r_orig.fill(128);
      pg1r_orig.rect(100, 100, 100, 50);
      pg1r_orig.endDraw();
    
      pg1r_move.beginDraw();
      pg1r_move.image(pg1r_orig, 0, 0, width, height);
      pg1r_move.endDraw();
    
      pg2r_orig.beginDraw();
      pg2r_orig.fill(128);
      pg2r_orig.rect(100, 100, 100, 50);
      pg2r_orig.rect(100, 300, 100, 50);
      pg2r_orig.endDraw();
    
      pg2r_move.beginDraw();
      pg2r_move.image(pg2r_orig, 0, 0, width, height);
      pg2r_move.endDraw();
    
      noLoop();
    }
    
    void draw() {
      background(0);
      // examples in upper left and right
      image(pg1r_orig, 0, 0, width/2, height/2);
      image(pg1r_move, width/2, 0, width/2, height/2);
    
      // examples in lower left and right
      image(pg2r_orig, 0, height/2, width/2, height/2);
      image(pg2r_move, width/2, height/2, width/2, height/2);
    }
    

    I haven't dug deeper to see what the actual problem is with your MCVE, but PGraphics.image(PGraphics) does work in the default renderer, as you can see.

  • My problem with PGraphics.image(PGraphics) in the default renderer is that it only works the first time. In my MCVE (when pressing 1 thru 4 in order), image() works the first time but not the second.

    I am currently able to work around this by using P2D.

  • Re:

    it only works the first time

    I'm just not seeing that. Try adding this to the end of setup:

      pg2r_move.beginDraw();
      pg2r_move.background(0);
      pg2r_move.endDraw();
    

    Okay, now pg2r is blank.

    Now add this below it in setup:

      pg2r_move.beginDraw();
      pg2r_move.image(pg2r_orig, 0, 0, width, height);
      pg2r_move.endDraw();
    

    Okay, we drew a PGraphics using image -- twice -- and it worked fine.

  • And after that, try adding this to setup below everything else. We'll use two different PGraphics AND draw each one twice multiple times AND do it all in the same beginDraw/endDraw -- that's four different PGraphics.image(PGraphics) calls:

      pg2r_move.beginDraw();
      pg2r_move.image(pg1r_orig, 0, 0, width, height);
      pg2r_move.translate(10,10);
      pg2r_move.image(pg1r_orig, 0, 0, width, height);
      pg2r_move.translate(100,-10);
      pg2r_move.image(pg2r_orig, 0, 0, width, height);
      pg2r_move.translate(10,10);
      pg2r_move.image(pg2r_orig, 0, 0, width, height);
      pg2r_move.endDraw();
    

    ...works just fine.

    Screen Shot 2017-12-28 at 2.28.18 PM

  • My best next guesses would be that you have confused your fill() commands with background() commands, and so you expect your original sketch to be doing something (clearing then replacing) that it doesn't actually to -- and/or that you aren't clear on the PGraphics having a transparent background by default, so you are surprised when the single rectangle drawn on top of two rectangles looks like two rectangles.

Sign In or Register to comment.