Quad() gets drawn twice

Hello, everyone.

Lately I’ve been casually working through Daniel Shiffman’s book Learning Processing, to better familiarize myself with Processing.

I was working on exercise 14-5 in the book: “Create a three-dimensional cube using eight quads — beginShape(QUADS)”.

My idea was to create a quad in the xy-plane, and then to translate and rotate the quad six times to generate the cube. Although when I tried this, I encountered a strange problem.

When I try to translate the quad using push/popMatrix(), the quad gets drawn twice, once at the origin, and once to where I translated the quad. If I comment out the push/popMatrix() lines, the quad only gets drawn once.

I don’t understand why this happens. So, I was hoping someone here can help me understand. :slight_smile:

float dphi;

void setup() {
  size(400, 400, P3D);
  
  dphi = 0;
}

void draw() {
  background(255);
  translate(width/2, height/2, 0);
  rotateX(-PI/12);
  rotateY(dphi);
  
  drawBox(200);
  
  dphi += 0.01;
}

void drawBox(int d) {
  stroke(0);
  strokeWeight(10);
  noFill();
  
  int D = d/2;
  
  beginShape(QUADS);
  
  pushMatrix();
  translate(0, 0, -D);
  quad(-D, -D, D, -D, D, D, -D, D);
  popMatrix();
  
  endShape();
}

I added some rotation to better visualize the 3D object.

1 Like

I see now that it draws two quad regardless of push/popMatrix(), but they were drawn at the same location, so I didn’t see.

beginShape(QUADS);
  
  translate(0, 0, -D);
  quad(-D, -D, D, -D, D, D, -D, D);
  
  translate(0, 0, 2*D);
  
  endShape();

But if I do this, still two quads get drawn, even though the quad() function is only called once, which I still don’t understand.

Hello,

Welcome.

Try translating only the shape:

  pushMatrix();
  translate(0, 0, -D);
 
 beginShape(QUAD);
  quad(-D, -D, D, -D, D, D, -D, D);
  endShape();
 
 popMatrix();

:)

Hello, thanks for the quick response!

This does work. But should I then use a new begin/endShape(), for every side of the cube?

Like this?:

pushMatrix();
  translate(0, 0, -D);
  beginShape(QUAD);
  quad(-D, -D, D, -D, D, D, -D, D);
  endShape();
  popMatrix();
  
  pushMatrix();
  translate(0, 0, D);
  beginShape(QUAD);
  quad(-D, -D, D, -D, D, D, -D, D);
  endShape();
  popMatrix();
  
  pushMatrix();
  rotateX(PI/2);
  translate(0, 0, -D);
  beginShape(QUAD);
  quad(-D, -D, D, -D, D, D, -D, D);
  endShape();
  popMatrix();
  
  pushMatrix();
  rotateX(PI/2);
  translate(0, 0, D);
  beginShape(QUAD);
  quad(-D, -D, D, -D, D, D, -D, D);
  endShape();
  popMatrix();

There is a discussion here about this:

:)

2 Likes

Because then it seems quicker to just not use push/popMatrix() and just translate back after each quad.

Okay, thank you, I will read through it!

Hello,

https://processing.org/examples/rgbcube.html

This example and others are also in the Processing PDE in the files menu; not on the site but should be.

Some insights here as well for grouping shapes:

https://processing.org/tutorials/pshape/

:)

1 Like

I did see that is most examples they used vertex() instead of quad(). Is there a specific reason for that?

Explore the references, examples and tutorials.

vertex() / Reference / Processing.org
quad() / Reference / Processing.org
PShape / Processing.org

:)

In general vertex is more flexible. You can have 3, 4, 5, 6, or 100 points, whereas quad has four. Also, if you are having many tiles – like a quad strip – then you can do it manually with vertex, or you can arrange your vertex data using the QUAD_STRIP feature of PShape / beginShape… if you have a lot of point data then this may end up being much more efficient to render as a surface / object rather than drawing a separate quad() 100 times, and it is often easier to code something that moves along stitching sets of coordinates rather than breaking it down into individual shapes.

Still, there is nothing wrong with using quad – its just that most of the documentation and examples jump straight from rect to vertex, as you say.

2 Likes

This question is expecting you to create a cube using the QUADS parameter.

See reference:
beginShape() / Reference / Processing.org

quad() is already a shape (in the xy plane) and does not require beginShape() and endShape().

See reference:
quad() / Reference / Processing.org

Your last example works with transformations but does not require beginShape() and endShape().

There is a learning curve to all of this and you are working through it.

:)

2 Likes

Aaah okay that explains it, thank you! :grin:

quad() also uses (by default) beginShape() and endShape() internally. That you are causing endShape() to be called twice in a row, before and after matrix change, is probably why you see it drawn twice.

1 Like