Add attrib() method to PGraphics #2963

Closed
codeanticode opened this Issue Nov 17, 2014 · 7 comments

Comments

Projects
None yet
2 participants
@codeanticode
Member

codeanticode commented Nov 17, 2014

The shader API is currently limited to handle only the following vertex attributes:

  • position
  • color (fill, stroke)
  • texture coordinates
  • normal vector
  • material properties (ambient, specular, and emissive colors, shininess)

After the Denver retreat, it has been decided to add the "attrib" function to the PGraphics API to let users specify generic per-vertex attributes. This function tentatively has the following signature:

void attrib(String name, float... values);
void attrib(String name, int... values);
void attrib(String name, boolean... values);

Usage example:

float angle;
void setup() {
  size(400, 400, P3D);
  noStroke();
}

void draw() {
  background(0);

  pointLight(200, 200, 200, width/2, height/2, -200);

  translate(width/2, height/2);
  rotateY(angle);

  beginShape(QUADS);
  normal(0, 0, 1);
  fill(50, 50, 200);

  // A scalar attribute named brightness, affecting the next two vertices
  attrib("brightness", 0.1);

  // A vector attribute named tangent, affecting the first vertex
  attrib("tangent", 0.1, 0.8, 0.1);
  vertex(-100, +100);
  // Another tangent vector, affecting the second vertex
  attrib("tangent", -0.3, 1, 0);
  vertex(+100, +100);
  fill(200, 50, 50);

  // A new brightness value, affecting the last two vertices
  attrib("brightness", 0.5);

  attrib("tangent", 0.5, 0.5, 0.1);
  vertex(+100, -100);
  attrib("tangent", 0.1, -0.9, 0);
  vertex(-100, -100);
  endShape();

  angle += 0.01;
} 

The first time attrib() is called with a new attribute name, the renderer needs to automatically initialize all the corresponding internal variables (VBO's and backing arrays) needed to handle this attribute. The tessellator also needs to interpolate the values for the attributes, in the same way it now does for the built-in attributes.

@codeanticode

This comment has been minimized.

Show comment
Hide comment
@codeanticode

codeanticode Mar 31, 2015

Member

Implemented, needs debugging.

Member

codeanticode commented Mar 31, 2015

Implemented, needs debugging.

@codeanticode

This comment has been minimized.

Show comment
Hide comment
@codeanticode

codeanticode May 24, 2015

Member

Working on immediate and retained mode.

However, attributes need special handling when they represent a position, a normal vector, or a color. Right now, the attribute "kind" is automatically guessed from its name using the following rule:

  • names starting with "pos" indicate positional attributes
  • names starting with "norm" indicate normal attributes
  • names starting with "color" indicate color attributes
  • regular attributes otherwise

This solution obviously is not very satisfactory. A separate method could be better, for example:

attribKind(name, kind)

where kind is a constant taking three values: POSITION, NORMAL, and COLOR:

Example of use:

PShader sh;
PShape star;
public void setup() {
  size(400, 400, P2D);
  star = createShape();
  star.beginShape();
  star.strokeWeight(3);
  star.stroke(0);
  star.attrib("otherColor", color(0, 0, 1));
  star.attribKind("otherColor", COLOR);
  star.vertex(0, -50);
  star.vertex(14, -20);
  star.vertex(47, -15);
  star.vertex(23, 7);
  star.vertex(29, 40);
  star.vertex(0, 25);
  star.vertex(-29, 40);
  star.vertex(-23, 7);
  star.vertex(-47, -15);
  star.vertex(-14, -20);
  star.endShape(CLOSE);
  sh = loadShader("frag.glsl", "vert.glsl");
  shader(sh);
}

void draw() {
  background(150);
  fill(255, 0, 0);
  translate(mouseX, mouseY);
  shape(star);
}

attribKind() could be called only after the first attrib() call defining the new attribute. @benfry, @REAS, @shiffman any thoughts on this?

Member

codeanticode commented May 24, 2015

Working on immediate and retained mode.

However, attributes need special handling when they represent a position, a normal vector, or a color. Right now, the attribute "kind" is automatically guessed from its name using the following rule:

  • names starting with "pos" indicate positional attributes
  • names starting with "norm" indicate normal attributes
  • names starting with "color" indicate color attributes
  • regular attributes otherwise

This solution obviously is not very satisfactory. A separate method could be better, for example:

attribKind(name, kind)

where kind is a constant taking three values: POSITION, NORMAL, and COLOR:

Example of use:

PShader sh;
PShape star;
public void setup() {
  size(400, 400, P2D);
  star = createShape();
  star.beginShape();
  star.strokeWeight(3);
  star.stroke(0);
  star.attrib("otherColor", color(0, 0, 1));
  star.attribKind("otherColor", COLOR);
  star.vertex(0, -50);
  star.vertex(14, -20);
  star.vertex(47, -15);
  star.vertex(23, 7);
  star.vertex(29, 40);
  star.vertex(0, 25);
  star.vertex(-29, 40);
  star.vertex(-23, 7);
  star.vertex(-47, -15);
  star.vertex(-14, -20);
  star.endShape(CLOSE);
  sh = loadShader("frag.glsl", "vert.glsl");
  shader(sh);
}

void draw() {
  background(150);
  fill(255, 0, 0);
  translate(mouseX, mouseY);
  shape(star);
}

attribKind() could be called only after the first attrib() call defining the new attribute. @benfry, @REAS, @shiffman any thoughts on this?

@benfry

This comment has been minimized.

Show comment
Hide comment
@benfry

benfry Jun 15, 2015

Member

I think I like:

  • attrib() for the default fellas
  • attribColor()
  • attribPos() (or position? or?)
  • attribNormal()

With the idea being that it helps self-document the code (which helps with reading and debugging). So instead of a one-time init function that sets the type, this does it automatically behind the scenes the first time it's used.

Member

benfry commented Jun 15, 2015

I think I like:

  • attrib() for the default fellas
  • attribColor()
  • attribPos() (or position? or?)
  • attribNormal()

With the idea being that it helps self-document the code (which helps with reading and debugging). So instead of a one-time init function that sets the type, this does it automatically behind the scenes the first time it's used.

@codeanticode

This comment has been minimized.

Show comment
Hide comment
@codeanticode

codeanticode Jun 20, 2015

Member

I like your idea. I would go with attribPosition(), although is somewhat long, because we don't use pos anywhere else, and we do use position as the built-in attribute to transfer the xyz coords to the vertex shader.

Member

codeanticode commented Jun 20, 2015

I like your idea. I would go with attribPosition(), although is somewhat long, because we don't use pos anywhere else, and we do use position as the built-in attribute to transfer the xyz coords to the vertex shader.

@benfry

This comment has been minimized.

Show comment
Hide comment
@benfry

benfry Jun 21, 2015

Member

Works for me. I'm planning to push out an alpha 11 sometime today (or tomorrow), which is hopefully the last alpha before the first beta. Let me know if you want to sneak this in before the alpha goes out.

Member

benfry commented Jun 21, 2015

Works for me. I'm planning to push out an alpha 11 sometime today (or tomorrow), which is hopefully the last alpha before the first beta. Let me know if you want to sneak this in before the alpha goes out.

@codeanticode

This comment has been minimized.

Show comment
Hide comment
@codeanticode

codeanticode Jun 21, 2015

Member

I'm working on #3384 right now, but will be great if we can include this into alpha 11.

Member

codeanticode commented Jun 21, 2015

I'm working on #3384 right now, but will be great if we can include this into alpha 11.

@codeanticode

This comment has been minimized.

Show comment
Hide comment
@codeanticode

codeanticode Jul 13, 2015

Member

last bits implemented in a99c094

Member

codeanticode commented Jul 13, 2015

last bits implemented in a99c094

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment