diff --git a/android/core/src/processing/opengl/PGL.java b/android/core/src/processing/opengl/PGL.java index 9c5ecec9c..c944e82fe 100644 --- a/android/core/src/processing/opengl/PGL.java +++ b/android/core/src/processing/opengl/PGL.java @@ -27,6 +27,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; +import java.nio.ShortBuffer; import java.util.Arrays; import processing.core.PApplet; @@ -356,24 +357,24 @@ public class PGL { // Texture rendering - protected boolean loadedTexShader = false; - protected int texShaderProgram; - protected int texVertShader; - protected int texFragShader; + protected static boolean loadedTexShader = false; + protected static int texShaderProgram; + protected static int texVertShader; + protected static int texFragShader; - protected int texVertLoc; - protected int texTCoordLoc; + protected static int texVertLoc; + protected static int texTCoordLoc; - protected float[] texCoords = { + protected static float[] texCoords = { // X, Y, U, V -1.0f, -1.0f, 0.0f, 0.0f, +1.0f, -1.0f, 1.0f, 0.0f, -1.0f, +1.0f, 0.0f, 1.0f, +1.0f, +1.0f, 1.0f, 1.0f }; - protected FloatBuffer texData; + protected static FloatBuffer texData; - protected String texVertShaderSource = + protected static String texVertShaderSource = "attribute vec2 inVertex;" + "attribute vec2 inTexcoord;" + "varying vec2 vertTexcoord;" + @@ -382,7 +383,7 @@ public class PGL { " vertTexcoord = inTexcoord;" + "}"; - protected String texFragShaderSource = + protected static String texFragShaderSource = SHADER_PREPROCESSOR_DIRECTIVE + "uniform sampler2D textureSampler;" + "varying vec2 vertTexcoord;" + @@ -392,7 +393,10 @@ public class PGL { /////////////////////////////////////////////////////////// - // 1-pixel color, depth, stencil buffers + // Utilities + + protected ByteBuffer byteBuffer; + protected IntBuffer intBuffer; protected IntBuffer colorBuffer; protected FloatBuffer depthBuffer; @@ -409,6 +413,12 @@ public class PGL { if (glu == null) { glu = new PGLU(); } + if (byteBuffer == null) { + byteBuffer = allocateDirectByteBuffer(1); + } + if (intBuffer == null) { + intBuffer = allocateDirectIntBuffer(1); + } initialized = false; } @@ -728,31 +738,57 @@ public class PGL { } - public void getIntegerv(int name, int[] values, int offset) { +// public void getIntegerv(int name, int[] values, int offset) { +// if (-1 < name) { +// GLES20.glGetIntegerv(name, values, offset); +// } else { +// Arrays.fill(values, 0); +// } +// } + + + public void getIntegerv(int name, IntBuffer values) { if (-1 < name) { - GLES20.glGetIntegerv(name, values, offset); + GLES20.glGetIntegerv(name, values); } else { - Arrays.fill(values, 0); + fillBuffer(values, 0, values.capacity() - 1, 0); } } - public void getFloatv(int name, float[] values, int offset) { +// public void getFloatv(int name, float[] values, int offset) { +// if (-1 < name) { +// GLES20.glGetFloatv(name, values, offset); +// } else { +// Arrays.fill(values, 0); +// } +// } + + + public void getFloatv(int name, FloatBuffer values) { if (-1 < name) { - GLES20.glGetFloatv(name, values, offset); + GLES20.glGetFloatv(name, values); } else { - Arrays.fill(values, 0); + fillBuffer(values, 0, values.capacity() - 1, 0); } } - public void getBooleanv(int name, boolean[] values, int offset) { +// public void getBooleanv(int name, boolean[] values, int offset) { +// if (-1 < name) { +// GLES20.glGetBooleanv(name, values, offset); +// } else { +// Arrays.fill(values, false); +// } +// } + + public void getBooleanv(int name, IntBuffer values) { if (-1 < name) { - GLES20.glGetBooleanv(name, values, offset); + GLES20.glGetBooleanv(name, values); } else { - Arrays.fill(values, false); + fillBuffer(values, 0, values.capacity() - 1, 0); } - } + } /////////////////////////////////////////////////////////// @@ -834,13 +870,20 @@ public class PGL { // Textures - public void genTextures(int n, int[] ids, int offset) { - GLES20.glGenTextures(n, ids, offset); +// public void genTextures(int n, int[] ids, int offset) { +// GLES20.glGenTextures(n, ids, offset); +// } + + public void genTextures(int n, IntBuffer ids) { + GLES20.glGenTextures(n, ids); } +// public void deleteTextures(int n, int[] ids, int offset) { +// GLES20.glDeleteTextures(n, ids, offset); +// } - public void deleteTextures(int n, int[] ids, int offset) { - GLES20.glDeleteTextures(n, ids, offset); + public void deleteTextures(int n, IntBuffer ids) { + GLES20.glDeleteTextures(n, ids); } @@ -883,9 +926,14 @@ public class PGL { } - public void getTexParameteriv(int target, int param, int[] values, - int offset) { - GLES20.glGetTexParameteriv(target, param, values, offset); +// public void getTexParameteriv(int target, int param, int[] values, +// int offset) { +// GLES20.glGetTexParameteriv(target, param, values, offset); +// } + + + public void getTexParameteriv(int target, int param, IntBuffer values) { + GLES20.glGetTexParameteriv(target, param, values); } @@ -899,13 +947,23 @@ public class PGL { // Vertex Buffers - public void genBuffers(int n, int[] ids, int offset) { - GLES20.glGenBuffers(n, ids, offset); +// public void genBuffers(int n, int[] ids, int offset) { +// GLES20.glGenBuffers(n, ids, offset); +// } + + + public void genBuffers(int n, IntBuffer ids) { + GLES20.glGenBuffers(n, ids); } - public void deleteBuffers(int n, int[] ids, int offset) { - GLES20.glDeleteBuffers(n, ids, offset); +// public void deleteBuffers(int n, int[] ids, int offset) { +// GLES20.glDeleteBuffers(n, ids, offset); +// } + + + public void deleteBuffers(int n, IntBuffer ids) { + GLES20.glDeleteBuffers(n, ids); } @@ -979,23 +1037,32 @@ public class PGL { // Framebuffers, renderbuffers - public void genFramebuffers(int n, int[] ids, int offset) { - GLES20.glGenFramebuffers(n, ids, offset); +// public void genFramebuffers(int n, int[] ids, int offset) { +// GLES20.glGenFramebuffers(n, ids, offset); +// } +// +// +// public void deleteFramebuffers(int n, int[] ids, int offset) { +// GLES20.glDeleteFramebuffers(n, ids, offset); +// } +// +// +// public void genRenderbuffers(int n, int[] ids, int offset) { +// GLES20.glGenRenderbuffers(n, ids, offset); +// } +// +// +// public void deleteRenderbuffers(int n, int[] ids, int offset) { +// GLES20.glDeleteRenderbuffers(n, ids, offset); +// } + + public void genFramebuffers(int n, IntBuffer ids) { + GLES20.glGenFramebuffers(n, ids); } - public void deleteFramebuffers(int n, int[] ids, int offset) { - GLES20.glDeleteFramebuffers(n, ids, offset); - } - - - public void genRenderbuffers(int n, int[] ids, int offset) { - GLES20.glGenRenderbuffers(n, ids, offset); - } - - - public void deleteRenderbuffers(int n, int[] ids, int offset) { - GLES20.glDeleteRenderbuffers(n, ids, offset); + public void deleteFramebuffers(int n, IntBuffer ids) { + GLES20.glDeleteFramebuffers(n, ids); } @@ -1004,6 +1071,16 @@ public class PGL { } + public void genRenderbuffers(int n, IntBuffer ids) { + GLES20.glGenRenderbuffers(n, ids); + } + + + public void deleteRenderbuffers(int n, IntBuffer ids) { + GLES20.glDeleteRenderbuffers(n, ids); + } + + public void blitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) { @@ -1138,61 +1215,120 @@ public class PGL { } - public void uniform1iv(int loc, int count, int[] v, int offset) { - GLES20.glUniform1iv(loc, count, v, offset); +// public void uniform1iv(int loc, int count, int[] v, int offset) { +// GLES20.glUniform1iv(loc, count, v, offset); +// } +// +// +// public void uniform2iv(int loc, int count, int[] v, int offset) { +// GLES20.glUniform2iv(loc, count, v, offset); +// } +// +// +// public void uniform3iv(int loc, int count, int[] v, int offset) { +// GLES20.glUniform3iv(loc, count, v, offset); +// } +// +// +// public void uniform4iv(int loc, int count, int[] v, int offset) { +// GLES20.glUniform4iv(loc, count, v, offset); +// } +// +// +// public void uniform1fv(int loc, int count, float[] v, int offset) { +// GLES20.glUniform1fv(loc, count, v, offset); +// } +// +// +// public void uniform2fv(int loc, int count, float[] v, int offset) { +// GLES20.glUniform2fv(loc, count, v, offset); +// } +// +// +// public void uniform3fv(int loc, int count, float[] v, int offset) { +// GLES20.glUniform3fv(loc, count, v, offset); +// } +// +// +// public void uniform4fv(int loc, int count, float[] v, int offset) { +// GLES20.glUniform4fv(loc, count, v, offset); +// } +// +// +// public void uniformMatrix2fv(int loc, int count, boolean transpose, +// float[] mat, int offset) { +// GLES20.glUniformMatrix2fv(loc, count, transpose, mat, offset); +// } +// +// +// public void uniformMatrix3fv(int loc, int count, boolean transpose, +// float[] mat, int offset) { +// GLES20.glUniformMatrix3fv(loc, count, transpose, mat, offset); +// } +// +// +// public void uniformMatrix4fv(int loc, int count, boolean transpose, +// float[] mat, int offset) { +// GLES20.glUniformMatrix4fv(loc, count, transpose, mat, offset); +// } + + + + public void uniform1iv(int loc, int count, IntBuffer v) { + GLES20.glUniform1iv(loc, count, v); } - public void uniform2iv(int loc, int count, int[] v, int offset) { - GLES20.glUniform2iv(loc, count, v, offset); + public void uniform2iv(int loc, int count, IntBuffer v) { + GLES20.glUniform2iv(loc, count, v); } - public void uniform3iv(int loc, int count, int[] v, int offset) { - GLES20.glUniform3iv(loc, count, v, offset); + public void uniform3iv(int loc, int count, IntBuffer v) { + GLES20.glUniform3iv(loc, count, v); } - public void uniform4iv(int loc, int count, int[] v, int offset) { - GLES20.glUniform4iv(loc, count, v, offset); + public void uniform4iv(int loc, int count, IntBuffer v) { + GLES20.glUniform4iv(loc, count, v); } - public void uniform1fv(int loc, int count, float[] v, int offset) { - GLES20.glUniform1fv(loc, count, v, offset); + public void uniform1fv(int loc, int count, FloatBuffer v) { + GLES20.glUniform1fv(loc, count, v); } - public void uniform2fv(int loc, int count, float[] v, int offset) { - GLES20.glUniform2fv(loc, count, v, offset); + public void uniform2fv(int loc, int count, FloatBuffer v) { + GLES20.glUniform2fv(loc, count, v); } - public void uniform3fv(int loc, int count, float[] v, int offset) { - GLES20.glUniform3fv(loc, count, v, offset); + public void uniform3fv(int loc, int count, FloatBuffer v) { + GLES20.glUniform3fv(loc, count, v); } - public void uniform4fv(int loc, int count, float[] v, int offset) { - GLES20.glUniform4fv(loc, count, v, offset); + public void uniform4fv(int loc, int count, FloatBuffer v) { + GLES20.glUniform4fv(loc, count, v); } public void uniformMatrix2fv(int loc, int count, boolean transpose, - float[] mat, int offset) { - GLES20.glUniformMatrix2fv(loc, count, transpose, mat, offset); + FloatBuffer mat) { + GLES20.glUniformMatrix2fv(loc, count, transpose, mat); } public void uniformMatrix3fv(int loc, int count, boolean transpose, - float[] mat, int offset) { - GLES20.glUniformMatrix3fv(loc, count, transpose, mat, offset); + FloatBuffer mat) { + GLES20.glUniformMatrix3fv(loc, count, transpose, mat); } public void uniformMatrix4fv(int loc, int count, boolean transpose, - float[] mat, int offset) { - GLES20.glUniformMatrix4fv(loc, count, transpose, mat, offset); + FloatBuffer mat) { + GLES20.glUniformMatrix4fv(loc, count, transpose, mat); } @@ -1217,23 +1353,42 @@ public class PGL { } - public void vertexAttrib1fv(int loc, float[] v, int offset) { - GLES20.glVertexAttrib1fv(loc, v, offset); +// public void vertexAttrib1fv(int loc, float[] v, int offset) { +// GLES20.glVertexAttrib1fv(loc, v, offset); +// } +// +// +// public void vertexAttrib2fv(int loc, float[] v, int offset) { +// GLES20.glVertexAttrib2fv(loc, v, offset); +// } +// +// +// public void vertexAttrib3fv(int loc, float[] v, int offset) { +// GLES20.glVertexAttrib3fv(loc, v, offset); +// } +// +// +// public void vertexAttrib4fv(int loc, float[] v, int offset) { +// GLES20.glVertexAttrib4fv(loc, v, offset); +// } + + public void vertexAttrib1fv(int loc, FloatBuffer v) { + GLES20.glVertexAttrib1fv(loc, v); } - public void vertexAttrib2fv(int loc, float[] v, int offset) { - GLES20.glVertexAttrib2fv(loc, v, offset); + public void vertexAttrib2fv(int loc, FloatBuffer v) { + GLES20.glVertexAttrib2fv(loc, v); } - public void vertexAttrib3fv(int loc, float[] v, int offset) { - GLES20.glVertexAttrib3fv(loc, v, offset); + public void vertexAttrib3fv(int loc, FloatBuffer v) { + GLES20.glVertexAttrib3fv(loc, v); } - public void vertexAttrib4fv(int loc, float[] v, int offset) { - GLES20.glVertexAttrib4fv(loc, v, offset); + public void vertexAttri4fv(int loc, FloatBuffer v) { + GLES20.glVertexAttrib4fv(loc, v); } @@ -1252,8 +1407,13 @@ public class PGL { } - public void getShaderiv(int shader, int pname, int[] params, int offset) { - GLES20.glGetShaderiv(shader, pname, params, offset); +// public void getShaderiv(int shader, int pname, int[] params, int offset) { +// GLES20.glGetShaderiv(shader, pname, params, offset); +// } + + + public void getShaderiv(int shader, int pname, IntBuffer params) { + GLES20.glGetShaderiv(shader, pname, params); } @@ -1262,8 +1422,13 @@ public class PGL { } - public void getProgramiv(int prog, int pname, int[] params, int offset) { - GLES20.glGetProgramiv(prog, pname, params, offset); +// public void getProgramiv(int prog, int pname, int[] params, int offset) { +// GLES20.glGetProgramiv(prog, pname, params, offset); +// } + + + public void getProgramiv(int prog, int pname, IntBuffer params) { + GLES20.glGetProgramiv(prog, pname, params); } @@ -1593,22 +1758,29 @@ public class PGL { texVertLoc = getAttribLocation(texShaderProgram, "inVertex"); texTCoordLoc = getAttribLocation(texShaderProgram, "inTexcoord"); } - texData = allocateDirectFloatBuffer(texCoords.length); loadedTexShader = true; } + if (texData == null) { + texData = allocateDirectFloatBuffer(texCoords.length); + } + + if (intBuffer == null) { + intBuffer = allocateDirectIntBuffer(1); + } + if (0 < texShaderProgram) { // The texture overwrites anything drawn earlier. - boolean[] depthTest = new boolean[1]; - getBooleanv(DEPTH_TEST, depthTest, 0); + getBooleanv(DEPTH_TEST, intBuffer); + boolean depthTest = intBuffer.get(0) == 0 ? false : true; disable(DEPTH_TEST); // When drawing the texture we don't write to the // depth mask, so the texture remains in the background // and can be occluded by anything drawn later, even if // if it is behind it. - boolean[] depthMask = new boolean[1]; - getBooleanv(DEPTH_WRITEMASK, depthMask, 0); + getBooleanv(DEPTH_WRITEMASK, intBuffer); + boolean depthMask = intBuffer.get(0) == 0 ? false : true; depthMask(false); useProgram(texShaderProgram); @@ -1673,12 +1845,12 @@ public class PGL { useProgram(0); - if (depthTest[0]) { + if (depthTest) { enable(DEPTH_TEST); } else { disable(DEPTH_TEST); } - depthMask(depthMask[0]); + depthMask(depthMask); } } @@ -2017,9 +2189,9 @@ public class PGL { if (shader != 0) { shaderSource(shader, source); compileShader(shader); - int[] compiled = new int[1]; - getShaderiv(shader, COMPILE_STATUS, compiled, 0); - if (compiled[0] == FALSE) { + getShaderiv(shader, COMPILE_STATUS, intBuffer); + boolean compiled = intBuffer.get(0) == 0 ? false : true; + if (!compiled) { System.err.println("Could not compile shader " + shaderType + ":"); System.err.println(getShaderInfoLog(shader)); deleteShader(shader); @@ -2036,9 +2208,9 @@ public class PGL { attachShader(program, vertexShader); attachShader(program, fragmentShader); linkProgram(program); - int[] linked = new int[1]; - getProgramiv(program, LINK_STATUS, linked, 0); - if (linked[0] == FALSE) { + getProgramiv(program, LINK_STATUS, intBuffer); + boolean linked = intBuffer.get(0) == 0 ? false : true; + if (!linked) { System.err.println("Could not link program: "); System.err.println(getProgramInfoLog(program)); deleteProgram(program); @@ -2077,24 +2249,6 @@ public class PGL { } - protected static ByteBuffer allocateDirectByteBuffer(int size) { - return ByteBuffer.allocateDirect(size * SIZEOF_BYTE). - order(ByteOrder.nativeOrder()); - } - - - protected static IntBuffer allocateDirectIntBuffer(int size) { - return ByteBuffer.allocateDirect(size * SIZEOF_INT). - order(ByteOrder.nativeOrder()).asIntBuffer(); - } - - - protected static FloatBuffer allocateDirectFloatBuffer(int size) { - return ByteBuffer.allocateDirect(size * SIZEOF_FLOAT). - order(ByteOrder.nativeOrder()).asFloatBuffer(); - } - - protected int[] getGLVersion() { String version = GLES20.glGetString(GLES20.GL_VERSION).trim(); int[] res = {0, 0, 0}; @@ -2122,6 +2276,78 @@ public class PGL { } + protected static ByteBuffer allocateDirectByteBuffer(int size) { + return ByteBuffer.allocateDirect(size * SIZEOF_BYTE). + order(ByteOrder.nativeOrder()); + } + + + protected static ShortBuffer allocateDirectShortBuffer(int size) { + return ByteBuffer.allocateDirect(size * SIZEOF_SHORT). + order(ByteOrder.nativeOrder()).asShortBuffer(); + } + + + protected static IntBuffer allocateDirectIntBuffer(int size) { + return ByteBuffer.allocateDirect(size * SIZEOF_INT). + order(ByteOrder.nativeOrder()).asIntBuffer(); + } + + + protected static FloatBuffer allocateDirectFloatBuffer(int size) { + return ByteBuffer.allocateDirect(size * SIZEOF_FLOAT). + order(ByteOrder.nativeOrder()).asFloatBuffer(); + } + + + protected static void fillBuffer(ByteBuffer buf, int i0, int i1, byte val) { + int n = i1 - i0 + 1; + byte[] temp = new byte[n]; + Arrays.fill(temp, 0, n, val); + buf.position(i0); + buf.limit(i1 + 1); + buf.put(temp, 0, n); + buf.position(0); + buf.limit(buf.capacity()); + } + + + protected static void fillBuffer(ShortBuffer buf, int i0, int i1, short val) { + int n = i1 - i0 + 1; + short[] temp = new short[n]; + Arrays.fill(temp, 0, n, val); + buf.position(i0); + buf.limit(i1 + 1); + buf.put(temp, 0, n); + buf.position(0); + buf.limit(buf.capacity()); + } + + + protected static void fillBuffer(IntBuffer buf, int i0, int i1, int val) { + int n = i1 - i0 + 1; + int[] temp = new int[n]; + Arrays.fill(temp, 0, n, val); + buf.position(i0); + buf.limit(i1 + 1); + buf.put(temp, 0, n); + buf.position(0); + buf.limit(buf.capacity()); + } + + + protected static void fillBuffer(FloatBuffer buf, int i0, int i1, float val) { + int n = i1 - i0 + 1; + float[] temp = new float[n]; + Arrays.fill(temp, 0, n, val); + buf.position(i0); + buf.limit(i1 + 1); + buf.put(temp, 0, n); + buf.position(0); + buf.limit(buf.capacity()); + } + + /////////////////////////////////////////////////////////// // Android specific stuff diff --git a/android/core/src/processing/opengl/PGraphicsOpenGL.java b/android/core/src/processing/opengl/PGraphicsOpenGL.java index 8fab7b367..e8f366675 100644 --- a/android/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/android/core/src/processing/opengl/PGraphicsOpenGL.java @@ -475,7 +475,7 @@ public class PGraphicsOpenGL extends PGraphics { protected int pixelsOp = OP_NONE; /** Viewport dimensions. */ - protected int[] viewport = {0, 0, 0, 0}; + protected IntBuffer viewport; /** Used to register calls to glClear. */ protected boolean clearColorBuffer; @@ -509,6 +509,9 @@ public class PGraphicsOpenGL extends PGraphics { final protected float[][] QUAD_POINT_SIGNS = { {-1, +1}, {-1, -1}, {+1, -1}, {+1, +1} }; + /** To get data from OpenGL. */ + protected IntBuffer intBuffer; + protected FloatBuffer floatBuffer; ////////////////////////////////////////////////////////////// @@ -522,6 +525,12 @@ public class PGraphicsOpenGL extends PGraphics { tessellator = new Tessellator(); } + + intBuffer = PGL.allocateDirectIntBuffer(2); + floatBuffer = PGL.allocateDirectFloatBuffer(2); + + viewport = PGL.allocateDirectIntBuffer(4); + inGeo = newInGeometry(IMMEDIATE); tessGeo = newTessGeometry(IMMEDIATE); texCache = newTexCache(); @@ -703,9 +712,8 @@ public class PGraphicsOpenGL extends PGraphics { protected int createTextureObject(int context) { deleteFinalizedTextureObjects(); - int[] temp = new int[1]; - pgl.genTextures(1, temp, 0); - int id = temp[0]; + pgl.genTextures(1, intBuffer); + int id = intBuffer.get(0); GLResource res = new GLResource(id, context); @@ -721,16 +729,16 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteTextureObject(int id, int context) { GLResource res = new GLResource(id, context); if (glTextureObjects.containsKey(res)) { - int[] temp = { id }; - pgl.deleteTextures(1, temp, 0); + intBuffer.put(0, id); + pgl.deleteTextures(1, intBuffer); glTextureObjects.remove(res); } } protected void deleteAllTextureObjects() { for (GLResource res : glTextureObjects.keySet()) { - int[] temp = { res.id }; - pgl.deleteTextures(1, temp, 0); + intBuffer.put(0, res.id); + pgl.deleteTextures(1, intBuffer); } glTextureObjects.clear(); } @@ -749,8 +757,8 @@ public class PGraphicsOpenGL extends PGraphics { for (GLResource res : glTextureObjects.keySet()) { if (glTextureObjects.get(res)) { finalized.add(res); - int[] temp = { res.id }; - pgl.deleteTextures(1, temp, 0); + intBuffer.put(0, res.id); + pgl.deleteTextures(1, intBuffer); } } @@ -771,9 +779,8 @@ public class PGraphicsOpenGL extends PGraphics { protected int createVertexBufferObject(int context) { deleteFinalizedVertexBufferObjects(); - int[] temp = new int[1]; - pgl.genBuffers(1, temp, 0); - int id = temp[0]; + pgl.genBuffers(1, intBuffer); + int id = intBuffer.get(0); GLResource res = new GLResource(id, context); @@ -789,16 +796,16 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteVertexBufferObject(int id, int context) { GLResource res = new GLResource(id, context); if (glVertexBuffers.containsKey(res)) { - int[] temp = { id }; - pgl.deleteBuffers(1, temp, 0); + intBuffer.put(0, id); + pgl.deleteBuffers(1, intBuffer); glVertexBuffers.remove(res); } } protected void deleteAllVertexBufferObjects() { for (GLResource res : glVertexBuffers.keySet()) { - int[] temp = { res.id }; - pgl.deleteBuffers(1, temp, 0); + intBuffer.put(0, res.id); + pgl.deleteBuffers(1, intBuffer); } glVertexBuffers.clear(); } @@ -817,8 +824,8 @@ public class PGraphicsOpenGL extends PGraphics { for (GLResource res : glVertexBuffers.keySet()) { if (glVertexBuffers.get(res)) { finalized.add(res); - int[] temp = { res.id }; - pgl.deleteBuffers(1, temp, 0); + intBuffer.put(0, res.id); + pgl.deleteBuffers(1, intBuffer); } } @@ -839,9 +846,8 @@ public class PGraphicsOpenGL extends PGraphics { protected int createFrameBufferObject(int context) { deleteFinalizedFrameBufferObjects(); - int[] temp = new int[1]; - pgl.genFramebuffers(1, temp, 0); - int id = temp[0]; + pgl.genFramebuffers(1, intBuffer); + int id = intBuffer.get(0); GLResource res = new GLResource(id, context); @@ -857,16 +863,16 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteFrameBufferObject(int id, int context) { GLResource res = new GLResource(id, context); if (glFrameBuffers.containsKey(res)) { - int[] temp = { id }; - pgl.deleteFramebuffers(1, temp, 0); + intBuffer.put(0, id); + pgl.deleteFramebuffers(1, intBuffer); glFrameBuffers.remove(res); } } protected void deleteAllFrameBufferObjects() { for (GLResource res : glFrameBuffers.keySet()) { - int[] temp = { res.id }; - pgl.deleteFramebuffers(1, temp, 0); + intBuffer.put(0, res.id); + pgl.deleteFramebuffers(1, intBuffer); } glFrameBuffers.clear(); } @@ -885,8 +891,8 @@ public class PGraphicsOpenGL extends PGraphics { for (GLResource res : glFrameBuffers.keySet()) { if (glFrameBuffers.get(res)) { finalized.add(res); - int[] temp = { res.id }; - pgl.deleteFramebuffers(1, temp, 0); + intBuffer.put(0, res.id); + pgl.deleteFramebuffers(1, intBuffer); } } @@ -907,9 +913,8 @@ public class PGraphicsOpenGL extends PGraphics { protected int createRenderBufferObject(int context) { deleteFinalizedRenderBufferObjects(); - int[] temp = new int[1]; - pgl.genRenderbuffers(1, temp, 0); - int id = temp[0]; + pgl.genRenderbuffers(1, intBuffer); + int id = intBuffer.get(0); GLResource res = new GLResource(id, context); @@ -925,16 +930,16 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteRenderBufferObject(int id, int context) { GLResource res = new GLResource(id, context); if (glRenderBuffers.containsKey(res)) { - int[] temp = { id }; - pgl.deleteRenderbuffers(1, temp, 0); + intBuffer.put(0, id); + pgl.deleteRenderbuffers(1, intBuffer); glRenderBuffers.remove(res); } } protected void deleteAllRenderBufferObjects() { for (GLResource res : glRenderBuffers.keySet()) { - int[] temp = { res.id }; - pgl.deleteRenderbuffers(1, temp, 0); + intBuffer.put(0, res.id); + pgl.deleteRenderbuffers(1, intBuffer); } glRenderBuffers.clear(); } @@ -953,8 +958,8 @@ public class PGraphicsOpenGL extends PGraphics { for (GLResource res : glRenderBuffers.keySet()) { if (glRenderBuffers.get(res)) { finalized.add(res); - int[] temp = { res.id }; - pgl.deleteRenderbuffers(1, temp, 0); + intBuffer.put(0, res.id); + pgl.deleteRenderbuffers(1, intBuffer); } } @@ -1279,46 +1284,54 @@ public class PGraphicsOpenGL extends PGraphics { int sizef = size * PGL.SIZEOF_FLOAT; int sizei = size * PGL.SIZEOF_INT; + tessGeo.updatePolyVerticesBuffer(); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyVertex); pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, - FloatBuffer.wrap(tessGeo.polyVertices, 0, 4 * size), PGL.STATIC_DRAW); + tessGeo.polyVerticesBuffer, PGL.STATIC_DRAW); + tessGeo.updatePolyColorsBuffer(); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyColor); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, - IntBuffer.wrap(tessGeo.polyColors, 0, size), PGL.STATIC_DRAW); + tessGeo.polyColorsBuffer, PGL.STATIC_DRAW); if (lit) { + tessGeo.updatePolyNormalsBuffer(); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyNormal); pgl.bufferData(PGL.ARRAY_BUFFER, 3 * sizef, - FloatBuffer.wrap(tessGeo.polyNormals, 0, 3 * size), PGL.STATIC_DRAW); + tessGeo.polyNormalsBuffer, PGL.STATIC_DRAW); + tessGeo.updatePolyAmbientBuffer(); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyAmbient); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, - IntBuffer.wrap(tessGeo.polyAmbient, 0, size), PGL.STATIC_DRAW); + tessGeo.polyAmbientBuffer, PGL.STATIC_DRAW); + tessGeo.updatePolySpecularBuffer(); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolySpecular); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, - IntBuffer.wrap(tessGeo.polySpecular, 0, size), PGL.STATIC_DRAW); + tessGeo.polySpecularBuffer, PGL.STATIC_DRAW); + tessGeo.updatePolyEmissiveBuffer(); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyEmissive); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, - IntBuffer.wrap(tessGeo.polyEmissive, 0, size), PGL.STATIC_DRAW); + tessGeo.polyEmissiveBuffer, PGL.STATIC_DRAW); + tessGeo.updatePolyShininessBuffer(); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyShininess); pgl.bufferData(PGL.ARRAY_BUFFER, sizef, - FloatBuffer.wrap(tessGeo.polyShininess, 0, size), PGL.STATIC_DRAW); + tessGeo.polyShininessBuffer, PGL.STATIC_DRAW); } if (tex) { + tessGeo.updatePolyTexcoordsBuffer(); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyTexcoord); pgl.bufferData(PGL.ARRAY_BUFFER, 2 * sizef, - FloatBuffer.wrap(tessGeo.polyTexcoords, 0, 2 * size), PGL.STATIC_DRAW); + tessGeo.polyTexcoordsBuffer, PGL.STATIC_DRAW); } + tessGeo.updatePolyIndicesBuffer(); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glPolyIndex); pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, - tessGeo.polyIndexCount * PGL.SIZEOF_INDEX, - ShortBuffer.wrap(tessGeo.polyIndices, 0, tessGeo.polyIndexCount), + tessGeo.polyIndexCount * PGL.SIZEOF_INDEX, tessGeo.polyIndicesBuffer, PGL.STATIC_DRAW); } @@ -1409,23 +1422,26 @@ public class PGraphicsOpenGL extends PGraphics { int sizef = size * PGL.SIZEOF_FLOAT; int sizei = size * PGL.SIZEOF_INT; + tessGeo.updateLineVerticesBuffer(); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineVertex); - pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, - FloatBuffer.wrap(tessGeo.lineVertices, 0, 4 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, tessGeo.lineVerticesBuffer, + PGL.STATIC_DRAW); + tessGeo.updateLineColorsBuffer(); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineColor); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, - IntBuffer.wrap(tessGeo.lineColors, 0, size), PGL.STATIC_DRAW); + tessGeo.lineColorsBuffer, PGL.STATIC_DRAW); + tessGeo.updateLineAttribsBuffer(); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineAttrib); pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, - FloatBuffer.wrap(tessGeo.lineAttribs, 0, 4 * size), PGL.STATIC_DRAW); + tessGeo.lineAttribsBuffer, PGL.STATIC_DRAW); + tessGeo.updateLineIndicesBuffer(); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glLineIndex); pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, - tessGeo.lineIndexCount * PGL.SIZEOF_INDEX, - ShortBuffer.wrap(tessGeo.lineIndices, 0, tessGeo.lineIndexCount), - PGL.STATIC_DRAW); + tessGeo.lineIndexCount * PGL.SIZEOF_INDEX, + tessGeo.lineIndicesBuffer, PGL.STATIC_DRAW); } @@ -1499,23 +1515,26 @@ public class PGraphicsOpenGL extends PGraphics { int sizef = size * PGL.SIZEOF_FLOAT; int sizei = size * PGL.SIZEOF_INT; + tessGeo.updatePointVerticesBuffer(); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointVertex); pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, - FloatBuffer.wrap(tessGeo.pointVertices, 0, 4 * size), PGL.STATIC_DRAW); + tessGeo.pointVerticesBuffer, PGL.STATIC_DRAW); + tessGeo.updatePointColorsBuffer(); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointColor); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, - IntBuffer.wrap(tessGeo.pointColors, 0, size), PGL.STATIC_DRAW); + tessGeo.pointColorsBuffer, PGL.STATIC_DRAW); + tessGeo.updatePointAttribsBuffer(); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointAttrib); pgl.bufferData(PGL.ARRAY_BUFFER, 2 * sizef, - FloatBuffer.wrap(tessGeo.pointAttribs, 0, 2 * size), PGL.STATIC_DRAW); + tessGeo.pointAttribsBuffer, PGL.STATIC_DRAW); + tessGeo.updatePointIndicesBuffer(); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glPointIndex); pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, tessGeo.pointIndexCount * PGL.SIZEOF_INDEX, - ShortBuffer.wrap(tessGeo.pointIndices, 0, tessGeo.pointIndexCount), - PGL.STATIC_DRAW); + tessGeo.pointIndicesBuffer, PGL.STATIC_DRAW); } @@ -1687,7 +1706,8 @@ public class PGraphicsOpenGL extends PGraphics { pgl.disable(PGL.POLYGON_SMOOTH); } - pgl.viewport(viewport[0], viewport[1], viewport[2], viewport[3]); + pgl.viewport(viewport.get(0), viewport.get(1), + viewport.get(2), viewport.get(3)); if (clip) { pgl.enable(PGL.SCISSOR_TEST); pgl.scissor(clipRect[0], clipRect[1], clipRect[2], clipRect[3]); @@ -5917,10 +5937,10 @@ public class PGraphicsOpenGL extends PGraphics { } if (primarySurface) { - int[] temp = new int[1]; - pgl.getIntegerv(PGL.SAMPLES, temp, 0); - if (quality != temp[0] && 1 < temp[0] && 1 < quality) { - quality = temp[0]; + pgl.getIntegerv(PGL.SAMPLES, intBuffer); + int temp = intBuffer.get(0); + if (quality != temp && 1 < temp && 1 < quality) { + quality = temp; } } if (quality < 2) { @@ -5933,8 +5953,10 @@ public class PGraphicsOpenGL extends PGraphics { pgl.disable(PGL.POLYGON_SMOOTH); // setup opengl viewport. - viewport[0] = 0; viewport[1] = 0; viewport[2] = width; viewport[3] = height; - pgl.viewport(viewport[0], viewport[1], viewport[2], viewport[3]); + viewport.put(0, 0); viewport.put(1, 0); + viewport.put(2, width); viewport.put(3, height); + pgl.viewport(viewport.get(0), viewport.get(1), + viewport.get(2), viewport.get(3)); if (sized) { // To avoid having garbage in the screen after a resize, @@ -6044,27 +6066,24 @@ public class PGraphicsOpenGL extends PGraphics { blendEqSupported = false; } - int temp[] = new int[2]; - depthBits = pgl.getDepthBits(); stencilBits = pgl.getStencilBits(); - pgl.getIntegerv(PGL.MAX_TEXTURE_SIZE, temp, 0); - maxTextureSize = temp[0]; + pgl.getIntegerv(PGL.MAX_TEXTURE_SIZE, intBuffer); + maxTextureSize = intBuffer.get(0); - pgl.getIntegerv(PGL.MAX_SAMPLES, temp, 0); - maxSamples = temp[0]; + pgl.getIntegerv(PGL.MAX_SAMPLES, intBuffer); + maxSamples = intBuffer.get(0); - pgl.getIntegerv(PGL.ALIASED_LINE_WIDTH_RANGE, temp, 0); - maxLineWidth = temp[1]; + pgl.getIntegerv(PGL.ALIASED_LINE_WIDTH_RANGE, intBuffer); + maxLineWidth = intBuffer.get(0); - pgl.getIntegerv(PGL.ALIASED_POINT_SIZE_RANGE, temp, 0); - maxPointSize = temp[1]; + pgl.getIntegerv(PGL.ALIASED_POINT_SIZE_RANGE, intBuffer); + maxPointSize = intBuffer.get(0); if (anisoSamplingSupported) { - float ftemp[] = new float[1]; - pgl.getFloatv(PGL.MAX_TEXTURE_MAX_ANISOTROPY, ftemp, 0); - maxAnisoAmount = ftemp[0]; + pgl.getFloatv(PGL.MAX_TEXTURE_MAX_ANISOTROPY, floatBuffer); + maxAnisoAmount = floatBuffer.get(0); } glParamsRead = true; @@ -6481,10 +6500,10 @@ public class PGraphicsOpenGL extends PGraphics { } if (-1 < viewportLoc) { - float x = pgCurrent.viewport[0]; - float y = pgCurrent.viewport[1]; - float w = pgCurrent.viewport[2]; - float h = pgCurrent.viewport[3]; + float x = pgCurrent.viewport.get(0); + float y = pgCurrent.viewport.get(1); + float w = pgCurrent.viewport.get(2); + float h = pgCurrent.viewport.get(3); setUniformValue(viewportLoc, x, y, w, h); } @@ -8695,7 +8714,7 @@ public class PGraphicsOpenGL extends PGraphics { addVertex(x1, y1, z2, 0, 0, VERTEX); addVertex(x1, y1, z1, 1, 0, VERTEX); addVertex(x1, y2, z1, 1, 1, VERTEX); - addVertex(x1, y2, z2, 0, 1, VERTEX);; + addVertex(x1, y2, z2, 0, 1, VERTEX); // top face setNormal(0, 1, 0); @@ -8876,52 +8895,71 @@ public class PGraphicsOpenGL extends PGraphics { int polyVertexCount; int firstPolyVertex; int lastPolyVertex; - float[] polyVertices; - int[] polyColors; - float[] polyNormals; - float[] polyTexcoords; + FloatBuffer polyVerticesBuffer; + IntBuffer polyColorsBuffer; + FloatBuffer polyNormalsBuffer; + FloatBuffer polyTexcoordsBuffer; // Polygon material properties (polyColors is used // as the diffuse color when lighting is enabled) - int[] polyAmbient; - int[] polySpecular; - int[] polyEmissive; - float[] polyShininess; + IntBuffer polyAmbientBuffer; + IntBuffer polySpecularBuffer; + IntBuffer polyEmissiveBuffer; + FloatBuffer polyShininessBuffer; int polyIndexCount; int firstPolyIndex; int lastPolyIndex; - short[] polyIndices; + ShortBuffer polyIndicesBuffer; IndexCache polyIndexCache = new IndexCache(); // Tessellated line data int lineVertexCount; int firstLineVertex; int lastLineVertex; - float[] lineVertices; - int[] lineColors; - float[] lineAttribs; + FloatBuffer lineVerticesBuffer; + IntBuffer lineColorsBuffer; + FloatBuffer lineAttribsBuffer; int lineIndexCount; int firstLineIndex; int lastLineIndex; - short[] lineIndices; + ShortBuffer lineIndicesBuffer; IndexCache lineIndexCache = new IndexCache(); // Tessellated point data int pointVertexCount; int firstPointVertex; int lastPointVertex; - float[] pointVertices; - int[] pointColors; - float[] pointAttribs; + FloatBuffer pointVerticesBuffer; + IntBuffer pointColorsBuffer; + FloatBuffer pointAttribsBuffer; int pointIndexCount; int firstPointIndex; int lastPointIndex; - short[] pointIndices; + ShortBuffer pointIndicesBuffer; IndexCache pointIndexCache = new IndexCache(); + // Backing arrays + float[] polyVertices; + int[] polyColors; + float[] polyNormals; + float[] polyTexcoords; + int[] polyAmbient; + int[] polySpecular; + int[] polyEmissive; + float[] polyShininess; + short[] polyIndices; + float[] lineVertices; + int[] lineColors; + float[] lineAttribs; + short[] lineIndices; + float[] pointVertices; + int[] pointColors; + float[] pointAttribs; + short[] pointIndices; + TessGeometry(int mode) { renderMode = mode; allocate(); @@ -8932,6 +8970,26 @@ public class PGraphicsOpenGL extends PGraphics { // Allocate/dispose void allocate() { + polyVerticesBuffer = PGL.allocateDirectFloatBuffer(4 * PGL.DEFAULT_TESS_VERTICES); + polyColorsBuffer = PGL.allocateDirectIntBuffer(PGL.DEFAULT_TESS_VERTICES); + polyNormalsBuffer = PGL.allocateDirectFloatBuffer(3 * PGL.DEFAULT_TESS_VERTICES); + polyTexcoordsBuffer = PGL.allocateDirectFloatBuffer(2 * PGL.DEFAULT_TESS_VERTICES); + polyAmbientBuffer = PGL.allocateDirectIntBuffer(PGL.DEFAULT_TESS_VERTICES); + polySpecularBuffer = PGL.allocateDirectIntBuffer(PGL.DEFAULT_TESS_VERTICES); + polyEmissiveBuffer = PGL.allocateDirectIntBuffer(PGL.DEFAULT_TESS_VERTICES); + polyShininessBuffer = PGL.allocateDirectFloatBuffer(PGL.DEFAULT_TESS_VERTICES); + polyIndicesBuffer = PGL.allocateDirectShortBuffer(PGL.DEFAULT_TESS_VERTICES); + + lineVerticesBuffer = PGL.allocateDirectFloatBuffer(4 * PGL.DEFAULT_TESS_VERTICES); + lineColorsBuffer = PGL.allocateDirectIntBuffer(PGL.DEFAULT_TESS_VERTICES); + lineAttribsBuffer = PGL.allocateDirectFloatBuffer(4 * PGL.DEFAULT_TESS_VERTICES); + lineIndicesBuffer = PGL.allocateDirectShortBuffer(PGL.DEFAULT_TESS_VERTICES); + + pointVerticesBuffer = PGL.allocateDirectFloatBuffer(4 * PGL.DEFAULT_TESS_VERTICES); + pointColorsBuffer = PGL.allocateDirectIntBuffer(PGL.DEFAULT_TESS_VERTICES); + pointAttribsBuffer = PGL.allocateDirectFloatBuffer(2 * PGL.DEFAULT_TESS_VERTICES); + pointIndicesBuffer = PGL.allocateDirectShortBuffer(PGL.DEFAULT_TESS_VERTICES); + polyVertices = new float[4 * PGL.DEFAULT_TESS_VERTICES]; polyColors = new int[PGL.DEFAULT_TESS_VERTICES]; polyNormals = new float[3 * PGL.DEFAULT_TESS_VERTICES]; @@ -8971,6 +9029,26 @@ public class PGraphicsOpenGL extends PGraphics { } void dipose() { + polyVerticesBuffer = null; + polyColorsBuffer = null; + polyNormalsBuffer = null; + polyTexcoordsBuffer = null; + polyAmbientBuffer = null; + polySpecularBuffer = null; + polyEmissiveBuffer = null; + polyShininessBuffer = null; + polyIndicesBuffer = null; + + lineVerticesBuffer = null; + lineColorsBuffer = null; + lineAttribsBuffer = null; + lineIndicesBuffer = null; + + pointVerticesBuffer = null; + pointColorsBuffer = null; + pointAttribsBuffer = null; + pointIndicesBuffer = null; + polyVertices = null; polyColors = null; polyNormals = null; @@ -8993,7 +9071,7 @@ public class PGraphicsOpenGL extends PGraphics { } void polyVertexCheck() { - if (polyVertexCount == polyVertices.length / 4) { + if (polyVertexCount == polyVerticesBuffer.capacity() / 4) { int newSize = polyVertexCount << 1; expandPolyVertices(newSize); @@ -9012,7 +9090,7 @@ public class PGraphicsOpenGL extends PGraphics { } void polyVertexCheck(int count) { - int oldSize = polyVertices.length / 4; + int oldSize = polyVerticesBuffer.capacity() / 4; if (polyVertexCount + count > oldSize) { int newSize = expandArraySize(oldSize, polyVertexCount + count); @@ -9032,7 +9110,7 @@ public class PGraphicsOpenGL extends PGraphics { } void polyIndexCheck(int count) { - int oldSize = polyIndices.length; + int oldSize = polyIndicesBuffer.capacity(); if (polyIndexCount + count > oldSize) { int newSize = expandArraySize(oldSize, polyIndexCount + count); @@ -9045,8 +9123,9 @@ public class PGraphicsOpenGL extends PGraphics { } void polyIndexCheck() { - if (polyIndexCount == polyIndices.length) { + if (polyIndexCount == polyIndicesBuffer.capacity()) { int newSize = polyIndexCount << 1; + expandPolyIndices(newSize); } @@ -9056,7 +9135,7 @@ public class PGraphicsOpenGL extends PGraphics { } void lineVertexCheck(int count) { - int oldSize = lineVertices.length / 4; + int oldSize = lineVerticesBuffer.capacity() / 4; if (lineVertexCount + count > oldSize) { int newSize = expandArraySize(oldSize, lineVertexCount + count); @@ -9071,7 +9150,7 @@ public class PGraphicsOpenGL extends PGraphics { } void lineIndexCheck(int count) { - int oldSize = lineIndices.length; + int oldSize = lineIndicesBuffer.capacity(); if (lineIndexCount + count > oldSize) { int newSize = expandArraySize(oldSize, lineIndexCount + count); @@ -9084,7 +9163,7 @@ public class PGraphicsOpenGL extends PGraphics { } void pointVertexCheck(int count) { - int oldSize = pointVertices.length / 4; + int oldSize = pointVerticesBuffer.capacity() / 4; if (pointVertexCount + count > oldSize) { int newSize = expandArraySize(oldSize, pointVertexCount + count); @@ -9099,7 +9178,7 @@ public class PGraphicsOpenGL extends PGraphics { } void pointIndexCheck(int count) { - int oldSize = pointIndices.length; + int oldSize = pointIndicesBuffer.capacity(); if (pointIndexCount + count > oldSize) { int newSize = expandArraySize(oldSize, pointIndexCount + count); @@ -9205,107 +9284,315 @@ public class PGraphicsOpenGL extends PGraphics { return last - first + 1; } + // ----------------------------------------------------------------- + // + // Methods to prepare buffers for relative read/write operations + + protected void updatePolyVerticesBuffer() { + updatePolyVerticesBuffer(0, polyVertexCount); + } + + protected void updatePolyVerticesBuffer(int offset, int size) { + polyVerticesBuffer.position(4 * offset); + polyVerticesBuffer.put(polyVertices, 4 * offset, 4 * size); + polyVerticesBuffer.rewind(); + } + + protected void updatePolyColorsBuffer() { + updatePolyColorsBuffer(0, polyVertexCount); + } + + protected void updatePolyColorsBuffer(int offset, int size) { + polyColorsBuffer.position(offset); + polyColorsBuffer.put(polyColors, offset, size); + polyColorsBuffer.rewind(); + } + + protected void updatePolyNormalsBuffer() { + updatePolyNormalsBuffer(0, polyVertexCount); + } + + protected void updatePolyNormalsBuffer(int offset, int size) { + polyNormalsBuffer.position(3 * offset); + polyNormalsBuffer.put(polyNormals, 3 * offset, 3 * size); + polyNormalsBuffer.rewind(); + } + + protected void updatePolyTexcoordsBuffer() { + updatePolyTexcoordsBuffer(0, polyVertexCount); + } + + protected void updatePolyTexcoordsBuffer(int offset, int size) { + polyTexcoordsBuffer.position(2 * offset); + polyTexcoordsBuffer.put(polyTexcoords, 2 * offset, 2 * size); + polyTexcoordsBuffer.rewind(); + } + + protected void updatePolyAmbientBuffer() { + updatePolyAmbientBuffer(0, polyVertexCount); + } + + protected void updatePolyAmbientBuffer(int offset, int size) { + polyAmbientBuffer.position(offset); + polyAmbientBuffer.put(polyAmbient, offset, size); + polyAmbientBuffer.rewind(); + } + + protected void updatePolySpecularBuffer() { + updatePolySpecularBuffer(0, polyVertexCount); + } + + protected void updatePolySpecularBuffer(int offset, int size) { + polySpecularBuffer.position(offset); + polySpecularBuffer.put(polySpecular, offset, size); + polySpecularBuffer.rewind(); + } + + protected void updatePolyEmissiveBuffer() { + updatePolyEmissiveBuffer(0, polyVertexCount); + } + + protected void updatePolyEmissiveBuffer(int offset, int size) { + polyEmissiveBuffer.position(offset); + polyEmissiveBuffer.put(polyEmissive, offset, size); + polyEmissiveBuffer.rewind(); + } + + protected void updatePolyShininessBuffer() { + updatePolyShininessBuffer(0, polyVertexCount); + } + + protected void updatePolyShininessBuffer(int offset, int size) { + polyShininessBuffer.position(offset); + polyShininessBuffer.put(polyShininess, offset, size); + polyShininessBuffer.rewind(); + } + + protected void updatePolyIndicesBuffer() { + updatePolyIndicesBuffer(0, polyIndexCount); + } + + protected void updatePolyIndicesBuffer(int offset, int size) { + polyIndicesBuffer.position(offset); + polyIndicesBuffer.put(polyIndices, offset, size); + polyIndicesBuffer.rewind(); + } + + protected void updateLineVerticesBuffer() { + updateLineVerticesBuffer(0, lineVertexCount); + } + + protected void updateLineVerticesBuffer(int offset, int size) { + lineVerticesBuffer.position(4 * offset); + lineVerticesBuffer.put(lineVertices, 4 * offset, 4 * size); + lineVerticesBuffer.rewind(); + } + + protected void updateLineColorsBuffer() { + updateLineColorsBuffer(0, lineVertexCount); + } + + protected void updateLineColorsBuffer(int offset, int size) { + lineColorsBuffer.position(offset); + lineColorsBuffer.put(lineColors, offset, size); + lineColorsBuffer.rewind(); + } + + protected void updateLineAttribsBuffer() { + updateLineAttribsBuffer(0, lineVertexCount); + } + + protected void updateLineAttribsBuffer(int offset, int size) { + lineAttribsBuffer.position(4 * offset); + lineAttribsBuffer.put(lineAttribs, 4 * offset, 4 * size); + lineAttribsBuffer.rewind(); + } + + protected void updateLineIndicesBuffer() { + updateLineIndicesBuffer(0, lineIndexCount); + } + + protected void updateLineIndicesBuffer(int offset, int size) { + lineIndicesBuffer.position(offset); + lineIndicesBuffer.put(lineIndices, offset, size); + lineIndicesBuffer.rewind(); + } + + protected void updatePointVerticesBuffer() { + updatePointVerticesBuffer(0, pointVertexCount); + } + + protected void updatePointVerticesBuffer(int offset, int size) { + pointVerticesBuffer.position(4 * offset); + pointVerticesBuffer.put(pointVertices, 4 * offset, 4 * size); + pointVerticesBuffer.rewind(); + } + + protected void updatePointColorsBuffer() { + updatePointColorsBuffer(0, pointVertexCount); + } + + protected void updatePointColorsBuffer(int offset, int size) { + pointColorsBuffer.position(offset); + pointColorsBuffer.put(pointColors, offset, size); + pointColorsBuffer.rewind(); + } + + protected void updatePointAttribsBuffer() { + updatePointAttribsBuffer(0, pointVertexCount); + } + + protected void updatePointAttribsBuffer(int offset, int size) { + pointAttribsBuffer.position(2 * offset); + pointAttribsBuffer.put(pointAttribs, 2 * offset, 2 * size); + pointAttribsBuffer.rewind(); + } + + protected void updatePointIndicesBuffer() { + updatePointIndicesBuffer(0, pointIndexCount); + } + + protected void updatePointIndicesBuffer(int offset, int size) { + pointIndicesBuffer.position(offset); + pointIndicesBuffer.put(pointIndices, offset, size); + pointIndicesBuffer.rewind(); + } + // ----------------------------------------------------------------- // // Expand arrays void expandPolyVertices(int n) { + polyVerticesBuffer = PGL.allocateDirectFloatBuffer(4 * n); + float temp[] = new float[4 * n]; PApplet.arrayCopy(polyVertices, 0, temp, 0, 4 * polyVertexCount); polyVertices = temp; } void expandPolyColors(int n) { + polyColorsBuffer = PGL.allocateDirectIntBuffer(n); + int temp[] = new int[n]; PApplet.arrayCopy(polyColors, 0, temp, 0, polyVertexCount); polyColors = temp; } void expandPolyNormals(int n) { + polyNormalsBuffer = PGL.allocateDirectFloatBuffer(3 * n); + float temp[] = new float[3 * n]; PApplet.arrayCopy(polyNormals, 0, temp, 0, 3 * polyVertexCount); polyNormals = temp; } void expandPolyTexcoords(int n) { + polyTexcoordsBuffer = PGL.allocateDirectFloatBuffer(2 * n); + float temp[] = new float[2 * n]; PApplet.arrayCopy(polyTexcoords, 0, temp, 0, 2 * polyVertexCount); polyTexcoords = temp; } void expandPolyAmbient(int n) { + polyAmbientBuffer = PGL.allocateDirectIntBuffer(n); + int temp[] = new int[n]; PApplet.arrayCopy(polyAmbient, 0, temp, 0, polyVertexCount); polyAmbient = temp; } void expandPolySpecular(int n) { + polySpecularBuffer = PGL.allocateDirectIntBuffer(n); + int temp[] = new int[n]; PApplet.arrayCopy(polySpecular, 0, temp, 0, polyVertexCount); polySpecular = temp; } void expandPolyEmissive(int n) { + polyEmissiveBuffer = PGL.allocateDirectIntBuffer(n); + int temp[] = new int[n]; PApplet.arrayCopy(polyEmissive, 0, temp, 0, polyVertexCount); polyEmissive = temp; } void expandPolyShininess(int n) { + polyShininessBuffer = PGL.allocateDirectFloatBuffer(n); + float temp[] = new float[n]; PApplet.arrayCopy(polyShininess, 0, temp, 0, polyVertexCount); polyShininess = temp; } void expandPolyIndices(int n) { + polyIndicesBuffer = PGL.allocateDirectShortBuffer(n); + short temp[] = new short[n]; PApplet.arrayCopy(polyIndices, 0, temp, 0, polyIndexCount); polyIndices = temp; } void expandLineVertices(int n) { + lineVerticesBuffer = PGL.allocateDirectFloatBuffer(4 * n); + float temp[] = new float[4 * n]; PApplet.arrayCopy(lineVertices, 0, temp, 0, 4 * lineVertexCount); lineVertices = temp; } void expandLineColors(int n) { + lineColorsBuffer = PGL.allocateDirectIntBuffer(n); + int temp[] = new int[n]; PApplet.arrayCopy(lineColors, 0, temp, 0, lineVertexCount); lineColors = temp; } void expandLineAttribs(int n) { + lineAttribsBuffer = PGL.allocateDirectFloatBuffer(4 * n); + float temp[] = new float[4 * n]; PApplet.arrayCopy(lineAttribs, 0, temp, 0, 4 * lineVertexCount); lineAttribs = temp; } void expandLineIndices(int n) { + lineIndicesBuffer = PGL.allocateDirectShortBuffer(n); + short temp[] = new short[n]; PApplet.arrayCopy(lineIndices, 0, temp, 0, lineIndexCount); lineIndices = temp; } void expandPointVertices(int n) { + pointVerticesBuffer = PGL.allocateDirectFloatBuffer(4 * n); + float temp[] = new float[4 * n]; PApplet.arrayCopy(pointVertices, 0, temp, 0, 4 * pointVertexCount); pointVertices = temp; } void expandPointColors(int n) { + pointColorsBuffer = PGL.allocateDirectIntBuffer(n); + int temp[] = new int[n]; PApplet.arrayCopy(pointColors, 0, temp, 0, pointVertexCount); pointColors = temp; } void expandPointAttribs(int n) { + pointAttribsBuffer = PGL.allocateDirectFloatBuffer(2 * n); + float temp[] = new float[2 * n]; PApplet.arrayCopy(pointAttribs, 0, temp, 0, 2 * pointVertexCount); pointAttribs = temp; } void expandPointIndices(int n) { + pointIndicesBuffer = PGL.allocateDirectShortBuffer(n); + short temp[] = new short[n]; PApplet.arrayCopy(pointIndices, 0, temp, 0, pointIndexCount); pointIndices = temp; @@ -9316,7 +9603,7 @@ public class PGraphicsOpenGL extends PGraphics { // Trim arrays void trim() { - if (0 < polyVertexCount && polyVertexCount < polyVertices.length / 4) { + if (0 < polyVertexCount && polyVertexCount < polyVerticesBuffer.capacity() / 4) { trimPolyVertices(); trimPolyColors(); trimPolyNormals(); @@ -9327,128 +9614,162 @@ public class PGraphicsOpenGL extends PGraphics { trimPolyShininess(); } - if (0 < polyIndexCount && polyIndexCount < polyIndices.length) { + if (0 < polyIndexCount && polyIndexCount < polyIndicesBuffer.capacity()) { trimPolyIndices(); } - if (0 < lineVertexCount && lineVertexCount < lineVertices.length / 4) { + if (0 < lineVertexCount && lineVertexCount < lineVerticesBuffer.capacity() / 4) { trimLineVertices(); trimLineColors(); trimLineAttribs(); } - if (0 < lineIndexCount && lineIndexCount < lineIndices.length) { + if (0 < lineIndexCount && lineIndexCount < lineIndicesBuffer.capacity()) { trimLineIndices(); } - if (0 < pointVertexCount && pointVertexCount < pointVertices.length / 4) { + if (0 < pointVertexCount && pointVertexCount < pointVerticesBuffer.capacity() / 4) { trimPointVertices(); trimPointColors(); trimPointAttribs(); } - if (0 < pointIndexCount && pointIndexCount < pointIndices.length) { + if (0 < pointIndexCount && pointIndexCount < pointIndicesBuffer.capacity()) { trimPointIndices(); } } void trimPolyVertices() { + polyVerticesBuffer = PGL.allocateDirectFloatBuffer(4 * polyVertexCount); + float temp[] = new float[4 * polyVertexCount]; PApplet.arrayCopy(polyVertices, 0, temp, 0, 4 * polyVertexCount); polyVertices = temp; } void trimPolyColors() { + polyColorsBuffer = PGL.allocateDirectIntBuffer(polyVertexCount); + int temp[] = new int[polyVertexCount]; PApplet.arrayCopy(polyColors, 0, temp, 0, polyVertexCount); polyColors = temp; } void trimPolyNormals() { + polyNormalsBuffer = PGL.allocateDirectFloatBuffer(3 * polyVertexCount); + float temp[] = new float[3 * polyVertexCount]; PApplet.arrayCopy(polyNormals, 0, temp, 0, 3 * polyVertexCount); polyNormals = temp; } void trimPolyTexcoords() { + polyTexcoordsBuffer = PGL.allocateDirectFloatBuffer(2 * polyVertexCount); + float temp[] = new float[2 * polyVertexCount]; PApplet.arrayCopy(polyTexcoords, 0, temp, 0, 2 * polyVertexCount); polyTexcoords = temp; } void trimPolyAmbient() { + polyAmbientBuffer = PGL.allocateDirectIntBuffer(polyVertexCount); + int temp[] = new int[polyVertexCount]; PApplet.arrayCopy(polyAmbient, 0, temp, 0, polyVertexCount); polyAmbient = temp; } void trimPolySpecular() { + polySpecularBuffer = PGL.allocateDirectIntBuffer(polyVertexCount); + int temp[] = new int[polyVertexCount]; PApplet.arrayCopy(polySpecular, 0, temp, 0, polyVertexCount); polySpecular = temp; } void trimPolyEmissive() { + polyEmissiveBuffer = PGL.allocateDirectIntBuffer(polyVertexCount); + int temp[] = new int[polyVertexCount]; PApplet.arrayCopy(polyEmissive, 0, temp, 0, polyVertexCount); polyEmissive = temp; } void trimPolyShininess() { + polyShininessBuffer = PGL.allocateDirectFloatBuffer(polyVertexCount); + float temp[] = new float[polyVertexCount]; PApplet.arrayCopy(polyShininess, 0, temp, 0, polyVertexCount); polyShininess = temp; } void trimPolyIndices() { + polyIndicesBuffer = PGL.allocateDirectShortBuffer(polyIndexCount); + short temp[] = new short[polyIndexCount]; PApplet.arrayCopy(polyIndices, 0, temp, 0, polyIndexCount); polyIndices = temp; } void trimLineVertices() { + lineVerticesBuffer = PGL.allocateDirectFloatBuffer(4 * lineVertexCount); + float temp[] = new float[4 * lineVertexCount]; PApplet.arrayCopy(lineVertices, 0, temp, 0, 4 * lineVertexCount); lineVertices = temp; } void trimLineColors() { + lineColorsBuffer = PGL.allocateDirectIntBuffer(lineVertexCount); + int temp[] = new int[lineVertexCount]; PApplet.arrayCopy(lineColors, 0, temp, 0, lineVertexCount); lineColors = temp; } void trimLineAttribs() { + lineAttribsBuffer = PGL.allocateDirectFloatBuffer(4 * lineVertexCount); + float temp[] = new float[4 * lineVertexCount]; PApplet.arrayCopy(lineAttribs, 0, temp, 0, 4 * lineVertexCount); lineAttribs = temp; } void trimLineIndices() { + lineIndicesBuffer = PGL.allocateDirectShortBuffer(lineIndexCount); + short temp[] = new short[lineIndexCount]; PApplet.arrayCopy(lineIndices, 0, temp, 0, lineIndexCount); lineIndices = temp; } void trimPointVertices() { + pointVerticesBuffer = PGL.allocateDirectFloatBuffer(4 * pointVertexCount); + float temp[] = new float[4 * pointVertexCount]; PApplet.arrayCopy(pointVertices, 0, temp, 0, 4 * pointVertexCount); pointVertices = temp; } void trimPointColors() { + pointColorsBuffer = PGL.allocateDirectIntBuffer(pointVertexCount); + int temp[] = new int[pointVertexCount]; PApplet.arrayCopy(pointColors, 0, temp, 0, pointVertexCount); pointColors = temp; } void trimPointAttribs() { + pointAttribsBuffer = PGL.allocateDirectFloatBuffer(2 * pointVertexCount); + float temp[] = new float[2 * pointVertexCount]; PApplet.arrayCopy(pointAttribs, 0, temp, 0, 2 * pointVertexCount); pointAttribs = temp; } void trimPointIndices() { + pointIndicesBuffer = PGL.allocateDirectShortBuffer(pointIndexCount); + short temp[] = new short[pointIndexCount]; PApplet.arrayCopy(pointIndices, 0, temp, 0, pointIndexCount); pointIndices = temp; @@ -9649,6 +9970,20 @@ public class PGraphicsOpenGL extends PGraphics { // // Add poly geometry + void addPolyVertex(float x, float y, float z, + int rgba, + float nx, float ny, float nz, + float u, float v, + int am, int sp, int em, float shine) { + polyVertexCheck(); + int tessIdx = polyVertexCount - 1; + setPolyVertex(tessIdx, x, y, z, + rgba, + nx, ny, nz, + u, v, + am, sp, em, shine); + } + void setPolyVertex(int tessIdx, float x, float y, float z, int rgba) { setPolyVertex(tessIdx, x, y, z, rgba, @@ -9703,54 +10038,6 @@ public class PGraphicsOpenGL extends PGraphics { polyShininess[tessIdx] = shine; } - void addPolyVertex(float x, float y, float z, - int rgba, - float nx, float ny, float nz, - float u, float v, - int am, int sp, int em, float shine) { - polyVertexCheck(); - int index; - int count = polyVertexCount - 1; - - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL) { - PMatrix3D mm = modelview; - PMatrix3D nm = modelviewInv; - - index = 4 * count; - polyVertices[index++] = x*mm.m00 + y*mm.m01 + z*mm.m02 + mm.m03; - polyVertices[index++] = x*mm.m10 + y*mm.m11 + z*mm.m12 + mm.m13; - polyVertices[index++] = x*mm.m20 + y*mm.m21 + z*mm.m22 + mm.m23; - polyVertices[index ] = x*mm.m30 + y*mm.m31 + z*mm.m32 + mm.m33; - - index = 3 * count; - polyNormals[index++] = nx*nm.m00 + ny*nm.m10 + nz*nm.m20; - polyNormals[index++] = nx*nm.m01 + ny*nm.m11 + nz*nm.m21; - polyNormals[index ] = nx*nm.m02 + ny*nm.m12 + nz*nm.m22; - } else { - index = 4 * count; - polyVertices[index++] = x; - polyVertices[index++] = y; - polyVertices[index++] = z; - polyVertices[index ] = 1; - - index = 3 * count; - polyNormals[index++] = nx; - polyNormals[index++] = ny; - polyNormals[index ] = nz; - } - - polyColors[count] = rgba; - - index = 2 * count; - polyTexcoords[index++] = u; - polyTexcoords[index ] = v; - - polyAmbient[count] = am; - polySpecular[count] = sp; - polyEmissive[count] = em; - polyShininess[count] = shine; - } - void addPolyVertices(InGeometry in) { addPolyVertices(in, in.firstVertex, in.lastVertex); } @@ -10045,6 +10332,7 @@ public class PGraphicsOpenGL extends PGraphics { } } + // Generates tessellated geometry given a batch of input vertices. // Generates tessellated geometry given a batch of input vertices. protected class Tessellator { InGeometry in; diff --git a/android/core/src/processing/opengl/PShader.java b/android/core/src/processing/opengl/PShader.java index 15c263cfb..acba492c4 100644 --- a/android/core/src/processing/opengl/PShader.java +++ b/android/core/src/processing/opengl/PShader.java @@ -27,6 +27,8 @@ import processing.core.*; import java.io.IOException; import java.net.URL; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; import java.util.HashMap; /** @@ -79,6 +81,9 @@ public class PShader { protected int firstTexUnit; protected int lastTexUnit; + // Direct buffers to pass shader dat to GL + protected IntBuffer intBuffer; + protected FloatBuffer floatBuffer; public PShader() { parent = null; @@ -97,6 +102,9 @@ public class PShader { firstTexUnit = 0; + intBuffer = PGL.allocateDirectIntBuffer(1); + floatBuffer = PGL.allocateDirectFloatBuffer(1); + bound = false; } @@ -132,6 +140,9 @@ public class PShader { glProgram = 0; glVertex = 0; glFragment = 0; + + intBuffer = PGL.allocateDirectIntBuffer(1); + floatBuffer = PGL.allocateDirectFloatBuffer(1); } /** @@ -151,6 +162,9 @@ public class PShader { glProgram = 0; glVertex = 0; glFragment = 0; + + intBuffer = PGL.allocateDirectIntBuffer(1); + floatBuffer = PGL.allocateDirectFloatBuffer(1); } @@ -460,14 +474,15 @@ public class PShader { protected void setUniformVector(int loc, int[] vec, int ncoords, int length) { if (-1 < loc) { + copyToIntBuffer(vec); if (ncoords == 1) { - pgl.uniform1iv(loc, length, vec, 0); + pgl.uniform1iv(loc, length, intBuffer); } else if (ncoords == 2) { - pgl.uniform2iv(loc, length, vec, 0); + pgl.uniform2iv(loc, length, intBuffer); } else if (ncoords == 3) { - pgl.uniform3iv(loc, length, vec, 0); + pgl.uniform3iv(loc, length, intBuffer); } else if (ncoords == 4) { - pgl.uniform3iv(loc, length, vec, 0); + pgl.uniform3iv(loc, length, intBuffer); } } } @@ -476,14 +491,15 @@ public class PShader { protected void setUniformVector(int loc, float[] vec, int ncoords, int length) { if (-1 < loc) { + copyToFloatBuffer(vec); if (ncoords == 1) { - pgl.uniform1fv(loc, length, vec, 0); + pgl.uniform1fv(loc, length, floatBuffer); } else if (ncoords == 2) { - pgl.uniform2fv(loc, length, vec, 0); + pgl.uniform2fv(loc, length, floatBuffer); } else if (ncoords == 3) { - pgl.uniform3fv(loc, length, vec, 0); + pgl.uniform3fv(loc, length, floatBuffer); } else if (ncoords == 4) { - pgl.uniform4fv(loc, length, vec, 0); + pgl.uniform4fv(loc, length, floatBuffer); } } } @@ -491,12 +507,13 @@ public class PShader { protected void setUniformMatrix(int loc, float[] mat) { if (-1 < loc) { + copyToFloatBuffer(mat); if (mat.length == 4) { - pgl.uniformMatrix2fv(loc, 1, false, mat, 0); + pgl.uniformMatrix2fv(loc, 1, false, floatBuffer); } else if (mat.length == 9) { - pgl.uniformMatrix3fv(loc, 1, false, mat, 0); + pgl.uniformMatrix3fv(loc, 1, false, floatBuffer); } else if (mat.length == 16) { - pgl.uniformMatrix4fv(loc, 1, false, mat, 0); + pgl.uniformMatrix4fv(loc, 1, false, floatBuffer); } } } @@ -587,37 +604,48 @@ public class PShader { pgl.uniform4f(loc, v[0], v[1], v[2], v[3]); } else if (val.type == UniformValue.INT1VEC) { int[] v = ((int[])val.value); - pgl.uniform1iv(loc, v.length, v, 0); + copyToIntBuffer(v); + pgl.uniform1iv(loc, v.length, intBuffer); } else if (val.type == UniformValue.INT2VEC) { int[] v = ((int[])val.value); - pgl.uniform2iv(loc, v.length / 2, v, 0); + copyToIntBuffer(v); + pgl.uniform2iv(loc, v.length / 2, intBuffer); } else if (val.type == UniformValue.INT3VEC) { int[] v = ((int[])val.value); - pgl.uniform3iv(loc, v.length / 3, v, 0); + copyToIntBuffer(v); + pgl.uniform3iv(loc, v.length / 3, intBuffer); } else if (val.type == UniformValue.INT4VEC) { int[] v = ((int[])val.value); - pgl.uniform4iv(loc, v.length / 4, v, 0); + copyToIntBuffer(v); + pgl.uniform4iv(loc, v.length / 4, intBuffer); } else if (val.type == UniformValue.FLOAT1VEC) { float[] v = ((float[])val.value); - pgl.uniform1fv(loc, v.length, v, 0); + copyToFloatBuffer(v); + pgl.uniform1fv(loc, v.length, floatBuffer); } else if (val.type == UniformValue.FLOAT2VEC) { float[] v = ((float[])val.value); - pgl.uniform2fv(loc, v.length / 2, v, 0); + copyToFloatBuffer(v); + pgl.uniform2fv(loc, v.length / 2, floatBuffer); } else if (val.type == UniformValue.FLOAT3VEC) { float[] v = ((float[])val.value); - pgl.uniform3fv(loc, v.length / 3, v, 0); + copyToFloatBuffer(v); + pgl.uniform3fv(loc, v.length / 3, floatBuffer); } else if (val.type == UniformValue.FLOAT4VEC) { float[] v = ((float[])val.value); - pgl.uniform4fv(loc, v.length / 4, v, 0); + copyToFloatBuffer(v); + pgl.uniform4fv(loc, v.length / 4, floatBuffer); } else if (val.type == UniformValue.MAT2) { float[] v = ((float[])val.value); - pgl.uniformMatrix2fv(loc, 1, false, v, 0); + copyToFloatBuffer(v); + pgl.uniformMatrix2fv(loc, 1, false, floatBuffer); } else if (val.type == UniformValue.MAT3) { float[] v = ((float[])val.value); - pgl.uniformMatrix3fv(loc, 1, false, v, 0); + copyToFloatBuffer(v); + pgl.uniformMatrix3fv(loc, 1, false, floatBuffer); } else if (val.type == UniformValue.MAT4) { float[] v = ((float[])val.value); - pgl.uniformMatrix4fv(loc, 1, false, v, 0); + copyToFloatBuffer(v); + pgl.uniformMatrix4fv(loc, 1, false, floatBuffer); } else if (val.type == UniformValue.SAMPLER2D) { PImage img = (PImage)val.value; Texture tex = pgMain.getTexture(img); @@ -634,6 +662,26 @@ public class PShader { } + protected void copyToIntBuffer(int[] vec) { + if (intBuffer.capacity() < vec.length) { + intBuffer = PGL.allocateDirectIntBuffer(vec.length); + } + intBuffer.rewind(); + intBuffer.put(vec, 0, vec.length); + intBuffer.rewind(); + } + + + protected void copyToFloatBuffer(float[] vec) { + if (floatBuffer.capacity() < vec.length) { + floatBuffer = PGL.allocateDirectFloatBuffer(vec.length); + } + floatBuffer.rewind(); + floatBuffer.put(vec, 0, vec.length); + floatBuffer.rewind(); + } + + protected void bindTextures() { if (textures != null) { for (int unit: textures.keySet()) { @@ -701,18 +749,17 @@ public class PShader { } pgl.linkProgram(glProgram); - int[] linked = new int[1]; - pgl.getProgramiv(glProgram, PGL.LINK_STATUS, linked, 0); - if (linked[0] == PGL.FALSE) { + pgl.getProgramiv(glProgram, PGL.LINK_STATUS, intBuffer); + boolean linked = intBuffer.get(0) == 0 ? false : true; + if (!linked) { PGraphics.showException("Cannot link shader program:\n" + pgl.getProgramInfoLog(glProgram)); } pgl.validateProgram(glProgram); - - int[] validated = new int[1]; - pgl.getProgramiv(glProgram, PGL.VALIDATE_STATUS, validated, 0); - if (validated[0] == PGL.FALSE) { + pgl.getProgramiv(glProgram, PGL.VALIDATE_STATUS, intBuffer); + boolean validated = intBuffer.get(0) == 0 ? false : true; + if (!validated) { PGraphics.showException("Cannot validate shader program:\n" + pgl.getProgramInfoLog(glProgram)); } @@ -801,9 +848,9 @@ public class PShader { pgl.shaderSource(glVertex, vertexShaderSource); pgl.compileShader(glVertex); - int[] compiled = new int[1]; - pgl.getShaderiv(glVertex, PGL.COMPILE_STATUS, compiled, 0); - if (compiled[0] == PGL.FALSE) { + pgl.getShaderiv(glVertex, PGL.COMPILE_STATUS, intBuffer); + boolean compiled = intBuffer.get(0) == 0 ? false : true; + if (!compiled) { PGraphics.showException("Cannot compile vertex shader:\n" + pgl.getShaderInfoLog(glVertex)); return false; @@ -822,9 +869,9 @@ public class PShader { pgl.shaderSource(glFragment, fragmentShaderSource); pgl.compileShader(glFragment); - int[] compiled = new int[1]; - pgl.getShaderiv(glFragment, PGL.COMPILE_STATUS, compiled, 0); - if (compiled[0] == PGL.FALSE) { + pgl.getShaderiv(glFragment, PGL.COMPILE_STATUS, intBuffer); + boolean compiled = intBuffer.get(0) == 0 ? false : true; + if (!compiled) { PGraphics.showException("Cannot compile fragment shader:\n" + pgl.getShaderInfoLog(glFragment)); return false; diff --git a/android/core/src/processing/opengl/PShapeOpenGL.java b/android/core/src/processing/opengl/PShapeOpenGL.java index 8f2149cb4..d8920294a 100644 --- a/android/core/src/processing/opengl/PShapeOpenGL.java +++ b/android/core/src/processing/opengl/PShapeOpenGL.java @@ -39,9 +39,6 @@ import processing.opengl.PGraphicsOpenGL.InGeometry; import processing.opengl.PGraphicsOpenGL.TessGeometry; import processing.opengl.PGraphicsOpenGL.Tessellator; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.nio.ShortBuffer; import java.util.Arrays; import java.util.HashSet; @@ -1662,7 +1659,7 @@ public class PShapeOpenGL extends PShape { PGL.javaToNativeARGB(ambientColor)); if (shapeEnded && tessellated && hasPolys) { if (is3D()) { - Arrays.fill(tessGeo.polyAmbient, firstPolyVertex, lastPolyVertex = 1, + Arrays.fill(tessGeo.polyAmbient, firstPolyVertex, lastPolyVertex + 1, PGL.javaToNativeARGB(ambientColor)); root.setModifiedPolyAmbient(firstPolyVertex, lastPolyVertex); } else if (is2D()) { @@ -3450,62 +3447,63 @@ public class PShapeOpenGL extends PShape { int sizef = size * PGL.SIZEOF_FLOAT; int sizei = size * PGL.SIZEOF_INT; + tessGeo.updatePolyVerticesBuffer(); glPolyVertex = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyVertex); pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, - FloatBuffer.wrap(tessGeo.polyVertices, 0, 4 * size), + tessGeo.polyVerticesBuffer, PGL.STATIC_DRAW); + tessGeo.updatePolyColorsBuffer(); glPolyColor = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyColor); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, - IntBuffer.wrap(tessGeo.polyColors, 0, size), - PGL.STATIC_DRAW); + tessGeo.polyColorsBuffer, PGL.STATIC_DRAW); + tessGeo.updatePolyNormalsBuffer(); glPolyNormal = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyNormal); pgl.bufferData(PGL.ARRAY_BUFFER, 3 * sizef, - FloatBuffer.wrap(tessGeo.polyNormals, 0, 3 * size), - PGL.STATIC_DRAW); + tessGeo.polyNormalsBuffer, PGL.STATIC_DRAW); + tessGeo.updatePolyTexcoordsBuffer(); glPolyTexcoord = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyTexcoord); pgl.bufferData(PGL.ARRAY_BUFFER, 2 * sizef, - FloatBuffer.wrap(tessGeo.polyTexcoords, 0, 2 * size), - PGL.STATIC_DRAW); + tessGeo.polyTexcoordsBuffer, PGL.STATIC_DRAW); + tessGeo.updatePolyAmbientBuffer(); glPolyAmbient = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyAmbient); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, - IntBuffer.wrap(tessGeo.polyAmbient, 0, size), - PGL.STATIC_DRAW); + tessGeo.polyAmbientBuffer, PGL.STATIC_DRAW); + tessGeo.updatePolySpecularBuffer(); glPolySpecular = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolySpecular); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, - IntBuffer.wrap(tessGeo.polySpecular, 0, size), - PGL.STATIC_DRAW); + tessGeo.polySpecularBuffer, PGL.STATIC_DRAW); + tessGeo.updatePolyEmissiveBuffer(); glPolyEmissive = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyEmissive); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, - IntBuffer.wrap(tessGeo.polyEmissive, 0, size), - PGL.STATIC_DRAW); + tessGeo.polyEmissiveBuffer, PGL.STATIC_DRAW); + tessGeo.updatePolyShininessBuffer(); glPolyShininess = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyShininess); pgl.bufferData(PGL.ARRAY_BUFFER, sizef, - FloatBuffer.wrap(tessGeo.polyShininess, 0, size), - PGL.STATIC_DRAW); + tessGeo.polyShininessBuffer, PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); + tessGeo.updatePolyIndicesBuffer(); glPolyIndex = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glPolyIndex); pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, tessGeo.polyIndexCount * PGL.SIZEOF_INDEX, - ShortBuffer.wrap(tessGeo.polyIndices, 0, - tessGeo.polyIndexCount), PGL.STATIC_DRAW); + tessGeo.polyIndicesBuffer, PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0); } @@ -3516,32 +3514,32 @@ public class PShapeOpenGL extends PShape { int sizef = size * PGL.SIZEOF_FLOAT; int sizei = size * PGL.SIZEOF_INT; + tessGeo.updateLineVerticesBuffer(); glLineVertex = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineVertex); pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, - FloatBuffer.wrap(tessGeo.lineVertices, 0, 4 * size), - PGL.STATIC_DRAW); + tessGeo.lineVerticesBuffer, PGL.STATIC_DRAW); + tessGeo.updateLineColorsBuffer(); glLineColor = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineColor); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, - IntBuffer.wrap(tessGeo.lineColors, 0, size), - PGL.STATIC_DRAW); + tessGeo.lineColorsBuffer, PGL.STATIC_DRAW); + tessGeo.updateLineAttribsBuffer(); glLineAttrib = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineAttrib); pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, - FloatBuffer.wrap(tessGeo.lineAttribs, 0, 4 * size), - PGL.STATIC_DRAW); + tessGeo.lineAttribsBuffer, PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); + tessGeo.updateLineIndicesBuffer(); glLineIndex = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glLineIndex); pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, tessGeo.lineIndexCount * PGL.SIZEOF_INDEX, - ShortBuffer.wrap(tessGeo.lineIndices, 0, - tessGeo.lineIndexCount), PGL.STATIC_DRAW); + tessGeo.lineIndicesBuffer, PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0); } @@ -3552,32 +3550,32 @@ public class PShapeOpenGL extends PShape { int sizef = size * PGL.SIZEOF_FLOAT; int sizei = size * PGL.SIZEOF_INT; + tessGeo.updatePointVerticesBuffer(); glPointVertex = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointVertex); pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, - FloatBuffer.wrap(tessGeo.pointVertices, 0, 4 * size), - PGL.STATIC_DRAW); + tessGeo.pointVerticesBuffer, PGL.STATIC_DRAW); + tessGeo.updatePointColorsBuffer(); glPointColor = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointColor); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, - IntBuffer.wrap(tessGeo.pointColors, 0, size), - PGL.STATIC_DRAW); + tessGeo.pointColorsBuffer, PGL.STATIC_DRAW); + tessGeo.updatePointAttribsBuffer(); glPointAttrib = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointAttrib); pgl.bufferData(PGL.ARRAY_BUFFER, 2 * sizef, - FloatBuffer.wrap(tessGeo.pointAttribs, 0, 2 * size), - PGL.STATIC_DRAW); + tessGeo.pointAttribsBuffer, PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); + tessGeo.updatePointIndicesBuffer(); glPointIndex = pg.createVertexBufferObject(context.id()); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glPointIndex); pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, tessGeo.pointIndexCount * PGL.SIZEOF_INDEX, - ShortBuffer.wrap(tessGeo.pointIndices, 0, - tessGeo.pointIndexCount), PGL.STATIC_DRAW); + tessGeo.pointIndicesBuffer, PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0); } @@ -3882,134 +3880,127 @@ public class PShapeOpenGL extends PShape { protected void copyPolyVertices(int offset, int size) { + tessGeo.updatePolyVerticesBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyVertex); pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, - 4 * size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.polyVertices, - 4 * offset, 4 * size)); + 4 * size * PGL.SIZEOF_FLOAT, tessGeo.polyVerticesBuffer); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPolyColors(int offset, int size) { + tessGeo.updatePolyColorsBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyColor); pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, - size * PGL.SIZEOF_INT, - IntBuffer.wrap(tessGeo.polyColors, offset, size)); + size * PGL.SIZEOF_INT, tessGeo.polyColorsBuffer); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPolyNormals(int offset, int size) { + tessGeo.updatePolyNormalsBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyNormal); pgl.bufferSubData(PGL.ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, - 3 * size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.polyNormals, - 3 * offset, 3 * size)); + 3 * size * PGL.SIZEOF_FLOAT, tessGeo.polyNormalsBuffer); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPolyTexcoords(int offset, int size) { + tessGeo.updatePolyTexcoordsBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyTexcoord); pgl.bufferSubData(PGL.ARRAY_BUFFER, 2 * offset * PGL.SIZEOF_FLOAT, - 2 * size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.polyTexcoords, - 2 * offset, 2 * size)); + 2 * size * PGL.SIZEOF_FLOAT, tessGeo.polyTexcoordsBuffer); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPolyAmbient(int offset, int size) { + tessGeo.updatePolyAmbientBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyAmbient); pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, - size * PGL.SIZEOF_INT, - IntBuffer.wrap(tessGeo.polyAmbient, offset, size)); + size * PGL.SIZEOF_INT, tessGeo.polyAmbientBuffer); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPolySpecular(int offset, int size) { + tessGeo.updatePolySpecularBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolySpecular); pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, - size * PGL.SIZEOF_INT, - IntBuffer.wrap(tessGeo.polySpecular, offset, size)); + size * PGL.SIZEOF_INT, tessGeo.polySpecularBuffer); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPolyEmissive(int offset, int size) { + tessGeo.updatePolyEmissiveBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyEmissive); pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, - size * PGL.SIZEOF_INT, - IntBuffer.wrap(tessGeo.polyEmissive, offset, size)); + size * PGL.SIZEOF_INT, tessGeo.polyEmissiveBuffer); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPolyShininess(int offset, int size) { + tessGeo.updatePolyShininessBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyShininess); pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_FLOAT, - size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.polyShininess, offset, size)); + size * PGL.SIZEOF_FLOAT, tessGeo.polyShininessBuffer); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyLineVertices(int offset, int size) { + tessGeo.updateLineVerticesBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineVertex); pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, - 4 * size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.lineVertices, - 4 * offset, 4 * size)); + 4 * size * PGL.SIZEOF_FLOAT, tessGeo.lineVerticesBuffer); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyLineColors(int offset, int size) { + tessGeo.updateLineColorsBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineColor); pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, - size * PGL.SIZEOF_INT, - IntBuffer.wrap(tessGeo.lineColors, offset, size)); + size * PGL.SIZEOF_INT, tessGeo.lineColorsBuffer); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyLineAttributes(int offset, int size) { + tessGeo.updateLineAttribsBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineAttrib); pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, - 4 * size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.lineAttribs, - 4 * offset, 4 * size)); + 4 * size * PGL.SIZEOF_FLOAT, tessGeo.lineAttribsBuffer); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPointVertices(int offset, int size) { + tessGeo.updatePointVerticesBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointVertex); pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, - 4 * size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.pointVertices, - 4 * offset, 4 * size)); + 4 * size * PGL.SIZEOF_FLOAT, tessGeo.pointVerticesBuffer); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPointColors(int offset, int size) { + tessGeo.updatePointColorsBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointColor); pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, - size * PGL.SIZEOF_INT, - IntBuffer.wrap(tessGeo.pointColors, offset, size)); + size * PGL.SIZEOF_INT,tessGeo.pointColorsBuffer); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPointAttributes(int offset, int size) { + tessGeo.updatePointAttribsBuffer(offset, size); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointAttrib); pgl.bufferSubData(PGL.ARRAY_BUFFER, 2 * offset * PGL.SIZEOF_FLOAT, - 2 * size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.pointAttribs, - 2 * offset, 2 * size)); + 2 * size * PGL.SIZEOF_FLOAT, tessGeo.pointAttribsBuffer); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); }