Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Second beginDraw / endDraw call clears PGraphics object when created w/ P2D #641

Closed
processing-bot opened this issue Aug 29, 2021 · 6 comments
Labels
help wanted Extra attention is needed opengl

Comments

@processing-bot
Copy link
Collaborator

Created by: rapatski

Description

Stumbled upon this just now - seems like beginDraw() / endDraw() clear the canvas of a PGraphics object when that object is created with the P2D renderer.

Expected Behavior

I expect the beginDraw() method not to change anything in the PGraphics object it's called on.

Current Behavior

Calling beginDraw() on a PGraphics object created with P2D and populated previously will clear it.

Steps to Reproduce

  1. Create PGraphics object with P2D renderer
  2. Draw into the PGraphics object, finish with endDraw()
  3. Call beginDraw() & endDraw() on the same object again
PGraphics pg;

void setup()
{
  size(500, 500, P2D);
  frameRate(60);
    
  //pg = createGraphics(width, height); // works as expected
  pg = createGraphics(width, height, P2D); // bug with beginDraw()/endDraw(), see below
  
  pg.beginDraw();
  pg.background(0, 255, 0); // green
  pg.endDraw();
  
  // this 'empties' the pg object in P2D mode
  pg.beginDraw();
  pg.endDraw();  
  
  background(255, 0, 0); // red
  
  // PG w/ P2D: renders transparent image,
  // PG w/ standard renderer: draws the original pg created in setup
  image(pg, 0, 0); 
}

Your Environment

  • Processing version: 3.5.4
  • Operating System and OS version: macOS Big Sur 11.4 (20F71)
  • Other information:
@processing-bot
Copy link
Collaborator Author

Created by: rapatski

Despite being rather limited in terms of true programming skills, I ventured to have a look at what PGraphicsOpenGL.beginDraw() actually is doing and though I understand very little of what's going on there, I was intrigued by the swapOffScreenTextures() call, and wondered if the behaviour I reported above, where the second beginDraw() call seemingly 'cleared' the canvas, in fact was caused by this function swapping the newly populated buffer for the old, empty one. Indeed, calling the beginShape() function twice seems to 'solve' the issue, 'stabilising' the buffer with subsequent beginDraw() calls not causing any further change:

PGraphics pg;

void setup()
{
  size(500, 500, P2D);
  frameRate(60);
    
  //pg = createGraphics(width, height); // works as expected
  pg = createGraphics(width, height, P2D); // bug with beginDraw()/endDraw(), see below
  
  pg.beginDraw();
  pg.background(0, 255, 0); // green background
  pg.endDraw();
  
  /* in P2D/PGraphicsOPENGL, this call seems to swap the buffer and starts drawing in a new, transparent one */
  pg.beginDraw(); 
  pg.ellipse(pg.width/2, pg.height/2, pg.width/2, pg.height/2); // white circle
  pg.endDraw();
  
  /* subsequent calls behave as expected */
  pg.beginDraw(); 
  pg.fill(255, 255, 0);
  pg.rect(0, 0, pg.width/2, pg.height/2); // yellow rect
  pg.endDraw(); 
  
  background(255, 0, 0); // red
  
  /*
  PG w/ P2D: draws white circle on red background
  PG w/ standard renderer: draws white circle on green background
  */
  image(pg, 0, 0); 
}

@processing-bot
Copy link
Collaborator Author

processing-bot commented Sep 2, 2021

Created by: jeremydouglass

@rapatski -- thanks for sharing. Confirmed on Processing 3.5.4 / macOS 10.12.

Here is an even simpler side-by-side test case. Create a P2D and default PGraphics, loop beginDraw/endDraw on each 4 times -- the first draw for P2D is missing.

PGraphics pgOK;
PGraphics pgBug;
void setup() {
  size(400, 200, P2D);

  // two PGraphics, one default, one P2D
  pgOK = createGraphics(width, height/2);
  pgBug = createGraphics(width, height/2, P2D);

  // apply same  process to both
  repeatBeginDraw(pgOK);
  repeatBeginDraw(pgBug);

  //display
  image(pgOK, 0, 0); // OK default -- displays results of 4 draw loops
  image(pgBug, 0, height/2); // bug w/P2D -- first draw loop is lost, last 3 shown
}

void repeatBeginDraw(PGraphics pg) {
  for (int i=0; i<4; i++) {
    pg.beginDraw();
    pg.textSize(40);
    pg.fill(0);
    pg.text(str(i), i*100 + 10, pg.height/2);
    pg.endDraw();
  }
}
processing-issue-6217

@processing-bot
Copy link
Collaborator Author

Created by: reiaaoyama

This is also broken on Processing 4.0b1/MacOS 11.6.4

@processing-bot
Copy link
Collaborator Author

Created by: mvaladas

I have this issue only from setup() to draw().
What I mean is that everything that was drawn to the PGraphics in setup() gets cleared when the first beginDraw() of the draw() function is called.
However, from there on it works as expected. So I only lose the drawing done at setup()

@processing-bot
Copy link
Collaborator Author

Created by: mvaladas

I believe I found the issue and fixed it.
in PGraphicsOpenGL.java, line 1424

    setViewport();
    if (primaryGraphics) {
      beginOnscreenDraw();
    } else {
      beginOffscreenDraw();
    }
    checkSettings();

checkSettings should be called before beginOffscreenDraw
Like so

    setViewport();
    checkSettings();
    if (primaryGraphics) {
      beginOnscreenDraw();
    } else {
      beginOffscreenDraw();
    }

The problem is that the sized variable is still false after the call to initialise the offscreen draw. This had the effect of setting initialised to false after being initialised.

A workaround can be calling begin/endDraw once at the very start. This "stabilises" the initialised and sized variables.

graphics.beginDraw();
graphics.endDraw();

I want to do further testing, but will submit a pull request if I can't find anything wrong with this approach.

@processing-bot
Copy link
Collaborator Author

Created by: benfry

Merged #728 for 4.3. Thanks for the report!

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 17, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
help wanted Extra attention is needed opengl
Projects
None yet
Development

No branches or pull requests

1 participant