From 294c96e2c8412f2d547de8971c0445fee44908d4 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Mon, 6 Feb 2012 15:38:29 +0000 Subject: [PATCH] More material properties handling --- android/core/src/processing/core/PGL.java | 10 +- .../processing/core/PGraphicsAndroid3D.java | 295 ++------- .../core/src/processing/core/PShape3D.java | 589 +++++++++++++++--- 3 files changed, 580 insertions(+), 314 deletions(-) diff --git a/android/core/src/processing/core/PGL.java b/android/core/src/processing/core/PGL.java index 98fdd7bf9..713a69d93 100644 --- a/android/core/src/processing/core/PGL.java +++ b/android/core/src/processing/core/PGL.java @@ -769,9 +769,13 @@ public class PGL { GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, id); } - public void initVertexBuffer(int size, int mode) { + public void initFloatVertexBuffer(int size, int mode) { GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, size * SIZEOF_FLOAT, null, mode); } + + public void initIntVertexBuffer(int size, int mode) { + GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, size * SIZEOF_INT, null, mode); + } public void copyVertexBufferData(float[] data, int size, int mode) { GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, size * SIZEOF_FLOAT, FloatBuffer.wrap(data, 0, size), mode); @@ -788,6 +792,10 @@ public class PGL { public void copyVertexBufferSubData(float[] data, int offset, int size, int mode) { GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, offset * SIZEOF_FLOAT, size * SIZEOF_FLOAT, FloatBuffer.wrap(data, 0, size)); } + + public void copyVertexBufferSubData(int[] data, int offset, int size, int mode) { + GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, offset * SIZEOF_INT, size * SIZEOF_INT, IntBuffer.wrap(data, 0, size)); + } public void unbindVertexBuffer() { GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); diff --git a/android/core/src/processing/core/PGraphicsAndroid3D.java b/android/core/src/processing/core/PGraphicsAndroid3D.java index c72219b17..c8e5a0065 100644 --- a/android/core/src/processing/core/PGraphicsAndroid3D.java +++ b/android/core/src/processing/core/PGraphicsAndroid3D.java @@ -55,8 +55,12 @@ public class PGraphicsAndroid3D extends PGraphics { public int glFillVertexBufferID; public int glFillColorBufferID; public int glFillNormalBufferID; - public int glFillTexCoordBufferID; - public int glFillIndexBufferID; + public int glFillTexCoordBufferID; + public int glFillAmbientBufferID; + public int glFillSpecularBufferID; + public int glFillEmissiveBufferID; + public int glFillShininessBufferID; + public int glFillIndexBufferID; protected boolean fillVBOsCreated = false; public int glLineVertexBufferID; @@ -281,12 +285,6 @@ public class PGraphicsAndroid3D extends PGraphics { /** True if we are inside a beginDraw()/endDraw() block. */ protected boolean drawing = false; - /** Used to make backups of current drawing state. */ - //protected DrawingState drawState; - - /** Used to hold color values to be sent to OpenGL. */ - protected float[] colorFloats; - /** Used to detect the occurrence of a frame resize event. */ protected boolean resized = false; @@ -401,7 +399,11 @@ public class PGraphicsAndroid3D extends PGraphics { glFillVertexBufferID = 0; glFillColorBufferID = 0; glFillNormalBufferID = 0; - glFillTexCoordBufferID = 0; + glFillTexCoordBufferID = 0; + glFillAmbientBufferID = 0; + glFillSpecularBufferID = 0; + glFillEmissiveBufferID = 0; + glFillShininessBufferID = 0; glFillIndexBufferID = 0; glLineVertexBufferID = 0; @@ -1077,19 +1079,35 @@ public class PGraphicsAndroid3D extends PGraphics { protected void createFillBuffers() { glFillVertexBufferID = createVertexBufferObject(); pgl.bindVertexBuffer(glFillVertexBufferID); - pgl.initVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.initFloatVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); glFillColorBufferID = createVertexBufferObject(); pgl.bindVertexBuffer(glFillColorBufferID); - pgl.initVertexBuffer(4 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.initFloatVertexBuffer(4 * PGL.MAX_TESS_VERTICES, vboMode); glFillNormalBufferID = createVertexBufferObject(); pgl.bindVertexBuffer(glFillNormalBufferID); - pgl.initVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.initFloatVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); glFillTexCoordBufferID = createVertexBufferObject(); pgl.bindVertexBuffer(glFillTexCoordBufferID); - pgl.initVertexBuffer(2 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.initFloatVertexBuffer(2 * PGL.MAX_TESS_VERTICES, vboMode); + + glFillAmbientBufferID = pg.createVertexBufferObject(); + pgl.bindVertexBuffer(glFillAmbientBufferID); + pgl.initIntVertexBuffer(PGL.MAX_TESS_VERTICES, vboMode); + + glFillSpecularBufferID = pg.createVertexBufferObject(); + pgl.bindVertexBuffer(glFillSpecularBufferID); + pgl.initIntVertexBuffer(PGL.MAX_TESS_VERTICES, vboMode); + + glFillEmissiveBufferID = pg.createVertexBufferObject(); + pgl.bindVertexBuffer(glFillEmissiveBufferID); + pgl.initIntVertexBuffer(PGL.MAX_TESS_VERTICES, vboMode); + + glFillShininessBufferID = pg.createVertexBufferObject(); + pgl.bindVertexBuffer(glFillShininessBufferID); + pgl.initFloatVertexBuffer(PGL.MAX_TESS_VERTICES, vboMode); pgl.unbindVertexBuffer(); @@ -1113,6 +1131,18 @@ public class PGraphicsAndroid3D extends PGraphics { deleteVertexBufferObject(glFillTexCoordBufferID); glFillTexCoordBufferID = 0; + deleteVertexBufferObject(glFillAmbientBufferID); + glFillAmbientBufferID = 0; + + deleteVertexBufferObject(glFillSpecularBufferID); + glFillSpecularBufferID = 0; + + deleteVertexBufferObject(glFillEmissiveBufferID); + glFillEmissiveBufferID = 0; + + deleteVertexBufferObject(glFillShininessBufferID); + glFillShininessBufferID = 0; + deleteVertexBufferObject(glFillIndexBufferID); glFillIndexBufferID = 0; } @@ -1120,19 +1150,19 @@ public class PGraphicsAndroid3D extends PGraphics { protected void createLineBuffers() { glLineVertexBufferID = createVertexBufferObject(); pgl.bindVertexBuffer(glLineVertexBufferID); - pgl.initVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.initFloatVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); glLineColorBufferID = createVertexBufferObject(); pgl.bindVertexBuffer(glLineColorBufferID); - pgl.initVertexBuffer(4 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.initFloatVertexBuffer(4 * PGL.MAX_TESS_VERTICES, vboMode); glLineNormalBufferID = createVertexBufferObject(); pgl.bindVertexBuffer(glLineNormalBufferID); - pgl.initVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.initFloatVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); glLineAttribBufferID = createVertexBufferObject(); pgl.bindVertexBuffer(glLineAttribBufferID); - pgl.initVertexBuffer(4 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.initFloatVertexBuffer(4 * PGL.MAX_TESS_VERTICES, vboMode); pgl.unbindVertexBuffer(); @@ -1163,19 +1193,19 @@ public class PGraphicsAndroid3D extends PGraphics { protected void createPointBuffers() { glPointVertexBufferID = createVertexBufferObject(); pgl.bindVertexBuffer(glPointVertexBufferID); - pgl.initVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.initFloatVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); glPointColorBufferID = createVertexBufferObject(); pgl.bindVertexBuffer(glPointColorBufferID); - pgl.initVertexBuffer(4 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.initFloatVertexBuffer(4 * PGL.MAX_TESS_VERTICES, vboMode); glPointNormalBufferID = createVertexBufferObject(); pgl.bindVertexBuffer(glPointNormalBufferID); - pgl.initVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.initFloatVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); glPointAttribBufferID = createVertexBufferObject(); pgl.bindVertexBuffer(glPointAttribBufferID); - pgl.initVertexBuffer(2 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.initFloatVertexBuffer(2 * PGL.MAX_TESS_VERTICES, vboMode); pgl.unbindVertexBuffer(); @@ -1418,11 +1448,6 @@ public class PGraphicsAndroid3D extends PGraphics { public GL beginGL() { saveGLState(); - // OpenGL is using Processing defaults at this point, - // such as the inverted Y axis, GL_COLOR_MATERIAL mode, etc. - // The user is free to change anything she wants, endGL will - // try to do its best to restore things to the Processing - // settings valid at the time of calling beginGL(). return pgl.gl; } @@ -1442,15 +1467,12 @@ public class PGraphicsAndroid3D extends PGraphics { protected void saveGLState() { - //saveGLMatrices(); } protected void restoreGLState() { // Restoring viewport. pgl.setViewport(viewport); - - //restoreGLMatrices(); // Restoring hints. if (hints[DISABLE_DEPTH_TEST]) { @@ -1470,80 +1492,6 @@ public class PGraphicsAndroid3D extends PGraphics { // Restoring blending. blendMode(blendMode); - // Restoring fill - if (fill) { - calcR = fillR; - calcG = fillG; - calcB = fillB; - calcA = fillA; - fillFromCalc(); - } - - // Restoring material properties. - calcR = ambientR; - calcG = ambientG; - calcB = ambientB; - ambientFromCalc(); - - calcR = specularR; - calcG = specularG; - calcB = specularB; - specularFromCalc(); - - shininess(shininess); - - calcR = emissiveR; - calcG = emissiveG; - calcB = emissiveB; - emissiveFromCalc(); - - /* - // Restoring lights. - if (lights) { - lights(); - for (int i = 0; i < lightCount; i++) { - lightEnable(i); - if (lightType[i] == AMBIENT) { - lightEnable(i); - lightAmbient(i); - lightPosition(i); - lightFalloff(i); - lightNoSpot(i); - lightNoDiffuse(i); - lightNoSpecular(i); - } else if (lightType[i] == DIRECTIONAL) { - lightEnable(i); - lightNoAmbient(i); - lightDirection(i); - lightDiffuse(i); - lightSpecular(i); - lightFalloff(i); - lightNoSpot(i); - } else if (lightType[i] == POINT) { - lightEnable(i); - lightNoAmbient(i); - lightPosition(i); - lightDiffuse(i); - lightSpecular(i); - lightFalloff(i); - lightNoSpot(i); - } else if (lightType[i] == SPOT) { - lightEnable(i); - lightNoAmbient(i); - lightPosition(i); - lightDirection(i); - lightDiffuse(i); - lightSpecular(i); - lightFalloff(i); - lightSpotAngle(i); - lightSpotConcentration(i); - } - } - } else { - noLights(); - } - */ - // Some things the user might have changed from OpenGL, // but we want to make sure they return to the Processing // defaults (plus these cannot be changed through the API @@ -1553,21 +1501,8 @@ public class PGraphicsAndroid3D extends PGraphics { setSurfaceParams(); } - - /* - protected void saveDrawingState() { - if (drawState == null) { - drawState = new DrawingState(); - } - drawState.save(); - } - protected void restoreDrawingState() { - drawState.restore(); - } - */ - // Utility function to get ready OpenGL for a specific // operation, such as grabbing the contents of the color // buffer. @@ -3939,85 +3874,6 @@ public class PGraphicsAndroid3D extends PGraphics { public void strokeCap(int cap) { this.strokeCap = cap; } - - ////////////////////////////////////////////////////////////// - - // STROKE, TINT, FILL - - // public void noStroke() - // public void stroke(int rgb) - // public void stroke(int rgb, float alpha) - // public void stroke(float gray) - // public void stroke(float gray, float alpha) - // public void stroke(float x, float y, float z) - // public void stroke(float x, float y, float z, float a) - // protected void strokeFromCalc() - - // public void noTint() - // public void tint(int rgb) - // public void tint(int rgb, float alpha) - // public void tint(float gray) - // public void tint(float gray, float alpha) - // public void tint(float x, float y, float z) - // public void tint(float x, float y, float z, float a) - // protected void tintFromCalc() - - // public void noFill() - // public void fill(int rgb) - // public void fill(int rgb, float alpha) - // public void fill(float gray) - // public void fill(float gray, float alpha) - // public void fill(float x, float y, float z) - // public void fill(float x, float y, float z, float a) - - protected void fillFromCalc() { - super.fillFromCalc(); - calcColorBuffer(); - - // P3D uses GL_COLOR_MATERIAL mode, so the ambient and diffuse components - // for all vertices are taken from the glColor/color buffer settings and we don't - // need this: - //gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT_AND_DIFFUSE, colorFloats, 0); - } - - protected void setFillColor() { - //pgl.setColor(fillR, fillG, fillB, fillA); - } - - protected void setTintColor() { - //pgl.setColor(tintR, tintG, tintB, tintA); - } - - ////////////////////////////////////////////////////////////// - - // MATERIAL PROPERTIES - - - protected void ambientFromCalc() { - super.ambientFromCalc(); - calcColorBuffer(); - //pgl.setMaterialAmbient(colorFloats); - } - - - protected void specularFromCalc() { - super.specularFromCalc(); - calcColorBuffer(); - //pgl.setMaterialSpecular(colorFloats); - } - - - public void shininess(float shine) { - super.shininess(shine); - //pgl.setMaterialShininess(shine); - } - - - protected void emissiveFromCalc() { - super.emissiveFromCalc(); - calcColorBuffer(); - //pgl.setMaterialEmission(colorFloats); - } ////////////////////////////////////////////////////////////// @@ -4409,25 +4265,6 @@ public class PGraphicsAndroid3D extends PGraphics { // colorMode() is inherited from PGraphics. - ////////////////////////////////////////////////////////////// - - // COLOR CALC - - // This is the OpenGL complement to the colorCalc() methods. - - /** - * Load the calculated color into a pre-allocated array so that it can be - * quickly passed over to OpenGL. - */ - protected final void calcColorBuffer() { - if (colorFloats == null) { - colorFloats = new float[4]; - } - colorFloats[0] = calcR; - colorFloats[1] = calcG; - colorFloats[2] = calcB; - colorFloats[3] = calcA; - } ////////////////////////////////////////////////////////////// @@ -6944,7 +6781,8 @@ public class PGraphicsAndroid3D extends PGraphics { public float[] fillNormals; public float[] fillTexcoords; - // Fill material + // Fill material properties (fillColor is used + // as the diffuse color when lighting is enabled) public int[] fillAmbient; public int[] fillSpecular; public int[] fillEmissive; @@ -7008,13 +6846,11 @@ public class PGraphicsAndroid3D extends PGraphics { fillColors = new float[4 * PGL.DEFAULT_TESS_VERTICES]; fillNormals = new float[3 * PGL.DEFAULT_TESS_VERTICES]; fillTexcoords = new float[2 * PGL.DEFAULT_TESS_VERTICES]; - fillIndices = new short[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]; - + fillShininess = new float[PGL.DEFAULT_TESS_VERTICES]; + fillIndices = new short[PGL.DEFAULT_TESS_VERTICES]; lineVertices = new float[3 * PGL.DEFAULT_TESS_VERTICES]; lineColors = new float[4 * PGL.DEFAULT_TESS_VERTICES]; @@ -7189,11 +7025,11 @@ public class PGraphicsAndroid3D extends PGraphics { fillColors = null; fillNormals = null; fillTexcoords = null; - fillIndices = null; fillAmbient = null; fillSpecular = null; fillEmissive = null; - fillShininess = null; + fillShininess = null; + fillIndices = null; lineVertices = null; lineColors = null; @@ -7787,13 +7623,11 @@ public class PGraphicsAndroid3D extends PGraphics { } } else { PApplet.arrayCopy(in.colors, 4 * i0, fillColors, 4 * firstFillVertex, 4 * nvert); - PApplet.arrayCopy(in.texcoords, 2 * i0, fillTexcoords, 2 * firstFillVertex, 2 * nvert); - + PApplet.arrayCopy(in.texcoords, 2 * i0, fillTexcoords, 2 * firstFillVertex, 2 * nvert); PApplet.arrayCopy(in.ambient, i0, fillAmbient, firstFillVertex, nvert); PApplet.arrayCopy(in.specular, i0, fillSpecular, firstFillVertex, nvert); PApplet.arrayCopy(in.emissive, i0, fillEmissive, firstFillVertex, nvert); - PApplet.arrayCopy(in.shininess, i0, fillShininess, firstFillVertex, nvert); - + PApplet.arrayCopy(in.shininess, i0, fillShininess, firstFillVertex, nvert); } } @@ -8898,7 +8732,8 @@ public class PGraphicsAndroid3D extends PGraphics { double[] vertData = (double[])data[j]; if (vertData != null) { if (11 < i && i < 15) { - // Color data + // Color data, needs to be split into rgba components + // for interpolation. int colorj = (int) vertData[i]; int aj = (colorj >> 24) & 0xFF; int rj = (colorj >> 16) & 0xFF; @@ -8910,13 +8745,13 @@ public class PGraphicsAndroid3D extends PGraphics { int ri = (colori >> 16) & 0xFF; int gi = (colori >> 8) & 0xFF; int bi = (colori >> 0) & 0xFF; - + + ai += weight[j] * aj; ri += weight[j] * rj; bi += weight[j] * bj; - gi += weight[j] * gj; - ai += weight[j] * aj; + gi += weight[j] * gj; - colori = (ai << 24) | (ri << 16) | (gi << 8) | bi; + vertex[i] = (ai << 24) | (ri << 16) | (gi << 8) | bi; } else { vertex[i] += weight[j] * vertData[i]; } diff --git a/android/core/src/processing/core/PShape3D.java b/android/core/src/processing/core/PShape3D.java index 2aa5008fe..bf0e5f679 100644 --- a/android/core/src/processing/core/PShape3D.java +++ b/android/core/src/processing/core/PShape3D.java @@ -29,6 +29,7 @@ import java.nio.FloatBuffer; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.Hashtable; import java.io.BufferedReader; @@ -74,7 +75,11 @@ public class PShape3D extends PShape { public int glFillVertexBufferID; public int glFillColorBufferID; public int glFillNormalBufferID; - public int glFillTexCoordBufferID; + public int glFillTexCoordBufferID; + public int glFillAmbientBufferID; + public int glFillSpecularBufferID; + public int glFillEmissiveBufferID; + public int glFillShininessBufferID; public int glFillIndexBufferID; public int glLineVertexBufferID; @@ -125,6 +130,10 @@ public class PShape3D extends PShape { boolean modifiedFillColors; boolean modifiedFillNormals; boolean modifiedFillTexCoords; + boolean modifiedFillAmbient; + boolean modifiedFillSpecular; + boolean modifiedFillEmissive; + boolean modifiedFillShininess; boolean modifiedLineVertices; boolean modifiedLineColors; @@ -139,7 +148,11 @@ public class PShape3D extends PShape { protected VertexCache fillVerticesCache; protected VertexCache fillColorsCache; protected VertexCache fillNormalsCache; - protected VertexCache fillTexCoordsCache; + protected VertexCache fillTexCoordsCache; + protected VertexCache fillAmbientCache; + protected VertexCache fillSpecularCache; + protected VertexCache fillEmissiveCache; + protected VertexCache fillShininessCache; protected VertexCache lineVerticesCache; protected VertexCache lineColorsCache; @@ -242,6 +255,10 @@ public class PShape3D extends PShape { glFillColorBufferID = 0; glFillNormalBufferID = 0; glFillTexCoordBufferID = 0; + glFillAmbientBufferID = 0; + glFillSpecularBufferID = 0; + glFillEmissiveBufferID = 0; + glFillShininessBufferID = 0; glFillIndexBufferID = 0; glLineVertexBufferID = 0; @@ -396,6 +413,22 @@ public class PShape3D extends PShape { if (glFillTexCoordBufferID != 0) { pg.finalizeVertexBufferObject(glFillTexCoordBufferID); } + + if (glFillAmbientBufferID != 0) { + pg.finalizeVertexBufferObject(glFillAmbientBufferID); + } + + if (glFillSpecularBufferID != 0) { + pg.finalizeVertexBufferObject(glFillSpecularBufferID); + } + + if (glFillEmissiveBufferID != 0) { + pg.finalizeVertexBufferObject(glFillEmissiveBufferID); + } + + if (glFillShininessBufferID != 0) { + pg.finalizeVertexBufferObject(glFillShininessBufferID); + } if (glFillIndexBufferID != 0) { pg.finalizeVertexBufferObject(glFillIndexBufferID); @@ -1194,17 +1227,60 @@ public class PShape3D extends PShape { // AMBIENT COLOR public void ambient(int rgb) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.ambient(rgb); + } + } else { + colorCalc(rgb); + ambientFromCalc(); + } } - public void ambient(float gray) { + public void ambient(float gray) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.ambient(gray); + } + } else { + colorCalc(gray); + ambientFromCalc(); + } } - public void ambient(float x, float y, float z) { + public void ambient(float x, float y, float z) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.ambient(x, y, z); + } + } else { + colorCalc(x, y, z); + ambientFromCalc(); + } } - + protected void ambientFromCalc() { + ambientColor = calcColor; + updateAmbientColor(); + } + + protected void updateAmbientColor() { + if (!shapeEnded || tess.fillVertexCount == 0 || texture == null) { + return; + } + + updateTesselation(); + + Arrays.fill(tess.fillAmbient, 0, tess.fillVertexCount, ambientColor); + + modifiedFillAmbient = true; + modified(); + } ////////////////////////////////////////////////////////////// @@ -1212,17 +1288,60 @@ public class PShape3D extends PShape { public void specular(int rgb) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.specular(rgb); + } + } else { + colorCalc(rgb); + specularFromCalc(); + } } public void specular(float gray) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.specular(gray); + } + } else { + colorCalc(gray); + specularFromCalc(); + } } public void specular(float x, float y, float z) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.specular(x, y, z); + } + } else { + colorCalc(x, y, z); + specularFromCalc(); + } } - + protected void specularFromCalc() { + specularColor = calcColor; + updateSpecularColor(); + } + + protected void updateSpecularColor() { + if (!shapeEnded || tess.fillVertexCount == 0 || texture == null) { + return; + } + + updateTesselation(); + + Arrays.fill(tess.fillSpecular, 0, tess.fillVertexCount, specularColor); + + modifiedFillSpecular = true; + modified(); + } ////////////////////////////////////////////////////////////// @@ -1230,27 +1349,92 @@ public class PShape3D extends PShape { public void emissive(int rgb) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.emissive(rgb); + } + } else { + colorCalc(rgb); + emissiveFromCalc(); + } } public void emissive(float gray) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.emissive(gray); + } + } else { + colorCalc(gray); + emissiveFromCalc(); + } } public void emissive(float x, float y, float z) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.emissive(x, y, z); + } + } else { + colorCalc(x, y, z); + emissiveFromCalc(); + } } + protected void emissiveFromCalc() { + emissiveColor = calcColor; + updateEmissiveColor(); + } + protected void updateEmissiveColor() { + if (!shapeEnded || tess.fillVertexCount == 0 || texture == null) { + return; + } + + updateTesselation(); + + Arrays.fill(tess.fillEmissive, 0, tess.fillVertexCount, emissiveColor); + + modifiedFillEmissive = true; + modified(); + } ////////////////////////////////////////////////////////////// // SHININESS - public void shininess(float shine) { + public void shininess(float shine) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.shininess(shine); + } + } else { + shininess = shine; + updateShininessFactor(); + } } + protected void updateShininessFactor() { + if (!shapeEnded || tess.fillVertexCount == 0 || texture == null) { + return; + } + + updateTesselation(); + + Arrays.fill(tess.fillShininess, 0, tess.fillVertexCount, shininess); + + modifiedFillShininess = true; + modified(); + } + /////////////////////////////////////////////////////////// // @@ -2001,6 +2185,26 @@ public class PShape3D extends PShape { updateTesselation(); return tess.fillTexcoords; } + + public int[] fillAmbient() { + updateTesselation(); + return tess.fillAmbient; + } + + public int[] fillSpecular() { + updateTesselation(); + return tess.fillSpecular; + } + + public int[] fillEmissive() { + updateTesselation(); + return tess.fillEmissive; + } + + public float[] fillShininess() { + updateTesselation(); + return tess.fillShininess; + } public short[] fillIndices() { updateTesselation(); @@ -2143,6 +2347,38 @@ public class PShape3D extends PShape { public FloatBuffer mapFillTexCoords() { return mapVertexImpl(root.glFillTexCoordBufferID, 2 * tess.firstFillVertex, 2 * tess.fillVertexCount).asFloatBuffer(); + } + + public IntBuffer mapFillAmbient() { + return mapVertexImpl(root.glFillAmbientBufferID, tess.firstFillVertex, tess.fillVertexCount).asIntBuffer(); + } + + public void unmapFillAmbient() { + unmapVertexImpl(); + } + + public IntBuffer mapFillSpecular() { + return mapVertexImpl(root.glFillSpecularBufferID, tess.firstFillVertex, tess.fillVertexCount).asIntBuffer(); + } + + public void unmapFillSpecular() { + unmapVertexImpl(); + } + + public IntBuffer mapFillEmissive() { + return mapVertexImpl(root.glFillEmissiveBufferID, tess.firstFillVertex, tess.fillVertexCount).asIntBuffer(); + } + + public void unmapFillEmissive() { + unmapVertexImpl(); + } + + public FloatBuffer mapFillShininess() { + return mapVertexImpl(root.glFillShininessBufferID, tess.firstFillVertex, tess.fillVertexCount).asFloatBuffer(); + } + + public void unmapFillShininess() { + unmapVertexImpl(); } public void unmapFillTexCoords() { @@ -2567,62 +2803,62 @@ public class PShape3D extends PShape { // Copying any data remaining in the caches if (root.fillVerticesCache != null && root.fillVerticesCache.hasData()) { - root.copyFillVertices(root.fillVerticesCache.offset, root.fillVerticesCache.size, root.fillVerticesCache.data); + root.copyFillVertices(root.fillVerticesCache.offset, root.fillVerticesCache.size, root.fillVerticesCache.floatData); root.fillVerticesCache.reset(); } if (root.fillColorsCache != null && root.fillColorsCache.hasData()) { - root.copyFillColors(root.fillColorsCache.offset, root.fillColorsCache.size, root.fillColorsCache.data); + root.copyFillColors(root.fillColorsCache.offset, root.fillColorsCache.size, root.fillColorsCache.floatData); root.fillColorsCache.reset(); } if (root.fillNormalsCache != null && root.fillNormalsCache.hasData()) { - root.copyFillNormals(root.fillNormalsCache.offset, root.fillNormalsCache.size, root.fillNormalsCache.data); + root.copyFillNormals(root.fillNormalsCache.offset, root.fillNormalsCache.size, root.fillNormalsCache.floatData); root.fillNormalsCache.reset(); } if (root.fillTexCoordsCache != null && root.fillTexCoordsCache.hasData()) { - root.copyFillTexCoords(root.fillTexCoordsCache.offset, root.fillTexCoordsCache.size, root.fillTexCoordsCache.data); + root.copyFillTexCoords(root.fillTexCoordsCache.offset, root.fillTexCoordsCache.size, root.fillTexCoordsCache.floatData); root.fillTexCoordsCache.reset(); } if (root.lineVerticesCache != null && root.lineVerticesCache.hasData()) { - root.copyLineVertices(root.lineVerticesCache.offset, root.lineVerticesCache.size, root.lineVerticesCache.data); + root.copyLineVertices(root.lineVerticesCache.offset, root.lineVerticesCache.size, root.lineVerticesCache.floatData); root.lineVerticesCache.reset(); } if (root.lineColorsCache != null && root.lineColorsCache.hasData()) { - root.copyLineColors(root.lineColorsCache.offset, root.lineColorsCache.size, root.lineColorsCache.data); + root.copyLineColors(root.lineColorsCache.offset, root.lineColorsCache.size, root.lineColorsCache.floatData); root.lineColorsCache.reset(); } if (root.lineNormalsCache != null && root.lineNormalsCache.hasData()) { - root.copyLineNormals(root.lineNormalsCache.offset, root.lineNormalsCache.size, root.lineNormalsCache.data); + root.copyLineNormals(root.lineNormalsCache.offset, root.lineNormalsCache.size, root.lineNormalsCache.floatData); root.lineNormalsCache.reset(); } if (root.lineAttributesCache != null && root.lineAttributesCache.hasData()) { - root.copyLineAttributes(root.lineAttributesCache.offset, root.lineAttributesCache.size, root.lineAttributesCache.data); + root.copyLineAttributes(root.lineAttributesCache.offset, root.lineAttributesCache.size, root.lineAttributesCache.floatData); root.lineAttributesCache.reset(); } if (root.pointVerticesCache != null && root.pointVerticesCache.hasData()) { - root.copyPointVertices(root.pointVerticesCache.offset, root.pointVerticesCache.size, root.pointVerticesCache.data); + root.copyPointVertices(root.pointVerticesCache.offset, root.pointVerticesCache.size, root.pointVerticesCache.floatData); root.pointVerticesCache.reset(); } if (root.pointColorsCache != null && root.pointColorsCache.hasData()) { - root.copyPointColors(root.pointColorsCache.offset, root.pointColorsCache.size, root.pointColorsCache.data); + root.copyPointColors(root.pointColorsCache.offset, root.pointColorsCache.size, root.pointColorsCache.floatData); root.pointColorsCache.reset(); } if (root.pointNormalsCache != null && root.pointNormalsCache.hasData()) { - root.copyPointNormals(root.pointNormalsCache.offset, root.pointNormalsCache.size, root.pointNormalsCache.data); + root.copyPointNormals(root.pointNormalsCache.offset, root.pointNormalsCache.size, root.pointNormalsCache.floatData); root.pointNormalsCache.reset(); } if (root.pointAttributesCache != null && root.pointAttributesCache.hasData()) { - root.copyPointAttributes(root.pointAttributesCache.offset, root.pointAttributesCache.size, root.pointAttributesCache.data); + root.copyPointAttributes(root.pointAttributesCache.offset, root.pointAttributesCache.size, root.pointAttributesCache.floatData); root.pointAttributesCache.reset(); } } @@ -2861,20 +3097,36 @@ public class PShape3D extends PShape { protected void initFillBuffers(int nvert, int nind) { glFillVertexBufferID = pg.createVertexBufferObject(); pgl.bindVertexBuffer(glFillVertexBufferID); - pgl.initVertexBuffer(3 * nvert, glMode); + pgl.initFloatVertexBuffer(3 * nvert, glMode); glFillColorBufferID = pg.createVertexBufferObject(); pgl.bindVertexBuffer(glFillColorBufferID); - pgl.initVertexBuffer(4 * nvert, glMode); + pgl.initFloatVertexBuffer(4 * nvert, glMode); glFillNormalBufferID = pg.createVertexBufferObject(); pgl.bindVertexBuffer(glFillNormalBufferID); - pgl.initVertexBuffer(3 * nvert, glMode); + pgl.initFloatVertexBuffer(3 * nvert, glMode); glFillTexCoordBufferID = pg.createVertexBufferObject(); pgl.bindVertexBuffer(glFillTexCoordBufferID); - pgl.initVertexBuffer(2 * nvert, glMode); + pgl.initFloatVertexBuffer(2 * nvert, glMode); + glFillAmbientBufferID = pg.createVertexBufferObject(); + pgl.bindVertexBuffer(glFillAmbientBufferID); + pgl.initIntVertexBuffer(nvert, glMode); + + glFillSpecularBufferID = pg.createVertexBufferObject(); + pgl.bindVertexBuffer(glFillSpecularBufferID); + pgl.initIntVertexBuffer(nvert, glMode); + + glFillEmissiveBufferID = pg.createVertexBufferObject(); + pgl.bindVertexBuffer(glFillEmissiveBufferID); + pgl.initIntVertexBuffer(nvert, glMode); + + glFillShininessBufferID = pg.createVertexBufferObject(); + pgl.bindVertexBuffer(glFillShininessBufferID); + pgl.initFloatVertexBuffer(nvert, glMode); + pgl.unbindVertexBuffer(); glFillIndexBufferID = pg.createVertexBufferObject(); @@ -2894,7 +3146,8 @@ public class PShape3D extends PShape { } else { if (0 < tess.fillVertexCount && 0 < tess.fillIndexCount) { root.copyFillGeometry(root.fillVertCopyOffset, tess.fillVertexCount, - tess.fillVertices, tess.fillColors, tess.fillNormals, tess.fillTexcoords); + tess.fillVertices, tess.fillColors, tess.fillNormals, tess.fillTexcoords, + tess.fillAmbient, tess.fillSpecular, tess.fillEmissive, tess.fillShininess); root.fillVertCopyOffset += tess.fillVertexCount; root.copyFillIndices(root.fillIndCopyOffset, tess.fillIndexCount, tess.fillIndices); @@ -2915,92 +3168,136 @@ public class PShape3D extends PShape { if (0 < tess.fillVertexCount) { if (modifiedFillVertices) { if (root.fillVerticesCache == null) { - root.fillVerticesCache = new VertexCache(3); + root.fillVerticesCache = new VertexCache(3, true); } root.fillVerticesCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillVertices); modifiedFillVertices = false; } else if (root.fillVerticesCache != null && root.fillVerticesCache.hasData()) { - root.copyFillVertices(root.fillVerticesCache.offset, root.fillVerticesCache.size, root.fillVerticesCache.data); + root.copyFillVertices(root.fillVerticesCache.offset, root.fillVerticesCache.size, root.fillVerticesCache.floatData); root.fillVerticesCache.reset(); } if (modifiedFillColors) { if (root.fillColorsCache == null) { - root.fillColorsCache = new VertexCache(4); + root.fillColorsCache = new VertexCache(4, true); } root.fillColorsCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillColors); modifiedFillColors = false; } else if (root.fillColorsCache != null && root.fillColorsCache.hasData()) { - root.copyFillColors(root.fillColorsCache.offset, root.fillColorsCache.size, root.fillColorsCache.data); + root.copyFillColors(root.fillColorsCache.offset, root.fillColorsCache.size, root.fillColorsCache.floatData); root.fillColorsCache.reset(); } if (modifiedFillNormals) { if (root.fillNormalsCache == null) { - root.fillNormalsCache = new VertexCache(3); + root.fillNormalsCache = new VertexCache(3, true); } root.fillNormalsCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillNormals); modifiedFillNormals = false; } else if (root.fillNormalsCache != null && root.fillNormalsCache.hasData()) { - root.copyFillNormals(root.fillNormalsCache.offset, root.fillNormalsCache.size, root.fillNormalsCache.data); + root.copyFillNormals(root.fillNormalsCache.offset, root.fillNormalsCache.size, root.fillNormalsCache.floatData); root.fillNormalsCache.reset(); } if (modifiedFillTexCoords) { if (root.fillTexCoordsCache == null) { - root.fillTexCoordsCache = new VertexCache(2); + root.fillTexCoordsCache = new VertexCache(2, true); } root.fillTexCoordsCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillTexcoords); modifiedFillTexCoords = false; } else if (root.fillTexCoordsCache != null && root.fillTexCoordsCache.hasData()) { - root.copyFillTexCoords(root.fillTexCoordsCache.offset, root.fillTexCoordsCache.size, root.fillTexCoordsCache.data); + root.copyFillTexCoords(root.fillTexCoordsCache.offset, root.fillTexCoordsCache.size, root.fillTexCoordsCache.floatData); root.fillTexCoordsCache.reset(); - } + } + + if (modifiedFillAmbient) { + if (root.fillAmbientCache == null) { + root.fillAmbientCache = new VertexCache(1, false); + } + root.fillAmbientCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillAmbient); + modifiedFillAmbient = false; + } else if (root.fillAmbientCache != null && root.fillAmbientCache.hasData()) { + root.copyfillAmbient(root.fillAmbientCache.offset, root.fillAmbientCache.size, root.fillAmbientCache.intData); + root.fillAmbientCache.reset(); + } + + if (modifiedFillSpecular) { + if (root.fillSpecularCache == null) { + root.fillSpecularCache = new VertexCache(1, false); + } + root.fillSpecularCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillSpecular); + modifiedFillSpecular = false; + } else if (root.fillSpecularCache != null && root.fillSpecularCache.hasData()) { + root.copyfillSpecular(root.fillSpecularCache.offset, root.fillSpecularCache.size, root.fillSpecularCache.intData); + root.fillSpecularCache.reset(); + } + + if (modifiedFillEmissive) { + if (root.fillEmissiveCache == null) { + root.fillEmissiveCache = new VertexCache(1, false); + } + root.fillEmissiveCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillEmissive); + modifiedFillEmissive = false; + } else if (root.fillEmissiveCache != null && root.fillEmissiveCache.hasData()) { + root.copyfillEmissive(root.fillEmissiveCache.offset, root.fillEmissiveCache.size, root.fillEmissiveCache.intData); + root.fillEmissiveCache.reset(); + } + + if (modifiedFillShininess) { + if (root.fillShininessCache == null) { + root.fillShininessCache = new VertexCache(1, true); + } + root.fillShininessCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillShininess); + modifiedFillShininess = false; + } else if (root.fillShininessCache != null && root.fillShininessCache.hasData()) { + root.copyfillShininess(root.fillShininessCache.offset, root.fillShininessCache.size, root.fillShininessCache.floatData); + root.fillShininessCache.reset(); + } } if (0 < tess.lineVertexCount) { if (modifiedLineVertices) { if (root.lineVerticesCache == null) { - root.lineVerticesCache = new VertexCache(3); + root.lineVerticesCache = new VertexCache(3, true); } root.lineVerticesCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineVertices); modifiedLineVertices = false; } else if (root.lineVerticesCache != null && root.lineVerticesCache.hasData()) { - root.copyLineVertices(root.lineVerticesCache.offset, root.lineVerticesCache.size, root.lineVerticesCache.data); + root.copyLineVertices(root.lineVerticesCache.offset, root.lineVerticesCache.size, root.lineVerticesCache.floatData); root.lineVerticesCache.reset(); } if (modifiedLineColors) { if (root.lineColorsCache == null) { - root.lineColorsCache = new VertexCache(4); + root.lineColorsCache = new VertexCache(4, true); } root.lineColorsCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineColors); modifiedLineColors = false; } else if (root.lineColorsCache != null && root.lineColorsCache.hasData()) { - root.copyLineColors(root.lineColorsCache.offset, root.lineColorsCache.size, root.lineColorsCache.data); + root.copyLineColors(root.lineColorsCache.offset, root.lineColorsCache.size, root.lineColorsCache.floatData); root.lineColorsCache.reset(); } if (modifiedLineNormals) { if (root.lineNormalsCache == null) { - root.lineNormalsCache = new VertexCache(3); + root.lineNormalsCache = new VertexCache(3, true); } root.lineNormalsCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineNormals); modifiedLineNormals = false; } else if (root.lineNormalsCache != null && root.lineNormalsCache.hasData()) { - root.copyLineNormals(root.lineNormalsCache.offset, root.lineNormalsCache.size, root.lineNormalsCache.data); + root.copyLineNormals(root.lineNormalsCache.offset, root.lineNormalsCache.size, root.lineNormalsCache.floatData); root.lineNormalsCache.reset(); } if (modifiedLineAttributes) { if (root.lineAttributesCache == null) { - root.lineAttributesCache = new VertexCache(4); + root.lineAttributesCache = new VertexCache(4, true); } root.lineAttributesCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineAttributes); modifiedLineAttributes = false; } else if (root.lineAttributesCache != null && root.lineAttributesCache.hasData()) { - root.copyLineAttributes(root.lineAttributesCache.offset, root.lineAttributesCache.size, root.lineAttributesCache.data); + root.copyLineAttributes(root.lineAttributesCache.offset, root.lineAttributesCache.size, root.lineAttributesCache.floatData); root.lineAttributesCache.reset(); } } @@ -3008,45 +3305,45 @@ public class PShape3D extends PShape { if (0 < tess.pointVertexCount) { if (modifiedPointVertices) { if (root.pointVerticesCache == null) { - root.pointVerticesCache = new VertexCache(3); + root.pointVerticesCache = new VertexCache(3, true); } root.pointVerticesCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointVertices); modifiedPointVertices = false; } else if (root.pointVerticesCache != null && root.pointVerticesCache.hasData()) { - root.copyPointVertices(root.pointVerticesCache.offset, root.pointVerticesCache.size, root.pointVerticesCache.data); + root.copyPointVertices(root.pointVerticesCache.offset, root.pointVerticesCache.size, root.pointVerticesCache.floatData); root.pointVerticesCache.reset(); } if (modifiedPointColors) { if (root.pointColorsCache == null) { - root.pointColorsCache = new VertexCache(4); + root.pointColorsCache = new VertexCache(4, true); } root.pointColorsCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointColors); modifiedPointColors = false; } else if (root.pointColorsCache != null && root.pointColorsCache.hasData()) { - root.copyPointColors(root.pointColorsCache.offset, root.pointColorsCache.size, root.pointColorsCache.data); + root.copyPointColors(root.pointColorsCache.offset, root.pointColorsCache.size, root.pointColorsCache.floatData); root.pointColorsCache.reset(); } if (modifiedPointNormals) { if (root.pointNormalsCache == null) { - root.pointNormalsCache = new VertexCache(3); + root.pointNormalsCache = new VertexCache(3, true); } root.pointNormalsCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointNormals); modifiedPointNormals = false; } else if (root.pointNormalsCache != null && root.pointNormalsCache.hasData()) { - root.copyPointNormals(root.pointNormalsCache.offset, root.pointNormalsCache.size, root.pointNormalsCache.data); + root.copyPointNormals(root.pointNormalsCache.offset, root.pointNormalsCache.size, root.pointNormalsCache.floatData); root.pointNormalsCache.reset(); } if (modifiedPointAttributes) { if (root.pointAttributesCache == null) { - root.pointAttributesCache = new VertexCache(2); + root.pointAttributesCache = new VertexCache(2, true); } root.pointAttributesCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointAttributes); modifiedPointAttributes = false; } else if (root.pointAttributesCache != null && root.pointAttributesCache.hasData()) { - root.copyPointAttributes(root.pointAttributesCache.offset, root.pointAttributesCache.size, root.pointAttributesCache.data); + root.copyPointAttributes(root.pointAttributesCache.offset, root.pointAttributesCache.size, root.pointAttributesCache.floatData); root.pointAttributesCache.reset(); } } @@ -3062,7 +3359,8 @@ public class PShape3D extends PShape { protected void copyFillGeometry(int offset, int size, float[] vertices, float[] colors, - float[] normals, float[] texcoords) { + float[] normals, float[] texcoords, + int[] ambient, int[] specular, int[] emissive, float[] shininess) { pgl.bindVertexBuffer(glFillVertexBufferID); pgl.copyVertexBufferSubData(vertices, 3 * offset, 3 * size, glMode); @@ -3073,8 +3371,20 @@ public class PShape3D extends PShape { pgl.copyVertexBufferSubData(normals, 3 * offset, 3 * size, glMode); pgl.bindVertexBuffer(glFillTexCoordBufferID); - pgl.copyVertexBufferSubData(texcoords, 2 * offset, 2 * size, glMode); + pgl.copyVertexBufferSubData(texcoords, 2 * offset, 2 * size, glMode); + pgl.bindVertexBuffer(glFillAmbientBufferID); + pgl.copyVertexBufferSubData(ambient, offset, size, glMode); + + pgl.bindVertexBuffer(glFillSpecularBufferID); + pgl.copyVertexBufferSubData(specular, offset, size, glMode); + + pgl.bindVertexBuffer(glFillEmissiveBufferID); + pgl.copyVertexBufferSubData(normals, offset, size, glMode); + + pgl.bindVertexBuffer(glFillShininessBufferID); + pgl.copyVertexBufferSubData(shininess, offset, size, glMode); + pgl.unbindVertexBuffer(); } @@ -3105,6 +3415,34 @@ public class PShape3D extends PShape { pgl.copyVertexBufferSubData(texcoords, 2 * offset, 2 * size, glMode); pgl.unbindVertexBuffer(); } + + + protected void copyfillAmbient(int offset, int size, int[] ambient) { + pgl.bindVertexBuffer(glFillAmbientBufferID); + pgl.copyVertexBufferSubData(ambient, offset, size, glMode); + pgl.unbindVertexBuffer(); + } + + + protected void copyfillSpecular(int offset, int size, int[] specular) { + pgl.bindVertexBuffer(glFillSpecularBufferID); + pgl.copyVertexBufferSubData(specular, offset, size, glMode); + pgl.unbindVertexBuffer(); + } + + + protected void copyfillEmissive(int offset, int size, int[] emissive) { + pgl.bindVertexBuffer(glFillEmissiveBufferID); + pgl.copyVertexBufferSubData(emissive, offset, size, glMode); + pgl.unbindVertexBuffer(); + } + + + protected void copyfillShininess(int offset, int size, float[] shininess) { + pgl.bindVertexBuffer(glFillShininessBufferID); + pgl.copyVertexBufferSubData(shininess, offset, size, glMode); + pgl.unbindVertexBuffer(); + } protected void copyFillIndices(int offset, int size, short[] indices) { @@ -3117,19 +3455,19 @@ public class PShape3D extends PShape { protected void initLineBuffers(int nvert, int nind) { glLineVertexBufferID = pg.createVertexBufferObject(); pgl.bindVertexBuffer(glLineVertexBufferID); - pgl.initVertexBuffer(3 * nvert, glMode); + pgl.initFloatVertexBuffer(3 * nvert, glMode); glLineColorBufferID = pg.createVertexBufferObject(); pgl.bindVertexBuffer(glLineColorBufferID); - pgl.initVertexBuffer(4 * nvert, glMode); + pgl.initFloatVertexBuffer(4 * nvert, glMode); glLineNormalBufferID = pg.createVertexBufferObject(); pgl.bindVertexBuffer(glLineNormalBufferID); - pgl.initVertexBuffer(3 * nvert, glMode); + pgl.initFloatVertexBuffer(3 * nvert, glMode); glLineAttribBufferID = pg.createVertexBufferObject(); pgl.bindVertexBuffer(glLineAttribBufferID); - pgl.initVertexBuffer(4 * nvert, glMode); + pgl.initFloatVertexBuffer(4 * nvert, glMode); pgl.unbindVertexBuffer(); @@ -3216,19 +3554,19 @@ public class PShape3D extends PShape { protected void initPointBuffers(int nvert, int nind) { glPointVertexBufferID = pg.createVertexBufferObject(); pgl.bindVertexBuffer(glPointVertexBufferID); - pgl.initVertexBuffer(3 * nvert, glMode); + pgl.initFloatVertexBuffer(3 * nvert, glMode); glPointColorBufferID = pg.createVertexBufferObject(); pgl.bindVertexBuffer(glPointColorBufferID); - pgl.initVertexBuffer(4 * nvert, glMode); + pgl.initFloatVertexBuffer(4 * nvert, glMode); glPointNormalBufferID = pg.createVertexBufferObject(); pgl.bindVertexBuffer(glPointNormalBufferID); - pgl.initVertexBuffer(3 * nvert, glMode); + pgl.initFloatVertexBuffer(3 * nvert, glMode); glPointAttribBufferID = pg.createVertexBufferObject(); pgl.bindVertexBuffer(glPointAttribBufferID); - pgl.initVertexBuffer(2 * nvert, glMode); + pgl.initFloatVertexBuffer(2 * nvert, glMode); pgl.unbindVertexBuffer(); @@ -3346,6 +3684,26 @@ public class PShape3D extends PShape { pg.deleteVertexBufferObject(glFillTexCoordBufferID); glFillTexCoordBufferID = 0; } + + if (glFillAmbientBufferID != 0) { + pg.deleteVertexBufferObject(glFillAmbientBufferID); + glFillAmbientBufferID = 0; + } + + if (glFillSpecularBufferID != 0) { + pg.deleteVertexBufferObject(glFillSpecularBufferID); + glFillSpecularBufferID = 0; + } + + if (glFillEmissiveBufferID != 0) { + pg.deleteVertexBufferObject(glFillEmissiveBufferID); + glFillEmissiveBufferID = 0; + } + + if (glFillShininessBufferID != 0) { + pg.deleteVertexBufferObject(glFillShininessBufferID); + glFillShininessBufferID = 0; + } if (glFillIndexBufferID != 0) { pg.deleteVertexBufferObject(glFillIndexBufferID); @@ -3659,14 +4017,22 @@ public class PShape3D extends PShape { // Internal class to store a cache of vertex data used to copy data // to the VBOs with fewer calls. protected class VertexCache { + boolean isFloat; int ncoords; int offset; int size; - float[] data; + float[] floatData; + int[] intData; - VertexCache(int ncoords) { + VertexCache(int ncoords, boolean isFloat) { this.ncoords = ncoords; - this.data = new float[ncoords * PGL.DEFAULT_VERTEX_CACHE_SIZE]; + this.isFloat = isFloat; + if (isFloat) { + this.floatData = new float[ncoords * PGL.DEFAULT_VERTEX_CACHE_SIZE]; + + } else { + this.intData = new int[ncoords * PGL.DEFAULT_VERTEX_CACHE_SIZE]; + } this.offset = 0; this.size = 0; } @@ -3681,7 +4047,7 @@ public class PShape3D extends PShape { offset = dataOffset; } - int oldSize = data.length / ncoords; + int oldSize = floatData.length / ncoords; if (size + dataSize >= oldSize) { int newSize = expandSize(oldSize, size + dataSize); expand(newSize); @@ -3695,25 +4061,68 @@ public class PShape3D extends PShape { int destIndex = ncoords * (size + i); if (ncoords == 2) { - data[destIndex++] = newData[srcIndex++]; - data[destIndex ] = newData[srcIndex ]; + floatData[destIndex++] = newData[srcIndex++]; + floatData[destIndex ] = newData[srcIndex ]; } else if (ncoords == 3) { - data[destIndex++] = newData[srcIndex++]; - data[destIndex++] = newData[srcIndex++]; - data[destIndex ] = newData[srcIndex ]; + floatData[destIndex++] = newData[srcIndex++]; + floatData[destIndex++] = newData[srcIndex++]; + floatData[destIndex ] = newData[srcIndex ]; } else if (ncoords == 4) { - data[destIndex++] = newData[srcIndex++]; - data[destIndex++] = newData[srcIndex++]; - data[destIndex++] = newData[srcIndex++]; - data[destIndex ] = newData[srcIndex ]; + floatData[destIndex++] = newData[srcIndex++]; + floatData[destIndex++] = newData[srcIndex++]; + floatData[destIndex++] = newData[srcIndex++]; + floatData[destIndex ] = newData[srcIndex ]; } else { for (int j = 0; j < ncoords; j++) { - data[destIndex++] = newData[srcIndex++]; + floatData[destIndex++] = newData[srcIndex++]; } } } } else { - PApplet.arrayCopy(newData, 0, data, ncoords * size, ncoords * dataSize); + PApplet.arrayCopy(newData, 0, floatData, ncoords * size, ncoords * dataSize); + } + + size += dataSize; + } + + void add(int dataOffset, int dataSize, int[] newData) { + if (size == 0) { + offset = dataOffset; + } + + int oldSize = intData.length / ncoords; + if (size + dataSize >= oldSize) { + int newSize = expandSize(oldSize, size + dataSize); + expand(newSize); + } + + if (dataSize <= PGraphicsAndroid3D.MIN_ARRAYCOPY_SIZE) { + // Copying elements one by one instead of using arrayCopy is more efficient for + // few vertices... + for (int i = 0; i < dataSize; i++) { + int srcIndex = ncoords * i; + int destIndex = ncoords * (size + i); + + if (ncoords == 2) { + intData[destIndex++] = newData[srcIndex++]; + intData[destIndex ] = newData[srcIndex ]; + } else if (ncoords == 3) { + intData[destIndex++] = newData[srcIndex++]; + intData[destIndex++] = newData[srcIndex++]; + intData[destIndex ] = newData[srcIndex ]; + } else if (ncoords == 4) { + intData[destIndex++] = newData[srcIndex++]; + intData[destIndex++] = newData[srcIndex++]; + intData[destIndex++] = newData[srcIndex++]; + intData[destIndex ] = newData[srcIndex ]; + } else { + for (int j = 0; j < ncoords; j++) { + intData[destIndex++] = newData[srcIndex++]; + } + } + } + } else { + PApplet.arrayCopy(newData, 0, intData, ncoords * size, ncoords * dataSize); } size += dataSize; @@ -3733,7 +4142,7 @@ public class PShape3D extends PShape { offset = dataOffset; } - int oldSize = data.length / ncoords; + int oldSize = floatData.length / ncoords; if (size + dataSize >= oldSize) { int newSize = expandSize(oldSize, size + dataSize); expand(newSize); @@ -3746,8 +4155,8 @@ public class PShape3D extends PShape { float y = newData[srcIndex ]; int destIndex = ncoords * (size + i); - data[destIndex++] = x * tr.m00 + y * tr.m01 + tr.m02; - data[destIndex ] = x * tr.m10 + y * tr.m11 + tr.m12; + floatData[destIndex++] = x * tr.m00 + y * tr.m01 + tr.m02; + floatData[destIndex ] = x * tr.m10 + y * tr.m11 + tr.m12; } } @@ -3759,7 +4168,7 @@ public class PShape3D extends PShape { offset = dataOffset; } - int oldSize = data.length / ncoords; + int oldSize = floatData.length / ncoords; if (size + dataSize >= oldSize) { int newSize = expandSize(oldSize, size + dataSize); expand(newSize); @@ -3773,9 +4182,9 @@ public class PShape3D extends PShape { float z = newData[srcIndex++]; int destIndex = ncoords * (size + i); - data[destIndex++] = x * tr.m00 + y * tr.m01 + z * tr.m02 + tr.m03; - data[destIndex++] = x * tr.m10 + y * tr.m11 + z * tr.m12 + tr.m13; - data[destIndex ] = x * tr.m20 + y * tr.m21 + z * tr.m22 + tr.m23; + floatData[destIndex++] = x * tr.m00 + y * tr.m01 + z * tr.m02 + tr.m03; + floatData[destIndex++] = x * tr.m10 + y * tr.m11 + z * tr.m12 + tr.m13; + floatData[destIndex ] = x * tr.m20 + y * tr.m21 + z * tr.m22 + tr.m23; } } @@ -3783,9 +4192,23 @@ public class PShape3D extends PShape { } void expand(int n) { + if (isFloat) { + expandFloat(n); + } else { + expandInt(n); + } + } + + void expandFloat(int n) { float temp[] = new float[ncoords * n]; - PApplet.arrayCopy(data, 0, temp, 0, ncoords * size); - data = temp; + PApplet.arrayCopy(floatData, 0, temp, 0, ncoords * size); + floatData = temp; + } + + void expandInt(int n) { + int temp[] = new int[ncoords * n]; + PApplet.arrayCopy(intData, 0, temp, 0, ncoords * size); + intData = temp; } int expandSize(int currSize, int newMinSize) {