From 828cafa44a32d04f87aced74e882304a440b81ee Mon Sep 17 00:00:00 2001 From: codeanticode Date: Tue, 31 Mar 2015 11:45:51 -0400 Subject: [PATCH] attrib bits in PShape --- core/src/processing/core/PShape.java | 13 +++ .../processing/opengl/PGraphicsOpenGL.java | 16 +++ core/src/processing/opengl/PShapeOpenGL.java | 110 +++++++++++++++++- 3 files changed, 138 insertions(+), 1 deletion(-) diff --git a/core/src/processing/core/PShape.java b/core/src/processing/core/PShape.java index c76c1a8b8..6aa930a4a 100644 --- a/core/src/processing/core/PShape.java +++ b/core/src/processing/core/PShape.java @@ -2223,6 +2223,19 @@ public class PShape implements PConstants { } + + public void setAttrib(String name, int index, float... values) { + } + + + public void setAttrib(String name, int index, int... values) { + } + + + public void setAttrib(String name, int index, boolean... values) { + } + + public float getTextureU(int index) { return vertices[index][PGraphics.U]; } diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index e62ac1ed6..b52fda6b7 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -7039,6 +7039,11 @@ public class PGraphicsOpenGL extends PGraphics { int[] ivalues; byte[] bvalues; + // For use in PShape + boolean modified; + int firstModified; + int lastModified; + VertexAttribute(String name, int type, int size) { this.name = name; this.type = type; @@ -7070,6 +7075,10 @@ public class PGraphicsOpenGL extends PGraphics { glName = 0; glLoc = -1; + + modified = false; + firstModified = PConstants.MAX_INT; + lastModified = PConstants.MIN_INT; } boolean isPosition() { @@ -7112,6 +7121,13 @@ public class PGraphicsOpenGL extends PGraphics { null, PGL.STATIC_DRAW); } + void deleteBuffer(PGL pgl) { + if (glName != 0) { + int ctx = pgl.getCurrentContext(); + PGraphicsOpenGL.deleteVertexBufferObject(glName, ctx, pgl); + } + } + void updateLoc(PShader shader) { if (glLoc == -1) glLoc = shader.getAttributeLoc(name); } diff --git a/core/src/processing/opengl/PShapeOpenGL.java b/core/src/processing/opengl/PShapeOpenGL.java index ceba997da..fb9a06476 100644 --- a/core/src/processing/opengl/PShapeOpenGL.java +++ b/core/src/processing/opengl/PShapeOpenGL.java @@ -36,7 +36,9 @@ import processing.opengl.PGraphicsOpenGL.IndexCache; import processing.opengl.PGraphicsOpenGL.InGeometry; import processing.opengl.PGraphicsOpenGL.TessGeometry; import processing.opengl.PGraphicsOpenGL.Tessellator; +import processing.opengl.PGraphicsOpenGL.VertexAttribute; +import java.nio.Buffer; import java.util.Arrays; import java.util.HashSet; import java.util.Stack; @@ -533,6 +535,13 @@ public class PShapeOpenGL extends PShape { PGraphicsOpenGL.finalizeVertexBufferObject(glPolyShininess, context); } + for (VertexAttribute attrib: attribs.values()) { + if (attrib.glName != 0) { + PGraphicsOpenGL.finalizeVertexBufferObject(attrib.glName, context); + } + } + + if (glPolyIndex != 0) { PGraphicsOpenGL.finalizeVertexBufferObject(glPolyIndex, context); } @@ -1125,6 +1134,46 @@ public class PShapeOpenGL extends PShape { } } + @Override + public void attrib(String name, float... values) { + VertexAttribute attrib = attribImpl(name, PGL.FLOAT, values.length); + if (attrib != null) attrib.set(values); + } + + + @Override + public void attrib(String name, int... values) { + VertexAttribute attrib = attribImpl(name, PGL.INT, values.length); + if (attrib != null) attrib.set(values); + } + + + @Override + public void attrib(String name, boolean... values) { + VertexAttribute attrib = attribImpl(name, PGL.BOOL, values.length); + if (attrib != null) attrib.set(values); + } + + + protected VertexAttribute attribImpl(String name, int type, int size) { + if (4 < size) { + PGraphics.showWarning("Vertex attributes cannot have more than 4 values"); + return null; + } + VertexAttribute attrib = attribs.get(name); + if (attrib == null) { + attrib = new VertexAttribute(name, type, size); + attribs.put(name, attrib); + inGeo.initAttrib(attrib); + tessGeo.initAttrib(attrib); + } + if (attrib.size != size) { + PGraphics.showWarning("New value for vertex attribute has wrong number of values"); + return null; + } + return attrib; + } + @Override public void endShape(int mode) { @@ -1381,6 +1430,11 @@ public class PShapeOpenGL extends PShape { firstPolyVertex, lastPolyVertex); root.setModifiedPolyVertices(firstPolyVertex, lastPolyVertex); root.setModifiedPolyNormals(firstPolyVertex, lastPolyVertex); + for (VertexAttribute attrib: attribs.values()) { + if (attrib.isPosition() || attrib.isNormal()) { + root.setModifiedPolyAttrib(attrib, firstPolyVertex, lastPolyVertex); + } + } } if (is3D()) { @@ -1604,7 +1658,7 @@ public class PShapeOpenGL extends PShape { // TODO: in certain cases (kind = TRIANGLE, etc) the correspondence between // input and tessellated vertices is 1-1, so in those cases re-tessellation - // wouldnt' be neccessary. + // wouldn't be necessary. inGeo.vertices[3 * index + 0] = x; inGeo.vertices[3 * index + 1] = y; inGeo.vertices[3 * index + 2] = z; @@ -3784,6 +3838,15 @@ public class PShapeOpenGL extends PShape { pgl.bufferData(PGL.ARRAY_BUFFER, sizef, tessGeo.polyShininessBuffer, glUsage); + for (String name: attribs.keySet()) { + VertexAttribute attrib = attribs.get(name); + tessGeo.updateAttribBuffer(attrib.name); + if (!attrib.bufferCreated()) attrib.createBuffer(pgl); + pgl.bindBuffer(PGL.ARRAY_BUFFER, attrib.glName); + pgl.bufferData(PGL.ARRAY_BUFFER, attrib.sizeInBytes(size), + tessGeo.attribBuffers.get(name), PGL.STATIC_DRAW); + } + pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); tessGeo.updatePolyIndicesBuffer(); @@ -3893,6 +3956,9 @@ public class PShapeOpenGL extends PShape { PGraphicsOpenGL.removeVertexBufferObject(glPolySpecular, context); PGraphicsOpenGL.removeVertexBufferObject(glPolyEmissive, context); PGraphicsOpenGL.removeVertexBufferObject(glPolyShininess, context); + for (VertexAttribute attrib: attribs.values()) { + PGraphicsOpenGL.removeVertexBufferObject(attrib.glName, context); + } PGraphicsOpenGL.removeVertexBufferObject(glPolyIndex, context); PGraphicsOpenGL.removeVertexBufferObject(glLineVertex, context); @@ -3917,6 +3983,7 @@ public class PShapeOpenGL extends PShape { glPolySpecular = 0; glPolyEmissive = 0; glPolyShininess = 0; + for (VertexAttribute attrib: attribs.values()) attrib.glName = 0; glPolyIndex = 0; glLineVertex = 0; @@ -3988,6 +4055,10 @@ public class PShapeOpenGL extends PShape { glPolyShininess = 0; } + for (VertexAttribute attrib: attribs.values()) { + attrib.deleteBuffer(pgl); + } + if (glPolyIndex != 0) { PGraphicsOpenGL.deleteVertexBufferObject(glPolyIndex, context, pgl); glPolyIndex = 0; @@ -4121,6 +4192,17 @@ public class PShapeOpenGL extends PShape { firstModifiedPolyShininess = PConstants.MAX_INT; lastModifiedPolyShininess = PConstants.MIN_INT; } + for (String name: attribs.keySet()) { + VertexAttribute attrib = attribs.get(name); + if (attrib.modified) { + int offset = firstModifiedPolyVertex; + int size = lastModifiedPolyVertex - offset + 1; + copyPolyAttrib(attrib, offset, size); + attrib.modified = false; + attrib.firstModified = PConstants.MAX_INT; + attrib.lastModified = PConstants.MIN_INT; + } + } if (modifiedLineVertices) { int offset = firstModifiedLineVertex; @@ -4264,6 +4346,18 @@ public class PShapeOpenGL extends PShape { } + protected void copyPolyAttrib(VertexAttribute attrib, int offset, int size) { + tessGeo.updateAttribBuffer(attrib.name, offset, size); + pgl.bindBuffer(PGL.ARRAY_BUFFER, attrib.glName); + Buffer buf = tessGeo.attribBuffers.get(attrib.name); + buf.position(attrib.size * offset); + pgl.bufferSubData(PGL.ARRAY_BUFFER, attrib.sizeInBytes(offset), + attrib.sizeInBytes(size), buf); + buf.rewind(); + pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); + } + + protected void copyLineVertices(int offset, int size) { tessGeo.updateLineVerticesBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineVertex); @@ -4393,6 +4487,20 @@ public class PShapeOpenGL extends PShape { modified = true; } + protected void setModifiedPolyAttrib(VertexAttribute attrib, int first, int last) { + if (first < attrib.firstModified) attrib.firstModified = first; + if (last > attrib.lastModified) attrib.lastModified = last; + attrib.modified = true; + modified = true; + } + + protected void setModifiedPolyAttribs(VertexAttribute attrib, int first, int last) { + if (first < attrib.firstModified) attrib.firstModified = first; + if (last > attrib.lastModified) attrib.lastModified = last; + attrib.modified = true; + modified = true; + } + protected void setModifiedLineVertices(int first, int last) { if (first < firstModifiedLineVertex) firstModifiedLineVertex = first;