From 5ea73a1c41fb5bbb9df3e8a67be1c2ba7b38defb Mon Sep 17 00:00:00 2001 From: codeanticode Date: Sun, 12 Feb 2012 01:22:42 +0000 Subject: [PATCH] Ported GLSL renderering from PGraphicsAndroid3D to PGraphicsOpenGL, several fixes --- android/core/src/processing/core/PGL.java | 47 +- .../core/src/processing/core/PGraphics.java | 5 +- .../processing/core/PGraphicsAndroid3D.java | 34 +- .../core/src/processing/core/PTexture.java | 17 +- core/src/processing/core/PConstants.java | 9 + core/src/processing/core/PGraphics.java | 104 +- core/src/processing/core/PMatrix3D.java | 20 +- core/src/processing/core/PShape.java | 5 + ...aderFrag.glsl => FillShaderFragNoTex.glsl} | 6 +- ...ShaderFrag.glsl => FillShaderFragTex.glsl} | 9 +- .../processing/opengl/FillShaderVertFull.glsl | 134 + .../processing/opengl/FillShaderVertLit.glsl | 130 + .../opengl/FillShaderVertSimple.glsl | 33 + .../processing/opengl/FillShaderVertTex.glsl | 36 + .../src/processing/opengl/LineShaderVert.glsl | 130 - .../src/processing/opengl/PFontTexture.java | 3 +- .../src/processing/opengl/PFramebuffer.java | 106 +- .../opengl/src/processing/opengl/PGL.java | 1245 ++---- .../processing/opengl/PGraphicsOpenGL.java | 3694 +++++++++-------- .../opengl/src/processing/opengl/PShader.java | 565 +-- .../src/processing/opengl/PShape3D.java | 1339 +++--- .../src/processing/opengl/PTexture.java | 113 +- .../processing/opengl/PointShaderVert.glsl | 84 - 23 files changed, 3895 insertions(+), 3973 deletions(-) rename java/libraries/opengl/src/processing/opengl/{LineShaderFrag.glsl => FillShaderFragNoTex.glsl} (93%) rename java/libraries/opengl/src/processing/opengl/{PointShaderFrag.glsl => FillShaderFragTex.glsl} (82%) create mode 100644 java/libraries/opengl/src/processing/opengl/FillShaderVertFull.glsl create mode 100644 java/libraries/opengl/src/processing/opengl/FillShaderVertLit.glsl create mode 100644 java/libraries/opengl/src/processing/opengl/FillShaderVertSimple.glsl create mode 100644 java/libraries/opengl/src/processing/opengl/FillShaderVertTex.glsl delete mode 100644 java/libraries/opengl/src/processing/opengl/LineShaderVert.glsl delete mode 100644 java/libraries/opengl/src/processing/opengl/PointShaderVert.glsl diff --git a/android/core/src/processing/core/PGL.java b/android/core/src/processing/core/PGL.java index f744fcff2..b0fc1ce75 100644 --- a/android/core/src/processing/core/PGL.java +++ b/android/core/src/processing/core/PGL.java @@ -25,6 +25,7 @@ package processing.core; import java.nio.Buffer; import java.nio.ByteBuffer; +import java.nio.IntBuffer; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; @@ -380,8 +381,8 @@ public class PGL { } static public short makeIndex(int intIdx) { - // When the index value is greater than 32767 subtracting 65536 - // will make it as a short to wrap around to the negative range, which + // When the index value is greater than 32767, subtracting 65536 + // will make it (as a short) to wrap around to the negative range, which // is all we need to later pass these numbers to opengl (which will // interpret them as unsigned shorts). See discussion here: // http://stackoverflow.com/questions/4331021/java-opengl-gldrawelements-with-32767-vertices @@ -396,6 +397,30 @@ public class PGL { //gl.glDisable(target); } + public void initTexture(int target, int width, int height, int format, int type) { + // Doing in patches of 16x16 pixels to avoid creating a (potentially) + // very large transient array which in certain situations (memory- + // constrained android devices) might lead to an out-of-memory error. + int[] texels = new int[16 * 16]; + for (int y = 0; y < height + 16; y += 16) { + int h = PApplet.min(16, height - y); + for (int x = 0; x < width + 16; x += 16) { + int w = PApplet.min(16, width - x); + gl.glTexSubImage2D(target, 0, x, y, w, h, format, type, IntBuffer.wrap(texels)); + } + } + } + + public String getShaderLog(int id) { + int[] compiled = new int[1]; + GLES20.glGetShaderiv(id, GLES20.GL_COMPILE_STATUS, compiled, 0); + if (compiled[0] == 0) { + return GLES20.glGetShaderInfoLog(id); + } else { + return ""; + } + } + /////////////////////////////////////////////////////////////////////////////////// // Frame rendering @@ -660,12 +685,12 @@ public class PGL { } - public ByteBuffer glMapBuffer(int target, int acccess) { + public ByteBuffer glMapBuffer(int target, int access) { //return gl2f.glMapBuffer(GL.GL_ARRAY_BUFFER, GL2.GL_READ_WRITE); return null; } - public ByteBuffer glMapBufferRange(int target, int offset, int length, int acccess) { + public ByteBuffer glMapBufferRange(int target, int offset, int length, int access) { //return gl2x.glMapBufferRange(GL.GL_ARRAY_BUFFER, offset, length, GL2.GL_READ_WRITE); return null; } @@ -707,7 +732,7 @@ public class PGL { } public void glBindRenderbuffer(int target, int id) { - GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, id); + GLES20.glBindRenderbuffer(target, id); } public void glRenderbufferStorageMultisample(int target, int samples, int format, int width, int height) { @@ -842,16 +867,6 @@ public class PGL { GLES20.glAttachShader(prog, shader); } - public String getShaderLog(int id) { - int[] compiled = new int[1]; - GLES20.glGetShaderiv(id, GLES20.GL_COMPILE_STATUS, compiled, 0); - if (compiled[0] == 0) { - return GLES20.glGetShaderInfoLog(id); - } else { - return ""; - } - } - ///////////////////////////////////////////////////////////////////////////////// // Viewport @@ -895,7 +910,7 @@ public class PGL { } public void glReadPixels(int x, int y, int width, int height, int format, int type, Buffer buffer) { - GLES20.glReadPixels(x, y, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buffer); + GLES20.glReadPixels(x, y, width, height, format, type, buffer); } public void setDrawBuffer(int buf) { diff --git a/android/core/src/processing/core/PGraphics.java b/android/core/src/processing/core/PGraphics.java index 19ee1583d..b391b502f 100644 --- a/android/core/src/processing/core/PGraphics.java +++ b/android/core/src/processing/core/PGraphics.java @@ -907,7 +907,6 @@ public class PGraphics extends PImage implements PConstants { normalY = ny; normalZ = nz; - /* // if drawing a shape and the normal hasn't been set yet, // then we need to set the normals for each vertex so far if (shape != 0) { @@ -918,11 +917,9 @@ public class PGraphics extends PImage implements PConstants { // a separate normal for each vertex normalMode = NORMAL_MODE_VERTEX; } - } - */ + } } - /** * Set texture mode to either to use coordinates based on the IMAGE * (more intuitive for new users) or NORMALIZED (better for advanced chaps) diff --git a/android/core/src/processing/core/PGraphicsAndroid3D.java b/android/core/src/processing/core/PGraphicsAndroid3D.java index 771a2fb2a..6507d7dfb 100644 --- a/android/core/src/processing/core/PGraphicsAndroid3D.java +++ b/android/core/src/processing/core/PGraphicsAndroid3D.java @@ -780,8 +780,6 @@ public class PGraphicsAndroid3D extends PGraphics { // GLSL Program Objects ----------------------------------------------- protected int createGLSLProgramObject() { - - pg.report("before delete"); deleteFinalizedGLSLProgramObjects(); int id = pgl.glCreateProgram(); @@ -2203,7 +2201,7 @@ public class PGraphicsAndroid3D extends PGraphics { } if (flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { - //popMatrix(); + popMatrix(); } } @@ -6327,7 +6325,7 @@ public class PGraphicsAndroid3D extends PGraphics { } public void trim() { - if (vertexCount < vertices.length / 3) { + if (0 < vertexCount && vertexCount < vertices.length / 3) { trimVertices(); trimColors(); trimNormals(); @@ -6337,9 +6335,12 @@ public class PGraphicsAndroid3D extends PGraphics { trimAmbient(); trimSpecular(); trimEmissive(); - trimShininess(); + trimShininess(); + } + + if (0 < edgeCount && edgeCount < edges.length) { trimEdges(); - } + } } public void dispose() { @@ -6437,7 +6438,7 @@ public class PGraphicsAndroid3D extends PGraphics { index = 3 * vertexCount; normals[index++] = nx; normals[index++] = ny; - normals[index ] = ny; + normals[index ] = nz; index = 2 * vertexCount; texcoords[index++] = u; @@ -7065,7 +7066,7 @@ public class PGraphicsAndroid3D extends PGraphics { } public void trim() { - if (fillVertexCount < fillVertices.length / 3) { + if (0 < fillVertexCount && fillVertexCount < fillVertices.length / 3) { trimFillVertices(); trimFillColors(); trimFillNormals(); @@ -7076,31 +7077,31 @@ public class PGraphicsAndroid3D extends PGraphics { trimFillShininess(); } - if (fillIndexCount < fillIndices.length) { + if (0 < fillIndexCount && fillIndexCount < fillIndices.length) { trimFillIndices(); } - if (lineVertexCount < lineVertices.length / 3) { + if (0 < lineVertexCount && lineVertexCount < lineVertices.length / 3) { trimLineVertices(); trimLineColors(); trimLineAttributes(); } - if (lineIndexCount < lineIndices.length) { + if (0 < lineIndexCount && lineIndexCount < lineIndices.length) { trimLineIndices(); } - if (pointVertexCount < pointVertices.length / 3) { + if (0 < pointVertexCount && pointVertexCount < pointVertices.length / 3) { trimPointVertices(); trimPointColors(); trimPointAttributes(); } - if (pointIndexCount < pointIndices.length) { + if (0 < pointIndexCount && pointIndexCount < pointIndices.length) { trimPointIndices(); } } - + protected void trimFillVertices() { float temp[] = new float[3 * fillVertexCount]; PApplet.arrayCopy(fillVertices, 0, temp, 0, 3 * fillVertexCount); @@ -7174,7 +7175,7 @@ public class PGraphicsAndroid3D extends PGraphics { } protected void trimLineIndices() { - short temp[] = new short[lineVertexCount]; + short temp[] = new short[lineIndexCount]; PApplet.arrayCopy(lineIndices, 0, temp, 0, lineIndexCount); lineIndices = temp; } @@ -8571,10 +8572,11 @@ public class PGraphicsAndroid3D extends PGraphics { // Vertex data includes coordinates, colors, normals, texture coordinates, and material properties. double[] vertex = new double[] { in.vertices [3 * i + 0], in.vertices [3 * i + 1], in.vertices[3 * i + 2], - in.colors [4 * i + 0], in.colors [4 * i + 1], in.colors [4 * i + 2], in.colors[4 * i + 3], + in.colors [i], in.normals [3 * i + 0], in.normals [3 * i + 1], in.normals [3 * i + 2], in.texcoords[2 * i + 0], in.texcoords[2 * i + 1], in.ambient[i], in.specular[i], in.emissive[i], in.shininess[i] }; + gluTess.addVertex(vertex); } gluTess.endContour(); diff --git a/android/core/src/processing/core/PTexture.java b/android/core/src/processing/core/PTexture.java index ba63d3040..00c3b0060 100644 --- a/android/core/src/processing/core/PTexture.java +++ b/android/core/src/processing/core/PTexture.java @@ -28,6 +28,7 @@ import java.nio.IntBuffer; import java.util.LinkedList; import java.util.NoSuchElementException; + /** * This class wraps an OpenGL texture. * By Andres Colubri @@ -782,20 +783,8 @@ public class PTexture implements PConstants { // from w/h in the case that the GPU doesn't support NPOT textures) pgl.glTexImage2D(glTarget, 0, glFormat, glWidth, glHeight, 0, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, null); - // Once OpenGL knows the size of the new texture, we make sure it doesn't - // contain any garbage in the region of interest (0, 0, width, height): - // Doing in patches of 16x16 pixels to avoid creating a (potentially) - // very large transient array which in certain situations (memory- - // constrained android devices) might lead to an out-of-memory error. - int[] texels = new int[16 * 16]; - for (int y = 0; y < height + 16; y += 16) { - int h = PApplet.min(16, height - y); - for (int x = 0; x < width + 16; x += 16) { - int w = PApplet.min(16, width - x); - setTexels(texels, x, y, w, h); - } - } - texels = null; + // Makes sure that the texture buffer in video memory doesn't contain any garbage. + pgl.initTexture(glTarget, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE); pgl.glBindTexture(glTarget, 0); pgl.disableTexturing(glTarget); diff --git a/core/src/processing/core/PConstants.java b/core/src/processing/core/PConstants.java index 416f26aec..addb2654e 100644 --- a/core/src/processing/core/PConstants.java +++ b/core/src/processing/core/PConstants.java @@ -46,6 +46,15 @@ public interface PConstants { static public final int FLUSH_CONTINUOUSLY = 0; static public final int FLUSH_WHEN_FULL = 1; + // shaders + + static public final int FILL_SHADER_SIMPLE = 0; + static public final int FILL_SHADER_LIT = 1; + static public final int FILL_SHADER_TEX = 2; + static public final int FILL_SHADER_FULL = 3; + static public final int LINE_SHADER = 4; + static public final int POINT_SHADER = 5; + // vertex fields static public final int X = 0; // model coords xyz (formerly MX/MY/MZ) diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index 6a6dcf88c..23e246c4d 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -342,9 +342,15 @@ public class PGraphics extends PImage implements PConstants { // PMaterial[] materialStack; // int materialStackPointer; + public int ambientColor; public float ambientR, ambientG, ambientB; + + public int specularColor; public float specularR, specularG, specularB; + + public int emissiveColor; public float emissiveR, emissiveG, emissiveB; + public float shininess; @@ -730,6 +736,11 @@ public class PGraphics extends PImage implements PConstants { colorMode(RGB, 255); fill(255); stroke(0); + + ambient(255); + specular(0); + emissive(0); + shininess(1); // as of 0178, no longer relying on local versions of the variables // being set, because subclasses may need to take extra action. @@ -1008,29 +1019,21 @@ public class PGraphics extends PImage implements PConstants { public void normal(float nx, float ny, float nz) { normalX = nx; normalY = ny; - normalZ = nz; - + normalZ = nz; + // if drawing a shape and the normal hasn't been set yet, // then we need to set the normals for each vertex so far if (shape != 0) { if (normalMode == NORMAL_MODE_AUTO) { - // either they set the normals, or they don't [0149] -// for (int i = vertex_start; i < vertexCount; i++) { -// vertices[i][NX] = normalX; -// vertices[i][NY] = normalY; -// vertices[i][NZ] = normalZ; -// } // One normal per begin/end shape normalMode = NORMAL_MODE_SHAPE; - } else if (normalMode == NORMAL_MODE_SHAPE) { // a separate normal for each vertex normalMode = NORMAL_MODE_VERTEX; } - } + } } - /** * ( begin auto-generated from textureMode.xml ) * @@ -2448,6 +2451,79 @@ public class PGraphics extends PImage implements PConstants { edge(false); + + float startLat = -90; + float startLon = 0.0f; + + float latInc = 180.0f / sphereDetailU; + float lonInc = 360.0f / sphereDetailV; + + float phi1, phi2; + float theta1, theta2; + float x0, y0, z0; + float x1, y1, z1; + float x2, y2, z2; + float x3, y3, z3; + float u1, v1, u2, v2, v3; + + beginShape(TRIANGLES); + + for (int col = 0; col < sphereDetailU; col++) { + phi1 = (startLon + col * lonInc) * DEG_TO_RAD; + phi2 = (startLon + (col + 1) * lonInc) * DEG_TO_RAD; + for (int row = 0; row < sphereDetailV; row++) { + theta1 = (startLat + row * latInc) * DEG_TO_RAD; + theta2 = (startLat + (row + 1) * latInc) * DEG_TO_RAD; + + x0 = PApplet.cos(phi1) * PApplet.cos(theta1); + y0 = PApplet.sin(theta1); + z0 = PApplet.sin(phi1) * PApplet.cos(theta1); + + x1 = PApplet.cos(phi1) * PApplet.cos(theta2); + y1 = PApplet.sin(theta2); + z1 = PApplet.sin(phi1) * PApplet.cos(theta2); + + x2 = PApplet.cos(phi2) * PApplet.cos(theta2); + y2 = PApplet.sin(theta2); + z2 = PApplet.sin(phi2) * PApplet.cos(theta2); + + x3 = PApplet.cos(phi2) * PApplet.cos(theta1); + y3 = PApplet.sin(theta1); + z3 = PApplet.sin(phi2) * PApplet.cos(theta1); + + u1 = PApplet.map(phi1, TWO_PI, 0, 0, 1); + u2 = PApplet.map(phi2, TWO_PI, 0, 0, 1); + v1 = PApplet.map(theta1, -HALF_PI, HALF_PI, 0, 1); + v2 = PApplet.map(theta2, -HALF_PI, HALF_PI, 0, 1); + v3 = PApplet.map(theta1, -HALF_PI, HALF_PI, 0, 1); + + normal(x0, y0, z0); + vertex(r * x0, r * y0, r * z0, u1, v1); + + normal(x2, y2, z2); + vertex(r * x2, r * y2, r * z2, u2, v2); + + normal(x1, y1, z1); + vertex(r * x1, r * y1, r * z1, u1, v2); + + + + normal(x0, y0, z0); + vertex(r * x0, r * y0, r * z0, u1, v1); + + normal(x3, y3, z3); + vertex(r * x3, r * y3, r * z3, u2, v3); + + normal(x2, y2, z2); + vertex(r * x2, r * y2, r * z2, u2, v2); + } + } + + endShape(); + + + + /* // 1st ring from south pole beginShape(TRIANGLE_STRIP); for (int i = 0; i < sphereDetailU; i++) { @@ -2501,7 +2577,8 @@ public class PGraphics extends PImage implements PConstants { normal(0, 1, 0); vertex(0, r, 0); endShape(); - +*/ + edge(true); } @@ -5971,6 +6048,7 @@ public class PGraphics extends PImage implements PConstants { protected void ambientFromCalc() { + ambientColor = calcColor; ambientR = calcR; ambientG = calcG; ambientB = calcB; @@ -6028,6 +6106,7 @@ public class PGraphics extends PImage implements PConstants { protected void specularFromCalc() { + specularColor = calcColor; specularR = calcR; specularG = calcG; specularB = calcB; @@ -6102,6 +6181,7 @@ public class PGraphics extends PImage implements PConstants { protected void emissiveFromCalc() { + emissiveColor = calcColor; emissiveR = calcR; emissiveG = calcG; emissiveB = calcB; diff --git a/core/src/processing/core/PMatrix3D.java b/core/src/processing/core/PMatrix3D.java index f4ac5627a..2840d4ec1 100644 --- a/core/src/processing/core/PMatrix3D.java +++ b/core/src/processing/core/PMatrix3D.java @@ -644,7 +644,7 @@ public final class PMatrix3D implements PMatrix /*, PConstants*/ { // These functions should not be used, as they will be removed in the future. - protected void invTranslate(float tx, float ty, float tz) { + public void invTranslate(float tx, float ty, float tz) { preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, @@ -652,28 +652,28 @@ public final class PMatrix3D implements PMatrix /*, PConstants*/ { } - protected void invRotateX(float angle) { + public void invRotateX(float angle) { float c = cos(-angle); float s = sin(-angle); preApply(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1); } - protected void invRotateY(float angle) { + public void invRotateY(float angle) { float c = cos(-angle); float s = sin(-angle); preApply(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1); } - protected void invRotateZ(float angle) { + public void invRotateZ(float angle) { float c = cos(-angle); float s = sin(-angle); preApply(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - protected void invRotate(float angle, float v0, float v1, float v2) { + public void invRotate(float angle, float v0, float v1, float v2) { //TODO should make sure this vector is normalized float c = cos(-angle); @@ -687,15 +687,15 @@ public final class PMatrix3D implements PMatrix /*, PConstants*/ { } - protected void invScale(float x, float y, float z) { + public void invScale(float x, float y, float z) { preApply(1/x, 0, 0, 0, 0, 1/y, 0, 0, 0, 0, 1/z, 0, 0, 0, 0, 1); } - protected boolean invApply(float n00, float n01, float n02, float n03, - float n10, float n11, float n12, float n13, - float n20, float n21, float n22, float n23, - float n30, float n31, float n32, float n33) { + public boolean invApply(float n00, float n01, float n02, float n03, + float n10, float n11, float n12, float n13, + float n20, float n21, float n22, float n23, + float n30, float n31, float n32, float n33) { if (inverseCopy == null) { inverseCopy = new PMatrix3D(); } diff --git a/core/src/processing/core/PShape.java b/core/src/processing/core/PShape.java index ce7d10d43..a1a4e45e0 100644 --- a/core/src/processing/core/PShape.java +++ b/core/src/processing/core/PShape.java @@ -145,6 +145,11 @@ public class PShape implements PConstants { protected boolean tint; protected int tintColor; + protected int ambientColor; + protected int specularColor; + protected int emissiveColor; + protected float shininess; + /** Temporary toggle for whether styles should be honored. */ protected boolean style = true; diff --git a/java/libraries/opengl/src/processing/opengl/LineShaderFrag.glsl b/java/libraries/opengl/src/processing/opengl/FillShaderFragNoTex.glsl similarity index 93% rename from java/libraries/opengl/src/processing/opengl/LineShaderFrag.glsl rename to java/libraries/opengl/src/processing/opengl/FillShaderFragNoTex.glsl index cd5c944f9..29e18414e 100644 --- a/java/libraries/opengl/src/processing/opengl/LineShaderFrag.glsl +++ b/java/libraries/opengl/src/processing/opengl/FillShaderFragNoTex.glsl @@ -19,6 +19,8 @@ Boston, MA 02111-1307 USA */ +varying vec4 vertColor; + void main() { - gl_FragColor = gl_Color; - } \ No newline at end of file + gl_FragColor = vertColor; +} \ No newline at end of file diff --git a/java/libraries/opengl/src/processing/opengl/PointShaderFrag.glsl b/java/libraries/opengl/src/processing/opengl/FillShaderFragTex.glsl similarity index 82% rename from java/libraries/opengl/src/processing/opengl/PointShaderFrag.glsl rename to java/libraries/opengl/src/processing/opengl/FillShaderFragTex.glsl index d360bba1a..ec310871e 100644 --- a/java/libraries/opengl/src/processing/opengl/PointShaderFrag.glsl +++ b/java/libraries/opengl/src/processing/opengl/FillShaderFragTex.glsl @@ -19,6 +19,11 @@ Boston, MA 02111-1307 USA */ -void main() { - gl_FragColor = gl_Color; +uniform sampler2D textureSampler; + +varying vec4 vertColor; +varying vec2 vertTexcoord; + +void main() { + gl_FragColor = texture2D(textureSampler, vertTexcoord) * vertColor; } \ No newline at end of file diff --git a/java/libraries/opengl/src/processing/opengl/FillShaderVertFull.glsl b/java/libraries/opengl/src/processing/opengl/FillShaderVertFull.glsl new file mode 100644 index 000000000..4179565d8 --- /dev/null +++ b/java/libraries/opengl/src/processing/opengl/FillShaderVertFull.glsl @@ -0,0 +1,134 @@ +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2011 Andres Colubri + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +uniform mat4 modelviewMatrix; +uniform mat4 projmodelviewMatrix; +uniform mat3 normalMatrix; + +uniform int lightCount; +uniform vec4 lightPosition[8]; +uniform vec3 lightNormal[8]; +uniform vec3 lightAmbient[8]; +uniform vec3 lightDiffuse[8]; +uniform vec3 lightSpecular[8]; +uniform vec3 lightFalloffCoefficients[8]; +uniform vec2 lightSpotParameters[8]; + +attribute vec4 inVertex; +attribute vec4 inColor; +attribute vec3 inNormal; +attribute vec2 inTexcoord; + +attribute vec4 inAmbient; +attribute vec4 inSpecular; +attribute vec4 inEmissive; +attribute float inShine; + +varying vec4 vertColor; +varying vec2 vertTexcoord; + +const float zero_float = 0.0; +const float one_float = 1.0; +const vec3 zero_vec3 = vec3(0); + +float falloffFactor(vec3 lightPos, vec3 vertPos, vec3 coeff) { + vec3 lpv = lightPos - vertPos; + vec3 dist = vec3(one_float); + dist.z = dot(lpv, lpv); + dist.y = sqrt(dist.z); + return one_float / dot(dist, coeff); +} + +float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, float spotExp) { + vec3 lpv = normalize(lightPos - vertPos); + float spotCos = dot(-lightNorm, lpv); + return spotCos <= minCos ? zero_float : pow(spotCos, spotExp); +} + +float lambertFactor(vec3 lightDir, vec3 vecNormal) { + return max(zero_float, dot(lightDir, vecNormal)); +} + +float blinnPhongFactor(vec3 lightDir, vec3 lightPos, vec3 vecNormal, float shine) { + vec3 ldp = normalize(lightDir - lightPos); + return pow(max(zero_float, dot(ldp, vecNormal)), shine); +} + +void main() { + // Vertex in clip coordinates + gl_Position = projmodelviewMatrix * inVertex; + + // Vertex in eye coordinates + vec3 ecVertex = vec3(modelviewMatrix * inVertex); + + // Normal vector in eye coordinates + vec3 ecNormal = normalize(normalMatrix * inNormal); + + // Light calculations + vec3 totalAmbient = vec3(0, 0, 0); + vec3 totalDiffuse = vec3(0, 0, 0); + vec3 totalSpecular = vec3(0, 0, 0); + for (int i = 0; i < lightCount; i++) { + vec3 lightPos = lightPosition[i].xyz; + bool isDir = zero_float < lightPosition[i].w; + float spotCos = lightSpotParameters[i].x; + float spotExp = lightSpotParameters[i].y; + + vec3 lightDir; + float falloff; + float spotf; + + if (isDir) { + falloff = one_float; + lightDir = -lightNormal[i]; + } else { + falloff = falloffFactor(lightPos, ecVertex, lightFalloffCoefficients[i]); + lightDir = normalize(lightPos - ecVertex); + } + + spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i], + spotCos, spotExp) + : one_float; + + if (any(greaterThan(lightAmbient[i], zero_vec3))) { + totalAmbient += lightAmbient[i] * falloff; + } + + if (any(greaterThan(lightDiffuse[i], zero_vec3))) { + totalDiffuse += lightDiffuse[i] * falloff * spotf * + lambertFactor(lightDir, ecNormal); + } + + if (any(greaterThan(lightSpecular[i], zero_vec3))) { + totalSpecular += lightSpecular[i] * falloff * spotf * + blinnPhongFactor(lightDir, lightPos, ecNormal, inShine); + } + } + + // Calculating final color as result of all lights (plus emissive term) + vertColor = vec4(totalAmbient, 1) * inAmbient + + vec4(totalDiffuse, 1) * inColor + + vec4(totalSpecular, 1) * inSpecular + + inEmissive; + + // Passing texture coordinates to the fragment shader + vertTexcoord = inTexcoord; +} diff --git a/java/libraries/opengl/src/processing/opengl/FillShaderVertLit.glsl b/java/libraries/opengl/src/processing/opengl/FillShaderVertLit.glsl new file mode 100644 index 000000000..eda80d84d --- /dev/null +++ b/java/libraries/opengl/src/processing/opengl/FillShaderVertLit.glsl @@ -0,0 +1,130 @@ +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2011 Andres Colubri + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +uniform mat4 modelviewMatrix; +uniform mat4 projmodelviewMatrix; +uniform mat3 normalMatrix; + +uniform int lightCount; +uniform vec4 lightPosition[8]; +uniform vec3 lightNormal[8]; +uniform vec3 lightAmbient[8]; +uniform vec3 lightDiffuse[8]; +uniform vec3 lightSpecular[8]; +uniform vec3 lightFalloffCoefficients[8]; +uniform vec2 lightSpotParameters[8]; + +attribute vec4 inVertex; +attribute vec4 inColor; +attribute vec3 inNormal; + +attribute vec4 inAmbient; +attribute vec4 inSpecular; +attribute vec4 inEmissive; +attribute float inShine; + +varying vec4 vertColor; + +const float zero_float = 0.0; +const float one_float = 1.0; +const vec3 zero_vec3 = vec3(0); + +float falloffFactor(vec3 lightPos, vec3 vertPos, vec3 coeff) { + vec3 lpv = lightPos - vertPos; + vec3 dist = vec3(one_float); + dist.z = dot(lpv, lpv); + dist.y = sqrt(dist.z); + return one_float / dot(dist, coeff); +} + +float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, float spotExp) { + vec3 lpv = normalize(lightPos - vertPos); + float spotCos = dot(-lightNorm, lpv); + return spotCos <= minCos ? zero_float : pow(spotCos, spotExp); +} + +float lambertFactor(vec3 lightDir, vec3 vecNormal) { + return max(zero_float, dot(lightDir, vecNormal)); +} + +float blinnPhongFactor(vec3 lightDir, vec3 lightPos, vec3 vecNormal, float shine) { + vec3 ldp = normalize(lightDir - lightPos); + return pow(max(zero_float, dot(ldp, vecNormal)), shine); +} + +void main() { + // Vertex in clip coordinates + gl_Position = projmodelviewMatrix * inVertex; + + // Vertex in eye coordinates + vec3 ecVertex = vec3(modelviewMatrix * inVertex); + + // Normal vector in eye coordinates + vec3 ecNormal = normalize(normalMatrix * inNormal); + + // Light calculations + vec3 totalAmbient = vec3(0, 0, 0); + vec3 totalDiffuse = vec3(0, 0, 0); + vec3 totalSpecular = vec3(0, 0, 0); + for (int i = 0; i < lightCount; i++) { + vec3 lightPos = lightPosition[i].xyz; + bool isDir = zero_float < lightPosition[i].w; + float spotCos = lightSpotParameters[i].x; + float spotExp = lightSpotParameters[i].y; + + vec3 lightDir; + float falloff; + float spotf; + + if (isDir) { + falloff = one_float; + lightDir = -lightNormal[i]; + } else { + falloff = falloffFactor(lightPos, ecVertex, lightFalloffCoefficients[i]); + lightDir = normalize(lightPos - ecVertex); + } + + spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i], + spotCos, spotExp) + : one_float; + + if (any(greaterThan(lightAmbient[i], zero_vec3))) { + totalAmbient += lightAmbient[i] * falloff; + } + + if (any(greaterThan(lightDiffuse[i], zero_vec3))) { + totalDiffuse += lightDiffuse[i] * falloff * spotf * + lambertFactor(lightDir, ecNormal); + } + + if (any(greaterThan(lightSpecular[i], zero_vec3))) { + totalSpecular += lightSpecular[i] * falloff * spotf * + blinnPhongFactor(lightDir, lightPos, ecNormal, inShine); + } + + } + + // Calculating final color as result of all lights (plus emissive term) + vertColor = vec4(totalAmbient, 1) * inAmbient + + vec4(totalDiffuse, 1) * inColor + + vec4(totalSpecular, 1) * inSpecular + + inEmissive; +} \ No newline at end of file diff --git a/java/libraries/opengl/src/processing/opengl/FillShaderVertSimple.glsl b/java/libraries/opengl/src/processing/opengl/FillShaderVertSimple.glsl new file mode 100644 index 000000000..9dd5d2b07 --- /dev/null +++ b/java/libraries/opengl/src/processing/opengl/FillShaderVertSimple.glsl @@ -0,0 +1,33 @@ +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2011 Andres Colubri + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +uniform mat4 projmodelviewMatrix; + +attribute vec4 inVertex; +attribute vec4 inColor; + +varying vec4 vertColor; + +void main() { + gl_Position = projmodelviewMatrix * inVertex; + + vertColor = inColor; +} \ No newline at end of file diff --git a/java/libraries/opengl/src/processing/opengl/FillShaderVertTex.glsl b/java/libraries/opengl/src/processing/opengl/FillShaderVertTex.glsl new file mode 100644 index 000000000..9d620e481 --- /dev/null +++ b/java/libraries/opengl/src/processing/opengl/FillShaderVertTex.glsl @@ -0,0 +1,36 @@ +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2011 Andres Colubri + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +uniform mat4 projmodelviewMatrix; + +attribute vec4 inVertex; +attribute vec4 inColor; +attribute vec2 inTexcoord; + +varying vec4 vertColor; +varying vec2 vertTexcoord; + +void main() { + gl_Position = projmodelviewMatrix * inVertex; + + vertColor = inColor; + vertTexcoord = inTexcoord; +} \ No newline at end of file diff --git a/java/libraries/opengl/src/processing/opengl/LineShaderVert.glsl b/java/libraries/opengl/src/processing/opengl/LineShaderVert.glsl deleted file mode 100644 index 140f14b5b..000000000 --- a/java/libraries/opengl/src/processing/opengl/LineShaderVert.glsl +++ /dev/null @@ -1,130 +0,0 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - Based on glsl code from the dpix library: - http://gfx.cs.princeton.edu/proj/dpix/ - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -attribute vec4 attribs; -uniform vec4 viewport; - -uniform int perspective; -uniform vec4 eye; -uniform int lights; - -vec3 clipToWindow(vec4 clip, vec4 viewport) { - vec3 post_div = clip.xyz / clip.w; - vec2 xypos = (post_div.xy + vec2(1.0, 1.0)) * 0.5 * viewport.zw; - return vec3(xypos, post_div.z * 0.5 + 0.5); -} - -vec4 windowToClipVector(vec2 window, vec4 viewport, float clip_w) { - vec2 xypos = (window / viewport.zw) * 2.0; - return vec4(xypos, 0.0, 0.0) * clip_w; -} - -// From the "Directional Lights I & II" tutorials from lighthouse 3D: -// http://www.lighthouse3d.com/tutorials/glsl-tutorial/directional-lights-i/ -vec4 calculateLight(int i) { - // Per-vertex diffuse and ambient lighting. - vec3 normal, lightDir; - vec4 diffuse, ambient, specular; - float NdotL, NdotHV; - - // first transform the normal into eye space and normalize the result. - normal = normalize(gl_NormalMatrix * gl_Normal); - - // now normalize the light's direction. Note that according to the - // OpenGL specification, the light is stored in eye space. Also since - // we're talking about a directional light, the position field is actually - // direction - lightDir = normalize(vec3(gl_LightSource[i].position)); - - // compute the cos of the angle between the normal and lights direction. - // The light is directional so the direction is constant for every vertex. - // Since these two are normalized the cosine is the dot product. We also - // need to clamp the result to the [0,1] range. - NdotL = max(dot(normal, lightDir), 0.0); - - // Compute the diffuse term. Ambient and diffuse material components - // are stored in the vertex color, since processing uses GL_COLOR_MATERIAL - diffuse = gl_Color * gl_LightSource[i].diffuse; - - // Compute the ambient and globalAmbient terms - ambient = gl_Color * gl_LightSource[i].ambient; - - // compute the specular term if NdotL is larger than zero - if (NdotL > 0.0) { - // normalize the half-vector, and then compute the - // cosine (dot product) with the normal - NdotHV = max(dot(normal, gl_LightSource[i].halfVector.xyz), 0.0); - specular = gl_FrontMaterial.specular * gl_LightSource[i].specular * pow(NdotHV, gl_FrontMaterial.shininess); - } - - return NdotL * diffuse + ambient; -} - -void main() { - vec4 pos_p = gl_Vertex; - vec4 pos_q = vec4(attribs.xyz, 1); - vec4 v_p = gl_ModelViewMatrix * pos_p; - // Moving vertices slightly toward the camera - // to avoid depth-fighting with the polys. - // Discussed here: - // http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=252848 - //v_p.xyz = v_p.xyz * 0.99; - - vec4 clip_p = gl_ProjectionMatrix * v_p; - vec4 v_q = gl_ModelViewMatrix * pos_q; - //v_q.xyz = v_q.xyz * 0.99; - - vec4 clip_q = gl_ProjectionMatrix * v_q; - vec3 window_p = clipToWindow(clip_p, viewport); - vec3 window_q = clipToWindow(clip_q, viewport); - vec3 tangent = window_q - window_p; - - float segment_length = length(tangent.xy); - vec2 perp = normalize(vec2(-tangent.y, tangent.x)); - float thickness = attribs.w; - vec2 window_offset = perp * thickness; - - if (0 < perspective) { - // Perspective correction (lines will look thiner as they move away - // from the view position). - gl_Position.xy = clip_p.xy + window_offset.xy; - gl_Position.zw = clip_p.zw; - } else { - // No perspective correction. - float clip_p_w = clip_p.w; - vec4 offset_p = windowToClipVector(window_offset, viewport, clip_p_w); - gl_Position = clip_p + offset_p; - } - - vec4 color = vec4(0, 0, 0, 0); - vec4 globalAmbient = gl_Color * gl_LightModel.ambient; - if (lights == 0) { - color = gl_Color; - } - for (int i = 0; i < lights; i++) { - vec4 light = calculateLight(i); - color += light; - } - color = clamp(color, 0.0, 1.0); - gl_FrontColor = color; -} \ No newline at end of file diff --git a/java/libraries/opengl/src/processing/opengl/PFontTexture.java b/java/libraries/opengl/src/processing/opengl/PFontTexture.java index fe90373c0..423ef5f80 100644 --- a/java/libraries/opengl/src/processing/opengl/PFontTexture.java +++ b/java/libraries/opengl/src/processing/opengl/PFontTexture.java @@ -28,6 +28,7 @@ import processing.core.PApplet; import processing.core.PConstants; import processing.core.PFont; import processing.core.PImage; + import java.util.HashMap; /** @@ -51,7 +52,7 @@ class PFontTexture implements PConstants { protected PApplet parent; protected PGraphicsOpenGL pg; protected PGL pgl; - protected PGL.Context context; + protected PGL.Context context; protected PFont font; protected int maxTexWidth; diff --git a/java/libraries/opengl/src/processing/opengl/PFramebuffer.java b/java/libraries/opengl/src/processing/opengl/PFramebuffer.java index 7e32220c4..59a9ffa2a 100644 --- a/java/libraries/opengl/src/processing/opengl/PFramebuffer.java +++ b/java/libraries/opengl/src/processing/opengl/PFramebuffer.java @@ -25,6 +25,7 @@ package processing.opengl; import processing.core.PApplet; import processing.core.PConstants; + import java.nio.IntBuffer; /** @@ -174,24 +175,24 @@ public class PFramebuffer implements PConstants { public void clear() { pg.pushFramebuffer(); pg.setFramebuffer(this); - pgl.setClearColor(0, 0, 0, 0); - pgl.clearAllBuffers(); + pgl.glClearColor(0, 0, 0, 0); + pgl.glClear(PGL.GL_COLOR_BUFFER_BIT | PGL.GL_DEPTH_BUFFER_BIT | PGL.GL_STENCIL_BUFFER_BIT); pg.popFramebuffer(); } public void copy(PFramebuffer dest) { - pgl.bindReadFramebuffer(this.glFboID); - pgl.bindWriteFramebuffer(dest.glFboID); - pgl.copyFramebuffer(this.width, this.height, dest.width, dest.height); + pgl.glBindFramebuffer(PGL.GL_READ_FRAMEBUFFER, this.glFboID); + pgl.glBindFramebuffer(PGL.GL_DRAW_FRAMEBUFFER, dest.glFboID); + pgl.glBlitFramebuffer(0, 0,this.width, this.height, 0, 0, dest.width, dest.height, PGL.GL_COLOR_BUFFER_BIT, PGL.GL_NEAREST); } public void bind() { if (screenFb) { if (PGraphicsOpenGL.fboSupported) { - pgl.bindFramebuffer(0); + pgl.glBindFramebuffer(PGL.GL_FRAMEBUFFER, 0); } } else if (fboMode) { - pgl.bindFramebuffer(glFboID); + pgl.glBindFramebuffer(PGL.GL_FRAMEBUFFER, glFboID); } else { backupScreen(); @@ -202,7 +203,7 @@ public class PFramebuffer implements PConstants { } if (noDepth) { - pgl.disableDepthTest(); + pgl.glDisable(PGL.GL_DEPTH_TEST); } } } @@ -215,9 +216,9 @@ public class PFramebuffer implements PConstants { if (noDepth) { // No need to clear depth buffer because depth testing was disabled. if (pg.hintEnabled(DISABLE_DEPTH_TEST)) { - pgl.disableDepthTest(); + pgl.glDisable(PGL.GL_DEPTH_TEST); } else { - pgl.enableDepthTest(); + pgl.glEnable(PGL.GL_DEPTH_TEST); } } @@ -232,8 +233,8 @@ public class PFramebuffer implements PConstants { // after this offscreen render. // A consequence of this behavior is that all the offscreen rendering when // no FBOs are available should be done before any onscreen drawing. - pgl.setClearColor(0, 0, 0, 0); - pgl.clearDepthBuffer(); + pgl.glClearColor(0, 0, 0, 0); + pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT); } } } @@ -242,8 +243,7 @@ public class PFramebuffer implements PConstants { public void backupScreen() { if (pixelBuffer == null) createPixelBuffer(); pixelBuffer.rewind(); - pgl.readPixels(pixelBuffer, 0, 0, width, height); - + pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer); copyToTexture(pixelBuffer, backupTexture.glID, backupTexture.glTarget); } @@ -256,7 +256,7 @@ public class PFramebuffer implements PConstants { public void copyToColorBuffers() { if (pixelBuffer == null) createPixelBuffer(); pixelBuffer.rewind(); - pgl.readPixels(pixelBuffer, 0, 0, width, height); + pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer); for (int i = 0; i < numColorBuffers; i++) { copyToTexture(pixelBuffer, colorBufferTex[i].glID, colorBufferTex[i].glTarget); } @@ -265,7 +265,7 @@ public class PFramebuffer implements PConstants { public void readPixels() { if (pixelBuffer == null) createPixelBuffer(); pixelBuffer.rewind(); - pgl.readPixels(pixelBuffer, 0, 0, width, height); + pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer); } public void getPixels(int[] pixels) { @@ -319,11 +319,11 @@ public class PFramebuffer implements PConstants { // Making sure nothing is attached. for (int i = 0; i < numColorBuffers; i++) { - pgl.cleanFramebufferTexture(i); + pgl.glFramebufferTexture2D(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0 + i, PGL.GL_TEXTURE_2D, 0, 0); } for (int i = 0; i < numColorBuffers; i++) { - pgl.setFramebufferTexture(i, colorBufferTex[i].glTarget, colorBufferTex[i].glID); + pgl.glFramebufferTexture2D(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0 + i, colorBufferTex[i].glTarget, colorBufferTex[i].glID, 0); } validateFbo(); @@ -344,7 +344,7 @@ public class PFramebuffer implements PConstants { if (screenFb) { glFboID = 0; } else if (fboMode) { - //glFboID = ogl.createGLResource(PGraphicsOpenGL.GL_FRAME_BUFFER); + //glFboID = ogl.createGLResource(PGraphicsAndroid3D.GL_FRAME_BUFFER); glFboID = pg.createFrameBufferObject(); } else { glFboID = 0; @@ -400,9 +400,9 @@ public class PFramebuffer implements PConstants { pg.setFramebuffer(this); glColorBufferMultisampleID = pg.createRenderBufferObject(); - pgl.bindRenderbuffer(glColorBufferMultisampleID); - pgl.setRenderbufferNumSamples(nsamples, PGL.RGBA8, width, height); - pgl.setRenderbufferColorAttachment(glColorBufferMultisampleID); + pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glColorBufferMultisampleID); + pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, PGL.GL_RGBA8, width, height); + pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_COLOR_ATTACHMENT0, PGL.GL_RENDERBUFFER, glColorBufferMultisampleID); pg.popFramebuffer(); } @@ -421,16 +421,16 @@ public class PFramebuffer implements PConstants { pg.setFramebuffer(this); glDepthStencilBufferID = pg.createRenderBufferObject(); - pgl.bindRenderbuffer(glDepthStencilBufferID); + pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glDepthStencilBufferID); if (multisample) { - pgl.setRenderbufferNumSamples(nsamples, PGL.DEPTH_24BIT_STENCIL_8BIT, width, height); + pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, PGL.GL_DEPTH24_STENCIL8, width, height); } else { - pgl.setRenderbufferStorage(PGL.DEPTH_24BIT_STENCIL_8BIT, width, height); + pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, PGL.GL_DEPTH24_STENCIL8, width, height); } - pgl.setRenderbufferDepthAttachment(glDepthStencilBufferID); - pgl.setRenderbufferStencilAttachment(glDepthStencilBufferID); + pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_DEPTH_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthStencilBufferID); + pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_STENCIL_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthStencilBufferID); pg.popFramebuffer(); } @@ -449,24 +449,24 @@ public class PFramebuffer implements PConstants { pg.setFramebuffer(this); glDepthBufferID = pg.createRenderBufferObject(); - pgl.bindRenderbuffer(glDepthBufferID); + pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glDepthBufferID); - int glConst = PGL.DEPTH_16BIT; + int glConst = PGL.GL_DEPTH_COMPONENT16; if (depthBits == 16) { - glConst = PGL.DEPTH_16BIT; + glConst = PGL.GL_DEPTH_COMPONENT16; } else if (depthBits == 24) { - glConst = PGL.DEPTH_24BIT; + glConst = PGL.GL_DEPTH_COMPONENT24; } else if (depthBits == 32) { - glConst = PGL.DEPTH_32BIT; + glConst = PGL.GL_DEPTH_COMPONENT32; } if (multisample) { - pgl.setRenderbufferNumSamples(nsamples, glConst, width, height); + pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, glConst, width, height); } else { - pgl.setRenderbufferStorage(glConst, width, height); + pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, glConst, width, height); } - pgl.setRenderbufferDepthAttachment(glDepthBufferID); + pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_DEPTH_ATTACHMENT, PGL.GL_RENDERBUFFER, glDepthBufferID); pg.popFramebuffer(); } @@ -485,23 +485,23 @@ public class PFramebuffer implements PConstants { pg.setFramebuffer(this); glStencilBufferID = pg.createRenderBufferObject(); - pgl.bindRenderbuffer(glStencilBufferID); + pgl.glBindRenderbuffer(PGL.GL_RENDERBUFFER, glStencilBufferID); - int glConst = PGL.STENCIL_1BIT; + int glConst = PGL.GL_STENCIL_INDEX1; if (stencilBits == 1) { - glConst = PGL.STENCIL_1BIT; + glConst = PGL.GL_STENCIL_INDEX1; } else if (stencilBits == 4) { - glConst = PGL.STENCIL_4BIT; + glConst = PGL.GL_STENCIL_INDEX4; } else if (stencilBits == 8) { - glConst = PGL.STENCIL_8BIT; + glConst = PGL.GL_STENCIL_INDEX8; } if (multisample) { - pgl.setRenderbufferNumSamples(nsamples, glConst, width, height); + pgl.glRenderbufferStorageMultisample(PGL.GL_RENDERBUFFER, nsamples, glConst, width, height); } else { - pgl.setRenderbufferStorage(glConst, width, height); + pgl.glRenderbufferStorage(PGL.GL_RENDERBUFFER, glConst, width, height); } - pgl.setRenderbufferStencilAttachment(glStencilBufferID); + pgl.glFramebufferRenderbuffer(PGL.GL_FRAMEBUFFER, PGL.GL_STENCIL_ATTACHMENT, PGL.GL_RENDERBUFFER, glStencilBufferID); pg.popFramebuffer(); } @@ -520,25 +520,25 @@ public class PFramebuffer implements PConstants { // Internal copy to texture method. protected void copyToTexture(IntBuffer buffer, int glid, int gltarget) { pgl.enableTexturing(gltarget); - pgl.bindTexture(gltarget, glid); - pgl.copyTexSubImage(buffer, gltarget, 0, 0, 0, width, height); - pgl.unbindTexture(gltarget); + pgl.glBindTexture(gltarget, glid); + pgl.glTexSubImage2D(gltarget, 0, 0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, buffer); + pgl.glBindTexture(gltarget, 0); pgl.disableTexturing(gltarget); } public boolean validateFbo() { - int status = pgl.getFramebufferStatus(); - if (status == PGL.FRAMEBUFFER_COMPLETE) { + int status = pgl.glCheckFramebufferStatus(PGL.GL_FRAMEBUFFER); + if (status == PGL.GL_FRAMEBUFFER_COMPLETE) { return true; - } else if (status == PGL.FRAMEBUFFER_INCOMPLETE_ATTACHMENT) { + } else if (status == PGL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) { throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT (" + Integer.toHexString(status) + ")"); - } else if (status == PGL.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) { + } else if (status == PGL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) { throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT (" + Integer.toHexString(status) + ")"); - } else if (status == PGL.FRAMEBUFFER_INCOMPLETE_DIMENSIONS) { + } else if (status == PGL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS) { throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS (" + Integer.toHexString(status) + ")"); - } else if (status == PGL.FRAMEBUFFER_INCOMPLETE_FORMATS) { + } else if (status == PGL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS) { throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_FORMATS (" + Integer.toHexString(status) + ")"); - } else if (status == PGL.FRAMEBUFFER_UNSUPPORTED) { + } else if (status == PGL.GL_FRAMEBUFFER_UNSUPPORTED) { throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_UNSUPPORTED" + Integer.toHexString(status)); } else { throw new RuntimeException("PFramebuffer: unknown framebuffer error (" + Integer.toHexString(status) + ")"); diff --git a/java/libraries/opengl/src/processing/opengl/PGL.java b/java/libraries/opengl/src/processing/opengl/PGL.java index c029f6ed9..c355b40bc 100644 --- a/java/libraries/opengl/src/processing/opengl/PGL.java +++ b/java/libraries/opengl/src/processing/opengl/PGL.java @@ -26,7 +26,6 @@ package processing.opengl; import java.nio.Buffer; import java.nio.ByteBuffer; -import java.nio.FloatBuffer; import java.nio.IntBuffer; import javax.media.nativewindow.GraphicsConfigurationFactory; @@ -37,16 +36,10 @@ import javax.media.nativewindow.awt.AWTGraphicsDevice; import javax.media.nativewindow.awt.AWTGraphicsScreen; import javax.media.opengl.GL; import javax.media.opengl.GL2; -import javax.media.opengl.GL2ES1; -import javax.media.opengl.GL2ES2; -import javax.media.opengl.GL2GL3; -import javax.media.opengl.GL3; -import javax.media.opengl.GL4; import javax.media.opengl.GLCapabilities; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawable; import javax.media.opengl.GLDrawableFactory; -import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; import javax.media.opengl.glu.GLU; import javax.media.opengl.glu.GLUtessellator; @@ -56,41 +49,25 @@ import processing.core.PApplet; import processing.core.PConstants; /** - * How the P3D renderer handles the different OpenGL profiles? Basically, - * P3D has two pipeline modes: fixed or programmable. In the fixed mode, - * only the gl and gl2f objects are available. The gl2f object contains the - * intersection between OpenGL 2.x desktop and OpenGL 1.1 embedded, and in this - * way it ensures the functionality parity between the P3D render (PC/MAC) - * and A3D (Android) in the fixed pipeline mode. - * In the programmable mode, there further options: GL2, GL3 and GL4. - * GL2 corresponds to the basic programmable profile that results from the common - * functionality between OpenGL 3.0 desktop and OpenGL 2.0 embedded. As said just - * before, since P3D and A3D aim at feature parity as much as possible, this is - * the only programmable-pipeline GL object that the P3D renderer uses. - * The gl3 and gl4 objects will be available when the pipeline mode is PROG_GL3 or - * PROG_GL4, respectively. Although P3D doens't make any use of these objects, - * they are part of the API nonetheless for users (or libraries) requiring advanced - * functionality introduced with OpenGL 3 or OpenGL 4. - * By default, P3D tries to auto-select the pipeline mode by with the following - * priority order: PROG_GL4, PROG_GL3, PROG_GL2, FIXED. In all the programmable modes, - * the gl2p object is always available. This auto-selection can be optionally - * overridden when creating the renderer object, so that a specific mode is set. - * Note that the programmable mode uses the non-backward compatible GL objects - * (GL3, GL4, and not GL3bc, GL4bc) so no fixed mode calls are possible under this mode. + * Processing-OpenGL abstraction layer. + * */ public class PGL { /** Size of a short (in bytes). */ - static final int SIZEOF_SHORT = Short.SIZE / 8; + static final int SIZEOF_SHORT = Short.SIZE / 8; /** Size of an int (in bytes). */ static final int SIZEOF_INT = Integer.SIZE / 8; /** Size of a float (in bytes). */ static final int SIZEOF_FLOAT = Float.SIZE / 8; - - /** Maximum lights by default is 8, the minimum defined by OpenGL. */ - public static final int MAX_LIGHTS = 8; + /** Size of a vertex index. */ + static final int SIZEOF_INDEX = SIZEOF_INT; + + /** Type of a vertex index. */ + static final int INDEX_TYPE = GL.GL_UNSIGNED_INT; + /** Initial sizes for arrays of input and tessellated data. */ public static final int DEFAULT_IN_VERTICES = 64; public static final int DEFAULT_IN_EDGES = 128; @@ -99,7 +76,10 @@ public class PGL { public static final int DEFAULT_TESS_INDICES = 128; /** Initial sizes for vertex cache used in PShape3D. */ - public static final int DEFAULT_VERTEX_CACHE_SIZE = 128; + public static final int DEFAULT_VERTEX_CACHE_SIZE = 512; + + /** Maximum lights by default is 8, the minimum defined by OpenGL. */ + public static final int MAX_LIGHTS = 8; /** Maximum number of tessellated vertices, using 2^20 for Mac/PC. */ public static final int MAX_TESS_VERTICES = 524288; @@ -107,76 +87,137 @@ public class PGL { /** Maximum number of indices. 2 times the max number of * vertices to have good room for vertex reuse. */ public static final int MAX_TESS_INDICES = 2 * MAX_TESS_VERTICES; - + /** Maximum dimension of a texture used to hold font data. **/ - public static final int MAX_FONT_TEX_SIZE = 2048; + public static final int MAX_FONT_TEX_SIZE = 256; - public static final int LESS = GL.GL_LESS; - public static final int LESS_OR_EQUAL = GL.GL_LEQUAL; - public static final int COUNTER_CLOCKWISE = GL.GL_CCW; - public static final int CLOCKWISE = GL.GL_CW; - public static final int FRONT = GL.GL_FRONT; - public static final int BACK = GL.GL_BACK; + /////////////////////////////////////////////////////////////////////////////////// - public static final int BLEND_EQ_ADD = GL.GL_FUNC_ADD; - public static final int BLEND_EQ_MIN = GL2.GL_MIN; - public static final int BLEND_EQ_MAX = GL2.GL_MAX; - public static final int BLEND_EQ_REVERSE_SUBTRACT = GL.GL_FUNC_REVERSE_SUBTRACT; + // OpenGL constants - public static final int REPLACE = GL2.GL_REPLACE; - public static final int MODULATE = GL2.GL_MODULATE; + public static final int GL_LESS = GL.GL_LESS; + public static final int GL_LEQUAL = GL.GL_LEQUAL; + public static final int GL_CCW = GL.GL_CCW; + public static final int GL_CW = GL.GL_CW; + public static final int GL_FRONT = GL.GL_FRONT; + public static final int GL_BACK = GL.GL_BACK; - public static final int FLAT = GL2.GL_FLAT; - public static final int SMOOTH = GL2.GL_SMOOTH; + public static final int GL_VIEWPORT = GL.GL_VIEWPORT; - public static final int TEXTURE_2D = GL.GL_TEXTURE_2D; - public static final int RGB = GL.GL_RGB; - public static final int RGBA = GL.GL_RGBA; - public static final int ALPHA = GL.GL_ALPHA; + public static final int GL_SCISSOR_TEST = GL.GL_SCISSOR_TEST; + public static final int GL_DEPTH_TEST = GL.GL_DEPTH_TEST; - public static final int NEAREST = GL.GL_NEAREST; - public static final int LINEAR = GL.GL_LINEAR; - public static final int LINEAR_MIPMAP_LINEAR = GL.GL_LINEAR_MIPMAP_LINEAR; + public static final int GL_COLOR_BUFFER_BIT = GL.GL_COLOR_BUFFER_BIT; + public static final int GL_DEPTH_BUFFER_BIT = GL.GL_DEPTH_BUFFER_BIT; + public static final int GL_STENCIL_BUFFER_BIT = GL.GL_STENCIL_BUFFER_BIT; - public static final int CLAMP_TO_EDGE = GL.GL_CLAMP_TO_EDGE; - public static final int REPEAT = GL.GL_REPEAT; + public static final int GL_FUNC_ADD = GL.GL_FUNC_ADD; + public static final int GL_FUNC_MIN = GL2.GL_MIN; + public static final int GL_FUNC_MAX = GL2.GL_MAX; + public static final int GL_FUNC_REVERSE_SUBTRACT = GL.GL_FUNC_REVERSE_SUBTRACT; - public static final int RGBA8 = GL.GL_RGBA8; - public static final int DEPTH_24BIT_STENCIL_8BIT = GL.GL_DEPTH24_STENCIL8; + public static final int GL_TEXTURE_2D = GL.GL_TEXTURE_2D; + public static final int GL_RGB = GL.GL_RGB; + public static final int GL_RGBA = GL.GL_RGBA; + public static final int GL_ALPHA = GL.GL_ALPHA; + public static final int GL_UNSIGNED_INT = GL.GL_UNSIGNED_INT; + public static final int GL_UNSIGNED_BYTE = GL.GL_UNSIGNED_BYTE; + public static final int GL_UNSIGNED_SHORT = GL.GL_UNSIGNED_SHORT; + public static final int GL_FLOAT = GL.GL_FLOAT; - public static final int DEPTH_16BIT = GL.GL_DEPTH_COMPONENT16; - public static final int DEPTH_24BIT = GL.GL_DEPTH_COMPONENT24; - public static final int DEPTH_32BIT = GL.GL_DEPTH_COMPONENT32; + public static final int GL_NEAREST = GL.GL_NEAREST; + public static final int GL_LINEAR = GL.GL_LINEAR; + public static final int GL_LINEAR_MIPMAP_LINEAR = GL.GL_LINEAR_MIPMAP_LINEAR; - public static final int STENCIL_1BIT = GL.GL_STENCIL_INDEX1; - public static final int STENCIL_4BIT = GL.GL_STENCIL_INDEX4; - public static final int STENCIL_8BIT = GL.GL_STENCIL_INDEX8; + public static final int GL_CLAMP_TO_EDGE = GL.GL_CLAMP_TO_EDGE; + public static final int GL_REPEAT = GL.GL_REPEAT; - public static final int FRAMEBUFFER_COMPLETE = GL.GL_FRAMEBUFFER_COMPLETE; - public static final int FRAMEBUFFER_INCOMPLETE_ATTACHMENT = GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - public static final int FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; - public static final int FRAMEBUFFER_INCOMPLETE_DIMENSIONS = GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; - public static final int FRAMEBUFFER_INCOMPLETE_FORMATS = GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS; - public static final int FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = -1; - public static final int FRAMEBUFFER_INCOMPLETE_READ_BUFFER = -1; - public static final int FRAMEBUFFER_UNSUPPORTED = GL.GL_FRAMEBUFFER_UNSUPPORTED; + public static final int GL_RGBA8 = -1; + public static final int GL_DEPTH24_STENCIL8 = -1; + + public static final int GL_DEPTH_COMPONENT16 = GL.GL_DEPTH_COMPONENT16; + public static final int GL_DEPTH_COMPONENT24 = GL.GL_DEPTH_COMPONENT24; + public static final int GL_DEPTH_COMPONENT32 = GL.GL_DEPTH_COMPONENT32; + + public static final int GL_STENCIL_INDEX1 = GL.GL_STENCIL_INDEX1; + public static final int GL_STENCIL_INDEX4 = GL.GL_STENCIL_INDEX4; + public static final int GL_STENCIL_INDEX8 = GL.GL_STENCIL_INDEX8; + + public static final int GL_ARRAY_BUFFER = GL.GL_ARRAY_BUFFER; + public static final int GL_ELEMENT_ARRAY_BUFFER = GL.GL_ELEMENT_ARRAY_BUFFER; - public static final int STATIC_DRAW = GL.GL_STATIC_DRAW; - public static final int DYNAMIC_DRAW = GL.GL_DYNAMIC_DRAW; - public static final int STREAM_DRAW = GL2.GL_STREAM_DRAW; + public static final int GL_FRAMEBUFFER_COMPLETE = GL.GL_FRAMEBUFFER_COMPLETE; + public static final int GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + public static final int GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; + public static final int GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS = GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; + public static final int GL_FRAMEBUFFER_INCOMPLETE_FORMATS = GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS; + public static final int GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = GL2.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER; + public static final int GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER = GL2.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER; + public static final int GL_FRAMEBUFFER_UNSUPPORTED = GL.GL_FRAMEBUFFER_UNSUPPORTED; + + public static final int GL_STATIC_DRAW = GL.GL_STATIC_DRAW; + public static final int GL_DYNAMIC_DRAW = GL.GL_DYNAMIC_DRAW; + public static final int GL_STREAM_DRAW = GL2.GL_STREAM_DRAW; - public static final int TRIANGLE_FAN = GL.GL_TRIANGLE_FAN; - public static final int TRIANGLE_STRIP = GL.GL_TRIANGLE_STRIP; - public static final int TRIANGLES = GL.GL_TRIANGLES; + public static final int GL_READ_ONLY = GL2.GL_READ_ONLY; + public static final int GL_WRITE_ONLY = GL2.GL_WRITE_ONLY; + public static final int GL_READ_WRITE = GL2.GL_READ_WRITE; + + public static final int GL_TRIANGLE_FAN = GL.GL_TRIANGLE_FAN; + public static final int GL_TRIANGLE_STRIP = GL.GL_TRIANGLE_STRIP; + public static final int GL_TRIANGLES = GL.GL_TRIANGLES; - public static final int TESS_WINDING_NONZERO = GLU.GLU_TESS_WINDING_NONZERO; - public static final int TESS_WINDING_ODD = GLU.GLU_TESS_WINDING_ODD; + public static final int GL_VENDOR = GL.GL_VENDOR; + public static final int GL_RENDERER = GL.GL_RENDERER; + public static final int GL_VERSION = GL.GL_VERSION; + public static final int GL_EXTENSIONS = GL.GL_EXTENSIONS; + + public static final int GL_MAX_TEXTURE_SIZE = GL.GL_MAX_TEXTURE_SIZE; + public static final int GL_ALIASED_LINE_WIDTH_RANGE = GL.GL_ALIASED_LINE_WIDTH_RANGE; + public static final int GL_ALIASED_POINT_SIZE_RANGE = GL.GL_ALIASED_POINT_SIZE_RANGE; + public static final int GL_SAMPLES = GL.GL_SAMPLES; + + public static final int GLU_TESS_WINDING_NONZERO = GLU.GLU_TESS_WINDING_NONZERO; + public static final int GLU_TESS_WINDING_ODD = GLU.GLU_TESS_WINDING_ODD; + + public static final int GL_TEXTURE0 = GL.GL_TEXTURE0; + public static final int GL_TEXTURE1 = GL.GL_TEXTURE1; + public static final int GL_TEXTURE2 = GL.GL_TEXTURE2; + public static final int GL_TEXTURE3 = GL.GL_TEXTURE3; + public static final int GL_TEXTURE_MIN_FILTER = GL.GL_TEXTURE_MIN_FILTER; + public static final int GL_TEXTURE_MAG_FILTER = GL.GL_TEXTURE_MAG_FILTER; + public static final int GL_TEXTURE_WRAP_S = GL.GL_TEXTURE_WRAP_S; + public static final int GL_TEXTURE_WRAP_T = GL.GL_TEXTURE_WRAP_T; - // Rendering pipeline modes - public static final int FIXED = 0; - public static final int PROG_GL2 = 1; - public static final int PROG_GL3 = 2; - public static final int PROG_GL4 = 3; + public static final int GL_BLEND = GL.GL_BLEND; + public static final int GL_ONE = GL.GL_ONE; + public static final int GL_ZERO = GL.GL_ZERO; + public static final int GL_SRC_ALPHA = GL.GL_SRC_ALPHA; + public static final int GL_DST_ALPHA = GL.GL_DST_ALPHA; + public static final int GL_ONE_MINUS_SRC_ALPHA = GL.GL_ONE_MINUS_SRC_ALPHA; + public static final int GL_ONE_MINUS_DST_COLOR = GL.GL_ONE_MINUS_DST_COLOR; + public static final int GL_ONE_MINUS_SRC_COLOR = GL.GL_ONE_MINUS_SRC_COLOR; + public static final int GL_DST_COLOR = GL.GL_DST_COLOR; + public static final int GL_SRC_COLOR = GL.GL_SRC_COLOR; + + public static final int GL_FRAMEBUFFER = GL.GL_FRAMEBUFFER; + public static final int GL_COLOR_ATTACHMENT0 = GL.GL_COLOR_ATTACHMENT0; + public static final int GL_RENDERBUFFER = GL.GL_RENDERBUFFER; + public static final int GL_DEPTH_ATTACHMENT = GL.GL_DEPTH_ATTACHMENT; + public static final int GL_STENCIL_ATTACHMENT = GL.GL_STENCIL_ATTACHMENT; + public static final int GL_READ_FRAMEBUFFER = GL2.GL_READ_FRAMEBUFFER; + public static final int GL_DRAW_FRAMEBUFFER = GL2.GL_DRAW_FRAMEBUFFER ; + public static final int GL_COLOR_ATTACHMENT1 = GL2.GL_COLOR_ATTACHMENT1; + public static final int GL_COLOR_ATTACHMENT2 = GL2.GL_COLOR_ATTACHMENT2; + public static final int GL_COLOR_ATTACHMENT3 = GL2.GL_COLOR_ATTACHMENT3; + + public static final int GL_VERTEX_SHADER = GL2.GL_VERTEX_SHADER; + public static final int GL_FRAGMENT_SHADER = GL2.GL_FRAGMENT_SHADER; + + public static final int GL_MULTISAMPLE = GL.GL_MULTISAMPLE; + public static final int GL_POINT_SMOOTH = GL2.GL_POINT_SMOOTH; + public static final int GL_LINE_SMOOTH = GL.GL_LINE_SMOOTH; + public static final int GL_POLYGON_SMOOTH = GL2.GL_POLYGON_SMOOTH; /** Pipeline mode: FIXED, PROG_GL2, PROG_GL3 or PROG_GL4 */ public int pipeline; @@ -184,24 +225,10 @@ public class PGL { /** Basic GL functionality, common to all profiles */ public GL gl; + /** GL2 functionality (shaders, etc) */ public GL2 gl2; - - /** Advanced GL functionality (usually, things available as extensions in JOGL1). - * This profile is the intersection between GL 2.0 and GL 3.0 */ - public GL2GL3 gl2x; - - /** Fixed GL pipeline, with the functionality common to the GL2 desktop and GLES 1.1 profiles */ - public GL2ES1 gl2f; - - /** Basic programmable GL pipeline: intersection of desktop GL3, GL2 and embedded ES2 profile */ - public GL2ES2 gl2p; - - /** GL3 programmable pipeline, not backwards compatible with GL2 fixed */ - public GL3 gl3p; - - /** GL4 programmable pipeline, not backwards compatible with GL2 fixed */ - public GL4 gl4p; - + + /** GLU interface **/ public GLU glu; /** Selected GL profile */ @@ -255,42 +282,13 @@ public class PGL { } public void updatePrimary() { - gl = context.getGL(); - - if (pipeline == PROG_GL4) { - gl4p = gl.getGL4(); - gl3p = gl4p; - gl2p = gl4p; - gl2f = null; - } else if (pipeline == PROG_GL3) { - gl4p = null; - gl3p = gl.getGL3(); - gl2p = gl3p; - gl2f = null; - } else if (pipeline == PROG_GL2) { - gl4p = null; - gl3p = null; - gl2p = gl.getGL2ES2(); - gl2f = null; - } else if (pipeline == FIXED) { - gl4p = null; - gl3p = null; - gl2p = null; - gl2f = gl.getGL2ES1(); - gl2 = gl.getGL2(); - } - - try { - gl2x = gl.getGL2GL3(); - } catch (GLException e) {} + gl = context.getGL(); + gl2 = gl.getGL2(); } public void updateOffscreen(PGL primary) { - gl = primary.gl; - gl4p = primary.gl4p; - gl3p = primary.gl3p; - gl2p = primary.gl2p; - gl2f = primary.gl2f; + gl = primary.gl; + gl2 = primary.gl2; } @@ -314,12 +312,13 @@ public class PGL { profile = null; - profile = GLProfile.getDefault(); + //profile = GLProfile.getDefault(); + profile = GLProfile.getMaxFixedFunc(); //profile = GLProfile.get(GLProfile.GL2ES1); //profile = GLProfile.get(GLProfile.GL4bc); //profile = GLProfile.getMaxProgrammable(); - pipeline = PGL.FIXED; + //pipeline = PGL.FIXED; /* // Profile auto-selection disabled for the time being. @@ -428,6 +427,40 @@ public class PGL { return intIdx; } + public void enableTexturing(int target) { + gl.glEnable(target); + } + + public void disableTexturing(int target) { + gl.glDisable(target); + } + + 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)); + } + + public String getShaderLog(int id) { + IntBuffer val = IntBuffer.allocate(1); + gl2.glGetObjectParameterivARB(id, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, val); + + int length = val.get(); + + if (length <= 1) { + return ""; + } + + // Some error occurred... + ByteBuffer infoLog = ByteBuffer.allocate(length); + val.flip(); + + gl2.glGetInfoLogARB(id, length, val, infoLog); + + byte[] infoBytes = new byte[length]; + infoLog.get(infoBytes); + return new String(infoBytes); + } + /////////////////////////////////////////////////////////////////////////////////// // Frame rendering @@ -471,134 +504,46 @@ public class PGL { /////////////////////////////////////////////////////////////////////////////////// // Caps query - - public String getVendorString() { - return gl.glGetString(GL.GL_VENDOR); + + public String glGetString(int name) { + return gl.glGetString(name); + } + + public void glGetIntegerv(int name, int[] values, int offset) { + gl.glGetIntegerv(name, values, offset); } - public String getRendererString() { - return gl.glGetString(GL.GL_RENDERER); - } + /////////////////////////////////////////////////////////////////////////////////// - public String getVersionString() { - return gl.glGetString(GL.GL_VERSION); - } + // Enable/disable caps - public String getExtensionsString() { - return gl.glGetString(GL.GL_EXTENSIONS); - } - - public boolean isNpotTexSupported() { - // Better way to check for extensions and related functions (taken from jMonkeyEngine): - // renderbufferStorageMultisample = gl.isExtensionAvailable("GL_EXT_framebuffer_multisample") && - // gl.isFunctionAvailable("glRenderbufferStorageMultisample"); - // For more details on GL properties initialization in jMonkey using JOGL2, take a look at: - // http://code.google.com/p/jmonkeyengine/source/browse/branches/jme3/src/jogl2/com/jme3/renderer/jogl/JoglRenderer.java - - String ext = gl.glGetString(GL.GL_EXTENSIONS); - if (-1 < ext.indexOf("texture_non_power_of_two")) { - return true; + public void glEnable(int cap) { + if (-1 < cap) { + gl.glEnable(cap); } - return false; - } - - public boolean hasMipmapGeneration() { - String ext = gl.glGetString(GL.GL_EXTENSIONS); - if (-1 < ext.indexOf("generate_mipmap")) { - return true; - } - return false; - } - - public boolean isMatrixGetSupported() { - String ext = gl.glGetString(GL.GL_EXTENSIONS); - if (-1 < ext.indexOf("matrix_get")) { - return true; - } - return false; - } - - public boolean isTexenvCrossbarSupported() { - String ext = gl.glGetString(GL.GL_EXTENSIONS); - if (-1 < ext.indexOf("texture_env_crossbar")) { - return true; - } - return false; - } - - public boolean isVboSupported() { - String ext = gl.glGetString(GL.GL_EXTENSIONS); - if (-1 < ext.indexOf("vertex_buffer_object")) { - return true; - } - return false; - } - - public boolean isFboSupported() { - String ext = gl.glGetString(GL.GL_EXTENSIONS); - if (-1 < ext.indexOf("framebuffer_object")) { - return true; - } - return false; - } - - public boolean isFboMultisampleSupported() { - String ext = gl.glGetString(GL.GL_EXTENSIONS); - if (-1 < ext.indexOf("framebuffer_multisample")) { - return true; - } - return false; - } - - public boolean isBlendEqSupported() { - return true; } - public int getMaxTexureSize() { - int temp[] = new int[1]; - gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, temp, 0); - return temp[0]; - } - - public int getMaxAliasedLineWidth() { - int temp[] = new int[2]; - gl.glGetIntegerv(GL.GL_ALIASED_LINE_WIDTH_RANGE, temp, 0); - return temp[1]; - } - - public int getMaxAliasedPointSize() { - int temp[] = new int[2]; - gl.glGetIntegerv(GL.GL_ALIASED_POINT_SIZE_RANGE, temp, 0); - return temp[1]; - } - - public int getMaxTextureUnits() { - // The maximum number of texture units only makes sense in the - // fixed pipeline. - int temp[] = new int[1]; - gl.glGetIntegerv(GL2.GL_MAX_TEXTURE_UNITS, temp, 0); - return temp[0]; - } - - public void getNumSamples(int[] num) { - gl.glGetIntegerv(GL.GL_SAMPLES, num, 0); + public void glDisable(int cap) { + if (-1 < cap) { + gl.glDisable(cap); + } } /////////////////////////////////////////////////////////////////////////////////// // Render control - public void flush() { + public void glFlush() { gl.glFlush(); } - public void finish() { + public void glFinish() { gl.glFinish(); } ///////////////////////////////////////////////////////////////////////////////// - // Errors + // Error handling public int getError() { return gl.glGetError(); @@ -607,833 +552,341 @@ public class PGL { public String getErrorString(int err) { return glu.gluErrorString(err); } - + ///////////////////////////////////////////////////////////////////////////////// // Rendering options - - public void enableDepthTest() { - gl.glEnable(GL.GL_DEPTH_TEST); - } - public void disableDepthTest() { - gl.glDisable(GL.GL_DEPTH_TEST); - } - - public void enableDepthMask() { - gl.glDepthMask(true); - } - - public void disableDepthMask() { - gl.glDepthMask(false); - } - - public void setDepthFunc(int func) { - gl.glDepthFunc(func); - } - - public void setShadeModel(int model) { - gl2f.glShadeModel(model); - } - public void setFrontFace(int mode) { gl.glFrontFace(mode); } - - public void enableMultisample() { - gl2f.glEnable(GL2.GL_MULTISAMPLE); + + public void glDepthMask(boolean flag) { + gl.glDepthMask(flag); } - - public void disableMultisample() { - gl2f.glDisable(GL2.GL_MULTISAMPLE); - } - - public void enablePointSmooth() { - gl2f.glEnable(GL2.GL_POINT_SMOOTH); - } - - public void disablePointSmooth() { - gl2f.glDisable(GL2.GL_POINT_SMOOTH); - } - - public void enableLineSmooth() { - gl2f.glEnable(GL2.GL_LINE_SMOOTH); - } - - public void disableLineSmooth() { - gl2f.glDisable(GL2.GL_LINE_SMOOTH); + + public void setDepthFunc(int func) { + gl.glDepthFunc(func); } - - public void enablePolygonSmooth() { - gl2f.glEnable(GL2.GL_POLYGON_SMOOTH); - } - - public void disablePolygonSmooth() { - gl2f.glDisable(GL2.GL_POLYGON_SMOOTH); - } - - public void enableColorMaterial() { - gl2f.glEnable(GL2.GL_COLOR_MATERIAL); - } - public void disableColorMaterial() { - gl2f.glDisable(GL2.GL_COLOR_MATERIAL); - } - - public void enableNormalization() { - gl2f.glEnable(GL2.GL_NORMALIZE); - } - - public void disableNormalization() { - gl2f.glDisable(GL2.GL_NORMALIZE); - } - - public void enableRescaleNormals() { - gl2f.glEnable(GL2.GL_RESCALE_NORMAL); - } - - public void disableRescaleNormals() { - gl2f.glDisable(GL2.GL_RESCALE_NORMAL); - } - - - ///////////////////////////////////////////////////////////////////////////////// - - // Vertex arrays - - public void genVertexArray(int[] id) { - gl2x.glGenVertexArrays(1, id, 0); - } - - public void delVertexArray(int[] id) { - gl2x.glDeleteVertexArrays(1, id, 0); - } ///////////////////////////////////////////////////////////////////////////////// // Textures - public void genTexture(int[] id) { - gl.glGenTextures(1, id, 0); + public void glGenTextures(int n, int[] ids, int offset) { + gl.glGenTextures(n, ids, offset); } - public void delTexture(int[] id) { - gl.glDeleteTextures(1, id, 0); + public void glDeleteTextures(int n, int[] ids, int offset) { + gl.glDeleteTextures(n, ids, offset); } - public void enableTexturing(int target) { - gl2f.glEnable(target); + public void glActiveTexture(int unit) { + gl.glActiveTexture(unit); } - public void setActiveTexUnit(int tu) { - gl2f.glActiveTexture(GL.GL_TEXTURE0 + tu); + public void glBindTexture(int target, int id) { + gl.glBindTexture(target, id); + } + + public void glTexImage2D(int target, int level, int internalFormat, int width, int height, int border, int format, int type, Buffer data) { + gl.glTexImage2D(target, level, internalFormat, width, height, border, format, type, data); } - public void bindTexture(int target, int id) { - gl2f.glBindTexture(target, id); + public void glTexSubImage2D(int target, int level, int xOffset, int yOffset, int width, int height, int format, int type, Buffer data) { + gl.glTexSubImage2D(target, level, xOffset, yOffset, width, height, format, type, data); } - public void unbindTexture(int target) { - gl2f.glBindTexture(target, 0); - } - - public void disableTexturing(int target) { - gl2f.glDisable(target); - } - - public void initTex(int target, int format, int w, int h) { - gl.glTexImage2D(target, 0, format, w, h, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, null); + public void glTexParameterf(int target, int param, int value) { + gl.glTexParameterf(target, param, value); } - public void copyTexImage(Buffer image, int target, int format, int level, int w, int h) { - gl.glTexImage2D(target, level, format, w, h, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, image); - } - - public void copyTexSubImage(Buffer image, int target, int level, int x, int y, int w, int h) { - gl.glTexSubImage2D(target, level, x, y, w, h, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, image); - } - - public void copyTexSubImage(int[] pixels, int target, int level, int x, int y, int w, int h) { - gl.glTexSubImage2D(target, level, x, y, w, h, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, IntBuffer.wrap(pixels)); - } - - public void setTexEnvironmentMode(int mode) { - gl2f.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, mode); - } - - public void enableTexMipmapGen(int target) { - gl.glTexParameteri(target, GL2.GL_GENERATE_MIPMAP, GL.GL_TRUE); - } - - public void disableTexMipmapGen(int target) { - gl.glTexParameteri(target, GL2.GL_GENERATE_MIPMAP, GL.GL_FALSE); - } - - public void setTexMinFilter(int target, int filter) { - gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, filter); - } - - public void setTexMagFilter(int target, int filter) { - gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, filter); - } - - public void setTexWrapS(int target, int wrap) { - gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, wrap); - } - - public void setTexWrapT(int target, int wrap) { - gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, wrap); + public void glGenerateMipmap(int target) { + gl.glGenerateMipmap(target); } ///////////////////////////////////////////////////////////////////////////////// // Vertex Buffers - public void genBuffer(int[] id) { - gl.glGenBuffers(1, id, 0); + public void glGenBuffers(int n, int[] ids, int offset) { + gl.glGenBuffers(n, ids, offset); } - public void delBuffer(int[] id) { - gl.glDeleteBuffers(1, id, 0); + public void glDeleteBuffers(int n, int[] ids, int offset) { + gl.glDeleteBuffers(n, ids, offset); + } + + public void glBindBuffer(int target, int id) { + gl.glBindBuffer(target, id); + } + + public void glBufferData(int target, int size, Buffer data, int usage) { + gl.glBufferData(target, size, data, usage); } - public void bindVertexBuffer(int id) { - gl2f.glBindBuffer(GL.GL_ARRAY_BUFFER, id); + public void glBufferSubData(int target, int offset, int size, Buffer data) { + gl.glBufferSubData(target, offset, size, data); } - public void initVertexBuffer(int size, int mode) { - gl2f.glBufferData(GL.GL_ARRAY_BUFFER, size * SIZEOF_FLOAT, null, mode); + + public void glDrawElements(int mode, int count, int type, int offset) { + gl.glDrawElements(mode, count, type, offset); + } + + + public void glEnableVertexAttribArray(int loc) { + gl2.glEnableVertexAttribArray(loc); } - public void copyVertexBufferData(float[] data, int size, int mode) { - gl2f.glBufferData(GL.GL_ARRAY_BUFFER, size * SIZEOF_FLOAT, FloatBuffer.wrap(data, 0, size), mode); - } - - public void copyVertexBufferData(float[] data, int offset, int size, int mode) { - gl2f.glBufferData(GL.GL_ARRAY_BUFFER, size * SIZEOF_FLOAT, FloatBuffer.wrap(data, offset, size), mode); + public void glDisableVertexAttribArray(int loc) { + gl2.glDisableVertexAttribArray(loc); } - public void copyVertexBufferSubData(float[] data, int offset, int size, int mode) { - gl2f.glBufferSubData(GL.GL_ARRAY_BUFFER, offset * SIZEOF_FLOAT, size * SIZEOF_FLOAT, FloatBuffer.wrap(data, 0, size)); + public void glVertexAttribPointer(int loc, int size, int type, boolean normalized, int stride, int offset) { + gl2.glVertexAttribPointer(loc, size, type, normalized, stride, offset); } - public void setVertexFormat(int size, long offset) { - gl2f.glVertexPointer(size, GL.GL_FLOAT, 0, size * offset * SIZEOF_FLOAT); + + public ByteBuffer glMapBuffer(int target, int access) { + return gl2.glMapBuffer(target, access); } - public void setColorFormat(int size, long offset) { - gl2f.glColorPointer(size, GL.GL_FLOAT, 0, size * offset * SIZEOF_FLOAT); + public ByteBuffer glMapBufferRange(int target, int offset, int length, int access) { + return gl2.glMapBufferRange(target, offset, length, access); } - public void setNormalFormat(int size, long offset) { - gl2f.glNormalPointer(GL.GL_FLOAT, 0, size * offset * SIZEOF_FLOAT); + public void glUnmapBuffer(int target) { + gl2.glUnmapBuffer(target); } - public void setTexCoordFormat(int size, long offset) { - gl2f.glTexCoordPointer(size, GL.GL_FLOAT, 0, size * offset * SIZEOF_FLOAT); - } - - public void unbindVertexBuffer() { - gl2f.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); - } - - public void bindIndexBuffer(int id) { - gl2f.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, id); - } - - public void initIndexBuffer(int size, int mode) { - gl2f.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, size * SIZEOF_INT, null, mode); - } - - public void copyIndexBufferData(int[] data, int size, int mode) { - gl2f.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, size * SIZEOF_INT, IntBuffer.wrap(data, 0, size), mode); - } - - public void copyIndexBufferData(int[] data, int offset, int size, int mode) { - gl2f.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, size * SIZEOF_INT, IntBuffer.wrap(data, offset, size), mode); - } - - public void copyIndexBufferSubData(int[] data, int offset, int size, int mode) { - gl2f.glBufferSubData(GL.GL_ELEMENT_ARRAY_BUFFER, offset * SIZEOF_INT, size * SIZEOF_INT, IntBuffer.wrap(data, 0, size)); - } - - public void renderIndexBuffer(int size) { - gl2f.glDrawElements(GL.GL_TRIANGLES, size, GL.GL_UNSIGNED_INT, 0); - } - - public void renderIndexBuffer(int offset, int size) { - gl2f.glDrawElements(GL.GL_TRIANGLES, size, GL.GL_UNSIGNED_INT, offset * SIZEOF_INT); - } - - public void unbindIndexBuffer() { - gl2f.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0); - } - - public void enableVertexArrays() { - gl2f.glEnableClientState(GL2.GL_VERTEX_ARRAY); - } - - public void enableColorArrays() { - gl2f.glEnableClientState(GL2.GL_COLOR_ARRAY); - } - - public void enableNormalArrays() { - gl2f.glEnableClientState(GL2.GL_NORMAL_ARRAY); - } - - public void enableTexCoordArrays() { - gl2f.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY); - } - - public void disableVertexArrays() { - gl2f.glDisableClientState(GL2.GL_VERTEX_ARRAY); - } - - public void disableColorArrays() { - gl2f.glDisableClientState(GL2.GL_COLOR_ARRAY); - } - - public void disableNormalArrays() { - gl2f.glDisableClientState(GL2.GL_NORMAL_ARRAY); - } - - public void disableTexCoordArrays() { - gl2f.glDisableClientState(GL2.GL_TEXTURE_COORD_ARRAY); - } - - public void enableAttribsArray(int loc) { - gl2x.glEnableVertexAttribArray(loc); - } - - public void setAttribsFormat(int loc, int size, int stride, long offset) { - gl2x.glVertexAttribPointer(loc, size, GL.GL_FLOAT, false, stride, offset); - } - - public void disableAttribsArray(int loc) { - gl2x.glDisableVertexAttribArray(loc); - } - - public ByteBuffer mapVertexBuffer() { - return gl2f.glMapBuffer(GL.GL_ARRAY_BUFFER, GL2.GL_READ_WRITE); - } - - public ByteBuffer mapVertexBufferRange(int offset, int length) { - return gl2x.glMapBufferRange(GL.GL_ARRAY_BUFFER, offset, length, GL2.GL_READ_WRITE); - } - - public void unmapVertexBuffer() { - gl2f.glUnmapBuffer(GL.GL_ARRAY_BUFFER); - } - - public ByteBuffer mapIndexBuffer() { - return gl2f.glMapBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, GL2.GL_READ_WRITE); - } - - public ByteBuffer mapIndexBufferRange(int offset, int length) { - return gl2x.glMapBufferRange(GL.GL_ELEMENT_ARRAY_BUFFER, offset, length, GL2.GL_READ_WRITE); - } - - public void unmapIndexBuffer() { - gl2f.glUnmapBuffer(GL.GL_ELEMENT_ARRAY_BUFFER); - } - ///////////////////////////////////////////////////////////////////////////////// // Framebuffers, renderbuffers - public void genFramebuffer(int[] id) { - gl.glGenFramebuffers(1, id, 0); + public void glGenFramebuffers(int n, int[] ids, int offset) { + gl.glGenFramebuffers(n, ids, offset); } - public void delFramebuffer(int[] id) { - gl.glDeleteFramebuffers(1, id, 0); + public void glDeleteFramebuffers(int n, int[] ids, int offset) { + gl.glDeleteFramebuffers(n, ids, offset); } - public void genRenderbuffer(int[] id) { - gl.glGenRenderbuffers(1, id, 0); + public void glGenRenderbuffers(int n, int[] ids, int offset) { + gl.glGenRenderbuffers(n, ids, offset); } - public void delRenderbuffer(int[] id) { - gl.glGenRenderbuffers(1, id, 0); + public void glDeleteRenderbuffers(int n, int[] ids, int offset) { + gl.glDeleteRenderbuffers(n, ids, offset); } - public void bindFramebuffer(int id) { - gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, id); + public void glBindFramebuffer(int target, int id) { + gl.glBindFramebuffer(target, id); } - public void bindReadFramebuffer(int id) { - gl.glBindFramebuffer(GL2.GL_READ_FRAMEBUFFER, id); + public void glBlitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) { + gl2.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + } + + public void glFramebufferTexture2D(int target, int attachment, int texTarget, int texId, int level) { + gl.glFramebufferTexture2D(target, attachment, texTarget, texId, level); } - public void bindWriteFramebuffer(int id) { - gl.glBindFramebuffer(GL2.GL_DRAW_FRAMEBUFFER, id); - } - - public void copyFramebuffer(int srcW, int srcH, int destW, int destH) { - gl2x.glBlitFramebuffer(0, 0, srcW, srcH, 0, 0, destW, destH, GL.GL_COLOR_BUFFER_BIT, GL.GL_NEAREST); - } - - public void cleanFramebufferTexture(int fb) { - gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER, GL.GL_COLOR_ATTACHMENT0 + fb, GL.GL_TEXTURE_2D, 0, 0); - } - - public void setFramebufferTexture(int fb, int target, int id) { - gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER, GL.GL_COLOR_ATTACHMENT0 + fb, target, id, 0); - } - - public void bindRenderbuffer(int id) { - gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, id); + public void glBindRenderbuffer(int target, int id) { + gl.glBindRenderbuffer(target, id); } - public void setRenderbufferNumSamples(int samples, int format, int w, int h) { - gl2x.glRenderbufferStorageMultisample(GL.GL_RENDERBUFFER, samples, format, w, h); + public void glRenderbufferStorageMultisample(int target, int samples, int format, int width, int height) { + gl2.glRenderbufferStorageMultisample(target, samples, format, width, height); } - public void setRenderbufferStorage(int format, int w, int h) { - gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, format, w, h); + public void glRenderbufferStorage(int target, int format, int width, int height) { + gl.glRenderbufferStorage(target, format, width, height); } - public void setRenderbufferColorAttachment(int id) { - gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_COLOR_ATTACHMENT0, GL.GL_RENDERBUFFER, id); + public void glFramebufferRenderbuffer(int target, int attachment, int rendbufTarget, int rendbufId) { + gl.glFramebufferRenderbuffer(target, attachment, rendbufTarget, rendbufId); } - - public void setRenderbufferDepthAttachment(int id) { - gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, id); - } - - public void setRenderbufferStencilAttachment(int id) { - gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, id); - } - - public int getFramebufferStatus() { - return gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER); + + public int glCheckFramebufferStatus(int target) { + return gl.glCheckFramebufferStatus(target); } ///////////////////////////////////////////////////////////////////////////////// // Shaders - public void genProgram(int[] id) { - id[0] = gl2x.glCreateProgram(); + public int glCreateProgram() { + return gl2.glCreateProgram(); } - public void delProgram(int[] id) { - gl2x.glDeleteProgram(id[0]); + public void glDeleteProgram(int id) { + gl2.glDeleteProgram(id); } - public void genVertexShader(int[] id) { - id[0] = gl2x.glCreateShader(GL2.GL_VERTEX_SHADER); + public int glCreateShader(int type) { + return gl2.glCreateShader(type); } - public void delVertexShader(int[] id) { - gl2x.glDeleteShader(id[0]); + public void glDeleteShader(int id) { + gl2.glDeleteShader(id); } - - public void genFragmentShader(int[] id) { - id[0] = gl2x.glCreateShader(GL2.GL_FRAGMENT_SHADER); - } - - public void delFragmentShader(int[] id) { - gl2x.glDeleteShader(id[0]); - } - - public void linkProgram(int prog) { + + public void glLinkProgram(int prog) { gl2.glLinkProgram(prog); } - public void validateProgram(int prog) { + public void glValidateProgram(int prog) { gl2.glValidateProgram(prog); } - public void startProgram(int prog) { - gl2.glUseProgramObjectARB(prog); + public void glUseProgram(int prog) { + gl2.glUseProgram(prog); } - public void stopProgram() { - gl2.glUseProgramObjectARB(0); - } - - public int getAttribLocation(int prog, String name) { - return gl2.glGetAttribLocation(prog, name); + public int glGetAttribLocation(int prog, String name) { + return gl2.glGetAttribLocation(prog, name); } - public int getUniformLocation(int prog, String name) { - return gl2.glGetUniformLocation(prog, name); + public int glGetUniformLocation(int prog, String name) { + return gl2.glGetUniformLocation(prog, name); } - public void setIntUniform(int loc, int value) { + public void glUniform1i(int loc, int value) { gl2.glUniform1i(loc, value); } - public void setFloatUniform(int loc, float value) { + public void glUniform1f(int loc, float value) { gl2.glUniform1f(loc, value); } - public void setFloatUniform(int loc, float value0, float value1) { + public void glUniform2f(int loc, float value0, float value1) { gl2.glUniform2f(loc, value0, value1); } - public void setFloatUniform(int loc, float value0, float value1, float value2) { + public void glUniform3f(int loc, float value0, float value1, float value2) { gl2.glUniform3f(loc, value0, value1, value2); } - public void setFloatUniform(int loc, float value0, float value1, float value2, float value3) { + public void glUniform4f(int loc, float value0, float value1, float value2, float value3) { gl2.glUniform4f(loc, value0, value1, value2, value3); } - public void setMatUniform(int loc, float m00, float m01, - float m10, float m11) { - float[] mat = new float[4]; - mat[0] = m00; mat[4] = m01; - mat[1] = m10; mat[5] = m11; - gl2.glUniformMatrix2fv(loc, 1, false, mat, 0); + public void glUniform1fv(int loc, int count, float[] v, int offset) { + gl2.glUniform1fv(loc, count, v, offset); + } + + public void glUniform2fv(int loc, int count, float[] v, int offset) { + gl2.glUniform2fv(loc, count, v, offset); + } + + public void glUniform3fv(int loc, int count, float[] v, int offset) { + gl2.glUniform3fv(loc, count, v, offset); + } + + public void glUniform4fv(int loc, int count, float[] v, int offset) { + gl2.glUniform4fv(loc, count, v, offset); + } + + public void glUniformMatrix2fv(int loc, int count, boolean transpose, float[] mat, int offset) { + gl2.glUniformMatrix2fv(loc, count, transpose, mat, offset); } - public void setMatUniform(int loc, float m00, float m01, float m02, - float m10, float m11, float m12, - float m20, float m21, float m22) { - float[] mat = new float[9]; - mat[0] = m00; mat[4] = m01; mat[ 8] = m02; - mat[1] = m10; mat[5] = m11; mat[ 9] = m12; - mat[2] = m20; mat[6] = m21; mat[10] = m22; - gl2.glUniformMatrix3fv(loc, 1, false, mat, 0); + public void glUniformMatrix3fv(int loc, int count, boolean transpose, float[] mat, int offset) { + gl2.glUniformMatrix3fv(loc, count, transpose, mat, offset); } - public void setMatUniform(int loc, float m00, float m01, float m02, float m03, - float m10, float m11, float m12, float m13, - float m20, float m21, float m22, float m23, - float m30, float m31, float m32, float m33) { - float[] mat = new float[16]; - mat[0] = m00; mat[4] = m01; mat[ 8] = m02; mat[12] = m03; - mat[1] = m10; mat[5] = m11; mat[ 9] = m12; mat[13] = m13; - mat[2] = m20; mat[6] = m21; mat[10] = m22; mat[14] = m23; - mat[3] = m30; mat[7] = m31; mat[11] = m32; mat[15] = m33; - gl2.glUniformMatrix4fv(loc, 1, false, mat, 0); + public void glUniformMatrix4fv(int loc, int count, boolean transpose, float[] mat, int offset) { + gl2.glUniformMatrix4fv(loc, count, transpose, mat, offset); } - public void setFloatAttrib(int loc, float value) { + public void glVertexAttrib1f(int loc, float value) { gl2.glVertexAttrib1f(loc, value); } - public void setFloatAttrib(int loc, float value0, float value1) { + public void glVertexAttrib2f(int loc, float value0, float value1) { gl2.glVertexAttrib2f(loc, value0, value1); } - public void setFloatAttrib(int loc, float value0, float value1, float value2) { + public void glVertexAttrib3f(int loc, float value0, float value1, float value2) { gl2.glVertexAttrib3f(loc, value0, value1, value2); } - public void setFloatAttrib(int loc, float value0, float value1, float value2, float value3) { + public void glVertexAttrib4f(int loc, float value0, float value1, float value2, float value3) { gl2.glVertexAttrib4f(loc, value0, value1, value2, value3); } - public void setShaderSource(int id, String source) { - gl2.glShaderSource(id, 1, new String[] { source }, (int[]) null, 0); + public void glShaderSource(int id, String source) { + gl2.glShaderSource(id, 1, new String[] { source }, (int[]) null, 0); } - public void compileShader(int id) { + public void glCompileShader(int id) { gl2.glCompileShader(id); } - public void attachShader(int prog, int shader) { - gl2.glAttachObjectARB(prog, shader); - } - - public String getShaderLog(int id) { - IntBuffer val = IntBuffer.allocate(1); - gl2.glGetObjectParameterivARB(id, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, val); - - int length = val.get(); - - if (length <= 1) { - return ""; - } - - // Some error occurred... - ByteBuffer infoLog = ByteBuffer.allocate(length); - val.flip(); - - gl2.glGetInfoLogARB(id, length, val, infoLog); - - byte[] infoBytes = new byte[length]; - infoLog.get(infoBytes); - return new String(infoBytes); + public void glAttachShader(int prog, int shader) { + gl2.glAttachShader(prog, shader); } ///////////////////////////////////////////////////////////////////////////////// - // Viewport - - public void getViweport(int[] viewport) { - gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0); - } + // Viewport - public void setViewport(int[] viewport) { - gl.glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + + public void glViewport(int x, int y, int width, int height) { + gl.glViewport(x, y, width, height); } ///////////////////////////////////////////////////////////////////////////////// // Clipping (scissor test) - public void enableClipping() { - gl.glEnable(GL.GL_SCISSOR_TEST); - } - - public void disableClipping() { - gl.glDisable(GL.GL_SCISSOR_TEST); - } - public void setClipRect(int x, int y, int w, int h) { + public void glScissor(int x, int y, int w, int h) { gl.glScissor(x, y, w, h); - } - - - ///////////////////////////////////////////////////////////////////////////////// - - // Matrices, transformations - - public void setProjectionMode() { - gl2f.glMatrixMode(GL2.GL_PROJECTION); - } - - public void setModelviewMode() { - gl2f.glMatrixMode(GL2.GL_MODELVIEW); - } - - public void pushMatrix() { - gl2f.glPushMatrix(); - } - - public void popMatrix() { - gl2f.glPopMatrix(); - } - - public void loadIdentity() { - gl2f.glLoadIdentity(); - } - - public void multMatrix(float[] mat) { - gl2f.glMultMatrixf(mat, 0); - } - - public void loadMatrix(float[] mat) { - gl2f.glLoadMatrixf(mat, 0); } - public void translate(float tx, float ty, float tz) { - gl2f.glTranslatef(tx, ty, tz); - } - - public void rotate(float angle, float vx, float vy, float vz) { - gl2f.glRotatef(PApplet.degrees(angle), vx, vy, vz); - } - - public void scale(float sx, float sy, float sz) { - gl2f.glScalef(sx, sy, sz); - } - - public void setOrthographicProjection(float left, float right, float bottom, float top, float near, float far) { - gl2f.glOrthof(left, right, bottom, top, near, far); - } - - ///////////////////////////////////////////////////////////////////////////////// - - // Materials - - public void setMaterialAmbient(float[] color) { - gl2f.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_AMBIENT, color, 0); - } - - public void setMaterialSpecular(float[] color) { - gl2f.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, color, 0); - } - - public void setMaterialEmission(float[] color) { - gl2f.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_EMISSION, color, 0); - } - - public void setMaterialShininess(float shine) { - gl2f.glMaterialf(GL.GL_FRONT_AND_BACK, GL2.GL_SHININESS, shine); - } - - public void setColor(float r, float g, float b, float a) { - gl2f.glColor4f(r, g, b, a); - } - - ///////////////////////////////////////////////////////////////////////////////// - - // Lights - - public void enableLighting() { - gl2f.glEnable(GL2.GL_LIGHTING); - } - - public void disableLighting() { - gl2f.glDisable(GL2.GL_LIGHTING); - } - - public void setTwoSidedLightModel() { - gl2f.glLightModelf(GL2.GL_LIGHT_MODEL_TWO_SIDE, 0); - } - - public void setDefaultAmbientLight(float[] color) { - gl2f.glLightModelfv(GL2.GL_LIGHT_MODEL_AMBIENT, color, 0); - } - - public void enableLight(int light) { - gl2f.glEnable(GL2.GL_LIGHT0 + light); - } - - public void disableLight(int light) { - gl2f.glDisable(GL2.GL_LIGHT0 + light); - } - - public void setLightPosition(int light, float[] pos) { - gl2f.glLightfv(GL2.GL_LIGHT0 + light, GL2.GL_POSITION, pos, 0); - } - - public void setAmbientLight(int light, float[] color) { - gl2f.glLightfv(GL2.GL_LIGHT0 + light, GL2.GL_AMBIENT, color, 0); - } - - public void setDiffuseLight(int light, float[] color) { - gl2f.glLightfv(GL2.GL_LIGHT0 + light, GL2.GL_DIFFUSE, color, 0); - } - - public void setSpecularLight(int light, float[] color) { - gl2f.glLightfv(GL2.GL_LIGHT0 + light, GL2.GL_SPECULAR, color, 0); - } - - public void setLightDirection(int light, float[] dir) { - // The w component of lightNormal[num] is zero, so the light is considered as - // a directional source because the position effectively becomes a direction - // in homogeneous coordinates: - // http://glprogramming.com/red/appendixf.html - dir[3] = 0; - gl2f.glLightfv(GL2.GL_LIGHT0 + light, GL2.GL_POSITION, dir, 0); - } - - public void setSpotLightCutoff(int light, float cutoff) { - gl2f.glLightf(GL2.GL_LIGHT0 + light, GL2.GL_SPOT_CUTOFF, cutoff); - } - - public void setSpotLightExponent(int light, float exp) { - gl2f.glLightf(GL2.GL_LIGHT0 + light, GL2.GL_SPOT_EXPONENT, exp); - } - - public void setSpotLightDirection(int light, float[] dir) { - gl2f.glLightfv(GL2.GL_LIGHT0 + light, GL2.GL_POSITION, dir, 0); - } - - public void setLightConstantAttenuation(int light, float attn) { - gl2f.glLightf(GL2.GL_LIGHT0 + light, GL2.GL_CONSTANT_ATTENUATION, attn); - } - - public void setLightLinearAttenuation(int light, float attn) { - gl2f.glLightf(GL2.GL_LIGHT0 + light, GL2.GL_LINEAR_ATTENUATION, attn); - } - - public void setLightQuadraticAttenuation(int light, float attn) { - gl2f.glLightf(GL2.GL_LIGHT0 + light, GL2.GL_QUADRATIC_ATTENUATION, attn); - } - - public void setNormal(float nx, float ny, float nz) { - gl2f.glNormal3f(nx, ny, nz); - } ///////////////////////////////////////////////////////////////////////////////// // Blending - - public void enableBlend() { - gl.glEnable(GL.GL_BLEND); - } - - public void setBlendEquation(int eq) { + + + public void glBlendEquation(int eq) { gl.glBlendEquation(eq); } - public void setReplaceBlend() { - gl.glBlendFunc(GL.GL_ONE, GL.GL_ZERO); + + public void glBlendFunc(int srcFactor, int dstFactor) { + gl.glBlendFunc(srcFactor, dstFactor); } - - public void setDefaultBlend() { - gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); - } - - public void setAdditiveBlend() { - gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE); - } - - public void setSubstractiveBlend() { - gl.glBlendFunc(GL.GL_ONE_MINUS_DST_COLOR, GL.GL_ZERO); - } - - public void setLightestBlend() { - gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_DST_ALPHA); - } - - public void setDarkestBlend() { - gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_DST_ALPHA); - } - - public void setDifferenceBlend() { - gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE); - } - - public void setExclussionBlend() { - gl.glBlendFunc(GL.GL_ONE_MINUS_DST_COLOR, GL.GL_ONE_MINUS_SRC_COLOR); - } - - public void setMultiplyBlend() { - gl.glBlendFunc(GL.GL_DST_COLOR, GL.GL_SRC_COLOR); - } - - public void setScreenBlend() { - gl.glBlendFunc(GL.GL_ONE_MINUS_DST_COLOR, GL.GL_ONE); - } + ///////////////////////////////////////////////////////////////////////////////// // Pixels public void setReadBuffer(int buf) { - gl2x.glReadBuffer(buf); + gl2.glReadBuffer(buf); } - public void readPixels(Buffer buffer, int x, int y, int w, int h) { - gl.glReadPixels(x, y, w, h, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, buffer); + public void glReadPixels(int x, int y, int width, int height, int format, int type, Buffer buffer) { + gl.glReadPixels(x, y, width, height, format, type, buffer); } public void setDrawBuffer(int buf) { - gl2x.glDrawBuffer(GL.GL_COLOR_ATTACHMENT0 + buf); + gl2.glDrawBuffer(buf); } - public void setClearColor(float r, float g, float b, float a) { + public void glClearColor(float r, float g, float b, float a) { gl.glClearColor(r, g, b, a); } - public void clearDepthBuffer() { - gl.glClear(GL.GL_DEPTH_BUFFER_BIT); - } + public void glClear(int mask) { + gl.glClear(mask); + } - public void clearStencilBuffer() { - gl.glClear(GL.GL_STENCIL_BUFFER_BIT); - } - - public void clearDepthAndStencilBuffers() { - gl.glClear(GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT); - } - - public void clearColorBuffer() { - gl.glClear(GL.GL_COLOR_BUFFER_BIT); - } - - public void clearAllBuffers() { - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT); - } - ///////////////////////////////////////////////////////////////////////////////// // Context interface diff --git a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java index 2c858505d..df69f03a1 100644 --- a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java +++ b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java @@ -34,6 +34,7 @@ import processing.core.PMatrix3D; import processing.core.PShape; import processing.core.PVector; +import java.net.URL; import java.nio.*; import java.util.EmptyStackException; import java.util.HashMap; @@ -41,9 +42,6 @@ import java.util.HashSet; import java.util.Set; import java.util.Stack; -// Needed to return the GL object in beginGL() -import javax.media.opengl.GL; - /** * OpenGL renderer. * @@ -62,21 +60,23 @@ public class PGraphicsOpenGL extends PGraphics { public int glFillVertexBufferID; public int glFillColorBufferID; public int glFillNormalBufferID; - public int glFillTexCoordBufferID; - public int glFillIndexBufferID; + public int glFillTexCoordBufferID; + public int glFillAmbientBufferID; + public int glFillSpecularBufferID; + public int glFillEmissiveBufferID; + public int glFillShininessBufferID; + public int glFillIndexBufferID; protected boolean fillVBOsCreated = false; public int glLineVertexBufferID; public int glLineColorBufferID; - public int glLineNormalBufferID; - public int glLineAttribBufferID; + public int glLineDirWidthBufferID; public int glLineIndexBufferID; protected boolean lineVBOsCreated = false; public int glPointVertexBufferID; public int glPointColorBufferID; - public int glPointNormalBufferID; - public int glPointAttribBufferID; + public int glPointSizeBufferID; public int glPointIndexBufferID; protected boolean pointVBOsCreated = false; @@ -89,18 +89,15 @@ public class PGraphicsOpenGL extends PGraphics { /** Extensions used by Processing */ static public boolean npotTexSupported; static public boolean mipmapGeneration; - static public boolean matrixGetSupported; static public boolean vboSupported; static public boolean fboSupported; - static public boolean blendEqSupported; - static public boolean texenvCrossbarSupported; static public boolean fboMultisampleSupported; + static public boolean blendEqSupported; /** Some hardware limits */ static public int maxTextureSize; static public float maxPointSize; static public float maxLineWidth; - static public int maxTextureUnits; /** OpenGL information strings */ static public String OPENGL_VENDOR; @@ -112,7 +109,6 @@ public class PGraphicsOpenGL extends PGraphics { // GL objects: - static protected HashMap glVertexArrays = new HashMap(); static protected HashMap glTextureObjects = new HashMap(); static protected HashMap glVertexBuffers = new HashMap(); static protected HashMap glFrameBuffers = new HashMap(); @@ -121,6 +117,45 @@ public class PGraphicsOpenGL extends PGraphics { static protected HashMap glslVertexShaders = new HashMap(); static protected HashMap glslFragmentShaders = new HashMap(); + // ........................................................ + + // Shaders + + protected static URL defFillShaderVertSimpleURL = PGraphicsOpenGL.class.getResource("FillShaderVertSimple.glsl"); + protected static URL defFillShaderVertTexURL = PGraphicsOpenGL.class.getResource("FillShaderVertTex.glsl"); + protected static URL defFillShaderVertLitURL = PGraphicsOpenGL.class.getResource("FillShaderVertLit.glsl"); + protected static URL defFillShaderVertFullURL = PGraphicsOpenGL.class.getResource("FillShaderVertFull.glsl"); + protected static URL defFillShaderFragNoTexURL = PGraphicsOpenGL.class.getResource("FillShaderFragNoTex.glsl"); + protected static URL defFillShaderFragTexURL = PGraphicsOpenGL.class.getResource("FillShaderFragTex.glsl"); + protected static URL defLineShaderVertURL = PGraphicsOpenGL.class.getResource("LineShaderVert.glsl"); + protected static URL defLineShaderFragURL = PGraphicsOpenGL.class.getResource("LineShaderFrag.glsl"); + protected static URL defPointShaderVertURL = PGraphicsOpenGL.class.getResource("PointShaderVert.glsl"); + protected static URL defPointShaderFragURL = PGraphicsOpenGL.class.getResource("PointShaderFrag.glsl"); + + protected static FillShaderSimple defFillShaderSimple; + protected static FillShaderTex defFillShaderTex; + protected static FillShaderLit defFillShaderLit; + protected static FillShaderFull defFillShaderFull; + protected static LineShader defLineShader; + protected static PointShader defPointShader; + + protected FillShaderSimple fillShaderSimple; + protected FillShaderTex fillShaderTex; + protected FillShaderLit fillShaderLit; + protected FillShaderFull fillShaderFull; + protected LineShader lineShader; + protected PointShader pointShader; + + // ........................................................ + + // Tessellator, geometry + + protected InGeometry inGeo; + protected TessGeometry tessGeo; + protected int firstTexIndex; + protected TexCache texCache; + protected Tessellator tessellator; + // ........................................................ // Camera: @@ -146,15 +181,20 @@ public class PGraphicsOpenGL extends PGraphics { // ........................................................ - // Projection, camera, and modelview matrices. + // All the matrices required for camera and geometry transformations. public PMatrix3D projection; public PMatrix3D camera; public PMatrix3D cameraInv; public PMatrix3D modelview; + public PMatrix3D modelviewInv; + public PMatrix3D projmodelview; - // Temporary array to copy the PMatrices to OpenGL. - protected float[] glMatrix; - + // To pass to shaders + protected float[] glProjection; + protected float[] glModelview; + protected float[] glProjmodelview; + protected float[] glNormal; + protected boolean matricesAllocated = false; /** @@ -165,6 +205,9 @@ public class PGraphicsOpenGL extends PGraphics { /** Modelview matrix stack **/ protected Stack modelviewStack; + + /** Inverse modelview matrix stack **/ + protected Stack modelviewInvStack; /** Projection matrix stack **/ protected Stack projectionStack; @@ -180,36 +223,33 @@ public class PGraphicsOpenGL extends PGraphics { public int[] lightType; /** Light positions */ - public float[][] lightPosition; + public float[] lightPosition; /** Light direction (normalized vector) */ - public float[][] lightNormal; - - /** Light falloff */ - public float[] lightFalloffConstant; - public float[] lightFalloffLinear; - public float[] lightFalloffQuadratic; - - /** Light spot angle */ - public float[] lightSpotAngle; - - /** Cosine of light spot angle */ - public float[] lightSpotAngleCos; - - /** Light spot concentration */ - public float[] lightSpotConcentration; + public float[] lightNormal; /** - * Diffuse colors for lights. For an ambient light, this will hold the ambient - * color. Internally these are stored as numbers between 0 and 1. + * Ambient colors for lights. */ - public float[][] lightDiffuse; - + public float[] lightAmbient; + + /** + * Diffuse colors for lights. + */ + public float[] lightDiffuse; + /** * Specular colors for lights. Internally these are stored as numbers between * 0 and 1. */ - public float[][] lightSpecular; + public float[] lightSpecular; + + /** Light falloff */ + public float[] lightFalloffCoefficients; + + /** Light spot parameters: Cosine of light spot angle + * and concentration */ + public float[] lightSpotParameters; /** Current specular color for lighting */ public float[] currentLightSpecular; @@ -219,14 +259,6 @@ public class PGraphicsOpenGL extends PGraphics { public float currentLightFalloffLinear; public float currentLightFalloffQuadratic; - /** - * Used to store empty values to be passed when a light has no - * ambient, diffuse or specular component - */ - public float[] zeroLight = { 0.0f, 0.0f, 0.0f, 1.0f }; - /** Default ambient light for the entire scene **/ - public float[] baseLight = { 0.05f, 0.05f, 0.05f, 1.0f }; - protected boolean lightsAllocated = false; // ........................................................ @@ -235,13 +267,18 @@ public class PGraphicsOpenGL extends PGraphics { protected int blendMode; + // ........................................................ + + // Clipping + + protected boolean clip = false; + // ........................................................ // Text: /** Font texture of currently selected font. */ PFontTexture textTex; - // ....................................................... @@ -263,6 +300,25 @@ public class PGraphicsOpenGL extends PGraphics { public int offscreenDepthBits = 24; public int offscreenStencilBits = 8; + // ........................................................ + + // Utility variables: + + /** True if we are inside a beginDraw()/endDraw() block. */ + protected boolean drawing = false; + + /** Used to detect the occurrence of a frame resize event. */ + protected boolean resized = false; + + /** Stores previous viewport dimensions. */ + protected int[] savedViewport = {0, 0, 0, 0}; + protected int[] viewport = {0, 0, 0, 0}; + + protected boolean openContour = false; + protected boolean breakShape = false; + protected boolean defaultEdges = false; + protected PImage textureImage0; + // ........................................................ // Drawing surface: @@ -281,37 +337,7 @@ public class PGraphicsOpenGL extends PGraphics { /** 1-pixel get/set texture. */ protected PTexture getsetTexture; - - // ........................................................ - // Utility variables: - - /** True if we are inside a beginDraw()/endDraw() block. */ - protected boolean drawing = false; - - /** Used to make backups of current drawing state. */ - protected DrawingState drawState; - - /** Used to hold color values to be sent to OpenGL. */ - protected float[] colorFloats; - - /** Used to detect the occurrence of a frame resize event. */ - protected boolean resized = false; - - /** Stores previous viewport dimensions. */ - protected int[] savedViewport = {0, 0, 0, 0}; - protected int[] viewport = {0, 0, 0, 0}; - - // ........................................................ - - // Utility constants: - - /** - * Set to true if the host system is big endian (PowerPC, MIPS, SPARC), false - * if little endian (x86 Intel for Mac or PC). - */ - static public boolean BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; - // ........................................................ // Bezier and Catmull-Rom curves @@ -339,44 +365,15 @@ public class PGraphicsOpenGL extends PGraphics { new PMatrix3D(-1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, - 1, 0, 0, 0); - - // ........................................................ - - // The new stuff (shaders, tessellator, etc) - - protected InGeometry inGeo; - protected TessGeometry tessGeo; - protected int firstTexIndex; - protected TexCache texCache; - - protected float[] currentVertex = { 0, 0, 0 }; - protected float[] currentColor = { 0, 0, 0, 0 }; - protected float[] currentNormal = { 0, 0, 1 }; - protected float[] currentTexcoord = { 0, 0 }; - protected float[] currentStroke = { 0, 0, 0, 1, 1 }; - - protected boolean openContour = false; - protected boolean breakShape = false; - - public static int flushMode = FLUSH_WHEN_FULL; - - public static final int MIN_ARRAYCOPY_SIZE = 2; + 1, 0, 0, 0); - protected Tessellator tessellator; + // ........................................................ - static protected PShader lineShader; - static protected PShader pointShader; - static protected int lineAttribsLoc; - static protected int pointAttribsLoc; + // Constants - protected PImage textureImage0; - - protected boolean clip = false; - - protected boolean defaultEdges = false; - - protected int vboMode = PGL.STATIC_DRAW; + protected static int flushMode = FLUSH_WHEN_FULL; + protected static final int MIN_ARRAYCOPY_SIZE = 2; + protected int vboMode = PGL.GL_STATIC_DRAW; static public float FLOAT_EPS = Float.MIN_VALUE; // Calculation of the Machine Epsilon for float precision. From: @@ -391,6 +388,12 @@ public class PGraphicsOpenGL extends PGraphics { FLOAT_EPS = eps; } + /** + * Set to true if the host system is big endian (PowerPC, MIPS, SPARC), false + * if little endian (x86 Intel for Mac or PC). + */ + static public boolean BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; + ////////////////////////////////////////////////////////////// @@ -408,19 +411,21 @@ public class PGraphicsOpenGL extends PGraphics { glFillVertexBufferID = 0; glFillColorBufferID = 0; glFillNormalBufferID = 0; - glFillTexCoordBufferID = 0; + glFillTexCoordBufferID = 0; + glFillAmbientBufferID = 0; + glFillSpecularBufferID = 0; + glFillEmissiveBufferID = 0; + glFillShininessBufferID = 0; glFillIndexBufferID = 0; glLineVertexBufferID = 0; glLineColorBufferID = 0; - glLineNormalBufferID = 0; - glLineAttribBufferID = 0; + glLineDirWidthBufferID = 0; glLineIndexBufferID = 0; glPointVertexBufferID = 0; glPointColorBufferID = 0; - glPointNormalBufferID = 0; - glPointAttribBufferID = 0; + glPointSizeBufferID = 0; glPointIndexBufferID = 0; } @@ -473,27 +478,25 @@ public class PGraphicsOpenGL extends PGraphics { super.allocate(); if (!matricesAllocated) { - glMatrix = new float[16]; projection = new PMatrix3D(); camera = new PMatrix3D(); cameraInv = new PMatrix3D(); - modelview = new PMatrix3D(); + modelview = new PMatrix3D(); + modelviewInv = new PMatrix3D(); + projmodelview = new PMatrix3D(); matricesAllocated = true; } if (!lightsAllocated) { lightType = new int[PGL.MAX_LIGHTS]; - lightPosition = new float[PGL.MAX_LIGHTS][4]; - lightNormal = new float[PGL.MAX_LIGHTS][4]; - lightDiffuse = new float[PGL.MAX_LIGHTS][4]; - lightSpecular = new float[PGL.MAX_LIGHTS][4]; - lightFalloffConstant = new float[PGL.MAX_LIGHTS]; - lightFalloffLinear = new float[PGL.MAX_LIGHTS]; - lightFalloffQuadratic = new float[PGL.MAX_LIGHTS]; - lightSpotAngle = new float[PGL.MAX_LIGHTS]; - lightSpotAngleCos = new float[PGL.MAX_LIGHTS]; - lightSpotConcentration = new float[PGL.MAX_LIGHTS]; - currentLightSpecular = new float[4]; + lightPosition = new float[4 * PGL.MAX_LIGHTS]; + lightNormal = new float[3 * PGL.MAX_LIGHTS]; + lightAmbient = new float[3 * PGL.MAX_LIGHTS]; + lightDiffuse = new float[3 * PGL.MAX_LIGHTS]; + lightSpecular = new float[3 * PGL.MAX_LIGHTS]; + lightFalloffCoefficients = new float[3 * PGL.MAX_LIGHTS]; + lightSpotParameters = new float[2 * PGL.MAX_LIGHTS]; + currentLightSpecular = new float[3]; lightsAllocated = true; } @@ -544,73 +547,13 @@ public class PGraphicsOpenGL extends PGraphics { // RESOURCE HANDLING - // Vertex Array Objects -------------------------------------- - - protected int createVertexArrayObject() { - deleteFinalizedVertexArrayObjects(); - - int[] temp = new int[1]; - pgl.genVertexArray(temp); - int id = temp[0]; - - if (glVertexArrays.containsKey(id)) { - showWarning("Adding same VAO twice"); - } else { - glVertexArrays.put(id, false); - } - - return id; - } - - protected void deleteVertexArrayObject(int id) { - if (glVertexArrays.containsKey(id)) { - int[] temp = { id }; - pgl.delVertexArray(temp); - glVertexArrays.remove(id); - } - } - - protected void deleteAllVertexArrayObjects() { - for (Integer id : glVertexArrays.keySet()) { - int[] temp = { id.intValue() }; - pgl.delVertexArray(temp); - } - glVertexArrays.clear(); - } - - // This is synchronized because it is called from the GC thread. - synchronized protected void finalizeVertexArrayObject(int id) { - if (glVertexArrays.containsKey(id)) { - glVertexArrays.put(id, true); - } else { - showWarning("Trying to finalize non-existing VAO"); - } - } - - protected void deleteFinalizedVertexArrayObjects() { - Set finalized = new HashSet(); - - for (Integer id : glVertexArrays.keySet()) { - if (glVertexArrays.get(id)) { - finalized.add(id); - int[] temp = { id.intValue() }; - pgl.delVertexArray(temp); - } - } - - for (Integer id : finalized) { - glVertexArrays.remove(id); - } - } - - // Texture Objects ------------------------------------------- protected int createTextureObject() { deleteFinalizedTextureObjects(); int[] temp = new int[1]; - pgl.genTexture(temp); + pgl.glGenTextures(1, temp, 0); int id = temp[0]; if (glTextureObjects.containsKey(id)) { @@ -625,7 +568,7 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteTextureObject(int id) { if (glTextureObjects.containsKey(id)) { int[] temp = { id }; - pgl.delTexture(temp); + pgl.glDeleteTextures(1, temp, 0); glTextureObjects.remove(id); } } @@ -633,7 +576,7 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteAllTextureObjects() { for (Integer id : glTextureObjects.keySet()) { int[] temp = { id.intValue() }; - pgl.delTexture(temp); + pgl.glDeleteTextures(1, temp, 0); } glTextureObjects.clear(); } @@ -654,7 +597,7 @@ public class PGraphicsOpenGL extends PGraphics { if (glTextureObjects.get(id)) { finalized.add(id); int[] temp = { id.intValue() }; - pgl.delTexture(temp); + pgl.glDeleteTextures(1, temp, 0); } } @@ -669,7 +612,7 @@ public class PGraphicsOpenGL extends PGraphics { deleteFinalizedVertexBufferObjects(); int[] temp = new int[1]; - pgl.genBuffer(temp); + pgl.glGenBuffers(1, temp, 0); int id = temp[0]; if (glVertexBuffers.containsKey(id)) { @@ -684,7 +627,7 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteVertexBufferObject(int id) { if (glVertexBuffers.containsKey(id)) { int[] temp = { id }; - pgl.delBuffer(temp); + pgl.glDeleteBuffers(1, temp, 0); glVertexBuffers.remove(id); } } @@ -692,7 +635,7 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteAllVertexBufferObjects() { for (Integer id : glVertexBuffers.keySet()) { int[] temp = { id.intValue() }; - pgl.delBuffer(temp); + pgl.glDeleteBuffers(1, temp, 0); } glVertexBuffers.clear(); } @@ -713,7 +656,7 @@ public class PGraphicsOpenGL extends PGraphics { if (glVertexBuffers.get(id)) { finalized.add(id); int[] temp = { id.intValue() }; - pgl.delBuffer(temp); + pgl.glDeleteBuffers(1, temp, 0); } } @@ -728,7 +671,7 @@ public class PGraphicsOpenGL extends PGraphics { deleteFinalizedFrameBufferObjects(); int[] temp = new int[1]; - pgl.genFramebuffer(temp); + pgl.glGenFramebuffers(1, temp, 0); int id = temp[0]; if (glFrameBuffers.containsKey(id)) { @@ -743,7 +686,7 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteFrameBufferObject(int id) { if (glFrameBuffers.containsKey(id)) { int[] temp = { id }; - pgl.delFramebuffer(temp); + pgl.glDeleteFramebuffers(1, temp, 0); glFrameBuffers.remove(id); } } @@ -751,7 +694,7 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteAllFrameBufferObjects() { for (Integer id : glFrameBuffers.keySet()) { int[] temp = { id.intValue() }; - pgl.delFramebuffer(temp); + pgl.glDeleteFramebuffers(1, temp, 0); } glFrameBuffers.clear(); } @@ -772,7 +715,7 @@ public class PGraphicsOpenGL extends PGraphics { if (glFrameBuffers.get(id)) { finalized.add(id); int[] temp = { id.intValue() }; - pgl.delFramebuffer(temp); + pgl.glDeleteFramebuffers(1, temp, 0); } } @@ -787,7 +730,7 @@ public class PGraphicsOpenGL extends PGraphics { deleteFinalizedRenderBufferObjects(); int[] temp = new int[1]; - pgl.genRenderbuffer(temp); + pgl.glDeleteRenderbuffers(1, temp, 0); int id = temp[0]; if (glRenderBuffers.containsKey(id)) { @@ -802,7 +745,7 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteRenderBufferObject(int id) { if (glRenderBuffers.containsKey(id)) { int[] temp = { id }; - pgl.delRenderbuffer(temp); + pgl.glGenRenderbuffers(1, temp, 0); glRenderBuffers.remove(id); } } @@ -810,7 +753,7 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteAllRenderBufferObjects() { for (Integer id : glRenderBuffers.keySet()) { int[] temp = { id.intValue() }; - pgl.delRenderbuffer(temp); + pgl.glDeleteRenderbuffers(1, temp, 0); } glRenderBuffers.clear(); } @@ -831,7 +774,7 @@ public class PGraphicsOpenGL extends PGraphics { if (glRenderBuffers.get(id)) { finalized.add(id); int[] temp = { id.intValue() }; - pgl.delRenderbuffer(temp); + pgl.glDeleteRenderbuffers(1, temp, 0); } } @@ -843,13 +786,9 @@ public class PGraphicsOpenGL extends PGraphics { // GLSL Program Objects ----------------------------------------------- protected int createGLSLProgramObject() { - - pg.report("before delete"); deleteFinalizedGLSLProgramObjects(); - int[] temp = new int[1]; - pgl.genProgram(temp); - int id = temp[0]; + int id = pgl.glCreateProgram(); if (glslPrograms.containsKey(id)) { showWarning("Adding same glsl program twice"); @@ -862,16 +801,14 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteGLSLProgramObject(int id) { if (glslPrograms.containsKey(id)) { - int[] temp = { id }; - pgl.delProgram(temp); + pgl.glDeleteProgram(id); glslPrograms.remove(id); } } protected void deleteAllGLSLProgramObjects() { for (Integer id : glslPrograms.keySet()) { - int[] temp = { id.intValue() }; - pgl.delProgram(temp); + pgl.glDeleteProgram(id); } glslPrograms.clear(); } @@ -891,8 +828,7 @@ public class PGraphicsOpenGL extends PGraphics { for (Integer id : glslPrograms.keySet()) { if (glslPrograms.get(id)) { finalized.add(id); - int[] temp = { id.intValue() }; - pgl.delProgram(temp); + pgl.glDeleteProgram(id); } } @@ -906,9 +842,7 @@ public class PGraphicsOpenGL extends PGraphics { protected int createGLSLVertShaderObject() { deleteFinalizedGLSLVertShaderObjects(); - int[] temp = new int[1]; - pgl.genVertexShader(temp); - int id = temp[0]; + int id = pgl.glCreateShader(PGL.GL_VERTEX_SHADER); if (glslVertexShaders.containsKey(id)) { showWarning("Adding same glsl vertex shader twice"); @@ -921,16 +855,14 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteGLSLVertShaderObject(int id) { if (glslVertexShaders.containsKey(id)) { - int[] temp = { id }; - pgl.delVertexShader(temp); + pgl.glDeleteShader(id); glslVertexShaders.remove(id); } } protected void deleteAllGLSLVertShaderObjects() { for (Integer id : glslVertexShaders.keySet()) { - int[] temp = { id.intValue() }; - pgl.delVertexShader(temp); + pgl.glDeleteShader(id); } glslVertexShaders.clear(); } @@ -950,8 +882,7 @@ public class PGraphicsOpenGL extends PGraphics { for (Integer id : glslVertexShaders.keySet()) { if (glslVertexShaders.get(id)) { finalized.add(id); - int[] temp = { id.intValue() }; - pgl.delVertexShader(temp); + pgl.glDeleteShader(id); } } @@ -966,9 +897,7 @@ public class PGraphicsOpenGL extends PGraphics { protected int createGLSLFragShaderObject() { deleteFinalizedGLSLFragShaderObjects(); - int[] temp = new int[1]; - pgl.genFragmentShader(temp); - int id = temp[0]; + int id = pgl.glCreateShader(PGL.GL_FRAGMENT_SHADER); if (glslFragmentShaders.containsKey(id)) { showWarning("Adding same glsl fragment shader twice"); @@ -981,16 +910,14 @@ public class PGraphicsOpenGL extends PGraphics { protected void deleteGLSLFragShaderObject(int id) { if (glslFragmentShaders.containsKey(id)) { - int[] temp = { id }; - pgl.delFragmentShader(temp); + pgl.glDeleteShader(id); glslFragmentShaders.remove(id); } } protected void deleteAllGLSLFragShaderObjects() { for (Integer id : glslFragmentShaders.keySet()) { - int[] temp = { id.intValue() }; - pgl.delFragmentShader(temp); + pgl.glDeleteShader(id); } glslFragmentShaders.clear(); } @@ -1010,8 +937,7 @@ public class PGraphicsOpenGL extends PGraphics { for (Integer id : glslFragmentShaders.keySet()) { if (glslFragmentShaders.get(id)) { finalized.add(id); - int[] temp = { id.intValue() }; - pgl.delFragmentShader(temp); + pgl.glDeleteShader(id); } } @@ -1092,13 +1018,35 @@ public class PGraphicsOpenGL extends PGraphics { texture.release(); texture = null; } - if (lineShader != null) { - lineShader.release(); - lineShader = null; + + if (defFillShaderSimple != null) { + defFillShaderSimple.release(); + defFillShaderSimple = null; } - if (pointShader != null) { - pointShader.release(); - pointShader = null; + + if (defFillShaderLit != null) { + defFillShaderLit.release(); + defFillShaderLit = null; + } + + if (defFillShaderTex != null) { + defFillShaderTex.release(); + defFillShaderTex = null; + } + + if (defFillShaderFull != null) { + defFillShaderFull.release(); + defFillShaderFull = null; + } + + if (defLineShader != null) { + defLineShader.release(); + defLineShader = null; + } + + if (defPointShader != null) { + defPointShader.release(); + defPointShader = null; } if (fillVBOsCreated) { @@ -1136,31 +1084,86 @@ public class PGraphicsOpenGL extends PGraphics { } protected void createFillBuffers() { + int sizef = PGL.MAX_TESS_VERTICES * PGL.SIZEOF_FLOAT; + int sizei = PGL.MAX_TESS_VERTICES * PGL.SIZEOF_INT; + int sizex = PGL.MAX_TESS_INDICES * PGL.SIZEOF_INDEX; + glFillVertexBufferID = createVertexBufferObject(); - pgl.bindVertexBuffer(glFillVertexBufferID); - pgl.initVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillVertexBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, vboMode); glFillColorBufferID = createVertexBufferObject(); - pgl.bindVertexBuffer(glFillColorBufferID); - pgl.initVertexBuffer(4 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillColorBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode); glFillNormalBufferID = createVertexBufferObject(); - pgl.bindVertexBuffer(glFillNormalBufferID); - pgl.initVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillNormalBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, vboMode); glFillTexCoordBufferID = createVertexBufferObject(); - pgl.bindVertexBuffer(glFillTexCoordBufferID); - pgl.initVertexBuffer(2 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillTexCoordBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, vboMode); - pgl.unbindVertexBuffer(); + glFillAmbientBufferID = pg.createVertexBufferObject(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillAmbientBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode); + + glFillSpecularBufferID = pg.createVertexBufferObject(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillSpecularBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode); + + glFillEmissiveBufferID = pg.createVertexBufferObject(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillEmissiveBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode); + + glFillShininessBufferID = pg.createVertexBufferObject(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillShininessBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizef, null, vboMode); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); glFillIndexBufferID = createVertexBufferObject(); - pgl.bindIndexBuffer(glFillIndexBufferID); - pgl.initIndexBuffer(PGL.MAX_TESS_INDICES, vboMode); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glFillIndexBufferID); + pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, vboMode); - pgl.unbindIndexBuffer(); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } + protected void updateFillBuffers(boolean lit, boolean tex) { + int size = tessGeo.fillVertexCount; + int sizef = size * PGL.SIZEOF_FLOAT; + int sizei = size * PGL.SIZEOF_INT; + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillVertexBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, FloatBuffer.wrap(tessGeo.fillVertices, 0, 3 * size), vboMode); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillColorBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.fillColors, 0, size), 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillAmbientBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.fillAmbient, 0, size), vboMode); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillSpecularBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.fillSpecular, 0, size), vboMode); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillEmissiveBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.fillEmissive, 0, size), vboMode); + + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillShininessBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizef, FloatBuffer.wrap(tessGeo.fillShininess, 0, size), 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); + } + } + protected void releaseFillBuffers() { deleteVertexBufferObject(glFillVertexBufferID); glFillVertexBufferID = 0; @@ -1174,36 +1177,64 @@ public class PGraphicsOpenGL extends PGraphics { deleteVertexBufferObject(glFillTexCoordBufferID); glFillTexCoordBufferID = 0; + deleteVertexBufferObject(glFillAmbientBufferID); + glFillAmbientBufferID = 0; + + deleteVertexBufferObject(glFillSpecularBufferID); + glFillSpecularBufferID = 0; + + deleteVertexBufferObject(glFillEmissiveBufferID); + glFillEmissiveBufferID = 0; + + deleteVertexBufferObject(glFillShininessBufferID); + glFillShininessBufferID = 0; + deleteVertexBufferObject(glFillIndexBufferID); glFillIndexBufferID = 0; } protected void createLineBuffers() { - glLineVertexBufferID = createVertexBufferObject(); - pgl.bindVertexBuffer(glLineVertexBufferID); - pgl.initVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); + int sizef = PGL.MAX_TESS_VERTICES * PGL.SIZEOF_FLOAT; + int sizex = PGL.MAX_TESS_INDICES * PGL.SIZEOF_INDEX; + int sizei = PGL.MAX_TESS_INDICES * PGL.SIZEOF_INT; + + glLineVertexBufferID = createVertexBufferObject(); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineVertexBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, vboMode); glLineColorBufferID = createVertexBufferObject(); - pgl.bindVertexBuffer(glLineColorBufferID); - pgl.initVertexBuffer(4 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineColorBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode); - glLineNormalBufferID = createVertexBufferObject(); - pgl.bindVertexBuffer(glLineNormalBufferID); - pgl.initVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); - - glLineAttribBufferID = createVertexBufferObject(); - pgl.bindVertexBuffer(glLineAttribBufferID); - pgl.initVertexBuffer(4 * PGL.MAX_TESS_VERTICES, vboMode); + glLineDirWidthBufferID = createVertexBufferObject(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineDirWidthBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 4 * sizef, null, vboMode); - pgl.unbindVertexBuffer(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); glLineIndexBufferID = createVertexBufferObject(); - pgl.bindIndexBuffer(glLineIndexBufferID); - pgl.initIndexBuffer(PGL.MAX_TESS_INDICES, vboMode); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glLineIndexBufferID); + pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, vboMode); - pgl.unbindIndexBuffer(); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } + protected void updateLineBuffers() { + int size = tessGeo.lineVertexCount; + int sizef = size * PGL.SIZEOF_FLOAT; + int sizei = size * PGL.SIZEOF_INT; + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineVertexBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, FloatBuffer.wrap(tessGeo.lineVertices, 0, 3 * size), vboMode); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineColorBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.lineColors, 0, size), vboMode); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineDirWidthBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 4 * sizef, FloatBuffer.wrap(tessGeo.lineDirWidths, 0, 4 * size), vboMode); + } + protected void releaseLineBuffers() { deleteVertexBufferObject(glLineVertexBufferID); glLineVertexBufferID = 0; @@ -1211,42 +1242,54 @@ public class PGraphicsOpenGL extends PGraphics { deleteVertexBufferObject(glLineColorBufferID); glLineColorBufferID = 0; - deleteVertexBufferObject(glLineNormalBufferID); - glLineNormalBufferID = 0; - - deleteVertexBufferObject(glLineAttribBufferID); - glLineAttribBufferID = 0; + deleteVertexBufferObject(glLineDirWidthBufferID); + glLineDirWidthBufferID = 0; deleteVertexBufferObject(glLineIndexBufferID); glLineIndexBufferID = 0; } protected void createPointBuffers() { + int sizef = PGL.MAX_TESS_VERTICES * PGL.SIZEOF_FLOAT; + int sizex = PGL.MAX_TESS_INDICES * PGL.SIZEOF_INDEX; + int sizei = PGL.MAX_TESS_INDICES * PGL.SIZEOF_INT; + glPointVertexBufferID = createVertexBufferObject(); - pgl.bindVertexBuffer(glPointVertexBufferID); - pgl.initVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointVertexBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, vboMode); glPointColorBufferID = createVertexBufferObject(); - pgl.bindVertexBuffer(glPointColorBufferID); - pgl.initVertexBuffer(4 * PGL.MAX_TESS_VERTICES, vboMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointColorBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, vboMode); - glPointNormalBufferID = createVertexBufferObject(); - pgl.bindVertexBuffer(glPointNormalBufferID); - pgl.initVertexBuffer(3 * PGL.MAX_TESS_VERTICES, vboMode); + glPointSizeBufferID = createVertexBufferObject(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointSizeBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, vboMode); - glPointAttribBufferID = createVertexBufferObject(); - pgl.bindVertexBuffer(glPointAttribBufferID); - pgl.initVertexBuffer(2 * PGL.MAX_TESS_VERTICES, vboMode); - - pgl.unbindVertexBuffer(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); glPointIndexBufferID = createVertexBufferObject(); - pgl.bindIndexBuffer(glPointIndexBufferID); - pgl.initIndexBuffer(PGL.MAX_TESS_INDICES, vboMode); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glPointIndexBufferID); + pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, vboMode); - pgl.unbindIndexBuffer(); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } + protected void updatePointBuffers() { + int size = tessGeo.pointVertexCount; + int sizef = size * PGL.SIZEOF_FLOAT; + int sizei = size * PGL.SIZEOF_INT; + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointVertexBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, FloatBuffer.wrap(tessGeo.pointVertices, 0, 3 * size), vboMode); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointColorBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.pointColors, 0, size), vboMode); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointSizeBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, FloatBuffer.wrap(tessGeo.pointSizes, 0, 2 * size), vboMode); + } + protected void releasePointBuffers() { deleteVertexBufferObject(glPointVertexBufferID); glPointVertexBufferID = 0; @@ -1254,18 +1297,14 @@ public class PGraphicsOpenGL extends PGraphics { deleteVertexBufferObject(glPointColorBufferID); glPointColorBufferID = 0; - deleteVertexBufferObject(glPointNormalBufferID); - glPointNormalBufferID = 0; - - deleteVertexBufferObject(glPointAttribBufferID); - glPointAttribBufferID = 0; + deleteVertexBufferObject(glPointSizeBufferID); + glPointSizeBufferID = 0; deleteVertexBufferObject(glPointIndexBufferID); glPointIndexBufferID = 0; } - - + /** * OpenGL cannot draw until a proper native peer is available, so this * returns the value of PApplet.isDisplayable() (inherited from Component). @@ -1329,7 +1368,7 @@ public class PGraphicsOpenGL extends PGraphics { // Disabling all lights, so the offscreen renderer can set completely // new light configuration (otherwise some light configuration from the // primary renderer might stay). - pg.disableLights(); + //pg.disableLights(); } inGeo.reset(); @@ -1347,17 +1386,17 @@ public class PGraphicsOpenGL extends PGraphics { // this is necessary for 3D drawing if (hints[DISABLE_DEPTH_TEST]) { - pgl.disableDepthTest(); + pgl.glDisable(PGL.GL_DEPTH_TEST); } else { - pgl.enableDepthTest(); + pgl.glEnable(PGL.GL_DEPTH_TEST); } // use <= since that's what processing.core does - pgl.setDepthFunc(PGL.LESS_OR_EQUAL); + pgl.setDepthFunc(PGL.GL_LEQUAL); if (hints[DISABLE_DEPTH_MASK]) { - pgl.disableDepthMask(); + pgl.glDepthMask(false); } else { - pgl.enableDepthMask(); + pgl.glDepthMask(true); } if (hints[ENABLE_ACCURATE_2D]) { @@ -1367,9 +1406,9 @@ public class PGraphicsOpenGL extends PGraphics { } // setup opengl viewport. - pgl.getViweport(savedViewport); + pgl.glGetIntegerv(PGL.GL_VIEWPORT, savedViewport, 0); viewport[0] = 0; viewport[1] = 0; viewport[2] = width; viewport[3] = height; - pgl.setViewport(viewport); + pgl.glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); if (resized) { // To avoid having garbage in the screen after a resize, // in the case background is not called in draw(). @@ -1385,15 +1424,15 @@ public class PGraphicsOpenGL extends PGraphics { resized = false; } - if (sizeChanged) { - // set up the default camera and initializes modelview matrix. - camera(); - + if (sizeChanged) { // defaults to perspective, if the user has setup up their // own projection, they'll need to fix it after resize anyway. // this helps the people who haven't set up their own projection. perspective(); + // set up the default camera and initializes modelview matrix. + camera(); + // clear the flag sizeChanged = false; } else { @@ -1401,9 +1440,9 @@ public class PGraphicsOpenGL extends PGraphics { // are set as the current modelview and projection matrices. This is done to // remove any additional modelview transformation (and less likely, projection // transformations) applied by the user after setting the camera and/or projection - loadCamera(); - modelview.set(camera); - loadProjection(); + modelview.set(camera); + modelviewInv.set(cameraInv); + calcProjmodelview(); } noLights(); @@ -1411,17 +1450,17 @@ public class PGraphicsOpenGL extends PGraphics { lightSpecular(0, 0, 0); // because y is flipped - pgl.setFrontFace(PGL.CLOCKWISE); + pgl.setFrontFace(PGL.GL_CW); - setSurfaceParams(); + // Processing uses only one texture unit. + pgl.glActiveTexture(PGL.GL_TEXTURE0); // The current normal vector is set to be parallel to the Z axis. - normalX = normalY = 0; - normalZ = 0; + normalX = normalY = normalZ = 0; // Clear depth and stencil buffers. - pgl.setClearColor(0, 0, 0, 0); - pgl.clearDepthAndStencilBuffers(); + pgl.glClearColor(0, 0, 0, 0); + pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT | PGL.GL_STENCIL_BUFFER_BIT); if (primarySurface) { pgl.beginOnscreenDraw(); @@ -1453,7 +1492,7 @@ public class PGraphicsOpenGL extends PGraphics { } // Restoring previous viewport. - pgl.setViewport(savedViewport); + pgl.glViewport(savedViewport[0], savedViewport[1], savedViewport[2], savedViewport[3]); if (primarySurface) { // glFlush should be called only once, since it is an expensive @@ -1461,7 +1500,7 @@ public class PGraphicsOpenGL extends PGraphics { // should call it at the end of draw, and none of the offscreen // renderers... pgl.endOnscreenDraw(); - pgl.flush(); + pgl.glFlush(); pgl.releaseContext(); } else { if (offscreenMultisample) { @@ -1480,29 +1519,13 @@ public class PGraphicsOpenGL extends PGraphics { } - public GL beginGL() { - saveGLState(); - // OpenGL is using Processing defaults at this point, - // such as the inverted Y axis, GL_COLOR_MATERIAL mode, etc. - // The user is free to change anything she wants, endGL will - // try to do its best to restore things to the Processing - // settings valid at the time of calling beginGL(). - return pgl.gl; - } - - - public void endGL() { - restoreGLState(); - } - - public PGL beginPGL() { saveGLState(); return pgl; } - public void endPGL() { + public void endGL() { restoreGLState(); } @@ -1517,129 +1540,40 @@ public class PGraphicsOpenGL extends PGraphics { protected void saveGLState() { - saveGLMatrices(); } protected void restoreGLState() { // Restoring viewport. - pgl.setViewport(viewport); - - restoreGLMatrices(); + pgl.glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); // Restoring hints. if (hints[DISABLE_DEPTH_TEST]) { - pgl.disableDepthTest(); - pgl.setClearColor(0, 0, 0, 0); - pgl.clearDepthBuffer(); + pgl.glDisable(PGL.GL_DEPTH_TEST); + pgl.glClearColor(0, 0, 0, 0); + pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT); } else { - pgl.enableDepthTest(); + pgl.glEnable(PGL.GL_DEPTH_TEST); } if (hints[DISABLE_DEPTH_MASK]) { - pgl.disableDepthMask(); + pgl.glDepthMask(false); } else { - pgl.enableDepthMask(); + pgl.glDepthMask(true); } // Restoring blending. blendMode(blendMode); - // Restoring fill - if (fill) { - calcR = fillR; - calcG = fillG; - calcB = fillB; - calcA = fillA; - fillFromCalc(); - } - - // Restoring material properties. - calcR = ambientR; - calcG = ambientG; - calcB = ambientB; - ambientFromCalc(); - - calcR = specularR; - calcG = specularG; - calcB = specularB; - specularFromCalc(); - - shininess(shininess); - - calcR = emissiveR; - calcG = emissiveG; - calcB = emissiveB; - emissiveFromCalc(); - - // Restoring lights. - if (lights) { - lights(); - for (int i = 0; i < lightCount; i++) { - lightEnable(i); - if (lightType[i] == AMBIENT) { - lightEnable(i); - lightAmbient(i); - lightPosition(i); - lightFalloff(i); - lightNoSpot(i); - lightNoDiffuse(i); - lightNoSpecular(i); - } else if (lightType[i] == DIRECTIONAL) { - lightEnable(i); - lightNoAmbient(i); - lightDirection(i); - lightDiffuse(i); - lightSpecular(i); - lightFalloff(i); - lightNoSpot(i); - } else if (lightType[i] == POINT) { - lightEnable(i); - lightNoAmbient(i); - lightPosition(i); - lightDiffuse(i); - lightSpecular(i); - lightFalloff(i); - lightNoSpot(i); - } else if (lightType[i] == SPOT) { - lightEnable(i); - lightNoAmbient(i); - lightPosition(i); - lightDirection(i); - lightDiffuse(i); - lightSpecular(i); - lightFalloff(i); - lightSpotAngle(i); - lightSpotConcentration(i); - } - } - } else { - noLights(); - } - // Some things the user might have changed from OpenGL, // but we want to make sure they return to the Processing // defaults (plus these cannot be changed through the API // so they should remain constant anyways): - pgl.setFrontFace(PGL.CLOCKWISE); - pgl.setDepthFunc(PGL.LESS_OR_EQUAL); - - setSurfaceParams(); + pgl.setFrontFace(PGL.GL_CW); + pgl.setDepthFunc(PGL.GL_LEQUAL); } - - - protected void saveDrawingState() { - if (drawState == null) { - drawState = new DrawingState(); - } - drawState.save(); - } - protected void restoreDrawingState() { - drawState.restore(); - } - // Utility function to get ready OpenGL for a specific // operation, such as grabbing the contents of the color // buffer. @@ -1653,7 +1587,111 @@ public class PGraphicsOpenGL extends PGraphics { protected void endGLOp() { pgl.releaseContext(); } + + protected void updateGLProjection() { + if (glProjection == null) { + glProjection = new float[16]; + } + + glProjection[0] = projection.m00; + glProjection[1] = projection.m10; + glProjection[2] = projection.m20; + glProjection[3] = projection.m30; + + glProjection[4] = projection.m01; + glProjection[5] = projection.m11; + glProjection[6] = projection.m21; + glProjection[7] = projection.m31; + + glProjection[8] = projection.m02; + glProjection[9] = projection.m12; + glProjection[10] = projection.m22; + glProjection[11] = projection.m32; + + glProjection[12] = projection.m03; + glProjection[13] = projection.m13; + glProjection[14] = projection.m23; + glProjection[15] = projection.m33; + } + + protected void updateGLModelview() { + if (glModelview == null) { + glModelview = new float[16]; + } + + glModelview[0] = modelview.m00; + glModelview[1] = modelview.m10; + glModelview[2] = modelview.m20; + glModelview[3] = modelview.m30; + + glModelview[4] = modelview.m01; + glModelview[5] = modelview.m11; + glModelview[6] = modelview.m21; + glModelview[7] = modelview.m31; + + glModelview[8] = modelview.m02; + glModelview[9] = modelview.m12; + glModelview[10] = modelview.m22; + glModelview[11] = modelview.m32; + + glModelview[12] = modelview.m03; + glModelview[13] = modelview.m13; + glModelview[14] = modelview.m23; + glModelview[15] = modelview.m33; + } + protected void calcProjmodelview() { + projmodelview.set(projection); + projmodelview.apply(modelview); + } + + protected void updateGLProjmodelview() { + if (glProjmodelview == null) { + glProjmodelview = new float[16]; + } + + glProjmodelview[0] = projmodelview.m00; + glProjmodelview[1] = projmodelview.m10; + glProjmodelview[2] = projmodelview.m20; + glProjmodelview[3] = projmodelview.m30; + + glProjmodelview[4] = projmodelview.m01; + glProjmodelview[5] = projmodelview.m11; + glProjmodelview[6] = projmodelview.m21; + glProjmodelview[7] = projmodelview.m31; + + glProjmodelview[8] = projmodelview.m02; + glProjmodelview[9] = projmodelview.m12; + glProjmodelview[10] = projmodelview.m22; + glProjmodelview[11] = projmodelview.m32; + + glProjmodelview[12] = projmodelview.m03; + glProjmodelview[13] = projmodelview.m13; + glProjmodelview[14] = projmodelview.m23; + glProjmodelview[15] = projmodelview.m33; + } + + protected void updateGLNormal() { + if (glNormal == null) { + glNormal = new float[9]; + } + + // The normal matrix is the transpose of the inverse of the + // modelview (remember that gl matrices are column-major, + // meaning that elements 0, 1, 2 are the first column, + // 3, 4, 5 the second, etc.: + glNormal[0] = modelviewInv.m00; + glNormal[1] = modelviewInv.m01; + glNormal[2] = modelviewInv.m02; + + glNormal[3] = modelviewInv.m10; + glNormal[4] = modelviewInv.m11; + glNormal[5] = modelviewInv.m12; + + glNormal[6] = modelviewInv.m20; + glNormal[7] = modelviewInv.m21; + glNormal[8] = modelviewInv.m22; + } ////////////////////////////////////////////////////////////// @@ -1677,6 +1715,9 @@ public class PGraphicsOpenGL extends PGraphics { if (modelviewStack == null) { modelviewStack = new Stack(); } + if (modelviewInvStack == null) { + modelviewInvStack = new Stack(); + } if (projectionStack == null) { projectionStack = new Stack(); } @@ -1692,31 +1733,31 @@ public class PGraphicsOpenGL extends PGraphics { // HINTS public void hint(int which) { - boolean oldValue = hints[Math.abs(which)]; + boolean oldValue = hints[PApplet.abs(which)]; super.hint(which); - boolean newValue = hints[Math.abs(which)]; - + boolean newValue = hints[PApplet.abs(which)]; + if (oldValue == newValue) { return; } if (which == DISABLE_DEPTH_TEST) { flush(); - pgl.disableDepthTest(); - pgl.setClearColor(0, 0, 0, 0); - pgl.clearDepthBuffer(); + pgl.glDisable(PGL.GL_DEPTH_TEST); + pgl.glClearColor(0, 0, 0, 0); + pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT); } else if (which == ENABLE_DEPTH_TEST) { flush(); - pgl.enableDepthTest(); + pgl.glEnable(PGL.GL_DEPTH_TEST); } else if (which == DISABLE_DEPTH_MASK) { flush(); - pgl.disableDepthMask(); + pgl.glDepthMask(false); } else if (which == ENABLE_DEPTH_MASK) { flush(); - pgl.enableDepthMask(); + pgl.glDepthMask(true); } else if (which == DISABLE_ACCURATE_2D) { flush(); @@ -1977,37 +2018,24 @@ public class PGraphicsOpenGL extends PGraphics { } boolean textured = textureImage != null; - float fR, fG, fB, fA; - fR = fG = fB = fA = 0; + int fcolor = 0x00; if (fill || textured) { if (!textured) { - fR = fillR; - fG = fillG; - fB = fillB; - fA = fillA; + fcolor = fillColor; } else { if (tint) { - fR = tintR; - fG = tintG; - fB = tintB; - fA = tintA; + fcolor = tintColor; } else { - fR = 1; - fG = 1; - fB = 1; - fA = 1; + fcolor = 0xffFFFFFF; } } } - float sR, sG, sB, sA, sW; - sR = sG = sB = sA = sW = 0; + int scolor = 0x00; + float sweight = 0; if (stroke) { - sR = strokeR; - sG = strokeG; - sB = strokeB; - sA = strokeA; - sW = strokeWeight; + scolor = strokeColor; + sweight = strokeWeight; } if (breakShape) { @@ -2026,10 +2054,11 @@ public class PGraphicsOpenGL extends PGraphics { } inGeo.addVertex(x, y, z, - fR, fG, fB, fA, + fcolor, normalX, normalY, normalZ, u, v, - sR, sG, sB, sA, sW, + scolor, sweight, + ambientColor, specularColor, emissiveColor, shininess, code); } @@ -2069,10 +2098,10 @@ public class PGraphicsOpenGL extends PGraphics { protected void clipImpl(float x1, float y1, float x2, float y2) { flush(); - pgl.enableClipping(); + pgl.glEnable(PGL.GL_SCISSOR_TEST); float h = y2 - y1; - pgl.setClipRect((int)x1, (int)(height - y1 - h), (int)(x2 - x1), (int)h); + pgl.glScissor((int)x1, (int)(height - y1 - h), (int)(x2 - x1), (int)h); clip = true; } @@ -2081,7 +2110,7 @@ public class PGraphicsOpenGL extends PGraphics { public void noClip() { if (clip) { flush(); - pgl.disableClipping(); + pgl.glDisable(PGL.GL_SCISSOR_TEST); clip = false; } } @@ -2103,15 +2132,12 @@ public class PGraphicsOpenGL extends PGraphics { tessellator.setStrokeWeight(strokeWeight); tessellator.setStrokeCap(strokeCap); tessellator.setStrokeJoin(strokeJoin); - tessellator.setStrokeColor(strokeR, strokeG, strokeB, strokeA); setFirstTexIndex(tessGeo.fillIndexCount); if (shape == POINTS) { - if (normalMode == NORMAL_MODE_AUTO) inGeo.calcPointsNormals(); tessellator.tessellatePoints(); } else if (shape == LINES) { - if (normalMode == NORMAL_MODE_AUTO) inGeo.calcLinesNormals(); tessellator.tessellateLines(); } else if (shape == TRIANGLE || shape == TRIANGLES) { if (stroke && defaultEdges) inGeo.addTrianglesEdges(); @@ -2163,9 +2189,9 @@ public class PGraphicsOpenGL extends PGraphics { if (flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { // The modelview transformation has been applied already to the // tessellated vertices, so we set the OpenGL modelview matrix as - // the identity to avoid applying the model transformations twice. - pgl.pushMatrix(); - pgl.loadIdentity(); + // the identity to avoid applying the model transformations twice. + pushMatrix(); + resetMatrix(); } if (hasFill) { @@ -2181,7 +2207,7 @@ public class PGraphicsOpenGL extends PGraphics { } if (flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { - pgl.popMatrix(); + popMatrix(); } } @@ -2195,42 +2221,22 @@ public class PGraphicsOpenGL extends PGraphics { createPointBuffers(); pointVBOsCreated = true; } + updatePointBuffers(); - startPointShader(); + PointShader shader = getPointShader(); + shader.start(); + shader.setVertexAttribute(glPointVertexBufferID, 3, PGL.GL_FLOAT, 0, 0); + shader.setColorAttribute(glPointColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); + shader.setSizeAttribute(glPointSizeBufferID, 2, PGL.GL_FLOAT, 0, 0); - pgl.enableVertexArrays(); - pgl.enableColorArrays(); - pgl.enableNormalArrays(); + 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); - int size = tessGeo.pointVertexCount; - - pgl.bindVertexBuffer(glPointVertexBufferID); - pgl.copyVertexBufferData(tessGeo.pointVertices, 3 * size, vboMode); - pgl.setVertexFormat(3, 0); - - pgl.bindVertexBuffer(glPointColorBufferID); - pgl.copyVertexBufferData(tessGeo.pointColors, 4 * size, vboMode); - pgl.setColorFormat(4, 0); - - pgl.bindVertexBuffer(glPointNormalBufferID); - pgl.copyVertexBufferData(tessGeo.pointNormals, 3 * size, vboMode); - pgl.setNormalFormat(3, 0); - - setupPointShader(glPointAttribBufferID, tessGeo.pointAttributes, size); - - size = tessGeo.pointIndexCount; - pgl.bindIndexBuffer(glPointIndexBufferID); - pgl.copyIndexBufferData(tessGeo.pointIndices, size, vboMode); - pgl.renderIndexBuffer(size); - - pgl.unbindIndexBuffer(); - pgl.unbindVertexBuffer(); - - pgl.disableVertexArrays(); - pgl.disableColorArrays(); - pgl.disableNormalArrays(); - - stopPointShader(); + shader.stop(); } protected void renderLines() { @@ -2238,42 +2244,22 @@ public class PGraphicsOpenGL extends PGraphics { createLineBuffers(); lineVBOsCreated = true; } + updateLineBuffers(); - startLineShader(); + LineShader shader = getLineShader(); + shader.start(); + shader.setVertexAttribute(glLineVertexBufferID, 3, PGL.GL_FLOAT, 0, 0); + shader.setColorAttribute(glLineColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); + shader.setDirWidthAttribute(glLineDirWidthBufferID, 4, PGL.GL_FLOAT, 0, 0); - pgl.enableVertexArrays(); - pgl.enableColorArrays(); - pgl.enableNormalArrays(); + 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); - int size = tessGeo.lineVertexCount; - - pgl.bindVertexBuffer(glLineVertexBufferID); - pgl.copyVertexBufferData(tessGeo.lineVertices, 3 * size, vboMode); - pgl.setVertexFormat(3, 0); - - pgl.bindVertexBuffer(glLineColorBufferID); - pgl.copyVertexBufferData(tessGeo.lineColors, 4 * size, vboMode); - pgl.setColorFormat(4, 0); - - pgl.bindVertexBuffer(glLineNormalBufferID); - pgl.copyVertexBufferData(tessGeo.lineNormals, 3 * size, vboMode); - pgl.setNormalFormat(3, 0); - - setupLineShader(glLineAttribBufferID, tessGeo.lineAttributes, size); - - size = tessGeo.lineIndexCount; - pgl.bindIndexBuffer(glLineIndexBufferID); - pgl.copyIndexBufferData(tessGeo.lineIndices, size, vboMode); - pgl.renderIndexBuffer(size); - - pgl.unbindIndexBuffer(); - pgl.unbindVertexBuffer(); - - pgl.disableVertexArrays(); - pgl.disableColorArrays(); - pgl.disableNormalArrays(); - - stopLineShader(); + shader.stop(); } @@ -2281,91 +2267,45 @@ public class PGraphicsOpenGL extends PGraphics { if (!fillVBOsCreated) { createFillBuffers(); fillVBOsCreated = true; - } - - pgl.enableVertexArrays(); - pgl.enableColorArrays(); - pgl.enableNormalArrays(); + } + updateFillBuffers(lights, texCache.hasTexture); - int size = tessGeo.fillVertexCount; - pgl.bindVertexBuffer(glFillVertexBufferID); - pgl.copyVertexBufferData(tessGeo.fillVertices, 3 * size, vboMode); - pgl.setVertexFormat(3, 0); - - pgl.bindVertexBuffer(glFillColorBufferID); - pgl.copyVertexBufferData(tessGeo.fillColors, 4 * size, vboMode); - pgl.setColorFormat(4, 0); + 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); - pgl.bindVertexBuffer(glFillNormalBufferID); - pgl.copyVertexBufferData(tessGeo.fillNormals, 3 * size, vboMode); - pgl.setNormalFormat(3, 0); - - if (texCache.hasTexture) { - pgl.enableTexCoordArrays(); - pgl.bindVertexBuffer(glFillTexCoordBufferID); - pgl.copyVertexBufferData(tessGeo.fillTexcoords, 2 * size, vboMode); - pgl.setTexCoordFormat(2, 0); - pgl.setActiveTexUnit(0); - } - - pgl.bindIndexBuffer(glFillIndexBufferID); - - PTexture tex0 = null; + texCache.beginRender(); for (int i = 0; i < texCache.count; i++) { - PImage img = texCache.textures[i]; - PTexture tex = null; + PTexture tex = texCache.getTexture(i); + + FillShader shader = getFillShader(lights, tex != null); + shader.start(); - if (img != null) { - tex = pg.getTexture(img); - if (tex != null) { - tex.bind(); - tex0 = tex; - } + shader.setVertexAttribute(glFillVertexBufferID, 3, PGL.GL_FLOAT, 0, 0); + shader.setColorAttribute(glFillColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); + + if (lights) { + shader.setNormalAttribute(glFillNormalBufferID, 3, PGL.GL_FLOAT, 0, 0); + shader.setAmbientAttribute(glFillAmbientBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); + shader.setSpecularAttribute(glFillSpecularBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); + shader.setEmissiveAttribute(glFillEmissiveBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); + shader.setShininessAttribute(glFillShininessBufferID, 1, PGL.GL_FLOAT, 0, 0); } - if (tex == null && tex0 != null) { - tex0.unbind(); - pgl.disableTexturing(tex0.glTarget); + + if (tex != null) { + shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0); } - + int offset = texCache.firstIndex[i]; - size = texCache.lastIndex[i] - texCache.firstIndex[i] + 1; - pgl.copyIndexBufferData(tessGeo.fillIndices, offset, size, vboMode); - pgl.renderIndexBuffer(size); - } - - if (texCache.hasTexture) { - // Unbinding all the textures in the cache. - for (int i = 0; i < texCache.count; i++) { - PImage img = texCache.textures[i]; - if (img != null) { - PTexture tex = pg.getTexture(img); - if (tex != null) { - tex.unbind(); - } - } - } - // Disabling texturing for each of the targets used - // by textures in the cache. - for (int i = 0; i < texCache.count; i++) { - PImage img = texCache.textures[i]; - if (img != null) { - PTexture tex = pg.getTexture(img); - if (tex != null) { - pgl.disableTexturing(tex.glTarget); - } - } - } + int size = texCache.lastIndex[i] - texCache.firstIndex[i] + 1; + pgl.glDrawElements(PGL.GL_TRIANGLES, size, PGL.INDEX_TYPE, offset * PGL.SIZEOF_INDEX); - pgl.disableTexCoordArrays(); - } - - pgl.unbindIndexBuffer(); - pgl.unbindVertexBuffer(); - - pgl.disableVertexArrays(); - pgl.disableColorArrays(); - pgl.disableNormalArrays(); + shader.stop(); + } + texCache.endRender(); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } + // Utility function to render current tessellated geometry, under the assumption that // the texture is already bound. @@ -2374,146 +2314,31 @@ public class PGraphicsOpenGL extends PGraphics { createFillBuffers(); fillVBOsCreated = true; } - - pgl.enableVertexArrays(); - pgl.enableColorArrays(); - pgl.enableNormalArrays(); - pgl.enableTexCoordArrays(); + updateFillBuffers(lights, true); - int size = tessGeo.fillVertexCount; - pgl.bindVertexBuffer(glFillVertexBufferID); - pgl.copyVertexBufferData(tessGeo.fillVertices, 3 * size, vboMode); - pgl.setVertexFormat(3, 0); - - pgl.bindVertexBuffer(glFillColorBufferID); - pgl.copyVertexBufferData(tessGeo.fillColors, 4 * size, vboMode); - pgl.setColorFormat(4, 0); + FillShader shader = getFillShader(lights, true); + shader.start(); - pgl.bindVertexBuffer(glFillNormalBufferID); - pgl.copyVertexBufferData(tessGeo.fillNormals, 3 * size, vboMode); - pgl.setNormalFormat(3, 0); - - pgl.bindVertexBuffer(glFillTexCoordBufferID); - pgl.copyVertexBufferData(tessGeo.fillTexcoords, 2 * size, vboMode); - pgl.setTexCoordFormat(2, 0); - - size = tessGeo.fillIndexCount; - pgl.bindIndexBuffer(glFillIndexBufferID); - pgl.copyIndexBufferData(tessGeo.fillIndices, size, vboMode); - pgl.renderIndexBuffer(size); - - pgl.unbindIndexBuffer(); - pgl.unbindVertexBuffer(); + shader.setVertexAttribute(glFillVertexBufferID, 3, PGL.GL_FLOAT, 0, 0); + shader.setColorAttribute(glFillColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); + shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0); - pgl.disableTexCoordArrays(); - pgl.disableVertexArrays(); - pgl.disableColorArrays(); - pgl.disableNormalArrays(); - } - - protected void startLineShader() { - if (lineShader == null) { - lineShader = new PShader(parent); - lineShader.loadVertexShader(PGraphicsOpenGL.class.getResource("LineShaderVert.glsl")); - lineShader.loadFragmentShader(PGraphicsOpenGL.class.getResource("LineShaderFrag.glsl")); - lineShader.setup(); + if (lights) { + shader.setNormalAttribute(glFillNormalBufferID, 3, PGL.GL_FLOAT, 0, 0); + shader.setAmbientAttribute(glFillAmbientBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); + shader.setSpecularAttribute(glFillSpecularBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); + shader.setEmissiveAttribute(glFillEmissiveBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); + shader.setShininessAttribute(glFillShininessBufferID, 1, PGL.GL_FLOAT, 0, 0); } - - lineShader.start(); - } - - protected void setupLineShader(int attrBufID, float[] attribs, int nvert) { - lineShader.setVecUniform("viewport", viewport[0], viewport[1], viewport[2], viewport[3]); + 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.glDrawElements(PGL.GL_TRIANGLES, size, PGL.INDEX_TYPE, 0); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); - if (hints[ENABLE_PERSPECTIVE_CORRECTED_LINES]) { - lineShader.setIntUniform("perspective", 1); - } else { - lineShader.setIntUniform("perspective", 0); - } - - lineShader.setIntUniform("lights", lightCount); - - lineShader.setVecUniform("eye", cameraEyeX, cameraEyeY, cameraEyeZ, 0); - - lineAttribsLoc = lineShader.getAttribLocation("attribs"); - - pgl.enableAttribsArray(lineAttribsLoc); - pgl.bindVertexBuffer(attrBufID); - pgl.copyVertexBufferData(attribs, 4 * nvert, vboMode); - pgl.setAttribsFormat(lineAttribsLoc, 4, 0, 0); - } - - - protected void setupLineShader(int attrBufID) { - lineShader.setVecUniform("viewport", viewport[0], viewport[1], viewport[2], viewport[3]); - - if (hints[ENABLE_PERSPECTIVE_CORRECTED_LINES]) { - lineShader.setIntUniform("perspective", 1); - } else { - lineShader.setIntUniform("perspective", 0); - } - - lineShader.setIntUniform("lights", lightCount); - - lineShader.setVecUniform("eye", cameraEyeX, cameraEyeY, cameraEyeZ, 0); - - lineAttribsLoc = lineShader.getAttribLocation("attribs"); - - pgl.enableAttribsArray(lineAttribsLoc); - pgl.bindVertexBuffer(attrBufID); - pgl.setAttribsFormat(lineAttribsLoc, 4, 0, 0); - } - - - protected void stopLineShader() { - pgl.disableAttribsArray(lineAttribsLoc); - lineShader.stop(); - } - - - protected void startPointShader() { - if (pointShader == null) { - pointShader = new PShader(parent); - pointShader.loadVertexShader(PGraphicsOpenGL.class.getResource("PointShaderVert.glsl")); - pointShader.loadFragmentShader(PGraphicsOpenGL.class.getResource("PointShaderFrag.glsl")); - pointShader.setup(); - } - - pointShader.start(); - } - - - protected void setupPointShader(int attrBufID, float[] attribs, int nvert) { - pointShader.setIntUniform("lights", lightCount); - - pointShader.setVecUniform("eye", cameraEyeX, cameraEyeY, cameraEyeZ, 0); - - pointAttribsLoc = PGraphicsOpenGL.pointShader.getAttribLocation("vertDisp"); - - pgl.enableAttribsArray(pointAttribsLoc); - pgl.bindVertexBuffer(attrBufID); - pgl.copyVertexBufferData(attribs, 2 * nvert, vboMode); - pgl.setAttribsFormat(pointAttribsLoc, 2, 0, 0); - } - - - protected void setupPointShader(int attrBufID) { - pointShader.setIntUniform("lights", lightCount); - - pointShader.setVecUniform("eye", cameraEyeX, cameraEyeY, cameraEyeZ, 0); - - pointAttribsLoc = PGraphicsOpenGL.pointShader.getAttribLocation("vertDisp"); - - pgl.enableAttribsArray(pointAttribsLoc); - pgl.bindVertexBuffer(attrBufID); - pgl.setAttribsFormat(pointAttribsLoc, 2, 0, 0); - } - - - protected void stopPointShader() { - pgl.disableAttribsArray(pointAttribsLoc); - pointShader.stop(); + shader.stop(); } ////////////////////////////////////////////////////////////// @@ -2871,9 +2696,9 @@ public class PGraphicsOpenGL extends PGraphics { beginShape(TRIANGLE_FAN); defaultEdges = false; inGeo.generateEllipse(ellipseMode, a, b, c, d, - fill, fillR, fillG, fillB, fillA, - stroke, strokeR, strokeG, strokeB, strokeA, - strokeWeight); + fill, fillColor, + stroke, strokeColor, strokeWeight, + ambientColor, specularColor, emissiveColor, shininess); endShape(); } @@ -3054,17 +2879,17 @@ public class PGraphicsOpenGL extends PGraphics { } int[] temp = { 0 }; - pgl.getNumSamples(temp); + pgl.glGetIntegerv(PGL.GL_SAMPLES, temp, 0); if (antialias != temp[0]) { antialias = temp[0]; PApplet.println("Effective multisampling level: " + antialias); } if (antialias < 2) { - pgl.enableMultisample(); - pgl.enablePointSmooth(); - pgl.enableLineSmooth(); - pgl.enablePolygonSmooth(); + pgl.glEnable(PGL.GL_MULTISAMPLE); + pgl.glEnable(PGL.GL_POINT_SMOOTH); + pgl.glEnable(PGL.GL_LINE_SMOOTH); + pgl.glEnable(PGL.GL_POLYGON_SMOOTH); } } @@ -3082,10 +2907,10 @@ public class PGraphicsOpenGL extends PGraphics { } } - pgl.disableMultisample(); - pgl.disablePointSmooth(); - pgl.disableLineSmooth(); - pgl.disablePolygonSmooth(); + pgl.glDisable(PGL.GL_MULTISAMPLE); + pgl.glDisable(PGL.GL_POINT_SMOOTH); + pgl.glDisable(PGL.GL_LINE_SMOOTH); + pgl.glDisable(PGL.GL_POLYGON_SMOOTH); } ////////////////////////////////////////////////////////////// @@ -3158,7 +2983,7 @@ public class PGraphicsOpenGL extends PGraphics { textTex = (PFontTexture)textFont.getCache(pg); if (textTex == null) { textTex = new PFontTexture(parent, textFont, maxTextureSize, maxTextureSize); - textFont.setCache(this, textTex); + textFont.setCache(this, textTex); } else { if (!pgl.contextIsCurrent(textTex.context)) { for (int i = 0; i < textTex.textures.length; i++) { @@ -3170,7 +2995,7 @@ public class PGraphicsOpenGL extends PGraphics { textFont.setCache(this, textTex); } } - textTex.setFirstTexture(); + textTex.setFirstTexture(); // Saving style parameters modified by text rendering. int savedTextureMode = textureMode; @@ -3179,10 +3004,7 @@ public class PGraphicsOpenGL extends PGraphics { float savedNormalY = normalY; float savedNormalZ = normalZ; boolean savedTint = tint; - float savedTintR = tintR; - float savedTintG = tintG; - float savedTintB = tintB; - float savedTintA = tintA; + int savedTintColor = tintColor; int savedBlendMode = blendMode; // Setting style used in text rendering. @@ -3192,10 +3014,7 @@ public class PGraphicsOpenGL extends PGraphics { normalY = 0; normalZ = 1; tint = true; - tintR = fillR; - tintG = fillG; - tintB = fillB; - tintA = fillA; + tintColor = fillColor; blendMode(BLEND); @@ -3208,10 +3027,7 @@ public class PGraphicsOpenGL extends PGraphics { normalY = savedNormalY; normalZ = savedNormalZ; tint = savedTint; - tintR = savedTintR; - tintG = savedTintG; - tintB = savedTintB; - tintA = savedTintA; + tintColor = savedTintColor; // Note that if the user is using a blending mode different from // BLEND, and has a bunch of continuous text rendering, the performance @@ -3261,7 +3077,7 @@ public class PGraphicsOpenGL extends PGraphics { vertex(x1, y0, info.u1, info.v0); vertex(x1, y1, info.u1, info.v1); vertex(x0, y1, info.u0, info.v1); - endShape(); + endShape(); } @@ -3271,18 +3087,24 @@ public class PGraphicsOpenGL extends PGraphics { public void pushMatrix() { - pgl.pushMatrix(); - modelviewStack.push(new PMatrix3D(modelview)); + modelviewStack.push(new PMatrix3D(modelview)); + modelviewInvStack.push(new PMatrix3D(modelviewInv)); } public void popMatrix() { if (hints[DISABLE_TRANSFORM_CACHE]) { flush(); - } - pgl.popMatrix(); - PMatrix3D mat = modelviewStack.pop(); + } + PMatrix3D mat; + + mat = modelviewStack.pop(); modelview.set(mat); + + mat = modelviewInvStack.pop(); + modelviewInv.set(mat); + + calcProjmodelview(); } @@ -3301,8 +3123,9 @@ public class PGraphicsOpenGL extends PGraphics { flush(); } - pgl.translate(tx, ty, tz); modelview.translate(tx, ty, tz); + modelviewInv.invTranslate(tx, ty, tz); + projmodelview.translate(tx, ty, tz); } @@ -3340,9 +3163,10 @@ public class PGraphicsOpenGL extends PGraphics { if (hints[DISABLE_TRANSFORM_CACHE]) { flush(); } - - pgl.rotate(angle, v0, v1, v2); + modelview.rotate(angle, v0, v1, v2); + modelviewInv.invRotate(angle, v0, v1, v2); + calcProjmodelview(); // Possibly cheaper than doing projmodelview.rotate() } @@ -3369,9 +3193,10 @@ public class PGraphicsOpenGL extends PGraphics { if (hints[DISABLE_TRANSFORM_CACHE]) { flush(); } - - pgl.scale(sx, sy, sz); + modelview.scale(sx, sy, sz); + modelviewInv.invScale(sx, sy, sz); + projmodelview.scale(sx, sy, sz); } @@ -3399,8 +3224,9 @@ public class PGraphicsOpenGL extends PGraphics { public void resetMatrix() { - pgl.loadIdentity(); modelview.reset(); + modelviewInv.reset(); + projmodelview.set(projection); } @@ -3428,8 +3254,7 @@ public class PGraphicsOpenGL extends PGraphics { /** - * Apply a 4x4 transformation matrix to the modelview stack using - * glMultMatrix(). + * Apply a 4x4 transformation matrix to the modelview stack. */ public void applyMatrix(float n00, float n01, float n02, float n03, float n10, float n11, float n12, float n13, @@ -3438,21 +3263,17 @@ public class PGraphicsOpenGL extends PGraphics { if (hints[DISABLE_TRANSFORM_CACHE]) { flush(); } - - glMatrix[ 0] = n00; glMatrix[ 4] = n01; glMatrix[ 8] = n02; glMatrix[12] = n03; - glMatrix[ 1] = n10; glMatrix[ 5] = n11; glMatrix[ 9] = n12; glMatrix[13] = n13; - glMatrix[ 2] = n20; glMatrix[ 6] = n21; glMatrix[10] = n22; glMatrix[14] = n23; - glMatrix[ 3] = n30; glMatrix[ 7] = n31; glMatrix[11] = n32; glMatrix[15] = n33; - - pgl.multMatrix(glMatrix); - modelview.apply(n00, n01, n02, n03, n10, n11, n12, n13, n20, n21, n22, n23, n30, n31, n32, n33); + projmodelview.apply(n00, n01, n02, n03, + n10, n11, n12, n13, + n20, n21, n22, n23, + n30, n31, n32, n33); } - + /* protected void loadProjection() { pgl.setProjectionMode(); loadMatrix(projection); @@ -3471,16 +3292,10 @@ public class PGraphicsOpenGL extends PGraphics { loadMatrix(modelview); } - protected void loadMatrix(PMatrix3D pMatrix) { - glMatrix[ 0] = pMatrix.m00; glMatrix[ 4] = pMatrix.m01; glMatrix[ 8] = pMatrix.m02; glMatrix[12] = pMatrix.m03; - glMatrix[ 1] = pMatrix.m10; glMatrix[ 5] = pMatrix.m11; glMatrix[ 9] = pMatrix.m12; glMatrix[13] = pMatrix.m13; - glMatrix[ 2] = pMatrix.m20; glMatrix[ 6] = pMatrix.m21; glMatrix[10] = pMatrix.m22; glMatrix[14] = pMatrix.m23; - glMatrix[ 3] = pMatrix.m30; glMatrix[ 7] = pMatrix.m31; glMatrix[11] = pMatrix.m32; glMatrix[15] = pMatrix.m33; - - pgl.loadMatrix(glMatrix); + modelview.set(pMatrix); } - + */ ////////////////////////////////////////////////////////////// @@ -3528,31 +3343,23 @@ public class PGraphicsOpenGL extends PGraphics { public void pushProjection() { - pgl.setProjectionMode(); - pgl.pushMatrix(); projectionStack.push(new PMatrix3D(projection)); - pgl.setModelviewMode(); } public void popProjection() { - pgl.setProjectionMode(); - pgl.popMatrix(); PMatrix3D mat = projectionStack.pop(); projection.set(mat); - pgl.setModelviewMode(); } public void applyProjection(PMatrix3D mat) { projection.apply(mat); - loadProjection(); } public void setProjection(PMatrix3D mat) { projection.set(mat); - loadProjection(); } @@ -3633,8 +3440,7 @@ public class PGraphicsOpenGL extends PGraphics { } camera.set(modelview); - cameraInv.set(camera); - cameraInv.invert(); + cameraInv.set(modelviewInv); // all done manipulatingCamera = false; @@ -3798,12 +3604,14 @@ public class PGraphicsOpenGL extends PGraphics { float ty = -eyeY; float tz = -eyeZ; modelview.translate(tx, ty, tz); - - loadModelview(); + + modelviewInv.set(modelview); + modelviewInv.invert(); camera.set(modelview); - cameraInv.set(camera); - cameraInv.invert(); + cameraInv.set(modelviewInv); + + calcProjmodelview(); } @@ -3876,8 +3684,6 @@ public class PGraphicsOpenGL extends PGraphics { 0, -y, 0, ty, 0, 0, z, tz, 0, 0, 0, 1); - - loadProjection(); } @@ -3941,7 +3747,7 @@ public class PGraphicsOpenGL extends PGraphics { 0, 0, (-zfar - znear) / temp4, (-temp * zfar) / temp4, 0, 0, -1, 1); - loadProjection(); + calcProjmodelview(); } @@ -4103,139 +3909,7 @@ public class PGraphicsOpenGL extends PGraphics { public void strokeCap(int cap) { this.strokeCap = cap; } - - ////////////////////////////////////////////////////////////// - - // STROKE, TINT, FILL - - // public void noStroke() - // public void stroke(int rgb) - // public void stroke(int rgb, float alpha) - // public void stroke(float gray) - // public void stroke(float gray, float alpha) - // public void stroke(float x, float y, float z) - // public void stroke(float x, float y, float z, float a) - // protected void strokeFromCalc() - - // public void noTint() - // public void tint(int rgb) - // public void tint(int rgb, float alpha) - // public void tint(float gray) - // public void tint(float gray, float alpha) - // public void tint(float x, float y, float z) - // public void tint(float x, float y, float z, float a) - // protected void tintFromCalc() - - // public void noFill() - // public void fill(int rgb) - // public void fill(int rgb, float alpha) - // public void fill(float gray) - // public void fill(float gray, float alpha) - // public void fill(float x, float y, float z) - // public void fill(float x, float y, float z, float a) - - protected void fillFromCalc() { - super.fillFromCalc(); - calcColorBuffer(); - - // P3D uses GL_COLOR_MATERIAL mode, so the ambient and diffuse components - // for all vertices are taken from the glColor/color buffer settings and we don't - // need this: - //gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT_AND_DIFFUSE, colorFloats, 0); - } - - protected void setFillColor() { - pgl.setColor(fillR, fillG, fillB, fillA); - } - protected void setTintColor() { - pgl.setColor(tintR, tintG, tintB, tintA); - } - - ////////////////////////////////////////////////////////////// - - // MATERIAL PROPERTIES - - // public void ambient(int rgb) { - // super.ambient(rgb); - // calcColorBuffer(); - // gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, colorBuffer, 0); - // } - - // public void ambient(float gray) { - // super.ambient(gray); - // calcColorBuffer(); - // gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, colorBuffer, 0); - // } - - // public void ambient(float x, float y, float z) { - // super.ambient(x, y, z); - // calcColorBuffer(); - // gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, colorBuffer, 0); - // } - - protected void ambientFromCalc() { - super.ambientFromCalc(); - calcColorBuffer(); - - // OPENGL uses GL_COLOR_MATERIAL mode, so the ambient and diffuse components - // for all vertices are taken from the glColor/color buffer settings. - pgl.setMaterialAmbient(colorFloats); - - } - - // public void specular(int rgb) { - // super.specular(rgb); - // calcColorBuffer(); - // gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, colorBuffer, 0); - // } - - // public void specular(float gray) { - // super.specular(gray); - // calcColorBuffer(); - // gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, colorBuffer, 0); - // } - - // public void specular(float x, float y, float z) { - // super.specular(x, y, z); - // calcColorBuffer(); - // gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, colorBuffer, 0); - // } - - protected void specularFromCalc() { - super.specularFromCalc(); - calcColorBuffer(); - pgl.setMaterialSpecular(colorFloats); - } - - public void shininess(float shine) { - super.shininess(shine); - pgl.setMaterialShininess(shine); - } - - // public void emissive(int rgb) { - // super.emissive(rgb); - // calcColorBuffer(); - // gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_EMISSION, colorBuffer, 0); - // } - - // public void emissive(float gray) { - // super.emissive(gray); - // calcColorBuffer(); - // gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_EMISSION, colorBuffer, 0); - // } - - // public void emissive(float x, float y, float z) { - // super.emissive(x, y, z); - // calcColorBuffer(); - // gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_EMISSION, colorBuffer, 0); - // } - - protected void emissiveFromCalc() { - super.emissiveFromCalc(); - calcColorBuffer(); - pgl.setMaterialEmission(colorFloats); - } ////////////////////////////////////////////////////////////// @@ -4348,7 +4022,7 @@ public class PGraphicsOpenGL extends PGraphics { colorMode = RGB; lightFalloff(1, 0, 0); - lightSpecular(0, 0, 0); + lightSpecular(255, 255, 255); ambientLight(colorModeX * 0.5f, colorModeY * 0.5f, colorModeZ * 0.5f); directionalLight(colorModeX * 0.5f, colorModeY * 0.5f, colorModeZ * 0.5f, 0, 0, -1); @@ -4380,151 +4054,95 @@ public class PGraphicsOpenGL extends PGraphics { if (lightCount == PGL.MAX_LIGHTS) { throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + " lights"); } - colorCalc(r, g, b); - lightDiffuse[lightCount][0] = calcR; - lightDiffuse[lightCount][1] = calcG; - lightDiffuse[lightCount][2] = calcB; - lightDiffuse[lightCount][3] = 1.0f; - - lightType[lightCount] = AMBIENT; - lightFalloffConstant[lightCount] = currentLightFalloffConstant; - lightFalloffLinear[lightCount] = currentLightFalloffLinear; - lightFalloffQuadratic[lightCount] = currentLightFalloffQuadratic; - lightPosition[lightCount][0] = x; - lightPosition[lightCount][1] = y; - lightPosition[lightCount][2] = z; - lightPosition[lightCount][3] = 1.0f; - lightEnable(lightCount); - lightAmbient(lightCount); - lightPosition(lightCount); - lightFalloff(lightCount); - lightNoSpot(lightCount); - lightNoDiffuse(lightCount); - lightNoSpecular(lightCount); + lightType[lightCount] = AMBIENT; + + lightPosition(lightCount, x, y, z, false); + lightNormal(lightCount, 0, 0, 0); + + lightAmbient(lightCount, r, g, b); + noLightDiffuse(lightCount); + noLightSpecular(lightCount); + noLightSpot(lightCount); + lightFalloff(lightCount, currentLightFalloffConstant, + currentLightFalloffLinear, + currentLightFalloffQuadratic); lightCount++; } - public void directionalLight(float r, float g, float b, float nx, float ny, float nz) { + public void directionalLight(float r, float g, float b, + float dx, float dy, float dz) { enableLighting(); if (lightCount == PGL.MAX_LIGHTS) { throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + " lights"); } - colorCalc(r, g, b); - lightDiffuse[lightCount][0] = calcR; - lightDiffuse[lightCount][1] = calcG; - lightDiffuse[lightCount][2] = calcB; - lightDiffuse[lightCount][3] = 1.0f; - - lightType[lightCount] = DIRECTIONAL; - lightFalloffConstant[lightCount] = currentLightFalloffConstant; - lightFalloffLinear[lightCount] = currentLightFalloffLinear; - lightFalloffQuadratic[lightCount] = currentLightFalloffQuadratic; - lightSpecular[lightCount][0] = currentLightSpecular[0]; - lightSpecular[lightCount][1] = currentLightSpecular[1]; - lightSpecular[lightCount][2] = currentLightSpecular[2]; - lightSpecular[lightCount][3] = currentLightSpecular[3]; - // In this case, the normal is used to indicate the direction - // of the light, with the w component equals to zero. See - // the comments in the lightDirection() method. - lightNormal[lightCount][0] = nx; - lightNormal[lightCount][1] = ny; - lightNormal[lightCount][2] = nz; - lightNormal[lightCount][3] = 0.0f; + lightType[lightCount] = DIRECTIONAL; - lightEnable(lightCount); - lightNoAmbient(lightCount); - lightDirection(lightCount); - lightDiffuse(lightCount); - lightSpecular(lightCount); - lightFalloff(lightCount); - lightNoSpot(lightCount); + lightPosition(lightCount, 0, 0, 0, true); + lightNormal(lightCount, dx, dy, dz); + + noLightAmbient(lightCount); + lightDiffuse(lightCount, r, g, b); + lightSpecular(lightCount, currentLightSpecular[0], + currentLightSpecular[1], + currentLightSpecular[2]); + noLightSpot(lightCount); + noLightFalloff(lightCount); lightCount++; } - public void pointLight(float r, float g, float b, float x, float y, float z) { + public void pointLight(float r, float g, float b, + float x, float y, float z) { enableLighting(); if (lightCount == PGL.MAX_LIGHTS) { throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + " lights"); } - colorCalc(r, g, b); - lightDiffuse[lightCount][0] = calcR; - lightDiffuse[lightCount][1] = calcG; - lightDiffuse[lightCount][2] = calcB; - lightDiffuse[lightCount][3] = 1.0f; - + lightType[lightCount] = POINT; - lightFalloffConstant[lightCount] = currentLightFalloffConstant; - lightFalloffLinear[lightCount] = currentLightFalloffLinear; - lightFalloffQuadratic[lightCount] = currentLightFalloffQuadratic; - lightSpecular[lightCount][0] = currentLightSpecular[0]; - lightSpecular[lightCount][1] = currentLightSpecular[1]; - lightSpecular[lightCount][2] = currentLightSpecular[2]; - - lightPosition[lightCount][0] = x; - lightPosition[lightCount][1] = y; - lightPosition[lightCount][2] = z; - lightPosition[lightCount][3] = 1.0f; - - lightEnable(lightCount); - lightNoAmbient(lightCount); - lightPosition(lightCount); - lightDiffuse(lightCount); - lightSpecular(lightCount); - lightFalloff(lightCount); - lightNoSpot(lightCount); + lightPosition(lightCount, x, y, z, false); + lightNormal(lightCount, 0, 0, 0); + + noLightAmbient(lightCount); + lightDiffuse(lightCount, r, g, b); + lightSpecular(lightCount, currentLightSpecular[0], + currentLightSpecular[1], + currentLightSpecular[2]); + noLightSpot(lightCount); + lightFalloff(lightCount, currentLightFalloffConstant, + currentLightFalloffLinear, + currentLightFalloffQuadratic); + lightCount++; } - public void spotLight(float r, float g, float b, float x, float y, float z, - float nx, float ny, float nz, float angle, float concentration) { + public void spotLight(float r, float g, float b, + float x, float y, float z, + float dx, float dy, float dz, + float angle, float concentration) { enableLighting(); if (lightCount == PGL.MAX_LIGHTS) { throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + " lights"); } - colorCalc(r, g, b); - lightDiffuse[lightCount][0] = calcR; - lightDiffuse[lightCount][1] = calcG; - lightDiffuse[lightCount][2] = calcB; - lightDiffuse[lightCount][3] = 1.0f; - + lightType[lightCount] = SPOT; - lightFalloffConstant[lightCount] = currentLightFalloffConstant; - lightFalloffLinear[lightCount] = currentLightFalloffLinear; - lightFalloffQuadratic[lightCount] = currentLightFalloffQuadratic; - lightSpecular[lightCount][0] = currentLightSpecular[0]; - lightSpecular[lightCount][1] = currentLightSpecular[1]; - lightSpecular[lightCount][2] = currentLightSpecular[2]; - - lightPosition[lightCount][0] = x; - lightPosition[lightCount][1] = y; - lightPosition[lightCount][2] = z; - lightPosition[lightCount][3] = 1.0f; - - float invn = 1.0f / PApplet.dist(0, 0, 0, nx, ny, nz); - lightNormal[lightCount][0] = invn * nx; - lightNormal[lightCount][1] = invn * ny; - lightNormal[lightCount][2] = invn * nz; - lightNormal[lightCount][3] = 0.0f; - - lightSpotAngle[lightCount] = PApplet.degrees(angle); - lightSpotAngleCos[lightCount] = Math.max(0, (float) Math.cos(angle)); - lightSpotConcentration[lightCount] = concentration; - - lightEnable(lightCount); - lightNoAmbient(lightCount); - lightPosition(lightCount); - lightDirection(lightCount); - lightDiffuse(lightCount); - lightSpecular(lightCount); - lightFalloff(lightCount); - lightSpotAngle(lightCount); - lightSpotConcentration(lightCount); + lightPosition(lightCount, x, y, z, false); + lightNormal(lightCount, dx, dy, dz); + + noLightAmbient(lightCount); + lightDiffuse(lightCount, r, g, b); + lightSpecular(lightCount, currentLightSpecular[0], + currentLightSpecular[1], + currentLightSpecular[2]); + lightSpot(lightCount, angle, concentration); + lightFalloff(lightCount, currentLightFalloffConstant, + currentLightFalloffLinear, + currentLightFalloffQuadratic); + lightCount++; } @@ -4546,105 +4164,105 @@ public class PGraphicsOpenGL extends PGraphics { currentLightSpecular[0] = calcR; currentLightSpecular[1] = calcG; currentLightSpecular[2] = calcB; - currentLightSpecular[3] = 1.0f; } - protected void enableLights() { - for (int i = 0; i < lightCount; i++) { - lightEnable(i); - } - } - - protected void disableLights() { - for (int i = 0; i < lightCount; i++) { - lightDisable(i); - } - } - protected void enableLighting() { - if (!lights) { - // Flushing non-lit geometry. - flush(); - + if (!lights) { + flush(); // Flushing non-lit geometry. lights = true; - pgl.enableLighting(); } } protected void disableLighting() { - if (lights) { - // Flushing lit geometry. - flush(); - + if (lights) { + flush(); // Flushing lit geometry. lights = false; - pgl.disableLighting(); } - } - - protected void lightAmbient(int num) { - pgl.setAmbientLight(num, lightDiffuse[num]); - - } - - protected void lightNoAmbient(int num) { - pgl.setAmbientLight(num, zeroLight); - } - - protected void lightNoSpot(int num) { - pgl.setSpotLightCutoff(num, 180); - pgl.setSpotLightExponent(num, 0); - } - - protected void lightDiffuse(int num) { - pgl.setDiffuseLight(num, lightDiffuse[num]); - } - - protected void lightNoDiffuse(int num) { - pgl.setDiffuseLight(num, zeroLight); - } - - protected void lightDirection(int num) { - if (lightType[num] == DIRECTIONAL) { - pgl.setLightDirection(num, lightNormal[num]); - } else { // spotlight - pgl.setSpotLightDirection(num, lightNormal[num]); - } - } - - protected void lightEnable(int num) { - pgl.enableLight(num); - } - - protected void lightDisable(int num) { - pgl.disableLight(num); - } - - protected void lightFalloff(int num) { - pgl.setLightConstantAttenuation(num, lightFalloffConstant[num]); - pgl.setLightLinearAttenuation(num, lightFalloffLinear[num]); - pgl.setLightQuadraticAttenuation(num, lightFalloffQuadratic[num]); - } - - protected void lightPosition(int num) { - pgl.setLightPosition(num, lightPosition[num]); - } - - protected void lightSpecular(int num) { - pgl.setSpecularLight(num, lightSpecular[num]); - } - - protected void lightNoSpecular(int num) { - pgl.setSpecularLight(num, zeroLight); - } - - protected void lightSpotAngle(int num) { - pgl.setSpotLightCutoff(num, lightSpotAngle[num]); - } - - protected void lightSpotConcentration(int num) { - pgl.setSpotLightExponent(num, lightSpotConcentration[num]); } + protected void lightPosition(int num, float x, float y, float z, boolean dir) { + lightPosition[4 * num + 0] = x * modelview.m00 + y * modelview.m01 + z * modelview.m02 + modelview.m03; + lightPosition[4 * num + 1] = x * modelview.m10 + y * modelview.m11 + z * modelview.m12 + modelview.m13; + lightPosition[4 * num + 2] = x * modelview.m20 + y * modelview.m21 + z * modelview.m22 + modelview.m23; + + // Used to inicate if the light is directional or not. + lightPosition[4 * num + 3] = dir ? 1: 0; + } + + protected void lightNormal(int num, float dx, float dy, float dz) { + // Applying normal matrix to the light direction vector, which is the transpose of the inverse of the + // modelview. + float nx = dx * modelviewInv.m00 + dy * modelviewInv.m10 + dz * modelviewInv.m20; + float ny = dx * modelviewInv.m01 + dy * modelviewInv.m11 + dz * modelviewInv.m21; + float nz = dx * modelviewInv.m02 + dy * modelviewInv.m12 + dz * modelviewInv.m22; + + float invn = 1.0f / PApplet.dist(0, 0, 0, nx, ny, nz); + lightNormal[3 * num + 0] = invn * nx; + lightNormal[3 * num + 1] = invn * ny; + lightNormal[3 * num + 2] = invn * nz; + } + + protected void lightAmbient(int num, float r, float g, float b) { + colorCalc(r, g, b); + lightAmbient[3 * num + 0] = calcR; + lightAmbient[3 * num + 1] = calcG; + lightAmbient[3 * num + 2] = calcB; + } + + protected void noLightAmbient(int num) { + lightAmbient[3 * num + 0] = 0; + lightAmbient[3 * num + 1] = 0; + lightAmbient[3 * num + 2] = 0; + } + + protected void lightDiffuse(int num, float r, float g, float b) { + colorCalc(r, g, b); + lightDiffuse[3 * num + 0] = calcR; + lightDiffuse[3 * num + 1] = calcG; + lightDiffuse[3 * num + 2] = calcB; + } + + protected void noLightDiffuse(int num) { + lightDiffuse[3 * num + 0] = 0; + lightDiffuse[3 * num + 1] = 0; + lightDiffuse[3 * num + 2] = 0; + } + + protected void lightSpecular(int num, float r, float g, float b) { + lightSpecular[3 * num + 0] = r; + lightSpecular[3 * num + 1] = g; + lightSpecular[3 * num + 2] = b; + } + + protected void noLightSpecular(int num) { + lightSpecular[3 * num + 0] = 0; + lightSpecular[3 * num + 1] = 0; + lightSpecular[3 * num + 2] = 0; + } + + protected void lightFalloff(int num, float c0, float c1, float c2) { + lightFalloffCoefficients[3 * num + 0] = c0; + lightFalloffCoefficients[3 * num + 1] = c1; + lightFalloffCoefficients[3 * num + 2] = c2; + } + + protected void noLightFalloff(int num) { + lightFalloffCoefficients[3 * num + 0] = 1; + lightFalloffCoefficients[3 * num + 1] = 0; + lightFalloffCoefficients[3 * num + 2] = 0; + } + + protected void lightSpot(int num, float angle, float exponent) { + lightSpotParameters[2 * num + 0] = Math.max(0, PApplet.cos(angle)); + lightSpotParameters[2 * num + 1] = exponent; + } + + protected void noLightSpot(int num) { + lightSpotParameters[2 * num + 0] = 0; + lightSpotParameters[2 * num + 1] = 0; + } + + ////////////////////////////////////////////////////////////// // BACKGROUND @@ -4658,11 +4276,11 @@ public class PGraphicsOpenGL extends PGraphics { tessGeo.reset(); texCache.reset(); - pgl.setClearColor(0, 0, 0, 0); - pgl.clearDepthBuffer(); + pgl.glClearColor(0, 0, 0, 0); + pgl.glClear(PGL.GL_DEPTH_BUFFER_BIT); - pgl.setClearColor(backgroundR, backgroundG, backgroundB, 1); - pgl.clearColorBuffer(); + pgl.glClearColor(backgroundR, backgroundG, backgroundB, 1); + pgl.glClear(PGL.GL_COLOR_BUFFER_BIT); } ////////////////////////////////////////////////////////////// @@ -4671,25 +4289,6 @@ public class PGraphicsOpenGL extends PGraphics { // colorMode() is inherited from PGraphics. - ////////////////////////////////////////////////////////////// - - // COLOR CALC - - // This is the OpenGL complement to the colorCalc() methods. - - /** - * Load the calculated color into a pre-allocated array so that it can be - * quickly passed over to OpenGL. - */ - protected final void calcColorBuffer() { - if (colorFloats == null) { - colorFloats = new float[4]; - } - colorFloats[0] = calcR; - colorFloats[1] = calcG; - colorFloats[2] = calcB; - colorFloats[3] = calcA; - } ////////////////////////////////////////////////////////////// @@ -4804,9 +4403,9 @@ public class PGraphicsOpenGL extends PGraphics { pixelBuffer.rewind(); if (primarySurface) { - pgl.setReadBuffer(PGL.FRONT); + pgl.setReadBuffer(PGL.GL_FRONT); } - pgl.readPixels(pixelBuffer, 0, 0, width, height); + pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer); if (notCurrent) { popFramebuffer(); @@ -5197,7 +4796,7 @@ public class PGraphicsOpenGL extends PGraphics { protected void copyFrameToTexture() { // Make sure that the execution off all the openGL commands is // finished before loading the texture. - pgl.finish(); + pgl.glFinish(); loadTexture(); } @@ -5245,9 +4844,9 @@ public class PGraphicsOpenGL extends PGraphics { getsetBuffer.rewind(); if (primarySurface) { - pgl.setReadBuffer(PGL.FRONT); + pgl.setReadBuffer(PGL.GL_FRONT); } - pgl.readPixels(getsetBuffer, x, height - y - 1, 1, 1); + pgl.glReadPixels(x, height - y - 1, 1, 1, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, getsetBuffer); if (notCurrent) { popFramebuffer(); @@ -5285,10 +4884,11 @@ public class PGraphicsOpenGL extends PGraphics { newbieBuffer.rewind(); if (primarySurface) { - pgl.setReadBuffer(PGL.FRONT); + pgl.setReadBuffer(PGL.GL_FRONT); } - pgl.readPixels(newbieBuffer, x, height - y - h, w, h); + pgl.glReadPixels(x, height - y - h, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, newbieBuffer); + if (notCurrent) { popFramebuffer(); } @@ -5493,66 +5093,67 @@ public class PGraphicsOpenGL extends PGraphics { flush(); blendMode = mode; - pgl.enableBlend(); + pgl.glEnable(PGL.GL_BLEND); if (mode == REPLACE) { - // This is equivalent to disable blending. - if (blendEqSupported) { - pgl.setBlendEquation(PGL.BLEND_EQ_ADD); + if (blendEqSupported) { + pgl.glBlendEquation(PGL.GL_FUNC_ADD); } - pgl.setReplaceBlend(); + pgl.glBlendFunc(PGL.GL_ONE, PGL.GL_ZERO); } else if (mode == BLEND) { if (blendEqSupported) { - pgl.setBlendEquation(PGL.BLEND_EQ_ADD); + pgl.glBlendEquation(PGL.GL_FUNC_ADD); } - pgl.setDefaultBlend(); + pgl.glBlendFunc(PGL.GL_SRC_ALPHA, PGL.GL_ONE_MINUS_SRC_ALPHA); } else if (mode == ADD) { if (blendEqSupported) { - pgl.setBlendEquation(PGL.BLEND_EQ_ADD); + pgl.glBlendEquation(PGL.GL_FUNC_ADD); } - pgl.setAdditiveBlend(); + pgl.glBlendFunc(PGL.GL_SRC_ALPHA, PGL.GL_ONE); } else if (mode == SUBTRACT) { if (blendEqSupported) { - pgl.setBlendEquation(PGL.BLEND_EQ_ADD); + pgl.glBlendEquation(PGL.GL_FUNC_ADD); } - pgl.setSubstractiveBlend(); + pgl.glBlendFunc(PGL.GL_ONE_MINUS_DST_COLOR, PGL.GL_ZERO); } else if (mode == LIGHTEST) { if (blendEqSupported) { - pgl.setBlendEquation(PGL.BLEND_EQ_MAX); - pgl.setLightestBlend(); + pgl.glBlendEquation(PGL.GL_FUNC_MAX); } else { - PGraphics.showWarning("P3D: This blend mode is currently unsupported."); + PGraphics.showWarning("This blend mode is not supported"); + return; } + pgl.glBlendFunc(PGL.GL_SRC_ALPHA, PGL.GL_DST_ALPHA); } else if (mode == DARKEST) { - if (blendEqSupported) { - pgl.setBlendEquation(PGL.BLEND_EQ_MIN); - pgl.setDarkestBlend(); + if (blendEqSupported) { + pgl.glBlendEquation(PGL.GL_FUNC_MIN); } else { - PGraphics.showWarning("P3D: This blend mode is currently unsupported."); - } + PGraphics.showWarning("This blend mode is not supported"); + return; + } + pgl.glBlendFunc(PGL.GL_SRC_ALPHA, PGL.GL_DST_ALPHA); } else if (mode == DIFFERENCE) { if (blendEqSupported) { - pgl.setBlendEquation(PGL.BLEND_EQ_REVERSE_SUBTRACT); - pgl.setDifferenceBlend(); - + pgl.glBlendEquation(PGL.GL_FUNC_REVERSE_SUBTRACT); } else { - PGraphics.showWarning("P3D: This blend mode is currently unsupported."); - } + PGraphics.showWarning("This blend mode is not supported"); + return; + } + pgl.glBlendFunc(PGL.GL_ONE, PGL.GL_ONE); } else if (mode == EXCLUSION) { if (blendEqSupported) { - pgl.setBlendEquation(PGL.BLEND_EQ_ADD); + pgl.glBlendEquation(PGL.GL_FUNC_ADD); } - pgl.setExclussionBlend(); + pgl.glBlendFunc(PGL.GL_ONE_MINUS_DST_COLOR, PGL.GL_ONE_MINUS_SRC_COLOR); } else if (mode == MULTIPLY) { if (blendEqSupported) { - pgl.setBlendEquation(PGL.BLEND_EQ_ADD); + pgl.glBlendEquation(PGL.GL_FUNC_ADD); } - pgl.setMultiplyBlend(); + pgl.glBlendFunc(PGL.GL_DST_COLOR, PGL.GL_SRC_COLOR); } else if (mode == SCREEN) { if (blendEqSupported) { - pgl.setBlendEquation(PGL.BLEND_EQ_ADD); + pgl.glBlendEquation(PGL.GL_FUNC_ADD); } - pgl.setScreenBlend(); + pgl.glBlendFunc(PGL.GL_ONE_MINUS_DST_COLOR, PGL.GL_ONE); } // HARD_LIGHT, SOFT_LIGHT, OVERLAY, DODGE, BURN modes cannot be implemented // in fixed-function pipeline because they require conditional blending and @@ -5562,11 +5163,11 @@ public class PGraphicsOpenGL extends PGraphics { protected void setDefaultBlend() { blendMode = BLEND; - pgl.enableBlend(); + pgl.glEnable(PGL.GL_BLEND); if (blendEqSupported) { - pgl.setBlendEquation(PGL.BLEND_EQ_ADD); + pgl.glBlendEquation(PGL.GL_FUNC_ADD); } - pgl.setDefaultBlend(); + pgl.glBlendFunc(PGL.GL_SRC_ALPHA, PGL.GL_ONE_MINUS_SRC_ALPHA); } @@ -5669,7 +5270,7 @@ public class PGraphicsOpenGL extends PGraphics { if (params == null) { params = PTexture.newParameters(); img.setParams(pg, params); - } + } PTexture tex = new PTexture(img.parent, img.width, img.height, params); img.loadPixels(); if (img.pixels != null) tex.set(img.pixels); @@ -5724,21 +5325,21 @@ public class PGraphicsOpenGL extends PGraphics { /** Utility function to render texture without blend. */ protected void drawTexture(int target, int id, int tw, int th, int[] crop, int x, int y, int w, int h) { pgl.enableTexturing(target); - pgl.bindTexture(target, id); + pgl.glBindTexture(target, id); int savedBlendMode = blendMode; blendMode(REPLACE); // The texels of the texture replace the color of wherever is on the screen. - pgl.setTexEnvironmentMode(PGL.REPLACE); +// texEnvMode = REPLACE; drawTexture(tw, th, crop, x, y, w, h); - // Returning to the default texture environment mode, GL_MODULATE. This allows tinting a texture - // with the current fragment color. - pgl.setTexEnvironmentMode(PGL.MODULATE); + // Returning to the default texture environment mode, MODULATE. + // This allows tinting a texture with the current fragment color. +// texEnvMode = MODULATE; - pgl.unbindTexture(target); + pgl.glBindTexture(target, 0); pgl.disableTexturing(target); blendMode(savedBlendMode); @@ -5759,8 +5360,11 @@ public class PGraphicsOpenGL extends PGraphics { protected void drawTexture(int tw, int th, int[] crop, int x, int y, int w, int h) { flush(); - pgl.disableDepthMask(); + pgl.glDepthMask(false); + // TODO: finish this! + /* + pgl.setProjectionMode(); pgl.pushMatrix(); pgl.loadIdentity(); @@ -5789,6 +5393,8 @@ public class PGraphicsOpenGL extends PGraphics { if (hintEnabled(ENABLE_DEPTH_MASK)) { pgl.enableDepthMask(); } + + */ } @@ -5819,59 +5425,12 @@ public class PGraphicsOpenGL extends PGraphics { protected void copyToTexture(PTexture tex, IntBuffer buffer, int x, int y, int w, int h) { buffer.rewind(); pgl.enableTexturing(tex.glTarget); - pgl.bindTexture(tex.glTarget, tex.glID); - pgl.copyTexSubImage(buffer, tex.glTarget, 0, x, y, w, h); - pgl.bindTexture(tex.glTarget, 0); + pgl.glBindTexture(tex.glTarget, tex.glID); + pgl.glTexSubImage2D(tex.glTarget, 0, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, buffer); + pgl.glBindTexture(tex.glTarget, 0); pgl.disableTexturing(tex.glTarget); } - ////////////////////////////////////////////////////////////// - - // OPENGL ROUTINES - - protected void setSurfaceParams() { - // The default shade model is GL_SMOOTH, but we set - // here just in case... - pgl.setShadeModel(PGL.SMOOTH); - - - // The ambient and diffuse components for each vertex are taken - // from the glColor/color buffer setting: - pgl.enableColorMaterial(); - - // For a quick overview of how the lighting model works in OpenGL - // see this page: - // http://www.sjbaker.org/steve/omniv/opengl_lighting.html - - // Some normal related settings: - pgl.enableNormalization(); - pgl.enableRescaleNormals(); - - // Light model defaults: - // The default opengl ambient light is (0.2, 0.2, 0.2), so - // here we set our own default value. - pgl.setTwoSidedLightModel(); - pgl.setDefaultAmbientLight(baseLight); - } - - protected void saveGLMatrices() { - pgl.setProjectionMode(); - pgl.pushMatrix(); - pgl.setModelviewMode(); - pgl.pushMatrix(); - } - - protected void restoreGLMatrices() { - pgl.setProjectionMode(); - pgl.popMatrix(); - pgl.setModelviewMode(); - pgl.popMatrix(); - } - - - protected void setDefNormals(float nx, float ny, float nz) { - pgl.setNormal(nx, ny, nz); - } ////////////////////////////////////////////////////////////// @@ -5954,154 +5513,617 @@ public class PGraphicsOpenGL extends PGraphics { } protected void getGLParameters() { - OPENGL_VENDOR = pgl.getVendorString(); - OPENGL_RENDERER = pgl.getRendererString(); - OPENGL_VERSION = pgl.getVersionString(); - OPENGL_EXTENSIONS = pgl.getExtensionsString(); - - npotTexSupported = pgl.isNpotTexSupported(); - mipmapGeneration = pgl.hasMipmapGeneration(); - matrixGetSupported = pgl.isMatrixGetSupported(); - texenvCrossbarSupported = pgl.isTexenvCrossbarSupported(); - vboSupported = pgl.isVboSupported(); - fboSupported = pgl.isFboSupported(); - fboMultisampleSupported = pgl.isFboMultisampleSupported(); - blendEqSupported = pgl.isBlendEqSupported(); + OPENGL_VENDOR = pgl.glGetString(PGL.GL_VENDOR); + OPENGL_RENDERER = pgl.glGetString(PGL.GL_RENDERER); + OPENGL_VERSION = pgl.glGetString(PGL.GL_VERSION); + OPENGL_EXTENSIONS = pgl.glGetString(PGL.GL_EXTENSIONS); - maxTextureSize = pgl.getMaxTexureSize(); - maxLineWidth = pgl.getMaxAliasedLineWidth(); - maxPointSize = pgl.getMaxAliasedPointSize(); - maxTextureUnits = pgl.getMaxTextureUnits(); + npotTexSupported = -1 < OPENGL_EXTENSIONS.indexOf("texture_non_power_of_two"); + mipmapGeneration = -1 < OPENGL_EXTENSIONS.indexOf("generate_mipmap"); + vboSupported = -1 < OPENGL_EXTENSIONS.indexOf("vertex_buffer_object"); + fboSupported = -1 < OPENGL_EXTENSIONS.indexOf("framebuffer_object"); + fboMultisampleSupported = -1 < OPENGL_EXTENSIONS.indexOf("framebuffer_multisample"); + + try { + pgl.glBlendEquation(PGL.GL_FUNC_ADD); + blendEqSupported = true; + } catch (UnsupportedOperationException e) { + blendEqSupported = false; + } + + int temp[] = new int[2]; + + pgl.glGetIntegerv(PGL.GL_MAX_TEXTURE_SIZE, temp, 0); + maxTextureSize = temp[0]; + + pgl.glGetIntegerv(PGL.GL_ALIASED_LINE_WIDTH_RANGE, temp, 0); + maxLineWidth = temp[1]; + + pgl.glGetIntegerv(PGL.GL_ALIASED_POINT_SIZE_RANGE, temp, 0); + maxPointSize = temp[1]; glParamsRead = true; } - - + ////////////////////////////////////////////////////////////// - // UTILITY INNER CLASSES - - /** - * This class encapsulates the drawing state in Processing. - */ - protected class DrawingState { - int tMode0; - boolean auto0; - boolean stroke0; - int cMode0; - boolean merge0; - float specularR0, specularG0, specularB0; - float ambientR0, ambientG0, ambientB0; - boolean fill0; - float fillR0, fillG0, fillB0, fillA0; - int fillRi0, fillGi0, fillBi0, fillAi0; - int fillColor0; - boolean fillAlpha0; - boolean tint0; - float tintR0, tintG0, tintB0, tintA0; - int tintRi0, tintGi0, tintBi0, tintAi0; - int tintColor0; - boolean tintAlpha0; - float shininess0; - - DrawingState() {} - - void save() { - tMode0 = textureMode; - auto0 = autoNormal; - stroke0 = stroke; - cMode0 = colorMode; - //merge0 = mergeRecShapes; - - // Saving current colors. - specularR0 = specularR; - specularG0 = specularG; - specularB0 = specularB; - - ambientR0 = ambientR; - ambientG0 = ambientG; - ambientB0 = ambientB; - - fill0 = fill; - fillR0 = fillR; - fillG0 = fillG; - fillB0 = fillB; - fillA0 = fillA; - fillRi0 = fillRi; - fillGi0 = fillGi; - fillBi0 = fillBi; - fillAi0 = fillAi; - fillColor0 = fillColor; - fillAlpha0 = fillAlpha; - - tint0 = tint; - tintR0 = tintR; - tintG0 = tintG; - tintB0 = tintB; - tintA0 = tintA; - tintRi0 = tintRi; - tintGi0 = tintGi; - tintBi0 = tintBi; - tintAi0 = tintAi; - tintColor0 = tintColor; - tintAlpha0 = tintAlpha; - - shininess0 = shininess; + // SHADER HANDLING + + public PShader loadShader(String vertFilename, String fragFilename, int kind) { + if (kind == FILL_SHADER_SIMPLE) { + return new FillShaderSimple(parent, vertFilename, fragFilename); + } else if (kind == FILL_SHADER_LIT) { + return new FillShaderLit(parent, vertFilename, fragFilename); + } else if (kind == FILL_SHADER_TEX) { + return new FillShaderTex(parent, vertFilename, fragFilename); + } else if (kind == FILL_SHADER_FULL) { + return new FillShaderFull(parent, vertFilename, fragFilename); + } else if (kind == LINE_SHADER) { + return new LineShader(parent, vertFilename, fragFilename); + } else if (kind == POINT_SHADER) { + return new PointShader(parent, vertFilename, fragFilename); + } else { + PGraphics.showWarning("Wrong shader type"); + return null; } + } - void restore() { - textureMode = tMode0; - colorMode = cMode0; - autoNormal = auto0; - stroke = stroke0; - //mergeRecShapes = merge0; - - // Restore colors - calcR = specularR0; - calcG = specularG0; - calcB = specularB0; - specularFromCalc(); - - calcR = ambientR0; - calcG = ambientG0; - calcB = ambientB0; - ambientFromCalc(); - - if (!fill0) { - noFill(); - } else { - calcR = fillR0; - calcG = fillG0; - calcB = fillB0; - calcA = fillA0; - calcRi = fillRi0; - calcGi = fillGi0; - calcBi = fillBi0; - calcAi = fillAi0; - calcColor = fillColor0; - calcAlpha = fillAlpha0; - fillFromCalc(); - } - - if (!tint0) { - noTint(); - } else { - calcR = tintR0; - calcG = tintG0; - calcB = tintB0; - calcA = tintA0; - calcRi = tintRi0; - calcGi = tintGi0; - calcBi = tintBi0; - calcAi = tintAi0; - calcColor = tintColor0; - calcAlpha = tintAlpha0; - tintFromCalc(); - } - - shininess(shininess0); + public void setShader(PShader shader, int kind) { + if (kind == FILL_SHADER_SIMPLE) { + fillShaderSimple = (FillShaderSimple) shader; + } else if (kind == FILL_SHADER_LIT) { + fillShaderLit = (FillShaderLit) shader; + } else if (kind == FILL_SHADER_TEX) { + fillShaderTex = (FillShaderTex) shader; + } else if (kind == FILL_SHADER_FULL) { + fillShaderFull = (FillShaderFull) shader; + } else if (kind == LINE_SHADER) { + lineShader = (LineShader) shader; + } else if (kind == POINT_SHADER) { + pointShader = (PointShader) shader; + } else { + PGraphics.showWarning("Wrong shader type"); } } + + public void resetShader(int kind) { + if (kind == FILL_SHADER_SIMPLE) { + if (defFillShaderSimple == null) { + defFillShaderSimple = new FillShaderSimple(parent, defFillShaderVertSimpleURL, defFillShaderFragNoTexURL); + } + fillShaderSimple = defFillShaderSimple; + } else if (kind == FILL_SHADER_LIT) { + if (defFillShaderLit == null) { + defFillShaderLit = new FillShaderLit(parent, defFillShaderVertLitURL, defFillShaderFragNoTexURL); + } + fillShaderLit = defFillShaderLit; + } else if (kind == FILL_SHADER_TEX) { + if (defFillShaderTex == null) { + defFillShaderTex = new FillShaderTex(parent, defFillShaderVertTexURL, defFillShaderFragTexURL); + } + fillShaderTex = defFillShaderTex; + } else if (kind == FILL_SHADER_FULL) { + if (defFillShaderFull == null) { + defFillShaderFull = new FillShaderFull(parent, defFillShaderVertFullURL, defFillShaderFragTexURL); + } + fillShaderFull = defFillShaderFull; + } else if (kind == LINE_SHADER) { + if (defLineShader == null) { + defLineShader = new LineShader(parent, defLineShaderVertURL, defLineShaderFragURL); + } + lineShader = defLineShader; + } else if (kind == POINT_SHADER) { + if (defPointShader == null) { + defPointShader = new PointShader(parent, defPointShaderVertURL, defPointShaderFragURL); + } + pointShader = defPointShader; + } else { + PGraphics.showWarning("Wrong shader type"); + } + } + + protected FillShader getFillShader(boolean lit, boolean tex) { + FillShader shader; + if (lit) { + if (tex) { + if (fillShaderFull == null) { + if (defFillShaderFull == null) { + defFillShaderFull = new FillShaderFull(parent, defFillShaderVertFullURL, defFillShaderFragTexURL); + } + fillShaderFull = defFillShaderFull; + } + shader = fillShaderFull; + } else { + if (defFillShaderLit == null) { + if (defFillShaderLit == null) { + defFillShaderLit = new FillShaderLit(parent, defFillShaderVertLitURL, defFillShaderFragNoTexURL); + } + fillShaderLit = defFillShaderLit; + } + shader = fillShaderLit; + } + } else { + if (tex) { + if (fillShaderTex == null) { + if (defFillShaderTex == null) { + defFillShaderTex = new FillShaderTex(parent, defFillShaderVertTexURL, defFillShaderFragTexURL); + } + fillShaderTex = defFillShaderTex; + } + shader = fillShaderTex; + } else { + if (fillShaderSimple == null) { + if (defFillShaderSimple == null) { + defFillShaderSimple = new FillShaderSimple(parent, defFillShaderVertSimpleURL, defFillShaderFragNoTexURL); + } + fillShaderSimple = defFillShaderSimple; + } + shader = fillShaderSimple; + } + } + shader.loadAttributes(); + shader.loadUniforms(); + return shader; + } + + protected LineShader getLineShader() { + if (lineShader == null) { + if (defLineShader == null) { + defLineShader = new LineShader(parent, defLineShaderVertURL, defLineShaderFragURL); + } + lineShader = defLineShader; + } + lineShader.loadAttributes(); + lineShader.loadUniforms(); + return lineShader; + } + + protected PointShader getPointShader() { + if (pointShader == null) { + if (defPointShader == null) { + defPointShader = new PointShader(parent, defPointShaderVertURL, defPointShaderFragURL); + } + pointShader = defPointShader; + } + pointShader.loadAttributes(); + pointShader.loadUniforms(); + return pointShader; + } + + protected class FillShader extends PShader { + public FillShader(PApplet parent, String vertFilename, String fragFilename) { + super(parent, vertFilename, fragFilename); + } + + public FillShader(PApplet parent, URL vertURL, URL fragURL) { + super(parent, vertURL, fragURL); + } + + public void loadAttributes() { } + public void loadUniforms() { } + + public void setAttribute(int loc, int vboId, int size, int type, boolean normalized, int stride, int offset) { + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, vboId); + pgl.glVertexAttribPointer(loc, size, type, normalized, stride, offset); + } + + public void setVertexAttribute(int vboId, int size, int type, int stride, int offset) { } + public void setColorAttribute(int vboId, int size, int type, int stride, int offset) { } + public void setNormalAttribute(int vboId, int size, int type, int stride, int offset) { } + public void setAmbientAttribute(int vboId, int size, int type, int stride, int offset) { } + public void setSpecularAttribute(int vboId, int size, int type, int stride, int offset) { } + public void setEmissiveAttribute(int vboId, int size, int type, int stride, int offset) { } + public void setShininessAttribute(int vboId, int size, int type, int stride, int offset) { } + public void setTexCoordAttribute(int vboId, int size, int type, int stride, int offset) { } + } + + protected class FillShaderSimple extends FillShader { + protected int projmodelviewMatrixLoc; + + protected int inVertexLoc; + protected int inColorLoc; + + public FillShaderSimple(PApplet parent, String vertFilename, String fragFilename) { + super(parent, vertFilename, fragFilename); + } + + public FillShaderSimple(PApplet parent, URL vertURL, URL fragURL) { + super(parent, vertURL, fragURL); + } + + public void loadAttributes() { + inVertexLoc = getAttribLocation("inVertex"); + inColorLoc = getAttribLocation("inColor"); + } + + public void loadUniforms() { + projmodelviewMatrixLoc = getUniformLocation("projmodelviewMatrix"); + } + + public void setVertexAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inVertexLoc, vboId, size, type, false, stride, offset); + } + + public void setColorAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inColorLoc, vboId, size, type, true, stride, offset); + } + + public void start() { + super.start(); + + pgl.glEnableVertexAttribArray(inVertexLoc); + pgl.glEnableVertexAttribArray(inColorLoc); + + updateGLProjmodelview(); + set4x4MatUniform(projmodelviewMatrixLoc, glProjmodelview); + } + + public void stop() { + pgl.glDisableVertexAttribArray(inVertexLoc); + pgl.glDisableVertexAttribArray(inColorLoc); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); + + super.stop(); + } + } + + protected class FillShaderLit extends FillShader { + protected int projmodelviewMatrixLoc; + protected int modelviewMatrixLoc; + protected int normalMatrixLoc; + + protected int lightCountLoc; + protected int lightPositionLoc; + protected int lightNormalLoc; + protected int lightAmbientLoc; + protected int lightDiffuseLoc; + protected int lightSpecularLoc; + protected int lightFalloffCoefficientsLoc; + protected int lightSpotParametersLoc; + + protected int inVertexLoc; + protected int inColorLoc; + protected int inNormalLoc; + + protected int inAmbientLoc; + protected int inSpecularLoc; + protected int inEmissiveLoc; + protected int inShineLoc; + + public FillShaderLit(PApplet parent, String vertFilename, String fragFilename) { + super(parent, vertFilename, fragFilename); + } + + public FillShaderLit(PApplet parent, URL vertURL, URL fragURL) { + super(parent, vertURL, fragURL); + } + + public void loadAttributes() { + inVertexLoc = getAttribLocation("inVertex"); + inColorLoc = getAttribLocation("inColor"); + + inNormalLoc = getAttribLocation("inNormal"); + + inAmbientLoc = getAttribLocation("inAmbient"); + inSpecularLoc = getAttribLocation("inSpecular"); + inEmissiveLoc = getAttribLocation("inEmissive"); + inShineLoc = getAttribLocation("inShine"); + } + + public void loadUniforms() { + projmodelviewMatrixLoc = getUniformLocation("projmodelviewMatrix"); + modelviewMatrixLoc = getUniformLocation("modelviewMatrix"); + normalMatrixLoc = getUniformLocation("normalMatrix"); + + lightCountLoc = getUniformLocation("lightCount"); + lightPositionLoc = getUniformLocation("lightPosition"); + lightNormalLoc = getUniformLocation("lightNormal"); + lightAmbientLoc = getUniformLocation("lightAmbient"); + lightDiffuseLoc = getUniformLocation("lightDiffuse"); + lightSpecularLoc = getUniformLocation("lightSpecular"); + lightFalloffCoefficientsLoc = getUniformLocation("lightFalloffCoefficients"); + lightSpotParametersLoc = getUniformLocation("lightSpotParameters"); + } + + public void setVertexAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inVertexLoc, vboId, size, type, false, stride, offset); + } + + public void setColorAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inColorLoc, vboId, size, type, true, stride, offset); + } + + public void setNormalAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inNormalLoc, vboId, size, type, false, stride, offset); + } + + public void setAmbientAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inAmbientLoc, vboId, size, type, true, stride, offset); + } + + public void setSpecularAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inSpecularLoc, vboId, size, type, true, stride, offset); + } + + public void setEmissiveAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inEmissiveLoc, vboId, size, type, true, stride, offset); + } + + public void setShininessAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inShineLoc, vboId, size, type, false, stride, offset); + } + + public void start() { + super.start(); + + pgl.glEnableVertexAttribArray(inVertexLoc); + pgl.glEnableVertexAttribArray(inColorLoc); + pgl.glEnableVertexAttribArray(inNormalLoc); + + pgl.glEnableVertexAttribArray(inAmbientLoc); + pgl.glEnableVertexAttribArray(inSpecularLoc); + pgl.glEnableVertexAttribArray(inEmissiveLoc); + pgl.glEnableVertexAttribArray(inShineLoc); + + updateGLProjmodelview(); + set4x4MatUniform(projmodelviewMatrixLoc, glProjmodelview); + + updateGLModelview(); + set4x4MatUniform(modelviewMatrixLoc, glModelview); + + updateGLNormal(); + set3x3MatUniform(normalMatrixLoc, glNormal); + + setIntUniform(lightCountLoc, lightCount); + set4FloatVecUniform(lightPositionLoc, lightPosition); + set3FloatVecUniform(lightNormalLoc, lightNormal); + set3FloatVecUniform(lightAmbientLoc, lightAmbient); + set3FloatVecUniform(lightDiffuseLoc, lightDiffuse); + set3FloatVecUniform(lightSpecularLoc, lightSpecular); + set3FloatVecUniform(lightFalloffCoefficientsLoc, lightFalloffCoefficients); + set2FloatVecUniform(lightSpotParametersLoc, lightSpotParameters); + } + + public void stop() { + pgl.glDisableVertexAttribArray(inVertexLoc); + pgl.glDisableVertexAttribArray(inColorLoc); + pgl.glDisableVertexAttribArray(inNormalLoc); + + pgl.glDisableVertexAttribArray(inAmbientLoc); + pgl.glDisableVertexAttribArray(inSpecularLoc); + pgl.glDisableVertexAttribArray(inEmissiveLoc); + pgl.glDisableVertexAttribArray(inShineLoc); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); + + super.stop(); + } + } + + protected class FillShaderTex extends FillShaderSimple { + protected int inTexcoordLoc; + + public FillShaderTex(PApplet parent, String vertFilename, String fragFilename) { + super(parent, vertFilename, fragFilename); + } + + public FillShaderTex(PApplet parent, URL vertURL, URL fragURL) { + super(parent, vertURL, fragURL); + } + + public void loadAttributes() { + super.loadAttributes(); + + inTexcoordLoc = getAttribLocation("inTexcoord"); + } + + public void setTexCoordAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inTexcoordLoc, vboId, size, type, false, stride, offset); + } + + public void start() { + super.start(); + + pgl.glEnableVertexAttribArray(inTexcoordLoc); + } + + public void stop() { + pgl.glDisableVertexAttribArray(inTexcoordLoc); + + super.stop(); + } + } + + protected class FillShaderFull extends FillShaderLit { + protected int inTexcoordLoc; + + public FillShaderFull(PApplet parent, String vertFilename, String fragFilename) { + super(parent, vertFilename, fragFilename); + } + + public FillShaderFull(PApplet parent, URL vertURL, URL fragURL) { + super(parent, vertURL, fragURL); + } + + public void loadAttributes() { + super.loadAttributes(); + + inTexcoordLoc = getAttribLocation("inTexcoord"); + } + + public void setTexCoordAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inTexcoordLoc, vboId, size, type, false, stride, offset); + } + + public void start() { + super.start(); + + pgl.glEnableVertexAttribArray(inTexcoordLoc); + } + + public void stop() { + pgl.glDisableVertexAttribArray(inTexcoordLoc); + + super.stop(); + } + } + + protected class LineShader extends PShader { + protected int projectionMatrixLoc; + protected int modelviewMatrixLoc; + + protected int viewportLoc; + protected int perspectiveLoc; + + protected int inVertexLoc; + protected int inColorLoc; + protected int inDirWidthLoc; + + public LineShader(PApplet parent, String vertFilename, String fragFilename) { + super(parent, vertFilename, fragFilename); + } + + public LineShader(PApplet parent, URL vertURL, URL fragURL) { + super(parent, vertURL, fragURL); + } + + public void loadAttributes() { + inVertexLoc = getAttribLocation("inVertex"); + inColorLoc = getAttribLocation("inColor"); + inDirWidthLoc = getAttribLocation("inDirWidth"); + } + + public void loadUniforms() { + projectionMatrixLoc = getUniformLocation("projectionMatrix"); + modelviewMatrixLoc = getUniformLocation("modelviewMatrix"); + + viewportLoc = getUniformLocation("viewport"); + perspectiveLoc = getUniformLocation("perspective"); + } + + public void setAttribute(int loc, int vboId, int size, int type, boolean normalized, int stride, int offset) { + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, vboId); + pgl.glVertexAttribPointer(loc, size, type, normalized, stride, offset); + } + + public void setVertexAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inVertexLoc, vboId, size, type, false, stride, offset); + } + + public void setColorAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inColorLoc, vboId, size, type, true, stride, offset); + } + + public void setDirWidthAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inDirWidthLoc, vboId, size, type, false, stride, offset); + } + + public void start() { + super.start(); + + pgl.glEnableVertexAttribArray(inVertexLoc); + pgl.glEnableVertexAttribArray(inColorLoc); + pgl.glEnableVertexAttribArray(inDirWidthLoc); + + updateGLProjection(); + set4x4MatUniform(projectionMatrixLoc, glProjection); + + updateGLModelview(); + set4x4MatUniform(modelviewMatrixLoc, glModelview); + + set4FloatUniform(viewportLoc, viewport[0], viewport[1], viewport[2], viewport[3]); + + if (hints[ENABLE_PERSPECTIVE_CORRECTED_LINES]) { + setIntUniform(perspectiveLoc, 1); + } else { + setIntUniform(perspectiveLoc, 0); + } + } + + public void stop() { + pgl.glDisableVertexAttribArray(inVertexLoc); + pgl.glDisableVertexAttribArray(inColorLoc); + pgl.glDisableVertexAttribArray(inDirWidthLoc); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); + + super.stop(); + } + } + + protected class PointShader extends PShader { + protected int projectionMatrixLoc; + protected int modelviewMatrixLoc; + + protected int inVertexLoc; + protected int inColorLoc; + protected int inSizeLoc; + + public PointShader(PApplet parent, String vertFilename, String fragFilename) { + super(parent, vertFilename, fragFilename); + } + + public PointShader(PApplet parent, URL vertURL, URL fragURL) { + super(parent, vertURL, fragURL); + } + + public void loadAttributes() { + inVertexLoc = getAttribLocation("inVertex"); + inColorLoc = getAttribLocation("inColor"); + inSizeLoc = getAttribLocation("inSize"); + } + + public void loadUniforms() { + projectionMatrixLoc = getUniformLocation("projectionMatrix"); + modelviewMatrixLoc = getUniformLocation("modelviewMatrix"); + } + + public void setAttribute(int loc, int vboId, int size, int type, boolean normalized, int stride, int offset) { + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, vboId); + pgl.glVertexAttribPointer(loc, size, type, normalized, stride, offset); + } + + public void setVertexAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inVertexLoc, vboId, size, type, false, stride, offset); + } + + public void setColorAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inColorLoc, vboId, size, type, true, stride, offset); + } + + public void setSizeAttribute(int vboId, int size, int type, int stride, int offset) { + setAttribute(inSizeLoc, vboId, size, type, false, stride, offset); + } + + public void start() { + super.start(); + + pgl.glEnableVertexAttribArray(inVertexLoc); + pgl.glEnableVertexAttribArray(inColorLoc); + pgl.glEnableVertexAttribArray(inSizeLoc); + + updateGLProjection(); + set4x4MatUniform(projectionMatrixLoc, glProjection); + + updateGLModelview(); + set4x4MatUniform(modelviewMatrixLoc, glModelview); + } + + public void stop() { + pgl.glDisableVertexAttribArray(inVertexLoc); + pgl.glDisableVertexAttribArray(inColorLoc); + pgl.glDisableVertexAttribArray(inSizeLoc); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); + + super.stop(); + } + } + + ////////////////////////////////////////////////////////////// + + // Input (raw) and Tessellated geometry, tessellator. public InGeometry newInGeometry(int mode) { return new InGeometry(mode); @@ -6113,14 +6135,17 @@ public class PGraphicsOpenGL extends PGraphics { protected TexCache newTexCache() { return new TexCache(); - } + } + // Holds an array of textures and the range of vertex + // indices each texture applies to. public class TexCache { - int count; - PImage[] textures; - int[] firstIndex; - int[] lastIndex; - boolean hasTexture; + protected int count; + protected PImage[] textures; + protected int[] firstIndex; + protected int[] lastIndex; + protected boolean hasTexture; + protected PTexture tex0; public TexCache() { allocate(); @@ -6146,6 +6171,55 @@ public class PGraphicsOpenGL extends PGraphics { lastIndex = null; } + public void beginRender() { + tex0 = null; + } + + public PTexture getTexture(int i) { + PImage img = textures[i]; + PTexture tex = null; + + if (img != null) { + tex = pg.getTexture(img); + if (tex != null) { + tex.bind(); + tex0 = tex; + } + } + if (tex == null && tex0 != null) { + tex0.unbind(); + pgl.disableTexturing(tex0.glTarget); + } + + return tex; + } + + public void endRender() { + if (hasTexture) { + // Unbinding all the textures in the cache. + for (int i = 0; i < count; i++) { + PImage img = textures[i]; + if (img != null) { + PTexture tex = pg.getTexture(img); + if (tex != null) { + tex.unbind(); + } + } + } + // Disabling texturing for each of the targets used + // by textures in the cache. + for (int i = 0; i < count; i++) { + PImage img = textures[i]; + if (img != null) { + PTexture tex = pg.getTexture(img); + if (tex != null) { + pgl.disableTexturing(tex.glTarget); + } + } + } + } + } + public void addTexture(PImage img, int first, int last) { textureCheck(); @@ -6192,6 +6266,8 @@ public class PGraphicsOpenGL extends PGraphics { } } + // Holds the input vertices: xyz coordinates, fill/tint color, + // normal, texture coordinates and stroke color and weight. public class InGeometry { int renderMode; public int vertexCount; @@ -6211,13 +6287,20 @@ public class PGraphicsOpenGL extends PGraphics { public int[] codes; public float[] vertices; - public float[] colors; + public int[] colors; public float[] normals; public float[] texcoords; - public float[] strokes; + public int[] scolors; + public float[] sweights; + + // Material properties + public int[] ambient; + public int[] specular; + public int[] emissive; + public float[] shininess; public int[][] edges; - + // For later, to be used by libraries... //public float[][] mtexcoords; //public float[][] attributes; @@ -6235,22 +6318,36 @@ public class PGraphicsOpenGL extends PGraphics { public void allocate() { codes = new int[PGL.DEFAULT_IN_VERTICES]; vertices = new float[3 * PGL.DEFAULT_IN_VERTICES]; - colors = new float[4 * PGL.DEFAULT_IN_VERTICES]; + colors = new int[PGL.DEFAULT_IN_VERTICES]; normals = new float[3 * PGL.DEFAULT_IN_VERTICES]; texcoords = new float[2 * PGL.DEFAULT_IN_VERTICES]; - strokes = new float[5 * PGL.DEFAULT_IN_VERTICES]; + scolors = new int[PGL.DEFAULT_IN_VERTICES]; + sweights = new float[PGL.DEFAULT_IN_VERTICES]; + ambient = new int[PGL.DEFAULT_IN_VERTICES]; + specular = new int[PGL.DEFAULT_IN_VERTICES]; + emissive = new int[PGL.DEFAULT_IN_VERTICES]; + shininess = new float[PGL.DEFAULT_IN_VERTICES]; edges = new int[PGL.DEFAULT_IN_EDGES][3]; reset(); } public void trim() { - if (vertexCount < vertices.length / 3) { + if (0 < vertexCount && vertexCount < vertices.length / 3) { trimVertices(); trimColors(); trimNormals(); trimTexcoords(); + trimStrokeColors(); + trimStrokeWeights(); + trimAmbient(); + trimSpecular(); + trimEmissive(); + trimShininess(); + } + + if (0 < edgeCount && edgeCount < edges.length) { trimEdges(); - } + } } public void dispose() { @@ -6259,7 +6356,12 @@ public class PGraphicsOpenGL extends PGraphics { colors = null; normals = null; texcoords = null; - strokes = null; + scolors = null; + scolors = null; + ambient = null; + specular = null; + emissive = null; + shininess = null; edges = null; } @@ -6290,54 +6392,43 @@ public class PGraphicsOpenGL extends PGraphics { public boolean isFull() { return PGL.MAX_TESS_VERTICES <= vertexCount; } - - public int addVertex(float[] vertex, float[] color, float[] normal, float[] texcoord, float[] stroke, int code) { - vertexCheck(); - codes[vertexCount] = code; - - PApplet.arrayCopy(vertex, 0, vertices, 3 * vertexCount, 3); - PApplet.arrayCopy(color, 0, colors, 4 * vertexCount, 4); - PApplet.arrayCopy(normal, 0, normals, 3 * vertexCount, 3); - PApplet.arrayCopy(texcoord, 0, texcoords, 2 * vertexCount, 2); - PApplet.arrayCopy(stroke, 0, strokes, 5 * vertexCount, 5); - - lastVertex = vertexCount; - vertexCount++; - - return lastVertex; - } public int addVertex(float x, float y, - float r, float g, float b, float a, + int fcolor, float u, float v, - float sr, float sg, float sb, float sa, float sw, + int scolor, float sweight, + int am, int sp, int em, float shine, int code) { return addVertex(x, y, 0, - r, g, b, a, + fcolor, 0, 0, 1, u, v, - sr, sg, sb, sa, sw, + scolor, sweight, + am, sp, em, shine, code); } public int addVertex(float x, float y, - float r, float g, float b, float a, - float sr, float sg, float sb, float sa, float sw, + int fcolor, + int scolor, float sweight, + int am, int sp, int em, float shine, int code) { return addVertex(x, y, 0, - r, g, b, a, + fcolor, 0, 0, 1, 0, 0, - sr, sg, sb, sa, sw, + scolor, sweight, + am, sp, em, shine, code); } public int addVertex(float x, float y, float z, - float r, float g, float b, float a, + int fcolor, float nx, float ny, float nz, float u, float v, - float sr, float sg, float sb, float sa, float sw, + int scolor, float sweight, + int am, int sp, int em, float shine, int code) { vertexCheck(); int index; @@ -6349,27 +6440,24 @@ public class PGraphicsOpenGL extends PGraphics { vertices[index++] = y; vertices[index ] = z; - index = 4 * vertexCount; - colors[index++] = r; - colors[index++] = g; - colors[index++] = b; - colors[index ] = a; - + colors[vertexCount] = javaToNativeARGB(fcolor); + index = 3 * vertexCount; normals[index++] = nx; normals[index++] = ny; - normals[index ] = ny; + normals[index ] = nz; index = 2 * vertexCount; texcoords[index++] = u; texcoords[index ] = v; - index = 5 * vertexCount; - strokes[index++] = sr; - strokes[index++] = sg; - strokes[index++] = sb; - strokes[index++] = sa; - strokes[index ] = sw; + scolors[vertexCount] = javaToNativeARGB(scolor); + sweights[vertexCount] = sweight; + + ambient[vertexCount] = javaToNativeARGB(am); + specular[vertexCount] = javaToNativeARGB(sp); + emissive[vertexCount] = javaToNativeARGB(em); + shininess[vertexCount] = shine; lastVertex = vertexCount; vertexCount++; @@ -6377,6 +6465,16 @@ public class PGraphicsOpenGL extends PGraphics { return lastVertex; } + public int javaToNativeARGB(int color) { + if (BIG_ENDIAN) { + return ((color >> 24) & 0xff) | ((color << 8) & 0xffffff00); + } else { + return (color & 0xff000000) + | ((color << 16) & 0xff0000) | (color & 0xff00) + | ((color >> 16) & 0xff); + } + } + public void vertexCheck() { if (vertexCount == vertices.length / 3) { int newSize = vertexCount << 1; @@ -6386,7 +6484,12 @@ public class PGraphicsOpenGL extends PGraphics { expandColors(newSize); expandNormals(newSize); expandTexcoords(newSize); - expandStrokes(newSize); + expandStrokeColors(newSize); + expandStrokeWeights(newSize); + expandAmbient(newSize); + expandSpecular(newSize); + expandEmissive(newSize); + expandShininess(newSize); } } @@ -6416,9 +6519,11 @@ public class PGraphicsOpenGL extends PGraphics { 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; + // n = v10 x v12 (so the normal points out following the + // clockwise direction along the vertices of the triangle). + float nx = v10y * v12z - v12y * v10z; + float ny = v10z * v12x - v12z * v10x; + float nz = v10x * v12y - v12x * v10y; float d = PApplet.sqrt(nx * nx + ny * ny + nz * nz); nx /= d; ny /= d; @@ -6483,8 +6588,8 @@ public class PGraphicsOpenGL extends PGraphics { } protected void expandColors(int n) { - float temp[] = new float[4 * n]; - PApplet.arrayCopy(colors, 0, temp, 0, 4 * vertexCount); + int temp[] = new int[n]; + PApplet.arrayCopy(colors, 0, temp, 0, vertexCount); colors = temp; } @@ -6500,10 +6605,40 @@ public class PGraphicsOpenGL extends PGraphics { texcoords = temp; } - protected void expandStrokes(int n) { - float temp[] = new float[5 * n]; - PApplet.arrayCopy(strokes, 0, temp, 0, 5 * vertexCount); - strokes = temp; + protected void expandStrokeColors(int n) { + int temp[] = new int[n]; + PApplet.arrayCopy(scolors, 0, temp, 0, vertexCount); + scolors = temp; + } + + protected void expandStrokeWeights(int n) { + float temp[] = new float[n]; + PApplet.arrayCopy(sweights, 0, temp, 0, vertexCount); + sweights = temp; + } + + protected void expandAmbient(int n) { + int temp[] = new int[n]; + PApplet.arrayCopy(ambient, 0, temp, 0, vertexCount); + ambient = temp; + } + + protected void expandSpecular(int n) { + int temp[] = new int[n]; + PApplet.arrayCopy(specular, 0, temp, 0, vertexCount); + specular = temp; + } + + protected void expandEmissive(int n) { + int temp[] = new int[n]; + PApplet.arrayCopy(emissive, 0, temp, 0, vertexCount); + emissive = temp; + } + + protected void expandShininess(int n) { + float temp[] = new float[n]; + PApplet.arrayCopy(shininess, 0, temp, 0, vertexCount); + shininess = temp; } protected void trimVertices() { @@ -6513,8 +6648,8 @@ public class PGraphicsOpenGL extends PGraphics { } protected void trimColors() { - float temp[] = new float[4 * vertexCount]; - PApplet.arrayCopy(colors, 0, temp, 0, 4 * vertexCount); + int temp[] = new int[vertexCount]; + PApplet.arrayCopy(colors, 0, temp, 0, vertexCount); colors = temp; } @@ -6530,18 +6665,48 @@ public class PGraphicsOpenGL extends PGraphics { texcoords = temp; } - protected void packStrokes() { - float temp[] = new float[5 * vertexCount]; - PApplet.arrayCopy(strokes, 0, temp, 0, 5 * vertexCount); - strokes = temp; + protected void trimStrokeColors() { + int temp[] = new int[vertexCount]; + PApplet.arrayCopy(scolors, 0, temp, 0, vertexCount); + scolors = temp; } + + protected void trimStrokeWeights() { + float temp[] = new float[vertexCount]; + PApplet.arrayCopy(sweights, 0, temp, 0, vertexCount); + sweights = temp; + } + protected void trimAmbient() { + int temp[] = new int[vertexCount]; + PApplet.arrayCopy(ambient, 0, temp, 0, vertexCount); + ambient = temp; + } + + protected void trimSpecular() { + int temp[] = new int[vertexCount]; + PApplet.arrayCopy(specular, 0, temp, 0, vertexCount); + specular = temp; + } + + protected void trimEmissive() { + int temp[] = new int[vertexCount]; + PApplet.arrayCopy(emissive, 0, temp, 0, vertexCount); + emissive = temp; + } + + protected void trimShininess() { + float temp[] = new float[vertexCount]; + PApplet.arrayCopy(shininess, 0, temp, 0, vertexCount); + shininess = temp; + } + protected void trimEdges() { int temp[][] = new int[edgeCount][3]; PApplet.arrayCopy(edges, 0, temp, 0, edgeCount); edges = temp; } - + public int getNumLineVertices() { return 4 *(lastEdge - firstEdge + 1); } @@ -6550,14 +6715,6 @@ public class PGraphicsOpenGL extends PGraphics { return 6 *(lastEdge - firstEdge + 1); } - public void calcPointsNormals() { - // TODO - } - - public void calcLinesNormals() { - // TODO - } - public void calcTrianglesNormals() { for (int i = 0; i < (lastVertex - firstVertex + 1) / 3; i++) { int i0 = 3 * i + 0; @@ -6734,9 +6891,9 @@ public class PGraphicsOpenGL extends PGraphics { // Primitive generation public void generateEllipse(int ellipseMode, float a, float b, float c, float d, - boolean fill, float fillR, float fillG, float fillB, float fillA, - boolean stroke, float strokeR, float strokeG, float strokeB, float strokeA, - float strokeWeight) { + boolean fill, int fillColor, + boolean stroke, int strokeColor, float strokeWeight, + int ambient, int specular, int emissive, float shininess) { float x = a; float y = b; float w = c; @@ -6786,7 +6943,9 @@ public class PGraphicsOpenGL extends PGraphics { if (fill) { addVertex(centerX, centerY, - fillR, fillG, fillB, fillA, strokeR, strokeG, strokeB, strokeA, strokeWeight, VERTEX); + fillColor, strokeColor, strokeWeight, + ambient, specular, emissive, shininess, + VERTEX); } int idx0, pidx, idx; idx0 = pidx = idx = 0; @@ -6794,7 +6953,9 @@ public class PGraphicsOpenGL extends PGraphics { for (int i = 0; i < accuracy; i++) { idx = addVertex(centerX + PGraphicsOpenGL.cosLUT[(int) val] * radiusH, centerY + PGraphicsOpenGL.sinLUT[(int) val] * radiusV, - fillR, fillG, fillB, fillA, strokeR, strokeG, strokeB, strokeA, strokeWeight, VERTEX); + fillColor, strokeColor, strokeWeight, + ambient, specular, emissive, shininess, + VERTEX); val = (val + inc) % PGraphicsOpenGL.SINCOS_LENGTH; if (0 < i) { @@ -6808,12 +6969,15 @@ public class PGraphicsOpenGL extends PGraphics { // Back to the beginning addVertex(centerX + PGraphicsOpenGL.cosLUT[0] * radiusH, centerY + PGraphicsOpenGL.sinLUT[0] * radiusV, - fillR, fillG, fillB, fillA, strokeR, strokeG, strokeB, strokeA, strokeWeight, VERTEX); + fillColor, strokeColor, strokeWeight, + ambient, specular, emissive, shininess, + VERTEX); if (stroke) addEdge(idx, idx0, false, true); } } + // Holds tessellated data for fill, line and point geometry. public class TessGeometry { int renderMode; @@ -6822,10 +6986,17 @@ public class PGraphicsOpenGL extends PGraphics { public int firstFillVertex; public int lastFillVertex; public float[] fillVertices; - public float[] fillColors; + public int[] fillColors; public float[] fillNormals; public float[] 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 int fillIndexCount; public int firstFillIndex; public int lastFillIndex; @@ -6836,9 +7007,8 @@ public class PGraphicsOpenGL extends PGraphics { public int firstLineVertex; public int lastLineVertex; public float[] lineVertices; - public float[] lineColors; - public float[] lineNormals; - public float[] lineAttributes; + public int[] lineColors; + public float[] lineDirWidths; public int lineIndexCount; public int firstLineIndex; @@ -6850,9 +7020,8 @@ public class PGraphicsOpenGL extends PGraphics { public int firstPointVertex; public int lastPointVertex; public float[] pointVertices; - public float[] pointColors; - public float[] pointNormals; - public float[] pointAttributes; + public int[] pointColors; + public float[] pointSizes; public int pointIndexCount; public int firstPointIndex; @@ -6881,57 +7050,61 @@ public class PGraphicsOpenGL extends PGraphics { public void allocate() { fillVertices = new float[3 * PGL.DEFAULT_TESS_VERTICES]; - fillColors = new float[4 * 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]; - fillIndices = new int[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]; lineVertices = new float[3 * PGL.DEFAULT_TESS_VERTICES]; - lineColors = new float[4 * PGL.DEFAULT_TESS_VERTICES]; - lineNormals = new float[3 * PGL.DEFAULT_TESS_VERTICES]; - lineAttributes = new float[4 * 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]; pointVertices = new float[3 * PGL.DEFAULT_TESS_VERTICES]; - pointColors = new float[4 * PGL.DEFAULT_TESS_VERTICES]; - pointNormals = new float[3 * PGL.DEFAULT_TESS_VERTICES]; - pointAttributes = new float[2 * 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]; reset(); } public void trim() { - if (fillVertexCount < fillVertices.length / 3) { + if (0 < fillVertexCount && fillVertexCount < fillVertices.length / 3) { trimFillVertices(); trimFillColors(); trimFillNormals(); trimFillTexcoords(); + trimFillAmbient(); + trimFillSpecular(); + trimFillEmissive(); + trimFillShininess(); } - if (fillIndexCount < fillIndices.length) { + if (0 < fillIndexCount && fillIndexCount < fillIndices.length) { trimFillIndices(); } - if (lineVertexCount < lineVertices.length / 3) { + if (0 < lineVertexCount && lineVertexCount < lineVertices.length / 3) { trimLineVertices(); trimLineColors(); - trimLineNormals(); trimLineAttributes(); } - if (lineIndexCount < lineIndices.length) { + if (0 < lineIndexCount && lineIndexCount < lineIndices.length) { trimLineIndices(); } - if (pointVertexCount < pointVertices.length / 3) { + if (0 < pointVertexCount && pointVertexCount < pointVertices.length / 3) { trimPointVertices(); trimPointColors(); - trimPointNormals(); trimPointAttributes(); } - if (pointIndexCount < pointIndices.length) { + if (0 < pointIndexCount && pointIndexCount < pointIndices.length) { trimPointIndices(); } } @@ -6943,8 +7116,8 @@ public class PGraphicsOpenGL extends PGraphics { } protected void trimFillColors() { - float temp[] = new float[4 * fillVertexCount]; - PApplet.arrayCopy(fillColors, 0, temp, 0, 4 * fillVertexCount); + int temp[] = new int[fillVertexCount]; + PApplet.arrayCopy(fillColors, 0, temp, 0, fillVertexCount); fillColors = temp; } @@ -6960,6 +7133,30 @@ public class PGraphicsOpenGL extends PGraphics { fillTexcoords = temp; } + protected void trimFillAmbient() { + int temp[] = new int[fillVertexCount]; + PApplet.arrayCopy(fillAmbient, 0, temp, 0, fillVertexCount); + fillAmbient = temp; + } + + protected void trimFillSpecular() { + int temp[] = new int[fillVertexCount]; + PApplet.arrayCopy(fillSpecular, 0, temp, 0, fillVertexCount); + fillSpecular = temp; + } + + protected void trimFillEmissive() { + int temp[] = new int[fillVertexCount]; + PApplet.arrayCopy(fillEmissive, 0, temp, 0, fillVertexCount); + fillEmissive = temp; + } + + protected void trimFillShininess() { + float temp[] = new float[fillVertexCount]; + PApplet.arrayCopy(fillShininess, 0, temp, 0, fillVertexCount); + fillShininess = temp; + } + public void trimFillIndices() { int temp[] = new int[fillIndexCount]; PApplet.arrayCopy(fillIndices, 0, temp, 0, fillIndexCount); @@ -6973,25 +7170,19 @@ public class PGraphicsOpenGL extends PGraphics { } protected void trimLineColors() { - float temp[] = new float[4 * lineVertexCount]; - PApplet.arrayCopy(lineColors, 0, temp, 0, 4 * lineVertexCount); + int temp[] = new int[lineVertexCount]; + PApplet.arrayCopy(lineColors, 0, temp, 0, lineVertexCount); lineColors = temp; } - protected void trimLineNormals() { - float temp[] = new float[3 * lineVertexCount]; - PApplet.arrayCopy(lineNormals, 0, temp, 0, 3 * lineVertexCount); - lineNormals = temp; - } - protected void trimLineAttributes() { float temp[] = new float[4 * lineVertexCount]; - PApplet.arrayCopy(lineAttributes, 0, temp, 0, 4 * lineVertexCount); - lineAttributes = temp; + PApplet.arrayCopy(lineDirWidths, 0, temp, 0, 4 * lineVertexCount); + lineDirWidths = temp; } protected void trimLineIndices() { - int temp[] = new int[lineVertexCount]; + int temp[] = new int[lineIndexCount]; PApplet.arrayCopy(lineIndices, 0, temp, 0, lineIndexCount); lineIndices = temp; } @@ -7003,21 +7194,15 @@ public class PGraphicsOpenGL extends PGraphics { } protected void trimPointColors() { - float temp[] = new float[4 * pointVertexCount]; - PApplet.arrayCopy(pointColors, 0, temp, 0, 4 * pointVertexCount); + int temp[] = new int[pointVertexCount]; + PApplet.arrayCopy(pointColors, 0, temp, 0, pointVertexCount); pointColors = temp; } - protected void trimPointNormals() { - float temp[] = new float[3 * pointVertexCount]; - PApplet.arrayCopy(pointNormals, 0, temp, 0, 3 * pointVertexCount); - pointNormals = temp; - } - protected void trimPointAttributes() { float temp[] = new float[2 * pointVertexCount]; - PApplet.arrayCopy(pointAttributes, 0, temp, 0, 2 * pointVertexCount); - pointAttributes = temp; + PApplet.arrayCopy(pointSizes, 0, temp, 0, 2 * pointVertexCount); + pointSizes = temp; } protected void trimPointIndices() { @@ -7031,18 +7216,20 @@ public class PGraphicsOpenGL extends PGraphics { fillColors = null; fillNormals = null; fillTexcoords = null; - fillIndices = null; + fillAmbient = null; + fillSpecular = null; + fillEmissive = null; + fillShininess = null; + fillIndices = null; lineVertices = null; lineColors = null; - lineNormals = null; - lineAttributes = null; + lineDirWidths = null; lineIndices = null; pointVertices = null; pointColors = null; - pointNormals = null; - pointAttributes = null; + pointSizes = null; pointIndices = null; } @@ -7267,7 +7454,11 @@ public class PGraphicsOpenGL extends PGraphics { expandFillVertices(newSize); expandFillColors(newSize); expandFillNormals(newSize); - expandFillTexcoords(newSize); + expandFillTexcoords(newSize); + expandFillAmbient(newSize); + expandFillSpecular(newSize); + expandFillEmissive(newSize); + expandFillShininess(newSize); } } @@ -7280,6 +7471,10 @@ public class PGraphicsOpenGL extends PGraphics { expandFillColors(newSize); expandFillNormals(newSize); expandFillTexcoords(newSize); + expandFillAmbient(newSize); + expandFillSpecular(newSize); + expandFillEmissive(newSize); + expandFillShininess(newSize); } firstFillVertex = fillVertexCount; @@ -7307,8 +7502,8 @@ public class PGraphicsOpenGL extends PGraphics { } protected void expandFillColors(int n) { - float temp[] = new float[4 * n]; - PApplet.arrayCopy(fillColors, 0, temp, 0, 4 * fillVertexCount); + int temp[] = new int[n]; + PApplet.arrayCopy(fillColors, 0, temp, 0, fillVertexCount); fillColors = temp; } @@ -7324,6 +7519,30 @@ public class PGraphicsOpenGL extends PGraphics { fillTexcoords = temp; } + protected void expandFillAmbient(int n) { + int temp[] = new int[n]; + PApplet.arrayCopy(fillAmbient, 0, temp, 0, fillVertexCount); + fillAmbient = temp; + } + + protected void expandFillSpecular(int n) { + int temp[] = new int[n]; + PApplet.arrayCopy(fillSpecular, 0, temp, 0, fillVertexCount); + fillSpecular = temp; + } + + protected void expandFillEmissive(int n) { + int temp[] = new int[n]; + PApplet.arrayCopy(fillEmissive, 0, temp, 0, fillVertexCount); + fillEmissive = temp; + } + + protected void expandFillShininess(int n) { + float temp[] = new float[n]; + PApplet.arrayCopy(fillShininess, 0, temp, 0, fillVertexCount); + fillShininess = temp; + } + public void addLineVertices(int count) { int oldSize = lineVertices.length / 3; if (lineVertexCount + count > oldSize) { @@ -7331,7 +7550,6 @@ public class PGraphicsOpenGL extends PGraphics { expandLineVertices(newSize); expandLineColors(newSize); - expandLineNormals(newSize); expandLineAttributes(newSize); } @@ -7347,21 +7565,15 @@ public class PGraphicsOpenGL extends PGraphics { } protected void expandLineColors(int n) { - float temp[] = new float[4 * n]; - PApplet.arrayCopy(lineColors, 0, temp, 0, 4 * lineVertexCount); + int temp[] = new int[n]; + PApplet.arrayCopy(lineColors, 0, temp, 0, lineVertexCount); lineColors = temp; } - protected void expandLineNormals(int n) { - float temp[] = new float[3 * n]; - PApplet.arrayCopy(lineNormals, 0, temp, 0, 3 * lineVertexCount); - lineNormals = temp; - } - protected void expandLineAttributes(int n) { float temp[] = new float[4 * n]; - PApplet.arrayCopy(lineAttributes, 0, temp, 0, 4 * lineVertexCount); - lineAttributes = temp; + PApplet.arrayCopy(lineDirWidths, 0, temp, 0, 4 * lineVertexCount); + lineDirWidths = temp; } public void addLineIndices(int count) { @@ -7390,7 +7602,6 @@ public class PGraphicsOpenGL extends PGraphics { expandPointVertices(newSize); expandPointColors(newSize); - expandPointNormals(newSize); expandPointAttributes(newSize); } @@ -7406,21 +7617,15 @@ public class PGraphicsOpenGL extends PGraphics { } protected void expandPointColors(int n) { - float temp[] = new float[4 * n]; - PApplet.arrayCopy(pointColors, 0, temp, 0, 4 * pointVertexCount); + int temp[] = new int[n]; + PApplet.arrayCopy(pointColors, 0, temp, 0, pointVertexCount); pointColors = temp; } - protected void expandPointNormals(int n) { - float temp[] = new float[3 * n]; - PApplet.arrayCopy(pointNormals, 0, temp, 0, 3 * pointVertexCount); - pointNormals = temp; - } - protected void expandPointAttributes(int n) { float temp[] = new float[2 * n]; - PApplet.arrayCopy(pointAttributes, 0, temp, 0, 2 * pointVertexCount); - pointAttributes = temp; + PApplet.arrayCopy(pointSizes, 0, temp, 0, 2 * pointVertexCount); + pointSizes = temp; } public void addPointIndices(int count) { @@ -7442,25 +7647,27 @@ public class PGraphicsOpenGL extends PGraphics { pointIndices = temp; } - public void addFillVertex(float x, float y, float z, float r, - float g, float b, float a, + public void addFillVertex(float x, float y, float z, + int rgba, float nx, float ny, float nz, - float u, float v) { + float u, float v, + int am, int sp, int em, float shine) { fillVertexCheck(); int index; if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { - PMatrix3D tr = modelview; + PMatrix3D mm = modelview; + PMatrix3D nm = modelviewInv; index = 3 * fillVertexCount; - 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; + 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; index = 3 * fillVertexCount; - 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; + 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; } else { index = 3 * fillVertexCount; fillVertices[index++] = x; @@ -7473,16 +7680,17 @@ public class PGraphicsOpenGL extends PGraphics { fillNormals[index ] = nz; } - index = 4 * fillVertexCount; - fillColors[index++] = r; - fillColors[index++] = g; - fillColors[index++] = b; - fillColors[index ] = a; + fillColors[fillVertexCount] = rgba; index = 2 * fillVertexCount; fillTexcoords[index++] = u; fillTexcoords[index ] = v; + fillAmbient[fillVertexCount] = am; + fillSpecular[fillVertexCount] = sp; + fillEmissive[fillVertexCount] = em; + fillShininess[fillVertexCount] = shine; + fillVertexCount++; } @@ -7495,7 +7703,8 @@ public class PGraphicsOpenGL extends PGraphics { addFillVertices(nvert); if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { - PMatrix3D tr = modelview; + PMatrix3D mm = modelview; + PMatrix3D nm = modelviewInv; for (int i = 0; i < nvert; i++) { int inIdx = i0 + i; @@ -7512,14 +7721,14 @@ public class PGraphicsOpenGL extends PGraphics { float nz = in.normals[index ]; index = 3 * tessIdx; - 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; + 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; index = 3 * tessIdx; - 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; + 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; } } else { if (nvert <= MIN_ARRAYCOPY_SIZE) { @@ -7547,7 +7756,7 @@ public class PGraphicsOpenGL extends PGraphics { index = 3 * tessIdx; fillNormals[index++] = nx; fillNormals[index++] = ny; - fillNormals[index ] = nz; + fillNormals[index ] = nz; } } else { PApplet.arrayCopy(in.vertices, 3 * i0, fillVertices, 3 * firstFillVertex, 3 * nvert); @@ -7560,34 +7769,32 @@ public class PGraphicsOpenGL extends PGraphics { int inIdx = i0 + i; int tessIdx = firstFillVertex + i; - index = 4 * inIdx; - float r = in.colors[index++]; - float g = in.colors[index++]; - float b = in.colors[index++]; - float a = in.colors[index ]; - index = 2 * inIdx; float u = in.texcoords[index++]; float v = in.texcoords[index ]; - index = 4 * tessIdx; - fillColors[index++] = r; - fillColors[index++] = g; - fillColors[index++] = b; - fillColors[index ] = a; + fillColors[tessIdx] = in.colors[inIdx]; index = 2 * tessIdx; fillTexcoords[index++] = u; - fillTexcoords[index ] = v; + 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, 4 * i0, fillColors, 4 * firstFillVertex, 4 * nvert); - PApplet.arrayCopy(in.texcoords, 2 * i0, fillTexcoords, 2 * firstFillVertex, 2 * nvert); + 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); } } - public void putLineVertex(InGeometry in, int inIdx0, int inIdx1, int tessIdx, - float sr, float sg, float sb, float sa) { + public void putLineVertex(InGeometry in, int inIdx0, int inIdx1, int tessIdx, int rgba) { int index; index = 3 * inIdx0; @@ -7595,64 +7802,40 @@ public class PGraphicsOpenGL extends PGraphics { float y0 = in.vertices[index++]; float z0 = in.vertices[index ]; - index = 3 * inIdx0; - float nx = in.normals[index++]; - float ny = in.normals[index++]; - float nz = in.normals[index ]; - index = 3 * inIdx1; float x1 = in.vertices[index++]; float y1 = in.vertices[index++]; float z1 = in.vertices[index ]; if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { - PMatrix3D tr = modelview; + PMatrix3D mm = modelview; index = 3 * tessIdx; - lineVertices[index++] = x0 * tr.m00 + y0 * tr.m01 + z0 * tr.m02 + tr.m03; - lineVertices[index++] = x0 * tr.m10 + y0 * tr.m11 + z0 * tr.m12 + tr.m13; - lineVertices[index ] = x0 * tr.m20 + y0 * tr.m21 + z0 * tr.m22 + tr.m23; + 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; - index = 3 * tessIdx; - lineNormals[index++] = nx * tr.m00 + ny * tr.m01 + nz * tr.m02; - lineNormals[index++] = nx * tr.m10 + ny * tr.m11 + nz * tr.m12; - lineNormals[index ] = nx * tr.m20 + ny * tr.m21 + nz * tr.m22; - index = 4 * tessIdx; - lineAttributes[index++] = x1 * tr.m00 + y1 * tr.m01 + z1 * tr.m02 + tr.m03; - lineAttributes[index++] = x1 * tr.m10 + y1 * tr.m11 + z1 * tr.m12 + tr.m13; - lineAttributes[index ] = x1 * tr.m20 + y1 * tr.m21 + z1 * tr.m22 + tr.m23; + 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; } else { index = 3 * tessIdx; lineVertices[index++] = x0; lineVertices[index++] = y0; lineVertices[index ] = z0; - index = 3 * tessIdx; - lineNormals[index++] = nx; - lineNormals[index++] = ny; - lineNormals[index ] = nz; - index = 4 * tessIdx; - lineAttributes[index++] = x1; - lineAttributes[index++] = y1; - lineAttributes[index ] = z1; + lineDirWidths[index++] = x1; + lineDirWidths[index++] = y1; + lineDirWidths[index ] = z1; } - index = 4 * tessIdx; - lineColors[index++] = sr; - lineColors[index++] = sg; - lineColors[index++] = sb; - lineColors[index ] = sa; + lineColors[tessIdx] = rgba; } public void putLineVertex(InGeometry in, int inIdx0, int inIdx1, int tessIdx) { - int index = 5 * inIdx0; - float r = in.strokes[index++]; - float g = in.strokes[index++]; - float b = in.strokes[index++]; - float a = in.strokes[index ]; - putLineVertex(in, inIdx0, inIdx1, tessIdx, r, g, b, a); + putLineVertex(in, inIdx0, inIdx1, tessIdx, in.scolors[inIdx0]); } @@ -7664,46 +7847,21 @@ public class PGraphicsOpenGL extends PGraphics { 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 ]; - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { - PMatrix3D tr = modelview; + PMatrix3D mm = modelview; index = 3 * tessIdx; - 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; - - index = 3 * tessIdx; - pointNormals[index++] = nx * tr.m00 + ny * tr.m01 + nz * tr.m02; - pointNormals[index++] = nx * tr.m10 + ny * tr.m11 + nz * tr.m12; - pointNormals[index ] = nx * tr.m20 + ny * tr.m21 + nz * tr.m22; + 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; } else { index = 3 * tessIdx; pointVertices[index++] = x; pointVertices[index++] = y; pointVertices[index ] = z; - - index = 3 * tessIdx; - pointNormals[index++] = nx; - pointNormals[index++] = ny; - pointNormals[index ] = nz; } - index = 5 * inIdx; - float r = in.strokes[index++]; - float g = in.strokes[index++]; - float b = in.strokes[index++]; - float a = in.strokes[index ]; - - index = 4 * tessIdx; - pointColors[index++] = r; - pointColors[index++] = g; - pointColors[index++] = b; - pointColors[index ] = a; + pointColors[tessIdx] = in.scolors[inIdx]; } public int expandVertSize(int currSize, int newMinSize) { @@ -7767,8 +7925,8 @@ public class PGraphicsOpenGL extends PGraphics { lineVertices[index ] += ty; index = 4 * i; - lineAttributes[index++] += tx; - lineAttributes[index ] += ty; + lineDirWidths[index++] += tx; + lineDirWidths[index ] += ty; } } @@ -7834,9 +7992,9 @@ public class PGraphicsOpenGL extends PGraphics { lineVertices[index ] += tz; index = 4 * i; - lineAttributes[index++] += tx; - lineAttributes[index++] += ty; - lineAttributes[index ] += tz; + lineDirWidths[index++] += tx; + lineDirWidths[index++] += ty; + lineDirWidths[index ] += tz; } } @@ -7904,25 +8062,17 @@ public class PGraphicsOpenGL extends PGraphics { float x = lineVertices[index++]; float y = lineVertices[index ]; - index = 3 * i; - float nx = lineNormals[index++]; - float ny = lineNormals[index ]; - index = 4 * i; - float xa = lineAttributes[index++]; - float ya = lineAttributes[index ]; + float xa = lineDirWidths[index++]; + float ya = lineDirWidths[index ]; index = 3 * i; lineVertices[index++] = x * tr.m00 + y * tr.m01 + tr.m02; lineVertices[index ] = x * tr.m10 + y * tr.m11 + tr.m12; - index = 3 * i; - lineNormals[index++] = nx * tr.m00 + ny * tr.m01; - lineNormals[index ] = nx * tr.m10 + ny * tr.m11; - index = 4 * i; - lineAttributes[index++] = xa * tr.m00 + ya * tr.m01 + tr.m02; - lineAttributes[index ] = xa * tr.m10 + ya * tr.m11 + tr.m12; + lineDirWidths[index++] = xa * tr.m00 + ya * tr.m01 + tr.m02; + lineDirWidths[index ] = xa * tr.m10 + ya * tr.m11 + tr.m12; } } @@ -7934,17 +8084,9 @@ public class PGraphicsOpenGL extends PGraphics { float x = pointVertices[index++]; float y = pointVertices[index ]; - index = 3 * i; - float nx = pointNormals[index++]; - float ny = pointNormals[index ]; - index = 3 * i; pointVertices[index++] = x * tr.m00 + y * tr.m01 + tr.m02; pointVertices[index ] = x * tr.m10 + y * tr.m11 + tr.m12; - - index = 3 * i; - pointNormals[index++] = nx * tr.m00 + ny * tr.m01; - pointNormals[index ] = nx * tr.m10 + ny * tr.m11; } } } @@ -7985,30 +8127,20 @@ public class PGraphicsOpenGL extends PGraphics { float y = lineVertices[index++]; float z = lineVertices[index ]; - index = 3 * i; - float nx = lineNormals[index++]; - float ny = lineNormals[index++]; - float nz = lineNormals[index ]; - index = 4 * i; - float xa = lineAttributes[index++]; - float ya = lineAttributes[index++]; - float za = lineAttributes[index ]; + 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 = 3 * i; - lineNormals[index++] = nx * tr.m00 + ny * tr.m01 + nz * tr.m02; - lineNormals[index++] = nx * tr.m10 + ny * tr.m11 + nz * tr.m12; - lineNormals[index ] = nx * tr.m20 + ny * tr.m21 + nz * tr.m22; - index = 4 * i; - lineAttributes[index++] = xa * tr.m00 + ya * tr.m01 + za * tr.m02 + tr.m03; - lineAttributes[index++] = xa * tr.m10 + ya * tr.m11 + za * tr.m12 + tr.m13; - lineAttributes[index ] = xa * tr.m20 + ya * tr.m21 + za * tr.m22 + tr.m23; + 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; } } @@ -8021,20 +8153,10 @@ public class PGraphicsOpenGL extends PGraphics { float y = pointVertices[index++]; float z = pointVertices[index ]; - index = 3 * i; - float nx = pointNormals[index++]; - float ny = pointNormals[index++]; - float nz = pointNormals[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; - - index = 3 * i; - pointNormals[index++] = nx * tr.m00 + ny * tr.m01 + nz * tr.m02; - pointNormals[index++] = nx * tr.m10 + ny * tr.m11 + nz * tr.m12; - pointNormals[index ] = nx * tr.m20 + ny * tr.m21 + nz * tr.m22; } } } @@ -8055,6 +8177,7 @@ public class PGraphicsOpenGL extends PGraphics { } final protected float[][] QUAD_SIGNS = { {-1, +1}, {-1, -1}, {+1, -1}, {+1, +1} }; + // Generates tessellated geometry given a batch of input vertices. public class Tessellator { InGeometry in; TessGeometry tess; @@ -8066,7 +8189,6 @@ public class PGraphicsOpenGL extends PGraphics { float strokeWeight; int strokeJoin; int strokeCap; - float strokeRed, strokeGreen, strokeBlue, strokeAlpha; int bezierDetil = 20; public Tessellator() { @@ -8103,13 +8225,6 @@ public class PGraphicsOpenGL extends PGraphics { this.strokeCap = strokeCap; } - public void setStrokeColor(float r, float g, float b, float a) { - this.strokeRed = r; - this.strokeGreen = g; - this.strokeBlue = b; - this.strokeAlpha = a; - } - public void tessellatePoints() { if (strokeCap == ROUND) { tessellateRoundPoints(); @@ -8160,14 +8275,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.pointAttributes[2 * attribIdx + 0] = 0; - tess.pointAttributes[2 * attribIdx + 1] = 0; + tess.pointSizes[2 * attribIdx + 0] = 0; + tess.pointSizes[2 * attribIdx + 1] = 0; attribIdx++; float val = 0; float inc = (float) SINCOS_LENGTH / perim; for (int k = 0; k < perim; k++) { - tess.pointAttributes[2 * attribIdx + 0] = 0.5f * cosLUT[(int) val] * strokeWeight; - tess.pointAttributes[2 * attribIdx + 1] = 0.5f * sinLUT[(int) val] * strokeWeight; + tess.pointSizes[2 * attribIdx + 0] = 0.5f * cosLUT[(int) val] * strokeWeight; + tess.pointSizes[2 * attribIdx + 1] = 0.5f * sinLUT[(int) val] * strokeWeight; val = (val + inc) % SINCOS_LENGTH; attribIdx++; } @@ -8226,12 +8341,12 @@ 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.pointAttributes[2 * attribIdx + 0] = 0; - tess.pointAttributes[2 * attribIdx + 1] = 0; + tess.pointSizes[2 * attribIdx + 0] = 0; + tess.pointSizes[2 * attribIdx + 1] = 0; attribIdx++; for (int k = 0; k < 4; k++) { - tess.pointAttributes[2 * attribIdx + 0] = 0.5f * QUAD_SIGNS[k][0] * strokeWeight; - tess.pointAttributes[2 * attribIdx + 1] = 0.5f * QUAD_SIGNS[k][1] * strokeWeight; + tess.pointSizes[2 * attribIdx + 0] = 0.5f * QUAD_SIGNS[k][0] * strokeWeight; + tess.pointSizes[2 * attribIdx + 1] = 0.5f * QUAD_SIGNS[k][1] * strokeWeight; attribIdx++; } @@ -8446,10 +8561,10 @@ public class PGraphicsOpenGL extends PGraphics { if (solid) { // Using NONZERO winding rule for solid polygons. - gluTess.setWindingRule(PGL.TESS_WINDING_NONZERO); + gluTess.setWindingRule(PGL.GLU_TESS_WINDING_NONZERO); } else { // Using ODD winding rule to generate polygon with holes. - gluTess.setWindingRule(PGL.TESS_WINDING_ODD); + gluTess.setWindingRule(PGL.GLU_TESS_WINDING_ODD); } gluTess.beginContour(); @@ -8461,12 +8576,13 @@ public class PGraphicsOpenGL extends PGraphics { gluTess.endContour(); gluTess.beginContour(); } - - // Vertex data includes coordinates, colors, normals and texture coordinates. + + // Vertex data includes coordinates, colors, normals, texture coordinates, and material properties. double[] vertex = new double[] { in.vertices [3 * i + 0], in.vertices [3 * i + 1], in.vertices[3 * i + 2], - in.colors [4 * i + 0], in.colors [4 * i + 1], in.colors [4 * i + 2], in.colors[4 * i + 3], + in.colors [i], in.normals [3 * i + 0], in.normals [3 * i + 1], in.normals [3 * i + 2], - in.texcoords[2 * i + 0], in.texcoords[2 * i + 1] }; + in.texcoords[2 * i + 0], in.texcoords[2 * i + 1], + in.ambient[i], in.specular[i], in.emissive[i], in.shininess[i] }; gluTess.addVertex(vertex); } gluTess.endContour(); @@ -8485,17 +8601,17 @@ public class PGraphicsOpenGL extends PGraphics { protected void addLine(int i0, int i1, int vcount, int icount) { tess.putLineVertex(in, i0, i1, vcount); - tess.lineAttributes[4 * vcount + 3] = +strokeWeight; + tess.lineDirWidths[4 * vcount + 3] = +strokeWeight; tess.lineIndices[icount++] = PGL.makeIndex(vcount); vcount++; tess.putLineVertex(in, i0, i1, vcount); - tess.lineAttributes[4 * vcount + 3] = -strokeWeight; + tess.lineDirWidths[4 * vcount + 3] = -strokeWeight; tess.lineIndices[icount++] = PGL.makeIndex(vcount); vcount++; tess.putLineVertex(in, i1, i0, vcount); - tess.lineAttributes[4 * vcount + 3] = -strokeWeight; + tess.lineDirWidths[4 * vcount + 3] = -strokeWeight; tess.lineIndices[icount++] = PGL.makeIndex(vcount); // Starting a new triangle re-using prev vertices. @@ -8504,7 +8620,7 @@ public class PGraphicsOpenGL extends PGraphics { vcount++; tess.putLineVertex(in, i1, i0, vcount); - tess.lineAttributes[4 * vcount + 3] = +strokeWeight; + tess.lineDirWidths[4 * vcount + 3] = +strokeWeight; tess.lineIndices[icount++] = PGL.makeIndex(vcount); } @@ -8560,13 +8676,13 @@ public class PGraphicsOpenGL extends PGraphics { tessCount = 0; switch (type) { - case PGL.TRIANGLE_FAN: + case PGL.GL_TRIANGLE_FAN: tessType = TRIANGLE_FAN; break; - case PGL.TRIANGLE_STRIP: + case PGL.GL_TRIANGLE_STRIP: tessType = TRIANGLE_STRIP; break; - case PGL.TRIANGLES: + case PGL.GL_TRIANGLES: tessType = TRIANGLES; break; } @@ -8627,15 +8743,18 @@ public class PGraphicsOpenGL extends PGraphics { public void vertex(Object data) { if (data instanceof double[]) { double[] d = (double[]) data; - if (d.length < 12) { - throw new RuntimeException("TessCallback vertex() data is not of length 12"); + if (d.length < 13) { + throw new RuntimeException("TessCallback vertex() data is not of length 13"); } + // We need to use separate rgba components for correct interpolation... + if (tess.fillVertexCount < PGL.MAX_TESS_VERTICES) { - tess.addFillVertex((float) d[ 0], (float) d[ 1], (float) d[2], - (float) d[ 3], (float) d[ 4], (float) d[5], (float) d[6], - (float) d[ 7], (float) d[ 8], (float) d[9], - (float) d[10], (float) d[11]); + tess.addFillVertex((float) d[0], (float) d[ 1], (float) d[ 2], + (int) d[3], + (float) d[4], (float) d[ 5], (float) d[ 6], + (float) d[7], (float) d[ 8], + (int) d[9], (int) d[10], (int) d[11], (float) d[12]); tessCount++; } else { throw new RuntimeException("P3D: the tessellator is generating too many vertices, reduce complexity of shape."); @@ -8666,20 +8785,45 @@ public class PGraphicsOpenGL extends PGraphics { */ public void combine(double[] coords, Object[] data, float[] weight, Object[] outData) { - double[] vertex = new double[12]; + double[] vertex = new double[13]; vertex[0] = coords[0]; vertex[1] = coords[1]; vertex[2] = coords[2]; + // Here w e need to use separate rgba components for correct interpolation... + // Calculating the rest of the vertex parameters (color, // normal, texcoords) as the linear combination of the // combined vertices. - for (int i = 3; i < 12; i++) { + for (int i = 3; i < 13; i++) { vertex[i] = 0; for (int j = 0; j < 4; j++) { double[] vertData = (double[])data[j]; if (vertData != null) { - vertex[i] += weight[j] * vertData[i]; + if (i == 3 || 8 < i) { + // Color data, needs to be split into rgba components + // for interpolation. + int colorj = (int) vertData[i]; + int xj = (colorj >> 24) & 0xFF; + int yj = (colorj >> 16) & 0xFF; + int zj = (colorj >> 8) & 0xFF; + int wj = (colorj >> 0) & 0xFF; + + int colori = (int) vertex[i]; + int xi = (colori >> 24) & 0xFF; + int yi = (colori >> 16) & 0xFF; + int zi = (colori >> 8) & 0xFF; + int wi = (colori >> 0) & 0xFF; + + xi += weight[j] * xj; + yi += weight[j] * yj; + zi += weight[j] * zj; + wi += weight[j] * wj; + + vertex[i] = (xi << 24) | (yi << 16) | (zi << 8) | wi; + } else { + vertex[i] += weight[j] * vertData[i]; + } } } } diff --git a/java/libraries/opengl/src/processing/opengl/PShader.java b/java/libraries/opengl/src/processing/opengl/PShader.java index 98c0adc0b..1835fb39e 100644 --- a/java/libraries/opengl/src/processing/opengl/PShader.java +++ b/java/libraries/opengl/src/processing/opengl/PShader.java @@ -24,54 +24,82 @@ package processing.opengl; import processing.core.*; + import java.io.IOException; import java.net.URL; /** - * This class encapsulates a glsl shader. Based in the code by JohnG + * This class encapsulates a GLSL shader program, including a vertex + * and a fragment shader. Originally based in the code by JohnG * (http://www.hardcorepawn.com/) */ public class PShader { protected PApplet parent; protected PGraphicsOpenGL pg; protected PGL pgl; + + protected URL vertexURL; + protected URL fragmentURL; + + protected String vertexFilename; + protected String fragmentFilename; protected int programObject; protected int vertexShader; protected int fragmentShader; - protected boolean initialized; - - /** - * Creates an instance of GLSLShader. - * - * @param parent PApplet - */ - public PShader(PApplet parent) { - this.parent = parent; - pg = (PGraphicsOpenGL) parent.g; - pgl = pg.pgl; - - programObject = pg.createGLSLProgramObject(); - - vertexShader = 0; - fragmentShader = 0; - initialized = false; - } + public PShader() { + parent = null; + pg = null; + pgl = null; + + this.vertexURL = null; + this.fragmentURL = null; + this.vertexFilename = null; + this.fragmentFilename = null; + + programObject = 0; + vertexShader = 0; + fragmentShader = 0; + } + /** - * Creates a read-to-use instance of GLSLShader with vertex and fragment shaders + * Creates a shader program using the specified vertex and fragment + * shaders. * * @param parent PApplet * @param vertexFN String * @param fragmentFN String */ - public PShader(PApplet parent, String vertexFN, String fragmentFN) { - this(parent); - loadVertexShader(vertexFN); - loadFragmentShader(fragmentFN); - setup(); + public PShader(PApplet parent, String vertFilename, String fragFilename) { + this.parent = parent; + pg = (PGraphicsOpenGL) parent.g; + pgl = pg.pgl; + + this.vertexURL = null; + this.fragmentURL = null; + this.vertexFilename = vertFilename; + this.fragmentFilename = fragFilename; + + programObject = 0; + vertexShader = 0; + fragmentShader = 0; } + public PShader(PApplet parent, URL vertURL, URL fragURL) { + this.parent = parent; + pg = (PGraphicsOpenGL) parent.g; + pgl = pg.pgl; + + this.vertexURL = vertURL; + this.fragmentURL = fragURL; + this.vertexFilename = null; + this.fragmentFilename = null; + + programObject = 0; + vertexShader = 0; + fragmentShader = 0; + } protected void finalize() throws Throwable { try { @@ -89,105 +117,24 @@ public class PShader { } } - - /** - * Loads and compiles the vertex shader contained in file. - * - * @param file String - */ - public void loadVertexShader(String file) { - String shaderSource = PApplet.join(parent.loadStrings(file), "\n"); - attachVertexShader(shaderSource, file); - } - - public void loadVertexShaderSource(String source) { - attachVertexShader(source, ""); - } - - /** - * Loads and compiles the vertex shader contained in the URL. - * - * @param file String - */ - public void loadVertexShader(URL url) { - String shaderSource; - try { - shaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n"); - attachVertexShader(shaderSource, url.getFile()); - } catch (IOException e) { - PGraphics.showException("Cannot load shader " + url.getFile()); - } - } - - /** - * Loads and compiles the fragment shader contained in file. - * - * @param file String - */ - public void loadFragmentShader(String file) { - String shaderSource = PApplet.join(parent.loadStrings(file), "\n"); - attachFragmentShader(shaderSource, file); - } - - public void loadFragmentShaderSource(String source) { - attachFragmentShader(source, ""); - } - - /** - * Loads and compiles the fragment shader contained in the URL. - * - * @param url URL - */ - public void loadFragmentShader(URL url) { - String shaderSource; - try { - shaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n"); - attachFragmentShader(shaderSource, url.getFile()); - } catch (IOException e) { - PGraphics.showException("Cannot load shader " + url.getFile()); - } - } - - /** - * Links the shader program and validates it. - */ - public void setup() { - pgl.linkProgram(programObject); - pgl.validateProgram(programObject); - checkLogInfo("GLSL program validation: ", programObject); - initialized = true; - } - - /** - * Returns true or false depending on whether the shader is initialized or not. - */ - public boolean isInitialized() { - return initialized; - } /** * Starts the execution of the shader program. */ - public void start() { - if (!initialized) { - PGraphics.showWarning("This shader is not properly initialized. Call the setup() method first"); - } - - // TODO: - // set the texture uniforms to the currently values texture units for all the - // textures. - // gl.glUniform1iARB(loc, unit); - - pgl.startProgram(programObject); + public void start() { + init(); + pgl.glUseProgram(programObject); } + /** * Stops the execution of the shader program. */ public void stop() { - pgl.stopProgram(); + pgl.glUseProgram(0); } + /** * Returns the ID location of the attribute parameter given its name. * @@ -195,9 +142,11 @@ public class PShader { * @return int */ public int getAttribLocation(String name) { - return pgl.getAttribLocation(programObject, name); + init(); + return pgl.glGetAttribLocation(programObject, name); } + /** * Returns the ID location of the uniform parameter given its name. * @@ -205,259 +154,191 @@ public class PShader { * @return int */ public int getUniformLocation(String name) { - return pgl.getUniformLocation(programObject, name); + init(); + return pgl.glGetUniformLocation(programObject, name); } - /** - * Sets the texture uniform name with the texture unit to use - * in the said uniform. - * - * @param name String - * @param unit int - */ - public void setTexUniform(String name, int unit) { - int loc = getUniformLocation(name); - if (-1 < loc) { - pgl.setIntUniform(loc, unit); - } + + public void setIntUniform(int loc, int x) { + pgl.glUniform1i(loc, x); + } + + + public void set1FloatUniform(int loc, float x) { + pgl.glUniform1f(loc, x); } - /** - * Sets the texture uniform with the unit of tex is attached to - * at the moment of running the shader. - * - * @param name String - * @param tex GLTexture - */ - /* - public void setTexUniform(String name, PTexture tex) { - int loc = getUniformLocation(name); - if (-1 < loc) { - int tu = tex.getTextureUnit(); - if (-1 < tu) { - // If tex is already bound to a texture unit, we use - // it as the value for the uniform. - gl.glUniform1iARB(loc, tu); - } - tex.setTexUniform(loc); - } + + public void set2FloatUniform(int loc, float x, float y) { + pgl.glUniform2f(loc, x, y); } - */ - /** - * Sets the int uniform with name to the given value - * - * @param name String - * @param x int - */ - public void setIntUniform(String name, int x) { - int loc = getUniformLocation(name); - if (-1 < loc) { - pgl.setIntUniform(loc, x); - } - } - /** - * Sets the float uniform with name to the given value - * - * @param name String - * @param x float - */ - public void setFloatUniform(String name, float x) { - int loc = getUniformLocation(name); - if (-1 < loc) { - pgl.setFloatUniform(loc, x); - } - } - - /** - * Sets the vec2 uniform with name to the given values. - * - * @param nam String - * @param x float - * @param y float - */ - public void setVecUniform(String name, float x, float y) { - int loc = getUniformLocation(name); - if (-1 < loc) { - pgl.setFloatUniform(loc, x, y); - } + public void set3FloatUniform(int loc, float x, float y, float z) { + pgl.glUniform3f(loc, x, y, z); } - /** - * Sets the vec3 uniform with name to the given values. - * - * @param name String - * @param x float - * @param y float - * @param z float - */ - public void setVecUniform(String name, float x, float y, float z) { - int loc = getUniformLocation(name); - if (-1 < loc) { - pgl.setFloatUniform(loc, x, y, z); - } - } - /** - * Sets the vec4 uniform with name to the given values. - * - * @param name String - * @param x float - * @param y float - * @param z float - * @param w float - */ - public void setVecUniform(String name, float x, float y, float z, float w) { - int loc = getUniformLocation(name); - if (-1 < loc) { - pgl.setFloatUniform(loc, x, y, z, w); - } - } + public void set4FloatUniform(int loc, float x, float y, float z, float w) { + pgl.glUniform4f(loc, x, y, z, w); + } - /** - * Sets the mat2 uniform with name to the given values - * - * @param name String - * @param m00 float - * ... - */ - public void setMatUniform(String name, float m00, float m01, - float m10, float m11) { - int loc = getUniformLocation(name); - if (-1 < loc) { - pgl.setMatUniform(loc, m00, m01, - m10, m11); - } - } - /** - * Sets the mat3 uniform with name to the given values - * - * @param name String - * @param m00 float - * ... - */ - public void setMatUniform(String name, float m00, float m01, float m02, - float m10, float m11, float m12, - float m20, float m21, float m22) { - int loc = getUniformLocation(name); - if (-1 < loc) { - pgl.setMatUniform(loc, m00, m01, m02, - m10, m11, m12, - m20, m21, m22); - } + public void set1FloatVecUniform(int loc, float[] vec) { + pgl.glUniform1fv(loc, vec.length, vec, 0); } - /** - * Sets the mat3 uniform with name to the given values - * - * @param name String - * @param m00 float - * ... - */ - public void setMatUniform(String name, float m00, float m01, float m02, float m03, - float m10, float m11, float m12, float m13, - float m20, float m21, float m22, float m23, - float m30, float m31, float m32, float m33) { - int loc = getUniformLocation(name); - if (-1 < loc) { - pgl.setMatUniform(loc, m00, m01, m02, m03, - m10, m11, m12, m13, - m20, m21, m22, m23, - m30, m31, m32, m33); - } - } - /** - * Sets the float attribute with name to the given value - * - * @param name String - * @param x float - */ - public void setFloatAttribute(String name, float x) { - int loc = getAttribLocation(name); - if (-1 < loc) { - pgl.setFloatAttrib(loc, x); - } + public void set2FloatVecUniform(int loc, float[] vec) { + pgl.glUniform2fv(loc, vec.length / 2, vec, 0); } + + public void set3FloatVecUniform(int loc, float[] vec) { + pgl.glUniform3fv(loc, vec.length / 3, vec, 0); + } + + + public void set4FloatVecUniform(int loc, float[] vec) { + pgl.glUniform4fv(loc, vec.length / 4, vec, 0); + } + + + public void set2x2MatUniform(int loc, float[] mat) { + pgl.glUniformMatrix2fv(loc, 1, false, mat, 0); + } + + + public void set3x3MatUniform(int loc, float[] mat) { + pgl.glUniformMatrix3fv(loc, 1, false, mat, 0); + } + + + public void set4x4MatUniform(int loc, float[] mat) { + pgl.glUniformMatrix4fv(loc, 1, false, mat, 0); + } + + + public void set1FloatAttribute(int loc, float x) { + pgl.glVertexAttrib1f(loc, x); + } + + + public void set2FloatAttribute(int loc, float x, float y) { + pgl.glVertexAttrib2f(loc, x, y); + } + + + public void set3FloatAttribute(int loc, float x, float y, float z) { + pgl.glVertexAttrib3f(loc, x, y, z); + } + + + public void set4FloatAttribute(int loc, float x, float y, float z, float w) { + pgl.glVertexAttrib4f(loc, x, y, z, w); + } + + + protected void init() { + if (programObject == 0) { + programObject = pg.createGLSLProgramObject(); + + if (vertexFilename != null && fragmentFilename != null) { + loadVertexShader(vertexFilename); + loadFragmentShader(fragmentFilename); + } else if (vertexURL != null && fragmentURL != null) { + loadVertexShader(vertexURL); + loadFragmentShader(fragmentURL); + } else { + PGraphics.showException("Shader filenames and URLs are both null!"); + } + + checkLogInfo("Vertex shader " + vertexFilename + " compilation: ", vertexShader); + checkLogInfo("Fragment shader " + fragmentFilename + " compilation: ", fragmentShader); + + pgl.glLinkProgram(programObject); + pgl.glValidateProgram(programObject); + } + } + + /** - * Sets the vec2 attribute with name to the given values + * Loads and compiles the vertex shader contained in file. * - * @param name String - * @param float x - * @param float y + * @param file String */ - public void setVecAttribute(String name, float x, float y) { - int loc = getAttribLocation(name); - if (-1 < loc) { - pgl.setFloatAttrib(loc, x, y); - } - } + protected void loadVertexShader(String filename) { + String shaderSource = PApplet.join(parent.loadStrings(filename), "\n"); + attachVertexShader(shaderSource); + } /** - * Sets the vec3 attribute with name to the given values + * Loads and compiles the vertex shader contained in the URL. * - * @param name String - * @param float x - * @param float y - * @param float z - */ - public void setVecAttribute(String name, float x, float y, float z) { - int loc = getAttribLocation(name); - if (-1 < loc) { - pgl.setFloatAttrib(loc, x, y, z); + * @param file String + */ + protected void loadVertexShader(URL url) { + try { + String shaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n"); + attachVertexShader(shaderSource); + } catch (IOException e) { + PGraphics.showException("Cannot load shader " + url.getFile()); } } + + /** + * Loads and compiles the fragment shader contained in file. + * + * @param file String + */ + protected void loadFragmentShader(String filename) { + String shaderSource = PApplet.join(parent.loadStrings(filename), "\n"); + attachFragmentShader(shaderSource); + } /** - * Sets the vec4 attribute with name to the given values + * Loads and compiles the fragment shader contained in the URL. * - * @param name String - * @param float x - * @param float y - * @param float z - * @param float w - */ - public void setVecAttribute(String name, float x, float y, float z, float w) { - int loc = getAttribLocation(name); - if (-1 < loc) { - pgl.setFloatAttrib(loc, x, y, z, w); + * @param url URL + */ + protected void loadFragmentShader(URL url) { + try { + String shaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n"); + attachFragmentShader(shaderSource); + } catch (IOException e) { + PGraphics.showException("Cannot load shader " + url.getFile()); } - } - + } + /** * @param shaderSource a string containing the shader's code - * @param filename the shader's filename, used to print error log information */ - private void attachVertexShader(String shaderSource, String file) { + protected void attachVertexShader(String shaderSource) { vertexShader = pg.createGLSLVertShaderObject(); - pgl.setShaderSource(vertexShader, shaderSource); - pgl.compileShader(vertexShader); - - checkLogInfo("Vertex shader " + file + " compilation: ", vertexShader); - pgl.attachShader(programObject, vertexShader); + pgl.glShaderSource(vertexShader, shaderSource); + pgl.glCompileShader(vertexShader); + + pgl.glAttachShader(programObject, vertexShader); } + /** * @param shaderSource a string containing the shader's code - * @param filename the shader's filename, used to print error log information */ - private void attachFragmentShader(String shaderSource, String file) { + protected void attachFragmentShader(String shaderSource) { fragmentShader = pg.createGLSLFragShaderObject(); - pgl.setShaderSource(fragmentShader, shaderSource); - pgl.compileShader(fragmentShader); - - checkLogInfo("Fragment shader " + file + " compilation: ", fragmentShader); - pgl.attachShader(programObject, fragmentShader); + pgl.glShaderSource(fragmentShader, shaderSource); + pgl.glCompileShader(fragmentShader); + + pgl.glAttachShader(programObject, fragmentShader); } + /** - * @invisible Check the log error for the opengl object obj. Prints error - * message if needed. + * Check the log error for the opengl object obj. Prints error + * message if needed. */ protected void checkLogInfo(String title, int obj) { String log = pgl.getShaderLog(obj); @@ -467,6 +348,7 @@ public class PShader { } } + protected void release() { if (vertexShader != 0) { pg.deleteGLSLVertShaderObject(vertexShader); @@ -480,43 +362,6 @@ public class PShader { pg.deleteGLSLProgramObject(programObject); programObject = 0; } - } - - /* - * - * - * GL.GL_BOOL_ARB GL.GL_BOOL_VEC2_ARB GL.GL_BOOL_VEC3_ARB GL.GL_BOOL_VEC4_ARB - * GL.GL_FLOAT GL.GL_FLOAT_MAT2_ARB GL.GL_FLOAT_MAT3_ARB GL.GL_FLOAT_MAT4_ARB - * GL.GL_FLOAT_VEC2_ARB GL.GL_FLOAT_VEC3_ARB GL.GL_FLOAT_VEC4_ARB GL.GL_INT - * GL.GL_INT_VEC2_ARB GL.GL_INT_VEC3_ARB GL.GL_INT_VEC4_ARB - * - * gl.glUseProgramObjectARB(program); - * - * // Build a mapping from texture parameters to texture units. - * texUnitMap.clear(); int count, size; int type; byte[] paramName = new - * byte[1024]; - * - * int texUnit = 0; - * - * int[] iVal = { 0 }; gl.glGetObjectParameterivARB(fragmentProgram, - * GL.GL_OBJECT_COMPILE_STATUS_ARB, iVal, 0); count = iVal[0]; for (int i = 0; - * i < count; ++i) { IntBuffer iVal1 = BufferUtil.newIntBuffer(1); IntBuffer - * iVal2 = BufferUtil.newIntBuffer(1); - * - * ByteBuffer paramStr = BufferUtil.newByteBuffer(1024); - * gl.glGetActiveUniformARB(program, i, 1024, null, iVal1, iVal2, paramStr); - * size = iVal1.get(); type = iVal2.get(); paramStr.get(paramName); - * - * if ((type == GL.GL_SAMPLER_1D_ARB) || (type == GL.GL_SAMPLER_2D_ARB) || - * (type == GL.GL_SAMPLER_3D_ARB) || (type == GL.GL_SAMPLER_CUBE_ARB) || (type - * == GL.GL_SAMPLER_1D_SHADOW_ARB) || (type == GL.GL_SAMPLER_2D_SHADOW_ARB) || - * (type == GL.GL_SAMPLER_2D_RECT_ARB) || (type == - * GL.GL_SAMPLER_2D_RECT_SHADOW_ARB)) { String strName = new String(paramName, - * 0, 1024); Integer unit = texUnit; texUnitMap.put(strName, unit); int - * location = gl.glGetUniformLocationARB(program, strName); - * gl.glUniform1iARB(location, texUnit); ++texUnit; } } - * - * gl.glUseProgramObjectARB(0); } - */ + } } diff --git a/java/libraries/opengl/src/processing/opengl/PShape3D.java b/java/libraries/opengl/src/processing/opengl/PShape3D.java index 9bae0451c..b07e894f8 100644 --- a/java/libraries/opengl/src/processing/opengl/PShape3D.java +++ b/java/libraries/opengl/src/processing/opengl/PShape3D.java @@ -31,7 +31,10 @@ import processing.core.PMatrix2D; import processing.core.PMatrix3D; import processing.core.PShape; import processing.core.PVector; +import processing.opengl.PGraphicsOpenGL.FillShader; import processing.opengl.PGraphicsOpenGL.InGeometry; +import processing.opengl.PGraphicsOpenGL.LineShader; +import processing.opengl.PGraphicsOpenGL.PointShader; import processing.opengl.PGraphicsOpenGL.TessGeometry; import processing.opengl.PGraphicsOpenGL.Tessellator; import java.io.BufferedReader; @@ -39,6 +42,7 @@ import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.Hashtable; @@ -48,12 +52,7 @@ import java.util.Hashtable; // transformation on all the childs, instead of // propagating the transformation downwards in order // to calculate the transformation matrices. -// 2) What about fill called on a GROUP shape? should apply -// color change to all child shapes. Probably yes. -// 3) Under this scenario, map/unmap methods are only required -// for advanced use/libraries (custom modification of complex -// meshes and patches for example). -// 4) Change the transformation logic, so the matrix is applied +// 2) Change the transformation logic, so the matrix is applied // on the values stored in the vertex cache and not on the // tessellated vertices. @@ -98,19 +97,21 @@ public class PShape3D extends PShape { public int glFillVertexBufferID; public int glFillColorBufferID; public int glFillNormalBufferID; - public int glFillTexCoordBufferID; + public int glFillTexCoordBufferID; + public int glFillAmbientBufferID; + public int glFillSpecularBufferID; + public int glFillEmissiveBufferID; + public int glFillShininessBufferID; public int glFillIndexBufferID; public int glLineVertexBufferID; public int glLineColorBufferID; - public int glLineNormalBufferID; - public int glLineAttribBufferID; + public int glLineDirWidthBufferID; public int glLineIndexBufferID; public int glPointVertexBufferID; public int glPointColorBufferID; - public int glPointNormalBufferID; - public int glPointAttribBufferID; + public int glPointSizeBufferID; public int glPointIndexBufferID; // ........................................................ @@ -149,10 +150,13 @@ public class PShape3D extends PShape { boolean modifiedFillColors; boolean modifiedFillNormals; boolean modifiedFillTexCoords; + boolean modifiedFillAmbient; + boolean modifiedFillSpecular; + boolean modifiedFillEmissive; + boolean modifiedFillShininess; boolean modifiedLineVertices; boolean modifiedLineColors; - boolean modifiedLineNormals; boolean modifiedLineAttributes; boolean modifiedPointVertices; @@ -163,16 +167,18 @@ public class PShape3D extends PShape { protected VertexCache fillVerticesCache; protected VertexCache fillColorsCache; protected VertexCache fillNormalsCache; - protected VertexCache fillTexCoordsCache; + protected VertexCache fillTexCoordsCache; + protected VertexCache fillAmbientCache; + protected VertexCache fillSpecularCache; + protected VertexCache fillEmissiveCache; + protected VertexCache fillShininessCache; protected VertexCache lineVerticesCache; protected VertexCache lineColorsCache; - protected VertexCache lineNormalsCache; protected VertexCache lineAttributesCache; protected VertexCache pointVerticesCache; protected VertexCache pointColorsCache; - protected VertexCache pointNormalsCache; protected VertexCache pointAttributesCache; protected boolean isSolid; @@ -204,20 +210,7 @@ public class PShape3D extends PShape { // Current mode for normals, one of AUTO, SHAPE, or VERTEX protected int normalMode; - - // ........................................................ - - // Fill, stroke and tint colors - - protected boolean fill; - protected float fillR, fillG, fillB, fillA; - - protected boolean stroke; - protected float strokeR, strokeG, strokeB, strokeA; - - protected boolean tint; - protected float tintR, tintG, tintB, tintA; - + // ........................................................ // Bezier and Catmull-Rom curves @@ -254,24 +247,26 @@ public class PShape3D extends PShape { pg = (PGraphicsOpenGL)parent.g; pgl = pg.pgl; - glMode = PGL.STATIC_DRAW; + glMode = PGL.GL_STATIC_DRAW; glFillVertexBufferID = 0; glFillColorBufferID = 0; glFillNormalBufferID = 0; glFillTexCoordBufferID = 0; + glFillAmbientBufferID = 0; + glFillSpecularBufferID = 0; + glFillEmissiveBufferID = 0; + glFillShininessBufferID = 0; glFillIndexBufferID = 0; glLineVertexBufferID = 0; glLineColorBufferID = 0; - glLineNormalBufferID = 0; - glLineAttribBufferID = 0; + glLineDirWidthBufferID = 0; glLineIndexBufferID = 0; glPointVertexBufferID = 0; glPointColorBufferID = 0; - glPointNormalBufferID = 0; - glPointAttribBufferID = 0; + glPointSizeBufferID = 0; glPointIndexBufferID = 0; this.tessellator = pg.tessellator; @@ -303,24 +298,19 @@ public class PShape3D extends PShape { // generated at rendering time, by which the color configuration of the renderer might // have changed. fill = pg.fill; - fillR = ((pg.fillColor >> 16) & 0xFF) / 255.0f; - fillG = ((pg.fillColor >> 8) & 0xFF) / 255.0f; - fillB = ((pg.fillColor >> 0) & 0xFF) / 255.0f; - fillA = ((pg.fillColor >> 24) & 0xFF) / 255.0f; - + fillColor = pg.fillColor; + stroke = pg.stroke; - strokeR = ((pg.strokeColor >> 16) & 0xFF) / 255.0f; - strokeG = ((pg.strokeColor >> 8) & 0xFF) / 255.0f; - strokeB = ((pg.strokeColor >> 0) & 0xFF) / 255.0f; - strokeA = ((pg.strokeColor >> 24) & 0xFF) / 255.0f; - + strokeColor = pg.strokeColor; strokeWeight = pg.strokeWeight; tint = pg.tint; - tintR = ((pg.tintColor >> 16) & 0xFF) / 255.0f; - tintG = ((pg.tintColor >> 8) & 0xFF) / 255.0f; - tintB = ((pg.tintColor >> 0) & 0xFF) / 255.0f; - tintA = ((pg.tintColor >> 24) & 0xFF) / 255.0f; + tintColor = pg.tintColor; + + ambientColor = pg.ambientColor; + specularColor = pg.specularColor; + emissiveColor = pg.emissiveColor; + shininess = pg.shininess; normalX = normalY = 0; normalZ = 1; @@ -336,11 +326,11 @@ public class PShape3D extends PShape { public void setMode(int mode) { if (mode == STATIC) { - glMode = PGL.STATIC_DRAW; + glMode = PGL.GL_STATIC_DRAW; } else if (mode == DYNAMIC) { - glMode = PGL.DYNAMIC_DRAW; + glMode = PGL.GL_DYNAMIC_DRAW; } else if (mode == STREAM) { - glMode = PGL.STREAM_DRAW; + glMode = PGL.GL_STREAM_DRAW; } } @@ -396,6 +386,22 @@ public class PShape3D extends PShape { if (glFillTexCoordBufferID != 0) { pg.finalizeVertexBufferObject(glFillTexCoordBufferID); } + + if (glFillAmbientBufferID != 0) { + pg.finalizeVertexBufferObject(glFillAmbientBufferID); + } + + if (glFillSpecularBufferID != 0) { + pg.finalizeVertexBufferObject(glFillSpecularBufferID); + } + + if (glFillEmissiveBufferID != 0) { + pg.finalizeVertexBufferObject(glFillEmissiveBufferID); + } + + if (glFillShininessBufferID != 0) { + pg.finalizeVertexBufferObject(glFillShininessBufferID); + } if (glFillIndexBufferID != 0) { pg.finalizeVertexBufferObject(glFillIndexBufferID); @@ -411,12 +417,8 @@ public class PShape3D extends PShape { pg.finalizeVertexBufferObject(glLineColorBufferID); } - if (glLineNormalBufferID != 0) { - pg.finalizeVertexBufferObject(glLineNormalBufferID); - } - - if (glLineAttribBufferID != 0) { - pg.finalizeVertexBufferObject(glLineAttribBufferID); + if (glLineDirWidthBufferID != 0) { + pg.finalizeVertexBufferObject(glLineDirWidthBufferID); } if (glLineIndexBufferID != 0) { @@ -433,12 +435,8 @@ public class PShape3D extends PShape { pg.finalizeVertexBufferObject(glPointColorBufferID); } - if (glPointNormalBufferID != 0) { - pg.finalizeVertexBufferObject(glPointNormalBufferID); - } - - if (glPointAttribBufferID != 0) { - pg.finalizeVertexBufferObject(glPointAttribBufferID); + if (glPointSizeBufferID != 0) { + pg.finalizeVertexBufferObject(glPointSizeBufferID); } if (glPointIndexBufferID != 0) { @@ -615,25 +613,15 @@ public class PShape3D extends PShape { } boolean textured = texture != null; - float fR, fG, fB, fA; - fR = fG = fB = fA = 0; + int fcolor = 0x00; if (fill || textured) { if (!textured) { - fR = fillR; - fG = fillG; - fB = fillB; - fA = fillA; + fcolor = fillColor; } else { if (tint) { - fR = tintR; - fG = tintG; - fB = tintB; - fA = tintA; + fcolor = tintColor; } else { - fR = 1; - fG = 1; - fB = 1; - fA = 1; + fcolor = 0xffFFFFFF; } } } @@ -648,15 +636,12 @@ public class PShape3D extends PShape { } } - float sR, sG, sB, sA, sW; - sR = sG = sB = sA = sW = 0; + int scolor = 0x00; + float sweight = 0; if (stroke) { - sR = strokeR; - sG = strokeG; - sB = strokeB; - sA = strokeA; - sW = strokeWeight; - } + scolor = strokeColor; + sweight = strokeWeight; + } if (breakShape) { code = BREAK; @@ -664,10 +649,11 @@ public class PShape3D extends PShape { } in.addVertex(x, y, z, - fR, fG, fB, fA, + fcolor, normalX, normalY, normalZ, u, v, - sR, sG, sB, sA, sW, + scolor, sweight, + ambientColor, specularColor, emissiveColor, shininess, code); root.tessellated = false; @@ -785,10 +771,6 @@ public class PShape3D extends PShape { } } else { fill = false; - fillR = 0; - fillG = 0; - fillB = 0; - fillA = 0; fillColor = 0x0; updateFillColor(); } @@ -875,10 +857,6 @@ public class PShape3D extends PShape { protected void fillFromCalc() { fill = true; - fillR = calcR; - fillG = calcG; - fillB = calcB; - fillA = calcA; fillColor = calcColor; updateFillColor(); } @@ -891,16 +869,8 @@ public class PShape3D extends PShape { updateTesselation(); - int size = tess.fillVertexCount; - float[] colors = tess.fillColors; - int index; - for (int i = 0; i < size; i++) { - index = 4 * i; - colors[index++] = fillR; - colors[index++] = fillG; - colors[index++] = fillB; - colors[index ] = fillA; - } + Arrays.fill(tess.fillColors, 0, tess.fillVertexCount, fillColor); + modifiedFillColors = true; modified(); } @@ -919,10 +889,6 @@ public class PShape3D extends PShape { } } else { stroke = false; - strokeR = 0; - strokeG = 0; - strokeB = 0; - strokeA = 0; strokeColor = 0x0; updateStrokeColor(); } @@ -1009,10 +975,6 @@ public class PShape3D extends PShape { protected void strokeFromCalc() { stroke = true; - strokeR = calcR; - strokeG = calcG; - strokeB = calcB; - strokeA = calcA; strokeColor = calcColor; updateStrokeColor(); } @@ -1023,31 +985,13 @@ public class PShape3D extends PShape { updateTesselation(); if (0 < tess.lineVertexCount) { - int size = tess.lineVertexCount; - float[] colors = tess.lineColors; - int index; - for (int i = 0; i < size; i++) { - index = 4 * i; - colors[index++] = strokeR; - colors[index++] = strokeG; - colors[index++] = strokeB; - colors[index ] = strokeA; - } + Arrays.fill(tess.lineColors, 0, tess.lineVertexCount, strokeColor); modifiedLineColors = true; modified(); } if (0 < tess.pointVertexCount) { - int size = tess.pointVertexCount; - float[] colors = tess.pointColors; - int index; - for (int i = 0; i < size; i++) { - index = 4 * i; - colors[index++] = strokeR; - colors[index++] = strokeG; - colors[index++] = strokeB; - colors[index ] = strokeA; - } + Arrays.fill(tess.pointColors, 0, tess.pointVertexCount, strokeColor); modifiedPointColors = true; modified(); } @@ -1068,10 +1012,6 @@ public class PShape3D extends PShape { } } else { tint = false; - tintR = 0; - tintG = 0; - tintB = 0; - tintA = 0; tintColor = 0x0; updateTintColor(); } @@ -1158,10 +1098,6 @@ public class PShape3D extends PShape { protected void tintFromCalc() { tint = true; - tintR = calcR; - tintG = calcG; - tintB = calcB; - tintA = calcA; tintColor = calcColor; updateTintColor(); } @@ -1174,20 +1110,225 @@ public class PShape3D extends PShape { updateTesselation(); - int size = tess.fillVertexCount; - float[] colors = tess.fillColors; - int index; - for (int i = 0; i < size; i++) { - index = 4 * i; - colors[index++] = tintR; - colors[index++] = tintG; - colors[index++] = tintB; - colors[index ] = tintA; - } + Arrays.fill(tess.fillColors, 0, tess.pointVertexCount, tintColor); + modifiedFillColors = true; modified(); } + ////////////////////////////////////////////////////////////// + + // AMBIENT COLOR + + public void ambient(int rgb) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.ambient(rgb); + } + } else { + colorCalc(rgb); + ambientFromCalc(); + } + } + + + public void ambient(float gray) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.ambient(gray); + } + } else { + colorCalc(gray); + ambientFromCalc(); + } + } + + + public void ambient(float x, float y, float z) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.ambient(x, y, z); + } + } else { + colorCalc(x, y, z); + ambientFromCalc(); + } + } + + protected void ambientFromCalc() { + ambientColor = calcColor; + updateAmbientColor(); + } + + protected void updateAmbientColor() { + if (!shapeEnded || tess.fillVertexCount == 0 || texture == null) { + return; + } + + updateTesselation(); + + Arrays.fill(tess.fillAmbient, 0, tess.fillVertexCount, ambientColor); + + modifiedFillAmbient = true; + modified(); + } + + ////////////////////////////////////////////////////////////// + + // SPECULAR COLOR + + + public void specular(int rgb) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.specular(rgb); + } + } else { + colorCalc(rgb); + specularFromCalc(); + } + } + + + public void specular(float gray) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.specular(gray); + } + } else { + colorCalc(gray); + specularFromCalc(); + } + } + + + public void specular(float x, float y, float z) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.specular(x, y, z); + } + } else { + colorCalc(x, y, z); + specularFromCalc(); + } + } + + protected void specularFromCalc() { + specularColor = calcColor; + updateSpecularColor(); + } + + protected void updateSpecularColor() { + if (!shapeEnded || tess.fillVertexCount == 0 || texture == null) { + return; + } + + updateTesselation(); + + Arrays.fill(tess.fillSpecular, 0, tess.fillVertexCount, specularColor); + + modifiedFillSpecular = true; + modified(); + } + + ////////////////////////////////////////////////////////////// + + // EMISSIVE COLOR + + + public void emissive(int rgb) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.emissive(rgb); + } + } else { + colorCalc(rgb); + emissiveFromCalc(); + } + } + + + public void emissive(float gray) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.emissive(gray); + } + } else { + colorCalc(gray); + emissiveFromCalc(); + } + } + + + public void emissive(float x, float y, float z) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.emissive(x, y, z); + } + } else { + colorCalc(x, y, z); + emissiveFromCalc(); + } + } + + protected void emissiveFromCalc() { + emissiveColor = calcColor; + updateEmissiveColor(); + } + + protected void updateEmissiveColor() { + if (!shapeEnded || tess.fillVertexCount == 0 || texture == null) { + return; + } + + updateTesselation(); + + Arrays.fill(tess.fillEmissive, 0, tess.fillVertexCount, emissiveColor); + + modifiedFillEmissive = true; + modified(); + } + + ////////////////////////////////////////////////////////////// + + // SHININESS + + + public void shininess(float shine) { + if (family == GROUP) { + for (int i = 0; i < childCount; i++) { + PShape3D child = (PShape3D) children[i]; + child.shininess(shine); + } + } else { + shininess = shine; + updateShininessFactor(); + } + } + + + protected void updateShininessFactor() { + if (!shapeEnded || tess.fillVertexCount == 0 || texture == null) { + return; + } + + updateTesselation(); + + Arrays.fill(tess.fillShininess, 0, tess.fillVertexCount, shininess); + + modifiedFillShininess = true; + modified(); + } + /////////////////////////////////////////////////////////// // @@ -1286,7 +1427,6 @@ public class PShape3D extends PShape { } if (0 < tess.lineVertexCount) { modifiedLineVertices = true; - modifiedLineNormals = true; modifiedLineAttributes = true; } if (0 < tess.pointVertexCount) { @@ -1322,7 +1462,6 @@ public class PShape3D extends PShape { } if (0 < tess.lineVertexCount) { modifiedLineVertices = true; - modifiedLineNormals = true; modifiedLineAttributes = true; } if (0 < tess.pointVertexCount) { @@ -1359,7 +1498,6 @@ public class PShape3D extends PShape { } if (0 < tess.lineVertexCount) { modifiedLineVertices = true; - modifiedLineNormals = true; modifiedLineAttributes = true; } if (0 < tess.pointVertexCount) { @@ -1396,7 +1534,6 @@ public class PShape3D extends PShape { } if (0 < tess.lineVertexCount) { modifiedLineVertices = true; - modifiedLineNormals = true; modifiedLineAttributes = true; } if (0 < tess.pointVertexCount) { @@ -1432,7 +1569,6 @@ public class PShape3D extends PShape { } if (0 < tess.lineVertexCount) { modifiedLineVertices = true; - modifiedLineNormals = true; modifiedLineAttributes = true; } if (0 < tess.pointVertexCount) { @@ -1469,7 +1605,6 @@ public class PShape3D extends PShape { } if (0 < tess.lineVertexCount) { modifiedLineVertices = true; - modifiedLineNormals = true; modifiedLineAttributes = true; } if (0 < tess.pointVertexCount) { @@ -1506,7 +1641,6 @@ public class PShape3D extends PShape { } if (0 < tess.lineVertexCount) { modifiedLineVertices = true; - modifiedLineNormals = true; modifiedLineAttributes = true; } if (0 < tess.pointVertexCount) { @@ -1556,7 +1690,6 @@ public class PShape3D extends PShape { } if (0 < tess.lineVertexCount) { modifiedLineVertices = true; - modifiedLineNormals = true; modifiedLineAttributes = true; } if (0 < tess.pointVertexCount) { @@ -1610,7 +1743,6 @@ public class PShape3D extends PShape { } if (0 < tess.lineVertexCount) { modifiedLineVertices = true; - modifiedLineNormals = true; modifiedLineAttributes = true; } if (0 < tess.pointVertexCount) { @@ -1924,7 +2056,7 @@ public class PShape3D extends PShape { return tess.fillVertices; } - public float[] fillColors() { + public int[] fillColors() { updateTesselation(); return tess.fillColors; } @@ -1938,6 +2070,26 @@ public class PShape3D extends PShape { updateTesselation(); return tess.fillTexcoords; } + + public int[] fillAmbient() { + updateTesselation(); + return tess.fillAmbient; + } + + public int[] fillSpecular() { + updateTesselation(); + return tess.fillSpecular; + } + + public int[] fillEmissive() { + updateTesselation(); + return tess.fillEmissive; + } + + public float[] fillShininess() { + updateTesselation(); + return tess.fillShininess; + } public int[] fillIndices() { updateTesselation(); @@ -1979,19 +2131,14 @@ public class PShape3D extends PShape { return tess.lineVertices; } - public float[] lineColors() { + public int[] lineColors() { updateTesselation(); return tess.lineColors; } - public float[] lineNormals() { - updateTesselation(); - return tess.lineNormals; - } - public float[] lineAttributes() { updateTesselation(); - return tess.lineAttributes; + return tess.lineDirWidths; } public int[] lineIndices() { @@ -2034,19 +2181,14 @@ public class PShape3D extends PShape { return tess.pointVertices; } - public float[] pointColors() { + public int[] pointColors() { updateTesselation(); return tess.pointColors; } - public float[] pointNormals() { - updateTesselation(); - return tess.pointNormals; - } - public float[] pointAttributes() { updateTesselation(); - return tess.pointAttributes; + return tess.pointSizes; } public int[] pointIndices() { @@ -2080,6 +2222,38 @@ public class PShape3D extends PShape { public FloatBuffer mapFillTexCoords() { return mapVertexImpl(root.glFillTexCoordBufferID, 2 * tess.firstFillVertex, 2 * tess.fillVertexCount).asFloatBuffer(); + } + + public IntBuffer mapFillAmbient() { + return mapVertexImpl(root.glFillAmbientBufferID, tess.firstFillVertex, tess.fillVertexCount).asIntBuffer(); + } + + public void unmapFillAmbient() { + unmapVertexImpl(); + } + + public IntBuffer mapFillSpecular() { + return mapVertexImpl(root.glFillSpecularBufferID, tess.firstFillVertex, tess.fillVertexCount).asIntBuffer(); + } + + public void unmapFillSpecular() { + unmapVertexImpl(); + } + + public IntBuffer mapFillEmissive() { + return mapVertexImpl(root.glFillEmissiveBufferID, tess.firstFillVertex, tess.fillVertexCount).asIntBuffer(); + } + + public void unmapFillEmissive() { + unmapVertexImpl(); + } + + public FloatBuffer mapFillShininess() { + return mapVertexImpl(root.glFillShininessBufferID, tess.firstFillVertex, tess.fillVertexCount).asFloatBuffer(); + } + + public void unmapFillShininess() { + unmapVertexImpl(); } public void unmapFillTexCoords() { @@ -2110,16 +2284,12 @@ public class PShape3D extends PShape { unmapVertexImpl(); } - public FloatBuffer mapLineNormals() { - return mapVertexImpl(root.glLineNormalBufferID, 3 * tess.firstLineVertex, 3 * tess.lineVertexCount).asFloatBuffer(); - } - public void unmapLineNormals() { unmapVertexImpl(); } public FloatBuffer mapLineAttributes() { - return mapVertexImpl(root.glLineAttribBufferID, 2 * tess.firstLineVertex, 2 * tess.lineVertexCount).asFloatBuffer(); + return mapVertexImpl(root.glLineDirWidthBufferID, 2 * tess.firstLineVertex, 2 * tess.lineVertexCount).asFloatBuffer(); } public void unmapLineAttributes() { @@ -2150,16 +2320,12 @@ public class PShape3D extends PShape { unmapVertexImpl(); } - public FloatBuffer mapPointNormals() { - return mapVertexImpl(root.glPointNormalBufferID, 3 * tess.firstPointVertex, 3 * tess.pointVertexCount).asFloatBuffer(); - } - public void unmapPointNormals() { unmapVertexImpl(); } public FloatBuffer mapPointAttributes() { - return mapVertexImpl(root.glPointAttribBufferID, 2 * tess.firstPointVertex, 2 * tess.pointVertexCount).asFloatBuffer(); + return mapVertexImpl(root.glPointSizeBufferID, 2 * tess.firstPointVertex, 2 * tess.pointVertexCount).asFloatBuffer(); } public void unmapPointAttributes() { @@ -2176,36 +2342,36 @@ public class PShape3D extends PShape { protected ByteBuffer mapVertexImpl(int id, int offset, int count) { updateTesselation(); - pgl.bindVertexBuffer(id); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, id); ByteBuffer bb; if (root == this) { - bb = pgl.mapVertexBuffer(); + bb = pgl.glMapBuffer(PGL.GL_ARRAY_BUFFER, PGL.GL_READ_WRITE); } else { - bb = pgl.mapVertexBufferRange(offset, count); + bb = pgl.glMapBufferRange(PGL.GL_ARRAY_BUFFER, offset, count, PGL.GL_READ_WRITE); } return bb; } protected void unmapVertexImpl() { - pgl.unmapVertexBuffer(); - pgl.unbindVertexBuffer(); + pgl.glUnmapBuffer(PGL.GL_ARRAY_BUFFER); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } protected ByteBuffer mapIndexImpl(int id, int offset, int count) { updateTesselation(); - pgl.bindIndexBuffer(id); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, id); ByteBuffer bb; if (root == this) { - bb = pgl.mapIndexBuffer(); + bb = pgl.glMapBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, PGL.GL_READ_WRITE); } else { - bb = pgl.mapIndexBufferRange(offset, count); + bb = pgl.glMapBufferRange(PGL.GL_ELEMENT_ARRAY_BUFFER, offset, count, PGL.GL_READ_WRITE); } return bb; } protected void unmapIndexImpl() { - pgl.unmapIndexBuffer(); - pgl.unbindIndexBuffer(); + pgl.glUnmapBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } @@ -2238,15 +2404,12 @@ public class PShape3D extends PShape { tessellator.setStroke(stroke); tessellator.setStrokeWeight(strokeWeight); tessellator.setStrokeCap(strokeCap); - tessellator.setStrokeJoin(strokeJoin); - tessellator.setStrokeColor(strokeR, strokeG, strokeB, strokeA); + tessellator.setStrokeJoin(strokeJoin); if (family == GEOMETRY) { if (kind == POINTS) { - if (normalMode == NORMAL_MODE_AUTO) in.calcPointsNormals(); tessellator.tessellatePoints(); } else if (kind == LINES) { - if (normalMode == NORMAL_MODE_AUTO) in.calcLinesNormals(); tessellator.tessellateLines(); } else if (kind == TRIANGLE || kind == TRIANGLES) { if (stroke) in.addTrianglesEdges(); @@ -2344,9 +2507,9 @@ public class PShape3D extends PShape { float d = params[3]; in.generateEllipse(ellipseMode, a, b, c, d, - fill, fillR, fillG, fillB, fillA, - stroke, strokeR, strokeG, strokeB, strokeA, - strokeWeight); + fill, fillColor, + stroke, strokeColor, strokeWeight, + ambientColor, specularColor, emissiveColor, shininess); tessellator.tessellateTriangleFan(); } @@ -2423,7 +2586,6 @@ public class PShape3D extends PShape { if ((nu < 3) || (nv < 2)) { nu = nv = 30; } - float startLat = -90; float startLon = 0.0f; @@ -2504,62 +2666,52 @@ public class PShape3D extends PShape { // Copying any data remaining in the caches if (root.fillVerticesCache != null && root.fillVerticesCache.hasData()) { - root.copyFillVertices(root.fillVerticesCache.offset, root.fillVerticesCache.size, root.fillVerticesCache.data); + root.copyFillVertices(root.fillVerticesCache.offset, root.fillVerticesCache.size, root.fillVerticesCache.floatData); root.fillVerticesCache.reset(); } if (root.fillColorsCache != null && root.fillColorsCache.hasData()) { - root.copyFillColors(root.fillColorsCache.offset, root.fillColorsCache.size, root.fillColorsCache.data); + root.copyFillColors(root.fillColorsCache.offset, root.fillColorsCache.size, root.fillColorsCache.intData); root.fillColorsCache.reset(); } if (root.fillNormalsCache != null && root.fillNormalsCache.hasData()) { - root.copyFillNormals(root.fillNormalsCache.offset, root.fillNormalsCache.size, root.fillNormalsCache.data); + root.copyFillNormals(root.fillNormalsCache.offset, root.fillNormalsCache.size, root.fillNormalsCache.floatData); root.fillNormalsCache.reset(); } if (root.fillTexCoordsCache != null && root.fillTexCoordsCache.hasData()) { - root.copyFillTexCoords(root.fillTexCoordsCache.offset, root.fillTexCoordsCache.size, root.fillTexCoordsCache.data); + root.copyFillTexCoords(root.fillTexCoordsCache.offset, root.fillTexCoordsCache.size, root.fillTexCoordsCache.floatData); root.fillTexCoordsCache.reset(); } if (root.lineVerticesCache != null && root.lineVerticesCache.hasData()) { - root.copyLineVertices(root.lineVerticesCache.offset, root.lineVerticesCache.size, root.lineVerticesCache.data); + root.copyLineVertices(root.lineVerticesCache.offset, root.lineVerticesCache.size, root.lineVerticesCache.floatData); root.lineVerticesCache.reset(); } if (root.lineColorsCache != null && root.lineColorsCache.hasData()) { - root.copyLineColors(root.lineColorsCache.offset, root.lineColorsCache.size, root.lineColorsCache.data); + root.copyLineColors(root.lineColorsCache.offset, root.lineColorsCache.size, root.lineColorsCache.intData); root.lineColorsCache.reset(); } - if (root.lineNormalsCache != null && root.lineNormalsCache.hasData()) { - root.copyLineNormals(root.lineNormalsCache.offset, root.lineNormalsCache.size, root.lineNormalsCache.data); - root.lineNormalsCache.reset(); - } - if (root.lineAttributesCache != null && root.lineAttributesCache.hasData()) { - root.copyLineAttributes(root.lineAttributesCache.offset, root.lineAttributesCache.size, root.lineAttributesCache.data); + root.copyLineAttributes(root.lineAttributesCache.offset, root.lineAttributesCache.size, root.lineAttributesCache.floatData); root.lineAttributesCache.reset(); } if (root.pointVerticesCache != null && root.pointVerticesCache.hasData()) { - root.copyPointVertices(root.pointVerticesCache.offset, root.pointVerticesCache.size, root.pointVerticesCache.data); + root.copyPointVertices(root.pointVerticesCache.offset, root.pointVerticesCache.size, root.pointVerticesCache.floatData); root.pointVerticesCache.reset(); } if (root.pointColorsCache != null && root.pointColorsCache.hasData()) { - root.copyPointColors(root.pointColorsCache.offset, root.pointColorsCache.size, root.pointColorsCache.data); + root.copyPointColors(root.pointColorsCache.offset, root.pointColorsCache.size, root.pointColorsCache.intData); root.pointColorsCache.reset(); } - if (root.pointNormalsCache != null && root.pointNormalsCache.hasData()) { - root.copyPointNormals(root.pointNormalsCache.offset, root.pointNormalsCache.size, root.pointNormalsCache.data); - root.pointNormalsCache.reset(); - } - if (root.pointAttributesCache != null && root.pointAttributesCache.hasData()) { - root.copyPointAttributes(root.pointAttributesCache.offset, root.pointAttributesCache.size, root.pointAttributesCache.data); + root.copyPointAttributes(root.pointAttributesCache.offset, root.pointAttributesCache.size, root.pointAttributesCache.floatData); root.pointAttributesCache.reset(); } } @@ -2796,29 +2948,49 @@ public class PShape3D extends PShape { } protected void initFillBuffers(int nvert, int nind) { + int sizef = nvert * PGL.SIZEOF_FLOAT; + int sizei = nvert * PGL.SIZEOF_INT; + int sizex = nind * PGL.SIZEOF_INDEX; + glFillVertexBufferID = pg.createVertexBufferObject(); - pgl.bindVertexBuffer(glFillVertexBufferID); - pgl.initVertexBuffer(3 * nvert, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillVertexBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, glMode); glFillColorBufferID = pg.createVertexBufferObject(); - pgl.bindVertexBuffer(glFillColorBufferID); - pgl.initVertexBuffer(4 * nvert, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillColorBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode); glFillNormalBufferID = pg.createVertexBufferObject(); - pgl.bindVertexBuffer(glFillNormalBufferID); - pgl.initVertexBuffer(3 * nvert, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillNormalBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, glMode); glFillTexCoordBufferID = pg.createVertexBufferObject(); - pgl.bindVertexBuffer(glFillTexCoordBufferID); - pgl.initVertexBuffer(2 * nvert, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillTexCoordBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, glMode); - pgl.unbindVertexBuffer(); + glFillAmbientBufferID = pg.createVertexBufferObject(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillAmbientBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode); + + glFillSpecularBufferID = pg.createVertexBufferObject(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillSpecularBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode); + + glFillEmissiveBufferID = pg.createVertexBufferObject(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillEmissiveBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode); + + glFillShininessBufferID = pg.createVertexBufferObject(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillShininessBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizef, null, glMode); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); glFillIndexBufferID = pg.createVertexBufferObject(); - pgl.bindIndexBuffer(glFillIndexBufferID); - pgl.initIndexBuffer(nind, glMode); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glFillIndexBufferID); + pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, glMode); - pgl.unbindIndexBuffer(); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } @@ -2831,7 +3003,8 @@ public class PShape3D extends PShape { } else { if (0 < tess.fillVertexCount && 0 < tess.fillIndexCount) { root.copyFillGeometry(root.fillVertCopyOffset, tess.fillVertexCount, - tess.fillVertices, tess.fillColors, tess.fillNormals, tess.fillTexcoords); + tess.fillVertices, tess.fillColors, tess.fillNormals, tess.fillTexcoords, + tess.fillAmbient, tess.fillSpecular, tess.fillEmissive, tess.fillShininess); root.fillVertCopyOffset += tess.fillVertexCount; root.copyFillIndices(root.fillIndCopyOffset, tess.fillIndexCount, tess.fillIndices); @@ -2852,92 +3025,125 @@ public class PShape3D extends PShape { if (0 < tess.fillVertexCount) { if (modifiedFillVertices) { if (root.fillVerticesCache == null) { - root.fillVerticesCache = new VertexCache(3); + root.fillVerticesCache = new VertexCache(3, true); } root.fillVerticesCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillVertices); modifiedFillVertices = false; } else if (root.fillVerticesCache != null && root.fillVerticesCache.hasData()) { - root.copyFillVertices(root.fillVerticesCache.offset, root.fillVerticesCache.size, root.fillVerticesCache.data); + root.copyFillVertices(root.fillVerticesCache.offset, root.fillVerticesCache.size, root.fillVerticesCache.floatData); root.fillVerticesCache.reset(); } if (modifiedFillColors) { if (root.fillColorsCache == null) { - root.fillColorsCache = new VertexCache(4); + root.fillColorsCache = new VertexCache(1, false); } root.fillColorsCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillColors); modifiedFillColors = false; } else if (root.fillColorsCache != null && root.fillColorsCache.hasData()) { - root.copyFillColors(root.fillColorsCache.offset, root.fillColorsCache.size, root.fillColorsCache.data); + root.copyFillColors(root.fillColorsCache.offset, root.fillColorsCache.size, root.fillColorsCache.intData); root.fillColorsCache.reset(); } if (modifiedFillNormals) { if (root.fillNormalsCache == null) { - root.fillNormalsCache = new VertexCache(3); + root.fillNormalsCache = new VertexCache(3, true); } root.fillNormalsCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillNormals); modifiedFillNormals = false; } else if (root.fillNormalsCache != null && root.fillNormalsCache.hasData()) { - root.copyFillNormals(root.fillNormalsCache.offset, root.fillNormalsCache.size, root.fillNormalsCache.data); + root.copyFillNormals(root.fillNormalsCache.offset, root.fillNormalsCache.size, root.fillNormalsCache.floatData); root.fillNormalsCache.reset(); } if (modifiedFillTexCoords) { if (root.fillTexCoordsCache == null) { - root.fillTexCoordsCache = new VertexCache(2); + root.fillTexCoordsCache = new VertexCache(2, true); } root.fillTexCoordsCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillTexcoords); modifiedFillTexCoords = false; } else if (root.fillTexCoordsCache != null && root.fillTexCoordsCache.hasData()) { - root.copyFillTexCoords(root.fillTexCoordsCache.offset, root.fillTexCoordsCache.size, root.fillTexCoordsCache.data); + root.copyFillTexCoords(root.fillTexCoordsCache.offset, root.fillTexCoordsCache.size, root.fillTexCoordsCache.floatData); root.fillTexCoordsCache.reset(); - } + } + + if (modifiedFillAmbient) { + if (root.fillAmbientCache == null) { + root.fillAmbientCache = new VertexCache(1, false); + } + root.fillAmbientCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillAmbient); + modifiedFillAmbient = false; + } else if (root.fillAmbientCache != null && root.fillAmbientCache.hasData()) { + root.copyfillAmbient(root.fillAmbientCache.offset, root.fillAmbientCache.size, root.fillAmbientCache.intData); + root.fillAmbientCache.reset(); + } + + if (modifiedFillSpecular) { + if (root.fillSpecularCache == null) { + root.fillSpecularCache = new VertexCache(1, false); + } + root.fillSpecularCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillSpecular); + modifiedFillSpecular = false; + } else if (root.fillSpecularCache != null && root.fillSpecularCache.hasData()) { + root.copyfillSpecular(root.fillSpecularCache.offset, root.fillSpecularCache.size, root.fillSpecularCache.intData); + root.fillSpecularCache.reset(); + } + + if (modifiedFillEmissive) { + if (root.fillEmissiveCache == null) { + root.fillEmissiveCache = new VertexCache(1, false); + } + root.fillEmissiveCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillEmissive); + modifiedFillEmissive = false; + } else if (root.fillEmissiveCache != null && root.fillEmissiveCache.hasData()) { + root.copyfillEmissive(root.fillEmissiveCache.offset, root.fillEmissiveCache.size, root.fillEmissiveCache.intData); + root.fillEmissiveCache.reset(); + } + + if (modifiedFillShininess) { + if (root.fillShininessCache == null) { + root.fillShininessCache = new VertexCache(1, true); + } + root.fillShininessCache.add(root.fillVertCopyOffset, tess.fillVertexCount, tess.fillShininess); + modifiedFillShininess = false; + } else if (root.fillShininessCache != null && root.fillShininessCache.hasData()) { + root.copyfillShininess(root.fillShininessCache.offset, root.fillShininessCache.size, root.fillShininessCache.floatData); + root.fillShininessCache.reset(); + } } if (0 < tess.lineVertexCount) { if (modifiedLineVertices) { if (root.lineVerticesCache == null) { - root.lineVerticesCache = new VertexCache(3); + root.lineVerticesCache = new VertexCache(3, true); } root.lineVerticesCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineVertices); modifiedLineVertices = false; } else if (root.lineVerticesCache != null && root.lineVerticesCache.hasData()) { - root.copyLineVertices(root.lineVerticesCache.offset, root.lineVerticesCache.size, root.lineVerticesCache.data); + root.copyLineVertices(root.lineVerticesCache.offset, root.lineVerticesCache.size, root.lineVerticesCache.floatData); root.lineVerticesCache.reset(); } if (modifiedLineColors) { if (root.lineColorsCache == null) { - root.lineColorsCache = new VertexCache(4); + root.lineColorsCache = new VertexCache(1, false); } root.lineColorsCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineColors); modifiedLineColors = false; } else if (root.lineColorsCache != null && root.lineColorsCache.hasData()) { - root.copyLineColors(root.lineColorsCache.offset, root.lineColorsCache.size, root.lineColorsCache.data); + root.copyLineColors(root.lineColorsCache.offset, root.lineColorsCache.size, root.lineColorsCache.intData); root.lineColorsCache.reset(); } - if (modifiedLineNormals) { - if (root.lineNormalsCache == null) { - root.lineNormalsCache = new VertexCache(3); - } - root.lineNormalsCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineNormals); - modifiedLineNormals = false; - } else if (root.lineNormalsCache != null && root.lineNormalsCache.hasData()) { - root.copyLineNormals(root.lineNormalsCache.offset, root.lineNormalsCache.size, root.lineNormalsCache.data); - root.lineNormalsCache.reset(); - } - if (modifiedLineAttributes) { if (root.lineAttributesCache == null) { - root.lineAttributesCache = new VertexCache(4); + root.lineAttributesCache = new VertexCache(4, true); } - root.lineAttributesCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineAttributes); + root.lineAttributesCache.add(root.lineVertCopyOffset, tess.lineVertexCount, tess.lineDirWidths); modifiedLineAttributes = false; } else if (root.lineAttributesCache != null && root.lineAttributesCache.hasData()) { - root.copyLineAttributes(root.lineAttributesCache.offset, root.lineAttributesCache.size, root.lineAttributesCache.data); + root.copyLineAttributes(root.lineAttributesCache.offset, root.lineAttributesCache.size, root.lineAttributesCache.floatData); root.lineAttributesCache.reset(); } } @@ -2945,45 +3151,34 @@ public class PShape3D extends PShape { if (0 < tess.pointVertexCount) { if (modifiedPointVertices) { if (root.pointVerticesCache == null) { - root.pointVerticesCache = new VertexCache(3); + root.pointVerticesCache = new VertexCache(3, true); } root.pointVerticesCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointVertices); modifiedPointVertices = false; } else if (root.pointVerticesCache != null && root.pointVerticesCache.hasData()) { - root.copyPointVertices(root.pointVerticesCache.offset, root.pointVerticesCache.size, root.pointVerticesCache.data); + root.copyPointVertices(root.pointVerticesCache.offset, root.pointVerticesCache.size, root.pointVerticesCache.floatData); root.pointVerticesCache.reset(); } if (modifiedPointColors) { if (root.pointColorsCache == null) { - root.pointColorsCache = new VertexCache(4); + root.pointColorsCache = new VertexCache(1, false); } root.pointColorsCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointColors); modifiedPointColors = false; } else if (root.pointColorsCache != null && root.pointColorsCache.hasData()) { - root.copyPointColors(root.pointColorsCache.offset, root.pointColorsCache.size, root.pointColorsCache.data); + root.copyPointColors(root.pointColorsCache.offset, root.pointColorsCache.size, root.pointColorsCache.intData); root.pointColorsCache.reset(); } - if (modifiedPointNormals) { - if (root.pointNormalsCache == null) { - root.pointNormalsCache = new VertexCache(3); - } - root.pointNormalsCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointNormals); - modifiedPointNormals = false; - } else if (root.pointNormalsCache != null && root.pointNormalsCache.hasData()) { - root.copyPointNormals(root.pointNormalsCache.offset, root.pointNormalsCache.size, root.pointNormalsCache.data); - root.pointNormalsCache.reset(); - } - if (modifiedPointAttributes) { if (root.pointAttributesCache == null) { - root.pointAttributesCache = new VertexCache(2); + root.pointAttributesCache = new VertexCache(2, true); } - root.pointAttributesCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointAttributes); + root.pointAttributesCache.add(root.pointVertCopyOffset, tess.pointVertexCount, tess.pointSizes); modifiedPointAttributes = false; } else if (root.pointAttributesCache != null && root.pointAttributesCache.hasData()) { - root.copyPointAttributes(root.pointAttributesCache.offset, root.pointAttributesCache.size, root.pointAttributesCache.data); + root.copyPointAttributes(root.pointAttributesCache.offset, root.pointAttributesCache.size, root.pointAttributesCache.floatData); root.pointAttributesCache.reset(); } } @@ -2998,83 +3193,129 @@ public class PShape3D extends PShape { protected void copyFillGeometry(int offset, int size, - float[] vertices, float[] colors, - float[] normals, float[] texcoords) { - pgl.bindVertexBuffer(glFillVertexBufferID); - pgl.copyVertexBufferSubData(vertices, 3 * offset, 3 * size, glMode); + float[] vertices, int[] colors, + float[] normals, float[] texcoords, + int[] ambient, int[] specular, int[] emissive, float[] 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.bindVertexBuffer(glFillColorBufferID); - pgl.copyVertexBufferSubData(colors, 4 * offset, 4 * size, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillVertexBufferID); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, FloatBuffer.wrap(vertices, 0, 3 * size)); - pgl.bindVertexBuffer(glFillNormalBufferID); - pgl.copyVertexBufferSubData(normals, 3 * offset, 3 * size, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillColorBufferID); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, IntBuffer.wrap(colors, 0, size)); - pgl.bindVertexBuffer(glFillTexCoordBufferID); - pgl.copyVertexBufferSubData(texcoords, 2 * offset, 2 * size, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillNormalBufferID); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, FloatBuffer.wrap(normals, 0, 3 * size)); - pgl.unbindVertexBuffer(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillTexCoordBufferID); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 2 * offsetf, 2 * sizef, FloatBuffer.wrap(texcoords, 0, 2 * size)); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillAmbientBufferID); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, IntBuffer.wrap(ambient, 0, size)); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillSpecularBufferID); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, IntBuffer.wrap(specular, 0, size)); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillEmissiveBufferID); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, IntBuffer.wrap(emissive, 0, size)); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glFillShininessBufferID); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offsetf, sizef, FloatBuffer.wrap(shininess, 0, size)); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyFillVertices(int offset, int size, float[] vertices) { - pgl.bindVertexBuffer(glFillVertexBufferID); - pgl.copyVertexBufferSubData(vertices, 3 * offset, 3 * size, glMode); - pgl.unbindVertexBuffer(); + protected void copyFillVertices(int offset, int size, float[] 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyFillColors(int offset, int size, float[] colors) { - pgl.bindVertexBuffer(glFillColorBufferID); - pgl.copyVertexBufferSubData(colors, 4 * offset, 4 * size, glMode); - pgl.unbindVertexBuffer(); + protected void copyFillColors(int offset, int size, int[] 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } protected void copyFillNormals(int offset, int size, float[] normals) { - pgl.bindVertexBuffer(glFillNormalBufferID); - pgl.copyVertexBufferSubData(normals, 3 * offset, 3 * size, glMode); - pgl.unbindVertexBuffer(); + 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } protected void copyFillTexCoords(int offset, int size, float[] texcoords) { - pgl.bindVertexBuffer(glFillTexCoordBufferID); - pgl.copyVertexBufferSubData(texcoords, 2 * offset, 2 * size, glMode); - pgl.unbindVertexBuffer(); + 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } + + + protected void copyfillAmbient(int offset, int size, int[] 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); + } + + + protected void copyfillSpecular(int offset, int size, int[] 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); + } + + + protected void copyfillEmissive(int offset, int size, int[] 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); + } + + + protected void copyfillShininess(int offset, int size, float[] 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); + } protected void copyFillIndices(int offset, int size, int[] indices) { - pgl.bindIndexBuffer(glFillIndexBufferID); - pgl.copyIndexBufferSubData(indices, offset, size, glMode); - pgl.unbindIndexBuffer(); + 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.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } protected void initLineBuffers(int nvert, int nind) { + int sizef = nvert * PGL.SIZEOF_FLOAT; + int sizei = nvert * PGL.SIZEOF_INT; + int sizex = nind * PGL.SIZEOF_INDEX; + glLineVertexBufferID = pg.createVertexBufferObject(); - pgl.bindVertexBuffer(glLineVertexBufferID); - pgl.initVertexBuffer(3 * nvert, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineVertexBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, glMode); glLineColorBufferID = pg.createVertexBufferObject(); - pgl.bindVertexBuffer(glLineColorBufferID); - pgl.initVertexBuffer(4 * nvert, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineColorBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode); - glLineNormalBufferID = pg.createVertexBufferObject(); - pgl.bindVertexBuffer(glLineNormalBufferID); - pgl.initVertexBuffer(3 * nvert, glMode); + glLineDirWidthBufferID = pg.createVertexBufferObject(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineDirWidthBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 4 * sizef, null, glMode); - glLineAttribBufferID = pg.createVertexBufferObject(); - pgl.bindVertexBuffer(glLineAttribBufferID); - pgl.initVertexBuffer(4 * nvert, glMode); - - pgl.unbindVertexBuffer(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); glLineIndexBufferID = pg.createVertexBufferObject(); - pgl.bindIndexBuffer(glLineIndexBufferID); - pgl.initIndexBuffer(nind, glMode); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glLineIndexBufferID); + pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, glMode); - pgl.unbindIndexBuffer(); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } @@ -3087,7 +3328,7 @@ public class PShape3D extends PShape { } else { if (hasLines) { root.copyLineGeometry(root.lineVertCopyOffset, tess.lineVertexCount, - tess.lineVertices, tess.lineColors, tess.lineNormals, tess.lineAttributes); + tess.lineVertices, tess.lineColors, tess.lineDirWidths); root.lineVertCopyOffset += tess.lineVertexCount; root.copyLineIndices(root.lineIndCopyOffset, tess.lineIndexCount, tess.lineIndices); @@ -3098,82 +3339,77 @@ public class PShape3D extends PShape { protected void copyLineGeometry(int offset, int size, - float[] vertices, float[] colors, float[] normals, float[] attribs) { - pgl.bindVertexBuffer(glLineVertexBufferID); - pgl.copyVertexBufferSubData(vertices, 3 * offset, 3 * size, glMode); + float[] vertices, int[] colors, float[] 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.bindVertexBuffer(glLineColorBufferID); - pgl.copyVertexBufferSubData(colors, 4 * offset, 4 * size, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineColorBufferID); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, IntBuffer.wrap(colors, 0, size)); - pgl.bindVertexBuffer(glLineNormalBufferID); - pgl.copyVertexBufferSubData(normals, 3 * offset, 3 * size, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glLineDirWidthBufferID); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 4 * offsetf, 4 * sizef, FloatBuffer.wrap(attribs, 0, 4 * size)); - pgl.bindVertexBuffer(glLineAttribBufferID); - pgl.copyVertexBufferSubData(attribs, 4 * offset, 4 * size, glMode); - - pgl.unbindVertexBuffer(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } protected void copyLineVertices(int offset, int size, float[] vertices) { - pgl.bindVertexBuffer(glLineVertexBufferID); - pgl.copyVertexBufferSubData(vertices, 3 * offset, 3 * size, glMode); - pgl.unbindVertexBuffer(); + 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyLineColors(int offset, int size, float[] colors) { - pgl.bindVertexBuffer(glLineColorBufferID); - pgl.copyVertexBufferSubData(colors, 4 * offset, 4 * size, glMode); - pgl.unbindVertexBuffer(); + protected void copyLineColors(int offset, int size, int[] 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyLineNormals(int offset, int size, float[] normals) { - pgl.bindVertexBuffer(glLineNormalBufferID); - pgl.copyVertexBufferSubData(normals, 3 * offset, 3 * size, glMode); - pgl.unbindVertexBuffer(); - } - - protected void copyLineAttributes(int offset, int size, float[] attribs) { - pgl.bindVertexBuffer(glLineAttribBufferID); - pgl.copyVertexBufferSubData(attribs, 4 * offset, 4 * size, glMode); - pgl.unbindVertexBuffer(); + 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } protected void copyLineIndices(int offset, int size, int[] indices) { - pgl.bindIndexBuffer(glLineIndexBufferID); - pgl.copyIndexBufferSubData(indices, offset, size, glMode); - pgl.unbindIndexBuffer(); + 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.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } protected void initPointBuffers(int nvert, int nind) { + int sizef = nvert * PGL.SIZEOF_FLOAT; + int sizei = nvert * PGL.SIZEOF_INT; + int sizex = nind * PGL.SIZEOF_INDEX; + glPointVertexBufferID = pg.createVertexBufferObject(); - pgl.bindVertexBuffer(glPointVertexBufferID); - pgl.initVertexBuffer(3 * nvert, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointVertexBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 3 * sizef, null, glMode); glPointColorBufferID = pg.createVertexBufferObject(); - pgl.bindVertexBuffer(glPointColorBufferID); - pgl.initVertexBuffer(4 * nvert, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointColorBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, sizei, null, glMode); - glPointNormalBufferID = pg.createVertexBufferObject(); - pgl.bindVertexBuffer(glPointNormalBufferID); - pgl.initVertexBuffer(3 * nvert, glMode); - - glPointAttribBufferID = pg.createVertexBufferObject(); - pgl.bindVertexBuffer(glPointAttribBufferID); - pgl.initVertexBuffer(2 * nvert, glMode); + glPointSizeBufferID = pg.createVertexBufferObject(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointSizeBufferID); + pgl.glBufferData(PGL.GL_ARRAY_BUFFER, 2 * sizef, null, glMode); - pgl.unbindVertexBuffer(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); glPointIndexBufferID = pg.createVertexBufferObject(); - pgl.bindIndexBuffer(glPointIndexBufferID); - pgl.initIndexBuffer(nind, glMode); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, glPointIndexBufferID); + pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, sizex, null, glMode); - pgl.unbindIndexBuffer(); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } @@ -3186,7 +3422,7 @@ public class PShape3D extends PShape { } else { if (hasPoints) { root.copyPointGeometry(root.pointVertCopyOffset, tess.pointVertexCount, - tess.pointVertices, tess.pointColors, tess.pointNormals, tess.pointAttributes); + tess.pointVertices, tess.pointColors, tess.pointSizes); root.pointVertCopyOffset += tess.pointVertexCount; root.copyPointIndices(root.pointIndCopyOffset, tess.pointIndexCount, tess.pointIndices); @@ -3197,55 +3433,50 @@ public class PShape3D extends PShape { protected void copyPointGeometry(int offset, int size, - float[] vertices, float[] colors, float[] normals, float[] attribs) { - pgl.bindVertexBuffer(glPointVertexBufferID); - pgl.copyVertexBufferSubData(vertices, 3 * offset, 3 * size, glMode); + float[] vertices, int[] colors, float[] 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.bindVertexBuffer(glPointColorBufferID); - pgl.copyVertexBufferSubData(colors, 4 * offset, 4 * size, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointVertexBufferID); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 3 * offsetf, 3 * sizef, FloatBuffer.wrap(vertices, 0, 3 * size)); + + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointColorBufferID); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, offseti, sizei, IntBuffer.wrap(colors, 0, size)); - pgl.bindVertexBuffer(glPointNormalBufferID); - pgl.copyVertexBufferSubData(normals, 3 * offset, 3 * size, glMode); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, glPointSizeBufferID); + pgl.glBufferSubData(PGL.GL_ARRAY_BUFFER, 2 * offsetf, 2 * sizef, FloatBuffer.wrap(attribs, 0, 2 * size)); - pgl.bindVertexBuffer(glPointAttribBufferID); - pgl.copyVertexBufferSubData(attribs, 2 * offset, 2 * size, glMode); - - pgl.unbindVertexBuffer(); + pgl.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } protected void copyPointVertices(int offset, int size, float[] vertices) { - pgl.bindVertexBuffer(glPointVertexBufferID); - pgl.copyVertexBufferSubData(vertices, 3 * offset, 3 * size, glMode); - pgl.unbindVertexBuffer(); + 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyPointColors(int offset, int size, float[] colors) { - pgl.bindVertexBuffer(glPointColorBufferID); - pgl.copyVertexBufferSubData(colors, 4 * offset, 4 * size, glMode); - pgl.unbindVertexBuffer(); + protected void copyPointColors(int offset, int size, int[] 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } - protected void copyPointNormals(int offset, int size, float[] normals) { - pgl.bindVertexBuffer(glPointNormalBufferID); - pgl.copyVertexBufferSubData(normals, 3 * offset, 3 * size, glMode); - pgl.unbindVertexBuffer(); - } - - protected void copyPointAttributes(int offset, int size, float[] attribs) { - pgl.bindVertexBuffer(glPointAttribBufferID); - pgl.copyVertexBufferSubData(attribs, 2 * offset, 2 * size, glMode); - pgl.unbindVertexBuffer(); + 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.glBindBuffer(PGL.GL_ARRAY_BUFFER, 0); } protected void copyPointIndices(int offset, int size, int[] indices) { - pgl.bindIndexBuffer(glPointIndexBufferID); - pgl.copyIndexBufferSubData(indices, offset, size, glMode); - pgl.unbindIndexBuffer(); + 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.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } @@ -3283,6 +3514,26 @@ public class PShape3D extends PShape { pg.deleteVertexBufferObject(glFillTexCoordBufferID); glFillTexCoordBufferID = 0; } + + if (glFillAmbientBufferID != 0) { + pg.deleteVertexBufferObject(glFillAmbientBufferID); + glFillAmbientBufferID = 0; + } + + if (glFillSpecularBufferID != 0) { + pg.deleteVertexBufferObject(glFillSpecularBufferID); + glFillSpecularBufferID = 0; + } + + if (glFillEmissiveBufferID != 0) { + pg.deleteVertexBufferObject(glFillEmissiveBufferID); + glFillEmissiveBufferID = 0; + } + + if (glFillShininessBufferID != 0) { + pg.deleteVertexBufferObject(glFillShininessBufferID); + glFillShininessBufferID = 0; + } if (glFillIndexBufferID != 0) { pg.deleteVertexBufferObject(glFillIndexBufferID); @@ -3302,14 +3553,9 @@ public class PShape3D extends PShape { glLineColorBufferID = 0; } - if (glLineNormalBufferID != 0) { - pg.deleteVertexBufferObject(glLineNormalBufferID); - glLineNormalBufferID = 0; - } - - if (glLineAttribBufferID != 0) { - pg.deleteVertexBufferObject(glLineAttribBufferID); - glLineAttribBufferID = 0; + if (glLineDirWidthBufferID != 0) { + pg.deleteVertexBufferObject(glLineDirWidthBufferID); + glLineDirWidthBufferID = 0; } if (glLineIndexBufferID != 0) { @@ -3330,14 +3576,9 @@ public class PShape3D extends PShape { glPointColorBufferID = 0; } - if (glPointNormalBufferID != 0) { - pg.deleteVertexBufferObject(glPointNormalBufferID); - glPointNormalBufferID = 0; - } - - if (glPointAttribBufferID != 0) { - pg.deleteVertexBufferObject(glPointAttribBufferID); - glPointAttribBufferID = 0; + if (glPointSizeBufferID != 0) { + pg.deleteVertexBufferObject(glPointSizeBufferID); + glPointSizeBufferID = 0; } if (glPointIndexBufferID != 0) { @@ -3431,11 +3672,8 @@ public class PShape3D extends PShape { protected void renderPoints() { - pg.startPointShader(); - - pgl.enableVertexArrays(); - pgl.enableColorArrays(); - pgl.enableNormalArrays(); + PointShader shader = pg.getPointShader(); + shader.start(); for (int i = 0; i < pointIndexData.size(); i++) { IndexData index = (IndexData)pointIndexData.get(i); @@ -3443,123 +3681,88 @@ public class PShape3D extends PShape { int offset = index.offset; int size = index.size; - pgl.bindVertexBuffer(root.glPointVertexBufferID); - pgl.setVertexFormat(3, first); - - pgl.bindVertexBuffer(root.glPointColorBufferID); - pgl.setColorFormat(4, first); + shader.setVertexAttribute(root.glPointVertexBufferID, 3, PGL.GL_FLOAT, 0, 3 * first * PGL.SIZEOF_FLOAT); + shader.setColorAttribute(root.glPointColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 4 * first); + shader.setSizeAttribute(root.glPointSizeBufferID, 2, PGL.GL_FLOAT, 0, 2 * first * PGL.SIZEOF_FLOAT); - pgl.bindVertexBuffer(root.glPointNormalBufferID); - pgl.setNormalFormat(3, first); - - pg.setupPointShader(root.glPointAttribBufferID); - - pgl.bindIndexBuffer(root.glPointIndexBufferID); - pgl.renderIndexBuffer(offset, size); - - pgl.unbindIndexBuffer(); - pgl.unbindVertexBuffer(); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, root.glPointIndexBufferID); + pgl.glDrawElements(PGL.GL_TRIANGLES, size, PGL.INDEX_TYPE, offset * PGL.SIZEOF_INDEX); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } - pgl.disableVertexArrays(); - pgl.disableColorArrays(); - pgl.disableNormalArrays(); - - pg.stopPointShader(); + shader.stop(); } protected void renderLines() { - pg.startLineShader(); - - pgl.enableVertexArrays(); - pgl.enableColorArrays(); - pgl.enableNormalArrays(); + LineShader shader = pg.getLineShader(); + shader.start(); for (int i = 0; i < lineIndexData.size(); i++) { IndexData index = (IndexData)lineIndexData.get(i); int first = index.first; int offset = index.offset; int size = index.size; + + shader.setVertexAttribute(root.glLineVertexBufferID, 3, PGL.GL_FLOAT, 0, 3 * first * PGL.SIZEOF_FLOAT); + shader.setColorAttribute(root.glLineColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 4 * first); + shader.setDirWidthAttribute(root.glLineDirWidthBufferID, 4, PGL.GL_FLOAT, 0, 4 * first * PGL.SIZEOF_FLOAT); - pgl.bindVertexBuffer(root.glLineVertexBufferID); - pgl.setVertexFormat(3, first); - - pgl.bindVertexBuffer(root.glLineColorBufferID); - pgl.setColorFormat(4, first); - - pgl.bindVertexBuffer(root.glLineNormalBufferID); - pgl.setNormalFormat(3, first); - - pg.setupLineShader(root.glLineAttribBufferID); - - pgl.bindIndexBuffer(root.glLineIndexBufferID); - pgl.renderIndexBuffer(offset, size); - - pgl.unbindIndexBuffer(); - pgl.unbindVertexBuffer(); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, root.glLineIndexBufferID); + pgl.glDrawElements(PGL.GL_TRIANGLES, size, PGL.INDEX_TYPE, offset * PGL.SIZEOF_INDEX); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } - pgl.disableVertexArrays(); - pgl.disableColorArrays(); - pgl.disableNormalArrays(); - - pg.stopLineShader(); + shader.stop(); } - protected void renderFill(PImage textureImage) { - pgl.enableVertexArrays(); - pgl.enableColorArrays(); - pgl.enableNormalArrays(); - pgl.enableTexCoordArrays(); - + protected void renderFill(PImage textureImage) { + PTexture tex = null; + if (textureImage != null) { + tex = pg.getTexture(textureImage); + if (tex != null) { + pgl.enableTexturing(tex.glTarget); + pgl.glBindTexture(tex.glTarget, tex.glID); + } + } + + FillShader shader = pg.getFillShader(pg.lights, tex != null); + shader.start(); + for (int i = 0; i < fillIndexData.size(); i++) { IndexData index = (IndexData)fillIndexData.get(i); int first = index.first; int offset = index.offset; int size = index.size; - - pgl.bindVertexBuffer(root.glFillVertexBufferID); - pgl.setVertexFormat(3, first); - - pgl.bindVertexBuffer(root.glFillColorBufferID); - pgl.setColorFormat(4, first); - pgl.bindVertexBuffer(root.glFillNormalBufferID); - pgl.setNormalFormat(3, first); + shader.setVertexAttribute(root.glFillVertexBufferID, 3, PGL.GL_FLOAT, 0, 3 * first * PGL.SIZEOF_FLOAT); + shader.setColorAttribute(root.glFillColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 4 * first); - pgl.bindVertexBuffer(root.glFillTexCoordBufferID); - pgl.setTexCoordFormat(2, first); - - PTexture tex = null; - if (textureImage != null) { - tex = pg.getTexture(textureImage); - if (tex != null) { - pgl.enableTexturing(tex.glTarget); - pgl.setActiveTexUnit(0); - pgl.bindTexture(tex.glTarget, tex.glID); - } + if (pg.lights) { + shader.setNormalAttribute(root.glFillNormalBufferID, 3, PGL.GL_FLOAT, 0, 3 * first * PGL.SIZEOF_FLOAT); + shader.setAmbientAttribute(root.glFillAmbientBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 4 * first); + shader.setSpecularAttribute(root.glFillSpecularBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 4 * first); + shader.setEmissiveAttribute(root.glFillEmissiveBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 4 * first); + shader.setShininessAttribute(root.glFillShininessBufferID, 1, PGL.GL_FLOAT, 0, first * PGL.SIZEOF_FLOAT); } - pgl.bindIndexBuffer(root.glFillIndexBufferID); - pgl.renderIndexBuffer(offset, size); + if (tex != null) { + shader.setTexCoordAttribute(root.glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 2 * first * PGL.SIZEOF_FLOAT); + } - if (tex != null) { - pgl.unbindTexture(tex.glTarget); - pgl.disableTexturing(tex.glTarget); - } - - pgl.unbindIndexBuffer(); - pgl.unbindVertexBuffer(); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, root.glFillIndexBufferID); + pgl.glDrawElements(PGL.GL_TRIANGLES, size, PGL.INDEX_TYPE, offset * PGL.SIZEOF_INDEX); + pgl.glBindBuffer(PGL.GL_ELEMENT_ARRAY_BUFFER, 0); } - pgl.disableVertexArrays(); - pgl.disableColorArrays(); - pgl.disableNormalArrays(); - pgl.disableTexCoordArrays(); - } - + shader.stop(); + + if (tex != null) { + pgl.glBindTexture(tex.glTarget, 0); + pgl.disableTexturing(tex.glTarget); + } + } /////////////////////////////////////////////////////////// @@ -3584,14 +3787,21 @@ public class PShape3D extends PShape { // Internal class to store a cache of vertex data used to copy data // to the VBOs with fewer calls. protected class VertexCache { + boolean isFloat; int ncoords; int offset; int size; - float[] data; + float[] floatData; + int[] intData; - VertexCache(int ncoords) { + VertexCache(int ncoords, boolean isFloat) { this.ncoords = ncoords; - this.data = new float[ncoords * PGL.DEFAULT_VERTEX_CACHE_SIZE]; + this.isFloat = isFloat; + if (isFloat) { + this.floatData = new float[ncoords * PGL.DEFAULT_VERTEX_CACHE_SIZE]; + } else { + this.intData = new int[ncoords * PGL.DEFAULT_VERTEX_CACHE_SIZE]; + } this.offset = 0; this.size = 0; } @@ -3606,7 +3816,7 @@ public class PShape3D extends PShape { offset = dataOffset; } - int oldSize = data.length / ncoords; + int oldSize = floatData.length / ncoords; if (size + dataSize >= oldSize) { int newSize = expandSize(oldSize, size + dataSize); expand(newSize); @@ -3620,25 +3830,68 @@ public class PShape3D extends PShape { int destIndex = ncoords * (size + i); if (ncoords == 2) { - data[destIndex++] = newData[srcIndex++]; - data[destIndex ] = newData[srcIndex ]; + floatData[destIndex++] = newData[srcIndex++]; + floatData[destIndex ] = newData[srcIndex ]; } else if (ncoords == 3) { - data[destIndex++] = newData[srcIndex++]; - data[destIndex++] = newData[srcIndex++]; - data[destIndex ] = newData[srcIndex ]; + floatData[destIndex++] = newData[srcIndex++]; + floatData[destIndex++] = newData[srcIndex++]; + floatData[destIndex ] = newData[srcIndex ]; } else if (ncoords == 4) { - data[destIndex++] = newData[srcIndex++]; - data[destIndex++] = newData[srcIndex++]; - data[destIndex++] = newData[srcIndex++]; - data[destIndex ] = newData[srcIndex ]; + floatData[destIndex++] = newData[srcIndex++]; + floatData[destIndex++] = newData[srcIndex++]; + floatData[destIndex++] = newData[srcIndex++]; + floatData[destIndex ] = newData[srcIndex ]; } else { for (int j = 0; j < ncoords; j++) { - data[destIndex++] = newData[srcIndex++]; + floatData[destIndex++] = newData[srcIndex++]; } } } } else { - PApplet.arrayCopy(newData, 0, data, ncoords * size, ncoords * dataSize); + PApplet.arrayCopy(newData, 0, floatData, ncoords * size, ncoords * dataSize); + } + + size += dataSize; + } + + void add(int dataOffset, int dataSize, int[] newData) { + if (size == 0) { + offset = dataOffset; + } + + int oldSize = intData.length / ncoords; + if (size + dataSize >= oldSize) { + int newSize = expandSize(oldSize, size + dataSize); + expand(newSize); + } + + if (dataSize <= 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); } size += dataSize; @@ -3658,7 +3911,7 @@ public class PShape3D extends PShape { offset = dataOffset; } - int oldSize = data.length / ncoords; + int oldSize = floatData.length / ncoords; if (size + dataSize >= oldSize) { int newSize = expandSize(oldSize, size + dataSize); expand(newSize); @@ -3671,8 +3924,8 @@ public class PShape3D extends PShape { float y = newData[srcIndex ]; int destIndex = ncoords * (size + i); - data[destIndex++] = x * tr.m00 + y * tr.m01 + tr.m02; - data[destIndex ] = x * tr.m10 + y * tr.m11 + tr.m12; + floatData[destIndex++] = x * tr.m00 + y * tr.m01 + tr.m02; + floatData[destIndex ] = x * tr.m10 + y * tr.m11 + tr.m12; } } @@ -3684,7 +3937,7 @@ public class PShape3D extends PShape { offset = dataOffset; } - int oldSize = data.length / ncoords; + int oldSize = floatData.length / ncoords; if (size + dataSize >= oldSize) { int newSize = expandSize(oldSize, size + dataSize); expand(newSize); @@ -3698,9 +3951,9 @@ public class PShape3D extends PShape { float z = newData[srcIndex++]; int destIndex = ncoords * (size + i); - data[destIndex++] = x * tr.m00 + y * tr.m01 + z * tr.m02 + tr.m03; - data[destIndex++] = x * tr.m10 + y * tr.m11 + z * tr.m12 + tr.m13; - data[destIndex ] = x * tr.m20 + y * tr.m21 + z * tr.m22 + tr.m23; + floatData[destIndex++] = x * tr.m00 + y * tr.m01 + z * tr.m02 + tr.m03; + floatData[destIndex++] = x * tr.m10 + y * tr.m11 + z * tr.m12 + tr.m13; + floatData[destIndex ] = x * tr.m20 + y * tr.m21 + z * tr.m22 + tr.m23; } } @@ -3708,9 +3961,23 @@ public class PShape3D extends PShape { } void expand(int n) { + if (isFloat) { + expandFloat(n); + } else { + expandInt(n); + } + } + + void expandFloat(int n) { float temp[] = new float[ncoords * n]; - PApplet.arrayCopy(data, 0, temp, 0, ncoords * size); - data = temp; + PApplet.arrayCopy(floatData, 0, temp, 0, ncoords * size); + floatData = temp; + } + + void expandInt(int n) { + int temp[] = new int[ncoords * n]; + PApplet.arrayCopy(intData, 0, temp, 0, ncoords * size); + intData = temp; } int expandSize(int currSize, int newMinSize) { @@ -3954,7 +4221,7 @@ public class PShape3D extends PShape { int mtlIdxCur = -1; OBJMaterial mtl = null; - pg.saveDrawingState(); + //pg.saveDrawingState(); // The recorded shapes are not merged, they are grouped // according to the group names found in the OBJ file. @@ -4073,7 +4340,7 @@ public class PShape3D extends PShape { //ogl.endShapeRecorderImpl(this); //ogl.endShapeRecorderImpl(null); - pg.restoreDrawingState(); + //pg.restoreDrawingState(); } diff --git a/java/libraries/opengl/src/processing/opengl/PTexture.java b/java/libraries/opengl/src/processing/opengl/PTexture.java index 25fd5619c..4640d6a95 100644 --- a/java/libraries/opengl/src/processing/opengl/PTexture.java +++ b/java/libraries/opengl/src/processing/opengl/PTexture.java @@ -27,6 +27,7 @@ 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; @@ -41,10 +42,10 @@ import java.util.NoSuchElementException; public class PTexture implements PConstants { public int width, height; - protected PApplet parent; // The Processing applet - protected PGraphicsOpenGL pg; // The main renderer - protected PGL pgl; // The interface between Processing and OpenGL. - protected PGL.Context context; // The context that created this texture. + protected PApplet parent; // The Processing applet + protected PGraphicsOpenGL pg; // The main renderer + protected PGL pgl; // The interface between Processing and OpenGL. + protected PGL.Context context; // The context that created this texture. // These are public but use at your own risk! public int glID; @@ -247,15 +248,15 @@ public class PTexture implements PConstants { } pgl.enableTexturing(glTarget); - pgl.bindTexture(glTarget, glID); + pgl.glBindTexture(glTarget, glID); if (usingMipmaps) { if (PGraphicsOpenGL.mipmapGeneration) { // Automatic mipmap generation. int[] rgbaPixels = new int[w * h]; - convertToRGBA(pixels, rgbaPixels, format, w, h); - pgl.enableTexMipmapGen(glTarget); - setTexels(rgbaPixels, x, y, w, h); + convertToRGBA(pixels, rgbaPixels, format, w, h); + setTexels(rgbaPixels, x, y, w, h); + pgl.glGenerateMipmap(glTarget); rgbaPixels = null; } else { // TODO: Manual mipmap generation. @@ -269,7 +270,7 @@ public class PTexture implements PConstants { rgbaPixels = null; } - pgl.bindTexture(glTarget, 0); + pgl.glBindTexture(glTarget, 0); pgl.disableTexturing(glTarget); } @@ -412,12 +413,12 @@ public class PTexture implements PConstants { public void bind() { pgl.enableTexturing(glTarget); - pgl.bindTexture(glTarget, glID); + pgl.glBindTexture(glTarget, glID); } public void unbind() { pgl.enableTexturing(glTarget); - pgl.unbindTexture(glTarget); + pgl.glBindTexture(glTarget, 0); } //////////////////////////////////////////////////////////// @@ -772,37 +773,25 @@ public class PTexture implements PConstants { */ protected void allocate() { release(); // Just in the case this object is being re-allocated. - + pgl.enableTexturing(glTarget); glID = pg.createTextureObject(); - pgl.bindTexture(glTarget, glID); - pgl.setTexMinFilter(glTarget, glMinFilter); - pgl.setTexMagFilter(glTarget, glMagFilter); - pgl.setTexWrapS(glTarget, glWrapS); - pgl.setTexWrapT(glTarget, glWrapT); - + pgl.glBindTexture(glTarget, glID); + pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_MIN_FILTER, glMinFilter); + pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_MAG_FILTER, glMagFilter); + pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_WRAP_S, glWrapS); + pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_WRAP_T, glWrapT); + // First, we use glTexImage2D to set the full size of the texture (glW/glH might be diff // from w/h in the case that the GPU doesn't support NPOT textures) - pgl.initTex(glTarget, glFormat, glWidth, glHeight); + pgl.glTexImage2D(glTarget, 0, glFormat, glWidth, glHeight, 0, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, null); - // Once OpenGL knows the size of the new texture, we make sure it doesn't - // contain any garbage in the region of interest (0, 0, width, height): - // Doing in patches of 16x16 pixels to avoid creating a (potentially) - // very large transient array which in certain situations (memory- - // constrained android devices) might lead to an out-of-memory error. - int[] texels = new int[16 * 16]; - for (int y = 0; y < height + 16; y += 16) { - int h = PApplet.min(16, height - y); - for (int x = 0; x < width + 16; x += 16) { - int w = PApplet.min(16, width - x); - setTexels(texels, x, y, w, h); - } - } - texels = null; + // Makes sure that the texture buffer in video memory doesn't contain any garbage. + pgl.initTexture(glTarget, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE); - pgl.unbindTexture(glTarget); + pgl.glBindTexture(glTarget, 0); pgl.disableTexturing(glTarget); } @@ -858,7 +847,7 @@ public class PTexture implements PConstants { } protected void setTexels(int[] pix, int level, int x, int y, int w, int h) { - pgl.copyTexSubImage(pix, glTarget, level, x, y, w, 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) { @@ -866,7 +855,7 @@ public class PTexture implements PConstants { } protected void setTexels(IntBuffer buffer, int level, int x, int y, int w, int h) { - pgl.copyTexSubImage(buffer, glTarget, level, x, y, w, h); + pgl.glTexSubImage2D(glTarget, level, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, buffer); } protected void copyObject(PTexture src) { @@ -905,35 +894,35 @@ public class PTexture implements PConstants { public Parameters getParameters() { Parameters res = new Parameters(); - if (glTarget == PGL.TEXTURE_2D) { + if (glTarget == PGL.GL_TEXTURE_2D) { res.target = TEXTURE2D; } - if (glFormat == PGL.RGB) { + if (glFormat == PGL.GL_RGB) { res.format = RGB; - } else if (glFormat == PGL.RGBA) { + } else if (glFormat == PGL.GL_RGBA) { res.format = ARGB; - } else if (glFormat == PGL.ALPHA) { + } else if (glFormat == PGL.GL_ALPHA) { res.format = ALPHA; } - if (glMinFilter == PGL.NEAREST) { + if (glMinFilter == PGL.GL_NEAREST) { res.sampling = POINT; - } else if (glMinFilter == PGL.LINEAR) { + } else if (glMinFilter == PGL.GL_LINEAR) { res.sampling = BILINEAR; - } else if (glMinFilter == PGL.LINEAR_MIPMAP_LINEAR) { + } else if (glMinFilter == PGL.GL_LINEAR_MIPMAP_LINEAR) { res.sampling = TRILINEAR; } - if (glWrapS == PGL.CLAMP_TO_EDGE) { + if (glWrapS == PGL.GL_CLAMP_TO_EDGE) { res.wrapU = CLAMP; - } else if (glWrapS == PGL.REPEAT) { + } else if (glWrapS == PGL.GL_REPEAT) { res.wrapU = REPEAT; } - if (glWrapT == PGL.CLAMP_TO_EDGE) { + if (glWrapT == PGL.GL_CLAMP_TO_EDGE) { res.wrapV = CLAMP; - } else if (glWrapT == PGL.REPEAT) { + } else if (glWrapT == PGL.GL_REPEAT) { res.wrapV = REPEAT; } @@ -948,51 +937,51 @@ public class PTexture implements PConstants { */ protected void setParameters(Parameters params) { if (params.target == TEXTURE2D) { - glTarget = PGL.TEXTURE_2D; + glTarget = PGL.GL_TEXTURE_2D; } else { throw new RuntimeException("OPENGL2: Unknown texture target"); } if (params.format == RGB) { - glFormat = PGL.RGB; + glFormat = PGL.GL_RGB; } else if (params.format == ARGB) { - glFormat = PGL.RGBA; + glFormat = PGL.GL_RGBA; } else if (params.format == ALPHA) { - glFormat = PGL.ALPHA; + glFormat = PGL.GL_ALPHA; } else { throw new RuntimeException("OPENGL2: Unknown texture format"); } if (params.sampling == POINT) { - glMagFilter = PGL.NEAREST; - glMinFilter = PGL.NEAREST; + glMagFilter = PGL.GL_NEAREST; + glMinFilter = PGL.GL_NEAREST; } else if (params.sampling == BILINEAR) { - glMagFilter = PGL.LINEAR; - glMinFilter = PGL.LINEAR; + glMagFilter = PGL.GL_LINEAR; + glMinFilter = PGL.GL_LINEAR; } else if (params.sampling == TRILINEAR) { - glMagFilter = PGL.LINEAR; - glMinFilter = PGL.LINEAR_MIPMAP_LINEAR; + glMagFilter = PGL.GL_LINEAR; + glMinFilter = PGL.GL_LINEAR_MIPMAP_LINEAR; } else { throw new RuntimeException("OPENGL2: Unknown texture filtering mode"); } if (params.wrapU == CLAMP) { - glWrapS = PGL.CLAMP_TO_EDGE; + glWrapS = PGL.GL_CLAMP_TO_EDGE; } else if (params.wrapU == REPEAT) { - glWrapS = PGL.REPEAT; + glWrapS = PGL.GL_REPEAT; } else { throw new RuntimeException("OPENGL2: Unknown wrapping mode"); } if (params.wrapV == CLAMP) { - glWrapT = PGL.CLAMP_TO_EDGE; + glWrapT = PGL.GL_CLAMP_TO_EDGE; } else if (params.wrapV == REPEAT) { - glWrapT = PGL.REPEAT; + glWrapT = PGL.GL_REPEAT; } else { throw new RuntimeException("OPENGL2: Unknown wrapping mode"); } - usingMipmaps = glMinFilter == PGL.LINEAR_MIPMAP_LINEAR; + usingMipmaps = glMinFilter == PGL.GL_LINEAR_MIPMAP_LINEAR; flippedX = false; flippedY = false; diff --git a/java/libraries/opengl/src/processing/opengl/PointShaderVert.glsl b/java/libraries/opengl/src/processing/opengl/PointShaderVert.glsl deleted file mode 100644 index fe984a844..000000000 --- a/java/libraries/opengl/src/processing/opengl/PointShaderVert.glsl +++ /dev/null @@ -1,84 +0,0 @@ -/* - Part of the Processing project - http://processing.org - - Copyright (c) 2011 Andres Colubri - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, - Boston, MA 02111-1307 USA -*/ - -attribute vec2 vertDisp; - -uniform vec4 eye; -uniform int lights; - -// From the "Directional Lights I & II" tutorials from lighthouse 3D: -// http://www.lighthouse3d.com/tutorials/glsl-tutorial/directional-lights-i/ -vec4 calculateLight(int i) { - // Per-vertex diffuse and ambient lighting. - vec3 normal, lightDir; - vec4 diffuse, ambient, specular; - float NdotL, NdotHV; - - // first transform the normal into eye space and normalize the result. - normal = normalize(gl_NormalMatrix * gl_Normal); - - // now normalize the light's direction. Note that according to the - // OpenGL specification, the light is stored in eye space. Also since - // we're talking about a directional light, the position field is actually - // direction - lightDir = normalize(vec3(gl_LightSource[i].position)); - - // compute the cos of the angle between the normal and lights direction. - // The light is directional so the direction is constant for every vertex. - // Since these two are normalized the cosine is the dot product. We also - // need to clamp the result to the [0,1] range. - NdotL = max(dot(normal, lightDir), 0.0); - - // Compute the diffuse term. Ambient and diffuse material components - // are stored in the vertex color, since processing uses GL_COLOR_MATERIAL - diffuse = gl_Color * gl_LightSource[i].diffuse; - - // Compute the ambient and globalAmbient terms - ambient = gl_Color * gl_LightSource[i].ambient; - - // compute the specular term if NdotL is larger than zero - if (NdotL > 0.0) { - // normalize the half-vector, and then compute the - // cosine (dot product) with the normal - NdotHV = max(dot(normal, gl_LightSource[i].halfVector.xyz), 0.0); - specular = gl_FrontMaterial.specular * gl_LightSource[i].specular * pow(NdotHV, gl_FrontMaterial.shininess); - } - - return NdotL * diffuse + ambient; -} - -void main() { - vec4 pos = gl_ModelViewMatrix * gl_Vertex; - pos.xy += vertDisp.xy; - gl_Position = gl_ProjectionMatrix * pos; - - vec4 color = vec4(0, 0, 0, 0); - vec4 globalAmbient = gl_Color * gl_LightModel.ambient; - if (lights == 0) { - color = gl_Color; - } - for (int i = 0; i < lights; i++) { - vec4 light = calculateLight(i); - color += light; - } - color = clamp(color, 0.0, 1.0); - gl_FrontColor = color; -} \ No newline at end of file