Is there something like beginRecord() that works with P2D/texture()?

#1

I’m creating a kaleidoscope program using texture() to mirror things and then I want to be able to redraw and save everything at a higher resolution. I found a method of redrawing and saving the screen but it uses JAVA2D/beginRecord() which doesn’t seem to work with texture(). Is there another way to use createGraphics so that it works with texture()? Or perhaps a different way to redraw and save everything?

This is as much as I could manage to trim down my code.

boolean record;
int mirrorAmount = 0;
float hypotenuse;

void drawShapes() {
  noStroke();
  background(100);
  for (int i=0; i<60; i++) {
    fill(random(100),random(100),random(100),100);
    ellipse(random(width),random(height),50,50);
  }
}

void setup(){
  size(800,800, P2D);
  colorMode(HSB,100);
  
  hypotenuse = sqrt(sq(width)+sq(height))/2;
}


void draw() {
  if (mirrorAmount==0) {
    //nothing
  } else if (mirrorAmount==1) {
    flipHalf();
  } else if (mirrorAmount==2) {
    flipQuarter();
    flipHalf();
  } else if (mirrorAmount==3) {
    flipEighth();
    flipQuarter();
    flipHalf();
  } else if (mirrorAmount==4) {
    flipSixteenth();
    flipEighth();
    flipQuarter();
    flipHalf();
  }
}

void flipSixteenth() {
  beginShape();
  texture(get());
  vertex(width/2, height/2, width/2, height/2);
  vertex(0, .2958*height, 0, .2958*height); //fix this eventually
  vertex(width/2 - hypotenuse, height/2, 0, 0);
  endShape();
}

void flipEighth() {
  beginShape();
  texture(get());
  vertex(width/2, height/2, width/2, height/2);
  vertex(width/2, 0, 0, height/2);
  vertex(0, 0, 0, 0);
  endShape();
}

void flipQuarter() {
  beginShape();
  texture(get());
  vertex(width/2, height/2, width/2, height/2);
  vertex(width/2, height, width/2, 0);
  vertex(0, height, 0, 0);
  vertex(0, height/2, 0, height/2);
  endShape();
}

void flipHalf() {
  beginShape();
  texture(get());
  vertex(width/2, 0, width/2, 0);
  vertex(width, 0, 0, 0);
  vertex(width, height, 0, height);
  vertex(width/2, height, width/2, height);
  endShape();
}

void saveHighRes(int scaleFactor) {
  PGraphics hires = createGraphics(
                        width * scaleFactor,
                        height * scaleFactor,
                        JAVA2D);
  println("Generating high-resolution image...");

  beginRecord(hires);
  colorMode(HSB,100);
  
  hires.scale(scaleFactor);
  drawShapes();
  
  //doesn't work
  if (mirrorAmount==0) {
    //nothing
  } else if (mirrorAmount==1) {
    flipHalf();
  } else if (mirrorAmount==2) {
    flipQuarter();
    flipHalf();
  } else if (mirrorAmount==3) {
    flipEighth();
    flipQuarter();
    flipHalf();
  } else if (mirrorAmount==4) {
    flipSixteenth();
    flipEighth();
    flipQuarter();
    flipHalf();
  }
  
  endRecord();

  hires.save("wowee_"+mirrorAmount+"_"+frameCount+".png");
  println("Finished");
}

void keyPressed() {
  if(key=='m') {
    mirrorAmount = mirrorAmount+1;
    mirrorAmount = mirrorAmount%5;
    if(mirrorAmount==0) {drawShapes();}
    println("mirror amount: " + mirrorAmount);
  }
  
  if(key=='r') {
    drawShapes();
  }
  
  if(key=='s') {
    saveFrame("coolio###.png");
    println("saved");
  }
  
  if(key=='z') {
    saveHighRes(5);
  }
}
0 Likes

#2

To get rid of the vertex warning message, change the hires renderer from JAVA2D to P2D.

I think that you shouldn’t use beginRecord() to produce png output:

beginRecord() works only with the PDF and SVG renderers. https://processing.org/reference/beginRecord_.html

Instead, you want beginDraw() / endDraw().

Now your problem is that you aren’t really drawing on your hires surface when you call your flip functions – you are drawing on the main canvas. Without refactoring your code, one fix would be to modify all your flip functions to take a PGraphics.

void flipQuarter(PGraphics pg) {
  pg.beginShape();
  pg.texture(get());
  pg.vertex(width/2, height/2, width/2, height/2);
  pg.vertex(width/2, height, width/2, 0);
  pg.vertex(0, height, 0, 0);
  pg.vertex(0, height/2, 0, height/2);
  pg.endShape();
}

Now, when you call flipQuarter, pass it either your high resolution PGraphics, hires or, if you are just drawing the main sketch window, g (which is the name of the main sketch graphics). Whichever image surface is passed (the main sketch or the hires buffer) is manipulated by the function.

0 Likes