From 6ba65dc2e33fc7e5dcbcfbdf6939ba7dc743aa4c Mon Sep 17 00:00:00 2001 From: codeanticode Date: Wed, 14 Mar 2012 20:24:03 +0000 Subject: [PATCH] Using buffers instead of arrays in P3D library as well --- .../opengl/src/processing/opengl/PGL.java | 85 +- .../processing/opengl/PGraphicsOpenGL.java | 1391 +++++++++-------- .../opengl/src/processing/opengl/PShader.java | 66 +- .../src/processing/opengl/PShape3D.java | 567 ++++--- .../src/processing/opengl/PTexture.java | 20 +- 5 files changed, 1228 insertions(+), 901 deletions(-) diff --git a/java/libraries/opengl/src/processing/opengl/PGL.java b/java/libraries/opengl/src/processing/opengl/PGL.java index 7ea8d0c06..c58f76d32 100644 --- a/java/libraries/opengl/src/processing/opengl/PGL.java +++ b/java/libraries/opengl/src/processing/opengl/PGL.java @@ -26,6 +26,7 @@ package processing.opengl; import java.nio.Buffer; import java.nio.ByteBuffer; +import java.nio.FloatBuffer; import java.nio.IntBuffer; import javax.media.nativewindow.GraphicsConfigurationFactory; @@ -428,8 +429,8 @@ public class PGL { return gl.glGetString(name); } - public void glGetIntegerv(int name, int[] values, int offset) { - gl.glGetIntegerv(name, values, offset); + public void glGetIntegerv(int name, IntBuffer values) { + gl.glGetIntegerv(name, values); } /////////////////////////////////////////////////////////////////////////////////// @@ -497,12 +498,14 @@ public class PGL { // Textures - public void glGenTextures(int n, int[] ids, int offset) { - gl.glGenTextures(n, ids, offset); + public void glGenTextures(int n, IntBuffer ids) { + ids.limit(n); + gl.glGenTextures(n, ids); } - public void glDeleteTextures(int n, int[] ids, int offset) { - gl.glDeleteTextures(n, ids, offset); + public void glDeleteTextures(int n, IntBuffer ids) { + ids.limit(n); + gl.glDeleteTextures(n, ids); } public void glActiveTexture(int unit) { @@ -533,12 +536,14 @@ public class PGL { // Vertex Buffers - public void glGenBuffers(int n, int[] ids, int offset) { - gl.glGenBuffers(n, ids, offset); + public void glGenBuffers(int n, IntBuffer ids) { + ids.limit(n); + gl.glGenBuffers(n, ids); } - public void glDeleteBuffers(int n, int[] ids, int offset) { - gl.glDeleteBuffers(n, ids, offset); + public void glDeleteBuffers(int n, IntBuffer ids) { + ids.limit(n); + gl.glDeleteBuffers(n, ids); } public void glBindBuffer(int target, int id) { @@ -588,20 +593,24 @@ public class PGL { // Framebuffers, renderbuffers - public void glGenFramebuffers(int n, int[] ids, int offset) { - gl.glGenFramebuffers(n, ids, offset); + public void glGenFramebuffers(int n, IntBuffer ids) { + ids.limit(n); + gl.glGenFramebuffers(n, ids); } - public void glDeleteFramebuffers(int n, int[] ids, int offset) { - gl.glDeleteFramebuffers(n, ids, offset); + public void glDeleteFramebuffers(int n, IntBuffer ids) { + ids.limit(n); + gl.glDeleteFramebuffers(n, ids); } - public void glGenRenderbuffers(int n, int[] ids, int offset) { - gl.glGenRenderbuffers(n, ids, offset); + public void glGenRenderbuffers(int n, IntBuffer ids) { + ids.limit(n); + gl.glGenRenderbuffers(n, ids); } - public void glDeleteRenderbuffers(int n, int[] ids, int offset) { - gl.glDeleteRenderbuffers(n, ids, offset); + public void glDeleteRenderbuffers(int n, IntBuffer ids) { + ids.limit(n); + gl.glDeleteRenderbuffers(n, ids); } public void glBindFramebuffer(int target, int id) { @@ -696,32 +705,32 @@ public class PGL { gl2.glUniform4f(loc, value0, value1, value2, value3); } - public void glUniform1fv(int loc, int count, float[] v, int offset) { - gl2.glUniform1fv(loc, count, v, offset); + public void glUniform1fv(int loc, int count, FloatBuffer v) { + gl2.glUniform1fv(loc, count, v); } - public void glUniform2fv(int loc, int count, float[] v, int offset) { - gl2.glUniform2fv(loc, count, v, offset); + public void glUniform2fv(int loc, int count, FloatBuffer v) { + gl2.glUniform2fv(loc, count, v); } - public void glUniform3fv(int loc, int count, float[] v, int offset) { - gl2.glUniform3fv(loc, count, v, offset); + public void glUniform3fv(int loc, int count, FloatBuffer v) { + gl2.glUniform3fv(loc, count, v); } - public void glUniform4fv(int loc, int count, float[] v, int offset) { - gl2.glUniform4fv(loc, count, v, offset); + public void glUniform4fv(int loc, int count, FloatBuffer v) { + gl2.glUniform4fv(loc, count, v); } - public void glUniformMatrix2fv(int loc, int count, boolean transpose, float[] mat, int offset) { - gl2.glUniformMatrix2fv(loc, count, transpose, mat, offset); + public void glUniformMatrix2fv(int loc, int count, boolean transpose, FloatBuffer mat) { + gl2.glUniformMatrix2fv(loc, count, transpose, mat); } - public void glUniformMatrix3fv(int loc, int count, boolean transpose, float[] mat, int offset) { - gl2.glUniformMatrix3fv(loc, count, transpose, mat, offset); + public void glUniformMatrix3fv(int loc, int count, boolean transpose, FloatBuffer mat) { + gl2.glUniformMatrix3fv(loc, count, transpose, mat); } - public void glUniformMatrix4fv(int loc, int count, boolean transpose, float[] mat, int offset) { - gl2.glUniformMatrix4fv(loc, count, transpose, mat, offset); + public void glUniformMatrix4fv(int loc, int count, boolean transpose, FloatBuffer mat) { + gl2.glUniformMatrix4fv(loc, count, transpose, mat); } public void glVertexAttrib1f(int loc, float value) { @@ -916,6 +925,14 @@ public class PGL { // Utility functions + public FloatBuffer createFloatBuffer(int size) { + return FloatBuffer.allocate(size); + } + + public IntBuffer createIntBuffer(int size) { + return IntBuffer.allocate(size); + } + public boolean contextIsCurrent(Context other) { return other.same(context); } @@ -933,8 +950,8 @@ public class PGL { } public void initTexture(int target, int width, int height, int format, int type) { - int[] texels = new int[width * height]; - gl.glTexSubImage2D(target, 0, 0, 0, width, height, format, type, IntBuffer.wrap(texels)); + IntBuffer texels = createIntBuffer(width * height); + gl.glTexSubImage2D(target, 0, 0, 0, width, height, format, type, texels); } public String getShaderLog(int id) { diff --git a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java index 9a0f662bb..f753224af 100644 --- a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java +++ b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java @@ -311,8 +311,8 @@ public class PGraphicsOpenGL extends PGraphics { protected boolean resized = false; /** Stores previous viewport dimensions. */ - protected int[] savedViewport = {0, 0, 0, 0}; - protected int[] viewport = {0, 0, 0, 0}; + protected IntBuffer savedViewport; + protected IntBuffer viewport; /** Used to register calls to glClear. */ protected boolean clearColorBuffer; @@ -323,6 +323,9 @@ public class PGraphicsOpenGL extends PGraphics { protected boolean defaultEdges = false; protected PImage textureImage0; + /** To get data from OpenGL. */ + protected IntBuffer getBuffer; + // ........................................................ // Drawing surface: @@ -375,8 +378,7 @@ public class PGraphicsOpenGL extends PGraphics { // Constants - protected static int flushMode = FLUSH_WHEN_FULL; - protected static final int MIN_ARRAYCOPY_SIZE = 2; + protected static int flushMode = FLUSH_WHEN_FULL; protected int vboMode = PGL.GL_STATIC_DRAW; static public float FLOAT_EPS = Float.MIN_VALUE; @@ -406,6 +408,9 @@ public class PGraphicsOpenGL extends PGraphics { public PGraphicsOpenGL() { pgl = new PGL(this); + getBuffer = pgl.createIntBuffer(16); + viewport = pgl.createIntBuffer(16); + savedViewport = pgl.createIntBuffer(16); tessellator = new Tessellator(); inGeo = newInGeometry(IMMEDIATE); @@ -556,9 +561,8 @@ public class PGraphicsOpenGL extends PGraphics { protected int createTextureObject() { deleteFinalizedTextureObjects(); - int[] temp = new int[1]; - pgl.glGenTextures(1, temp, 0); - int id = temp[0]; + pgl.glGenTextures(1, getBuffer); + int id = getBuffer.get(0); if (glTextureObjects.containsKey(id)) { showWarning("Adding same texture twice"); @@ -571,16 +575,16 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteTextureObject(int id) { if (glTextureObjects.containsKey(id)) { - int[] temp = { id }; - pgl.glDeleteTextures(1, temp, 0); + getBuffer.put(0, id); + pgl.glDeleteTextures(1, getBuffer); glTextureObjects.remove(id); } } protected void deleteAllTextureObjects() { for (Integer id : glTextureObjects.keySet()) { - int[] temp = { id.intValue() }; - pgl.glDeleteTextures(1, temp, 0); + getBuffer.put(0, id.intValue()); + pgl.glDeleteTextures(1, getBuffer); } glTextureObjects.clear(); } @@ -600,8 +604,8 @@ public class PGraphicsOpenGL extends PGraphics { for (Integer id : glTextureObjects.keySet()) { if (glTextureObjects.get(id)) { finalized.add(id); - int[] temp = { id.intValue() }; - pgl.glDeleteTextures(1, temp, 0); + getBuffer.put(0, id.intValue()); + pgl.glDeleteTextures(1, getBuffer); } } @@ -615,9 +619,8 @@ public class PGraphicsOpenGL extends PGraphics { protected int createVertexBufferObject() { deleteFinalizedVertexBufferObjects(); - int[] temp = new int[1]; - pgl.glGenBuffers(1, temp, 0); - int id = temp[0]; + pgl.glGenBuffers(1, getBuffer); + int id = getBuffer.get(0); if (glVertexBuffers.containsKey(id)) { showWarning("Adding same VBO twice"); @@ -630,16 +633,16 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteVertexBufferObject(int id) { if (glVertexBuffers.containsKey(id)) { - int[] temp = { id }; - pgl.glDeleteBuffers(1, temp, 0); + getBuffer.put(0, id); + pgl.glDeleteBuffers(1, getBuffer); glVertexBuffers.remove(id); } } protected void deleteAllVertexBufferObjects() { for (Integer id : glVertexBuffers.keySet()) { - int[] temp = { id.intValue() }; - pgl.glDeleteBuffers(1, temp, 0); + getBuffer.put(0, id.intValue()); + pgl.glDeleteBuffers(1, getBuffer); } glVertexBuffers.clear(); } @@ -659,8 +662,8 @@ public class PGraphicsOpenGL extends PGraphics { for (Integer id : glVertexBuffers.keySet()) { if (glVertexBuffers.get(id)) { finalized.add(id); - int[] temp = { id.intValue() }; - pgl.glDeleteBuffers(1, temp, 0); + getBuffer.put(0, id.intValue()); + pgl.glDeleteBuffers(1, getBuffer); } } @@ -674,9 +677,8 @@ public class PGraphicsOpenGL extends PGraphics { protected int createFrameBufferObject() { deleteFinalizedFrameBufferObjects(); - int[] temp = new int[1]; - pgl.glGenFramebuffers(1, temp, 0); - int id = temp[0]; + pgl.glGenFramebuffers(1, getBuffer); + int id = getBuffer.get(0); if (glFrameBuffers.containsKey(id)) { showWarning("Adding same FBO twice"); @@ -689,16 +691,16 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteFrameBufferObject(int id) { if (glFrameBuffers.containsKey(id)) { - int[] temp = { id }; - pgl.glDeleteFramebuffers(1, temp, 0); + getBuffer.put(0, id); + pgl.glDeleteFramebuffers(1, getBuffer); glFrameBuffers.remove(id); } } protected void deleteAllFrameBufferObjects() { for (Integer id : glFrameBuffers.keySet()) { - int[] temp = { id.intValue() }; - pgl.glDeleteFramebuffers(1, temp, 0); + getBuffer.put(0, id.intValue()); + pgl.glDeleteFramebuffers(1, getBuffer); } glFrameBuffers.clear(); } @@ -718,8 +720,8 @@ public class PGraphicsOpenGL extends PGraphics { for (Integer id : glFrameBuffers.keySet()) { if (glFrameBuffers.get(id)) { finalized.add(id); - int[] temp = { id.intValue() }; - pgl.glDeleteFramebuffers(1, temp, 0); + getBuffer.put(0, id.intValue()); + pgl.glDeleteFramebuffers(1, getBuffer); } } @@ -733,9 +735,8 @@ public class PGraphicsOpenGL extends PGraphics { protected int createRenderBufferObject() { deleteFinalizedRenderBufferObjects(); - int[] temp = new int[1]; - pgl.glDeleteRenderbuffers(1, temp, 0); - int id = temp[0]; + pgl.glDeleteRenderbuffers(1, getBuffer); + int id = getBuffer.get(0); if (glRenderBuffers.containsKey(id)) { showWarning("Adding same renderbuffer twice"); @@ -748,16 +749,16 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteRenderBufferObject(int id) { if (glRenderBuffers.containsKey(id)) { - int[] temp = { id }; - pgl.glGenRenderbuffers(1, temp, 0); + getBuffer.put(0, id); + pgl.glGenRenderbuffers(1, getBuffer); glRenderBuffers.remove(id); } } protected void deleteAllRenderBufferObjects() { for (Integer id : glRenderBuffers.keySet()) { - int[] temp = { id.intValue() }; - pgl.glDeleteRenderbuffers(1, temp, 0); + getBuffer.put(0, id.intValue()); + pgl.glDeleteRenderbuffers(1, getBuffer); } glRenderBuffers.clear(); } @@ -777,8 +778,8 @@ public class PGraphicsOpenGL extends PGraphics { for (Integer id : glRenderBuffers.keySet()) { if (glRenderBuffers.get(id)) { finalized.add(id); - int[] temp = { id.intValue() }; - pgl.glDeleteRenderbuffers(1, temp, 0); + getBuffer.put(0, id.intValue()); + pgl.glDeleteRenderbuffers(1, getBuffer); } } @@ -1138,36 +1139,48 @@ public class PGraphicsOpenGL extends PGraphics { int sizef = size * PGL.SIZEOF_FLOAT; int sizei = size * PGL.SIZEOF_INT; + tessGeo.prepareFillVerticesForCopy(); + 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, tessGeo.fillVertices, vboMode); 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, tessGeo.fillColors, vboMode); 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, tessGeo.fillNormals, vboMode); 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, tessGeo.fillAmbient, vboMode); 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, tessGeo.fillSpecular, vboMode); 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, tessGeo.fillEmissive, vboMode); 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, tessGeo.fillShininess, vboMode); } 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, tessGeo.fillTexcoords, vboMode); } + + tessGeo.prepareFillIndicesForCopy(); + + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glFillIndexBufferID); + pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, tessGeo.fillIndexCount * PGL.SIZEOF_INDEX, + tessGeo.fillIndices, vboMode); } + protected void unbindFillBuffers(boolean lit, boolean tex) { + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); + } + protected void releaseFillBuffers() { deleteVertexBufferObject(glFillVertexBufferID); glFillVertexBufferID = 0; @@ -1229,14 +1242,27 @@ public class PGraphicsOpenGL extends PGraphics { int sizef = size * PGL.SIZEOF_FLOAT; int sizei = size * PGL.SIZEOF_INT; + tessGeo.prepareLineVerticesForCopy(); + 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, tessGeo.lineVertices, vboMode); 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, tessGeo.lineColors, vboMode); 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, tessGeo.lineDirWidths, vboMode); + + tessGeo.prepareLineIndicesForCopy(); + + int sizex = size * PGL.SIZEOF_INDEX; + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glLineIndexBufferID); + pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, tessGeo.lineIndices, vboMode); + } + + protected void unbindLineBuffers() { + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } protected void releaseLineBuffers() { @@ -1284,16 +1310,29 @@ public class PGraphicsOpenGL extends PGraphics { int sizef = size * PGL.SIZEOF_FLOAT; int sizei = size * PGL.SIZEOF_INT; + tessGeo.preparePointVerticesForCopy(); + 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, tessGeo.pointVertices, vboMode); 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, tessGeo.pointColors, vboMode); 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, tessGeo.pointSizes, vboMode); + + tessGeo.preparePointIndicesForCopy(); + + int sizex = size * PGL.SIZEOF_INDEX; + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glPointIndexBufferID); + pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, tessGeo.pointIndices, vboMode); } + protected void unbindPointBuffers() { + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); + } + protected void releasePointBuffers() { deleteVertexBufferObject(glPointVertexBufferID); glPointVertexBufferID = 0; @@ -1375,9 +1414,9 @@ public class PGraphicsOpenGL extends PGraphics { //pg.disableLights(); } - inGeo.reset(); - tessGeo.reset(); - texCache.reset(); + inGeo.clear(); + tessGeo.clear(); + texCache.clear(); // Each frame starts with textures disabled. super.noTexture(); @@ -1410,9 +1449,9 @@ public class PGraphicsOpenGL extends PGraphics { } // setup opengl viewport. - pgl.glGetIntegerv(PGL.GL_VIEWPORT, savedViewport, 0); - viewport[0] = 0; viewport[1] = 0; viewport[2] = width; viewport[3] = height; - pgl.glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + pgl.glGetIntegerv(PGL.GL_VIEWPORT, savedViewport); + viewport.put(0, 0); viewport.put(1, 0); viewport.put(2, width); viewport.put(3, height); + pgl.glViewport(viewport.get(0), viewport.get(1), viewport.get(2), viewport.get(3)); if (resized) { // To avoid having garbage in the screen after a resize, // in the case background is not called in draw(). @@ -1499,7 +1538,7 @@ public class PGraphicsOpenGL extends PGraphics { } // Restoring previous viewport. - pgl.glViewport(savedViewport[0], savedViewport[1], savedViewport[2], savedViewport[3]); + pgl.glViewport(savedViewport.get(0), savedViewport.get(1), savedViewport.get(2), savedViewport.get(3)); if (primarySurface) { pgl.glFlush(); @@ -1548,7 +1587,7 @@ public class PGraphicsOpenGL extends PGraphics { protected void restoreGLState() { // Restoring viewport. - pgl.glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + pgl.glViewport(viewport.get(0), viewport.get(1), viewport.get(2), viewport.get(3)); // Restoring hints. if (hints[DISABLE_DEPTH_TEST]) { @@ -1917,7 +1956,7 @@ public class PGraphicsOpenGL extends PGraphics { public void beginShape(int kind) { shape = kind; - inGeo.reset(); + inGeo.clear(); breakShape = false; defaultEdges = true; @@ -2215,8 +2254,8 @@ public class PGraphicsOpenGL extends PGraphics { } } - tessGeo.reset(); - texCache.reset(); + tessGeo.clear(); + texCache.clear(); } @@ -2233,14 +2272,10 @@ public class PGraphicsOpenGL extends PGraphics { shader.setColorAttribute(glPointColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); shader.setSizeAttribute(glPointSizeBufferID, 2, PGL.GL_FLOAT, 0, 0); - int size = tessGeo.pointIndexCount; - int sizex = size * PGL.SIZEOF_INDEX; - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glPointIndexBufferID); - pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, IntBuffer.wrap(tessGeo.pointIndices, 0, size), vboMode); - pgl.glDrawElements(PGL.GL_TRIANGLES, size, PGL.INDEX_TYPE, 0); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); + pgl.glDrawElements(PGL.GL_TRIANGLES, tessGeo.pointIndexCount, PGL.INDEX_TYPE, 0); shader.stop(); + unbindPointBuffers(); } protected void renderLines() { @@ -2256,14 +2291,10 @@ public class PGraphicsOpenGL extends PGraphics { shader.setColorAttribute(glLineColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); shader.setDirWidthAttribute(glLineDirWidthBufferID, 4, PGL.GL_FLOAT, 0, 0); - int size = tessGeo.lineIndexCount; - int sizex = size * PGL.SIZEOF_INDEX; - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glLineIndexBufferID); - pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, IntBuffer.wrap(tessGeo.lineIndices, 0, size), vboMode); - pgl.glDrawElements(PGL.GL_TRIANGLES, size, PGL.INDEX_TYPE, 0); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); + pgl.glDrawElements(PGL.GL_TRIANGLES, tessGeo.lineIndexCount, PGL.INDEX_TYPE, 0); shader.stop(); + unbindLineBuffers(); } @@ -2271,13 +2302,9 @@ public class PGraphicsOpenGL extends PGraphics { if (!fillVBOsCreated) { createFillBuffers(); fillVBOsCreated = true; - } + } updateFillBuffers(lights, texCache.hasTexture); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glFillIndexBufferID); - pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, tessGeo.fillIndexCount * PGL.SIZEOF_INDEX, - IntBuffer.wrap(tessGeo.fillIndices, 0, tessGeo.fillIndexCount), vboMode); - texCache.beginRender(); for (int i = 0; i < texCache.count; i++) { PTexture tex = texCache.getTexture(i); @@ -2307,8 +2334,8 @@ public class PGraphicsOpenGL extends PGraphics { shader.stop(); } - texCache.endRender(); - pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); + texCache.endRender(); + unbindFillBuffers(lights, texCache.hasTexture); } @@ -2340,7 +2367,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, IntBuffer.wrap(tessGeo.fillIndices, 0, size), vboMode); + pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, tessGeo.fillIndices, vboMode); pgl.glDrawElements(PGL.GL_TRIANGLES, size, PGL.INDEX_TYPE, 0); pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); @@ -2884,10 +2911,10 @@ public class PGraphicsOpenGL extends PGraphics { } } - int[] temp = { 0 }; - pgl.glGetIntegerv(PGL.GL_SAMPLES, temp, 0); - if (antialias != temp[0]) { - antialias = temp[0]; + pgl.glGetIntegerv(PGL.GL_SAMPLES, getBuffer); + int newAntialias = getBuffer.get(0); + if (antialias != newAntialias) { + antialias = newAntialias; PApplet.println("Effective multisampling level: " + antialias); } @@ -4280,8 +4307,8 @@ public class PGraphicsOpenGL extends PGraphics { } protected void backgroundImpl() { - tessGeo.reset(); - texCache.reset(); + tessGeo.clear(); + texCache.clear(); pgl.glClearColor(0, 0, 0, 0); pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT); @@ -5536,16 +5563,16 @@ public class PGraphicsOpenGL extends PGraphics { blendEqSupported = false; } - int temp[] = new int[2]; +// int temp[] = new int[2]; - pgl.glGetIntegerv(PGL.GL_MAX_TEXTURE_SIZE, temp, 0); - maxTextureSize = temp[0]; + pgl.glGetIntegerv(PGL.GL_MAX_TEXTURE_SIZE, getBuffer); + maxTextureSize = getBuffer.get(0); - pgl.glGetIntegerv(PGL.GL_ALIASED_LINE_WIDTH_RANGE, temp, 0); - maxLineWidth = temp[1]; + pgl.glGetIntegerv(PGL.GL_ALIASED_LINE_WIDTH_RANGE, getBuffer); + maxLineWidth = getBuffer.get(0); - pgl.glGetIntegerv(PGL.GL_ALIASED_POINT_SIZE_RANGE, temp, 0); - maxPointSize = temp[1]; + pgl.glGetIntegerv(PGL.GL_ALIASED_POINT_SIZE_RANGE, getBuffer); + maxPointSize = getBuffer.get(0); glParamsRead = true; } @@ -6163,7 +6190,7 @@ public class PGraphicsOpenGL extends PGraphics { updateGLModelview(); set4x4MatUniform(modelviewMatrixLoc, glModelview); - set4FloatUniform(viewportLoc, viewport[0], viewport[1], viewport[2], viewport[3]); + set4FloatUniform(viewportLoc, viewport.get(0), viewport.get(1), viewport.get(2), viewport.get(3)); if (hints[ENABLE_PERSPECTIVE_CORRECTED_LINES]) { setIntUniform(perspectiveLoc, 1); @@ -6294,7 +6321,7 @@ public class PGraphicsOpenGL extends PGraphics { hasTexture = false; } - public void reset() { + public void clear() { java.util.Arrays.fill(textures, 0, count, null); count = 0; hasTexture = false; @@ -6445,7 +6472,7 @@ public class PGraphicsOpenGL extends PGraphics { allocate(); } - public void reset() { + public void clear() { vertexCount = firstVertex = lastVertex = 0; edgeCount = firstEdge = lastEdge = 0; } @@ -6463,7 +6490,7 @@ public class PGraphicsOpenGL extends PGraphics { emissive = new int[PGL.DEFAULT_IN_VERTICES]; shininess = new float[PGL.DEFAULT_IN_VERTICES]; edges = new int[PGL.DEFAULT_IN_EDGES][3]; - reset(); + clear(); } public void trim() { @@ -7120,48 +7147,48 @@ public class PGraphicsOpenGL extends PGraphics { public int fillVertexCount; public int firstFillVertex; public int lastFillVertex; - public float[] fillVertices; - public int[] fillColors; - public float[] fillNormals; - public float[] fillTexcoords; + public FloatBuffer fillVertices; + public IntBuffer fillColors; + public FloatBuffer fillNormals; + public FloatBuffer fillTexcoords; // Fill material properties (fillColor is used // as the diffuse color when lighting is enabled) - public int[] fillAmbient; - public int[] fillSpecular; - public int[] fillEmissive; - public float[] fillShininess; + public IntBuffer fillAmbient; + public IntBuffer fillSpecular; + public IntBuffer fillEmissive; + public FloatBuffer fillShininess; public int fillIndexCount; public int firstFillIndex; public int lastFillIndex; - public int[] fillIndices; + public IntBuffer fillIndices; // Tessellated line data public int lineVertexCount; public int firstLineVertex; public int lastLineVertex; - public float[] lineVertices; - public int[] lineColors; - public float[] lineDirWidths; + public FloatBuffer lineVertices; + public IntBuffer lineColors; + public FloatBuffer lineDirWidths; public int lineIndexCount; public int firstLineIndex; public int lastLineIndex; - public int[] lineIndices; + public IntBuffer lineIndices; // Tessellated point data public int pointVertexCount; public int firstPointVertex; public int lastPointVertex; - public float[] pointVertices; - public int[] pointColors; - public float[] pointSizes; + public FloatBuffer pointVertices; + public IntBuffer pointColors; + public FloatBuffer pointSizes; public int pointIndexCount; public int firstPointIndex; public int lastPointIndex; - public int[] pointIndices; + public IntBuffer pointIndices; public boolean isStroked; @@ -7170,7 +7197,7 @@ public class PGraphicsOpenGL extends PGraphics { allocate(); } - public void reset() { + public void clear() { firstFillVertex = lastFillVertex = fillVertexCount = 0; firstFillIndex = lastFillIndex = fillIndexCount = 0; @@ -7179,36 +7206,57 @@ public class PGraphicsOpenGL extends PGraphics { firstPointVertex = lastPointVertex = pointVertexCount = 0; firstPointIndex = lastPointIndex = pointIndexCount = 0; + + fillVertices.clear(); + fillColors.clear(); + fillNormals.clear(); + fillTexcoords.clear(); + fillAmbient.clear(); + fillSpecular.clear(); + fillEmissive.clear(); + fillShininess.clear(); + fillIndices.clear(); + + lineVertices.clear(); + lineColors.clear(); + lineDirWidths.clear(); + lineIndices.clear(); + + pointVertices.clear(); + pointColors.clear(); + pointSizes.clear(); + pointIndices.clear(); 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 int[PGL.DEFAULT_TESS_VERTICES]; + fillVertices = pgl.createFloatBuffer(3 * PGL.DEFAULT_TESS_VERTICES); + fillColors = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); + fillNormals = pgl.createFloatBuffer(3 * PGL.DEFAULT_TESS_VERTICES); + fillTexcoords = pgl.createFloatBuffer(2 * PGL.DEFAULT_TESS_VERTICES); + fillAmbient = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); + fillSpecular = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); + fillEmissive = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); + fillShininess = pgl.createFloatBuffer(PGL.DEFAULT_TESS_VERTICES); + fillIndices = pgl.createIntBuffer(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 int[PGL.DEFAULT_TESS_VERTICES]; + lineVertices = pgl.createFloatBuffer(3 * PGL.DEFAULT_TESS_VERTICES); + lineColors = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); + lineDirWidths = pgl.createFloatBuffer(4 * PGL.DEFAULT_TESS_VERTICES); + lineIndices = pgl.createIntBuffer(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 int[PGL.DEFAULT_TESS_VERTICES]; + pointVertices = pgl.createFloatBuffer(3 * PGL.DEFAULT_TESS_VERTICES); + pointColors = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); + pointSizes = pgl.createFloatBuffer(2 * PGL.DEFAULT_TESS_VERTICES); + pointIndices = pgl.createIntBuffer(PGL.DEFAULT_TESS_VERTICES); - reset(); + clear(); } public void trim() { - if (0 < fillVertexCount && fillVertexCount < fillVertices.length / 3) { + if (0 < fillVertexCount && fillVertexCount < fillVertices.capacity() / 3) { + prepareFillVerticesForCopy(); trimFillVertices(); trimFillColors(); trimFillNormals(); @@ -7219,131 +7267,136 @@ public class PGraphicsOpenGL extends PGraphics { trimFillShininess(); } - if (0 < fillIndexCount && fillIndexCount < fillIndices.length) { + if (0 < fillIndexCount && fillIndexCount < fillIndices.capacity()) { + prepareFillIndicesForCopy(); trimFillIndices(); } - if (0 < lineVertexCount && lineVertexCount < lineVertices.length / 3) { + if (0 < lineVertexCount && lineVertexCount < lineVertices.capacity() / 3) { + prepareLineVerticesForCopy(); trimLineVertices(); trimLineColors(); trimLineAttributes(); } - if (0 < lineIndexCount && lineIndexCount < lineIndices.length) { + if (0 < lineIndexCount && lineIndexCount < lineIndices.capacity()) { + prepareLineIndicesForCopy(); trimLineIndices(); } - if (0 < pointVertexCount && pointVertexCount < pointVertices.length / 3) { + if (0 < pointVertexCount && pointVertexCount < pointVertices.capacity() / 3) { + preparePointVerticesForCopy(); trimPointVertices(); trimPointColors(); trimPointAttributes(); } - if (0 < pointIndexCount && pointIndexCount < pointIndices.length) { + if (0 < pointIndexCount && pointIndexCount < pointIndices.capacity()) { + preparePointIndicesForCopy(); trimPointIndices(); } } protected void trimFillVertices() { - float temp[] = new float[3 * fillVertexCount]; - PApplet.arrayCopy(fillVertices, 0, temp, 0, 3 * fillVertexCount); - fillVertices = temp; + FloatBuffer temp = pgl.createFloatBuffer(3 * fillVertexCount); + temp.put(fillVertices); + fillVertices = temp; } protected void trimFillColors() { - int temp[] = new int[fillVertexCount]; - PApplet.arrayCopy(fillColors, 0, temp, 0, fillVertexCount); - fillColors = temp; + IntBuffer temp = pgl.createIntBuffer(fillVertexCount); + temp.put(fillColors); + fillColors = temp; } protected void trimFillNormals() { - float temp[] = new float[3 * fillVertexCount]; - PApplet.arrayCopy(fillNormals, 0, temp, 0, 3 * fillVertexCount); - fillNormals = temp; + FloatBuffer temp = pgl.createFloatBuffer(3 * fillVertexCount); + temp.put(fillNormals); + fillNormals = temp; } protected void trimFillTexcoords() { - float temp[] = new float[2 * fillVertexCount]; - PApplet.arrayCopy(fillTexcoords, 0, temp, 0, 2 * fillVertexCount); - fillTexcoords = temp; + FloatBuffer temp = pgl.createFloatBuffer(2 * fillVertexCount); + temp.put(fillTexcoords); + fillTexcoords = temp; } protected void trimFillAmbient() { - int temp[] = new int[fillVertexCount]; - PApplet.arrayCopy(fillAmbient, 0, temp, 0, fillVertexCount); - fillAmbient = temp; + IntBuffer temp = pgl.createIntBuffer(fillVertexCount); + temp.put(fillAmbient); + fillAmbient = temp; } protected void trimFillSpecular() { - int temp[] = new int[fillVertexCount]; - PApplet.arrayCopy(fillSpecular, 0, temp, 0, fillVertexCount); - fillSpecular = temp; + IntBuffer temp = pgl.createIntBuffer(fillVertexCount); + temp.put(fillSpecular); + fillSpecular = temp; } protected void trimFillEmissive() { - int temp[] = new int[fillVertexCount]; - PApplet.arrayCopy(fillEmissive, 0, temp, 0, fillVertexCount); - fillEmissive = temp; + IntBuffer temp = pgl.createIntBuffer(fillVertexCount); + temp.put(fillEmissive); + fillEmissive = temp; } protected void trimFillShininess() { - float temp[] = new float[fillVertexCount]; - PApplet.arrayCopy(fillShininess, 0, temp, 0, fillVertexCount); - fillShininess = temp; + FloatBuffer temp = pgl.createFloatBuffer(fillVertexCount); + temp.put(fillShininess); + fillShininess = temp; } public void trimFillIndices() { - int temp[] = new int[fillIndexCount]; - PApplet.arrayCopy(fillIndices, 0, temp, 0, fillIndexCount); - fillIndices = temp; + IntBuffer temp = pgl.createIntBuffer(fillIndexCount); + temp.put(fillIndices); + fillIndices = temp; } protected void trimLineVertices() { - float temp[] = new float[3 * lineVertexCount]; - PApplet.arrayCopy(lineVertices, 0, temp, 0, 3 * lineVertexCount); - lineVertices = temp; + FloatBuffer temp = pgl.createFloatBuffer(3 * lineVertexCount); + temp.put(lineVertices); + lineVertices = temp; } protected void trimLineColors() { - int temp[] = new int[lineVertexCount]; - PApplet.arrayCopy(lineColors, 0, temp, 0, lineVertexCount); - lineColors = temp; + IntBuffer temp = pgl.createIntBuffer(lineVertexCount); + temp.put(lineColors); + lineColors = temp; } protected void trimLineAttributes() { - float temp[] = new float[4 * lineVertexCount]; - PApplet.arrayCopy(lineDirWidths, 0, temp, 0, 4 * lineVertexCount); - lineDirWidths = temp; + FloatBuffer temp = pgl.createFloatBuffer(4 * lineVertexCount); + temp.put(lineDirWidths); + lineDirWidths = temp; } protected void trimLineIndices() { - int temp[] = new int[lineIndexCount]; - PApplet.arrayCopy(lineIndices, 0, temp, 0, lineIndexCount); + IntBuffer temp = pgl.createIntBuffer(lineIndexCount); + temp.put(lineIndices); lineIndices = temp; } protected void trimPointVertices() { - float temp[] = new float[3 * pointVertexCount]; - PApplet.arrayCopy(pointVertices, 0, temp, 0, 3 * pointVertexCount); - pointVertices = temp; + FloatBuffer temp = pgl.createFloatBuffer(3 * pointVertexCount); + temp.put(pointVertices); + pointVertices = temp; } protected void trimPointColors() { - int temp[] = new int[pointVertexCount]; - PApplet.arrayCopy(pointColors, 0, temp, 0, pointVertexCount); - pointColors = temp; + IntBuffer temp = pgl.createIntBuffer(pointVertexCount); + temp.put(pointColors); + pointColors = temp; } protected void trimPointAttributes() { - float temp[] = new float[2 * pointVertexCount]; - PApplet.arrayCopy(pointSizes, 0, temp, 0, 2 * pointVertexCount); - pointSizes = temp; + FloatBuffer temp = pgl.createFloatBuffer(2 * pointVertexCount); + temp.put(pointSizes); + pointSizes = temp; } protected void trimPointIndices() { - int temp[] = new int[pointIndexCount]; - PApplet.arrayCopy(pointIndices, 0, temp, 0, pointIndexCount); - pointIndices = temp; + IntBuffer temp = pgl.createIntBuffer(pointIndexCount); + temp.put(pointIndices); + pointIndices = temp; } public void dipose() { @@ -7447,7 +7500,8 @@ public class PGraphicsOpenGL extends PGraphics { // shapes in the hierarchy, as the entire geometry will be stored // contiguously in a single VBO in the root node. for (int i = 0; i < fillIndexCount; i++) { - fillIndices[i] += voffset; + fillIndices.position(i); + fillIndices.put(fillIndices.get(i) + voffset); } } @@ -7475,7 +7529,8 @@ public class PGraphicsOpenGL extends PGraphics { // shapes in the hierarchy, as the entire geometry will be stored // contiguously in a single VBO in the root node. for (int i = 0; i < lineIndexCount; i++) { - lineIndices[i] += firstLineVertex; + lineIndices.position(i); + lineIndices.put(lineIndices.get(i) + voffset); } } @@ -7503,7 +7558,8 @@ public class PGraphicsOpenGL extends PGraphics { // shapes in the hierarchy, as the entire geometry will be stored // contiguously in a single VBO in the root node. for (int i = 0; i < pointIndexCount; i++) { - pointIndices[i] += firstPointVertex; + pointIndices.position(i); + pointIndices.put(pointIndices.get(i) + voffset); } } @@ -7512,80 +7568,70 @@ public class PGraphicsOpenGL extends PGraphics { } public void fillIndexCheck() { - if (fillIndexCount == fillIndices.length) { + if (fillIndexCount == fillIndices.capacity()) { int newSize = fillIndexCount << 1; expandFillIndices(newSize); } - } + } public void expandFillIndices(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(fillIndices, 0, temp, 0, fillIndexCount); + IntBuffer temp = pgl.createIntBuffer(n); + temp.put(fillIndices); fillIndices = temp; } public void addFillIndex(int idx) { fillIndexCheck(); - fillIndices[fillIndexCount] = PGL.makeIndex(idx); + fillIndices.put(fillIndexCount, PGL.makeIndex(idx)); fillIndexCount++; lastFillIndex = fillIndexCount - 1; } public void calcFillNormal(int i0, int i1, int i2) { - int index; + float[] v0 = new float[3]; + float[] v1 = new float[3]; + float[] v2 = new float[3]; + float[] normal = new float[3]; - index = 3 * i0; - float x0 = fillVertices[index++]; - float y0 = fillVertices[index++]; - float z0 = fillVertices[index ]; + fillVertices.position(3 * i0); + fillVertices.get(v0); - index = 3 * i1; - float x1 = fillVertices[index++]; - float y1 = fillVertices[index++]; - float z1 = fillVertices[index ]; + fillVertices.position(3 * i1); + fillVertices.get(v1); + + fillVertices.position(3 * i2); + fillVertices.get(v2); + + float v12x = v2[0] - v1[0]; + float v12y = v2[1] - v1[1]; + float v12z = v2[2] - v1[2]; + + float v10x = v0[0] - v1[0]; + float v10y = v0[1] - v1[1]; + float v10z = v0[2] - v1[2]; + + normal[0] = v12y * v10z - v10y * v12z; + normal[1] = v12z * v10x - v10z * v12x; + normal[2] = v12x * v10y - v10x * v12y; + float d = PApplet.sqrt(normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2]); + normal[0] /= d; + normal[1] /= d; + normal[2] /= d; + + fillNormals.position(3 * i0); + fillNormals.put(normal); - index = 3 * i2; - float x2 = fillVertices[index++]; - float y2 = fillVertices[index++]; - float z2 = fillVertices[index ]; - - float v12x = x2 - x1; - float v12y = y2 - y1; - float v12z = z2 - z1; - - float v10x = x0 - x1; - float v10y = y0 - y1; - float v10z = z0 - z1; - - float nx = v12y * v10z - v10y * v12z; - float ny = v12z * v10x - v10z * v12x; - float nz = v12x * v10y - v10x * v12y; - float d = PApplet.sqrt(nx * nx + ny * ny + nz * nz); - nx /= d; - ny /= d; - nz /= d; - - index = 3 * i0; - fillNormals[index++] = nx; - fillNormals[index++] = ny; - fillNormals[index ] = nz; + fillNormals.position(3 * i1); + fillNormals.put(normal); - index = 3 * i1; - fillNormals[index++] = nx; - fillNormals[index++] = ny; - fillNormals[index ] = nz; - - index = 3 * i2; - fillNormals[index++] = nx; - fillNormals[index++] = ny; - fillNormals[index ] = nz; - + fillNormals.position(3 * i2); + fillNormals.put(normal); } public void fillVertexCheck() { - if (fillVertexCount == fillVertices.length / 3) { + if (fillVertexCount == fillVertices.capacity() / 3) { int newSize = fillVertexCount << 1; - + prepareFillVerticesForCopy(); expandFillVertices(newSize); expandFillColors(newSize); expandFillNormals(newSize); @@ -7598,10 +7644,10 @@ public class PGraphicsOpenGL extends PGraphics { } public void addFillVertices(int count) { - int oldSize = fillVertices.length / 3; + int oldSize = fillVertices.capacity() / 3; if (fillVertexCount + count > oldSize) { int newSize = expandVertSize(oldSize, fillVertexCount + count); - + prepareFillVerticesForCopy(); expandFillVertices(newSize); expandFillColors(newSize); expandFillNormals(newSize); @@ -7618,10 +7664,10 @@ public class PGraphicsOpenGL extends PGraphics { } public void addFillIndices(int count) { - int oldSize = fillIndices.length; + int oldSize = fillIndices.capacity(); if (fillIndexCount + count > oldSize) { int newSize = expandIndSize(oldSize, fillIndexCount + count); - + prepareFillIndicesForCopy(); expandFillIndices(newSize); } @@ -7630,59 +7676,147 @@ public class PGraphicsOpenGL extends PGraphics { lastFillIndex = fillIndexCount - 1; } + protected void prepareFillVerticesForCopy() { + prepareFillVerticesForCopy(0, fillVertexCount); + } + + protected void prepareFillIndicesForCopy() { + prepareFillIndicesForCopy(0, fillIndexCount); + } + + protected void prepareFillVerticesForCopy(int start, int count) { + fillVertices.position(3 * start); + fillVertices.limit(3 * count); + + fillColors.position(start); + fillColors.limit(count); + + fillNormals.position(3 * start); + fillNormals.limit(3 * count); + + fillTexcoords.position(2 * start); + fillTexcoords.limit(2 * count); + + fillAmbient.position(start); + fillAmbient.limit(count); + + fillSpecular.position(start); + fillSpecular.limit(count); + + fillEmissive.position(start); + fillEmissive.limit(count); + + fillShininess.position(start); + fillShininess.limit(count); + } + + protected void prepareFillIndicesForCopy(int start, int count) { + fillIndices.position(start); + fillIndices.limit(count); + } + + protected void prepareLineVerticesForCopy() { + prepareLineVerticesForCopy(0, lineVertexCount); + } + + protected void prepareLineIndicesForCopy() { + prepareLineIndicesForCopy(0, lineIndexCount); + } + + protected void prepareLineVerticesForCopy(int start, int count) { + lineVertices.position(3 * start); + lineVertices.limit(3 * count); + + lineColors.position(start); + lineColors.limit(count); + + lineDirWidths.position(4 * start); + lineDirWidths.limit(4 * count); + } + + protected void prepareLineIndicesForCopy(int start, int count) { + lineIndices.position(start); + lineIndices.limit(count); + } + + protected void preparePointVerticesForCopy() { + preparePointVerticesForCopy(0, pointVertexCount); + } + + protected void preparePointIndicesForCopy() { + preparePointIndicesForCopy(0, pointIndexCount); + } + + protected void preparePointVerticesForCopy(int start, int count) { + pointVertices.position(3 * start); + pointVertices.limit(3 * count); + + pointColors.position(start); + pointColors.limit(count); + + pointSizes.position(2 * start); + pointSizes.limit(2 * count); + } + + protected void preparePointIndicesForCopy(int start, int count) { + pointIndices.position(start); + pointIndices.limit(count); + } + + protected void expandFillVertices(int n) { - float temp[] = new float[3 * n]; - PApplet.arrayCopy(fillVertices, 0, temp, 0, 3 * fillVertexCount); - fillVertices = temp; + FloatBuffer temp = pgl.createFloatBuffer(3 * n); + temp.put(fillVertices); + fillVertices = temp; } protected void expandFillColors(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(fillColors, 0, temp, 0, fillVertexCount); - fillColors = temp; + IntBuffer temp = pgl.createIntBuffer(n); + temp.put(fillColors); + fillColors = temp; } protected void expandFillNormals(int n) { - float temp[] = new float[3 * n]; - PApplet.arrayCopy(fillNormals, 0, temp, 0, 3 * fillVertexCount); - fillNormals = temp; + FloatBuffer temp = pgl.createFloatBuffer(3 * n); + temp.put(fillNormals); + fillNormals = temp; } protected void expandFillTexcoords(int n) { - float temp[] = new float[2 * n]; - PApplet.arrayCopy(fillTexcoords, 0, temp, 0, 2 * fillVertexCount); - fillTexcoords = temp; + FloatBuffer temp = pgl.createFloatBuffer(2 * n); + temp.put(fillTexcoords); + fillTexcoords = temp; } protected void expandFillAmbient(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(fillAmbient, 0, temp, 0, fillVertexCount); - fillAmbient = temp; + IntBuffer temp = pgl.createIntBuffer(n); + temp.put(fillAmbient); + fillAmbient = temp; } protected void expandFillSpecular(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(fillSpecular, 0, temp, 0, fillVertexCount); - fillSpecular = temp; + IntBuffer temp = pgl.createIntBuffer(n); + temp.put(fillSpecular); + fillSpecular = temp; } protected void expandFillEmissive(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(fillEmissive, 0, temp, 0, fillVertexCount); - fillEmissive = temp; + IntBuffer temp = pgl.createIntBuffer(n); + temp.put(fillEmissive); + fillEmissive = temp; } protected void expandFillShininess(int n) { - float temp[] = new float[n]; - PApplet.arrayCopy(fillShininess, 0, temp, 0, fillVertexCount); - fillShininess = temp; + FloatBuffer temp = pgl.createFloatBuffer(n); + temp.put(fillShininess); + fillShininess = temp; } public void addLineVertices(int count) { - int oldSize = lineVertices.length / 3; + int oldSize = lineVertices.capacity() / 3; if (lineVertexCount + count > oldSize) { int newSize = expandVertSize(oldSize, lineVertexCount + count); - + prepareLineVerticesForCopy(); expandLineVertices(newSize); expandLineColors(newSize); expandLineAttributes(newSize); @@ -7694,28 +7828,28 @@ public class PGraphicsOpenGL extends PGraphics { } protected void expandLineVertices(int n) { - float temp[] = new float[3 * n]; - PApplet.arrayCopy(lineVertices, 0, temp, 0, 3 * lineVertexCount); - lineVertices = temp; + FloatBuffer temp = pgl.createFloatBuffer(3 * n); + temp.put(lineVertices); + lineVertices = temp; } protected void expandLineColors(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(lineColors, 0, temp, 0, lineVertexCount); - lineColors = temp; + IntBuffer temp = pgl.createIntBuffer(n); + temp.put(lineColors); + lineColors = temp; } protected void expandLineAttributes(int n) { - float temp[] = new float[4 * n]; - PApplet.arrayCopy(lineDirWidths, 0, temp, 0, 4 * lineVertexCount); - lineDirWidths = temp; + FloatBuffer temp = pgl.createFloatBuffer(4 * n); + temp.put(lineDirWidths); + lineDirWidths = temp; } public void addLineIndices(int count) { - int oldSize = lineIndices.length; + int oldSize = lineIndices.capacity(); if (lineIndexCount + count > oldSize) { int newSize = expandIndSize(oldSize, lineIndexCount + count); - + prepareLineIndicesForCopy(); expandLineIndices(newSize); } @@ -7725,16 +7859,16 @@ public class PGraphicsOpenGL extends PGraphics { } protected void expandLineIndices(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(lineIndices, 0, temp, 0, lineIndexCount); - lineIndices = temp; + IntBuffer temp = pgl.createIntBuffer(n); + temp.put(lineIndices); + lineIndices = temp; } public void addPointVertices(int count) { - int oldSize = pointVertices.length / 3; + int oldSize = pointVertices.capacity() / 3; if (pointVertexCount + count > oldSize) { int newSize = expandVertSize(oldSize, pointVertexCount + count); - + preparePointVerticesForCopy(); expandPointVertices(newSize); expandPointColors(newSize); expandPointAttributes(newSize); @@ -7746,28 +7880,28 @@ public class PGraphicsOpenGL extends PGraphics { } protected void expandPointVertices(int n) { - float temp[] = new float[3 * n]; - PApplet.arrayCopy(pointVertices, 0, temp, 0, 3 * pointVertexCount); - pointVertices = temp; + FloatBuffer temp = pgl.createFloatBuffer(3 * n); + temp.put(pointVertices); + pointVertices = temp; } protected void expandPointColors(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(pointColors, 0, temp, 0, pointVertexCount); - pointColors = temp; + IntBuffer temp = pgl.createIntBuffer(n); + temp.put(pointColors); + pointColors = temp; } protected void expandPointAttributes(int n) { - float temp[] = new float[2 * n]; - PApplet.arrayCopy(pointSizes, 0, temp, 0, 2 * pointVertexCount); - pointSizes = temp; + FloatBuffer temp = pgl.createFloatBuffer(2 * n); + temp.put(pointSizes); + pointSizes = temp; } public void addPointIndices(int count) { - int oldSize = pointIndices.length; + int oldSize = pointIndices.capacity(); if (pointIndexCount + count > oldSize) { int newSize = expandIndSize(oldSize, pointIndexCount + count); - + preparePointIndicesForCopy(); expandPointIndices(newSize); } @@ -7777,9 +7911,9 @@ public class PGraphicsOpenGL extends PGraphics { } protected void expandPointIndices(int n) { - int temp[] = new int[n]; - PApplet.arrayCopy(pointIndices, 0, temp, 0, pointIndexCount); - pointIndices = temp; + IntBuffer temp = pgl.createIntBuffer(n); + temp.put(pointIndices); + pointIndices = temp; } public void addFillVertex(float x, float y, float z, @@ -7788,43 +7922,50 @@ public class PGraphicsOpenGL extends PGraphics { float u, float v, int am, int sp, int em, float shine) { fillVertexCheck(); - int index; + float[] vert = new float[3]; + float[] norm = new float[3]; + float[] tcoord = {u, v}; if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { PMatrix3D mm = modelview; PMatrix3D nm = modelviewInv; - index = 3 * fillVertexCount; - fillVertices[index++] = x * mm.m00 + y * mm.m01 + z * mm.m02 + mm.m03; - fillVertices[index++] = x * mm.m10 + y * mm.m11 + z * mm.m12 + mm.m13; - fillVertices[index ] = x * mm.m20 + y * mm.m21 + z * mm.m22 + mm.m23; + vert[0] = x * mm.m00 + y * mm.m01 + z * mm.m02 + mm.m03; + vert[1] = x * mm.m10 + y * mm.m11 + z * mm.m12 + mm.m13; + vert[2] = x * mm.m20 + y * mm.m21 + z * mm.m22 + mm.m23; - index = 3 * fillVertexCount; - fillNormals[index++] = nx * nm.m00 + ny * nm.m10 + nz * nm.m20; - fillNormals[index++] = nx * nm.m01 + ny * nm.m11 + nz * nm.m21; - fillNormals[index ] = nx * nm.m02 + ny * nm.m12 + nz * nm.m22; + norm[0] = nx * nm.m00 + ny * nm.m10 + nz * nm.m20; + norm[1] = nx * nm.m01 + ny * nm.m11 + nz * nm.m21; + norm[2] = nx * nm.m02 + ny * nm.m12 + nz * nm.m22; } else { - index = 3 * fillVertexCount; - fillVertices[index++] = x; - fillVertices[index++] = y; - fillVertices[index ] = z; - - index = 3 * fillVertexCount; - fillNormals[index++] = nx; - fillNormals[index++] = ny; - fillNormals[index ] = nz; + vert[0] = x; + vert[1] = y; + vert[2] = z; + + norm[0] = nx; + norm[1] = ny; + norm[2] = nz; } + fillVertices.position(3 * fillVertexCount); + fillVertices.put(vert); - fillColors[fillVertexCount] = rgba; + fillColors.position(fillVertexCount); + fillColors.put(rgba); - index = 2 * fillVertexCount; - fillTexcoords[index++] = u; - fillTexcoords[index ] = v; + fillNormals.position(3 * fillVertexCount); + fillNormals.put(norm); + + fillTexcoords.position(2 * fillVertexCount); + fillTexcoords.put(tcoord); - fillAmbient[fillVertexCount] = am; - fillSpecular[fillVertexCount] = sp; - fillEmissive[fillVertexCount] = em; - fillShininess[fillVertexCount] = shine; + fillAmbient.position(fillVertexCount); + fillAmbient.put(am); + fillSpecular.position(fillVertexCount); + fillSpecular.put(sp); + fillEmissive.position(fillVertexCount); + fillEmissive.put(em); + fillShininess.position(fillVertexCount); + fillShininess.put(shine); fillVertexCount++; } @@ -7837,6 +7978,8 @@ public class PGraphicsOpenGL extends PGraphics { addFillVertices(nvert); + float[] vert = new float[3]; + float[] norm = new float[3]; if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { PMatrix3D mm = modelview; PMatrix3D nm = modelviewInv; @@ -7855,78 +7998,49 @@ public class PGraphicsOpenGL extends PGraphics { float ny = in.normals[index++]; float nz = in.normals[index ]; - index = 3 * tessIdx; - fillVertices[index++] = x * mm.m00 + y * mm.m01 + z * mm.m02 + mm.m03; - fillVertices[index++] = x * mm.m10 + y * mm.m11 + z * mm.m12 + mm.m13; - fillVertices[index ] = x * mm.m20 + y * mm.m21 + z * mm.m22 + mm.m23; + vert[0] = x * mm.m00 + y * mm.m01 + z * mm.m02 + mm.m03; + vert[1] = x * mm.m10 + y * mm.m11 + z * mm.m12 + mm.m13; + vert[2] = x * mm.m20 + y * mm.m21 + z * mm.m22 + mm.m23; + + norm[0] = nx * nm.m00 + ny * nm.m10 + nz * nm.m20; + norm[1] = nx * nm.m01 + ny * nm.m11 + nz * nm.m21; + norm[2] = nx * nm.m02 + ny * nm.m12 + nz * nm.m22; + + fillVertices.position(3 * tessIdx); + try { + fillVertices.put(vert); + } catch (java.nio.BufferOverflowException e) { + PApplet.println("mama mia " + 3 * tessIdx + " " + fillVertices.position() + " " + fillVertices.limit() + " " + fillVertices.capacity() + " " + 3 * fillVertexCount); + } - index = 3 * tessIdx; - fillNormals[index++] = nx * nm.m00 + ny * nm.m10 + nz * nm.m20; - fillNormals[index++] = nx * nm.m01 + ny * nm.m11 + nz * nm.m21; - fillNormals[index ] = nx * nm.m02 + ny * nm.m12 + nz * nm.m22; + fillNormals.position(3 * tessIdx); + fillNormals.put(norm); } - } else { - if (nvert <= MIN_ARRAYCOPY_SIZE) { - // Copying elements one by one instead of using arrayCopy is more efficient for - // few vertices... - for (int i = 0; i < nvert; i++) { - int inIdx = i0 + i; - int tessIdx = firstFillVertex + i; - - index = 3 * inIdx; - float x = in.vertices[index++]; - float y = in.vertices[index++]; - float z = in.vertices[index ]; - - index = 3 * inIdx; - float nx = in.normals[index++]; - float ny = in.normals[index++]; - float nz = in.normals[index ]; - - index = 3 * tessIdx; - fillVertices[index++] = x; - fillVertices[index++] = y; - fillVertices[index ] = z; - - index = 3 * tessIdx; - fillNormals[index++] = nx; - fillNormals[index++] = ny; - fillNormals[index ] = nz; - } - } else { - PApplet.arrayCopy(in.vertices, 3 * i0, fillVertices, 3 * firstFillVertex, 3 * nvert); - PApplet.arrayCopy(in.normals, 3 * i0, fillNormals, 3 * firstFillVertex, 3 * nvert); - } - } - - if (nvert <= MIN_ARRAYCOPY_SIZE) { - for (int i = 0; i < nvert; i++) { - int inIdx = i0 + i; - int tessIdx = firstFillVertex + i; - - index = 2 * inIdx; - float u = in.texcoords[index++]; - float v = in.texcoords[index ]; - - fillColors[tessIdx] = in.colors[inIdx]; - - index = 2 * tessIdx; - fillTexcoords[index++] = u; - fillTexcoords[index ] = v; - - fillAmbient[tessIdx] = in.ambient[inIdx]; - fillSpecular[tessIdx] = in.specular[inIdx]; - fillEmissive[tessIdx] = in.emissive[inIdx]; - fillShininess[tessIdx] = in.shininess[inIdx]; - } - } else { - PApplet.arrayCopy(in.colors, i0, fillColors, firstFillVertex, 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); + } else { + fillVertices.position(3 * firstFillVertex); + fillVertices.put(in.vertices, 3 * i0, 3 * nvert); + + fillNormals.position(3 * firstFillVertex); + fillNormals.put(in.normals, 3 * i0, 3 * nvert); } + + fillColors.position(firstFillVertex); + fillColors.put(in.colors, i0, nvert); + + fillTexcoords.position(2 * firstFillVertex); + fillTexcoords.put(in.texcoords, 2 * i0, 2 * nvert); + + fillAmbient.position(firstFillVertex); + fillAmbient.put(in.ambient, i0, nvert); + + fillSpecular.position(firstFillVertex); + fillSpecular.put(in.specular, i0, nvert); + + fillEmissive.position(firstFillVertex); + fillEmissive.put(in.emissive, i0, nvert); + + fillShininess.position(firstFillVertex); + fillShininess.put(in.shininess, i0, nvert); } public void putLineVertex(InGeometry in, int inIdx0, int inIdx1, int tessIdx, int rgba) { @@ -7945,39 +8059,41 @@ public class PGraphicsOpenGL extends PGraphics { if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { PMatrix3D mm = modelview; - index = 3 * tessIdx; - lineVertices[index++] = x0 * mm.m00 + y0 * mm.m01 + z0 * mm.m02 + mm.m03; - lineVertices[index++] = x0 * mm.m10 + y0 * mm.m11 + z0 * mm.m12 + mm.m13; - lineVertices[index ] = x0 * mm.m20 + y0 * mm.m21 + z0 * mm.m22 + mm.m23; + float[] vert = { + x0 * mm.m00 + y0 * mm.m01 + z0 * mm.m02 + mm.m03, + x0 * mm.m10 + y0 * mm.m11 + z0 * mm.m12 + mm.m13, + x0 * mm.m20 + y0 * mm.m21 + z0 * mm.m22 + mm.m23 + }; - index = 4 * tessIdx; - lineDirWidths[index++] = x1 * mm.m00 + y1 * mm.m01 + z1 * mm.m02 + mm.m03; - lineDirWidths[index++] = x1 * mm.m10 + y1 * mm.m11 + z1 * mm.m12 + mm.m13; - lineDirWidths[index ] = x1 * mm.m20 + y1 * mm.m21 + z1 * mm.m22 + mm.m23; + float[] attr = { + x1 * mm.m00 + y1 * mm.m01 + z1 * mm.m02 + mm.m03, + x1 * mm.m10 + y1 * mm.m11 + z1 * mm.m12 + mm.m13, + x1 * mm.m20 + y1 * mm.m21 + z1 * mm.m22 + mm.m23 + }; + + lineVertices.position(3 * tessIdx); + lineVertices.put(vert); + + lineDirWidths.position(4 * tessIdx); + lineDirWidths.put(attr); } else { - index = 3 * tessIdx; - lineVertices[index++] = x0; - lineVertices[index++] = y0; - lineVertices[index ] = z0; + lineVertices.position(3 * tessIdx); + lineVertices.put(in.vertices, 3 * inIdx0, 3); - index = 4 * tessIdx; - lineDirWidths[index++] = x1; - lineDirWidths[index++] = y1; - lineDirWidths[index ] = z1; + lineDirWidths.position(4 * tessIdx); + lineDirWidths.put(in.vertices, 3 * inIdx1, 3); } - lineColors[tessIdx] = rgba; + lineColors.position(tessIdx); + lineColors.put(rgba); } public void putLineVertex(InGeometry in, int inIdx0, int inIdx1, int tessIdx) { putLineVertex(in, inIdx0, inIdx1, tessIdx, in.scolors[inIdx0]); } - - + public void putPointVertex(InGeometry in, int inIdx, int tessIdx) { - int index; - - index = 3 * inIdx; + int index = 3 * inIdx; float x = in.vertices[index++]; float y = in.vertices[index++]; float z = in.vertices[index ]; @@ -7985,18 +8101,22 @@ public class PGraphicsOpenGL extends PGraphics { if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { PMatrix3D mm = modelview; - index = 3 * tessIdx; - pointVertices[index++] = x * mm.m00 + y * mm.m01 + z * mm.m02 + mm.m03; - pointVertices[index++] = x * mm.m10 + y * mm.m11 + z * mm.m12 + mm.m13; - pointVertices[index ] = x * mm.m20 + y * mm.m21 + z * mm.m22 + mm.m23; + float[] vert = { + x * mm.m00 + y * mm.m01 + z * mm.m02 + mm.m03, + x * mm.m10 + y * mm.m11 + z * mm.m12 + mm.m13, + x * mm.m20 + y * mm.m21 + z * mm.m22 + mm.m23 + }; + + pointVertices.position(3 * tessIdx); + pointVertices.put(vert, 0, 3); } else { index = 3 * tessIdx; - pointVertices[index++] = x; - pointVertices[index++] = y; - pointVertices[index ] = z; + pointVertices.position(3 * tessIdx); + pointVertices.put(in.vertices, 3 * inIdx, 3); } - pointColors[tessIdx] = in.scolors[inIdx]; + pointColors.position(tessIdx); + pointColors.put(in.scolors[inIdx]); } public int expandVertSize(int currSize, int newMinSize) { @@ -8023,18 +8143,18 @@ public class PGraphicsOpenGL extends PGraphics { float cy0 = 0; for (int i = 0; i < fillVertexCount; i++) { index = 3 * i; - cx0 += fillVertices[index++]; - cy0 += fillVertices[index ]; - } + cx0 += fillVertices.get(index++); + cy0 += fillVertices.get(index ); + } for (int i = 0; i < lineVertexCount; i++) { index = 3 * i; - cx0 += lineVertices[index++]; - cy0 += lineVertices[index ]; + cx0 += lineVertices.get(index++); + cy0 += lineVertices.get(index ); } for (int i = 0; i < pointVertexCount; i++) { index = 3 * i; - cx0 += pointVertices[index++]; - cy0 += pointVertices[index ]; + cx0 += pointVertices.get(index++); + cy0 += pointVertices.get(index ); } int nt = fillVertexCount + lineVertexCount + pointVertexCount; if (0 < nt) { @@ -8042,34 +8162,43 @@ public class PGraphicsOpenGL extends PGraphics { cy0 /= nt; } - float tx = cx - cx0; - float ty = cy - cy0; + float[] tvect = { cx - cx0, cy - cy0 }; if (0 < fillVertexCount) { for (int i = 0; i < fillVertexCount; i++) { index = 3 * i; - fillVertices[index++] += tx; - fillVertices[index ] += ty; + for (int j = 0; j < 2; j++) { + float v = fillVertices.get(index + j); + + fillVertices.position(index + j); + //fillVertices.put(v + tvect[j]); + fillVertices.put(v + 100); + } } } if (0 < lineVertexCount) { for (int i = 0; i < lineVertexCount; i++) { index = 3 * i; - lineVertices[index++] += tx; - lineVertices[index ] += ty; - + for (int j = 0; j < 2; j++) { + lineVertices.position(index + j); + lineVertices.put(lineVertices.get(index + j) + tvect[j]); + } index = 4 * i; - lineDirWidths[index++] += tx; - lineDirWidths[index ] += ty; + for (int j = 0; j < 2; j++) { + lineDirWidths.position(index + j); + lineDirWidths.put(lineDirWidths.get(index + j) + tvect[j]); + } } } if (0 < pointVertexCount) { for (int i = 0; i < pointVertexCount; i++) { index = 3 * i; - pointVertices[index++] += tx; - pointVertices[index ] += ty; + for (int j = 0; j < 2; j++) { + pointVertices.position(index + j); + pointVertices.put(pointVertices.get(index + j) + tvect[j]); + } } } } @@ -8083,21 +8212,21 @@ public class PGraphicsOpenGL extends PGraphics { float cz0 = 0; for (int i = 0; i < fillVertexCount; i++) { index = 3 * i; - cx0 += fillVertices[index++]; - cy0 += fillVertices[index++]; - cz0 += fillVertices[index ]; + cx0 += fillVertices.get(index++); + cy0 += fillVertices.get(index++); + cz0 += fillVertices.get(index ); } for (int i = 0; i < lineVertexCount; i++) { - index = 3 * i; - cx0 += lineVertices[index++]; - cy0 += lineVertices[index++]; - cz0 += lineVertices[index ]; + index = 3 * i; + cx0 += lineVertices.get(index++); + cy0 += lineVertices.get(index++); + cz0 += lineVertices.get(index ); } for (int i = 0; i < pointVertexCount; i++) { - index = 3 * i; - cx0 += pointVertices[index++]; - cy0 += pointVertices[index++]; - cz0 += pointVertices[index ]; + index = 3 * i; + cx0 += pointVertices.get(index++); + cy0 += pointVertices.get(index++); + cz0 += pointVertices.get(index ); } int nt = fillVertexCount + lineVertexCount + pointVertexCount; if (0 < nt) { @@ -8106,192 +8235,174 @@ public class PGraphicsOpenGL extends PGraphics { cz0 /= nt; } - float tx = cx - cx0; - float ty = cy - cy0; - float tz = cz - cz0; + float[] tvec = {cx - cx0, cy - cy0, cz - cz0}; if (0 < fillVertexCount) { for (int i = 0; i < fillVertexCount; i++) { index = 3 * i; - fillVertices[index++] += tx; - fillVertices[index++] += ty; - fillVertices[index ] += tz; + for (int j = 0; j < 3; j++) { + fillVertices.position(index + j); + fillVertices.put(fillVertices.get(index + j) + tvec[j]); + } } } if (0 < lineVertexCount) { for (int i = 0; i < lineVertexCount; i++) { index = 3 * i; - lineVertices[index++] += tx; - lineVertices[index++] += ty; - lineVertices[index ] += tz; - + for (int j = 0; j < 3; j++) { + lineVertices.position(index + j); + lineVertices.put(lineVertices.get(index + j) + tvec[j]); + } index = 4 * i; - lineDirWidths[index++] += tx; - lineDirWidths[index++] += ty; - lineDirWidths[index ] += tz; + for (int j = 0; j < 3; j++) { + lineDirWidths.position(index + j); + lineDirWidths.put(lineDirWidths.get(index + j) + tvec[j]); + } } } if (0 < pointVertexCount) { for (int i = 0; i < pointVertexCount; i++) { index = 3 * i; - pointVertices[index++] += tx; - pointVertices[index++] += ty; - pointVertices[index ] += tz; + for (int j = 0; j < 3; j++) { + pointVertices.position(index + j); + pointVertices.put(pointVertices.get(index + j) + tvec[j]); + } } } } - public int getCenter(PVector v) { + public int sumVertices(PVector v) { int index; for (int i = 0; i < fillVertexCount; i++) { - index = 3 * i; - v.x += fillVertices[index++]; - v.y += fillVertices[index++]; - v.z += fillVertices[index ]; + index = 3 * i; + v.x += fillVertices.get(index++); + v.y += fillVertices.get(index++); + v.z += fillVertices.get(index ); } for (int i = 0; i < lineVertexCount; i++) { index = 3 * i; - v.x += lineVertices[index++]; - v.y += lineVertices[index++]; - v.z += lineVertices[index ]; + v.x += lineVertices.get(index++); + v.y += lineVertices.get(index++); + v.z += lineVertices.get(index ); } for (int i = 0; i < pointVertexCount; i++) { index = 3 * i; - v.x += pointVertices[index++]; - v.y += pointVertices[index++]; - v.z += pointVertices[index ]; + v.x += pointVertices.get(index++); + v.y += pointVertices.get(index++); + v.z += pointVertices.get(index ); } - return fillVertexCount + lineVertexCount + pointVertexCount; - } + int ntot = fillVertexCount + lineVertexCount + pointVertexCount; + return ntot; + } + public void applyMatrix(PMatrix2D tr) { - if (0 < fillVertexCount) { - int index; - - for (int i = 0; i < fillVertexCount; i++) { - index = 3 * i; - float x = fillVertices[index++]; - float y = fillVertices[index ]; - - index = 3 * i; - float nx = fillNormals[index++]; - float ny = fillNormals[index ]; + float[] vec0 = new float[2]; + float[] vec1 = new float[2]; - index = 3 * i; - fillVertices[index++] = x * tr.m00 + y * tr.m01 + tr.m02; - fillVertices[index ] = x * tr.m10 + y * tr.m11 + tr.m12; - - index = 3 * i; - fillNormals[index++] = nx * tr.m00 + ny * tr.m01; - fillNormals[index ] = nx * tr.m10 + ny * tr.m11; + if (0 < fillVertexCount) { + for (int i = 0; i < fillVertexCount; i++) { + fillVertices.position(3 * i); + fillVertices.get(vec0); + vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + tr.m02; + vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + tr.m12; + fillVertices.position(3 * i); + fillVertices.put(vec1); + + fillNormals.position(3 * i); + fillNormals.get(vec0); + vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + tr.m02; + vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + tr.m12; + fillNormals.position(3 * i); + fillNormals.put(vec1); } } if (0 < lineVertexCount) { - int index; - for (int i = 0; i < lineVertexCount; i++) { - index = 3 * i; - float x = lineVertices[index++]; - float y = lineVertices[index ]; - - index = 4 * i; - float xa = lineDirWidths[index++]; - float ya = lineDirWidths[index ]; + lineVertices.position(3 * i); + lineVertices.get(vec0); + vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + tr.m02; + vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + tr.m12; + lineVertices.position(3 * i); + lineVertices.put(vec1); - index = 3 * i; - lineVertices[index++] = x * tr.m00 + y * tr.m01 + tr.m02; - lineVertices[index ] = x * tr.m10 + y * tr.m11 + tr.m12; - - index = 4 * i; - lineDirWidths[index++] = xa * tr.m00 + ya * tr.m01 + tr.m02; - lineDirWidths[index ] = xa * tr.m10 + ya * tr.m11 + tr.m12; + lineDirWidths.position(4 * i); + lineDirWidths.get(vec0); + vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + tr.m02; + vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + tr.m12; + lineDirWidths.position(4 * i); + lineDirWidths.put(vec1, 0, 2); } } if (0 < pointVertexCount) { - int index; - for (int i = 0; i < pointVertexCount; i++) { - index = 3 * i; - float x = pointVertices[index++]; - float y = pointVertices[index ]; - - index = 3 * i; - pointVertices[index++] = x * tr.m00 + y * tr.m01 + tr.m02; - pointVertices[index ] = x * tr.m10 + y * tr.m11 + tr.m12; + pointVertices.position(3 * i); + pointVertices.get(vec0); + vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + tr.m02; + vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + tr.m12; + pointVertices.position(3 * i); + pointVertices.put(vec1, 0, 2); } } } public void applyMatrix(PMatrix3D tr) { + float[] vec0 = new float[3]; + float[] vec1 = new float[3]; + if (0 < fillVertexCount) { - int index; - for (int i = 0; i < fillVertexCount; i++) { - index = 3 * i; - float x = fillVertices[index++]; - float y = fillVertices[index++]; - float z = fillVertices[index ]; - - index = 3 * i; - float nx = fillNormals[index++]; - float ny = fillNormals[index++]; - float nz = fillNormals[index ]; - - index = 3 * i; - fillVertices[index++] = x * tr.m00 + y * tr.m01 + z * tr.m02 + tr.m03; - fillVertices[index++] = x * tr.m10 + y * tr.m11 + z * tr.m12 + tr.m13; - fillVertices[index ] = x * tr.m20 + y * tr.m21 + z * tr.m22 + tr.m23; - - index = 3 * i; - fillNormals[index++] = nx * tr.m00 + ny * tr.m01 + nz * tr.m02; - fillNormals[index++] = nx * tr.m10 + ny * tr.m11 + nz * tr.m12; - fillNormals[index ] = nx * tr.m20 + ny * tr.m21 + nz * tr.m22; + fillVertices.position(3 * i); + fillVertices.get(vec0); + vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + vec0[2] * tr.m02 + tr.m03; + vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + vec0[2] * tr.m12 + tr.m13; + vec1[2] = vec0[0] * tr.m20 + vec0[1] * tr.m21 + vec0[2] * tr.m22 + tr.m23; + fillVertices.position(3 * i); + fillVertices.put(vec1); + + fillNormals.position(3 * i); + fillNormals.get(vec0); + vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + vec0[2] * tr.m02; + vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + vec0[2] * tr.m12; + vec1[2] = vec0[0] * tr.m20 + vec0[1] * tr.m21 + vec0[2] * tr.m22; + fillNormals.position(3 * i); + fillNormals.put(vec1); } } if (0 < lineVertexCount) { - int index; - for (int i = 0; i < lineVertexCount; i++) { - index = 3 * i; - float x = lineVertices[index++]; - float y = lineVertices[index++]; - float z = lineVertices[index ]; - - index = 4 * i; - float xa = lineDirWidths[index++]; - float ya = lineDirWidths[index++]; - float za = lineDirWidths[index ]; - - index = 3 * i; - lineVertices[index++] = x * tr.m00 + y * tr.m01 + z * tr.m02 + tr.m03; - lineVertices[index++] = x * tr.m10 + y * tr.m11 + z * tr.m12 + tr.m13; - lineVertices[index ] = x * tr.m20 + y * tr.m21 + z * tr.m22 + tr.m23; - - index = 4 * i; - lineDirWidths[index++] = xa * tr.m00 + ya * tr.m01 + za * tr.m02 + tr.m03; - lineDirWidths[index++] = xa * tr.m10 + ya * tr.m11 + za * tr.m12 + tr.m13; - lineDirWidths[index ] = xa * tr.m20 + ya * tr.m21 + za * tr.m22 + tr.m23; + lineVertices.position(3 * i); + lineVertices.get(vec0); + vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + vec0[2] * tr.m02; + vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + vec0[2] * tr.m12; + vec1[2] = vec0[0] * tr.m20 + vec0[1] * tr.m21 + vec0[2] * tr.m22; + lineVertices.position(3 * i); + lineVertices.put(vec1); + + lineDirWidths.position(4 * i); + lineDirWidths.get(vec0); + vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + vec0[2] * tr.m02; + vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + vec0[2] * tr.m12; + vec1[2] = vec0[0] * tr.m20 + vec0[1] * tr.m21 + vec0[2] * tr.m22; + lineDirWidths.position(4 * i); + lineDirWidths.put(vec1, 0, 3); } } if (0 < pointVertexCount) { - int index; - for (int i = 0; i < pointVertexCount; i++) { - index = 3 * i; - float x = pointVertices[index++]; - float y = pointVertices[index++]; - float z = pointVertices[index ]; - - index = 3 * i; - pointVertices[index++] = x * tr.m00 + y * tr.m01 + z * tr.m02 + tr.m03; - pointVertices[index++] = x * tr.m10 + y * tr.m11 + z * tr.m12 + tr.m13; - pointVertices[index ] = x * tr.m20 + y * tr.m21 + z * tr.m22 + tr.m23; + pointVertices.position(3 * i); + pointVertices.get(vec0); + vec1[0] = vec0[0] * tr.m00 + vec0[1] * tr.m01 + vec0[2] * tr.m02; + vec1[1] = vec0[0] * tr.m10 + vec0[1] * tr.m11 + vec0[2] * tr.m12; + vec1[2] = vec0[0] * tr.m20 + vec0[1] * tr.m21 + vec0[2] * tr.m22; + pointVertices.position(3 * i); + pointVertices.put(vec1); } } } @@ -8410,14 +8521,14 @@ public class PGraphicsOpenGL extends PGraphics { // the circle perimeter. The point shader will read these attributes and // displace the vertices in screen coordinates so the circles are always // camera facing (bilboards) - tess.pointSizes[2 * attribIdx + 0] = 0; - tess.pointSizes[2 * attribIdx + 1] = 0; + tess.pointSizes.put(2 * attribIdx + 0, 0); + tess.pointSizes.put(2 * attribIdx + 1, 0); attribIdx++; float val = 0; float inc = (float) SINCOS_LENGTH / perim; for (int k = 0; k < perim; k++) { - tess.pointSizes[2 * attribIdx + 0] = 0.5f * cosLUT[(int) val] * strokeWeight; - tess.pointSizes[2 * attribIdx + 1] = 0.5f * sinLUT[(int) val] * strokeWeight; + tess.pointSizes.put(2 * attribIdx + 0, 0.5f * cosLUT[(int) val] * strokeWeight); + tess.pointSizes.put(2 * attribIdx + 1, 0.5f * sinLUT[(int) val] * strokeWeight); val = (val + inc) % SINCOS_LENGTH; attribIdx++; } @@ -8425,15 +8536,14 @@ public class PGraphicsOpenGL extends PGraphics { // Adding vert0 to take into account the triangles of all // the preceding points. for (int k = 1; k < nvert - 1; k++) { - tess.pointIndices[indIdx++] = PGL.makeIndex(firstVert + 0); - tess.pointIndices[indIdx++] = PGL.makeIndex(firstVert + k); - tess.pointIndices[indIdx++] = PGL.makeIndex(firstVert + k + 1); + tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + 0)); + tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + k)); + tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + k + 1)); } // Final triangle between the last and first point: - tess.pointIndices[indIdx++] = PGL.makeIndex(firstVert + 0); - tess.pointIndices[indIdx++] = PGL.makeIndex(firstVert + 1); - tess.pointIndices[indIdx++] = PGL.makeIndex(firstVert + nvert - 1); - + tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + 0)); + tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + 1)); + tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + nvert - 1)); firstVert = vertIdx; } } @@ -8476,27 +8586,26 @@ public class PGraphicsOpenGL extends PGraphics { // the quad corners. The point shader will read these attributes and // displace the vertices in screen coordinates so the quads are always // camera facing (bilboards) - tess.pointSizes[2 * attribIdx + 0] = 0; - tess.pointSizes[2 * attribIdx + 1] = 0; + tess.pointSizes.put(2 * attribIdx + 0, 0); + tess.pointSizes.put(2 * attribIdx + 1, 0); attribIdx++; for (int k = 0; k < 4; k++) { - tess.pointSizes[2 * attribIdx + 0] = 0.5f * QUAD_SIGNS[k][0] * strokeWeight; - tess.pointSizes[2 * attribIdx + 1] = 0.5f * QUAD_SIGNS[k][1] * strokeWeight; + tess.pointSizes.put(2 * attribIdx + 0, 0.5f * QUAD_SIGNS[k][0] * strokeWeight); + tess.pointSizes.put(2 * attribIdx + 1, 0.5f * QUAD_SIGNS[k][1] * strokeWeight); attribIdx++; } // Adding firstVert to take into account the triangles of all // the preceding points. for (int k = 1; k < nvert - 1; k++) { - tess.pointIndices[indIdx++] = PGL.makeIndex(firstVert + 0); - tess.pointIndices[indIdx++] = PGL.makeIndex(firstVert + k); - tess.pointIndices[indIdx++] = PGL.makeIndex(firstVert + k + 1); + tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + 0)); + tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + k)); + tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + k + 1)); } // Final triangle between the last and first point: - tess.pointIndices[indIdx++] = PGL.makeIndex(firstVert + 0); - tess.pointIndices[indIdx++] = PGL.makeIndex(firstVert + 1); - tess.pointIndices[indIdx++] = PGL.makeIndex(firstVert + nvert - 1); - + tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + 0)); + tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + 1)); + tess.pointIndices.put(indIdx++, PGL.makeIndex(firstVert + nvert - 1)); firstVert = vertIdx; } } @@ -8545,7 +8654,7 @@ public class PGraphicsOpenGL extends PGraphics { int idx0 = tess.firstFillIndex; int offset = tess.firstFillVertex; for (int i = in.firstVertex; i <= in.lastVertex; i++) { - tess.fillIndices[idx0 + i] = PGL.makeIndex(offset + i); + tess.fillIndices.put(idx0 + i, PGL.makeIndex(offset + i)); } } @@ -8568,9 +8677,9 @@ public class PGraphicsOpenGL extends PGraphics { int idx = tess.firstFillIndex; int offset = tess.firstFillVertex; for (int i = in.firstVertex + 1; i < in.lastVertex; i++) { - tess.fillIndices[idx++] = PGL.makeIndex(offset + in.firstVertex); - tess.fillIndices[idx++] = PGL.makeIndex(offset + i); - tess.fillIndices[idx++] = PGL.makeIndex(offset + i + 1); + tess.fillIndices.put(idx++, PGL.makeIndex(offset + in.firstVertex)); + tess.fillIndices.put(idx++, PGL.makeIndex(offset + i)); + tess.fillIndices.put(idx++, PGL.makeIndex(offset + i + 1)); } } @@ -8596,13 +8705,13 @@ public class PGraphicsOpenGL extends PGraphics { int idx = tess.firstFillIndex; int offset = tess.firstFillVertex; for (int i = in.firstVertex + 1; i < in.lastVertex; i++) { - tess.fillIndices[idx++] = PGL.makeIndex(offset + i); + tess.fillIndices.put(idx++, PGL.makeIndex(offset + i)); if (i % 2 == 0) { - tess.fillIndices[idx++] = PGL.makeIndex(offset + i - 1); - tess.fillIndices[idx++] = PGL.makeIndex(offset + i + 1); + tess.fillIndices.put(idx++, PGL.makeIndex(offset + i - 1)); + tess.fillIndices.put(idx++, PGL.makeIndex(offset + i + 1)); } else { - tess.fillIndices[idx++] = PGL.makeIndex(offset + i + 1); - tess.fillIndices[idx++] = PGL.makeIndex(offset + i - 1); + tess.fillIndices.put(idx++, PGL.makeIndex(offset + i + 1)); + tess.fillIndices.put(idx++, PGL.makeIndex(offset + i - 1)); } } } @@ -8632,13 +8741,13 @@ public class PGraphicsOpenGL extends PGraphics { int i2 = offset + 4 * qd + 2; int i3 = offset + 4 * qd + 3; - tess.fillIndices[idx++] = PGL.makeIndex(i0); - tess.fillIndices[idx++] = PGL.makeIndex(i1); - tess.fillIndices[idx++] = PGL.makeIndex(i3); + tess.fillIndices.put(idx++, PGL.makeIndex(i0)); + tess.fillIndices.put(idx++, PGL.makeIndex(i1)); + tess.fillIndices.put(idx++, PGL.makeIndex(i3)); - tess.fillIndices[idx++] = PGL.makeIndex(i1); - tess.fillIndices[idx++] = PGL.makeIndex(i2); - tess.fillIndices[idx++] = PGL.makeIndex(i3); + tess.fillIndices.put(idx++, PGL.makeIndex(i1)); + tess.fillIndices.put(idx++, PGL.makeIndex(i2)); + tess.fillIndices.put(idx++, PGL.makeIndex(i3)); } } @@ -8668,13 +8777,13 @@ public class PGraphicsOpenGL extends PGraphics { int i2 = offset + 2 * qd + 1; int i3 = offset + 2 * qd; - tess.fillIndices[idx++] = PGL.makeIndex(i0); - tess.fillIndices[idx++] = PGL.makeIndex(i1); - tess.fillIndices[idx++] = PGL.makeIndex(i3); + tess.fillIndices.put(idx++, PGL.makeIndex(i0)); + tess.fillIndices.put(idx++, PGL.makeIndex(i1)); + tess.fillIndices.put(idx++, PGL.makeIndex(i3)); - tess.fillIndices[idx++] = PGL.makeIndex(i1); - tess.fillIndices[idx++] = PGL.makeIndex(i2); - tess.fillIndices[idx++] = PGL.makeIndex(i3); + tess.fillIndices.put(idx++, PGL.makeIndex(i1)); + tess.fillIndices.put(idx++, PGL.makeIndex(i2)); + tess.fillIndices.put(idx++, PGL.makeIndex(i3)); } } @@ -8759,27 +8868,27 @@ public class PGraphicsOpenGL extends PGraphics { protected void addLine(int i0, int i1, int vcount, int icount) { tess.putLineVertex(in, i0, i1, vcount); - tess.lineDirWidths[4 * vcount + 3] = +strokeWeight; - tess.lineIndices[icount++] = PGL.makeIndex(vcount); + tess.lineDirWidths.put(4 * vcount + 3, +strokeWeight); + tess.lineIndices.put(icount++, PGL.makeIndex(vcount)); vcount++; tess.putLineVertex(in, i0, i1, vcount); - tess.lineDirWidths[4 * vcount + 3] = -strokeWeight; - tess.lineIndices[icount++] = PGL.makeIndex(vcount); + tess.lineDirWidths.put(4 * vcount + 3, -strokeWeight); + tess.lineIndices.put(icount++, PGL.makeIndex(vcount)); vcount++; tess.putLineVertex(in, i1, i0, vcount); - tess.lineDirWidths[4 * vcount + 3] = -strokeWeight; - tess.lineIndices[icount++] = PGL.makeIndex(vcount); + tess.lineDirWidths.put(4 * vcount + 3, -strokeWeight); + tess.lineIndices.put(icount++, PGL.makeIndex(vcount)); // Starting a new triangle re-using prev vertices. - tess.lineIndices[icount++] = PGL.makeIndex(vcount); - tess.lineIndices[icount++] = PGL.makeIndex(vcount - 1); + tess.lineIndices.put(icount++, PGL.makeIndex(vcount)); + tess.lineIndices.put(icount++, PGL.makeIndex(vcount - 1)); vcount++; tess.putLineVertex(in, i1, i0, vcount); - tess.lineDirWidths[4 * vcount + 3] = +strokeWeight; - tess.lineIndices[icount++] = PGL.makeIndex(vcount); + tess.lineDirWidths.put(4 * vcount + 3, +strokeWeight); + tess.lineIndices.put(icount++, PGL.makeIndex(vcount)); } public void tessellateEdges() { diff --git a/java/libraries/opengl/src/processing/opengl/PShader.java b/java/libraries/opengl/src/processing/opengl/PShader.java index 7855513c7..3622eb454 100644 --- a/java/libraries/opengl/src/processing/opengl/PShader.java +++ b/java/libraries/opengl/src/processing/opengl/PShader.java @@ -24,9 +24,9 @@ package processing.opengl; import processing.core.*; - import java.io.IOException; import java.net.URL; +import java.nio.FloatBuffer; /** * This class encapsulates a GLSL shader program, including a vertex @@ -48,6 +48,14 @@ public class PShader { protected int vertexShader; protected int fragmentShader; + protected FloatBuffer vec1f; + protected FloatBuffer vec2f; + protected FloatBuffer vec3f; + protected FloatBuffer vec4f; + protected FloatBuffer mat2x2; + protected FloatBuffer mat3x3; + protected FloatBuffer mat4x4; + public PShader() { parent = null; pg = null; @@ -218,49 +226,91 @@ public class PShader { public void set1FloatVecUniform(int loc, float[] vec) { if (-1 < loc) { - pgl.glUniform1fv(loc, vec.length, vec, 0); + if (vec1f == null || vec1f.capacity() != vec.length) { + vec1f = pgl.createFloatBuffer(vec.length); + } + vec1f.rewind(); + vec1f.put(vec); + vec1f.flip(); + pgl.glUniform1fv(loc, vec.length, vec1f); } } public void set2FloatVecUniform(int loc, float[] vec) { if (-1 < loc) { - pgl.glUniform2fv(loc, vec.length / 2, vec, 0); + if (vec2f == null || vec2f.capacity() != vec.length) { + vec2f = pgl.createFloatBuffer(vec.length); + } + vec2f.rewind(); + vec2f.put(vec); + vec2f.flip(); + pgl.glUniform2fv(loc, vec.length / 2, vec2f); } } public void set3FloatVecUniform(int loc, float[] vec) { if (-1 < loc) { - pgl.glUniform3fv(loc, vec.length / 3, vec, 0); + if (vec3f == null || vec3f.capacity() != vec.length) { + vec3f = pgl.createFloatBuffer(vec.length); + } + vec3f.rewind(); + vec3f.put(vec); + vec3f.flip(); + pgl.glUniform3fv(loc, vec.length / 3, vec3f); } } public void set4FloatVecUniform(int loc, float[] vec) { if (-1 < loc) { - pgl.glUniform4fv(loc, vec.length / 4, vec, 0); + if (vec4f == null || vec4f.capacity() != vec.length) { + vec4f = pgl.createFloatBuffer(vec.length); + } + vec4f.rewind(); + vec4f.put(vec); + vec4f.flip(); + pgl.glUniform4fv(loc, vec.length / 4, vec4f); } } public void set2x2MatUniform(int loc, float[] mat) { if (-1 < loc) { - pgl.glUniformMatrix2fv(loc, 1, false, mat, 0); + if (mat2x2 == null) { + mat2x2 = pgl.createFloatBuffer(2 * 2); + } + mat2x2.rewind(); + mat2x2.put(mat); + mat2x2.flip(); + pgl.glUniformMatrix2fv(loc, 1, false, mat2x2); } } public void set3x3MatUniform(int loc, float[] mat) { if (-1 < loc) { - pgl.glUniformMatrix3fv(loc, 1, false, mat, 0); + if (mat3x3 == null) { + mat3x3 = pgl.createFloatBuffer(3 * 3); + } + mat3x3.rewind(); + mat3x3.put(mat); + mat3x3.flip(); + pgl.glUniformMatrix3fv(loc, 1, false, mat3x3); } } public void set4x4MatUniform(int loc, float[] mat) { if (-1 < loc) { - pgl.glUniformMatrix4fv(loc, 1, false, mat, 0); + if (mat4x4 == null) { + mat4x4 = pgl.createFloatBuffer(4 * 4); + } + mat4x4.rewind(); + mat4x4.put(mat); + mat4x4.flip(); + pgl.glUniformMatrix4fv(loc, 1, false, mat4x4); } } diff --git a/java/libraries/opengl/src/processing/opengl/PShape3D.java b/java/libraries/opengl/src/processing/opengl/PShape3D.java index 1e16f3cda..5ddb0d087 100644 --- a/java/libraries/opengl/src/processing/opengl/PShape3D.java +++ b/java/libraries/opengl/src/processing/opengl/PShape3D.java @@ -864,13 +864,15 @@ public class PShape3D extends PShape { updateTesselation(); - Arrays.fill(tess.fillColors, 0, tess.fillVertexCount, fillColor); - + int[] temp = new int[tess.fillVertexCount]; + Arrays.fill(temp, 0, tess.fillVertexCount, fillColor); + tess.fillColors.rewind(); + tess.fillColors.put(temp); + modifiedFillColors = true; modified(); } - - + ////////////////////////////////////////////////////////////// // STROKE COLOR @@ -980,13 +982,19 @@ public class PShape3D extends PShape { updateTesselation(); if (0 < tess.lineVertexCount) { - Arrays.fill(tess.lineColors, 0, tess.lineVertexCount, strokeColor); + int[] temp = new int[tess.lineVertexCount]; + Arrays.fill(temp, 0, tess.lineVertexCount, strokeColor); + tess.lineColors.rewind(); + tess.lineColors.put(temp); modifiedLineColors = true; modified(); } if (0 < tess.pointVertexCount) { - Arrays.fill(tess.pointColors, 0, tess.pointVertexCount, strokeColor); + int[] temp = new int[tess.pointVertexCount]; + Arrays.fill(temp, 0, tess.pointVertexCount, strokeColor); + tess.pointColors.rewind(); + tess.pointColors.put(temp); modifiedPointColors = true; modified(); } @@ -1105,8 +1113,11 @@ public class PShape3D extends PShape { updateTesselation(); - Arrays.fill(tess.fillColors, 0, tess.pointVertexCount, tintColor); - + int[] temp = new int[tess.fillVertexCount]; + Arrays.fill(temp, 0, tess.fillVertexCount, tintColor); + tess.fillColors.rewind(); + tess.fillColors.put(temp); + modifiedFillColors = true; modified(); } @@ -1164,8 +1175,11 @@ public class PShape3D extends PShape { } updateTesselation(); - - Arrays.fill(tess.fillAmbient, 0, tess.fillVertexCount, ambientColor); + + int[] temp = new int[tess.fillVertexCount]; + Arrays.fill(temp, 0, tess.fillVertexCount, ambientColor); + tess.fillAmbient.rewind(); + tess.fillAmbient.put(temp); modifiedFillAmbient = true; modified(); @@ -1226,7 +1240,10 @@ public class PShape3D extends PShape { updateTesselation(); - Arrays.fill(tess.fillSpecular, 0, tess.fillVertexCount, specularColor); + int[] temp = new int[tess.fillVertexCount]; + Arrays.fill(temp, 0, tess.fillVertexCount, specularColor); + tess.fillSpecular.rewind(); + tess.fillSpecular.put(temp); modifiedFillSpecular = true; modified(); @@ -1287,7 +1304,10 @@ public class PShape3D extends PShape { updateTesselation(); - Arrays.fill(tess.fillEmissive, 0, tess.fillVertexCount, emissiveColor); + int[] temp = new int[tess.fillVertexCount]; + Arrays.fill(temp, 0, tess.fillVertexCount, emissiveColor); + tess.fillEmissive.rewind(); + tess.fillEmissive.put(temp); modifiedFillEmissive = true; modified(); @@ -1318,7 +1338,10 @@ public class PShape3D extends PShape { updateTesselation(); - Arrays.fill(tess.fillShininess, 0, tess.fillVertexCount, shininess); + float[] temp = new float[tess.fillVertexCount]; + Arrays.fill(temp, 0, tess.fillVertexCount, shininess); + tess.fillShininess.rewind(); + tess.fillShininess.put(temp); modifiedFillShininess = true; modified(); @@ -1335,7 +1358,7 @@ public class PShape3D extends PShape { if (family == GROUP) { count = updateCenter(vec, count); } else { - count += tess.getCenter(vec); + count += tess.sumVertices(vec); } return count; } @@ -1357,7 +1380,7 @@ public class PShape3D extends PShape { super.translate(tx, ty); } else { PVector vec = new PVector(); - int count = tess.getCenter(vec); + int count = tess.sumVertices(vec); vec.x /= count; vec.y /= count; @@ -1386,7 +1409,7 @@ public class PShape3D extends PShape { super.translate(tx, ty, tz); } else { PVector vec = new PVector(); - int count = tess.getCenter(vec); + int count = tess.sumVertices(vec); vec.x /= count; vec.y /= count; vec.z /= count; @@ -2046,49 +2069,94 @@ public class PShape3D extends PShape { return tess.fillIndexCount; } - public float[] fillVertices() { + public float[] fillVertices(float[] vertices) { updateTesselation(); - return tess.fillVertices; + if (vertices == null || vertices.length != tess.fillVertices.capacity()) { + vertices = new float[tess.fillVertices.capacity()]; + } + tess.fillVertices.rewind(); + tess.fillVertices.get(vertices); + return vertices; } - public int[] fillColors() { + public int[] fillColors(int[] colors) { updateTesselation(); - return tess.fillColors; + if (colors == null || colors.length != tess.fillColors.capacity()) { + colors = new int[tess.fillVertices.capacity()]; + } + tess.fillColors.rewind(); + tess.fillColors.get(colors); + return colors; } - public float[] fillNormals() { + public float[] fillNormals(float[] normals) { updateTesselation(); - return tess.fillNormals; + if (normals == null || normals.length != tess.fillNormals.capacity()) { + normals = new float[tess.fillNormals.capacity()]; + } + tess.fillNormals.rewind(); + tess.fillNormals.get(normals); + return normals; } - public float[] fillTexCoords() { + public float[] fillTexCoords(float[] texcoords) { updateTesselation(); - return tess.fillTexcoords; + if (texcoords == null || texcoords.length != tess.fillTexcoords.capacity()) { + texcoords = new float[tess.fillTexcoords.capacity()]; + } + tess.fillTexcoords.rewind(); + tess.fillTexcoords.get(texcoords); + return texcoords; } - public int[] fillAmbient() { + public int[] fillAmbient(int[] ambient) { updateTesselation(); - return tess.fillAmbient; + if (ambient == null || ambient.length != tess.fillAmbient.capacity()) { + ambient = new int[tess.fillAmbient.capacity()]; + } + tess.fillAmbient.rewind(); + tess.fillAmbient.get(ambient); + return ambient; } - public int[] fillSpecular() { + public int[] fillSpecular(int[] specular) { updateTesselation(); - return tess.fillSpecular; + if (specular == null || specular.length != tess.fillSpecular.capacity()) { + specular = new int[tess.fillSpecular.capacity()]; + } + tess.fillSpecular.rewind(); + tess.fillSpecular.get(specular); + return specular; } - public int[] fillEmissive() { + public int[] fillEmissive(int[] emissive) { updateTesselation(); - return tess.fillEmissive; + if (emissive == null || emissive.length != tess.fillEmissive.capacity()) { + emissive = new int[tess.fillEmissive.capacity()]; + } + tess.fillEmissive.rewind(); + tess.fillEmissive.get(emissive); + return emissive; } - public float[] fillShininess() { + public float[] fillShininess(float[] shininess) { updateTesselation(); - return tess.fillShininess; + if (shininess == null || shininess.length != tess.fillShininess.capacity()) { + shininess = new float[tess.fillShininess.capacity()]; + } + tess.fillShininess.rewind(); + tess.fillShininess.get(shininess); + return shininess; } - public int[] fillIndices() { - updateTesselation(); - return tess.fillIndices; + public int[] fillIndices(int[] indices) { + updateTesselation(); + if (indices == null || indices.length != tess.fillIndices.capacity()) { + indices = new int[tess.fillIndices.capacity()]; + } + tess.fillIndices.rewind(); + tess.fillIndices.get(indices); + return indices; } public int firstLineVertex() { @@ -2121,24 +2189,44 @@ public class PShape3D extends PShape { return tess.lineIndexCount; } - public float[] lineVertices() { + public float[] lineVertices(float[] vertices) { updateTesselation(); - return tess.lineVertices; + if (vertices == null || vertices.length != tess.lineVertices.capacity()) { + vertices = new float[tess.lineVertices.capacity()]; + } + tess.lineVertices.rewind(); + tess.lineVertices.get(vertices); + return vertices; } - public int[] lineColors() { + public int[] lineColors(int[] colors) { updateTesselation(); - return tess.lineColors; + if (colors == null || colors.length != tess.lineColors.capacity()) { + colors = new int[tess.lineColors.capacity()]; + } + tess.lineColors.rewind(); + tess.lineColors.get(colors); + return colors; } - public float[] lineAttributes() { + public float[] lineAttributes(float[] attribs) { updateTesselation(); - return tess.lineDirWidths; + if (attribs == null || attribs.length != tess.lineDirWidths.capacity()) { + attribs = new float[tess.lineDirWidths.capacity()]; + } + tess.lineDirWidths.rewind(); + tess.lineDirWidths.get(attribs); + return attribs; } - public int[] lineIndices() { + public int[] lineIndices(int[] indices) { updateTesselation(); - return tess.lineIndices; + if (indices == null || indices.length != tess.lineIndices.capacity()) { + indices = new int[tess.lineIndices.capacity()]; + } + tess.lineIndices.rewind(); + tess.lineIndices.get(indices); + return indices; } public int firstPointVertex() { @@ -2171,24 +2259,44 @@ public class PShape3D extends PShape { return tess.pointIndexCount; } - public float[] pointVertices() { + public float[] pointVertices(float[] vertices) { updateTesselation(); - return tess.pointVertices; + if (vertices == null || vertices.length != tess.pointVertices.capacity()) { + vertices = new float[tess.pointVertices.capacity()]; + } + tess.pointVertices.rewind(); + tess.pointVertices.get(vertices); + return vertices; } - public int[] pointColors() { + public int[] pointColors(int[] colors) { updateTesselation(); - return tess.pointColors; + if (colors == null || colors.length != tess.pointColors.capacity()) { + colors = new int[tess.pointColors.capacity()]; + } + tess.pointColors.rewind(); + tess.pointColors.get(colors); + return colors; } - public float[] pointAttributes() { + public float[] pointAttributes(float[] attribs) { updateTesselation(); - return tess.pointSizes; + if (attribs == null || attribs.length != tess.pointSizes.capacity()) { + attribs = new float[tess.pointSizes.capacity()]; + } + tess.pointSizes.rewind(); + tess.pointSizes.get(attribs); + return attribs; } - public int[] pointIndices() { + public int[] pointIndices(int[] indices) { updateTesselation(); - return tess.pointIndices; + if (indices == null || indices.length != tess.pointIndices.capacity()) { + indices = new int[tess.pointIndices.capacity()]; + } + tess.pointIndices.rewind(); + tess.pointIndices.get(indices); + return indices; } public FloatBuffer mapFillVertices() { @@ -2393,6 +2501,7 @@ public class PShape3D extends PShape { } } else { if (!tessellated && shapeEnded) { + tess.clear(); tessellator.setInGeometry(in); tessellator.setTessGeometry(tess); tessellator.setFill(fill || texture != null); @@ -2661,51 +2770,85 @@ public class PShape3D extends PShape { // Copying any data remaining in the caches if (root.fillVerticesCache != null && root.fillVerticesCache.hasData()) { + root.fillVerticesCache.prepareForCopy(); root.copyFillVertices(root.fillVerticesCache.offset, root.fillVerticesCache.size, root.fillVerticesCache.floatData); root.fillVerticesCache.reset(); } if (root.fillColorsCache != null && root.fillColorsCache.hasData()) { + root.fillColorsCache.prepareForCopy(); root.copyFillColors(root.fillColorsCache.offset, root.fillColorsCache.size, root.fillColorsCache.intData); root.fillColorsCache.reset(); } if (root.fillNormalsCache != null && root.fillNormalsCache.hasData()) { + root.fillNormalsCache.prepareForCopy(); root.copyFillNormals(root.fillNormalsCache.offset, root.fillNormalsCache.size, root.fillNormalsCache.floatData); root.fillNormalsCache.reset(); } if (root.fillTexCoordsCache != null && root.fillTexCoordsCache.hasData()) { + root.fillTexCoordsCache.prepareForCopy(); root.copyFillTexCoords(root.fillTexCoordsCache.offset, root.fillTexCoordsCache.size, root.fillTexCoordsCache.floatData); root.fillTexCoordsCache.reset(); } + if (root.fillAmbientCache != null && root.fillAmbientCache.hasData()) { + root.fillAmbientCache.prepareForCopy(); + root.copyFillAmbient(root.fillAmbientCache.offset, root.fillAmbientCache.size, root.fillAmbientCache.intData); + root.fillAmbientCache.reset(); + } + + if (root.fillSpecularCache != null && root.fillSpecularCache.hasData()) { + root.fillSpecularCache.prepareForCopy(); + root.copyfillSpecular(root.fillSpecularCache.offset, root.fillSpecularCache.size, root.fillSpecularCache.intData); + root.fillSpecularCache.reset(); + } + + if (root.fillEmissiveCache != null && root.fillEmissiveCache.hasData()) { + root.fillEmissiveCache.prepareForCopy(); + root.copyFillEmissive(root.fillEmissiveCache.offset, root.fillEmissiveCache.size, root.fillEmissiveCache.intData); + root.fillEmissiveCache.reset(); + } + + if (root.fillShininessCache != null && root.fillShininessCache.hasData()) { + root.fillShininessCache.prepareForCopy(); + root.copyFillShininess(root.fillShininessCache.offset, root.fillShininessCache.size, root.fillShininessCache.floatData); + root.fillShininessCache.reset(); + } + if (root.lineVerticesCache != null && root.lineVerticesCache.hasData()) { + root.lineVerticesCache.prepareForCopy(); root.copyLineVertices(root.lineVerticesCache.offset, root.lineVerticesCache.size, root.lineVerticesCache.floatData); root.lineVerticesCache.reset(); } if (root.lineColorsCache != null && root.lineColorsCache.hasData()) { + root.lineColorsCache.prepareForCopy(); root.copyLineColors(root.lineColorsCache.offset, root.lineColorsCache.size, root.lineColorsCache.intData); root.lineColorsCache.reset(); } if (root.lineAttributesCache != null && root.lineAttributesCache.hasData()) { + root.lineAttributesCache.prepareForCopy(); root.copyLineAttributes(root.lineAttributesCache.offset, root.lineAttributesCache.size, root.lineAttributesCache.floatData); root.lineAttributesCache.reset(); } if (root.pointVerticesCache != null && root.pointVerticesCache.hasData()) { + root.pointVerticesCache.prepareForCopy(); root.copyPointVertices(root.pointVerticesCache.offset, root.pointVerticesCache.size, root.pointVerticesCache.floatData); root.pointVerticesCache.reset(); } if (root.pointColorsCache != null && root.pointColorsCache.hasData()) { + root.pointColorsCache.prepareForCopy(); root.copyPointColors(root.pointColorsCache.offset, root.pointColorsCache.size, root.pointColorsCache.intData); root.pointColorsCache.reset(); } if (root.pointAttributesCache != null && root.pointAttributesCache.hasData()) { + root.pointAttributesCache.prepareForCopy(); root.copyPointAttributes(root.pointAttributesCache.offset, root.pointAttributesCache.size, root.pointAttributesCache.floatData); root.pointAttributesCache.reset(); } @@ -2763,7 +2906,7 @@ public class PShape3D extends PShape { // level of the shape hierarchy. protected void aggregateImpl() { if (family == GROUP) { - tess.reset(); + tess.clear(); boolean firstGeom = true; boolean firstStroke = true; @@ -2996,12 +3139,14 @@ public class PShape3D extends PShape { child.copyFillGeometryToRoot(); } } else { - if (0 < tess.fillVertexCount && 0 < tess.fillIndexCount) { + if (0 < tess.fillVertexCount && 0 < tess.fillIndexCount) { + tess.prepareFillVerticesForCopy(); root.copyFillGeometry(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillVertices, tess.fillColors, tess.fillNormals, tess.fillTexcoords, tess.fillAmbient, tess.fillSpecular, tess.fillEmissive, tess.fillShininess); root.fillVertCopyOffset += tess.fillVertexCount; + tess.prepareFillIndicesForCopy(); root.copyFillIndices(root.fillIndCopyOffset, tess.fillIndexCount, tess.fillIndices); root.fillIndCopyOffset += tess.fillIndexCount; } @@ -3017,15 +3162,17 @@ public class PShape3D extends PShape { } } else { - if (0 < tess.fillVertexCount) { + if (0 < tess.fillVertexCount) { + tess.prepareFillVerticesForCopy(); + if (modifiedFillVertices) { if (root.fillVerticesCache == null) { 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.fillVerticesCache.prepareForCopy(); root.copyFillVertices(root.fillVerticesCache.offset, root.fillVerticesCache.size, root.fillVerticesCache.floatData); root.fillVerticesCache.reset(); } @@ -3037,6 +3184,7 @@ public class PShape3D extends PShape { root.fillColorsCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillColors); modifiedFillColors = false; } else if (root.fillColorsCache != null && root.fillColorsCache.hasData()) { + root.fillColorsCache.prepareForCopy(); root.copyFillColors(root.fillColorsCache.offset, root.fillColorsCache.size, root.fillColorsCache.intData); root.fillColorsCache.reset(); } @@ -3048,6 +3196,7 @@ public class PShape3D extends PShape { root.fillNormalsCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillNormals); modifiedFillNormals = false; } else if (root.fillNormalsCache != null && root.fillNormalsCache.hasData()) { + root.fillNormalsCache.prepareForCopy(); root.copyFillNormals(root.fillNormalsCache.offset, root.fillNormalsCache.size, root.fillNormalsCache.floatData); root.fillNormalsCache.reset(); } @@ -3059,6 +3208,7 @@ public class PShape3D extends PShape { root.fillTexCoordsCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillTexcoords); modifiedFillTexCoords = false; } else if (root.fillTexCoordsCache != null && root.fillTexCoordsCache.hasData()) { + root.fillTexCoordsCache.prepareForCopy(); root.copyFillTexCoords(root.fillTexCoordsCache.offset, root.fillTexCoordsCache.size, root.fillTexCoordsCache.floatData); root.fillTexCoordsCache.reset(); } @@ -3070,7 +3220,8 @@ public class PShape3D extends PShape { 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.prepareForCopy(); + root.copyFillAmbient(root.fillAmbientCache.offset, root.fillAmbientCache.size, root.fillAmbientCache.intData); root.fillAmbientCache.reset(); } @@ -3081,6 +3232,7 @@ public class PShape3D extends PShape { root.fillSpecularCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillSpecular); modifiedFillSpecular = false; } else if (root.fillSpecularCache != null && root.fillSpecularCache.hasData()) { + root.fillSpecularCache.prepareForCopy(); root.copyfillSpecular(root.fillSpecularCache.offset, root.fillSpecularCache.size, root.fillSpecularCache.intData); root.fillSpecularCache.reset(); } @@ -3092,7 +3244,8 @@ public class PShape3D extends PShape { 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.prepareForCopy(); + root.copyFillEmissive(root.fillEmissiveCache.offset, root.fillEmissiveCache.size, root.fillEmissiveCache.intData); root.fillEmissiveCache.reset(); } @@ -3103,12 +3256,15 @@ public class PShape3D extends PShape { 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.prepareForCopy(); + root.copyFillShininess(root.fillShininessCache.offset, root.fillShininessCache.size, root.fillShininessCache.floatData); root.fillShininessCache.reset(); } } if (0 < tess.lineVertexCount) { + tess.prepareLineVerticesForCopy(); + if (modifiedLineVertices) { if (root.lineVerticesCache == null) { root.lineVerticesCache = new VertexCache(3, true); @@ -3116,6 +3272,7 @@ public class PShape3D extends PShape { root.lineVerticesCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineVertices); modifiedLineVertices = false; } else if (root.lineVerticesCache != null && root.lineVerticesCache.hasData()) { + root.lineVerticesCache.prepareForCopy(); root.copyLineVertices(root.lineVerticesCache.offset, root.lineVerticesCache.size, root.lineVerticesCache.floatData); root.lineVerticesCache.reset(); } @@ -3127,6 +3284,7 @@ public class PShape3D extends PShape { root.lineColorsCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineColors); modifiedLineColors = false; } else if (root.lineColorsCache != null && root.lineColorsCache.hasData()) { + root.lineColorsCache.prepareForCopy(); root.copyLineColors(root.lineColorsCache.offset, root.lineColorsCache.size, root.lineColorsCache.intData); root.lineColorsCache.reset(); } @@ -3138,12 +3296,15 @@ public class PShape3D extends PShape { root.lineAttributesCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineDirWidths); modifiedLineAttributes = false; } else if (root.lineAttributesCache != null && root.lineAttributesCache.hasData()) { + root.lineAttributesCache.prepareForCopy(); root.copyLineAttributes(root.lineAttributesCache.offset, root.lineAttributesCache.size, root.lineAttributesCache.floatData); root.lineAttributesCache.reset(); } } if (0 < tess.pointVertexCount) { + tess.preparePointVerticesForCopy(); + if (modifiedPointVertices) { if (root.pointVerticesCache == null) { root.pointVerticesCache = new VertexCache(3, true); @@ -3151,6 +3312,7 @@ public class PShape3D extends PShape { root.pointVerticesCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointVertices); modifiedPointVertices = false; } else if (root.pointVerticesCache != null && root.pointVerticesCache.hasData()) { + root.pointVerticesCache.prepareForCopy(); root.copyPointVertices(root.pointVerticesCache.offset, root.pointVerticesCache.size, root.pointVerticesCache.floatData); root.pointVerticesCache.reset(); } @@ -3162,6 +3324,7 @@ public class PShape3D extends PShape { root.pointColorsCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointColors); modifiedPointColors = false; } else if (root.pointColorsCache != null && root.pointColorsCache.hasData()) { + root.pointColorsCache.prepareForCopy(); root.copyPointColors(root.pointColorsCache.offset, root.pointColorsCache.size, root.pointColorsCache.intData); root.pointColorsCache.reset(); } @@ -3173,6 +3336,7 @@ public class PShape3D extends PShape { root.pointAttributesCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointSizes); modifiedPointAttributes = false; } else if (root.pointAttributesCache != null && root.pointAttributesCache.hasData()) { + root.pointAttributesCache.prepareForCopy(); root.copyPointAttributes(root.pointAttributesCache.offset, root.pointAttributesCache.size, root.pointAttributesCache.floatData); root.pointAttributesCache.reset(); } @@ -3188,101 +3352,101 @@ public class PShape3D extends PShape { protected void copyFillGeometry(int offset, int size, - float[] vertices, int[] colors, - float[] normals, float[] texcoords, - int[] ambient, int[] specular, int[] emissive, float[] shininess) { + FloatBuffer vertices, IntBuffer colors, + FloatBuffer normals, FloatBuffer texcoords, + IntBuffer ambient, IntBuffer specular, IntBuffer emissive, FloatBuffer shininess) { int offsetf = offset * PGL.SIZEOF_FLOAT; int offseti = offset * PGL.SIZEOF_INT; int sizef = size * PGL.SIZEOF_FLOAT; int sizei = size * PGL.SIZEOF_INT; pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillVertexBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, FloatBuffer.wrap(vertices, 0, 3 * size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, vertices); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillColorBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, IntBuffer.wrap(colors, 0, size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, colors); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillNormalBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, FloatBuffer.wrap(normals, 0, 3 * size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, normals); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillTexCoordBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 2 * offsetf, 2 * sizef, FloatBuffer.wrap(texcoords, 0, 2 * size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 2 * offsetf, 2 * sizef, texcoords); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillAmbientBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, IntBuffer.wrap(ambient, 0, size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, ambient); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillSpecularBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, IntBuffer.wrap(specular, 0, size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, specular); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillEmissiveBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, IntBuffer.wrap(emissive, 0, size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, emissive); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillShininessBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offsetf, sizef, FloatBuffer.wrap(shininess, 0, size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offsetf, sizef, shininess); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyFillVertices(int offset, int size, float[] vertices) { + protected void copyFillVertices(int offset, int size, FloatBuffer vertices) { pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillVertexBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, 3 * size * PGL.SIZEOF_FLOAT, FloatBuffer.wrap(vertices, 0, 3 * size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, 3 * size * PGL.SIZEOF_FLOAT, vertices); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyFillColors(int offset, int size, int[] colors) { + protected void copyFillColors(int offset, int size, IntBuffer colors) { pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillColorBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, IntBuffer.wrap(colors, 0, size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, colors); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyFillNormals(int offset, int size, float[] normals) { + protected void copyFillNormals(int offset, int size, FloatBuffer normals) { pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillNormalBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, 3 * size * PGL.SIZEOF_FLOAT, FloatBuffer.wrap(normals, 0, 3 * size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, 3 * size * PGL.SIZEOF_FLOAT, normals); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyFillTexCoords(int offset, int size, float[] texcoords) { + protected void copyFillTexCoords(int offset, int size, FloatBuffer texcoords) { pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillTexCoordBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 2 * offset * PGL.SIZEOF_FLOAT, 2 * size * PGL.SIZEOF_FLOAT, FloatBuffer.wrap(texcoords, 0, 2 * size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 2 * offset * PGL.SIZEOF_FLOAT, 2 * size * PGL.SIZEOF_FLOAT, texcoords); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyfillAmbient(int offset, int size, int[] ambient) { + protected void copyFillAmbient(int offset, int size, IntBuffer ambient) { pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillAmbientBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, IntBuffer.wrap(ambient, 0, size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, ambient); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyfillSpecular(int offset, int size, int[] specular) { + protected void copyfillSpecular(int offset, int size, IntBuffer specular) { pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillSpecularBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, IntBuffer.wrap(specular, 0, size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, specular); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyfillEmissive(int offset, int size, int[] emissive) { + protected void copyFillEmissive(int offset, int size, IntBuffer emissive) { pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillEmissiveBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, IntBuffer.wrap(emissive, 0, size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, emissive); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyfillShininess(int offset, int size, float[] shininess) { + protected void copyFillShininess(int offset, int size, FloatBuffer shininess) { pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillShininessBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_FLOAT, size * PGL.SIZEOF_FLOAT, FloatBuffer.wrap(shininess, 0, size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_FLOAT, size * PGL.SIZEOF_FLOAT, shininess); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyFillIndices(int offset, int size, int[] indices) { + protected void copyFillIndices(int offset, int size, IntBuffer indices) { pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glFillIndexBufferID); - pgl.glBufferSubData(PGL.GL_ELEMENT_ARRAY_BUFFER, offset * PGL.SIZEOF_INDEX, size * PGL.SIZEOF_INDEX, IntBuffer.wrap(indices, 0, size)); + pgl.glBufferSubData(PGL.GL_ELEMENT_ARRAY_BUFFER, offset * PGL.SIZEOF_INDEX, size * PGL.SIZEOF_INDEX, indices); pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } @@ -3322,10 +3486,12 @@ public class PShape3D extends PShape { } } else { if (hasLines) { + tess.prepareLineVerticesForCopy(); root.copyLineGeometry(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineVertices, tess.lineColors, tess.lineDirWidths); root.lineVertCopyOffset += tess.lineVertexCount; + tess.prepareLineIndicesForCopy(); root.copyLineIndices(root.lineIndCopyOffset, tess.lineIndexCount, tess.lineIndices); root.lineIndCopyOffset += tess.lineIndexCount; } @@ -3334,49 +3500,49 @@ public class PShape3D extends PShape { protected void copyLineGeometry(int offset, int size, - float[] vertices, int[] colors, float[] attribs) { + FloatBuffer vertices, IntBuffer colors, FloatBuffer attribs) { int offsetf = offset * PGL.SIZEOF_FLOAT; int sizef = size * PGL.SIZEOF_FLOAT; int offseti = offset * PGL.SIZEOF_INT; int sizei = size * PGL.SIZEOF_INT; pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineVertexBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, FloatBuffer.wrap(vertices, 0, 3 * size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, vertices); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineColorBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, IntBuffer.wrap(colors, 0, size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, colors); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineDirWidthBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 4 * offsetf, 4 * sizef, FloatBuffer.wrap(attribs, 0, 4 * size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 4 * offsetf, 4 * sizef, attribs); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyLineVertices(int offset, int size, float[] vertices) { + protected void copyLineVertices(int offset, int size, FloatBuffer vertices) { pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineVertexBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, 3 * size * PGL.SIZEOF_FLOAT, FloatBuffer.wrap(vertices, 0, 3 * size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, 3 * size * PGL.SIZEOF_FLOAT, vertices); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyLineColors(int offset, int size, int[] colors) { + protected void copyLineColors(int offset, int size, IntBuffer colors) { pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineColorBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, IntBuffer.wrap(colors, 0, size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, colors); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyLineAttributes(int offset, int size, float[] attribs) { + protected void copyLineAttributes(int offset, int size, FloatBuffer attribs) { pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineDirWidthBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, 4 * size * PGL.SIZEOF_FLOAT, FloatBuffer.wrap(attribs, 0, 4 * size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, 4 * size * PGL.SIZEOF_FLOAT, attribs); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyLineIndices(int offset, int size, int[] indices) { + protected void copyLineIndices(int offset, int size, IntBuffer indices) { pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glLineIndexBufferID); - pgl.glBufferSubData(PGL.GL_ELEMENT_ARRAY_BUFFER, offset * PGL.SIZEOF_INDEX, size * PGL.SIZEOF_INDEX, IntBuffer.wrap(indices, 0, size)); + pgl.glBufferSubData(PGL.GL_ELEMENT_ARRAY_BUFFER, offset * PGL.SIZEOF_INDEX, size * PGL.SIZEOF_INDEX, indices); pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } @@ -3416,10 +3582,12 @@ public class PShape3D extends PShape { } } else { if (hasPoints) { + tess.preparePointVerticesForCopy(); root.copyPointGeometry(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointVertices, tess.pointColors, tess.pointSizes); root.pointVertCopyOffset += tess.pointVertexCount; + tess.preparePointIndicesForCopy(); root.copyPointIndices(root.pointIndCopyOffset, tess.pointIndexCount, tess.pointIndices); root.pointIndCopyOffset += tess.pointIndexCount; } @@ -3428,49 +3596,49 @@ public class PShape3D extends PShape { protected void copyPointGeometry(int offset, int size, - float[] vertices, int[] colors, float[] attribs) { + FloatBuffer vertices, IntBuffer colors, FloatBuffer attribs) { int offsetf = offset * PGL.SIZEOF_FLOAT; int sizef = size * PGL.SIZEOF_FLOAT; int offseti = offset * PGL.SIZEOF_INT; int sizei = size * PGL.SIZEOF_INT; pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointVertexBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, FloatBuffer.wrap(vertices, 0, 3 * size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, vertices); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointColorBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, IntBuffer.wrap(colors, 0, size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, colors); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointSizeBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 2 * offsetf, 2 * sizef, FloatBuffer.wrap(attribs, 0, 2 * size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 2 * offsetf, 2 * sizef, attribs); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyPointVertices(int offset, int size, float[] vertices) { + protected void copyPointVertices(int offset, int size, FloatBuffer vertices) { pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointVertexBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, 3 * size * PGL.SIZEOF_FLOAT, FloatBuffer.wrap(vertices, 0, 3 * size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, 3 * size * PGL.SIZEOF_FLOAT, vertices); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyPointColors(int offset, int size, int[] colors) { + protected void copyPointColors(int offset, int size, IntBuffer colors) { pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointColorBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, IntBuffer.wrap(colors, 0, size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, colors); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyPointAttributes(int offset, int size, float[] attribs) { + protected void copyPointAttributes(int offset, int size, FloatBuffer attribs) { pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointSizeBufferID); - pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 2 * offset * PGL.SIZEOF_FLOAT, 2 * size * PGL.SIZEOF_FLOAT, FloatBuffer.wrap(attribs, 0, 2 * size)); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 2 * offset * PGL.SIZEOF_FLOAT, 2 * size * PGL.SIZEOF_FLOAT, attribs); pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyPointIndices(int offset, int size, int[] indices) { + protected void copyPointIndices(int offset, int size, IntBuffer indices) { pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glPointIndexBufferID); - pgl.glBufferSubData(PGL.GL_ELEMENT_ARRAY_BUFFER, offset * PGL.SIZEOF_INDEX, size * PGL.SIZEOF_INDEX, IntBuffer.wrap(indices, 0, size)); + pgl.glBufferSubData(PGL.GL_ELEMENT_ARRAY_BUFFER, offset * PGL.SIZEOF_INDEX, size * PGL.SIZEOF_INDEX, indices); pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } @@ -3784,19 +3952,19 @@ public class PShape3D extends PShape { // to the VBOs with fewer calls. protected class VertexCache { boolean isFloat; - int ncoords; - int offset; - int size; - float[] floatData; - int[] intData; + int ncoords; // Number of components per data element + int offset; // Offset (in the dest VBO) to start copying this data to + int size; // Total number of data elements + FloatBuffer floatData; + IntBuffer intData; VertexCache(int ncoords, boolean isFloat) { this.ncoords = ncoords; this.isFloat = isFloat; if (isFloat) { - this.floatData = new float[ncoords * PGL.DEFAULT_VERTEX_CACHE_SIZE]; + this.floatData = pgl.createFloatBuffer(ncoords * PGL.DEFAULT_VERTEX_CACHE_SIZE); } else { - this.intData = new int[ncoords * PGL.DEFAULT_VERTEX_CACHE_SIZE]; + this.intData = pgl.createIntBuffer(ncoords * PGL.DEFAULT_VERTEX_CACHE_SIZE); } this.offset = 0; this.size = 0; @@ -3805,96 +3973,50 @@ public class PShape3D extends PShape { void reset() { offset = 0; size = 0; - } + if (isFloat) { + floatData.clear(); + } else { + intData.clear(); + } + } - void add(int dataOffset, int dataSize, float[] newData) { + void add(int dataOffset, int dataSize, FloatBuffer newData) { if (size == 0) { offset = dataOffset; } - int oldSize = floatData.length / ncoords; + int oldSize = floatData.capacity() / ncoords; if (size + dataSize >= oldSize) { - int newSize = expandSize(oldSize, size + dataSize); + int newSize = expandSize(oldSize, size + dataSize); + prepareFloatDataForCopy(); expand(newSize); } - if (dataSize <= PGraphicsOpenGL.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) { - floatData[destIndex++] = newData[srcIndex++]; - floatData[destIndex ] = newData[srcIndex ]; - } else if (ncoords == 3) { - floatData[destIndex++] = newData[srcIndex++]; - floatData[destIndex++] = newData[srcIndex++]; - floatData[destIndex ] = newData[srcIndex ]; - } else if (ncoords == 4) { - floatData[destIndex++] = newData[srcIndex++]; - floatData[destIndex++] = newData[srcIndex++]; - floatData[destIndex++] = newData[srcIndex++]; - floatData[destIndex ] = newData[srcIndex ]; - } else { - for (int j = 0; j < ncoords; j++) { - floatData[destIndex++] = newData[srcIndex++]; - } - } - } - } else { - PApplet.arrayCopy(newData, 0, floatData, ncoords * size, ncoords * dataSize); - } + floatData.position(ncoords * size); + floatData.put(newData); size += dataSize; } - void add(int dataOffset, int dataSize, int[] newData) { + void add(int dataOffset, int dataSize, IntBuffer newData) { if (size == 0) { offset = dataOffset; } - int oldSize = intData.length / ncoords; + int oldSize = intData.capacity() / ncoords; if (size + dataSize >= oldSize) { - int newSize = expandSize(oldSize, size + dataSize); + int newSize = expandSize(oldSize, size + dataSize); + prepareIntDataForCopy(); expand(newSize); } - if (dataSize <= PGraphicsOpenGL.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); - } + intData.position(ncoords * size); + intData.put(newData); size += dataSize; } - void add(int dataOffset, int dataSize, float[] newData, PMatrix tr) { - + void add(int dataOffset, int dataSize, float[] newData, PMatrix tr) { if (tr instanceof PMatrix2D) { add(dataOffset, dataSize, newData, (PMatrix2D)tr); } else if (tr instanceof PMatrix3D) { @@ -3902,60 +4024,82 @@ public class PShape3D extends PShape { } } - void add(int dataOffset, int dataSize, float[] newData, PMatrix2D tr) { + void add(int dataOffset, int dataSize, FloatBuffer newData, PMatrix2D tr) { if (size == 0) { offset = dataOffset; } - int oldSize = floatData.length / ncoords; + int oldSize = floatData.capacity() / ncoords; if (size + dataSize >= oldSize) { - int newSize = expandSize(oldSize, size + dataSize); + int newSize = expandSize(oldSize, size + dataSize); + prepareFloatDataForCopy(); expand(newSize); } if (2 <= ncoords) { + float[] data0 = new float[2]; + float[] data1 = new float[2]; for (int i = 0; i < dataSize; i++) { - int srcIndex = ncoords * i; - float x = newData[srcIndex++]; - float y = newData[srcIndex ]; + newData.get(data0); - int destIndex = ncoords * (size + i); - floatData[destIndex++] = x * tr.m00 + y * tr.m01 + tr.m02; - floatData[destIndex ] = x * tr.m10 + y * tr.m11 + tr.m12; + data1[0] = data0[0] * tr.m00 + data0[1] * tr.m01 + tr.m02; + data1[1] = data0[0] * tr.m10 + data0[1] * tr.m11 + tr.m12; + floatData.position(ncoords * (size + i)); + floatData.put(data1, 0, 2); } } size += dataSize; } - void add(int dataOffset, int dataSize, float[] newData, PMatrix3D tr) { + void add(int dataOffset, int dataSize, FloatBuffer newData, PMatrix3D tr) { if (size == 0) { offset = dataOffset; } - int oldSize = floatData.length / ncoords; + int oldSize = floatData.capacity() / ncoords; if (size + dataSize >= oldSize) { - int newSize = expandSize(oldSize, size + dataSize); + int newSize = expandSize(oldSize, size + dataSize); + prepareIntDataForCopy(); expand(newSize); } if (3 <= ncoords) { + float[] data0 = new float[3]; + float[] data1 = new float[3]; for (int i = 0; i < dataSize; i++) { - int srcIndex = ncoords * i; - float x = newData[srcIndex++]; - float y = newData[srcIndex++]; - float z = newData[srcIndex++]; - - int destIndex = ncoords * (size + i); - 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; + newData.get(data0); + + data1[0] = data0[0] * tr.m00 + data0[1] * tr.m01 + data0[2] * tr.m02 + tr.m03; + data1[1] = data0[0] * tr.m10 + data0[1] * tr.m11 + data0[2] * tr.m12 + tr.m13; + data1[2] = data0[0] * tr.m20 + data0[1] * tr.m21 + data0[2] * tr.m22 + tr.m23; + + floatData.position(ncoords * (size + i)); + floatData.put(data1); } } size += dataSize; } + void prepareForCopy() { + if (isFloat) { + prepareFloatDataForCopy(); + } else { + prepareIntDataForCopy(); + } + } + + void prepareFloatDataForCopy() { + floatData.position(0); + floatData.limit(ncoords * size); + } + + void prepareIntDataForCopy() { + intData.position(0); + intData.limit(ncoords * size); + } + void expand(int n) { if (isFloat) { expandFloat(n); @@ -3965,15 +4109,15 @@ public class PShape3D extends PShape { } void expandFloat(int n) { - float temp[] = new float[ncoords * n]; - PApplet.arrayCopy(floatData, 0, temp, 0, ncoords * size); + FloatBuffer temp = pgl.createFloatBuffer(ncoords * n); + temp.put(floatData); floatData = temp; } void expandInt(int n) { - int temp[] = new int[ncoords * n]; - PApplet.arrayCopy(intData, 0, temp, 0, ncoords * size); - intData = temp; + IntBuffer temp = pgl.createIntBuffer(ncoords * n); + temp.put(intData); + intData = temp; } int expandSize(int currSize, int newMinSize) { @@ -3986,8 +4130,7 @@ public class PShape3D extends PShape { boolean hasData() { return 0 < size; - } - + } } diff --git a/java/libraries/opengl/src/processing/opengl/PTexture.java b/java/libraries/opengl/src/processing/opengl/PTexture.java index 4640d6a95..1a1bc2a39 100644 --- a/java/libraries/opengl/src/processing/opengl/PTexture.java +++ b/java/libraries/opengl/src/processing/opengl/PTexture.java @@ -27,7 +27,6 @@ import processing.core.PApplet; import processing.core.PConstants; import processing.core.PGraphics; import processing.core.PImage; - import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.nio.IntBuffer; @@ -68,6 +67,8 @@ public class PTexture implements PConstants { protected int[] tempPixels = null; protected PFramebuffer tempFbo = null; + protected IntBuffer texels; + protected Object bufferSource; protected LinkedList bufferCache = null; protected Method disposeBufferMethod; @@ -845,14 +846,21 @@ public class PTexture implements PConstants { protected void setTexels(int[] pix, int x, int y, int w, int h) { setTexels(pix, 0, x, y, w, h); } - - protected void setTexels(int[] pix, int level, int x, int y, int w, int h) { - pgl.glTexSubImage2D(glTarget, level, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, IntBuffer.wrap(pix)); - } protected void setTexels(IntBuffer buffer, int x, int y, int w, int h) { setTexels(buffer, 0, x, y, w, h); - } + } + + protected void setTexels(int[] pix, int level, int x, int y, int w, int h) { + if (texels == null || texels.capacity() != width * height) { + texels = pgl.createIntBuffer(width * height); + } + texels.position(0); + texels.limit(pix.length); + texels.put(pix); + texels.flip(); + pgl.glTexSubImage2D(glTarget, level, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, texels); + } protected void setTexels(IntBuffer buffer, int level, int x, int y, int w, int h) { pgl.glTexSubImage2D(glTarget, level, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, buffer);