Drawings within setup() after surface.setSize()

I like to write simple pieces of code without a draw() block. In this way, it often doesn’t even have to be surrounded by the setup() function, since Processing will do that behind the scenes.

When I brought over an old sketch to P3, I had to use surface.setSize() instead of size() to adjust the display window to something I opened on the fly. To my surpise, I got an empy the display window.

An example code:

surface.setSize(400, 200);
ellipse(10, 10, 20, 20);

This has been brought up 2 years ago here:
Can’t draw anything just after using surface.setSize()
The conclusion of the accepted answer was:

The surface.setSize() is done at next draw() loop.

Yet if I add a 4s delay the circle will appear as an enlarged ellipse for 4s:

surface.setSize(400, 200);
ellipse(10, 10, 20, 20);
delay(4000);

The zooming effect seems to have a reference to an “ideal” 100 x 100 sized window. Let’s try that as well:

surface.setSize(100, 100);
ellipse(10, 10, 20, 20);
delay(4000);

Oops, the circle will not disappear after 4s! What is going on?

Now everything will look fine after 4s if I follow jeremydouglass’s advice (from the above quoted topic) to “move all drawing code to draw()…”:

void setup() {
  surface.setSize(400, 200);
  ellipse(10, 10, 20, 20);
  delay(4000);
  noLoop();
}
void draw() {
   ellipse(10, 10, 20, 20);
}

Of course jeremydouglass meant this:

void setup() {
  surface.setSize(400, 200);
  noLoop();
}
void draw() {
   ellipse(10, 10, 20, 20);
}

Thanks.

1 Like

It‘s because you draw the circle, then wait 4 Seconds… and what you have is still the Circle, because it was not overwritten. If you use background() somewhere in between frames you‘ll ‚reset‘ the background and can draw a new ellipse onto it. Though i‘m not sure what exactly the question was…

This is sometimes called “immediate mode” in Processing docs.

It seems like, instead of using size() in immediate mode, you are using surface.setSize(), which is causing problems in immediate mode. Can you give an example of something you are trying to do in immediate mode that requires surface.setSize(), not size()? Other than saying “just use size() in immediate mode” I’m trying to understand your problem.

If you are trying to understand why things are happening in the order they are, keep in mind that immediate mode is a shorthand for a full sketch – it is compiled into java (with setup and draw) before being run. If you look at where size() is relocated and where surface.setSize() is relocated in your example sketch, that might help explain what is happening.

There is a special rule for moving size() to settings so that it is run first.

Here is what these two sketches look like in .java when they run:

size(400,200);
ellipse(10, 10, 20, 20);

…in java:

public class sketch_181111d extends PApplet {
  public void setup() {
    ellipse(10, 10, 20, 20);
    noLoop();
  }
  public void settings() {
    size(400,200);
  }
  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "sketch_181111d" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}

…and with surface.setSize():

surface.setSize(400, 200);
ellipse(10, 10, 20, 20);

…in java:

public class sketch_181111d extends PApplet {
  public void setup() {
    surface.setSize(400, 200);
    ellipse(10, 10, 20, 20);
    noLoop();
  }
  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "sketch_181111d" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}
1 Like

Ok, a picture is worth a thousand words. In the setup block, instead of a circle I get this zoomed ellipse for 4 seconds,
image

which after 4 s will get overwritten even without using background():
image

However, the draw block will properly render the intended circle:
image

My question was: What is going on in the setup block?

My old sketch loaded and displayed a colormap, a text file containing RGB values in many lines. The number of lines was not known before starting the program:

int [][] colorMatrix;
String selectedFile;

void setup() {
  // Open a file chooser dialog to select a matrix file
  selectInput("Select a file to process:", "fileSelected");

  // Wait for selectedFile
  while (selectedFile == null) {
    delay(200);
  }

  // Load matrix from file
  colorMatrix = loadMatCSV(selectedFile);

  // Set display window height to no. of lines in file
  size(50, colorMatrix.length);

  // Display colormap
  int i = height;
  for (int[] row : colorMatrix) {
    if (row.length == 3) {
      stroke(row[0], row[1], row[2]);
      line(0, i, width, i);
      i--;
    }
  }
}  // end of setup()


// Load matrix from file
int[][] loadMatCSV(String fileName) {
  String lines[] = loadStrings(fileName);
  int rows = lines.length;
  int[][] x = new int[rows][rows];
  for (int i=0; i<rows; i++) {
    x[i] = int(splitTokens(lines[i]));
  }
  return x;
}


// 'callback' function for selectInput
void fileSelected(File selection) {
  if (selection == null) {
    println("Window was closed or the user hit cancel.");
    System.exit(0);
  } 
  else {
    selectedFile = selection.getAbsolutePath();
  }
}

Meanwhile I’ve found this closed issue: image() in void setup() along with surface.setSize() #3935. It is very similar to my problem, and from there I got the idea of reproducing the “zooming phenomenon” :slight_smile: with a much shorter example:

PImage img;

void setup() {
  img = loadImage("https://i.imgur.com/zvG5m03.png");
  surface.setSize(img.width, img.height);
  image(img, 0, 0);
  delay(4000);
  noLoop();
}

void draw() {
  image(img, 0, 0);
}

Finally, thank you for expaining the concept of immediate mode.:+1:

2 Likes