Skip to content

image() causes PImage reference to break when using PGraphics #5760

@JackWitherell

Description

@JackWitherell

Last minute note- I waited a day or so for 3.5 to come out to test to see if this was an issue isolated to 3.4 and it's not. This behavior is still present in 3.5

ANOTHER NOTE: I've gained more insight in trying to figure out this issue. Take a look at the second post for a better example of this behavior that isolates the problem more.

Description

I couldn't find any other cases where this is happening and I've spent the past few days trying to narrow down what causes this behavior. I have a few PGraphics objects and depending where the main PImage is called from when calling image() I'm getting different results for what it looks like.

Made a post on Processing's forums and we've started looking into possible reasons why this is happening and solutions.

Example Code Description

Try running this code example. In this example, 'container' is of a class MajorObject that stores
a. a graphics buffer
b. several objects of type "Object"

Each of the Objects contains
a. a PImage object

setup starts things out by creating an image of a loading bar in a global PGraphics object and then sends that image into the constructor of two "Object" objects that are then stored inside of MajorObject. The draw loop then asks MajorObject to draw those objects onto the screen, starting with the global PGraphics object.

Example Code

PGraphics spriteImage;
MajorObject container;

class MajorObject{
  ArrayList<Object> contains;
  PGraphics localCanvas;
  MajorObject(){
    contains=new ArrayList<Object>();
    localCanvas=createGraphics(180,30);
  }
  void addObject(Object takingInObject){
    contains.add(takingInObject);
  }
  PImage displayObjects(){
    localCanvas.beginDraw();
    localCanvas.clear();
    for(int i=0; i<contains.size();i++){
      image(contains.get(i).getImage(),10,30); //18 draws the internal reference to the image onto the screen
      localCanvas.image(contains.get(i).getImage(),0,20*i); //19 draws the image locally to the internal canvas
    }
    localCanvas.endDraw();
    return localCanvas;
  }
  void printContainer(){
    image(displayObjects(),10,50);
  }
}

class Object{
  PImage storedImage;
  Object(PImage takingInImage){ //31 taking in PGraphics object
    storedImage=takingInImage;
  }
  PImage getImage(){
    PImage tempImage=storedImage;
    return tempImage;
  }
}

void settings(){
  size(200,150);
}

void setup(){
  frameRate(2);
  spriteImage=createGraphics(180,10);
  spriteImage.beginDraw();
  spriteImage.stroke(255);
  spriteImage.fill(0);
  spriteImage.rect(0,0,179,9);
  spriteImage.endDraw();
  container=new MajorObject();
  container.addObject(new Object(spriteImage));
  container.addObject(new Object(spriteImage));
}

void draw(){
  background(0);
  spriteImage.beginDraw();
  spriteImage.line(frameCount,0,frameCount,10);
  spriteImage.endDraw();
  image(spriteImage,10,10);                  //59    display from global object
  container.printContainer();                //60    draw global object's reference in buffer
}

Expected Behavior

I expect either
a. the original PGraphics object to be sent into the constructor and be copied and stored inside of each Object in their respective PImages, therefore to remain unchanged and stay the way they are from the beginning of the program.
or
b. a reference to the original PGraphics object's PImage to be sent in on line 31 to be maintained as a reference to the external global PGraphic's internal PImage. Any changes made towards that PGraphics object to be preserved and shown in any internal calls to the PImages stored in the Objects inside of MajorObject's ArrayList of Objects.

Current Behavior

Depending on which image() function gets called first, either the global reference to the original PGraphics object is severed internally with preliminary changes being apparent (showing that changes to the original PGraphics object did effect the internal PImage at some point) or, if the internal ones get called first, the external reference to the original PGraphics object is severed and isn't updated correctly anymore in draw()

demon

Steps to Reproduce

  1. Copy and Paste the code above into processing
  2. Notice how only the external call to draw the PGraphics object and the internal one to directly draw the internal objects inside of the MajorObject are actually updating along with the original PGraphics object. The internal reference being drawn to the internal buffer in MajorObject isn't updating anymore past the first frame.
  3. Remove lines 18 and 59. Notice how when there's no attempt to draw the global PGraphics object or the reference to it internally, the internal PImages can be drawn to MajorObjects buffer and will update alongside the global PGraphics Object.
    OPTIONALLY, and for insight: place lines 18 19 59 and 60 inside of an if(key=='a') block. What you'll find is that the PGraphics global object will be updating in the background, but as soon as you press the a key and they draw, half of the PImage references get suspended at the progress that the global PGraphics object is at.

Your Environment

Windows 10 newest build, happened on last build of windows too, Processing 3.4 and 3.5

Possible Causes / Solutions

My theory is that the image() function itself is messing with references. I'm not sure if this is a feature inherent to the way java works or if it's even part of Processing's implementation and that it's like this on purpose, but it seems to go against the way java references work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions