Added mode to PShape, reworked tessellation, update in PShape3D, release of cache and tess objects when STATIC mode is used.

This commit is contained in:
codeanticode
2012-04-13 18:57:27 +00:00
parent c718b4e280
commit 81ead7a627
4 changed files with 417 additions and 284 deletions
+3 -5
View File
@@ -450,14 +450,12 @@ public interface PConstants {
public static final int REPEAT = 1;
// vbos
// shape objects
/** Static usage mode for PShape3D (vertices won't be updated after creation). */
/** Static shapes (vertices won't be updated after creation). */
public static final int STATIC = 0;
/** Dynamic usage mode for PShape3D (vertices will be updated after creation). */
/** Dynamic shapes (vertices will be updated after creation). */
public static final int DYNAMIC = 1;
/** Dynamic usage mode for PShape3D (vertices will be updated at every frame). */
public static final int STREAM = 2;
// shaders
+28
View File
@@ -95,6 +95,9 @@ public class PShape implements PConstants {
/** ELLIPSE, LINE, QUAD; TRIANGLE_FAN, QUAD_STRIP; etc. */
protected int kind;
/** STATIC, DYNAMIC, STREAM */
protected int mode;
protected PMatrix matrix;
@@ -255,7 +258,17 @@ public class PShape implements PConstants {
this.family = family;
}
public void setKind(int kind) {
this.kind = kind;
}
public void setMode(int mode) {
this.mode = mode;
}
public void setName(String name) {
this.name = name;
}
@@ -1135,6 +1148,13 @@ public class PShape implements PConstants {
}
}
protected void notModified() {
modified = false;
for (int i = 0; i < childCount; i++) {
children[i].notModified();
}
}
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
@@ -1432,6 +1452,14 @@ public class PShape implements PConstants {
*/
public void rotate(float angle, float v0, float v1, float v2) {
checkMatrix(3);
float norm2 = v0 * v0 + v1 * v1 + v2 * v2;
if (Math.abs(norm2 - 1) > EPSILON) {
// The rotation vector is not normalized.
float norm = PApplet.sqrt(norm2);
v0 /= norm;
v1 /= norm;
v2 /= norm;
}
matrix.rotate(angle, v0, v1, v2);
}
@@ -40,6 +40,10 @@ import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
// TODO:
// 1) Should edges stay in InGeometry or go to TessGeometry?
// 2) move bezier/curve vertex generation to InGeometry.
/**
* OpenGL renderer.
*
@@ -70,9 +74,6 @@ public class PGraphicsOpenGL extends PGraphics {
/** Current flush mode. */
protected int flushMode = FLUSH_WHEN_FULL;
/** VBO storage mode. */
protected int vboMode = PGL.GL_STATIC_DRAW;
// ........................................................
// VBOs for immediate rendering:
@@ -341,8 +342,6 @@ public class PGraphicsOpenGL extends PGraphics {
// ........................................................
// Bezier and Catmull-Rom curves
// TODO: move bezier/curve vertex generation to InGeometry.
protected boolean bezierInited = false;
public int bezierDetail = 20;
@@ -1090,41 +1089,41 @@ public class PGraphicsOpenGL extends PGraphics {
glFillVertexBufferID = createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillVertexBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, PGL.GL_STATIC_DRAW);
glFillColorBufferID = createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillColorBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, PGL.GL_STATIC_DRAW);
glFillNormalBufferID = createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillNormalBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, PGL.GL_STATIC_DRAW);
glFillTexCoordBufferID = createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillTexCoordBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, PGL.GL_STATIC_DRAW);
glFillAmbientBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillAmbientBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, PGL.GL_STATIC_DRAW);
glFillSpecularBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillSpecularBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, PGL.GL_STATIC_DRAW);
glFillEmissiveBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillEmissiveBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, PGL.GL_STATIC_DRAW);
glFillShininessBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillShininessBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizef, null, vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizef, null, PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0);
glFillIndexBufferID = createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glFillIndexBufferID);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, vboMode);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0);
}
@@ -1136,37 +1135,37 @@ public class PGraphicsOpenGL extends PGraphics {
int sizei = size * PGL.SIZEOF_INT;
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillVertexBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, FloatBuffer.wrap(tessGeo.fillVertices, 0, 3 * size), vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, FloatBuffer.wrap(tessGeo.fillVertices, 0, 3 * size), PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillColorBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.fillColors, 0, size), vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.fillColors, 0, size), PGL.GL_STATIC_DRAW);
if (lit) {
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillNormalBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, FloatBuffer.wrap(tessGeo.fillNormals, 0, 3 * size), vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, FloatBuffer.wrap(tessGeo.fillNormals, 0, 3 * size), PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillAmbientBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.fillAmbient, 0, size), vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.fillAmbient, 0, size), PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillSpecularBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.fillSpecular, 0, size), vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.fillSpecular, 0, size), PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillEmissiveBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.fillEmissive, 0, size), vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.fillEmissive, 0, size), PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillShininessBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizef, FloatBuffer.wrap(tessGeo.fillShininess, 0, size), vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizef, FloatBuffer.wrap(tessGeo.fillShininess, 0, size), PGL.GL_STATIC_DRAW);
}
if (tex) {
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillTexCoordBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, FloatBuffer.wrap(tessGeo.fillTexcoords, 0, 2 * size), vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, FloatBuffer.wrap(tessGeo.fillTexcoords, 0, 2 * size), PGL.GL_STATIC_DRAW);
}
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glFillIndexBufferID);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, tessGeo.fillIndexCount * PGL.SIZEOF_INDEX,
ShortBuffer.wrap(tessGeo.fillIndices, 0, tessGeo.fillIndexCount), vboMode);
ShortBuffer.wrap(tessGeo.fillIndices, 0, tessGeo.fillIndexCount), PGL.GL_STATIC_DRAW);
}
@@ -1214,21 +1213,21 @@ public class PGraphicsOpenGL extends PGraphics {
glLineVertexBufferID = createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineVertexBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, PGL.GL_STATIC_DRAW);
glLineColorBufferID = createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineColorBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, PGL.GL_STATIC_DRAW);
glLineDirWidthBufferID = createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineDirWidthBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 4 * sizef, null, vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 4 * sizef, null, PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0);
glLineIndexBufferID = createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glLineIndexBufferID);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, vboMode);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0);
}
@@ -1240,17 +1239,17 @@ public class PGraphicsOpenGL extends PGraphics {
int sizei = size * PGL.SIZEOF_INT;
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineVertexBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, FloatBuffer.wrap(tessGeo.lineVertices, 0, 3 * size), vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, FloatBuffer.wrap(tessGeo.lineVertices, 0, 3 * size), PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineColorBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.lineColors, 0, size), vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.lineColors, 0, size), PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineDirWidthBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 4 * sizef, FloatBuffer.wrap(tessGeo.lineDirWidths, 0, 4 * size), vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 4 * sizef, FloatBuffer.wrap(tessGeo.lineDirWidths, 0, 4 * size), PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glLineIndexBufferID);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, tessGeo.lineIndexCount * PGL.SIZEOF_INDEX,
ShortBuffer.wrap(tessGeo.lineIndices, 0, tessGeo.lineIndexCount), vboMode);
ShortBuffer.wrap(tessGeo.lineIndices, 0, tessGeo.lineIndexCount), PGL.GL_STATIC_DRAW);
}
@@ -1282,21 +1281,21 @@ public class PGraphicsOpenGL extends PGraphics {
glPointVertexBufferID = createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointVertexBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, PGL.GL_STATIC_DRAW);
glPointColorBufferID = createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointColorBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, PGL.GL_STATIC_DRAW);
glPointSizeBufferID = createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointSizeBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0);
glPointIndexBufferID = createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glPointIndexBufferID);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, vboMode);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0);
}
@@ -1308,17 +1307,17 @@ public class PGraphicsOpenGL extends PGraphics {
int sizei = size * PGL.SIZEOF_INT;
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointVertexBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, FloatBuffer.wrap(tessGeo.pointVertices, 0, 3 * size), vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, FloatBuffer.wrap(tessGeo.pointVertices, 0, 3 * size), PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointColorBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.pointColors, 0, size), vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.pointColors, 0, size), PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointSizeBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, FloatBuffer.wrap(tessGeo.pointSizes, 0, 2 * size), vboMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, FloatBuffer.wrap(tessGeo.pointSizes, 0, 2 * size), PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glPointIndexBufferID);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, tessGeo.pointIndexCount * PGL.SIZEOF_INDEX,
ShortBuffer.wrap(tessGeo.pointIndices, 0, tessGeo.pointIndexCount), vboMode);
ShortBuffer.wrap(tessGeo.pointIndices, 0, tessGeo.pointIndexCount), PGL.GL_STATIC_DRAW);
}
@@ -1549,16 +1548,6 @@ public class PGraphicsOpenGL extends PGraphics {
// Flushing any remaining geometry.
flush();
// if (settingPixels) {
// // Drawing the pixels array. We can only get
// // here if there was no geometry to flush at
// // the end of draw, and the user has been
// // manipulating individual pixels. If that's
// // the case we need to update the screen with
// // the changes in the pixels array.
// updatePixels();
// }
// TODO: Implement depth sorting (http://code.google.com/p/processing/issues/detail?id=51)
//if (hints[ENABLE_DEPTH_SORT]) {
// flush();
@@ -2019,6 +2008,8 @@ public class PGraphicsOpenGL extends PGraphics {
}
shape = new PShape3D(parent, PShape.PRIMITIVE);
shape.setKind(SPHERE);
} else {
showWarning("Unrecognized primitive type");
}
if (shape != null) {
@@ -2498,7 +2489,7 @@ public class PGraphicsOpenGL extends PGraphics {
int size = tessGeo.fillIndexCount;
int sizex = size * PGL.SIZEOF_INDEX;
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glFillIndexBufferID);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, ShortBuffer.wrap(tessGeo.fillIndices, 0, size), vboMode);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, ShortBuffer.wrap(tessGeo.fillIndices, 0, size), PGL.GL_STATIC_DRAW);
pgl.glDrawElements(PGL.GL_TRIANGLES, size, PGL.INDEX_TYPE, 0);
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0);
@@ -2712,9 +2703,6 @@ public class PGraphicsOpenGL extends PGraphics {
curveToBezierMatrix = new PMatrix3D();
}
// TODO only needed for PGraphicsJava2D? if so, move it there
// actually, it's generally useful for other renderers, so keep it
// or hide the implementation elsewhere.
curveToBezierMatrix.set(curveBasisMatrix);
curveToBezierMatrix.preApply(bezierBasisInverse);
@@ -2912,9 +2900,6 @@ public class PGraphicsOpenGL extends PGraphics {
// BOX
// TODO GL and GLUT in GL ES doesn't offer functions to create
// cubes.
// public void box(float size)
// public void box(float w, float h, float d) // P3D
@@ -2923,9 +2908,6 @@ public class PGraphicsOpenGL extends PGraphics {
// SPHERE
// TODO GL and GLUT in GL ES doesn't offer functions to create
// spheres.
// public void sphereDetail(int res)
// public void sphereDetail(int ures, int vres)
@@ -3333,8 +3315,15 @@ public class PGraphicsOpenGL extends PGraphics {
static private void invRotate(PMatrix3D matrix, float angle, float v0, float v1, float v2) {
//TODO should make sure this vector is normalized
float norm2 = v0 * v0 + v1 * v1 + v2 * v2;
if (Math.abs(norm2 - 1) > EPSILON) {
// The rotation vector is not normalized.
float norm = PApplet.sqrt(norm2);
v0 /= norm;
v1 /= norm;
v2 /= norm;
}
float c = PApplet.cos(-angle);
float s = PApplet.sin(-angle);
float t = 1.0f - c;
@@ -4842,10 +4831,6 @@ public class PGraphicsOpenGL extends PGraphics {
// public void copy(int sx1, int sy1, int sx2, int sy2,
// int dx1, int dy1, int dx2, int dy2)
/**
* TODO - extremely slow and not optimized. Currently calls a beginPixels() on
* the whole canvas, then does the copy, then it calls endPixels().
*/
// public void copy(PImage src,
// int sx1, int sy1, int sx2, int sy2,
// int dx1, int dy1, int dx2, int dy2)
@@ -5994,6 +5979,11 @@ public class PGraphicsOpenGL extends PGraphics {
}
protected TessGeometry newTessGeometry(int mode, boolean empty) {
return new TessGeometry(mode, empty);
}
protected TexCache newTexCache() {
return new TexCache();
}
@@ -6160,8 +6150,7 @@ public class PGraphicsOpenGL extends PGraphics {
public int[] specular;
public int[] emissive;
public float[] shininess;
// TODO: this should probably go in the TessGeometry class, or maybe not...
public int[][] edges;
// Internally used by the addVertex() methods.
@@ -7040,9 +7029,14 @@ public class PGraphicsOpenGL extends PGraphics {
public TessGeometry(int mode) {
renderMode = mode;
allocate();
allocate(false);
}
public TessGeometry(int mode, boolean empty) {
renderMode = mode;
allocate(empty);
}
public void clear() {
firstFillVertex = lastFillVertex = fillVertexCount = 0;
firstFillIndex = lastFillIndex = fillIndexCount = 0;
@@ -7056,30 +7050,56 @@ public class PGraphicsOpenGL extends PGraphics {
isStroked = false;
}
public void allocate() {
fillVertices = new float[3 * PGL.DEFAULT_TESS_VERTICES];
fillColors = new int[PGL.DEFAULT_TESS_VERTICES];
fillNormals = new float[3 * PGL.DEFAULT_TESS_VERTICES];
fillTexcoords = new float[2 * PGL.DEFAULT_TESS_VERTICES];
fillAmbient = new int[PGL.DEFAULT_TESS_VERTICES];
fillSpecular = new int[PGL.DEFAULT_TESS_VERTICES];
fillEmissive = new int[PGL.DEFAULT_TESS_VERTICES];
fillShininess = new float[PGL.DEFAULT_TESS_VERTICES];
fillIndices = new short[PGL.DEFAULT_TESS_VERTICES];
public void allocate(boolean empty) {
if (!empty) {
fillVertices = new float[3 * PGL.DEFAULT_TESS_VERTICES];
fillColors = new int[PGL.DEFAULT_TESS_VERTICES];
fillNormals = new float[3 * PGL.DEFAULT_TESS_VERTICES];
fillTexcoords = new float[2 * PGL.DEFAULT_TESS_VERTICES];
fillAmbient = new int[PGL.DEFAULT_TESS_VERTICES];
fillSpecular = new int[PGL.DEFAULT_TESS_VERTICES];
fillEmissive = new int[PGL.DEFAULT_TESS_VERTICES];
fillShininess = new float[PGL.DEFAULT_TESS_VERTICES];
fillIndices = new short[PGL.DEFAULT_TESS_VERTICES];
lineVertices = new float[3 * PGL.DEFAULT_TESS_VERTICES];
lineColors = new int[PGL.DEFAULT_TESS_VERTICES];
lineDirWidths = new float[4 * PGL.DEFAULT_TESS_VERTICES];
lineIndices = new short[PGL.DEFAULT_TESS_VERTICES];
lineVertices = new float[3 * PGL.DEFAULT_TESS_VERTICES];
lineColors = new int[PGL.DEFAULT_TESS_VERTICES];
lineDirWidths = new float[4 * PGL.DEFAULT_TESS_VERTICES];
lineIndices = new short[PGL.DEFAULT_TESS_VERTICES];
pointVertices = new float[3 * PGL.DEFAULT_TESS_VERTICES];
pointColors = new int[PGL.DEFAULT_TESS_VERTICES];
pointSizes = new float[2 * PGL.DEFAULT_TESS_VERTICES];
pointIndices = new short[PGL.DEFAULT_TESS_VERTICES];
pointVertices = new float[3 * PGL.DEFAULT_TESS_VERTICES];
pointColors = new int[PGL.DEFAULT_TESS_VERTICES];
pointSizes = new float[2 * PGL.DEFAULT_TESS_VERTICES];
pointIndices = new short[PGL.DEFAULT_TESS_VERTICES];
} else {
fillVertices = null;
fillColors = null;
fillNormals = null;
fillTexcoords = null;
fillAmbient = null;
fillSpecular = null;
fillEmissive = null;
fillShininess = null;
fillIndices = null;
lineVertices = null;
lineColors = null;
lineDirWidths = null;
lineIndices = null;
pointVertices = null;
pointColors = null;
pointSizes = null;
pointIndices = null;
}
clear();
}
public void free() {
}
public void trim() {
if (0 < fillVertexCount && fillVertexCount < fillVertices.length / 3) {
trimFillVertices();
@@ -47,15 +47,28 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
// Notes about geometry update in PShape3D.
// 1) When applying a transformation on a group shape
// check if it is more efficient to apply as a gl
// transformation on all the childs, instead of
// propagating the transformation downwards in order
// to calculate the transformation matrices.
// 2) Change the transformation logic, so the matrix is applied
// on the values stored in the vertex cache and not on the
// tessellated vertices.
// TODO:
// 1) after geometry is copied to the root in first tessellation, clear tess arrays of childs
// 2) Determine if PATH type is necessary, since it is equivalent to use POLYGON with fill disabled.
// 3) Move tessellateSphere to InGeometry and implement rest of primitive tessellation functions.
// 4) strokeWeight() should update the attributes of lines and points when called after tessellation.
// 5) getters/setters for individual vertex data:
// PVector getVertex(int n) gets vertex n from fill data.
// PVector getVertex(int n, PVector v, int type)
// PVector getVertex(int n, PVector v, int type)
// void setVertex(int n, PVector v, type)
// int getFillColor(int n, int)
// void setFillColor(int n, int color);
// void setFillColor(int n, int color);
// ....
// void getStrokeWeight(int n)
// void setStrokeWeight(int n, int weight)
// where type for vertices = FILL, LINE, POINT
// where type for fill colors = FILL, LINE, POINT ... AMBIENT, ...
// STROKE = LINE and POINTS ...!
// setStrokeWeight(int n) for a line vertex should automatically update the attributes...
// 6) Rename fillVertices to be compatible with the above, add corresponding setters, remove map methods.
/**
* This class holds a 3D model composed of vertices, normals, colors (per vertex) and
@@ -83,18 +96,21 @@ public class PShape3D extends PShape {
protected PGL.Context context; // The context that created this shape.
protected PShape3D root;
protected int glMode;
// ........................................................
// Input, tessellated geometry
protected InGeometry in;
protected TessGeometry tess;
protected Tessellator tessellator;
// ........................................................
protected ArrayList<IndexData> fillIndexData;
protected ArrayList<IndexData> lineIndexData;
protected ArrayList<IndexData> pointIndexData;
// Texturing
protected HashSet<PImage> textures;
protected PImage texture;
protected PImage texture;
// ........................................................
@@ -148,9 +164,90 @@ public class PShape3D extends PShape {
// ........................................................
// Drawing/rendering state
// Indices
// Contains the blocks of geometry that can be rendered
// in a single drawElements() call.
protected ArrayList<IndexData> fillIndexData;
protected ArrayList<IndexData> lineIndexData;
protected ArrayList<IndexData> pointIndexData;
// ........................................................
// State/rendering flags
protected boolean tessellated;
protected boolean needBufferInit;
protected boolean isSolid;
protected boolean isClosed;
protected boolean openContour = false;
protected boolean breakShape = false;
protected boolean shapeEnded = false;
protected boolean hasFill;
protected boolean hasLines;
protected boolean hasPoints;
protected int prevMode;
// ........................................................
// Modes inherited from renderer
protected int textureMode;
protected int rectMode;
protected int ellipseMode;
protected int shapeMode;
protected int imageMode;
// ........................................................
// Geometric transformations
protected PMatrix transform;
protected boolean cacheTransformations;
protected boolean childHasMatrix;
// ........................................................
// Normals
protected float normalX, normalY, normalZ;
// normal calculated per triangle
static protected final int NORMAL_MODE_AUTO = 0;
// one normal manually specified per shape
static protected final int NORMAL_MODE_SHAPE = 1;
// normals specified for each shape vertex
static protected final int NORMAL_MODE_VERTEX = 2;
// Current mode for normals, one of AUTO, SHAPE, or VERTEX
protected int normalMode;
// ........................................................
// Modification caches
// The caches are used to copy the data from each modified child shape
// to a contiguous array that will be then copied to the VBO in the root shape.
protected VertexCache fillVerticesCache;
protected VertexCache fillColorsCache;
protected VertexCache fillNormalsCache;
protected VertexCache fillTexCoordsCache;
protected VertexCache fillAmbientCache;
protected VertexCache fillSpecularCache;
protected VertexCache fillEmissiveCache;
protected VertexCache fillShininessCache;
protected VertexCache lineVerticesCache;
protected VertexCache lineColorsCache;
protected VertexCache lineAttributesCache;
protected VertexCache pointVerticesCache;
protected VertexCache pointColorsCache;
protected VertexCache pointAttributesCache;
boolean modifiedFillVertices;
boolean modifiedFillColors;
@@ -168,54 +265,7 @@ public class PShape3D extends PShape {
boolean modifiedPointVertices;
boolean modifiedPointColors;
boolean modifiedPointNormals;
boolean modifiedPointAttributes;
protected VertexCache fillVerticesCache;
protected VertexCache fillColorsCache;
protected VertexCache fillNormalsCache;
protected VertexCache fillTexCoordsCache;
protected VertexCache fillAmbientCache;
protected VertexCache fillSpecularCache;
protected VertexCache fillEmissiveCache;
protected VertexCache fillShininessCache;
protected VertexCache lineVerticesCache;
protected VertexCache lineColorsCache;
protected VertexCache lineAttributesCache;
protected VertexCache pointVerticesCache;
protected VertexCache pointColorsCache;
protected VertexCache pointAttributesCache;
protected boolean isSolid;
protected boolean isClosed;
protected boolean openContour = false;
protected boolean breakShape = false;
protected boolean shapeEnded = false;
protected boolean hasFill;
protected boolean hasLines;
protected boolean hasPoints;
protected boolean applyMatrix;
protected boolean childHasMatrix;
// ........................................................
// Input data
protected float normalX, normalY, normalZ;
// normal calculated per triangle
static protected final int NORMAL_MODE_AUTO = 0;
// one normal manually specified per shape
static protected final int NORMAL_MODE_SHAPE = 1;
// normals specified for each shape vertex
static protected final int NORMAL_MODE_VERTEX = 2;
// Current mode for normals, one of AUTO, SHAPE, or VERTEX
protected int normalMode;
boolean modifiedPointAttributes;
// ........................................................
@@ -239,22 +289,6 @@ public class PShape3D extends PShape {
protected float curveVertices[][];
protected int curveVertexCount;
// ........................................................
// Modes inherited from renderer
protected int textureMode;
protected int rectMode;
protected int ellipseMode;
protected int shapeMode;
protected int imageMode;
// ........................................................
// Geometric transformations
protected PMatrix transform;
protected boolean cacheTransformations;
@@ -262,7 +296,7 @@ public class PShape3D extends PShape {
pg = (PGraphicsOpenGL)parent.g;
pgl = pg.pgl;
glMode = PGL.GL_STATIC_DRAW;
prevMode = mode = DYNAMIC;
glFillVertexBufferID = 0;
glFillColorBufferID = 0;
@@ -293,10 +327,12 @@ public class PShape3D extends PShape {
if (family == GEOMETRY || family == PRIMITIVE || family == PATH) {
in = pg.newInGeometry(PGraphicsOpenGL.RETAINED);
}
tess = pg.newTessGeometry(PGraphicsOpenGL.RETAINED);
//tess = pg.newTessGeometry(PGraphicsOpenGL.RETAINED);
fillIndexData = new ArrayList<IndexData>();
lineIndexData = new ArrayList<IndexData>();
pointIndexData = new ArrayList<IndexData>();
pointIndexData = new ArrayList<IndexData>();
// Modes are retrieved from the current values in the renderer.
textureMode = pg.textureMode;
@@ -339,21 +375,17 @@ public class PShape3D extends PShape {
shapeEnded = true;
}
}
public void setKind(int kind) {
this.kind = kind;
}
public void setMode(int mode) {
if (mode == STATIC) {
glMode = PGL.GL_STATIC_DRAW;
} else if (mode == DYNAMIC) {
glMode = PGL.GL_DYNAMIC_DRAW;
} else if (mode == STREAM) {
glMode = PGL.GL_STREAM_DRAW;
if (this.mode == STATIC && mode == DYNAMIC) {
// Marking the shape as not tessellated, this
// will trigger a tessellation next time the
// shape is drawn or modified, which will bring
// back all the tess objects.
tessellated = false;
}
super.setMode(mode);
}
public void addChild(PShape child) {
@@ -997,7 +1029,7 @@ public class PShape3D extends PShape {
protected void updateFillColor() {
if (shapeEnded && 0 < tess.fillVertexCount && texture == null) {
if (shapeEnded && tessellated && 0 < tess.fillVertexCount && texture == null) {
Arrays.fill(tess.fillColors, 0, tess.fillVertexCount, PGL.javaToNativeARGB(fillColor));
modifiedFillColors = true;
modified();
@@ -1110,7 +1142,7 @@ public class PShape3D extends PShape {
protected void updateStrokeColor() {
if (shapeEnded && (0 < tess.lineVertexCount || 0 < tess.pointVertexCount)) {
if (shapeEnded && tessellated && (0 < tess.lineVertexCount || 0 < tess.pointVertexCount)) {
if (0 < tess.lineVertexCount) {
Arrays.fill(tess.lineColors, 0, tess.lineVertexCount, PGL.javaToNativeARGB(strokeColor));
modifiedLineColors = true;
@@ -1231,7 +1263,7 @@ public class PShape3D extends PShape {
protected void updateTintColor() {
if (shapeEnded && 0 < tess.fillVertexCount && texture != null) {
if (shapeEnded && tessellated && 0 < tess.fillVertexCount && texture != null) {
Arrays.fill(tess.fillColors, 0, tess.fillVertexCount, PGL.javaToNativeARGB(tintColor));
modifiedFillColors = true;
modified();
@@ -1290,7 +1322,7 @@ public class PShape3D extends PShape {
protected void updateAmbientColor() {
if (shapeEnded && 0 < tess.fillVertexCount) {
if (shapeEnded && tessellated && 0 < tess.fillVertexCount) {
Arrays.fill(tess.fillAmbient, 0, tess.fillVertexCount, PGL.javaToNativeARGB(ambientColor));
modifiedFillAmbient = true;
modified();
@@ -1349,7 +1381,7 @@ public class PShape3D extends PShape {
protected void updateSpecularColor() {
if (shapeEnded && 0 < tess.fillVertexCount) {
if (shapeEnded && tessellated && 0 < tess.fillVertexCount) {
Arrays.fill(tess.fillSpecular, 0, tess.fillVertexCount, PGL.javaToNativeARGB(specularColor));
modifiedFillSpecular = true;
modified();
@@ -1408,7 +1440,7 @@ public class PShape3D extends PShape {
protected void updateEmissiveColor() {
if (shapeEnded && 0 < tess.fillVertexCount) {
if (shapeEnded && tessellated && 0 < tess.fillVertexCount) {
Arrays.fill(tess.fillEmissive, 0, tess.fillVertexCount, PGL.javaToNativeARGB(emissiveColor));
modifiedFillEmissive = true;
modified();
@@ -1434,16 +1466,11 @@ public class PShape3D extends PShape {
protected void updateShininessFactor() {
if (!shapeEnded || tess.fillVertexCount == 0) {
return;
if (shapeEnded && tessellated && 0 < tess.fillVertexCount) {
Arrays.fill(tess.fillShininess, 0, tess.fillVertexCount, shininess);
modifiedFillShininess = true;
modified();
}
updateTessellation();
Arrays.fill(tess.fillShininess, 0, tess.fillVertexCount, shininess);
modifiedFillShininess = true;
modified();
}
@@ -1522,13 +1549,14 @@ public class PShape3D extends PShape {
}
if (matrix != null) {
matrix.reset();
applyMatrix = false;
}
} else {
if (cacheTransformations) {
boolean res = matrix.invert();
if (res) {
if (tessellated) {
// This will be ultimately handled by transformImpl(),
// which will take care of setting the modified flags, etc.
applyMatrix(matrix);
}
matrix.reset();
@@ -1538,7 +1566,6 @@ public class PShape3D extends PShape {
} else {
if (hasMatrix()) {
matrix.reset();
applyMatrix = false;
}
}
}
@@ -1563,12 +1590,6 @@ public class PShape3D extends PShape {
if (shapeEnded) {
if (family == GROUP) {
// The tessellation is not updated for geometry/primitive shapes
// because a common situation is shapes not still tessellated
// but being transformed before adding them to the parent group
// shape. If each shape is tessellated individually, then the process,
// although still valid, is significantly slower than tessellating
// all the geometry in a single batch.
updateTessellation();
if (cacheTransformations) {
@@ -1582,19 +1603,20 @@ public class PShape3D extends PShape {
} else {
checkMatrix(ncoords);
calcTransform(type, ncoords, args);
applyMatrix = true;
}
} else {
} else {
// The tessellation is not updated for geometry/primitive shapes
// because a common situation is shapes not still tessellated
// but being transformed before adding them to the parent group
// shape. If each shape is tessellated individually, then the process
// is significantly slower than tessellating all the geometry in a single
// batch when calling tessellate() on the root shape.
checkMatrix(ncoords);
if (cacheTransformations) {
calcTransform(type, ncoords, args);
if (tessellated) {
applyTransform(ncoords);
// Setting the applyMatrix variable to false so
// that the transformation is not applied again
// in the draw() method.
applyMatrix = false;
modified();
if (0 < tess.fillVertexCount) {
modifiedFillVertices = true;
@@ -1608,15 +1630,10 @@ public class PShape3D extends PShape {
modifiedPointVertices = true;
modifiedPointNormals = true;
}
} else {
// The matrix will be applied right after tessellation.
applyMatrix = true;
}
} else {
// The transformation will be applied in draw().
calcTransform(type, ncoords, args);
applyMatrix = true;
calcTransform(type, ncoords, args);
}
}
@@ -1894,9 +1911,6 @@ public class PShape3D extends PShape {
curveToBezierMatrix = new PMatrix3D();
}
// TODO only needed for PGraphicsJava2D? if so, move it there
// actually, it's generally useful for other renderers, so keep it
// or hide the implementation elsewhere.
curveToBezierMatrix.set(curveBasisMatrix);
curveToBezierMatrix.preApply(bezierBasisInverse);
@@ -2380,19 +2394,30 @@ public class PShape3D extends PShape {
protected void updateTessellation() {
if (!root.tessellated || root.contextIsOutdated()) {
root.tessellate();
root.aggregate();
root.aggregate();
}
}
protected void tessellate() {
if (tess == null) {
tess = pg.newTessGeometry(PGraphicsOpenGL.RETAINED, family == GROUP);
}
tess.clear();
if (family == GROUP) {
for (int i = 0; i < childCount; i++) {
PShape3D child = (PShape3D) children[i];
child.tessellate();
}
} else {
if (shapeEnded && !tessellated) {
if (shapeEnded) {
// If the geometry was tessellated previously, then
// the edges information will still be stored in the
// input object, so it needs to be removed to avoid
// duplication.
in.clearEdges();
tessellator.setInGeometry(in);
tessellator.setTessGeometry(tess);
tessellator.setFill(fill || texture != null);
@@ -2431,6 +2456,12 @@ public class PShape3D extends PShape {
tessellator.tessellatePolygon(isSolid, isClosed, normalMode == NORMAL_MODE_AUTO);
}
} else if (family == PRIMITIVE) {
// The input geometry needs to be cleared because the geometry
// generation methods in InGeometry add the vertices of the
// new primitive to what is already stored.
in.clear();
if (kind == POINT) {
tessellatePoint();
} else if (kind == LINE) {
@@ -2450,9 +2481,7 @@ public class PShape3D extends PShape {
} else if (kind == SPHERE) {
tessellateSphere();
}
} else if (family == PATH) {
// TODO: Determine if this is necessary, since it is
// equivalent to use POLYGON with fill disabled.
} else if (family == PATH) {
}
// Tessellated arrays are trimmed since they are expanded
@@ -2464,11 +2493,10 @@ public class PShape3D extends PShape {
((PShape3D)parent).addTexture(texture);
}
if (cacheTransformations && applyMatrix) {
if (cacheTransformations && matrix != null) {
// Some geometric transformations were applied on
// this shape before tessellation, so they are applied now.
tess.applyMatrix(matrix);
applyMatrix = false;
}
}
}
@@ -2544,8 +2572,7 @@ public class PShape3D extends PShape {
}
protected void tessellateSphere() {
// TODO: move to InGeometry
protected void tessellateSphere() {
float r = params[0];
int nu = pg.sphereDetailU;
int nv = pg.sphereDetailV;
@@ -2725,29 +2752,7 @@ public class PShape3D extends PShape {
aggregateImpl();
context = pgl.getContext();
// Now that we know, we can initialize the buffers with the correct size.
if (0 < tess.fillVertexCount && 0 < tess.fillIndexCount) {
initFillBuffers(tess.fillVertexCount, tess.fillIndexCount);
fillVertCopyOffset = 0;
fillIndCopyOffset = 0;
copyFillGeometryToRoot();
}
if (0 < tess.lineVertexCount && 0 < tess.lineIndexCount) {
initLineBuffers(tess.lineVertexCount, tess.lineIndexCount);
lineVertCopyOffset = 0;
lineIndCopyOffset = 0;
copyLineGeometryToRoot();
}
if (0 < tess.pointVertexCount && 0 < tess.pointIndexCount) {
initPointBuffers(tess.pointVertexCount, tess.pointIndexCount);
pointVertCopyOffset = 0;
pointIndCopyOffset = 0;
copyPointGeometryToRoot();
}
needBufferInit = true;
}
}
@@ -2757,8 +2762,6 @@ public class PShape3D extends PShape {
// level of the shape hierarchy.
protected void aggregateImpl() {
if (family == GROUP) {
tess.clear();
boolean firstGeom = true;
boolean firstStroke = true;
boolean firstPoint = true;
@@ -2833,7 +2836,7 @@ public class PShape3D extends PShape {
hasFill = 0 < tess.fillVertexCount && 0 < tess.fillIndexCount;
hasLines = 0 < tess.lineVertexCount && 0 < tess.lineIndexCount;
hasPoints = 0 < tess.pointVertexCount && 0 < tess.pointIndexCount;
hasPoints = 0 < tess.pointVertexCount && 0 < tess.pointIndexCount;
}
// Creates fill index data for a geometry shape.
@@ -2939,6 +2942,56 @@ public class PShape3D extends PShape {
}
protected void initBuffers() {
if (root.needBufferInit) {
root.copyGeometryToRoot();
}
}
protected void copyGeometryToRoot() {
if (root == this && parent == null) {
context = pgl.getContext();
// Now that we know, we can initialize the buffers with the correct size.
if (0 < tess.fillVertexCount && 0 < tess.fillIndexCount) {
initFillBuffers(tess.fillVertexCount, tess.fillIndexCount);
fillVertCopyOffset = 0;
fillIndCopyOffset = 0;
copyFillGeometryToRoot();
}
if (0 < tess.lineVertexCount && 0 < tess.lineIndexCount) {
initLineBuffers(tess.lineVertexCount, tess.lineIndexCount);
lineVertCopyOffset = 0;
lineIndCopyOffset = 0;
copyLineGeometryToRoot();
}
if (0 < tess.pointVertexCount && 0 < tess.pointIndexCount) {
initPointBuffers(tess.pointVertexCount, tess.pointIndexCount);
pointVertCopyOffset = 0;
pointIndCopyOffset = 0;
copyPointGeometryToRoot();
}
needBufferInit = false;
// Since all the tessellated geometry has just been copied to the
// root VBOs, we can mark all the shapes as not modified.
notModified();
}
}
protected void modeCheck() {
if (root.mode == STATIC && root.prevMode == DYNAMIC) {
root.freeCaches();
root.freeTessData();
}
root.prevMode = root.mode;
}
protected boolean contextIsOutdated() {
boolean outdated = !pgl.contextIsCurrent(context);
if (outdated) {
@@ -2977,41 +3030,41 @@ public class PShape3D extends PShape {
glFillVertexBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillVertexBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, glMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, PGL.GL_STATIC_DRAW);
glFillColorBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillColorBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, PGL.GL_STATIC_DRAW);
glFillNormalBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillNormalBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, glMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, PGL.GL_STATIC_DRAW);
glFillTexCoordBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillTexCoordBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, glMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, PGL.GL_STATIC_DRAW);
glFillAmbientBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillAmbientBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, PGL.GL_STATIC_DRAW);
glFillSpecularBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillSpecularBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, PGL.GL_STATIC_DRAW);
glFillEmissiveBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillEmissiveBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, PGL.GL_STATIC_DRAW);
glFillShininessBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillShininessBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizef, null, glMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizef, null, PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0);
glFillIndexBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glFillIndexBufferID);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, glMode);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0);
}
@@ -3043,8 +3096,7 @@ public class PShape3D extends PShape {
PShape3D child = (PShape3D) children[i];
child.updateRootGeometry();
}
} else {
} else {
if (0 < tess.fillVertexCount) {
if (modifiedFillVertices) {
if (root.fillVerticesCache == null) {
@@ -3322,21 +3374,21 @@ public class PShape3D extends PShape {
glLineVertexBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineVertexBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, glMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, PGL.GL_STATIC_DRAW);
glLineColorBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineColorBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, PGL.GL_STATIC_DRAW);
glLineDirWidthBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineDirWidthBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 4 * sizef, null, glMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 4 * sizef, null, PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0);
glLineIndexBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glLineIndexBufferID);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, glMode);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0);
}
@@ -3349,7 +3401,7 @@ public class PShape3D extends PShape {
child.copyLineGeometryToRoot();
}
} else {
if (hasLines) {
if (0 < tess.lineVertexCount && 0 < tess.lineIndexCount) {
root.copyLineGeometry(root.lineVertCopyOffset, tess.lineVertexCount,
tess.lineVertices, tess.lineColors, tess.lineDirWidths);
root.lineVertCopyOffset += tess.lineVertexCount;
@@ -3416,21 +3468,21 @@ public class PShape3D extends PShape {
glPointVertexBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointVertexBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, glMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, PGL.GL_STATIC_DRAW);
glPointColorBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointColorBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, PGL.GL_STATIC_DRAW);
glPointSizeBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointSizeBufferID);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, glMode);
pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0);
glPointIndexBufferID = pg.createVertexBufferObject();
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glPointIndexBufferID);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, glMode);
pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, PGL.GL_STATIC_DRAW);
pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0);
}
@@ -3443,7 +3495,7 @@ public class PShape3D extends PShape {
child.copyPointGeometryToRoot();
}
} else {
if (hasPoints) {
if (0 < tess.pointVertexCount && 0 < tess.pointIndexCount) {
root.copyPointGeometry(root.pointVertCopyOffset, tess.pointVertexCount,
tess.pointVertices, tess.pointColors, tess.pointSizes);
root.pointVertCopyOffset += tess.pointVertexCount;
@@ -3610,6 +3662,38 @@ public class PShape3D extends PShape {
}
}
protected void freeCaches() {
fillVerticesCache = null;
fillColorsCache = null;
fillNormalsCache = null;
fillTexCoordsCache = null;
fillAmbientCache = null;
fillSpecularCache = null;
fillEmissiveCache = null;
fillShininessCache = null;
lineVerticesCache = null;
lineColorsCache = null;
lineAttributesCache = null;
pointVerticesCache = null;
pointColorsCache = null;
pointAttributesCache = null;
}
protected void freeTessData() {
tess = null;
if (family == GROUP) {
for (int i = 0; i < childCount; i++) {
PShape3D child = (PShape3D)children[i];
child.freeTessData();
}
}
}
///////////////////////////////////////////////////////////
//
@@ -3624,10 +3708,11 @@ public class PShape3D extends PShape {
public void draw(PGraphics g) {
if (visible) {
updateTessellation();
updateTessellation();
initBuffers();
updateGeometry();
if (applyMatrix && matrix != null) {
if (!cacheTransformations && matrix != null) {
g.pushMatrix();
g.applyMatrix(matrix);
}
@@ -3663,9 +3748,11 @@ public class PShape3D extends PShape {
render(texture);
}
if (applyMatrix && matrix != null) {
if (!cacheTransformations && matrix != null) {
g.popMatrix();
}
modeCheck();
}
}
@@ -3677,7 +3764,7 @@ public class PShape3D extends PShape {
// Some error. Root should never be null. At least it should be this.
return;
}
if (hasPoints) {
renderPoints();
}