diff --git a/android/core/src/processing/core/PConstants.java b/android/core/src/processing/core/PConstants.java index 8542a90ca..777d9e8f1 100644 --- a/android/core/src/processing/core/PConstants.java +++ b/android/core/src/processing/core/PConstants.java @@ -457,41 +457,40 @@ public interface PConstants { // hints - hint values are positive for the alternate version, // negative of the same value returns to the normal/default state - static final int ENABLE_NATIVE_FONTS = 1; - static final int DISABLE_NATIVE_FONTS = -1; + static final int ENABLE_NATIVE_FONTS = 1; + static final int DISABLE_NATIVE_FONTS = -1; + + static final int DISABLE_DEPTH_TEST = 2; + static final int ENABLE_DEPTH_TEST = -2; + + static final int ENABLE_DEPTH_SORT = 3; + static final int DISABLE_DEPTH_SORT = -3; + + static final int DISABLE_OPENGL_ERROR_REPORT = 4; + static final int ENABLE_OPENGL_ERROR_REPORT = -4; + + static final int ENABLE_ACCURATE_TEXTURES = 5; + static final int DISABLE_ACCURATE_TEXTURES = -5; + + static final int DISABLE_DEPTH_MASK = 6; + static final int ENABLE_DEPTH_MASK = -6; + + static final int ENABLE_ACCURATE_2D = 7; + static final int DISABLE_ACCURATE_2D = -7; + + static final int DISABLE_TEXTURE_CACHE = 8; + static final int ENABLE_TEXTURE_CACHE = -8; + + static final int DISABLE_TRANSFORM_CACHE = 9; + static final int ENABLE_TRANSFORM_CACHE = -9; + + static final int ENABLE_STROKE_PERSPECTIVE = 10; + static final int DISABLE_STROKE_PERSPECTIVE = -10; + + static final int DISABLE_TEXTURE_MIPMAPS = 11; + static final int ENABLE_TEXTURE_MIPMAPS = -11; - static final int DISABLE_DEPTH_TEST = 2; - static final int ENABLE_DEPTH_TEST = -2; - - static final int ENABLE_DEPTH_SORT = 3; - static final int DISABLE_DEPTH_SORT = -3; - - static final int DISABLE_OPENGL_ERROR_REPORT = 4; - static final int ENABLE_OPENGL_ERROR_REPORT = -4; - - static final int ENABLE_ACCURATE_TEXTURES = 5; - static final int DISABLE_ACCURATE_TEXTURES = -5; - - static final int DISABLE_DEPTH_MASK = 6; - static final int ENABLE_DEPTH_MASK = -6; - - static final int ENABLE_ACCURATE_2D = 7; - static final int DISABLE_ACCURATE_2D = -7; - - static final int DISABLE_TEXTURE_CACHE = 8; - static final int ENABLE_TEXTURE_CACHE = -8; - - static final int DISABLE_TRANSFORM_CACHE = 9; - static final int ENABLE_TRANSFORM_CACHE = -9; - - static final int ENABLE_PERSPECTIVE_CORRECTED_LINES = 10; - static final int DISABLE_PERSPECTIVE_CORRECTED_LINES = -10; - - static final int DISABLE_TEXTURE_MIPMAPS = 11; - static final int ENABLE_TEXTURE_MIPMAPS = -11; - - static final int HINT_COUNT = 12; - + static final int HINT_COUNT = 12; // error messages diff --git a/android/core/src/processing/opengl/FrameBuffer.java b/android/core/src/processing/opengl/FrameBuffer.java index e63c638df..f6732edde 100644 --- a/android/core/src/processing/opengl/FrameBuffer.java +++ b/android/core/src/processing/opengl/FrameBuffer.java @@ -43,7 +43,7 @@ public class FrameBuffer implements PConstants { protected PApplet parent; protected PGraphicsOpenGL pg; protected PGL pgl; - protected PGL.Context context; // The context that created this framebuffer. + protected PGL.Context context; // The context that created this framebuffer. public int glFbo; public int glDepth; @@ -120,8 +120,9 @@ public class FrameBuffer implements PConstants { this.packedDepthStencil = false; } else { if (packedDepthStencil) { - // When combined depth/stencil format is required, the depth and stencil bits - // are overriden and the 24/8 combination for a 32 bits surface is used. + // When combined depth/stencil format is required, the depth and stencil + // bits are overriden and the 24/8 combination for a 32 bits surface is + // used. this.depthBits = 24; this.stencilBits = 8; this.packedDepthStencil = true; @@ -169,7 +170,9 @@ public class FrameBuffer implements PConstants { pgl.clearDepth(1); pgl.clearStencil(0); pgl.clearColor(0, 0, 0, 0); - pgl.clear(PGL.DEPTH_BUFFER_BIT | PGL.STENCIL_BUFFER_BIT | PGL.COLOR_BUFFER_BIT); + pgl.clear(PGL.DEPTH_BUFFER_BIT | + PGL.STENCIL_BUFFER_BIT | + PGL.COLOR_BUFFER_BIT); pg.popFramebuffer(); } @@ -203,7 +206,8 @@ public class FrameBuffer implements PConstants { public void readPixels() { if (pixelBuffer == null) createPixelBuffer(); pixelBuffer.rewind(); - pgl.readPixels(0, 0, width, height, PGL.RGBA, PGL.UNSIGNED_BYTE, pixelBuffer); + pgl.readPixels(0, 0, width, height, PGL.RGBA, PGL.UNSIGNED_BYTE, + pixelBuffer); } public void getPixels(int[] pixels) { @@ -244,7 +248,8 @@ public class FrameBuffer implements PConstants { if (screenFb) return; if (numColorBuffers != PApplet.min(n, textures.length)) { - throw new RuntimeException("Wrong number of textures to set the color buffers."); + throw new RuntimeException("Wrong number of textures to set the color " + + "buffers."); } for (int i = 0; i < numColorBuffers; i++) { @@ -256,11 +261,14 @@ public class FrameBuffer implements PConstants { // Making sure nothing is attached. for (int i = 0; i < numColorBuffers; i++) { - pgl.framebufferTexture2D(PGL.FRAMEBUFFER, PGL.COLOR_ATTACHMENT0 + i, PGL.TEXTURE_2D, 0, 0); + pgl.framebufferTexture2D(PGL.FRAMEBUFFER, PGL.COLOR_ATTACHMENT0 + i, + PGL.TEXTURE_2D, 0, 0); } for (int i = 0; i < numColorBuffers; i++) { - pgl.framebufferTexture2D(PGL.FRAMEBUFFER, PGL.COLOR_ATTACHMENT0 + i, colorBufferTex[i].glTarget, colorBufferTex[i].glName, 0); + pgl.framebufferTexture2D(PGL.FRAMEBUFFER, PGL.COLOR_ATTACHMENT0 + i, + colorBufferTex[i].glTarget, + colorBufferTex[i].glName, 0); } pgl.validateFramebuffer(); @@ -358,8 +366,10 @@ public class FrameBuffer implements PConstants { glMultisample = pg.createRenderBufferObject(context.code()); pgl.bindRenderbuffer(PGL.RENDERBUFFER, glMultisample); - pgl.renderbufferStorageMultisample(PGL.RENDERBUFFER, nsamples, PGL.RGBA8, width, height); - pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.COLOR_ATTACHMENT0, PGL.RENDERBUFFER, glMultisample); + pgl.renderbufferStorageMultisample(PGL.RENDERBUFFER, nsamples, + PGL.RGBA8, width, height); + pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.COLOR_ATTACHMENT0, + PGL.RENDERBUFFER, glMultisample); pg.popFramebuffer(); } @@ -379,13 +389,17 @@ public class FrameBuffer implements PConstants { pgl.bindRenderbuffer(PGL.RENDERBUFFER, glDepthStencil); if (multisample) { - pgl.renderbufferStorageMultisample(PGL.RENDERBUFFER, nsamples, PGL.DEPTH24_STENCIL8, width, height); + pgl.renderbufferStorageMultisample(PGL.RENDERBUFFER, nsamples, + PGL.DEPTH24_STENCIL8, width, height); } else { - pgl.renderbufferStorage(PGL.RENDERBUFFER, PGL.DEPTH24_STENCIL8, width, height); + pgl.renderbufferStorage(PGL.RENDERBUFFER, PGL.DEPTH24_STENCIL8, + width, height); } - pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.DEPTH_ATTACHMENT, PGL.RENDERBUFFER, glDepthStencil); - pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.STENCIL_ATTACHMENT, PGL.RENDERBUFFER, glDepthStencil); + pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.DEPTH_ATTACHMENT, + PGL.RENDERBUFFER, glDepthStencil); + pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.STENCIL_ATTACHMENT, + PGL.RENDERBUFFER, glDepthStencil); pg.popFramebuffer(); } @@ -414,12 +428,14 @@ public class FrameBuffer implements PConstants { } if (multisample) { - pgl.renderbufferStorageMultisample(PGL.RENDERBUFFER, nsamples, glConst, width, height); + pgl.renderbufferStorageMultisample(PGL.RENDERBUFFER, nsamples, glConst, + width, height); } else { pgl.renderbufferStorage(PGL.RENDERBUFFER, glConst, width, height); } - pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.DEPTH_ATTACHMENT, PGL.RENDERBUFFER, glDepth); + pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.DEPTH_ATTACHMENT, + PGL.RENDERBUFFER, glDepth); pg.popFramebuffer(); } @@ -447,12 +463,14 @@ public class FrameBuffer implements PConstants { glConst = PGL.STENCIL_INDEX8; } if (multisample) { - pgl.renderbufferStorageMultisample(PGL.RENDERBUFFER, nsamples, glConst, width, height); + pgl.renderbufferStorageMultisample(PGL.RENDERBUFFER, nsamples, glConst, + width, height); } else { pgl.renderbufferStorage(PGL.RENDERBUFFER, glConst, width, height); } - pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.STENCIL_ATTACHMENT, PGL.RENDERBUFFER, glStencil); + pgl.framebufferRenderbuffer(PGL.FRAMEBUFFER, PGL.STENCIL_ATTACHMENT, + PGL.RENDERBUFFER, glStencil); pg.popFramebuffer(); } diff --git a/android/core/src/processing/opengl/MaskShaderFrag.glsl b/android/core/src/processing/opengl/MaskShaderFrag.glsl new file mode 100644 index 000000000..d70e76394 --- /dev/null +++ b/android/core/src/processing/opengl/MaskShaderFrag.glsl @@ -0,0 +1,31 @@ +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2012 Ben Fry and Casey Reas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + 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 sampler2D textureSampler; +uniform sampler2D maskSampler; + +varying vec4 vertTexcoord; + +void main() { + vec3 texColor = texture2D(textureSampler, vertTexcoord.st).rgb; + vec3 maskColor = texture2D(maskSampler, vertTexcoord.st).rgb; + float luminance = dot(maskColor, vec3(0.2126, 0.7152, 0.0722)); + gl_FragColor = vec4(texColor, luminance); +} \ No newline at end of file diff --git a/android/core/src/processing/opengl/PFontTexture.java b/android/core/src/processing/opengl/PFontTexture.java index d5863891a..a4585e593 100644 --- a/android/core/src/processing/opengl/PFontTexture.java +++ b/android/core/src/processing/opengl/PFontTexture.java @@ -65,7 +65,8 @@ class PFontTexture implements PConstants { protected TextureInfo[] glyphTexinfos; protected HashMap texinfoMap; - public PFontTexture(PApplet parent, PFont font, int maxw, int maxh, boolean is3D) { + public PFontTexture(PApplet parent, PFont font, int maxw, int maxh, + boolean is3D) { this.parent = parent; this.font = font; pg = (PGraphicsOpenGL)parent.g; @@ -112,20 +113,24 @@ class PFontTexture implements PConstants { h = PApplet.min(2 * textures[currentTex].glHeight, maxTexHeight); resize = true; } else { - h = PApplet.min(PGraphicsOpenGL.maxTextureSize, PGL.MAX_FONT_TEX_SIZE / 2, maxTexHeight / 4); + h = PApplet.min(PGraphicsOpenGL.maxTextureSize, PGL.MAX_FONT_TEX_SIZE / 2, + maxTexHeight / 4); resize = false; } Texture tex; if (is3D) { - // Bilinear sampling ensures that the texture doesn't look pixelated either - // when it is magnified or minified... - tex = new Texture(parent, w, h, new Texture.Parameters(ARGB, Texture.BILINEAR, false)); + // Bilinear sampling ensures that the texture doesn't look pixelated + // either when it is magnified or minified... + tex = new Texture(parent, w, h, + new Texture.Parameters(ARGB, Texture.BILINEAR, false)); } else { - // ...however, the effect of bilinear sampling is to add some blurriness to the text - // in its original size. In 2D, we assume that text will be shown at its original - // size, so linear sampling is chosen instead (which only affects minimized text). - tex = new Texture(parent, w, h, new Texture.Parameters(ARGB, Texture.LINEAR, false)); + // ...however, the effect of bilinear sampling is to add some blurriness + // to the text in its original size. In 2D, we assume that text will be + // shown at its original size, so linear sampling is chosen instead (which + // only affects minimized text). + tex = new Texture(parent, w, h, + new Texture.Parameters(ARGB, Texture.LINEAR, false)); } if (textures == null) { @@ -253,18 +258,19 @@ class PFontTexture implements PConstants { // Adds this glyph to the opengl texture in PFont. protected void addToTexture(int idx, PFont.Glyph glyph) { - // We add one pixel to avoid issues when sampling the font texture at fractional - // screen positions. I.e.: the pixel on the screen only contains half of the - // font rectangle, so it would sample half of the color from the glyph - // area in the texture, and the other half from the contiguous pixel. If the - // later contains a portion of the neighbor glyph and the former doesn't, this - // would result in a shaded pixel when the correct output is blank. - // This is a consequence of putting all the glyphs in a common texture with - // bilinear sampling. + // We add one pixel to avoid issues when sampling the font texture at + // fractional screen positions. I.e.: the pixel on the screen only contains + // half of the font rectangle, so it would sample half of the color from the + // glyph area in the texture, and the other half from the contiguous pixel. + // If the later contains a portion of the neighbor glyph and the former + // doesn't, this would result in a shaded pixel when the correct output is + // blank. This is a consequence of putting all the glyphs in a common + // texture with bilinear sampling. int w = 1 + glyph.width + 1; int h = 1 + glyph.height + 1; - // Converting the pixels array from the PImage into a valid RGBA array for OpenGL. + // Converting the pixels array from the PImage into a valid RGBA array for + // OpenGL. int[] rgba = new int[w * h]; int t = 0; int p = 0; @@ -326,7 +332,8 @@ class PFontTexture implements PConstants { currentTex = idx; } - TextureInfo tinfo = new TextureInfo(currentTex, offsetX, offsetY, w, h, rgba); + TextureInfo tinfo = new TextureInfo(currentTex, offsetX, offsetY, + w, h, rgba); offsetX += w; if (idx == glyphTexinfos.length) { @@ -349,12 +356,13 @@ class PFontTexture implements PConstants { public float v0, v1; public int[] pixels; - public TextureInfo(int tidx, int cropX, int cropY, int cropW, int cropH, int[] pix) { + public TextureInfo(int tidx, int cropX, int cropY, int cropW, int cropH, + int[] pix) { texIndex = tidx; crop = new int[4]; // The region of the texture corresponding to the glyph is surrounded by a - // 1-pixel wide border to avoid artifacts due to bilinear sampling. This is - // why the additions and subtractions to the crop values. + // 1-pixel wide border to avoid artifacts due to bilinear sampling. This + // is why the additions and subtractions to the crop values. crop[0] = cropX + 1; crop[1] = cropY + 1 + cropH - 2; crop[2] = cropW - 2; @@ -376,7 +384,8 @@ class PFontTexture implements PConstants { void updateTex() { - textures[texIndex].setNative(pixels, crop[0] - 1, crop[1] + crop[3] - 1, crop[2] + 2, -crop[3] + 2); + textures[texIndex].setNative(pixels, crop[0] - 1, crop[1] + crop[3] - 1, + crop[2] + 2, -crop[3] + 2); } } } \ No newline at end of file diff --git a/android/core/src/processing/opengl/PGL.java b/android/core/src/processing/opengl/PGL.java index d717811f9..28d5537c2 100644 --- a/android/core/src/processing/opengl/PGL.java +++ b/android/core/src/processing/opengl/PGL.java @@ -132,18 +132,21 @@ public class PGL { * Set to true if the host system is big endian (PowerPC, MIPS, SPARC), false * if little endian (x86 Intel for Mac or PC). */ - protected static boolean BIG_ENDIAN = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; + protected static boolean BIG_ENDIAN = + ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; - protected static final String SHADER_PREPROCESSOR_DIRECTIVE = "#ifdef GL_ES\n" + - "precision mediump float;\n" + - "precision mediump int;\n" + - "#endif\n"; + protected static final String SHADER_PREPROCESSOR_DIRECTIVE = + "#ifdef GL_ES\n" + + "precision mediump float;\n" + + "precision mediump int;\n" + + "#endif\n"; /////////////////////////////////////////////////////////////////////////////////// // OpenGL constants - // The values for constants not defined in the GLES20 interface can be found in this file: + // The values for constants not defined in the GLES20 interface can be found + // in this file: // http://androidxref.com/source/raw/development/tools/glesv2debugger/src/com/android/glesv2debugger/GLEnum.java public static final int FALSE = GLES20.GL_FALSE; @@ -173,11 +176,12 @@ public class PGL { public static final int FUNC_ADD = GLES20.GL_FUNC_ADD; public static final int FUNC_MIN = 0x8007; public static final int FUNC_MAX = 0x8008; - public static final int FUNC_REVERSE_SUBTRACT = GLES20.GL_FUNC_REVERSE_SUBTRACT; + public static final int FUNC_REVERSE_SUBTRACT = + GLES20.GL_FUNC_REVERSE_SUBTRACT; - public static final int TEXTURE_2D = GLES20.GL_TEXTURE_2D; + public static final int TEXTURE_2D = GLES20.GL_TEXTURE_2D; - public static final int TEXTURE_BINDING_2D = GLES20.GL_TEXTURE_BINDING_2D; + public static final int TEXTURE_BINDING_2D = GLES20.GL_TEXTURE_BINDING_2D; public static final int RGB = GLES20.GL_RGB; public static final int RGBA = GLES20.GL_RGBA; @@ -189,8 +193,10 @@ public class PGL { public static final int NEAREST = GLES20.GL_NEAREST; public static final int LINEAR = GLES20.GL_LINEAR; - public static final int LINEAR_MIPMAP_NEAREST = GLES20.GL_LINEAR_MIPMAP_NEAREST; - public static final int LINEAR_MIPMAP_LINEAR = GLES20.GL_LINEAR_MIPMAP_LINEAR; + public static final int LINEAR_MIPMAP_NEAREST = + GLES20.GL_LINEAR_MIPMAP_NEAREST; + public static final int LINEAR_MIPMAP_LINEAR = + GLES20.GL_LINEAR_MIPMAP_LINEAR; public static final int CLAMP_TO_EDGE = GLES20.GL_CLAMP_TO_EDGE; public static final int REPEAT = GLES20.GL_REPEAT; @@ -213,14 +219,20 @@ public class PGL { public static final int SAMPLES = GLES20.GL_SAMPLES; - public static final int FRAMEBUFFER_COMPLETE = GLES20.GL_FRAMEBUFFER_COMPLETE; - public static final int FRAMEBUFFER_INCOMPLETE_ATTACHMENT = GLES20.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - public static final int FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = GLES20.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; - public static final int FRAMEBUFFER_INCOMPLETE_DIMENSIONS = GLES20.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; - public static final int FRAMEBUFFER_INCOMPLETE_FORMATS = 0x8CDA; + public static final int FRAMEBUFFER_COMPLETE = + GLES20.GL_FRAMEBUFFER_COMPLETE; + public static final int FRAMEBUFFER_INCOMPLETE_ATTACHMENT = + GLES20.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + public static final int FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = + GLES20.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; + public static final int FRAMEBUFFER_INCOMPLETE_DIMENSIONS = + GLES20.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; + public static final int FRAMEBUFFER_INCOMPLETE_FORMATS = + 0x8CDA; public static final int FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = -1; public static final int FRAMEBUFFER_INCOMPLETE_READ_BUFFER = -1; - public static final int FRAMEBUFFER_UNSUPPORTED = GLES20.GL_FRAMEBUFFER_UNSUPPORTED; + public static final int FRAMEBUFFER_UNSUPPORTED = + GLES20.GL_FRAMEBUFFER_UNSUPPORTED; public static final int STATIC_DRAW = GLES20.GL_STATIC_DRAW; public static final int DYNAMIC_DRAW = GLES20.GL_DYNAMIC_DRAW; @@ -238,12 +250,15 @@ public class PGL { public static final int RENDERER = GLES20.GL_RENDERER; public static final int VERSION = GLES20.GL_VERSION; public static final int EXTENSIONS = GLES20.GL_EXTENSIONS; - public static final int SHADING_LANGUAGE_VERSION = GLES20.GL_SHADING_LANGUAGE_VERSION; + public static final int SHADING_LANGUAGE_VERSION = + GLES20.GL_SHADING_LANGUAGE_VERSION; public static final int MAX_TEXTURE_SIZE = GLES20.GL_MAX_TEXTURE_SIZE; public static final int MAX_SAMPLES = -1; - public static final int ALIASED_LINE_WIDTH_RANGE = GLES20.GL_ALIASED_LINE_WIDTH_RANGE; - public static final int ALIASED_POINT_SIZE_RANGE = GLES20.GL_ALIASED_POINT_SIZE_RANGE; + public static final int ALIASED_LINE_WIDTH_RANGE = + GLES20.GL_ALIASED_LINE_WIDTH_RANGE; + public static final int ALIASED_POINT_SIZE_RANGE = + GLES20.GL_ALIASED_POINT_SIZE_RANGE; public static final int DEPTH_BITS = GLES20.GL_DEPTH_BITS; public static final int STENCIL_BITS = GLES20.GL_STENCIL_BITS; @@ -320,7 +335,7 @@ public class PGL { /** Which textures are bound to each target */ protected static int[] boundTextures = { 0 }; - /////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // FBO for incremental drawing @@ -331,7 +346,7 @@ public class PGL { protected int[] glColorTex = { 0, 0 }; protected int[] glColorFbo = { 0 }; - /////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Texture rendering @@ -352,22 +367,24 @@ public class PGL { }; protected FloatBuffer texData; - protected String texVertShaderSource = "attribute vec2 inVertex;" + - "attribute vec2 inTexcoord;" + - "varying vec2 vertTexcoord;" + - "void main() {" + - " gl_Position = vec4(inVertex, 0, 1);" + - " vertTexcoord = inTexcoord;" + - "}"; + protected String texVertShaderSource = + "attribute vec2 inVertex;" + + "attribute vec2 inTexcoord;" + + "varying vec2 vertTexcoord;" + + "void main() {" + + " gl_Position = vec4(inVertex, 0, 1);" + + " vertTexcoord = inTexcoord;" + + "}"; - protected String texFragShaderSource = SHADER_PREPROCESSOR_DIRECTIVE + - "uniform sampler2D textureSampler;" + - "varying vec2 vertTexcoord;" + - "void main() {" + - " gl_FragColor = texture2D(textureSampler, vertTexcoord.st);" + - "}"; + protected String texFragShaderSource = + SHADER_PREPROCESSOR_DIRECTIVE + + "uniform sampler2D textureSampler;" + + "varying vec2 vertTexcoord;" + + "void main() {" + + " gl_FragColor = texture2D(textureSampler, vertTexcoord.st);" + + "}"; - /////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // 1-pixel color, depth, stencil buffers @@ -375,7 +392,7 @@ public class PGL { protected FloatBuffer depthBuffer; protected ByteBuffer stencilBuffer; - /////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Intialization, finalization @@ -418,17 +435,23 @@ public class PGL { boolean packed = ext.indexOf("packed_depth_stencil") != -1; - // We create the GL resources we need to draw incrementally, ie: not clearing - // the screen in each frame. Because the way Android handles double buffering - // we need to handle our own custom buffering using FBOs. + // We create the GL resources we need to draw incrementally, ie: not + // clearing the screen in each frame. Because the way Android handles + // double buffering we need to handle our own custom buffering using FBOs. GLES20.glGenTextures(2, glColorTex, 0); for (int i = 0; i < 2; i++) { GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, glColorTex[i]); - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); - GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, fboWidth, fboHeight, 0, PGL.RGBA, PGL.UNSIGNED_BYTE, null); + GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); + GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); + GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); + GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, + GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); + GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, + fboWidth, fboHeight, 0, PGL.RGBA, PGL.UNSIGNED_BYTE, + null); initTexture(GLES20.GL_TEXTURE_2D, PGL.RGBA, fboWidth, fboHeight); } GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); @@ -441,17 +464,28 @@ public class PGL { int[] depthStencil = { 0 }; GLES20.glGenRenderbuffers(1, depthStencil, 0); GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthStencil[0]); - GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, DEPTH24_STENCIL8, fboWidth, fboHeight); - GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthStencil[0]); - GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_STENCIL_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthStencil[0]); + GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, DEPTH24_STENCIL8, + fboWidth, fboHeight); + GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, + GLES20.GL_DEPTH_ATTACHMENT, + GLES20.GL_RENDERBUFFER, + depthStencil[0]); + GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, + GLES20.GL_STENCIL_ATTACHMENT, + GLES20.GL_RENDERBUFFER, + depthStencil[0]); } else { // separate depth and stencil buffers int[] depth = { 0 }; int[] stencil = { 0 }; GLES20.glGenRenderbuffers(1, depth, 0); GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depth[0]); - GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, fboWidth, fboHeight); - GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depth[0]); + GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, + GLES20.GL_DEPTH_COMPONENT16, + fboWidth, fboHeight); + GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, + GLES20.GL_DEPTH_ATTACHMENT, + GLES20.GL_RENDERBUFFER, depth[0]); int[] temp = new int[1]; GLES20.glGetIntegerv(GLES20.GL_STENCIL_BITS, temp, 0); @@ -459,8 +493,12 @@ public class PGL { if (stencilBits == 8) { GLES20.glGenRenderbuffers(1, stencil, 0); GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, stencil[0]); - GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_STENCIL_INDEX8, fboWidth, fboHeight); - GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_STENCIL_ATTACHMENT, GLES20.GL_RENDERBUFFER, stencil[0]); + GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, + GLES20.GL_STENCIL_INDEX8, + fboWidth, fboHeight); + GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, + GLES20.GL_STENCIL_ATTACHMENT, + GLES20.GL_RENDERBUFFER, stencil[0]); } } @@ -528,7 +566,7 @@ public class PGL { } - /////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Frame rendering @@ -542,11 +580,15 @@ public class PGL { PGraphicsOpenGL.screenFramebuffer.glFbo = 0; } else { GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, glColorFbo[0]); - GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, glColorTex[frontTex], 0); + GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, + GLES20.GL_COLOR_ATTACHMENT0, + GLES20.GL_TEXTURE_2D, + glColorTex[frontTex], 0); validateFramebuffer(); - // We need to save the color buffer after finishing with the rendering of this frame, - // to use is as the background for the next frame ("incremental drawing"). + // We need to save the color buffer after finishing with the rendering of + // this frame, to use is as the background for the next frame + // ("incremental drawing"). GLES20.glClearColor(0, 0, 0, 0); GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT); if (firstOnscreenFrame) { @@ -554,7 +596,9 @@ public class PGL { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); } else { // Render previous draw texture as background. - drawTexture(GLES20.GL_TEXTURE_2D, glColorTex[backTex], fboWidth, fboHeight, 0, 0, pg.width, pg.height, 0, 0, pg.width, pg.height); + drawTexture(GLES20.GL_TEXTURE_2D, glColorTex[backTex], + fboWidth, fboHeight, 0, 0, pg.width, pg.height, + 0, 0, pg.width, pg.height); } PGraphicsOpenGL.screenFramebuffer.glFbo = glColorFbo[0]; } @@ -567,8 +611,9 @@ public class PGL { protected void endOnscreenDraw(boolean clear0) { if (!clear0 || FORCE_SCREEN_FBO) { - // We are in the primary surface, and no clear mode, this means that the current - // contents of the front buffer needs to be used in the next frame as the background. + // We are in the primary surface, and no clear mode, this means that the + // current contents of the front buffer needs to be used in the next frame + // as the background. GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glClearDepthf(1); @@ -577,7 +622,9 @@ public class PGL { // Render current front texture to screen, without blending. GLES20.glDisable(GLES20.GL_BLEND); - drawTexture(GLES20.GL_TEXTURE_2D, glColorTex[frontTex], fboWidth, fboHeight, 0, 0, pg.width, pg.height, 0, 0, pg.width, pg.height); + drawTexture(GLES20.GL_TEXTURE_2D, glColorTex[frontTex], + fboWidth, fboHeight, 0, 0, pg.width, pg.height, + 0, 0, pg.width, pg.height); // Swapping front and back textures. int temp = frontTex; @@ -605,7 +652,7 @@ public class PGL { } - /////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Caps query @@ -633,7 +680,7 @@ public class PGL { } - /////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Enable/disable caps @@ -652,7 +699,7 @@ public class PGL { } - /////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Render control @@ -667,7 +714,7 @@ public class PGL { } - ///////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Error handling @@ -682,7 +729,7 @@ public class PGL { } - ///////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Rendering options @@ -707,7 +754,7 @@ public class PGL { } - ///////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Textures @@ -735,13 +782,19 @@ public class PGL { } - public void texImage2D(int target, int level, int internalFormat, int width, int height, int border, int format, int type, Buffer data) { - GLES20.glTexImage2D(target, level, internalFormat, width, height, border, format, type, data); + public void texImage2D(int target, int level, int internalFormat, + int width, int height, int border, int format, + int type, Buffer data) { + GLES20.glTexImage2D(target, level, internalFormat, + width, height, border, format, type, data); } - public void texSubImage2D(int target, int level, int xOffset, int yOffset, int width, int height, int format, int type, Buffer data) { - GLES20.glTexSubImage2D(target, level, xOffset, yOffset, width, height, format, type, data); + public void texSubImage2D(int target, int level, int xOffset, int yOffset, + int width, int height, int format, + int type, Buffer data) { + GLES20.glTexSubImage2D(target, level, xOffset, yOffset, + width, height, format, type, data); } @@ -750,7 +803,8 @@ public class PGL { } - public void getTexParameteriv(int target, int param, int[] values, int offset) { + public void getTexParameteriv(int target, int param, int[] values, + int offset) { GLES20.glGetTexParameteriv(target, param, values, offset); } @@ -760,7 +814,7 @@ public class PGL { } - ///////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Vertex Buffers @@ -810,12 +864,14 @@ public class PGL { } - public void vertexAttribPointer(int loc, int size, int type, boolean normalized, int stride, int offset) { + public void vertexAttribPointer(int loc, int size, int type, + boolean normalized, int stride, int offset) { GLES20.glVertexAttribPointer(loc, size, type, normalized, stride, offset); } - public void vertexAttribPointer(int loc, int size, int type, boolean normalized, int stride, Buffer data) { + public void vertexAttribPointer(int loc, int size, int type, + boolean normalized, int stride, Buffer data) { GLES20.glVertexAttribPointer(loc, size, type, normalized, stride, data); } @@ -826,7 +882,8 @@ public class PGL { } - public ByteBuffer mapBufferRange(int target, int offset, int length, int access) { + public ByteBuffer mapBufferRange(int target, int offset, int length, + int access) { //return gl2x.glMapBufferRange(GL.GL_ARRAY_BUFFER, offset, length, GL2.GL_READ_WRITE); return null; } @@ -837,7 +894,7 @@ public class PGL { } - ///////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Framebuffers, renderbuffers @@ -867,12 +924,15 @@ public class PGL { } - public void blitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, int mask, int filter) { + public void blitFramebuffer(int srcX0, int srcY0, int srcX1, int srcY1, + int dstX0, int dstY0, int dstX1, int dstY1, + int mask, int filter) { // GLES20.glBlitFramebuffer(0, 0, srcW, srcH, 0, 0, destW, destH, GLES20.GL_COLOR_BUFFER_BIT, GLES20.GL_NEAREST); } - public void framebufferTexture2D(int target, int attachment, int texTarget, int texId, int level) { + public void framebufferTexture2D(int target, int attachment, int texTarget, + int texId, int level) { GLES20.glFramebufferTexture2D(target, attachment, texTarget, texId, level); } @@ -882,18 +942,22 @@ public class PGL { } - public void renderbufferStorageMultisample(int target, int samples, int format, int width, int height) { + public void renderbufferStorageMultisample(int target, int samples, + int format, int width, int height){ // GLES20.glRenderbufferStorageMultisample(GLES20.GL_RENDERBUFFER, samples, format, w, h); } - public void renderbufferStorage(int target, int format, int width, int height) { + public void renderbufferStorage(int target, int format, + int width, int height) { GLES20.glRenderbufferStorage(target, format, width, height); } - public void framebufferRenderbuffer(int target, int attachment, int rendbufTarget, int rendbufId) { - GLES20.glFramebufferRenderbuffer(target, attachment, rendbufTarget, rendbufId); + public void framebufferRenderbuffer(int target, int attachment, + int rendbufTarget, int rendbufId) { + GLES20.glFramebufferRenderbuffer(target, attachment, rendbufTarget, + rendbufId); } @@ -902,7 +966,7 @@ public class PGL { } - ///////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Shaders @@ -967,7 +1031,8 @@ public class PGL { } - public void uniform4i(int loc, int value0, int value1, int value2, int value3) { + public void uniform4i(int loc, int value0, int value1, int value2, + int value3) { GLES20.glUniform4i(loc, value0, value1, value2, value3); } @@ -987,7 +1052,8 @@ public class PGL { } - public void uniform4f(int loc, float value0, float value1, float value2, float value3) { + public void uniform4f(int loc, float value0, float value1, float value2, + float value3) { GLES20.glUniform4f(loc, value0, value1, value2, value3); } @@ -1032,17 +1098,20 @@ public class PGL { } - public void uniformMatrix2fv(int loc, int count, boolean transpose, float[] mat, int offset) { + public void uniformMatrix2fv(int loc, int count, boolean transpose, + float[] mat, int offset) { GLES20.glUniformMatrix2fv(loc, count, transpose, mat, offset); } - public void uniformMatrix3fv(int loc, int count, boolean transpose, float[] mat, int offset) { + public void uniformMatrix3fv(int loc, int count, boolean transpose, + float[] mat, int offset) { GLES20.glUniformMatrix3fv(loc, count, transpose, mat, offset); } - public void uniformMatrix4fv(int loc, int count, boolean transpose, float[] mat, int offset) { + public void uniformMatrix4fv(int loc, int count, boolean transpose, + float[] mat, int offset) { GLES20.glUniformMatrix4fv(loc, count, transpose, mat, offset); } @@ -1057,12 +1126,13 @@ public class PGL { } - public void vertexAttrib3f(int loc, float value0, float value1, float value2) { + public void vertexAttrib3f(int loc, float value0, float value1, float value2){ GLES20.glVertexAttrib3f(loc, value0, value1, value2); } - public void vertexAttrib4f(int loc, float value0, float value1, float value2, float value3) { + public void vertexAttrib4f(int loc, float value0, float value1, float value2, + float value3) { GLES20.glVertexAttrib4f(loc, value0, value1, value2, value3); } @@ -1122,7 +1192,7 @@ public class PGL { } - ///////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Viewport @@ -1132,7 +1202,7 @@ public class PGL { } - ///////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Clipping (scissor test) @@ -1142,7 +1212,7 @@ public class PGL { } - ///////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Blending @@ -1157,7 +1227,7 @@ public class PGL { } - ///////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Pixels @@ -1167,7 +1237,8 @@ public class PGL { } - public void readPixels(int x, int y, int width, int height, int format, int type, Buffer buffer) { + public void readPixels(int x, int y, int width, int height, int format, + int type, Buffer buffer) { GLES20.glReadPixels(x, y, width, height, format, type, buffer); } @@ -1202,7 +1273,7 @@ public class PGL { } - ///////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Context interface @@ -1236,7 +1307,7 @@ public class PGL { } - ///////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Tessellator interface @@ -1327,7 +1398,7 @@ public class PGL { } - /////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Utility functions @@ -1378,13 +1449,15 @@ public class PGL { int h = PApplet.min(16, height - y); for (int x = 0; x < width; x += 16) { int w = PApplet.min(16, width - x); - texSubImage2D(target, 0, x, y, w, h, format, UNSIGNED_BYTE, IntBuffer.wrap(texels)); + texSubImage2D(target, 0, x, y, w, h, format, UNSIGNED_BYTE, + IntBuffer.wrap(texels)); } } } - protected void copyToTexture(int target, int format, int id, int x, int y, int w, int h, IntBuffer buffer) { + protected void copyToTexture(int target, int format, int id, int x, int y, + int w, int h, IntBuffer buffer) { activeTexture(TEXTURE0); boolean enabledTex = false; if (!texturingIsEnabled(target)) { @@ -1401,14 +1474,14 @@ public class PGL { protected void drawTexture(int target, int id, int width, int height, - int X0, int Y0, int X1, int Y1) { + int X0, int Y0, int X1, int Y1) { drawTexture(target, id, width, height, X0, Y0, X1, Y1, X0, Y0, X1, Y1); } protected void drawTexture(int target, int id, int width, int height, - int texX0, int texY0, int texX1, int texY1, - int scrX0, int scrY0, int scrX1, int scrY1) { + int texX0, int texY0, int texX1, int texY1, + int scrX0, int scrY0, int scrX1, int scrY1) { if (!loadedTexShader) { texVertShader = createShader(VERTEX_SHADER, texVertShaderSource); texFragShader = createShader(FRAGMENT_SHADER, texFragShaderSource); @@ -1481,9 +1554,11 @@ public class PGL { bindTexture(target, id); texData.position(0); - vertexAttribPointer(texVertLoc, 2, FLOAT, false, 4 * SIZEOF_FLOAT, texData); + vertexAttribPointer(texVertLoc, 2, FLOAT, false, 4 * SIZEOF_FLOAT, + texData); texData.position(2); - vertexAttribPointer(texTCoordLoc, 2, FLOAT, false, 4 * SIZEOF_FLOAT, texData); + vertexAttribPointer(texTCoordLoc, 2, FLOAT, false, 4 * SIZEOF_FLOAT, + texData); drawArrays(TRIANGLE_STRIP, 0, 4); @@ -1512,7 +1587,8 @@ public class PGL { colorBuffer = IntBuffer.allocate(1); } colorBuffer.rewind(); - readPixels(scrX, pg.height - scrY - 1, 1, 1, RGBA, UNSIGNED_BYTE, colorBuffer); + readPixels(scrX, pg.height - scrY - 1, 1, 1, RGBA, UNSIGNED_BYTE, + colorBuffer); return colorBuffer.get(); } @@ -1556,10 +1632,10 @@ public class PGL { /** - * Converts input array of native OpenGL values (RGBA on big endian, ABGR on little - * endian) representing an image of width x height resolution to Java ARGB. - * It also rearranges the elements in the array so that the image is flipped - * vertically. + * Converts input array of native OpenGL values (RGBA on big endian, ABGR on + * little endian) representing an image of width x height resolution to Java + * ARGB. It also rearranges the elements in the array so that the image is + * flipped vertically. */ protected static void nativeToJavaARGB(int[] pixels, int width, int height) { int index = 0; @@ -1632,10 +1708,11 @@ public class PGL { /** - * Converts input array of native OpenGL values (RGBA on big endian, ABGR on little - * endian) representing an image of width x height resolution to Java RGB, - * so that the alpha component of all pixels is set to opaque (255). It also - * rearranges the elements in the array so that the image is flipped vertically. + * Converts input array of native OpenGL values (RGBA on big endian, ABGR on + * little endian) representing an image of width x height resolution to Java + * RGB, so that the alpha component of all pixels is set to opaque (255). It + * also rearranges the elements in the array so that the image is flipped + * vertically. */ protected static void nativeToJavaRGB(int[] pixels, int width, int height) { int index = 0; @@ -1703,10 +1780,10 @@ public class PGL { /** - * Converts input array of Java ARGB values representing an image of width x height - * resolution to native OpenGL format (RGBA on big endian, BGRA on little endian). - * It also rearranges the elements in the array so that the image is flipped - * vertically. + * Converts input array of Java ARGB values representing an image of width x + * height resolution to native OpenGL format (RGBA on big endian, BGRA on + * little endian). It also rearranges the elements in the array so that the + * image is flipped vertically. */ protected static void javaToNativeARGB(int[] pixels, int width, int height) { int index = 0; @@ -1779,10 +1856,11 @@ public class PGL { /** - * Converts input array of Java ARGB values representing an image of width x height - * resolution to native OpenGL format (RGBA on big endian, BGRA on little endian), - * while setting alpha component of all pixels to opaque (255). It also rearranges - * the elements in the array so that the image is flipped vertically. + * Converts input array of Java ARGB values representing an image of width x + * height resolution to native OpenGL format (RGBA on big endian, BGRA on + * little endian), while setting alpha component of all pixels to opaque + * (255). It also rearranges the elements in the array so that the image is + * flipped vertically. */ protected static void javaToNativeRGB(int[] pixels, int width, int height) { int index = 0; @@ -1875,37 +1953,48 @@ public class PGL { if (status == FRAMEBUFFER_COMPLETE) { return true; } else if (status == FRAMEBUFFER_INCOMPLETE_ATTACHMENT) { - throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT (" + Integer.toHexString(status) + ")"); + throw new RuntimeException( + "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT (" + + Integer.toHexString(status) + ")"); } else if (status == FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) { - throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT (" + Integer.toHexString(status) + ")"); + throw new RuntimeException( + "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT (" + + Integer.toHexString(status) + ")"); } else if (status == FRAMEBUFFER_INCOMPLETE_DIMENSIONS) { - throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS (" + Integer.toHexString(status) + ")"); + throw new RuntimeException("GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS (" + + Integer.toHexString(status) + ")"); } else if (status == FRAMEBUFFER_INCOMPLETE_FORMATS) { - throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_INCOMPLETE_FORMATS (" + Integer.toHexString(status) + ")"); + throw new RuntimeException("GL_FRAMEBUFFER_INCOMPLETE_FORMATS (" + + Integer.toHexString(status) + ")"); } else if (status == FRAMEBUFFER_UNSUPPORTED) { - throw new RuntimeException("PFramebuffer: GL_FRAMEBUFFER_UNSUPPORTED" + Integer.toHexString(status)); + throw new RuntimeException("GL_FRAMEBUFFER_UNSUPPORTED" + + Integer.toHexString(status)); } else { - throw new RuntimeException("PFramebuffer: unknown framebuffer error (" + Integer.toHexString(status) + ")"); + throw new RuntimeException("unknown framebuffer error (" + + Integer.toHexString(status) + ")"); } - } + } protected static ByteBuffer allocateDirectByteBuffer(int size) { - return ByteBuffer.allocateDirect(size * SIZEOF_BYTE).order(ByteOrder.nativeOrder()); + return ByteBuffer.allocateDirect(size * SIZEOF_BYTE). + order(ByteOrder.nativeOrder()); } protected static IntBuffer allocateDirectIntBuffer(int size) { - return ByteBuffer.allocateDirect(size * SIZEOF_INT).order(ByteOrder.nativeOrder()).asIntBuffer(); + return ByteBuffer.allocateDirect(size * SIZEOF_INT). + order(ByteOrder.nativeOrder()).asIntBuffer(); } protected static FloatBuffer allocateDirectFloatBuffer(int size) { - return ByteBuffer.allocateDirect(size * SIZEOF_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); + return ByteBuffer.allocateDirect(size * SIZEOF_FLOAT). + order(ByteOrder.nativeOrder()).asFloatBuffer(); } - ///////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Android specific stuff @@ -1920,7 +2009,8 @@ public class PGL { } - public AndroidConfigChooser getConfigChooser(int r, int g, int b, int a, int d, int s) { + public AndroidConfigChooser getConfigChooser(int r, int g, int b, int a, + int d, int s) { return new AndroidConfigChooser(r, g, b, a, d, s); } @@ -1949,16 +2039,20 @@ public class PGL { } - protected class AndroidContextFactory implements GLSurfaceView.EGLContextFactory { + protected class AndroidContextFactory implements + GLSurfaceView.EGLContextFactory { public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; - EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); + EGLContext context = egl.eglCreateContext(display, eglConfig, + EGL10.EGL_NO_CONTEXT, + attrib_list); return context; } - public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) { + public void destroyContext(EGL10 egl, EGLDisplay display, + EGLContext context) { egl.eglDestroyContext(display, context); } } @@ -1973,7 +2067,8 @@ public class PGL { public int depthTarget; public int stencilTarget; - // Actual rgba color, depth and stencil sizes (in bits) supported by the device. + // Actual rgba color, depth and stencil sizes (in bits) supported by the + // device. public int redBits; public int greenBits; public int blueBits; @@ -1988,7 +2083,8 @@ public class PGL { protected int[] configAttribsGL = { EGL10.EGL_RED_SIZE, 4, EGL10.EGL_GREEN_SIZE, 4, EGL10.EGL_BLUE_SIZE, 4, - EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL10.EGL_RENDERABLE_TYPE, + EGL_OPENGL_ES2_BIT, EGL10.EGL_NONE }; public AndroidConfigChooser(int r, int g, int b, int a, int d, int s) { @@ -2029,20 +2125,28 @@ public class PGL { return chooseBestConfig(egl, display, configs); } - public EGLConfig chooseBestConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) { + public EGLConfig chooseBestConfig(EGL10 egl, EGLDisplay display, + EGLConfig[] configs) { EGLConfig bestConfig = null; float bestScore = 1000; for (EGLConfig config : configs) { - int gl = findConfigAttrib(egl, display, config, EGL10.EGL_RENDERABLE_TYPE, 0); + int gl = findConfigAttrib(egl, display, config, + EGL10.EGL_RENDERABLE_TYPE, 0); if (gl == EGL_OPENGL_ES2_BIT) { - int d = findConfigAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE, 0); - int s = findConfigAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE, 0); + int d = findConfigAttrib(egl, display, config, + EGL10.EGL_DEPTH_SIZE, 0); + int s = findConfigAttrib(egl, display, config, + EGL10.EGL_STENCIL_SIZE, 0); - int r = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE, 0); - int g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0); - int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0); - int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0); + int r = findConfigAttrib(egl, display, config, + EGL10.EGL_RED_SIZE, 0); + int g = findConfigAttrib(egl, display, config, + EGL10.EGL_GREEN_SIZE, 0); + int b = findConfigAttrib(egl, display, config, + EGL10.EGL_BLUE_SIZE, 0); + int a = findConfigAttrib(egl, display, config, + EGL10.EGL_ALPHA_SIZE, 0); float score = 0.20f * PApplet.abs(r - redTarget) + 0.20f * PApplet.abs(g - greenTarget) + @@ -2077,24 +2181,38 @@ public class PGL { return bestConfig; } - protected String printConfig(EGL10 egl, EGLDisplay display, EGLConfig config) { - int r = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE, 0); - int g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0); - int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0); - int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0); - int d = findConfigAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE, 0); - int s = findConfigAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE, 0); - int type = findConfigAttrib(egl, display, config, EGL10.EGL_RENDERABLE_TYPE, 0); - int nat = findConfigAttrib(egl, display, config, EGL10.EGL_NATIVE_RENDERABLE, 0); - int bufSize = findConfigAttrib(egl, display, config, EGL10.EGL_BUFFER_SIZE, 0); - int bufSurf = findConfigAttrib(egl, display, config, EGL10.EGL_RENDER_BUFFER, 0); + protected String printConfig(EGL10 egl, EGLDisplay display, + EGLConfig config) { + int r = findConfigAttrib(egl, display, config, + EGL10.EGL_RED_SIZE, 0); + int g = findConfigAttrib(egl, display, config, + EGL10.EGL_GREEN_SIZE, 0); + int b = findConfigAttrib(egl, display, config, + EGL10.EGL_BLUE_SIZE, 0); + int a = findConfigAttrib(egl, display, config, + EGL10.EGL_ALPHA_SIZE, 0); + int d = findConfigAttrib(egl, display, config, + EGL10.EGL_DEPTH_SIZE, 0); + int s = findConfigAttrib(egl, display, config, + EGL10.EGL_STENCIL_SIZE, 0); + int type = findConfigAttrib(egl, display, config, + EGL10.EGL_RENDERABLE_TYPE, 0); + int nat = findConfigAttrib(egl, display, config, + EGL10.EGL_NATIVE_RENDERABLE, 0); + int bufSize = findConfigAttrib(egl, display, config, + EGL10.EGL_BUFFER_SIZE, 0); + int bufSurf = findConfigAttrib(egl, display, config, + EGL10.EGL_RENDER_BUFFER, 0); - return String.format("EGLConfig rgba=%d%d%d%d depth=%d stencil=%d", r,g,b,a,d,s) + return String.format("EGLConfig rgba=%d%d%d%d depth=%d stencil=%d", + r,g,b,a,d,s) + " type=" + type + " native=" + nat + " buffer size=" + bufSize + " buffer surface=" + bufSurf + - String.format(" caveat=0x%04x", findConfigAttrib(egl, display, config, EGL10.EGL_CONFIG_CAVEAT, 0)); + String.format(" caveat=0x%04x", + findConfigAttrib(egl, display, config, + EGL10.EGL_CONFIG_CAVEAT, 0)); } protected int findConfigAttrib(EGL10 egl, EGLDisplay display, diff --git a/android/core/src/processing/opengl/PGraphics2D.java b/android/core/src/processing/opengl/PGraphics2D.java index 6482001e6..44d704a1c 100644 --- a/android/core/src/processing/opengl/PGraphics2D.java +++ b/android/core/src/processing/opengl/PGraphics2D.java @@ -33,224 +33,230 @@ import processing.core.PShapeSVG; import processing.data.XML; public class PGraphics2D extends PGraphicsOpenGL { - + public PGraphics2D() { super(); - hints[ENABLE_PERSPECTIVE_CORRECTED_LINES] = false; + hints[ENABLE_STROKE_PERSPECTIVE] = false; } - + ////////////////////////////////////////////////////////////// // RENDERER SUPPORT QUERIES - - + + public boolean is2D() { return true; } - + public boolean is3D() { return false; - } - - + } + + ////////////////////////////////////////////////////////////// // HINTS - + public void hint(int which) { - if (which == ENABLE_PERSPECTIVE_CORRECTED_LINES) { + if (which == ENABLE_STROKE_PERSPECTIVE) { showWarning("2D lines cannot be perspective-corrected."); return; } super.hint(which); } - + ////////////////////////////////////////////////////////////// // PROJECTION - - + + public void ortho() { showMethodWarning("ortho"); } - - + + public void ortho(float left, float right, float bottom, float top) { showMethodWarning("ortho"); } - - + + public void ortho(float left, float right, float bottom, float top, float near, float far) { showMethodWarning("ortho"); } - - + + public void perspective() { showMethodWarning("perspective"); - } - - + } + + public void perspective(float fov, float aspect, float zNear, float zFar) { showMethodWarning("perspective"); } - - + + public void frustum(float left, float right, float bottom, float top, float znear, float zfar) { showMethodWarning("frustum"); } - - - protected void defaultPerspective() { + + + protected void defaultPerspective() { super.ortho(-width/2, +width/2, -height/2, +height/2, -1, +1); } - - + + ////////////////////////////////////////////////////////////// // CAMERA - - + + public void beginCamera() { showMethodWarning("beginCamera"); } - - + + public void endCamera() { showMethodWarning("endCamera"); } - - + + public void camera() { showMethodWarning("camera"); } - - + + public void camera(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ) { showMethodWarning("camera"); } - - protected void defaultCamera() { + + protected void defaultCamera() { super.camera(width/2, height/2); } - - + + ////////////////////////////////////////////////////////////// // MATRIX MORE! - - + + protected void begin2D() { pushProjection(); defaultPerspective(); pushMatrix(); - defaultCamera(); + defaultCamera(); } - + protected void end2D() { popMatrix(); - popProjection(); - } + popProjection(); + } + - ////////////////////////////////////////////////////////////// // SHAPE - - + + public void shape(PShape shape) { if (shape.is2D()) { super.shape(shape); } else { - showWarning("The shape object is not 2D, cannot be displayed with this renderer"); + showWarning("The shape object is not 2D, cannot be displayed with " + + "this renderer"); } } - - + + public void shape(PShape shape, float x, float y) { if (shape.is2D()) { super.shape(shape, x, y); } else { - showWarning("The shape object is not 2D, cannot be displayed with this renderer"); - } + showWarning("The shape object is not 2D, cannot be displayed with " + + "this renderer"); + } } - - + + public void shape(PShape shape, float a, float b, float c, float d) { if (shape.is2D()) { super.shape(shape, a, b, c, d); } else { - showWarning("The shape object is not 2D, cannot be displayed with this renderer"); - } + showWarning("The shape object is not 2D, cannot be displayed with " + + "this renderer"); + } } - - + + public void shape(PShape shape, float x, float y, float z) { - showDepthWarningXYZ("shape"); + showDepthWarningXYZ("shape"); } - - - public void shape(PShape shape, float x, float y, float z, float c, float d, float e) { - showDepthWarningXYZ("shape"); + + + public void shape(PShape shape, float x, float y, float z, + float c, float d, float e) { + showDepthWarningXYZ("shape"); } - - + + ////////////////////////////////////////////////////////////// // SHAPE I/O - - + + static protected boolean isSupportedExtension(String extension) { return extension.equals("svg") || extension.equals("svgz"); } - static protected PShape2D loadShapeImpl(PGraphics pg, String filename, String extension) { + static protected PShape2D loadShapeImpl(PGraphics pg, String filename, + String extension) { PShapeSVG svg = null; - - try { - if (extension.equals("svg")) { - svg = new PShapeSVG(pg.parent, filename); - } else if (extension.equals("svgz")) { - InputStream input = new GZIPInputStream(pg.parent.createInput(filename)); + if (extension.equals("svg")) { + svg = new PShapeSVG(pg.parent, filename); + + } else if (extension.equals("svgz")) { + try { + InputStream input = + new GZIPInputStream(pg.parent.createInput(filename)); XML xml = new XML(PApplet.createReader(input)); svg = new PShapeSVG(xml); + } catch (Exception e) { + e.printStackTrace(); } - } catch (Exception e) { - e.printStackTrace(); } - + if (svg != null) { - PShape2D p2d = PShape2D.createShape(pg.parent, svg); + PShape2D p2d = PShape2D.createShape(pg.parent, svg); return p2d; } else { return null; } } - + ////////////////////////////////////////////////////////////// // SHAPE CREATION - - + + public PShape createShape(PShape source) { - return PShape2D.createShape(parent, source); + return PShape2D.createShape(parent, source); } - + public PShape createShape() { return createShape(POLYGON); } @@ -259,13 +265,13 @@ public class PGraphics2D extends PGraphicsOpenGL { public PShape createShape(int type) { return createShapeImpl(parent, type); } - - + + public PShape createShape(int kind, float... p) { - return createShapeImpl(parent, kind, p); + return createShapeImpl(parent, kind, p); } - - + + static protected PShape2D createShapeImpl(PApplet parent, int type) { PShape2D shape = null; if (type == PShape.GROUP) { @@ -301,7 +307,8 @@ public class PGraphics2D extends PGraphicsOpenGL { } - static protected PShape2D createShapeImpl(PApplet parent, int kind, float... p) { + static protected PShape2D createShapeImpl(PApplet parent, int kind, + float... p) { PShape2D shape = null; int len = p.length; @@ -367,21 +374,21 @@ public class PGraphics2D extends PGraphicsOpenGL { } return shape; - } - - + } + + ////////////////////////////////////////////////////////////// // BEZIER VERTICES - + public void bezierVertex(float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4) { showDepthWarningXYZ("bezierVertex"); } - - + + ////////////////////////////////////////////////////////////// // QUADRATIC BEZIER VERTICES @@ -390,19 +397,19 @@ public class PGraphics2D extends PGraphicsOpenGL { public void quadraticVertex(float x2, float y2, float z2, float x4, float y4, float z4) { showDepthWarningXYZ("quadVertex"); - } - - + } + + ////////////////////////////////////////////////////////////// - // CURVE VERTICES - - + // CURVE VERTICES + + public void curveVertex(float x, float y, float z) { showDepthWarningXYZ("curveVertex"); - } - - + } + + ////////////////////////////////////////////////////////////// // BOX @@ -410,9 +417,9 @@ public class PGraphics2D extends PGraphicsOpenGL { public void box(float w, float h, float d) { showMethodWarning("box"); - } + } + - ////////////////////////////////////////////////////////////// // SPHERE @@ -420,30 +427,30 @@ public class PGraphics2D extends PGraphicsOpenGL { public void sphere(float r) { showMethodWarning("sphere"); - } - - + } + + ////////////////////////////////////////////////////////////// // VERTEX SHAPES - - + + public void vertex(float x, float y, float z) { showDepthWarningXYZ("vertex"); } - + public void vertex(float x, float y, float z, float u, float v) { showDepthWarningXYZ("vertex"); - } - + } + ////////////////////////////////////////////////////////////// - // MATRIX TRANSFORMATIONS - + // MATRIX TRANSFORMATIONS + public void translate(float tx, float ty, float tz) { showDepthWarningXYZ("translate"); } - + public void rotateX(float angle) { showDepthWarning("rotateX"); } @@ -458,27 +465,27 @@ public class PGraphics2D extends PGraphicsOpenGL { public void rotate(float angle, float vx, float vy, float vz) { showVariationWarning("rotate"); - } - + } + public void applyMatrix(PMatrix3D source) { showVariationWarning("applyMatrix"); } - + public void applyMatrix(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) { showVariationWarning("applyMatrix"); - } - + } + public void scale(float sx, float sy, float sz) { showDepthWarningXYZ("scale"); } - + ////////////////////////////////////////////////////////////// - // SCREEN AND MODEL COORDS - + // SCREEN AND MODEL COORDS + public float screenX(float x, float y, float z) { showDepthWarningXYZ("screenX"); return 0; @@ -492,18 +499,18 @@ public class PGraphics2D extends PGraphicsOpenGL { public float screenZ(float x, float y, float z) { showDepthWarningXYZ("screenZ"); return 0; - } - + } + public PMatrix3D getMatrix(PMatrix3D target) { showVariationWarning("getMatrix"); return target; } - + public void setMatrix(PMatrix3D source) { showVariationWarning("setMatrix"); } - - ////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////// // LIGHTS diff --git a/android/core/src/processing/opengl/PGraphics3D.java b/android/core/src/processing/opengl/PGraphics3D.java index e93fdc29b..c85847fb2 100644 --- a/android/core/src/processing/opengl/PGraphics3D.java +++ b/android/core/src/processing/opengl/PGraphics3D.java @@ -34,6 +34,11 @@ import processing.core.PVector; public class PGraphics3D extends PGraphicsOpenGL { + public PGraphics3D() { + super(); + hints[ENABLE_STROKE_PERSPECTIVE] = true; + } + ////////////////////////////////////////////////////////////// // RENDERER SUPPORT QUERIES @@ -98,7 +103,8 @@ public class PGraphics3D extends PGraphicsOpenGL { } - static protected PShape loadShapeImpl(PGraphics pg, String filename, String ext) { + static protected PShape loadShapeImpl(PGraphics pg, String filename, + String ext) { ArrayList vertices = new ArrayList(); ArrayList normals = new ArrayList(); ArrayList textures = new ArrayList(); @@ -205,7 +211,8 @@ public class PGraphics3D extends PGraphicsOpenGL { root.addChild(child); } - pg.colorMode(prevColorMode, prevColorModeX, prevColorModeY, prevColorModeZ, prevColorModeA); + pg.colorMode(prevColorMode, prevColorModeX, prevColorModeY, prevColorModeZ, + prevColorModeA); pg.stroke = prevStroke; pg.textureMode = prevTextureMode; @@ -358,11 +365,12 @@ public class PGraphics3D extends PGraphicsOpenGL { static protected void parseOBJ(PApplet parent, - BufferedReader reader, ArrayList vertices, - ArrayList normals, - ArrayList textures, - ArrayList faces, - ArrayList materials) { + BufferedReader reader, + ArrayList vertices, + ArrayList normals, + ArrayList textures, + ArrayList faces, + ArrayList materials) { Hashtable mtlTable = new Hashtable(); int mtlIdxCur = -1; boolean readv, readvn, readvt; @@ -411,10 +419,11 @@ public class PGraphics3D extends PGraphicsOpenGL { normals.add(tempn); readvn = true; } else if (elements[0].equals("vt")) { - // uv, inverting v to take into account Processing's invertex Y axis with - // respect to OpenGL. + // uv, inverting v to take into account Processing's invertex Y axis + // with respect to OpenGL. PVector tempv = new PVector(Float.valueOf(elements[1]).floatValue(), - 1 - Float.valueOf(elements[2]).floatValue()); + 1 - Float.valueOf(elements[2]). + floatValue()); textures.add(tempv); readvt = true; } else if (elements[0].equals("o")) { @@ -511,8 +520,9 @@ public class PGraphics3D extends PGraphicsOpenGL { static protected void parseMTL(PApplet parent, - BufferedReader reader, ArrayList materials, - Hashtable materialsHash) { + BufferedReader reader, + ArrayList materials, + Hashtable materialsHash) { try { String line; OBJMaterial currentMtl = null; @@ -550,7 +560,8 @@ public class PGraphics3D extends PGraphicsOpenGL { currentMtl.ks.x = Float.valueOf(elements[1]).floatValue(); currentMtl.ks.y = Float.valueOf(elements[2]).floatValue(); currentMtl.ks.z = Float.valueOf(elements[3]).floatValue(); - } else if ((elements[0].equals("d") || elements[0].equals("Tr")) && elements.length > 1) { + } else if ((elements[0].equals("d") || + elements[0].equals("Tr")) && elements.length > 1) { // Reading the alpha transparency. currentMtl.d = Float.valueOf(elements[1]).floatValue(); } else if (elements[0].equals("Ns") && elements.length > 1) { diff --git a/android/core/src/processing/opengl/PGraphicsOpenGL.java b/android/core/src/processing/opengl/PGraphicsOpenGL.java index a093217bd..c39d7dc0a 100644 --- a/android/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/android/core/src/processing/opengl/PGraphicsOpenGL.java @@ -38,6 +38,8 @@ import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * OpenGL renderer. @@ -137,43 +139,72 @@ public class PGraphicsOpenGL extends PGraphics { // GL objects: - static protected HashMap glTextureObjects = new HashMap(); - static protected HashMap glVertexBuffers = new HashMap(); - static protected HashMap glFrameBuffers = new HashMap(); - static protected HashMap glRenderBuffers = new HashMap(); - static protected HashMap glslPrograms = new HashMap(); - static protected HashMap glslVertexShaders = new HashMap(); - static protected HashMap glslFragmentShaders = new HashMap(); + static protected HashMap glTextureObjects = + new HashMap(); + static protected HashMap glVertexBuffers = + new HashMap(); + static protected HashMap glFrameBuffers = + new HashMap(); + static protected HashMap glRenderBuffers = + new HashMap(); + static protected HashMap glslPrograms = + new HashMap(); + static protected HashMap glslVertexShaders = + new HashMap(); + static protected HashMap glslFragmentShaders = + new HashMap(); // ........................................................ // Shaders - static protected URL defPolyFlatShaderVertURL = PGraphicsOpenGL.class.getResource("PolyFlatShaderVert.glsl"); - static protected URL defPolyTexShaderVertURL = PGraphicsOpenGL.class.getResource("PolyTexShaderVert.glsl"); - static protected URL defPolyLightShaderVertURL = PGraphicsOpenGL.class.getResource("PolyLightShaderVert.glsl"); - static protected URL defPolyFullShaderVertURL = PGraphicsOpenGL.class.getResource("PolyFullShaderVert.glsl"); - static protected URL defPolyNoTexShaderFragURL = PGraphicsOpenGL.class.getResource("PolyNoTexShaderFrag.glsl"); - static protected URL defPolyTexShaderFragURL = PGraphicsOpenGL.class.getResource("PolyTexShaderFrag.glsl"); - static protected URL defLineShaderVertURL = PGraphicsOpenGL.class.getResource("LineShaderVert.glsl"); - static protected URL defLineShaderFragURL = PGraphicsOpenGL.class.getResource("LineShaderFrag.glsl"); - static protected URL defPointShaderVertURL = PGraphicsOpenGL.class.getResource("PointShaderVert.glsl"); - static protected URL defPointShaderFragURL = PGraphicsOpenGL.class.getResource("PointShaderFrag.glsl"); - - static protected PolyFlatShader defPolyFlatShader; + static protected URL defPolyColorShaderVertURL = + PGraphicsOpenGL.class.getResource("PolyColorShaderVert.glsl"); + static protected URL defPolyTexShaderVertURL = + PGraphicsOpenGL.class.getResource("PolyTexShaderVert.glsl"); + static protected URL defPolyLightShaderVertURL = + PGraphicsOpenGL.class.getResource("PolyLightShaderVert.glsl"); + static protected URL defPolyTexlightShaderVertURL = + PGraphicsOpenGL.class.getResource("PolyTexlightShaderVert.glsl"); + static protected URL defPolyNoTexShaderFragURL = + PGraphicsOpenGL.class.getResource("PolyNoTexShaderFrag.glsl"); + static protected URL defPolyTexShaderFragURL = + PGraphicsOpenGL.class.getResource("PolyTexShaderFrag.glsl"); + static protected URL defLineShaderVertURL = + PGraphicsOpenGL.class.getResource("LineShaderVert.glsl"); + static protected URL defLineShaderFragURL = + PGraphicsOpenGL.class.getResource("LineShaderFrag.glsl"); + static protected URL defPointShaderVertURL = + PGraphicsOpenGL.class.getResource("PointShaderVert.glsl"); + static protected URL defPointShaderFragURL = + PGraphicsOpenGL.class.getResource("PointShaderFrag.glsl"); + + static protected PolyColorShader defPolyColorShader; static protected PolyTexShader defPolyTexShader; static protected PolyLightShader defPolyLightShader; - static protected PolyFullShader defPolyFullShader; + static protected PolyTexlightShader defPolyTexlightShader; static protected LineShader defLineShader; static protected PointShader defPointShader; - protected PolyFlatShader polyFlatShader; + static protected URL maskShaderFragURL = + PGraphicsOpenGL.class.getResource("MaskShaderFrag.glsl"); + static protected PolyTexShader maskShader; + + protected PolyColorShader polyColorShader; protected PolyTexShader polyTexShader; protected PolyLightShader polyLightShader; - protected PolyFullShader polyFullShader; + protected PolyTexlightShader polyTexlightShader; protected LineShader lineShader; protected PointShader pointShader; + // When shader warnings are enabled, the renderer is strict in regards to the + // use of the polygon shaders. For instance, if a light shader is set to + // render lit geometry, but the geometry is mixed with some pieces of unlit or + // textured geometry, then it will warn that the set shader cannot be used for + // that other type of geometry, even though Processing will use the correct, + // built-in shaders to handle it. + protected boolean shaderWarningsEnabled = true; + // ........................................................ // Tessellator, geometry @@ -435,7 +466,8 @@ public class PGraphicsOpenGL extends PGraphics { final static protected float POINT_ACCURACY_FACTOR = 10.0f; /** Used in quad point tessellation. */ - final protected float[][] QUAD_POINT_SIGNS = { {-1, +1}, {-1, -1}, {+1, -1}, {+1, +1} }; + final protected float[][] QUAD_POINT_SIGNS = + { {-1, +1}, {-1, -1}, {+1, -1}, {+1, +1} }; ////////////////////////////////////////////////////////////// @@ -502,7 +534,8 @@ public class PGraphicsOpenGL extends PGraphics { public void setSize(int iwidth, int iheight) { - resized = (0 < width && width != iwidth) || (0 < height && height != iwidth); + resized = (0 < width && width != iwidth) || + (0 < height && height != iwidth); width = iwidth; height = iheight; @@ -600,7 +633,7 @@ public class PGraphicsOpenGL extends PGraphics { } - // Texture Objects ------------------------------------------- + // Texture Objects ----------------------------------------------------------- protected int createTextureObject(int context) { deleteFinalizedTextureObjects(); @@ -668,7 +701,7 @@ public class PGraphicsOpenGL extends PGraphics { } } - // Vertex Buffer Objects ---------------------------------------------- + // Vertex Buffer Objects ----------------------------------------------------- protected int createVertexBufferObject(int context) { deleteFinalizedVertexBufferObjects(); @@ -736,7 +769,7 @@ public class PGraphicsOpenGL extends PGraphics { } } - // FrameBuffer Objects ----------------------------------------- + // FrameBuffer Objects ------------------------------------------------------- protected int createFrameBufferObject(int context) { deleteFinalizedFrameBufferObjects(); @@ -804,7 +837,7 @@ public class PGraphicsOpenGL extends PGraphics { } } - // RenderBuffer Objects ----------------------------------------------- + // RenderBuffer Objects ------------------------------------------------------ protected int createRenderBufferObject(int context) { deleteFinalizedRenderBufferObjects(); @@ -872,7 +905,7 @@ public class PGraphicsOpenGL extends PGraphics { } } - // GLSL Program Objects ----------------------------------------------- + // GLSL Program Objects ------------------------------------------------------ protected int createGLSLProgramObject(int context) { deleteFinalizedGLSLProgramObjects(); @@ -935,7 +968,7 @@ public class PGraphicsOpenGL extends PGraphics { } } - // GLSL Vertex Shader Objects ----------------------------------------------- + // GLSL Vertex Shader Objects ------------------------------------------------ protected int createGLSLVertShaderObject(int context) { deleteFinalizedGLSLVertShaderObjects(); @@ -969,7 +1002,8 @@ public class PGraphicsOpenGL extends PGraphics { } // This is synchronized because it is called from the GC thread. - synchronized protected void finalizeGLSLVertShaderObject(int id, int context) { + synchronized protected void finalizeGLSLVertShaderObject(int id, + int context) { GLResource res = new GLResource(id, context); if (glslVertexShaders.containsKey(res)) { glslVertexShaders.put(res, true); @@ -998,7 +1032,7 @@ public class PGraphicsOpenGL extends PGraphics { } } - // GLSL Fragment Shader Objects ----------------------------------------------- + // GLSL Fragment Shader Objects ---------------------------------------------- protected int createGLSLFragShaderObject(int context) { deleteFinalizedGLSLFragShaderObjects(); @@ -1032,7 +1066,8 @@ public class PGraphicsOpenGL extends PGraphics { } // This is synchronized because it is called from the GC thread. - synchronized protected void finalizeGLSLFragShaderObject(int id, int context) { + synchronized protected void finalizeGLSLFragShaderObject(int id, + int context) { GLResource res = new GLResource(id, context); if (glslFragmentShaders.containsKey(res)) { glslFragmentShaders.put(res, true); @@ -1061,7 +1096,7 @@ public class PGraphicsOpenGL extends PGraphics { } } - // All OpenGL resources ----------------------------------------------- + // All OpenGL resources ------------------------------------------------------ protected void deleteFinalizedGLResources() { deleteFinalizedTextureObjects(); @@ -1134,19 +1169,23 @@ public class PGraphicsOpenGL extends PGraphics { pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyTexcoord); pgl.bufferData(PGL.ARRAY_BUFFER, 2 * sizef, null, PGL.STATIC_DRAW); - glPolyAmbient = pgPrimary.createVertexBufferObject(polyBuffersContext.code()); + glPolyAmbient = pgPrimary.createVertexBufferObject( + polyBuffersContext.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyAmbient); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, null, PGL.STATIC_DRAW); - glPolySpecular = pgPrimary.createVertexBufferObject(polyBuffersContext.code()); + glPolySpecular = pgPrimary.createVertexBufferObject( + polyBuffersContext.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolySpecular); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, null, PGL.STATIC_DRAW); - glPolyEmissive = pgPrimary.createVertexBufferObject(polyBuffersContext.code()); + glPolyEmissive = pgPrimary.createVertexBufferObject( + polyBuffersContext.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyEmissive); pgl.bufferData(PGL.ARRAY_BUFFER, sizei, null, PGL.STATIC_DRAW); - glPolyShininess = pgPrimary.createVertexBufferObject(polyBuffersContext.code()); + glPolyShininess = pgPrimary.createVertexBufferObject( + polyBuffersContext.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyShininess); pgl.bufferData(PGL.ARRAY_BUFFER, sizef, null, PGL.STATIC_DRAW); @@ -1171,37 +1210,46 @@ public class PGraphicsOpenGL extends PGraphics { int sizei = size * PGL.SIZEOF_INT; pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyVertex); - pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, FloatBuffer.wrap(tessGeo.polyVertices, 0, 4 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, + FloatBuffer.wrap(tessGeo.polyVertices, 0, 4 * size), PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyColor); - pgl.bufferData(PGL.ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.polyColors, 0, size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, sizei, + IntBuffer.wrap(tessGeo.polyColors, 0, size), PGL.STATIC_DRAW); if (lit) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyNormal); - pgl.bufferData(PGL.ARRAY_BUFFER, 3 * sizef, FloatBuffer.wrap(tessGeo.polyNormals, 0, 3 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 3 * sizef, + FloatBuffer.wrap(tessGeo.polyNormals, 0, 3 * size), PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyAmbient); - pgl.bufferData(PGL.ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.polyAmbient, 0, size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, sizei, + IntBuffer.wrap(tessGeo.polyAmbient, 0, size), PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolySpecular); - pgl.bufferData(PGL.ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.polySpecular, 0, size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, sizei, + IntBuffer.wrap(tessGeo.polySpecular, 0, size), PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyEmissive); - pgl.bufferData(PGL.ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.polyEmissive, 0, size), PGL.STATIC_DRAW); - + pgl.bufferData(PGL.ARRAY_BUFFER, sizei, + IntBuffer.wrap(tessGeo.polyEmissive, 0, size), PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyShininess); - pgl.bufferData(PGL.ARRAY_BUFFER, sizef, FloatBuffer.wrap(tessGeo.polyShininess, 0, size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, sizef, + FloatBuffer.wrap(tessGeo.polyShininess, 0, size), PGL.STATIC_DRAW); } if (tex) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyTexcoord); - pgl.bufferData(PGL.ARRAY_BUFFER, 2 * sizef, FloatBuffer.wrap(tessGeo.polyTexcoords, 0, 2 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 2 * sizef, + FloatBuffer.wrap(tessGeo.polyTexcoords, 0, 2 * size), PGL.STATIC_DRAW); } pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glPolyIndex); - pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, tessGeo.polyIndexCount * PGL.SIZEOF_INDEX, - ShortBuffer.wrap(tessGeo.polyIndices, 0, tessGeo.polyIndexCount), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, + tessGeo.polyIndexCount * PGL.SIZEOF_INDEX, + ShortBuffer.wrap(tessGeo.polyIndices, 0, tessGeo.polyIndexCount), + PGL.STATIC_DRAW); } @@ -1292,17 +1340,22 @@ public class PGraphicsOpenGL extends PGraphics { int sizei = size * PGL.SIZEOF_INT; pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineVertex); - pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, FloatBuffer.wrap(tessGeo.lineVertices, 0, 4 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, + FloatBuffer.wrap(tessGeo.lineVertices, 0, 4 * size), PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineColor); - pgl.bufferData(PGL.ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.lineColors, 0, size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, sizei, + IntBuffer.wrap(tessGeo.lineColors, 0, size), PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineAttrib); - pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, FloatBuffer.wrap(tessGeo.lineAttribs, 0, 4 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, + FloatBuffer.wrap(tessGeo.lineAttribs, 0, 4 * size), PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glLineIndex); - pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, tessGeo.lineIndexCount * PGL.SIZEOF_INDEX, - ShortBuffer.wrap(tessGeo.lineIndices, 0, tessGeo.lineIndexCount), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, + tessGeo.lineIndexCount * PGL.SIZEOF_INDEX, + ShortBuffer.wrap(tessGeo.lineIndices, 0, tessGeo.lineIndexCount), + PGL.STATIC_DRAW); } @@ -1377,17 +1430,22 @@ public class PGraphicsOpenGL extends PGraphics { int sizei = size * PGL.SIZEOF_INT; pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointVertex); - pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, FloatBuffer.wrap(tessGeo.pointVertices, 0, 4 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, + FloatBuffer.wrap(tessGeo.pointVertices, 0, 4 * size), PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointColor); - pgl.bufferData(PGL.ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.pointColors, 0, size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, sizei, + IntBuffer.wrap(tessGeo.pointColors, 0, size), PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointAttrib); - pgl.bufferData(PGL.ARRAY_BUFFER, 2 * sizef, FloatBuffer.wrap(tessGeo.pointAttribs, 0, 2 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 2 * sizef, + FloatBuffer.wrap(tessGeo.pointAttribs, 0, 2 * size), PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glPointIndex); - pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, tessGeo.pointIndexCount * PGL.SIZEOF_INDEX, - ShortBuffer.wrap(tessGeo.pointIndices, 0, tessGeo.pointIndexCount), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, + tessGeo.pointIndexCount * PGL.SIZEOF_INDEX, + ShortBuffer.wrap(tessGeo.pointIndices, 0, tessGeo.pointIndexCount), + PGL.STATIC_DRAW); } @@ -1447,10 +1505,13 @@ public class PGraphicsOpenGL extends PGraphics { return; } - if (pgCurrent != null && !pgCurrent.primarySurface && !this.primarySurface) { - // It seems that the user is trying to start another beginDraw()/endDraw() block for an - // offscreen surface, still drawing on another offscreen surface. - showWarning("Already called beginDraw() for another PGraphicsOpenGL object."); + if (pgCurrent != null && !pgCurrent.primarySurface && + !this.primarySurface) { + // It seems that the user is trying to start another beginDraw()/endDraw() + // block for an offscreen surface, still drawing on another offscreen + // surface. + showWarning("Already called beginDraw() for another " + + "PGraphicsOpenGL object."); return; } @@ -1472,8 +1533,10 @@ public class PGraphicsOpenGL extends PGraphics { if (!pgl.initialized) { initOffscreen(); } else { - boolean outdated = offscreenFramebuffer != null && offscreenFramebuffer.contextIsOutdated(); - boolean outdatedMulti = offscreenFramebufferMultisample != null && offscreenFramebufferMultisample.contextIsOutdated(); + boolean outdated = offscreenFramebuffer != null && + offscreenFramebuffer.contextIsOutdated(); + boolean outdatedMulti = offscreenFramebufferMultisample != null && + offscreenFramebufferMultisample.contextIsOutdated(); if (outdated || outdatedMulti) { pgl.initialized = false; initOffscreen(); @@ -1675,7 +1738,8 @@ public class PGraphicsOpenGL extends PGraphics { offscreenFramebufferMultisample.copy(offscreenFramebuffer); } - if (!pgl.initialized || !pgPrimary.pgl.initialized || parent.frameCount == 0) { + if (!pgl.initialized || !pgPrimary.pgl.initialized || + parent.frameCount == 0) { // If the primary surface is re-initialized, this offscreen // surface needs to save its contents into the pixels array // so they can be restored after the FBOs are recreated. @@ -1817,7 +1881,8 @@ public class PGraphicsOpenGL extends PGraphics { // We can write directly to the color FBO, or to the multisample FBO // if multisampling is enabled. if (offscreenMultisample) { - offscreenNotCurrent = offscreenFramebufferMultisample != currentFramebuffer; + offscreenNotCurrent = offscreenFramebufferMultisample != + currentFramebuffer; } else { offscreenNotCurrent = offscreenFramebuffer != currentFramebuffer; } @@ -2028,12 +2093,12 @@ public class PGraphicsOpenGL extends PGraphics { setFlushMode(FLUSH_CONTINUOUSLY); } else if (which == DISABLE_TEXTURE_CACHE) { flush(); - } else if (which == DISABLE_PERSPECTIVE_CORRECTED_LINES) { + } else if (which == DISABLE_STROKE_PERSPECTIVE) { if (0 < tessGeo.lineVertexCount && 0 < tessGeo.lineIndexCount) { // We flush the geometry using the previous line setting. flush(); } - } else if (which == ENABLE_PERSPECTIVE_CORRECTED_LINES) { + } else if (which == ENABLE_STROKE_PERSPECTIVE) { if (0 < tessGeo.lineVertexCount && 0 < tessGeo.lineIndexCount) { // We flush the geometry using the previous line setting. flush(); @@ -2066,8 +2131,8 @@ public class PGraphicsOpenGL extends PGraphics { public void endShape(int mode) { if (flushMode == FLUSH_WHEN_FULL && hints[DISABLE_TEXTURE_CACHE] && textureImage0 != null && textureImage == null) { - // The previous shape had a texture and this one doesn't. So we need to flush - // the textured geometry. + // The previous shape had a texture and this one doesn't. So we need to + // flush the textured geometry. textureImage = textureImage0; flush(); textureImage = null; @@ -2087,13 +2152,14 @@ public class PGraphicsOpenGL extends PGraphics { protected void endShape(int[] indices, int[] edges) { if (shape != TRIANGLE && shape != TRIANGLES) { - throw new RuntimeException("Indices and edges can only be set for TRIANGLE shapes"); + throw new RuntimeException("Indices and edges can only be set for " + + "TRIANGLE shapes"); } if (flushMode == FLUSH_WHEN_FULL && hints[DISABLE_TEXTURE_CACHE] && textureImage0 != null && textureImage == null) { - // The previous shape had a texture and this one doesn't. So we need to flush - // the textured geometry. + // The previous shape had a texture and this one doesn't. So we need to + // flush the textured geometry. textureImage = textureImage0; flush(); textureImage = null; @@ -2339,7 +2405,8 @@ public class PGraphicsOpenGL extends PGraphics { tessellator.tessellateQuadStrip(); } else if (shape == POLYGON) { if (stroke && defaultEdges) inGeo.addPolygonEdges(mode == CLOSE); - tessellator.tessellatePolygon(false, mode == CLOSE, normalMode == NORMAL_MODE_AUTO); + tessellator.tessellatePolygon(false, mode == CLOSE, + normalMode == NORMAL_MODE_AUTO); } } @@ -2372,9 +2439,12 @@ public class PGraphicsOpenGL extends PGraphics { public void flush() { - boolean hasPolys = 0 < tessGeo.polyVertexCount && 0 < tessGeo.polyIndexCount; - boolean hasLines = 0 < tessGeo.lineVertexCount && 0 < tessGeo.lineIndexCount; - boolean hasPoints = 0 < tessGeo.pointVertexCount && 0 < tessGeo.pointIndexCount; + boolean hasPolys = 0 < tessGeo.polyVertexCount && + 0 < tessGeo.polyIndexCount; + boolean hasLines = 0 < tessGeo.lineVertexCount && + 0 < tessGeo.lineIndexCount; + boolean hasPoints = 0 < tessGeo.pointVertexCount && + 0 < tessGeo.pointIndexCount; boolean hasPixels = modified && pixels != null; @@ -2394,7 +2464,8 @@ public class PGraphicsOpenGL extends PGraphics { // tessellated vertices, so we set the OpenGL modelview matrix as // the identity to avoid applying the model transformations twice. // We save the modelview objects and temporarily use the identity - // static matrix to avoid calling pushMatrix(), resetMatrix(), popMatrix(). + // static matrix to avoid calling pushMatrix(), resetMatrix(), + // popMatrix(). modelview0 = modelview; modelviewInv0 = modelviewInv; modelview = modelviewInv = identity; @@ -2464,24 +2535,33 @@ public class PGraphicsOpenGL extends PGraphics { cache.indexOffset[n] + cache.indexCount[n] - ioffset; int voffset = cache.vertexOffset[n]; - shader.setVertexAttribute(glPolyVertex, 4, PGL.FLOAT, 0, 4 * voffset * PGL.SIZEOF_FLOAT); - shader.setColorAttribute(glPolyColor, 4, PGL.UNSIGNED_BYTE, 0, 4 * voffset * PGL.SIZEOF_BYTE); + shader.setVertexAttribute(glPolyVertex, 4, PGL.FLOAT, 0, + 4 * voffset * PGL.SIZEOF_FLOAT); + shader.setColorAttribute(glPolyColor, 4, PGL.UNSIGNED_BYTE, 0, + 4 * voffset * PGL.SIZEOF_BYTE); if (lights) { - shader.setNormalAttribute(glPolyNormal, 3, PGL.FLOAT, 0, 3 * voffset * PGL.SIZEOF_FLOAT); - shader.setAmbientAttribute(glPolyAmbient, 4, PGL.UNSIGNED_BYTE, 0, 4 * voffset * PGL.SIZEOF_BYTE); - shader.setSpecularAttribute(glPolySpecular, 4, PGL.UNSIGNED_BYTE, 0, 4 * voffset * PGL.SIZEOF_BYTE); - shader.setEmissiveAttribute(glPolyEmissive, 4, PGL.UNSIGNED_BYTE, 0, 4 * voffset * PGL.SIZEOF_BYTE); - shader.setShininessAttribute(glPolyShininess, 1, PGL.FLOAT, 0, voffset * PGL.SIZEOF_FLOAT); + shader.setNormalAttribute(glPolyNormal, 3, PGL.FLOAT, 0, + 3 * voffset * PGL.SIZEOF_FLOAT); + shader.setAmbientAttribute(glPolyAmbient, 4, PGL.UNSIGNED_BYTE, 0, + 4 * voffset * PGL.SIZEOF_BYTE); + shader.setSpecularAttribute(glPolySpecular, 4, PGL.UNSIGNED_BYTE, 0, + 4 * voffset * PGL.SIZEOF_BYTE); + shader.setEmissiveAttribute(glPolyEmissive, 4, PGL.UNSIGNED_BYTE, 0, + 4 * voffset * PGL.SIZEOF_BYTE); + shader.setShininessAttribute(glPolyShininess, 1, PGL.FLOAT, 0, + voffset * PGL.SIZEOF_FLOAT); } if (tex != null) { - shader.setTexcoordAttribute(glPolyTexcoord, 2, PGL.FLOAT, 0, 2 * voffset * PGL.SIZEOF_FLOAT); + shader.setTexcoordAttribute(glPolyTexcoord, 2, PGL.FLOAT, 0, + 2 * voffset * PGL.SIZEOF_FLOAT); shader.setTexture(tex); } pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glPolyIndex); - pgl.drawElements(PGL.TRIANGLES, icount, PGL.INDEX_TYPE, ioffset * PGL.SIZEOF_INDEX); + pgl.drawElements(PGL.TRIANGLES, icount, PGL.INDEX_TYPE, + ioffset * PGL.SIZEOF_INDEX); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0); } @@ -2509,9 +2589,11 @@ public class PGraphicsOpenGL extends PGraphics { int last = texCache.lastCache[i]; IndexCache cache = tessGeo.polyIndexCache; for (int n = first; n <= last; n++) { - int ioffset = n == first ? texCache.firstIndex[i] : cache.indexOffset[n]; + int ioffset = n == first ? texCache.firstIndex[i] : + cache.indexOffset[n]; int icount = n == last ? texCache.lastIndex[i] - ioffset + 1 : - cache.indexOffset[n] + cache.indexCount[n] - ioffset; + cache.indexOffset[n] + cache.indexCount[n] - + ioffset; int voffset = cache.vertexOffset[n]; for (int tr = ioffset / 3; tr < (ioffset + icount) / 3; tr++) { @@ -2526,7 +2608,8 @@ public class PGraphicsOpenGL extends PGraphics { int argb1 = PGL.nativeToJavaARGB(color[i1]); int argb2 = PGL.nativeToJavaARGB(color[i2]); - if (flushMode == FLUSH_CONTINUOUSLY || hints[DISABLE_TRANSFORM_CACHE]) { + if (flushMode == FLUSH_CONTINUOUSLY || + hints[DISABLE_TRANSFORM_CACHE]) { float[] src0 = {0, 0, 0, 0}; float[] src1 = {0, 0, 0, 0}; float[] src2 = {0, 0, 0, 0}; @@ -2552,9 +2635,12 @@ public class PGraphicsOpenGL extends PGraphics { raw.fill(argb2); raw.vertex(pt2[X], pt2[Y], pt2[Z], uv[2 * i2 + 0], uv[2 * i2 + 1]); } else if (raw.is2D()) { - float sx0 = screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]), sy0 = screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); - float sx1 = screenXImpl(pt1[0], pt1[1], pt1[2], pt1[3]), sy1 = screenYImpl(pt1[0], pt1[1], pt1[2], pt1[3]); - float sx2 = screenXImpl(pt2[0], pt2[1], pt2[2], pt2[3]), sy2 = screenYImpl(pt2[0], pt2[1], pt2[2], pt2[3]); + float sx0 = screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sy0 = screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sx1 = screenXImpl(pt1[0], pt1[1], pt1[2], pt1[3]); + float sy1 = screenYImpl(pt1[0], pt1[1], pt1[2], pt1[3]); + float sx2 = screenXImpl(pt2[0], pt2[1], pt2[2], pt2[3]); + float sy2 = screenYImpl(pt2[0], pt2[1], pt2[2], pt2[3]); raw.fill(argb0); raw.vertex(sx0, sy0, uv[2 * i0 + 0], uv[2 * i0 + 1]); raw.fill(argb1); @@ -2571,9 +2657,12 @@ public class PGraphicsOpenGL extends PGraphics { raw.fill(argb2); raw.vertex(pt2[X], pt2[Y], pt2[Z]); } else if (raw.is2D()) { - float sx0 = screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]), sy0 = screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); - float sx1 = screenXImpl(pt1[0], pt1[1], pt1[2], pt1[3]), sy1 = screenYImpl(pt1[0], pt1[1], pt1[2], pt1[3]); - float sx2 = screenXImpl(pt2[0], pt2[1], pt2[2], pt2[3]), sy2 = screenYImpl(pt2[0], pt2[1], pt2[2], pt2[3]); + float sx0 = screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sy0 = screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sx1 = screenXImpl(pt1[0], pt1[1], pt1[2], pt1[3]); + float sy1 = screenYImpl(pt1[0], pt1[1], pt1[2], pt1[3]); + float sx2 = screenXImpl(pt2[0], pt2[1], pt2[2], pt2[3]); + float sy2 = screenYImpl(pt2[0], pt2[1], pt2[2], pt2[3]); raw.fill(argb0); raw.vertex(sx0, sy0); raw.fill(argb1); @@ -2602,12 +2691,16 @@ public class PGraphicsOpenGL extends PGraphics { int icount = cache.indexCount[n]; int voffset = cache.vertexOffset[n]; - shader.setVertexAttribute(glLineVertex, 4, PGL.FLOAT, 0, 4 * voffset * PGL.SIZEOF_FLOAT); - shader.setColorAttribute(glLineColor, 4, PGL.UNSIGNED_BYTE, 0, 4 * voffset * PGL.SIZEOF_BYTE); - shader.setLineAttribute(glLineAttrib, 4, PGL.FLOAT, 0, 4 * voffset * PGL.SIZEOF_FLOAT); + shader.setVertexAttribute(glLineVertex, 4, PGL.FLOAT, 0, + 4 * voffset * PGL.SIZEOF_FLOAT); + shader.setColorAttribute(glLineColor, 4, PGL.UNSIGNED_BYTE, 0, + 4 * voffset * PGL.SIZEOF_BYTE); + shader.setLineAttribute(glLineAttrib, 4, PGL.FLOAT, 0, + 4 * voffset * PGL.SIZEOF_FLOAT); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glLineIndex); - pgl.drawElements(PGL.TRIANGLES, icount, PGL.INDEX_TYPE, ioffset * PGL.SIZEOF_INDEX); + pgl.drawElements(PGL.TRIANGLES, icount, PGL.INDEX_TYPE, + ioffset * PGL.SIZEOF_INDEX); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0); } @@ -2672,8 +2765,10 @@ public class PGraphicsOpenGL extends PGraphics { raw.stroke(argb1); raw.vertex(pt1[X], pt1[Y], pt1[Z]); } else if (raw.is2D()) { - float sx0 = screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]), sy0 = screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); - float sx1 = screenXImpl(pt1[0], pt1[1], pt1[2], pt1[3]), sy1 = screenYImpl(pt1[0], pt1[1], pt1[2], pt1[3]); + float sx0 = screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sy0 = screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sx1 = screenXImpl(pt1[0], pt1[1], pt1[2], pt1[3]); + float sy1 = screenYImpl(pt1[0], pt1[1], pt1[2], pt1[3]); raw.strokeWeight(sw0); raw.stroke(argb0); raw.vertex(sx0, sy0); @@ -2700,12 +2795,16 @@ public class PGraphicsOpenGL extends PGraphics { int icount = cache.indexCount[n]; int voffset = cache.vertexOffset[n]; - shader.setVertexAttribute(glPointVertex, 4, PGL.FLOAT, 0, 4 * voffset * PGL.SIZEOF_FLOAT); - shader.setColorAttribute(glPointColor, 4, PGL.UNSIGNED_BYTE, 0, 4 * voffset * PGL.SIZEOF_BYTE); - shader.setPointAttribute(glPointAttrib, 2, PGL.FLOAT, 0, 2 * voffset * PGL.SIZEOF_FLOAT); + shader.setVertexAttribute(glPointVertex, 4, PGL.FLOAT, 0, + 4 * voffset * PGL.SIZEOF_FLOAT); + shader.setColorAttribute(glPointColor, 4, PGL.UNSIGNED_BYTE, 0, + 4 * voffset * PGL.SIZEOF_BYTE); + shader.setPointAttribute(glPointAttrib, 2, PGL.FLOAT, 0, + 2 * voffset * PGL.SIZEOF_FLOAT); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glPointIndex); - pgl.drawElements(PGL.TRIANGLES, icount, PGL.INDEX_TYPE, ioffset * PGL.SIZEOF_INDEX); + pgl.drawElements(PGL.TRIANGLES, icount, PGL.INDEX_TYPE, + ioffset * PGL.SIZEOF_INDEX); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0); } @@ -2739,7 +2838,7 @@ public class PGraphicsOpenGL extends PGraphics { if (0 < size) { // round point weight = +size / 0.5f; perim = PApplet.max(MIN_POINT_ACCURACY, - (int) (TWO_PI * weight / POINT_ACCURACY_FACTOR)) + 1; + (int) (TWO_PI * weight / POINT_ACCURACY_FACTOR)) + 1; } else { // Square point weight = -size / 0.5f; perim = 5; @@ -2762,7 +2861,8 @@ public class PGraphicsOpenGL extends PGraphics { raw.stroke(argb0); raw.vertex(pt0[X], pt0[Y], pt0[Z]); } else if (raw.is2D()) { - float sx0 = screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]), sy0 = screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sx0 = screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sy0 = screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); raw.strokeWeight(weight); raw.stroke(argb0); raw.vertex(sx0, sy0); @@ -3046,7 +3146,8 @@ public class PGraphicsOpenGL extends PGraphics { normalMode = NORMAL_MODE_VERTEX; inGeo.setMaterial(fillColor, strokeColor, strokeWeight, ambientColor, specularColor, emissiveColor, shininess); - int[] indices = inGeo.addSphere(r, sphereDetailU, sphereDetailV, fill, stroke); + int[] indices = inGeo.addSphere(r, sphereDetailU, sphereDetailV, + fill, stroke); endShape(indices); } @@ -3136,8 +3237,10 @@ public class PGraphicsOpenGL extends PGraphics { smoothCallCount++; if (parent.frameCount - lastSmoothCall < 30 && 5 < smoothCallCount) { smoothDisabled = true; - PGraphics.showWarning("The smooth/noSmooth functions are being called too often.\n" + - "This results in screen flickering, so they will be disabled\n" + + PGraphics.showWarning("The smooth/noSmooth functions are being " + + "called too often.\n" + + "This results in screen flickering, so they " + + "will be disabled\n" + "for the rest of the sketch's execution."); } lastSmoothCall = parent.frameCount; @@ -3162,8 +3265,10 @@ public class PGraphicsOpenGL extends PGraphics { smoothCallCount++; if (parent.frameCount - lastSmoothCall < 30 && 5 < smoothCallCount) { smoothDisabled = true; - PGraphics.showWarning("The smooth/noSmooth functions are being called too often.\n" + - "This results in screen flickering, so they will be disabled\n" + + PGraphics.showWarning("The smooth/noSmooth functions are being " + + "called too often.\n" + + "This results in screen flickering, so they " + + "will be disabled\n" + "for the rest of the sketch's execution."); } lastSmoothCall = parent.frameCount; @@ -3203,7 +3308,8 @@ public class PGraphicsOpenGL extends PGraphics { } - public void shape(PShape shape, float x, float y, float z, float c, float d, float e) { + public void shape(PShape shape, float x, float y, float z, float c, float d, + float e) { if (shape.isVisible()) { // don't do expensive matrix ops if invisible flush(); @@ -3212,11 +3318,15 @@ public class PGraphicsOpenGL extends PGraphics { if (shapeMode == CENTER) { // x, y and z are center, c, d and e refer to a diameter translate(x - c / 2f, y - d / 2f, z - e / 2f); - scale(c / shape.getWidth(), d / shape.getHeight(), e / shape.getDepth()); + scale(c / shape.getWidth(), + d / shape.getHeight(), + e / shape.getDepth()); } else if (shapeMode == CORNER) { translate(x, y, z); - scale(c / shape.getWidth(), d / shape.getHeight(), e / shape.getDepth()); + scale(c / shape.getWidth(), + d / shape.getHeight(), + e / shape.getDepth()); } else if (shapeMode == CORNERS) { // c, d, e are x2/y2/z2, make them into width/height/depth @@ -3225,7 +3335,9 @@ public class PGraphicsOpenGL extends PGraphics { e -= z; // then same as above translate(x, y, z); - scale(c / shape.getWidth(), d / shape.getHeight(), e / shape.getDepth()); + scale(c / shape.getWidth(), + d / shape.getHeight(), + e / shape.getDepth()); } shape.draw(this); @@ -3296,15 +3408,18 @@ public class PGraphicsOpenGL extends PGraphics { /** * Implementation of actual drawing for a line of text. */ - protected void textLineImpl(char buffer[], int start, int stop, float x, float y) { + protected void textLineImpl(char buffer[], int start, int stop, + float x, float y) { textTex = (PFontTexture)textFont.getCache(pgPrimary); if (textTex == null) { - textTex = new PFontTexture(parent, textFont, maxTextureSize, maxTextureSize, is3D()); + textTex = new PFontTexture(parent, textFont, maxTextureSize, + maxTextureSize, is3D()); textFont.setCache(pgPrimary, textTex); } else { if (textTex.contextIsOutdated()) { - textTex = new PFontTexture(parent, textFont, PApplet.min(PGL.MAX_FONT_TEX_SIZE, maxTextureSize), - PApplet.min(PGL.MAX_FONT_TEX_SIZE, maxTextureSize), is3D()); + textTex = new PFontTexture(parent, textFont, + PApplet.min(PGL.MAX_FONT_TEX_SIZE, maxTextureSize), + PApplet.min(PGL.MAX_FONT_TEX_SIZE, maxTextureSize), is3D()); textFont.setCache(pgPrimary, textTex); } } @@ -3380,8 +3495,9 @@ public class PGraphicsOpenGL extends PGraphics { } - protected void textCharModelImpl(PFontTexture.TextureInfo info, float x0, float y0, - float x1, float y1) { + protected void textCharModelImpl(PFontTexture.TextureInfo info, + float x0, float y0, + float x1, float y1) { if (textTex.currentTex != info.texIndex) { textTex.setTexture(info.texIndex); } @@ -3457,7 +3573,8 @@ public class PGraphicsOpenGL extends PGraphics { } - static protected void invTranslate(PMatrix3D matrix, float tx, float ty, float tz) { + static protected void invTranslate(PMatrix3D matrix, + float tx, float ty, float tz) { matrix.preApply(1, 0, 0, -tx, 0, 1, 0, -ty, 0, 0, 1, -tz, @@ -3525,7 +3642,8 @@ public class PGraphicsOpenGL extends PGraphics { } - static private void invRotate(PMatrix3D matrix, float angle, float v0, float v1, float v2) { + static private void invRotate(PMatrix3D matrix, float angle, + float v0, float v1, float v2) { float c = PApplet.cos(-angle); float s = PApplet.sin(-angle); float t = 1.0f - c; @@ -4260,17 +4378,23 @@ public class PGraphicsOpenGL extends PGraphics { protected float screenXImpl(float x, float y, float z) { - float ax = modelview.m00 * x + modelview.m01 * y + modelview.m02 * z + modelview.m03; - float ay = modelview.m10 * x + modelview.m11 * y + modelview.m12 * z + modelview.m13; - float az = modelview.m20 * x + modelview.m21 * y + modelview.m22 * z + modelview.m23; - float aw = modelview.m30 * x + modelview.m31 * y + modelview.m32 * z + modelview.m33; + float ax = + modelview.m00*x + modelview.m01*y + modelview.m02*z + modelview.m03; + float ay = + modelview.m10*x + modelview.m11*y + modelview.m12*z + modelview.m13; + float az = + modelview.m20*x + modelview.m21*y + modelview.m22*z + modelview.m23; + float aw = + modelview.m30*x + modelview.m31*y + modelview.m32*z + modelview.m33; return screenXImpl(ax, ay, az, aw); } protected float screenXImpl(float x, float y, float z, float w) { - float ox = projection.m00 * x + projection.m01 * y + projection.m02 * z + projection.m03 * w; - float ow = projection.m30 * x + projection.m31 * y + projection.m32 * z + projection.m33 * w; + float ox = + projection.m00*x + projection.m01*y + projection.m02*z + projection.m03*w; + float ow = + projection.m30*x + projection.m31*y + projection.m32*z + projection.m33*w; if (nonZero(ow)) { ox /= ow; @@ -4281,17 +4405,23 @@ public class PGraphicsOpenGL extends PGraphics { protected float screenYImpl(float x, float y, float z) { - float ax = modelview.m00 * x + modelview.m01 * y + modelview.m02 * z + modelview.m03; - float ay = modelview.m10 * x + modelview.m11 * y + modelview.m12 * z + modelview.m13; - float az = modelview.m20 * x + modelview.m21 * y + modelview.m22 * z + modelview.m23; - float aw = modelview.m30 * x + modelview.m31 * y + modelview.m32 * z + modelview.m33; + float ax = + modelview.m00*x + modelview.m01*y + modelview.m02*z + modelview.m03; + float ay = + modelview.m10*x + modelview.m11*y + modelview.m12*z + modelview.m13; + float az = + modelview.m20*x + modelview.m21*y + modelview.m22*z + modelview.m23; + float aw = + modelview.m30*x + modelview.m31*y + modelview.m32*z + modelview.m33; return screenYImpl(ax, ay, az, aw); } protected float screenYImpl(float x, float y, float z, float w) { - float oy = projection.m10 * x + projection.m11 * y + projection.m12 * z + projection.m13 * w; - float ow = projection.m30 * x + projection.m31 * y + projection.m32 * z + projection.m33 * w; + float oy = + projection.m10*x + projection.m11*y + projection.m12*z + projection.m13*w; + float ow = + projection.m30*x + projection.m31*y + projection.m32*z + projection.m33*w; if (nonZero(ow)) { oy /= ow; @@ -4304,17 +4434,23 @@ public class PGraphicsOpenGL extends PGraphics { protected float screenZImpl(float x, float y, float z) { - float ax = modelview.m00 * x + modelview.m01 * y + modelview.m02 * z + modelview.m03; - float ay = modelview.m10 * x + modelview.m11 * y + modelview.m12 * z + modelview.m13; - float az = modelview.m20 * x + modelview.m21 * y + modelview.m22 * z + modelview.m23; - float aw = modelview.m30 * x + modelview.m31 * y + modelview.m32 * z + modelview.m33; + float ax = + modelview.m00*x + modelview.m01*y + modelview.m02*z + modelview.m03; + float ay = + modelview.m10*x + modelview.m11*y + modelview.m12*z + modelview.m13; + float az = + modelview.m20*x + modelview.m21*y + modelview.m22*z + modelview.m23; + float aw = + modelview.m30*x + modelview.m31*y + modelview.m32*z + modelview.m33; return screenZImpl(ax, ay, az, aw); } protected float screenZImpl(float x, float y, float z, float w) { - float oz = projection.m20 * x + projection.m21 * y + projection.m22 * z + projection.m23 * w; - float ow = projection.m30 * x + projection.m31 * y + projection.m32 * z + projection.m33 * w; + float oz = + projection.m20*x + projection.m21*y + projection.m22*z + projection.m23*w; + float ow = + projection.m30*x + projection.m31*y + projection.m32*z + projection.m33*w; if (nonZero(ow)) { oz /= ow; @@ -4325,39 +4461,57 @@ public class PGraphicsOpenGL extends PGraphics { public float modelX(float x, float y, float z) { - float ax = modelview.m00 * x + modelview.m01 * y + modelview.m02 * z + modelview.m03; - float ay = modelview.m10 * x + modelview.m11 * y + modelview.m12 * z + modelview.m13; - float az = modelview.m20 * x + modelview.m21 * y + modelview.m22 * z + modelview.m23; - float aw = modelview.m30 * x + modelview.m31 * y + modelview.m32 * z + modelview.m33; + float ax = + modelview.m00*x + modelview.m01*y + modelview.m02*z + modelview.m03; + float ay = + modelview.m10*x + modelview.m11*y + modelview.m12*z + modelview.m13; + float az = + modelview.m20*x + modelview.m21*y + modelview.m22*z + modelview.m23; + float aw = + modelview.m30*x + modelview.m31*y + modelview.m32*z + modelview.m33; - float ox = cameraInv.m00 * ax + cameraInv.m01 * ay + cameraInv.m02 * az + cameraInv.m03 * aw; - float ow = cameraInv.m30 * ax + cameraInv.m31 * ay + cameraInv.m32 * az + cameraInv.m33 * aw; + float ox = + cameraInv.m00*ax + cameraInv.m01*ay + cameraInv.m02*az + cameraInv.m03*aw; + float ow = + cameraInv.m30*ax + cameraInv.m31*ay + cameraInv.m32*az + cameraInv.m33*aw; return nonZero(ow) ? ox / ow : ox; } public float modelY(float x, float y, float z) { - float ax = modelview.m00 * x + modelview.m01 * y + modelview.m02 * z + modelview.m03; - float ay = modelview.m10 * x + modelview.m11 * y + modelview.m12 * z + modelview.m13; - float az = modelview.m20 * x + modelview.m21 * y + modelview.m22 * z + modelview.m23; - float aw = modelview.m30 * x + modelview.m31 * y + modelview.m32 * z + modelview.m33; + float ax = + modelview.m00*x + modelview.m01*y + modelview.m02*z + modelview.m03; + float ay = + modelview.m10*x + modelview.m11*y + modelview.m12*z + modelview.m13; + float az = + modelview.m20*x + modelview.m21*y + modelview.m22*z + modelview.m23; + float aw = + modelview.m30*x + modelview.m31*y + modelview.m32*z + modelview.m33; - float oy = cameraInv.m10 * ax + cameraInv.m11 * ay + cameraInv.m12 * az + cameraInv.m13 * aw; - float ow = cameraInv.m30 * ax + cameraInv.m31 * ay + cameraInv.m32 * az + cameraInv.m33 * aw; + float oy = + cameraInv.m10*ax + cameraInv.m11*ay + cameraInv.m12*az + cameraInv.m13*aw; + float ow = + cameraInv.m30*ax + cameraInv.m31*ay + cameraInv.m32*az + cameraInv.m33*aw; return nonZero(ow) ? oy / ow : oy; } public float modelZ(float x, float y, float z) { - float ax = modelview.m00 * x + modelview.m01 * y + modelview.m02 * z + modelview.m03; - float ay = modelview.m10 * x + modelview.m11 * y + modelview.m12 * z + modelview.m13; - float az = modelview.m20 * x + modelview.m21 * y + modelview.m22 * z + modelview.m23; - float aw = modelview.m30 * x + modelview.m31 * y + modelview.m32 * z + modelview.m33; + float ax = + modelview.m00*x + modelview.m01*y + modelview.m02*z + modelview.m03; + float ay = + modelview.m10*x + modelview.m11*y + modelview.m12*z + modelview.m13; + float az = + modelview.m20*x + modelview.m21*y + modelview.m22*z + modelview.m23; + float aw = + modelview.m30*x + modelview.m31*y + modelview.m32*z + modelview.m33; - float oz = cameraInv.m20 * ax + cameraInv.m21 * ay + cameraInv.m22 * az + cameraInv.m23 * aw; - float ow = cameraInv.m30 * ax + cameraInv.m31 * ay + cameraInv.m32 * az + cameraInv.m33 * aw; + float oz = + cameraInv.m20*ax + cameraInv.m21*ay + cameraInv.m22*az + cameraInv.m23*aw; + float ow = + cameraInv.m30*ax + cameraInv.m31*ay + cameraInv.m32*az + cameraInv.m33*aw; return nonZero(ow) ? oz / ow : oz; } @@ -4544,7 +4698,8 @@ public class PGraphicsOpenGL extends PGraphics { lightSpecular(0, 0, 0); ambientLight(colorModeX * 0.5f, colorModeY * 0.5f, colorModeZ * 0.5f); - directionalLight(colorModeX * 0.5f, colorModeY * 0.5f, colorModeZ * 0.5f, 0, 0, -1); + directionalLight(colorModeX * 0.5f, colorModeY * 0.5f, colorModeZ * 0.5f, + 0, 0, -1); colorMode = colorModeSaved; } @@ -4571,10 +4726,12 @@ public class PGraphicsOpenGL extends PGraphics { * Add an ambient light based on the current color mode. This version includes * an (x, y, z) position for situations where the falloff distance is used. */ - public void ambientLight(float r, float g, float b, float x, float y, float z) { + public void ambientLight(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"); + throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + + " lights"); } lightType[lightCount] = AMBIENT; @@ -4598,7 +4755,8 @@ public class PGraphicsOpenGL extends PGraphics { float dx, float dy, float dz) { enableLighting(); if (lightCount == PGL.MAX_LIGHTS) { - throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + " lights"); + throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + + " lights"); } lightType[lightCount] = DIRECTIONAL; @@ -4622,7 +4780,8 @@ public class PGraphicsOpenGL extends PGraphics { float x, float y, float z) { enableLighting(); if (lightCount == PGL.MAX_LIGHTS) { - throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + " lights"); + throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + + " lights"); } lightType[lightCount] = POINT; @@ -4650,7 +4809,8 @@ public class PGraphicsOpenGL extends PGraphics { float angle, float concentration) { enableLighting(); if (lightCount == PGL.MAX_LIGHTS) { - throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + " lights"); + throw new RuntimeException("can only create " + PGL.MAX_LIGHTS + + " lights"); } lightType[lightCount] = SPOT; @@ -4710,10 +4870,14 @@ public class PGraphicsOpenGL extends PGraphics { } - 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; + 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; @@ -4721,11 +4885,14 @@ public class PGraphicsOpenGL extends PGraphics { 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; + // 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; @@ -4969,7 +5136,8 @@ public class PGraphicsOpenGL extends PGraphics { protected void readPixels() { beginPixelsOp(OP_READ); pixelBuffer.rewind(); - pgl.readPixels(0, 0, width, height, PGL.RGBA, PGL.UNSIGNED_BYTE, pixelBuffer); + pgl.readPixels(0, 0, width, height, PGL.RGBA, PGL.UNSIGNED_BYTE, + pixelBuffer); endPixelsOp(); PGL.nativeToJavaARGB(pixels, width, height); @@ -5064,20 +5232,24 @@ public class PGraphicsOpenGL extends PGraphics { if (pgl.primaryIsFboBacked()) { pgl.bindPrimaryColorFBO(); - // Copy the contents of the FBO used by the primary surface into texture, this copy - // operation is very fast because it is resolved in the GPU. - texture.set(pgl.getFboTexTarget(), pgl.getFboTexName(), pgl.getFboWidth(), pgl.getFboHeight(), width, height); + // Copy the contents of the FBO used by the primary surface into + // texture, this copy operation is very fast because it is resolved + // in the GPU. + texture.set(pgl.getFboTexTarget(), pgl.getFboTexName(), + pgl.getFboWidth(), pgl.getFboHeight(), width, height); pgl.bindPrimaryMultiFBO(); } else { - // Here we go the slow route: we first copy the contents of the color buffer into a pixels array (but we keep it - // in native format) and then copy this array into the texture. + // Here we go the slow route: we first copy the contents of the color + // buffer into a pixels array (but we keep it in native format) and + // then copy this array into the texture. if (nativePixels == null || nativePixels.length < width * height) { nativePixels = new int[width * height]; nativePixelBuffer = IntBuffer.wrap(nativePixels); } beginPixelsOp(OP_READ); - pgl.readPixels(0, 0, width, height, PGL.RGBA, PGL.UNSIGNED_BYTE, nativePixelBuffer); + pgl.readPixels(0, 0, width, height, PGL.RGBA, PGL.UNSIGNED_BYTE, + nativePixelBuffer); endPixelsOp(); texture.setNative(nativePixels, 0, 0, width, height); @@ -5135,7 +5307,8 @@ public class PGraphicsOpenGL extends PGraphics { // Uses the texture in img as the color buffer for this surface. public void setTexture(PImage img) { if (width != img.width || height != img.height) { - PGraphics.showWarning("Resolution of image is different from PGraphics object"); + PGraphics.showWarning("Resolution of image is different from PGraphics " + + "object"); return; } @@ -5188,7 +5361,8 @@ public class PGraphicsOpenGL extends PGraphics { protected void loadTextureImpl(int sampling, boolean mipmap) { if (width == 0 || height == 0) return; if (texture == null || texture.contextIsOutdated()) { - Texture.Parameters params = new Texture.Parameters(ARGB, sampling, mipmap); + Texture.Parameters params = new Texture.Parameters(ARGB, + sampling, mipmap); texture = new Texture(parent, width, height, params); texture.setFlippedY(true); this.setCache(pgPrimary, texture); @@ -5260,14 +5434,26 @@ public class PGraphicsOpenGL extends PGraphics { public void mask(int alpha[]) { - PGraphics.showMethodWarning("mask"); + PImage temp = get(); + temp.mask(alpha); + set(0, 0, temp); } public void mask(PImage alpha) { - PGraphics.showMethodWarning("mask"); + if (alpha.width != width || alpha.height != height) { + throw new RuntimeException("The PImage used with mask() must be " + + "the same size as the applet."); + } + + if (maskShader == null) { + maskShader = new PolyTexShader(parent, defPolyTexShaderVertURL, + maskShaderFragURL); + } + maskShader.set("maskSampler", alpha); + filter(maskShader); } - + ////////////////////////////////////////////////////////////// @@ -5306,19 +5492,22 @@ public class PGraphicsOpenGL extends PGraphics { loadTexture(); - if (textureCopy == null || textureCopy.width != width || textureCopy.height != height) { - Texture.Parameters params = new Texture.Parameters(ARGB, Texture.POINT, false); + if (textureCopy == null || textureCopy.width != width || + textureCopy.height != height) { + Texture.Parameters params = new Texture.Parameters(ARGB, Texture.POINT, + false); textureCopy = new Texture(parent, width, height, params); textureCopy.setFlippedY(true); imageCopy = wrapTexture(textureCopy); } - textureCopy.set(texture.glTarget, texture.glName, texture.glWidth, texture.glHeight, width, height); + textureCopy.set(texture.glTarget, texture.glName, + texture.glWidth, texture.glHeight, width, height); - // Disable writing to the depth buffer, so that after applying the filter we can - // still use the depth information to keep adding geometry to the scene. + // Disable writing to the depth buffer, so that after applying the filter we + // can still use the depth information to keep adding geometry to the scene. pgl.depthMask(false); - // Also disabling depth testing so the texture is drawn on top of everything that - // has been drawn before. + // Also disabling depth testing so the texture is drawn on top of everything + // that has been drawn before. pgl.disable(PGL.DEPTH_TEST); PolyTexShader prevTexShader = polyTexShader; @@ -5483,9 +5672,9 @@ public class PGraphicsOpenGL extends PGraphics { } pgl.blendFunc(PGL.ONE_MINUS_DST_COLOR, PGL.ONE); } - // HARD_LIGHT, SOFT_LIGHT, OVERLAY, DODGE, BURN modes cannot be implemented - // in fixed-function pipeline because they require conditional blending and - // non-linear blending equations. + // HARD_LIGHT, SOFT_LIGHT, OVERLAY, DODGE, BURN modes cannot be + // implemented in fixed-function pipeline because they require conditional + // blending and non-linear blending equations. } } @@ -5690,25 +5879,28 @@ public class PGraphicsOpenGL extends PGraphics { offscreenFramebufferMultisample.release(); } - if (PGraphicsOpenGL.fboMultisampleSupported && 1 < quality) { - offscreenFramebufferMultisample = new FrameBuffer(parent, texture.glWidth, texture.glHeight, quality, 0, - depthBits, stencilBits, - depthBits == 24 && stencilBits == 8 && packedDepthStencilSupported, false); + boolean packed = depthBits == 24 && stencilBits == 8 && + packedDepthStencilSupported; + if (PGraphicsOpenGL.fboMultisampleSupported && 1 < quality) { + offscreenFramebufferMultisample = + new FrameBuffer(parent, texture.glWidth, texture.glHeight, quality, 0, + depthBits, stencilBits, packed, false); offscreenFramebufferMultisample.clear(); offscreenMultisample = true; - // The offscreen framebuffer where the multisampled image is finally drawn to doesn't - // need depth and stencil buffers since they are part of the multisampled framebuffer. - offscreenFramebuffer = new FrameBuffer(parent, texture.glWidth, texture.glHeight, 1, 1, - 0, 0, - false, false); + // The offscreen framebuffer where the multisampled image is finally drawn + // to doesn't need depth and stencil buffers since they are part of the + // multisampled framebuffer. + offscreenFramebuffer = + new FrameBuffer(parent, texture.glWidth, texture.glHeight, 1, 1, 0, 0, + false, false); } else { quality = 0; - offscreenFramebuffer = new FrameBuffer(parent, texture.glWidth, texture.glHeight, 1, 1, - depthBits, stencilBits, - depthBits == 24 && stencilBits == 8 && packedDepthStencilSupported, false); + offscreenFramebuffer = + new FrameBuffer(parent, texture.glWidth, texture.glHeight, 1, 1, + depthBits, stencilBits, packed, false); offscreenMultisample = false; } @@ -5724,10 +5916,14 @@ public class PGraphicsOpenGL extends PGraphics { OPENGL_EXTENSIONS = pgl.getString(PGL.EXTENSIONS); GLSL_VERSION = pgl.getString(PGL.SHADING_LANGUAGE_VERSION); - npotTexSupported = -1 < OPENGL_EXTENSIONS.indexOf("_texture_non_power_of_two"); - autoMipmapGenSupported = -1 < OPENGL_EXTENSIONS.indexOf("_generate_mipmap"); - fboMultisampleSupported = -1 < OPENGL_EXTENSIONS.indexOf("_framebuffer_multisample"); - packedDepthStencilSupported = -1 < OPENGL_EXTENSIONS.indexOf("_packed_depth_stencil"); + npotTexSupported = + -1 < OPENGL_EXTENSIONS.indexOf("_texture_non_power_of_two"); + autoMipmapGenSupported = + -1 < OPENGL_EXTENSIONS.indexOf("_generate_mipmap"); + fboMultisampleSupported = + -1 < OPENGL_EXTENSIONS.indexOf("_framebuffer_multisample"); + packedDepthStencilSupported = + -1 < OPENGL_EXTENSIONS.indexOf("_packed_depth_stencil"); try { pgl.blendEquation(PGL.FUNC_ADD); @@ -5765,77 +5961,107 @@ public class PGraphicsOpenGL extends PGraphics { // SHADER HANDLING - public PShader loadShader(int kind, String fragFilename) { - PShader shader; - if (kind == PShader.FLAT) { - shader = new PolyFlatShader(parent); - shader.setVertexShader(defPolyFlatShaderVertURL); - } else if (kind == PShader.LIT) { - shader = new PolyLightShader(parent); - shader.setVertexShader(defPolyLightShaderVertURL); - } else if (kind == PShader.TEXTURED) { + public PShader loadShader(String fragFilename) { + int shaderType = getTypeFromFragmentShader(fragFilename); + PShader shader = null; + if (shaderType == PShader.TEXTURE) { shader = new PolyTexShader(parent); shader.setVertexShader(defPolyTexShaderVertURL); - } else if (kind == PShader.FULL) { - shader = new PolyFullShader(parent); - shader.setVertexShader(defPolyFullShaderVertURL); - } else if (kind == PShader.LINE) { - shader = new LineShader(parent); - shader.setVertexShader(defLineShaderVertURL); - } else if (kind == PShader.POINT) { - shader = new PointShader(parent); - shader.setVertexShader(defPointShaderVertURL); + } else if (shaderType == PShader.COLOR) { + shader = new PolyColorShader(parent); + shader.setVertexShader(defPolyColorShaderVertURL); + } + if (shader == null){ + PGraphics.showWarning("The GLSL code doesn't seem to contain a valid " + + "shader to use in Processing."); } else { - PGraphics.showWarning("loadShader(" + kind + ") is not valid."); - return null; + shader.setFragmentShader(fragFilename); } - shader.setFragmentShader(fragFilename); return shader; } - public PShader loadShader(int kind, String fragFilename, String vertFilename) { - if (kind == PShader.FLAT) { - return new PolyFlatShader(parent, vertFilename, fragFilename); - } else if (kind == PShader.LIT) { - return new PolyLightShader(parent, vertFilename, fragFilename); - } else if (kind == PShader.TEXTURED) { - return new PolyTexShader(parent, vertFilename, fragFilename); - } else if (kind == PShader.FULL) { - return new PolyFullShader(parent, vertFilename, fragFilename); - } else if (kind == PShader.LINE) { - return new LineShader(parent, vertFilename, fragFilename); - } else if (kind == PShader.POINT) { - return new PointShader(parent, vertFilename, fragFilename); + public PShader loadShader(String fragFilename, String vertFilename) { + int shaderType = getTypeFromVertexShader(vertFilename); + PShader shader = null; + if (fragFilename == null || fragFilename.equals("")) { + if (shaderType == PShader.POINT) { + shader = new PointShader(parent); + shader.setFragmentShader(defPointShaderFragURL); + } else if (shaderType == PShader.LINE) { + shader = new LineShader(parent); + shader.setFragmentShader(defLineShaderFragURL); + } else if (shaderType == PShader.TEXLIGHT) { + shader = new PolyTexlightShader(parent); + shader.setFragmentShader(defPolyTexShaderFragURL); + } else if (shaderType == PShader.LIGHT) { + shader = new PolyLightShader(parent); + shader.setFragmentShader(defPolyNoTexShaderFragURL); + } else if (shaderType == PShader.TEXTURE) { + shader = new PolyTexShader(parent); + shader.setFragmentShader(defPolyTexShaderFragURL); + } else if (shaderType == PShader.COLOR) { + shader = new PolyColorShader(parent); + shader.setFragmentShader(defPolyNoTexShaderFragURL); + } + if (shader != null) { + shader.setVertexShader(vertFilename); + } } else { - PGraphics.showWarning("loadShader(" + kind + ") is not valid."); - return null; + if (shaderType == PShader.POINT) { + shader = new PointShader(parent, vertFilename, fragFilename); + } else if (shaderType == PShader.LINE) { + shader = new LineShader(parent, vertFilename, fragFilename); + } else if (shaderType == PShader.TEXLIGHT) { + shader = new PolyTexlightShader(parent, vertFilename, fragFilename); + } else if (shaderType == PShader.LIGHT) { + shader = new PolyLightShader(parent, vertFilename, fragFilename); + } else if (shaderType == PShader.TEXTURE) { + shader = new PolyTexShader(parent, vertFilename, fragFilename); + } else if (shaderType == PShader.COLOR) { + shader = new PolyColorShader(parent, vertFilename, fragFilename); + } } - } - - - public PShader loadShader(String fragFilename) { - return loadShader(PShader.TEXTURED, fragFilename); + if (shader == null) { + PGraphics.showWarning("The GLSL code doesn't seem to contain a valid " + + "shader to use in Processing."); + } + return shader; } public void shader(PShader shader) { + shader(shader, POLYGON); + } + + + public void shader(PShader shader, int kind) { flush(); // Flushing geometry drawn with a different shader. - // The ordering below is important, because some of these classes - // extend others, so multiple instanceof cases will evaluate to 'true'. - if (shader instanceof PolyTexShader) { - polyTexShader = (PolyTexShader) shader; - } else if (shader instanceof PolyFlatShader) { - polyFlatShader = (PolyFlatShader) shader; - } else if (shader instanceof PolyFullShader) { - polyFullShader = (PolyFullShader) shader; - } else if (shader instanceof PolyLightShader) { - polyLightShader = (PolyLightShader) shader; - } else if (shader instanceof LineShader) { - lineShader = (LineShader) shader; - } else if (shader instanceof PointShader) { - pointShader = (PointShader) shader; + if (kind == TRIANGLES || kind == QUADS || kind == POLYGON) { + if (shader instanceof PolyTexShader) { + polyTexShader = (PolyTexShader) shader; + } else if (shader instanceof PolyColorShader) { + polyColorShader = (PolyColorShader) shader; + } else if (shader instanceof PolyTexlightShader) { + polyTexlightShader = (PolyTexlightShader) shader; + } else if (shader instanceof PolyLightShader) { + polyLightShader = (PolyLightShader) shader; + } else { + showWarning("shader() called with a wrong shader object"); + } + } else if (kind == LINES) { + if (shader instanceof LineShader) { + lineShader = (LineShader)shader; + } else { + showWarning("shader() called with a wrong shader object"); + } + } else if (kind == POINTS) { + if (shader instanceof PointShader) { + pointShader = (PointShader)shader; + } else { + showWarning("shader() called with a wrong shader object"); + } } else { showWarning("shader() called with an unknown shader type"); } @@ -5843,180 +6069,223 @@ public class PGraphicsOpenGL extends PGraphics { public void resetShader() { - resetShader(PShader.TEXTURED); + resetShader(POLYGON); + } + + + public void resetShader(int kind) { + flush(); // Flushing geometry drawn with a different shader. + + if (kind == TRIANGLES || kind == QUADS || kind == POLYGON) { + polyTexShader = null; + polyColorShader = null; + polyTexlightShader = null; + polyLightShader = null; + } else if (kind == LINES) { + lineShader = null; + } else if (kind == POINTS) { + pointShader = null; + } else { + PGraphics.showWarning("Wrong shader type"); + } + } + + + public void shaderWarnings(boolean enable) { + shaderWarningsEnabled = enable; } - public void resetShader(int kind) { - flush(); // Flushing geometry drawn with a different shader. - if (kind == PShader.FLAT) { - if (defPolyFlatShader == null) { - defPolyFlatShader = new PolyFlatShader(parent, defPolyFlatShaderVertURL, defPolyNoTexShaderFragURL); + protected int getTypeFromFragmentShader(String filename) { + String[] source = parent.loadStrings(filename); + + Pattern pattern = Pattern.compile("uniform *sampler2D *textureSampler"); + + int type = PShader.COLOR; + for (int i = 0; i < source.length; i++) { + Matcher matcher = pattern.matcher(source[i]); + if (matcher.find()) { + type = PShader.TEXTURE; + break; } - polyFlatShader = defPolyFlatShader; - } else if (kind == PShader.LIT) { - if (defPolyLightShader == null) { - defPolyLightShader = new PolyLightShader(parent, defPolyLightShaderVertURL, defPolyNoTexShaderFragURL); - } - polyLightShader = defPolyLightShader; - } else if (kind == PShader.TEXTURED) { - if (defPolyTexShader == null) { - defPolyTexShader = new PolyTexShader(parent, defPolyTexShaderVertURL, defPolyTexShaderFragURL); - } - polyTexShader = defPolyTexShader; - } else if (kind == PShader.FULL) { - if (defPolyFullShader == null) { - defPolyFullShader = new PolyFullShader(parent, defPolyFullShaderVertURL, defPolyTexShaderFragURL); - } - polyFullShader = defPolyFullShader; - } else if (kind == PShader.LINE) { - if (defLineShader == null) { - defLineShader = new LineShader(parent, defLineShaderVertURL, defLineShaderFragURL); - } - lineShader = defLineShader; - } else if (kind == PShader.POINT) { - if (defPointShader == null) { - defPointShader = new PointShader(parent, defPointShaderVertURL, defPointShaderFragURL); - } - pointShader = defPointShader; - } else { - PGraphics.showWarning("Wrong shader type"); } + return type; } - - - public PShader getShader(int kind) { - PShader shader; - if (kind == PShader.FLAT) { - if (polyFlatShader == null) { - if (defPolyFlatShader == null) { - defPolyFlatShader = new PolyFlatShader(parent, defPolyFlatShaderVertURL, defPolyNoTexShaderFragURL); - } - polyFlatShader = defPolyFlatShader; - } - shader = polyFlatShader; - } else if (kind == PShader.LIT) { - if (polyLightShader == null) { - if (defPolyLightShader == null) { - defPolyLightShader = new PolyLightShader(parent, defPolyLightShaderVertURL, defPolyNoTexShaderFragURL); - } - polyLightShader = defPolyLightShader; - } - shader = polyLightShader; - } else if (kind == PShader.TEXTURED) { - if (polyTexShader == null) { - if (defPolyTexShader == null) { - defPolyTexShader = new PolyTexShader(parent, defPolyTexShaderVertURL, defPolyTexShaderFragURL); - } - polyTexShader = defPolyTexShader; - } - shader = polyTexShader; - } else if (kind == PShader.FULL) { - if (polyFullShader == null) { - if (defPolyFullShader == null) { - defPolyFullShader = new PolyFullShader(parent, defPolyFullShaderVertURL, defPolyTexShaderFragURL); - } - polyFullShader = defPolyFullShader; - } - shader = polyFullShader; - } else if (kind == PShader.LINE) { - if (lineShader == null) { - if (defLineShader == null) { - defLineShader = new LineShader(parent, defLineShaderVertURL, defLineShaderFragURL); - } - lineShader = defLineShader; - } - shader = lineShader; - } else if (kind == PShader.POINT) { - if (pointShader == null) { - if (defPointShader == null) { - defPointShader = new PointShader(parent, defPointShaderVertURL, defPointShaderFragURL); - } - pointShader = defPointShader; - } - shader = pointShader; - } else { - PGraphics.showWarning("Wrong shader type"); - return null; - } - shader.setRenderer(this); - shader.loadAttributes(); - shader.loadUniforms(); - return shader; + + + protected int getTypeFromVertexShader(String filename) { + String[] source = parent.loadStrings(filename); + + Pattern pointPattern = Pattern.compile("attribute *vec2 *inPoint"); + Pattern linePattern = Pattern.compile("attribute *vec4 *inLine"); + Pattern lightPattern1 = Pattern.compile("uniform *vec4 *lightPosition"); + Pattern lightPattern2 = Pattern.compile("uniform *vec3 *lightNormal"); + Pattern texPattern = Pattern.compile("attribute vec2 inTexcoord"); + + int type = PShader.COLOR; + for (int i = 0; i < source.length; i++) { + boolean foundPoint = pointPattern.matcher(source[i]).find(); + boolean foundLine = linePattern.matcher(source[i]).find(); + boolean foundLight = lightPattern1.matcher(source[i]).find() || + lightPattern2.matcher(source[i]).find(); + boolean foundTex = texPattern.matcher(source[i]).find(); + + if (foundPoint) { + type = PShader.POINT; + } else if (foundLine) { + type = PShader.LINE; + } else if (foundLight && foundTex) { + type = PShader.TEXLIGHT; + } else if (foundLight) { + type = PShader.LIGHT; + } else if (foundTex) { + type = PShader.TEXTURE; + } + if (type != PShader.COLOR) break; + } + return type; } - - + + protected PolyShader getPolyShader(boolean lit, boolean tex) { PolyShader shader; if (lit) { if (tex) { - if (polyFullShader == null) { - if (defPolyFullShader == null) { - defPolyFullShader = new PolyFullShader(parent, defPolyFullShaderVertURL, defPolyTexShaderFragURL); + if (polyTexlightShader == null) { + if (defPolyTexlightShader == null) { + defPolyTexlightShader = new PolyTexlightShader(parent, + defPolyTexlightShaderVertURL, + defPolyTexShaderFragURL); } - polyFullShader = defPolyFullShader; + shader = defPolyTexlightShader; + texlightShaderCheck(); + } else { + shader = polyTexlightShader; } - shader = polyFullShader; } else { if (polyLightShader == null) { if (defPolyLightShader == null) { - defPolyLightShader = new PolyLightShader(parent, defPolyLightShaderVertURL, defPolyNoTexShaderFragURL); + defPolyLightShader = new PolyLightShader(parent, + defPolyLightShaderVertURL, + defPolyNoTexShaderFragURL); } - polyLightShader = defPolyLightShader; + shader = defPolyLightShader; + lightShaderCheck(); + } else { + shader = polyLightShader; } - shader = polyLightShader; } } else { if (tex) { if (polyTexShader == null) { if (defPolyTexShader == null) { - defPolyTexShader = new PolyTexShader(parent, defPolyTexShaderVertURL, defPolyTexShaderFragURL); + defPolyTexShader = new PolyTexShader(parent, + defPolyTexShaderVertURL, + defPolyTexShaderFragURL); } - polyTexShader = defPolyTexShader; + shader = defPolyTexShader; + texShaderCheck(); + } else { + shader = polyTexShader; } - shader = polyTexShader; } else { - if (polyFlatShader == null) { - if (defPolyFlatShader == null) { - defPolyFlatShader = new PolyFlatShader(parent, defPolyFlatShaderVertURL, defPolyNoTexShaderFragURL); + if (polyColorShader == null) { + if (defPolyColorShader == null) { + defPolyColorShader = new PolyColorShader(parent, + defPolyColorShaderVertURL, + defPolyNoTexShaderFragURL); } - polyFlatShader = defPolyFlatShader; + shader = defPolyColorShader; + colorShaderCheck(); + } else { + shader = polyColorShader; } - shader = polyFlatShader; } } shader.setRenderer(this); shader.loadAttributes(); - shader.loadUniforms(); + shader.loadUniforms(); return shader; } + protected void texlightShaderCheck() { + if (shaderWarningsEnabled && + (polyLightShader != null || + polyTexShader != null || + polyColorShader != null)) { + PGraphics.showWarning("Your shader cannot be used to render textured " + + "and lit geometry, using default shader instead."); + } + } + + + protected void lightShaderCheck() { + if (shaderWarningsEnabled && + (polyTexlightShader != null || + polyTexShader != null || + polyColorShader != null)) { + PGraphics.showWarning("Your shader cannot be used to render lit " + + "geometry, using default shader instead."); + } + } + + + protected void texShaderCheck() { + if (shaderWarningsEnabled && + (polyTexlightShader != null || + polyLightShader != null || + polyColorShader != null)) { + PGraphics.showWarning("Your shader cannot be used to render textured " + + "geometry, using default shader instead."); + } + } + + + protected void colorShaderCheck() { + if (shaderWarningsEnabled && + (polyTexlightShader != null || + polyLightShader != null || + polyTexShader != null)) { + PGraphics.showWarning("Your shader cannot be used to render colored " + + "geometry, using default shader instead."); + } + } + + protected LineShader getLineShader() { + LineShader shader; if (lineShader == null) { if (defLineShader == null) { - defLineShader = new LineShader(parent, defLineShaderVertURL, defLineShaderFragURL); + defLineShader = new LineShader(parent, defLineShaderVertURL, + defLineShaderFragURL); } - lineShader = defLineShader; + shader = defLineShader; + } else { + shader = lineShader; } - lineShader.setRenderer(this); - lineShader.loadAttributes(); - lineShader.loadUniforms(); - return lineShader; + shader.setRenderer(this); + shader.loadAttributes(); + shader.loadUniforms(); + return shader; } protected PointShader getPointShader() { + PointShader shader; if (pointShader == null) { if (defPointShader == null) { - defPointShader = new PointShader(parent, defPointShaderVertURL, defPointShaderFragURL); + defPointShader = new PointShader(parent, defPointShaderVertURL, + defPointShaderFragURL); } - pointShader = defPointShader; + shader = defPointShader; + } else { + shader = pointShader; } - pointShader.setRenderer(this); - pointShader.loadAttributes(); - pointShader.loadUniforms(); - return pointShader; + shader.setRenderer(this); + shader.loadAttributes(); + shader.loadUniforms(); + return shader; } @@ -6033,19 +6302,27 @@ public class PGraphicsOpenGL extends PGraphics { super(parent, vertURL, fragURL); } - 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) { } + 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) { } public void setTexture(Texture tex) { } } - protected class PolyFlatShader extends PolyShader { + protected class PolyColorShader extends PolyShader { protected int projmodelviewMatrixLoc; protected int modelviewMatrixLoc; protected int projectionMatrixLoc; @@ -6053,15 +6330,16 @@ public class PGraphicsOpenGL extends PGraphics { protected int inVertexLoc; protected int inColorLoc; - public PolyFlatShader(PApplet parent) { + public PolyColorShader(PApplet parent) { super(parent); } - public PolyFlatShader(PApplet parent, String vertFilename, String fragFilename) { + public PolyColorShader(PApplet parent, String vertFilename, + String fragFilename) { super(parent, vertFilename, fragFilename); } - public PolyFlatShader(PApplet parent, URL vertURL, URL fragURL) { + public PolyColorShader(PApplet parent, URL vertURL, URL fragURL) { super(parent, vertURL, fragURL); } @@ -6076,35 +6354,40 @@ public class PGraphicsOpenGL extends PGraphics { projectionMatrixLoc = getUniformLoc("projectionMatrix"); } - public void setVertexAttribute(int vboId, int size, int type, int stride, int offset) { + public void setVertexAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inVertexLoc, vboId, size, type, false, stride, offset); } - public void setColorAttribute(int vboId, int size, int type, int stride, int offset) { + public void setColorAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inColorLoc, vboId, size, type, true, stride, offset); } public void bind() { super.bind(); - + if (pgCurrent == null) { + setRenderer(PGraphicsOpenGL.pgCurrent); + loadAttributes(); + loadUniforms(); + } + if (-1 < inVertexLoc) pgl.enableVertexAttribArray(inVertexLoc); if (-1 < inColorLoc) pgl.enableVertexAttribArray(inColorLoc); - if (pgCurrent != null) { - if (-1 < projmodelviewMatrixLoc) { - pgCurrent.updateGLProjmodelview(); - setUniformMatrix(projmodelviewMatrixLoc, pgCurrent.glProjmodelview); - } + if (-1 < projmodelviewMatrixLoc) { + pgCurrent.updateGLProjmodelview(); + setUniformMatrix(projmodelviewMatrixLoc, pgCurrent.glProjmodelview); + } - if (-1 < modelviewMatrixLoc) { - pgCurrent.updateGLModelview(); - setUniformMatrix(modelviewMatrixLoc, pgCurrent.glModelview); - } + if (-1 < modelviewMatrixLoc) { + pgCurrent.updateGLModelview(); + setUniformMatrix(modelviewMatrixLoc, pgCurrent.glModelview); + } - if (-1 < projectionMatrixLoc) { - pgCurrent.updateGLProjection(); - setUniformMatrix(projectionMatrixLoc, pgCurrent.glProjection); - } + if (-1 < projectionMatrixLoc) { + pgCurrent.updateGLProjection(); + setUniformMatrix(projectionMatrixLoc, pgCurrent.glProjection); } } @@ -6147,7 +6430,8 @@ public class PGraphicsOpenGL extends PGraphics { super(parent); } - public PolyLightShader(PApplet parent, String vertFilename, String fragFilename) { + public PolyLightShader(PApplet parent, String vertFilename, + String fragFilename) { super(parent, vertFilename, fragFilename); } @@ -6182,37 +6466,49 @@ public class PGraphicsOpenGL extends PGraphics { lightSpotParametersLoc = getUniformLoc("lightSpotParameters"); } - public void setVertexAttribute(int vboId, int size, int type, int stride, int offset) { + public void setVertexAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inVertexLoc, vboId, size, type, false, stride, offset); } - public void setColorAttribute(int vboId, int size, int type, int stride, int offset) { + public void setColorAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inColorLoc, vboId, size, type, true, stride, offset); } - public void setNormalAttribute(int vboId, int size, int type, int stride, int offset) { + public void setNormalAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inNormalLoc, vboId, size, type, false, stride, offset); } - public void setAmbientAttribute(int vboId, int size, int type, int stride, int offset) { + public void setAmbientAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inAmbientLoc, vboId, size, type, true, stride, offset); } - public void setSpecularAttribute(int vboId, int size, int type, int stride, int offset) { + public void setSpecularAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inSpecularLoc, vboId, size, type, true, stride, offset); } - public void setEmissiveAttribute(int vboId, int size, int type, int stride, int offset) { + public void setEmissiveAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inEmissiveLoc, vboId, size, type, true, stride, offset); } - public void setShininessAttribute(int vboId, int size, int type, int stride, int offset) { + public void setShininessAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inShineLoc, vboId, size, type, false, stride, offset); } public void bind() { super.bind(); - + if (pgCurrent == null) { + setRenderer(PGraphicsOpenGL.pgCurrent); + loadAttributes(); + loadUniforms(); + } + if (-1 < inVertexLoc) pgl.enableVertexAttribArray(inVertexLoc); if (-1 < inColorLoc) pgl.enableVertexAttribArray(inColorLoc); if (-1 < inNormalLoc) pgl.enableVertexAttribArray(inNormalLoc); @@ -6222,36 +6518,36 @@ public class PGraphicsOpenGL extends PGraphics { if (-1 < inEmissiveLoc) pgl.enableVertexAttribArray(inEmissiveLoc); if (-1 < inShineLoc) pgl.enableVertexAttribArray(inShineLoc); - if (pgCurrent != null) { - if (-1 < projmodelviewMatrixLoc) { - pgCurrent.updateGLProjmodelview(); - setUniformMatrix(projmodelviewMatrixLoc, pgCurrent.glProjmodelview); - } - - if (-1 < modelviewMatrixLoc) { - pgCurrent.updateGLModelview(); - setUniformMatrix(modelviewMatrixLoc, pgCurrent.glModelview); - } - - if (-1 < projectionMatrixLoc) { - pgCurrent.updateGLProjection(); - setUniformMatrix(projectionMatrixLoc, pgCurrent.glProjection); - } - - if (-1 < normalMatrixLoc) { - pgCurrent.updateGLNormal(); - setUniformMatrix(normalMatrixLoc, pgCurrent.glNormal); - } - - setUniformValue(lightCountLoc, pgCurrent.lightCount); - setUniformVector(lightPositionLoc, pgCurrent.lightPosition, 4); - setUniformVector(lightNormalLoc, pgCurrent.lightNormal, 3); - setUniformVector(lightAmbientLoc, pgCurrent.lightAmbient, 3); - setUniformVector(lightDiffuseLoc, pgCurrent.lightDiffuse, 3); - setUniformVector(lightSpecularLoc, pgCurrent.lightSpecular, 3); - setUniformVector(lightFalloffCoefficientsLoc, pgCurrent.lightFalloffCoefficients, 3); - setUniformVector(lightSpotParametersLoc, pgCurrent.lightSpotParameters, 2); + if (-1 < projmodelviewMatrixLoc) { + pgCurrent.updateGLProjmodelview(); + setUniformMatrix(projmodelviewMatrixLoc, pgCurrent.glProjmodelview); } + + if (-1 < modelviewMatrixLoc) { + pgCurrent.updateGLModelview(); + setUniformMatrix(modelviewMatrixLoc, pgCurrent.glModelview); + } + + if (-1 < projectionMatrixLoc) { + pgCurrent.updateGLProjection(); + setUniformMatrix(projectionMatrixLoc, pgCurrent.glProjection); + } + + if (-1 < normalMatrixLoc) { + pgCurrent.updateGLNormal(); + setUniformMatrix(normalMatrixLoc, pgCurrent.glNormal); + } + + setUniformValue(lightCountLoc, pgCurrent.lightCount); + setUniformVector(lightPositionLoc, pgCurrent.lightPosition, 4); + setUniformVector(lightNormalLoc, pgCurrent.lightNormal, 3); + setUniformVector(lightAmbientLoc, pgCurrent.lightAmbient, 3); + setUniformVector(lightDiffuseLoc, pgCurrent.lightDiffuse, 3); + setUniformVector(lightSpecularLoc, pgCurrent.lightSpecular, 3); + setUniformVector(lightFalloffCoefficientsLoc, + pgCurrent.lightFalloffCoefficients, 3); + setUniformVector(lightSpotParametersLoc, + pgCurrent.lightSpotParameters, 2); } public void unbind() { @@ -6271,7 +6567,7 @@ public class PGraphicsOpenGL extends PGraphics { } - protected class PolyTexShader extends PolyFlatShader { + protected class PolyTexShader extends PolyColorShader { protected int inTexcoordLoc; protected int textureSamplerLoc; @@ -6284,7 +6580,8 @@ public class PGraphicsOpenGL extends PGraphics { super(parent); } - public PolyTexShader(PApplet parent, String vertFilename, String fragFilename) { + public PolyTexShader(PApplet parent, String vertFilename, + String fragFilename) { super(parent, vertFilename, fragFilename); } @@ -6306,7 +6603,8 @@ public class PGraphicsOpenGL extends PGraphics { inTexcoordLoc = getAttributeLoc("inTexcoord"); } - public void setTexcoordAttribute(int vboId, int size, int type, int stride, int offset) { + public void setTexcoordAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inTexcoordLoc, vboId, size, type, false, stride, offset); } @@ -6363,7 +6661,7 @@ public class PGraphicsOpenGL extends PGraphics { } - protected class PolyFullShader extends PolyLightShader { + protected class PolyTexlightShader extends PolyLightShader { protected int inTexcoordLoc; protected int textureSamplerLoc; @@ -6372,15 +6670,16 @@ public class PGraphicsOpenGL extends PGraphics { protected float[] tcmat; - public PolyFullShader(PApplet parent) { + public PolyTexlightShader(PApplet parent) { super(parent); } - public PolyFullShader(PApplet parent, String vertFilename, String fragFilename) { + public PolyTexlightShader(PApplet parent, String vertFilename, + String fragFilename) { super(parent, vertFilename, fragFilename); } - public PolyFullShader(PApplet parent, URL vertURL, URL fragURL) { + public PolyTexlightShader(PApplet parent, URL vertURL, URL fragURL) { super(parent, vertURL, fragURL); } @@ -6398,7 +6697,8 @@ public class PGraphicsOpenGL extends PGraphics { inTexcoordLoc = getAttributeLoc("inTexcoord"); } - public void setTexcoordAttribute(int vboId, int size, int type, int stride, int offset) { + public void setTexcoordAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inTexcoordLoc, vboId, size, type, false, stride, offset); } @@ -6442,7 +6742,7 @@ public class PGraphicsOpenGL extends PGraphics { public void bind() { firstTexUnit = 1; // 0 will be used by the textureSampler - super.bind(); + super.bind(); if (-1 < inTexcoordLoc) pgl.enableVertexAttribArray(inTexcoordLoc); } @@ -6472,7 +6772,8 @@ public class PGraphicsOpenGL extends PGraphics { super(parent); } - public LineShader(PApplet parent, String vertFilename, String fragFilename) { + public LineShader(PApplet parent, String vertFilename, + String fragFilename) { super(parent, vertFilename, fragFilename); } @@ -6496,61 +6797,67 @@ public class PGraphicsOpenGL extends PGraphics { scaleLoc = getUniformLoc("scale"); } - public void setVertexAttribute(int vboId, int size, int type, int stride, int offset) { + public void setVertexAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inVertexLoc, vboId, size, type, false, stride, offset); } - public void setColorAttribute(int vboId, int size, int type, int stride, int offset) { + public void setColorAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inColorLoc, vboId, size, type, true, stride, offset); } - public void setLineAttribute(int vboId, int size, int type, int stride, int offset) { + public void setLineAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inAttribLoc, vboId, size, type, false, stride, offset); } public void bind() { super.bind(); + if (pgCurrent == null) { + setRenderer(PGraphicsOpenGL.pgCurrent); + loadAttributes(); + loadUniforms(); + } if (-1 < inVertexLoc) pgl.enableVertexAttribArray(inVertexLoc); if (-1 < inColorLoc) pgl.enableVertexAttribArray(inColorLoc); if (-1 < inAttribLoc) pgl.enableVertexAttribArray(inAttribLoc); - if (pgCurrent != null) { - if (-1 < projmodelviewMatrixLoc) { - pgCurrent.updateGLProjmodelview(); - setUniformMatrix(projmodelviewMatrixLoc, pgCurrent.glProjmodelview); - } + if (-1 < projmodelviewMatrixLoc) { + pgCurrent.updateGLProjmodelview(); + setUniformMatrix(projmodelviewMatrixLoc, pgCurrent.glProjmodelview); + } - if (-1 < modelviewMatrixLoc) { - pgCurrent.updateGLModelview(); - setUniformMatrix(modelviewMatrixLoc, pgCurrent.glModelview); - } + if (-1 < modelviewMatrixLoc) { + pgCurrent.updateGLModelview(); + setUniformMatrix(modelviewMatrixLoc, pgCurrent.glModelview); + } - if (-1 < projectionMatrixLoc) { - pgCurrent.updateGLProjection(); - setUniformMatrix(projectionMatrixLoc, pgCurrent.glProjection); - } + if (-1 < projectionMatrixLoc) { + pgCurrent.updateGLProjection(); + setUniformMatrix(projectionMatrixLoc, pgCurrent.glProjection); + } - float x = pgCurrent.viewport[0]; - float y = pgCurrent.viewport[1]; - float w = pgCurrent.viewport[2]; - float h = pgCurrent.viewport[3]; - setUniformValue(viewportLoc, x, y, w, h); + float x = pgCurrent.viewport[0]; + float y = pgCurrent.viewport[1]; + float w = pgCurrent.viewport[2]; + float h = pgCurrent.viewport[3]; + setUniformValue(viewportLoc, x, y, w, h); - if (pgCurrent.hintEnabled(ENABLE_PERSPECTIVE_CORRECTED_LINES)) { - setUniformValue(perspectiveLoc, 1); + if (pgCurrent.hintEnabled(ENABLE_STROKE_PERSPECTIVE)) { + setUniformValue(perspectiveLoc, 1); + } else { + setUniformValue(perspectiveLoc, 0); + } + + if (pgCurrent.hintEnabled(ENABLE_ACCURATE_2D)) { + setUniformValue(scaleLoc, 1.0f, 1.0f, 1.0f); + } else { + if (usingOrthoProjection) { + setUniformValue(scaleLoc, 1.0f, 1.0f, 0.99f); } else { - setUniformValue(perspectiveLoc, 0); - } - - if (pgCurrent.hintEnabled(ENABLE_ACCURATE_2D)) { - setUniformValue(scaleLoc, 1.0f, 1.0f, 1.0f); - } else { - if (usingOrthoProjection) { - setUniformValue(scaleLoc, 1.0f, 1.0f, 0.99f); - } else { - setUniformValue(scaleLoc, 0.99f, 0.99f, 0.99f); - } + setUniformValue(scaleLoc, 0.99f, 0.99f, 0.99f); } } } @@ -6572,6 +6879,9 @@ public class PGraphicsOpenGL extends PGraphics { protected int modelviewMatrixLoc; protected int projectionMatrixLoc; + protected int viewportLoc; + protected int perspectiveLoc; + protected int inVertexLoc; protected int inColorLoc; protected int inPointLoc; @@ -6580,7 +6890,8 @@ public class PGraphicsOpenGL extends PGraphics { super(parent); } - public PointShader(PApplet parent, String vertFilename, String fragFilename) { + public PointShader(PApplet parent, String vertFilename, + String fragFilename) { super(parent, vertFilename, fragFilename); } @@ -6598,43 +6909,64 @@ public class PGraphicsOpenGL extends PGraphics { projmodelviewMatrixLoc = getUniformLoc("projmodelviewMatrix"); modelviewMatrixLoc = getUniformLoc("modelviewMatrix"); projectionMatrixLoc = getUniformLoc("projectionMatrix"); + + viewportLoc = getUniformLoc("viewport"); + perspectiveLoc = getUniformLoc("perspective"); } - public void setVertexAttribute(int vboId, int size, int type, int stride, int offset) { + public void setVertexAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inVertexLoc, vboId, size, type, false, stride, offset); } - public void setColorAttribute(int vboId, int size, int type, int stride, int offset) { + public void setColorAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inColorLoc, vboId, size, type, true, stride, offset); } - public void setPointAttribute(int vboId, int size, int type, int stride, int offset) { + public void setPointAttribute(int vboId, int size, int type, + int stride, int offset) { setAttributeVBO(inPointLoc, vboId, size, type, false, stride, offset); } public void bind() { super.bind(); + if (pgCurrent == null) { + setRenderer(PGraphicsOpenGL.pgCurrent); + loadAttributes(); + loadUniforms(); + } if (-1 < inVertexLoc) pgl.enableVertexAttribArray(inVertexLoc); if (-1 < inColorLoc) pgl.enableVertexAttribArray(inColorLoc); if (-1 < inPointLoc) pgl.enableVertexAttribArray(inPointLoc); - if (pgCurrent != null) { - if (-1 < projmodelviewMatrixLoc) { - pgCurrent.updateGLProjmodelview(); - setUniformMatrix(projmodelviewMatrixLoc, pgCurrent.glProjmodelview); - } - - if (-1 < modelviewMatrixLoc) { - pgCurrent.updateGLModelview(); - setUniformMatrix(modelviewMatrixLoc, pgCurrent.glModelview); - } - - if (-1 < projectionMatrixLoc) { - pgCurrent.updateGLProjection(); - setUniformMatrix(projectionMatrixLoc, pgCurrent.glProjection); - } + if (-1 < projmodelviewMatrixLoc) { + pgCurrent.updateGLProjmodelview(); + setUniformMatrix(projmodelviewMatrixLoc, pgCurrent.glProjmodelview); } + + if (-1 < modelviewMatrixLoc) { + pgCurrent.updateGLModelview(); + setUniformMatrix(modelviewMatrixLoc, pgCurrent.glModelview); + } + + if (-1 < projectionMatrixLoc) { + pgCurrent.updateGLProjection(); + setUniformMatrix(projectionMatrixLoc, pgCurrent.glProjection); + } + + float x = pgCurrent.viewport[0]; + float y = pgCurrent.viewport[1]; + float w = pgCurrent.viewport[2]; + float h = pgCurrent.viewport[3]; + setUniformValue(viewportLoc, x, y, w, h); + + if (pgCurrent.hintEnabled(ENABLE_STROKE_PERSPECTIVE)) { + setUniformValue(perspectiveLoc, 1); + } else { + setUniformValue(perspectiveLoc, 0); + } } public void unbind() { @@ -7326,7 +7658,8 @@ public class PGraphicsOpenGL extends PGraphics { normalX, normalY, normalZ, 0, 0, strokeColor, strokeWeight, - ambientColor, specularColor, emissiveColor, shininessFactor, + ambientColor, specularColor, emissiveColor, + shininessFactor, code); } @@ -7338,7 +7671,8 @@ public class PGraphicsOpenGL extends PGraphics { normalX, normalY, normalZ, u, v, strokeColor, strokeWeight, - ambientColor, specularColor, emissiveColor, shininessFactor, + ambientColor, specularColor, emissiveColor, + shininessFactor, code); } @@ -7349,7 +7683,8 @@ public class PGraphicsOpenGL extends PGraphics { normalX, normalY, normalZ, 0, 0, strokeColor, strokeWeight, - ambientColor, specularColor, emissiveColor, shininessFactor, + ambientColor, specularColor, emissiveColor, + shininessFactor, code); } @@ -7361,7 +7696,8 @@ public class PGraphicsOpenGL extends PGraphics { normalX, normalY, normalZ, u, v, strokeColor, strokeWeight, - ambientColor, specularColor, emissiveColor, shininessFactor, + ambientColor, specularColor, emissiveColor, + shininessFactor, code); } @@ -7422,7 +7758,8 @@ public class PGraphicsOpenGL extends PGraphics { void addBezierVertex(float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4, - boolean fill, boolean stroke, int detail, int code, int shape) { + boolean fill, boolean stroke, int detail, int code, + int shape) { bezierInitCheck(); bezierVertexCheck(shape, vertexCount); @@ -7454,7 +7791,8 @@ public class PGraphicsOpenGL extends PGraphics { public void addQuadraticVertex(float cx, float cy, float cz, float x3, float y3, float z3, - boolean fill, boolean stroke, int detail, int code) { + boolean fill, boolean stroke, int detail, + int code) { addQuadraticVertex(cx, cy, cz, x3, y3, z3, fill, stroke, detail, code, POLYGON); @@ -7462,14 +7800,16 @@ public class PGraphicsOpenGL extends PGraphics { public void addQuadraticVertex(float cx, float cy, float cz, float x3, float y3, float z3, - boolean fill, boolean stroke, int detail, int code, int shape) { + boolean fill, boolean stroke, int detail, + int code, int shape) { float x1 = getLastVertexX(); float y1 = getLastVertexY(); float z1 = getLastVertexZ(); - addBezierVertex(x1 + ((cx-x1)*2/3.0f), y1 + ((cy-y1)*2/3.0f), z1 + ((cz-z1)*2/3.0f), - x3 + ((cx-x3)*2/3.0f), y3 + ((cy-y3)*2/3.0f), z3 + ((cz-z3)*2/3.0f), - x3, y3, z3, - fill, stroke, detail, code, shape); + addBezierVertex( + x1 + ((cx-x1)*2/3.0f), y1 + ((cy-y1)*2/3.0f), z1 + ((cz-z1)*2/3.0f), + x3 + ((cx-x3)*2/3.0f), y3 + ((cy-y3)*2/3.0f), z3 + ((cz-z3)*2/3.0f), + x3, y3, z3, + fill, stroke, detail, code, shape); } void addCurveVertex(float x, float y, float z, @@ -7479,7 +7819,8 @@ public class PGraphicsOpenGL extends PGraphics { } void addCurveVertex(float x, float y, float z, - boolean fill, boolean stroke, int detail, int code, int shape) { + boolean fill, boolean stroke, int detail, int code, + int shape) { curveVertexCheck(shape); float[] vertex = curveVertices[curveVertexCount]; vertex[X] = x; @@ -7849,7 +8190,8 @@ public class PGraphicsOpenGL extends PGraphics { // Primitives void setMaterial(int fillColor, int strokeColor, float strokeWeight, - int ambientColor, int specularColor, int emissiveColor, float shininessFactor) { + int ambientColor, int specularColor, int emissiveColor, + float shininessFactor) { this.fillColor = fillColor; this.strokeColor = strokeColor; this.strokeWeight = strokeWeight; @@ -8066,8 +8408,10 @@ public class PGraphicsOpenGL extends PGraphics { float sx2 = pgCurrent.screenX(x + w, y + h); float sy2 = pgCurrent.screenY(x + w, y + h); - int accuracy = PApplet.max(MIN_POINT_ACCURACY, - (int) (TWO_PI * PApplet.dist(sx1, sy1, sx2, sy2) / POINT_ACCURACY_FACTOR)); + int accuracy = + PApplet.max(MIN_POINT_ACCURACY, + (int) (TWO_PI * PApplet.dist(sx1, sy1, sx2, sy2) / + POINT_ACCURACY_FACTOR)); float inc = (float) PGraphicsOpenGL.SINCOS_LENGTH / accuracy; if (fill) { @@ -8309,13 +8653,15 @@ public class PGraphicsOpenGL extends PGraphics { for (int i = 0; i < detailU; i++) { int ioff = offset + i; setNormal(sphereX[ioff], sphereY[ioff], sphereZ[ioff]); - addVertex(r * sphereX[ioff], r *sphereY[ioff], r * sphereZ[ioff], u , v, VERTEX); + addVertex(r * sphereX[ioff], r *sphereY[ioff], r * sphereZ[ioff], + u , v, VERTEX); u -= du; } vertCount += detailU; vert1 = vertCount; setNormal(sphereX[offset], sphereY[offset], sphereZ[offset]); - addVertex(r * sphereX[offset], r * sphereY[offset], r * sphereZ[offset], u, v, VERTEX); + addVertex(r * sphereX[offset], r * sphereY[offset], r * sphereZ[offset], + u, v, VERTEX); vertCount++; for (int i = 0; i < detailU; i++) { @@ -9041,7 +9387,8 @@ public class PGraphicsOpenGL extends PGraphics { // // Add point geometry - // Sets point vertex with index tessIdx using the data from input vertex inIdx. + // Sets point vertex with index tessIdx using the data from input vertex + // inIdx. void setPointVertex(int tessIdx, InGeometry in, int inIdx) { int index; @@ -9050,14 +9397,15 @@ public class PGraphicsOpenGL extends PGraphics { float y = in.vertices[index++]; float z = in.vertices[index ]; - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { + if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && + !hints[DISABLE_TRANSFORM_CACHE]) { PMatrix3D mm = modelview; index = 4 * tessIdx; - pointVertices[index++] = x * mm.m00 + y * mm.m01 + z * mm.m02 + mm.m03; - pointVertices[index++] = x * mm.m10 + y * mm.m11 + z * mm.m12 + mm.m13; - pointVertices[index++] = x * mm.m20 + y * mm.m21 + z * mm.m22 + mm.m23; - pointVertices[index ] = x * mm.m30 + y * mm.m31 + z * mm.m32 + mm.m33; + 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; + pointVertices[index ] = x*mm.m30 + y*mm.m31 + z*mm.m32 + mm.m33; } else { index = 4 * tessIdx; pointVertices[index++] = x; @@ -9081,14 +9429,15 @@ public class PGraphicsOpenGL extends PGraphics { float y0 = in.vertices[index++]; float z0 = in.vertices[index ]; - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { + if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && + !hints[DISABLE_TRANSFORM_CACHE]) { PMatrix3D mm = modelview; index = 4 * tessIdx; - lineVertices[index++] = x0 * mm.m00 + y0 * mm.m01 + z0 * mm.m02 + mm.m03; - lineVertices[index++] = x0 * mm.m10 + y0 * mm.m11 + z0 * mm.m12 + mm.m13; - lineVertices[index++] = x0 * mm.m20 + y0 * mm.m21 + z0 * mm.m22 + mm.m23; - lineVertices[index ] = x0 * mm.m30 + y0 * mm.m31 + z0 * mm.m32 + mm.m33; + 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; + lineVertices[index ] = x0*mm.m30 + y0*mm.m31 + z0*mm.m32 + mm.m33; } else { index = 4 * tessIdx; lineVertices[index++] = x0; @@ -9105,8 +9454,10 @@ public class PGraphicsOpenGL extends PGraphics { lineAttribs[index ] = 0; } - // Sets line vertex with index tessIdx using the data from input vertices inIdx0 and inIdx1. - void setLineVertex(int tessIdx, InGeometry in, int inIdx0, int inIdx1, int rgba, float weight) { + // Sets line vertex with index tessIdx using the data from input vertices + //inIdx0 and inIdx1. + void setLineVertex(int tessIdx, InGeometry in, int inIdx0, int inIdx1, + int rgba, float weight) { int index; index = 3 * inIdx0; @@ -9119,19 +9470,20 @@ public class PGraphicsOpenGL extends PGraphics { float y1 = in.vertices[index++]; float z1 = in.vertices[index ]; - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { + if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && + !hints[DISABLE_TRANSFORM_CACHE]) { PMatrix3D mm = modelview; index = 4 * tessIdx; - lineVertices[index++] = x0 * mm.m00 + y0 * mm.m01 + z0 * mm.m02 + mm.m03; - lineVertices[index++] = x0 * mm.m10 + y0 * mm.m11 + z0 * mm.m12 + mm.m13; - lineVertices[index++] = x0 * mm.m20 + y0 * mm.m21 + z0 * mm.m22 + mm.m23; - lineVertices[index ] = x0 * mm.m30 + y0 * mm.m31 + z0 * mm.m32 + mm.m33; + 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; + lineVertices[index ] = x0*mm.m30 + y0*mm.m31 + z0*mm.m32 + mm.m33; index = 4 * tessIdx; - lineAttribs[index++] = x1 * mm.m00 + y1 * mm.m01 + z1 * mm.m02 + mm.m03; - lineAttribs[index++] = x1 * mm.m10 + y1 * mm.m11 + z1 * mm.m12 + mm.m13; - lineAttribs[index ] = x1 * mm.m20 + y1 * mm.m21 + z1 * mm.m22 + mm.m23; + lineAttribs[index++] = x1*mm.m00 + y1*mm.m01 + z1*mm.m02 + mm.m03; + lineAttribs[index++] = x1*mm.m10 + y1*mm.m11 + z1*mm.m12 + mm.m13; + lineAttribs[index ] = x1*mm.m20 + y1*mm.m21 + z1*mm.m22 + mm.m23; } else { index = 4 * tessIdx; lineVertices[index++] = x0; @@ -9168,20 +9520,21 @@ public class PGraphicsOpenGL extends PGraphics { int am, int sp, int em, float shine) { int index; - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { + if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && + !hints[DISABLE_TRANSFORM_CACHE]) { PMatrix3D mm = modelview; PMatrix3D nm = modelviewInv; index = 4 * tessIdx; - polyVertices[index++] = x * mm.m00 + y * mm.m01 + z * mm.m02 + mm.m03; - polyVertices[index++] = x * mm.m10 + y * mm.m11 + z * mm.m12 + mm.m13; - polyVertices[index++] = x * mm.m20 + y * mm.m21 + z * mm.m22 + mm.m23; - polyVertices[index ] = x * mm.m30 + y * mm.m31 + z * mm.m32 + mm.m33; + polyVertices[index++] = x*mm.m00 + y*mm.m01 + z*mm.m02 + mm.m03; + polyVertices[index++] = x*mm.m10 + y*mm.m11 + z*mm.m12 + mm.m13; + polyVertices[index++] = x*mm.m20 + y*mm.m21 + z*mm.m22 + mm.m23; + polyVertices[index ] = x*mm.m30 + y*mm.m31 + z*mm.m32 + mm.m33; index = 3 * tessIdx; - polyNormals[index++] = nx * nm.m00 + ny * nm.m10 + nz * nm.m20; - polyNormals[index++] = nx * nm.m01 + ny * nm.m11 + nz * nm.m21; - polyNormals[index ] = nx * nm.m02 + ny * nm.m12 + nz * nm.m22; + polyNormals[index++] = nx*nm.m00 + ny*nm.m10 + nz*nm.m20; + polyNormals[index++] = nx*nm.m01 + ny*nm.m11 + nz*nm.m21; + polyNormals[index ] = nx*nm.m02 + ny*nm.m12 + nz*nm.m22; } else { index = 4 * tessIdx; polyVertices[index++] = x; @@ -9216,20 +9569,21 @@ public class PGraphicsOpenGL extends PGraphics { int index; int count = polyVertexCount - 1; - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { + if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && + !hints[DISABLE_TRANSFORM_CACHE]) { PMatrix3D mm = modelview; PMatrix3D nm = modelviewInv; index = 4 * count; - polyVertices[index++] = x * mm.m00 + y * mm.m01 + z * mm.m02 + mm.m03; - polyVertices[index++] = x * mm.m10 + y * mm.m11 + z * mm.m12 + mm.m13; - polyVertices[index++] = x * mm.m20 + y * mm.m21 + z * mm.m22 + mm.m23; - polyVertices[index ] = x * mm.m30 + y * mm.m31 + z * mm.m32 + mm.m33; + polyVertices[index++] = x*mm.m00 + y*mm.m01 + z*mm.m02 + mm.m03; + polyVertices[index++] = x*mm.m10 + y*mm.m11 + z*mm.m12 + mm.m13; + polyVertices[index++] = x*mm.m20 + y*mm.m21 + z*mm.m22 + mm.m23; + polyVertices[index ] = x*mm.m30 + y*mm.m31 + z*mm.m32 + mm.m33; index = 3 * count; - polyNormals[index++] = nx * nm.m00 + ny * nm.m10 + nz * nm.m20; - polyNormals[index++] = nx * nm.m01 + ny * nm.m11 + nz * nm.m21; - polyNormals[index ] = nx * nm.m02 + ny * nm.m12 + nz * nm.m22; + polyNormals[index++] = nx*nm.m00 + ny*nm.m10 + nz*nm.m20; + polyNormals[index++] = nx*nm.m01 + ny*nm.m11 + nz*nm.m21; + polyNormals[index ] = nx*nm.m02 + ny*nm.m12 + nz*nm.m22; } else { index = 4 * count; polyVertices[index++] = x; @@ -9269,7 +9623,8 @@ public class PGraphicsOpenGL extends PGraphics { polyVertexCheck(nvert); - if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && !hints[DISABLE_TRANSFORM_CACHE]) { + if (renderMode == IMMEDIATE && flushMode == FLUSH_WHEN_FULL && + !hints[DISABLE_TRANSFORM_CACHE]) { PMatrix3D mm = modelview; PMatrix3D nm = modelviewInv; @@ -9288,20 +9643,20 @@ public class PGraphicsOpenGL extends PGraphics { float nz = in.normals[index ]; index = 4 * tessIdx; - polyVertices[index++] = x * mm.m00 + y * mm.m01 + z * mm.m02 + mm.m03; - polyVertices[index++] = x * mm.m10 + y * mm.m11 + z * mm.m12 + mm.m13; - polyVertices[index++] = x * mm.m20 + y * mm.m21 + z * mm.m22 + mm.m23; - polyVertices[index ] = x * mm.m30 + y * mm.m31 + z * mm.m32 + mm.m33; + polyVertices[index++] = x*mm.m00 + y*mm.m01 + z*mm.m02 + mm.m03; + polyVertices[index++] = x*mm.m10 + y*mm.m11 + z*mm.m12 + mm.m13; + polyVertices[index++] = x*mm.m20 + y*mm.m21 + z*mm.m22 + mm.m23; + polyVertices[index ] = x*mm.m30 + y*mm.m31 + z*mm.m32 + mm.m33; index = 3 * tessIdx; - polyNormals[index++] = nx * nm.m00 + ny * nm.m10 + nz * nm.m20; - polyNormals[index++] = nx * nm.m01 + ny * nm.m11 + nz * nm.m21; - polyNormals[index ] = nx * nm.m02 + ny * nm.m12 + nz * nm.m22; + polyNormals[index++] = nx*nm.m00 + ny*nm.m10 + nz*nm.m20; + polyNormals[index++] = nx*nm.m01 + ny*nm.m11 + nz*nm.m21; + polyNormals[index ] = nx*nm.m02 + ny*nm.m12 + nz*nm.m22; } } else { if (nvert <= PGL.MIN_ARRAYCOPY_SIZE) { - // Copying elements one by one instead of using arrayCopy is more efficient for - // few vertices... + // Copying elements one by one instead of using arrayCopy is more + // efficient for few vertices... for (int i = 0; i < nvert; i++) { int inIdx = i0 + i; int tessIdx = firstPolyVertex + i; @@ -9331,10 +9686,12 @@ public class PGraphicsOpenGL extends PGraphics { for (int i = 0; i < nvert; i++) { int inIdx = i0 + i; int tessIdx = firstPolyVertex + i; - PApplet.arrayCopy(in.vertices, 3 * inIdx, polyVertices, 4 * tessIdx, 3); + PApplet.arrayCopy(in.vertices, 3 * inIdx, + polyVertices, 4 * tessIdx, 3); polyVertices[4 * tessIdx + 3] = 1; } - PApplet.arrayCopy(in.normals, 3 * i0, polyNormals, 3 * firstPolyVertex, 3 * nvert); + PApplet.arrayCopy(in.normals, 3 * i0, + polyNormals, 3 * firstPolyVertex, 3 * nvert); } } @@ -9359,12 +9716,18 @@ public class PGraphicsOpenGL extends PGraphics { polyShininess[tessIdx] = in.shininess[inIdx]; } } else { - PApplet.arrayCopy(in.colors, i0, polyColors, firstPolyVertex, nvert); - PApplet.arrayCopy(in.texcoords, 2 * i0, polyTexcoords, 2 * firstPolyVertex, 2 * nvert); - PApplet.arrayCopy(in.ambient, i0, polyAmbient, firstPolyVertex, nvert); - PApplet.arrayCopy(in.specular, i0, polySpecular, firstPolyVertex, nvert); - PApplet.arrayCopy(in.emissive, i0, polyEmissive, firstPolyVertex, nvert); - PApplet.arrayCopy(in.shininess, i0, polyShininess, firstPolyVertex, nvert); + PApplet.arrayCopy(in.colors, i0, + polyColors, firstPolyVertex, nvert); + PApplet.arrayCopy(in.texcoords, 2 * i0, + polyTexcoords, 2 * firstPolyVertex, 2 * nvert); + PApplet.arrayCopy(in.ambient, i0, + polyAmbient, firstPolyVertex, nvert); + PApplet.arrayCopy(in.specular, i0, + polySpecular, firstPolyVertex, nvert); + PApplet.arrayCopy(in.emissive, i0, + polyEmissive, firstPolyVertex, nvert); + PApplet.arrayCopy(in.shininess, i0, + polyShininess, firstPolyVertex, nvert); } } @@ -9410,12 +9773,12 @@ public class PGraphicsOpenGL extends PGraphics { float ny = polyNormals[index ]; index = 4 * i; - polyVertices[index++] = x * tr.m00 + y * tr.m01 + tr.m02; - polyVertices[index ] = x * tr.m10 + y * tr.m11 + tr.m12; + polyVertices[index++] = x*tr.m00 + y*tr.m01 + tr.m02; + polyVertices[index ] = x*tr.m10 + y*tr.m11 + tr.m12; index = 3 * i; - polyNormals[index++] = nx * tr.m00 + ny * tr.m01; - polyNormals[index ] = nx * tr.m10 + ny * tr.m11; + polyNormals[index++] = nx*tr.m00 + ny*tr.m01; + polyNormals[index ] = nx*tr.m10 + ny*tr.m11; } } } @@ -9434,12 +9797,12 @@ public class PGraphicsOpenGL extends PGraphics { float ya = lineAttribs[index ]; index = 4 * i; - lineVertices[index++] = x * tr.m00 + y * tr.m01 + tr.m02; - lineVertices[index ] = x * tr.m10 + y * tr.m11 + tr.m12; + lineVertices[index++] = x*tr.m00 + y*tr.m01 + tr.m02; + lineVertices[index ] = x*tr.m10 + y*tr.m11 + tr.m12; index = 4 * i; - lineAttribs[index++] = xa * tr.m00 + ya * tr.m01 + tr.m02; - lineAttribs[index ] = xa * tr.m10 + ya * tr.m11 + tr.m12; + lineAttribs[index++] = xa*tr.m00 + ya*tr.m01 + tr.m02; + lineAttribs[index ] = xa*tr.m10 + ya*tr.m11 + tr.m12; } } } @@ -9454,8 +9817,8 @@ public class PGraphicsOpenGL extends PGraphics { float y = pointVertices[index ]; index = 4 * i; - pointVertices[index++] = x * tr.m00 + y * tr.m01 + tr.m02; - pointVertices[index ] = x * tr.m10 + y * tr.m11 + tr.m12; + pointVertices[index++] = x*tr.m00 + y*tr.m01 + tr.m02; + pointVertices[index ] = x*tr.m10 + y*tr.m11 + tr.m12; } } } @@ -9477,15 +9840,15 @@ public class PGraphicsOpenGL extends PGraphics { float nz = polyNormals[index ]; index = 4 * i; - polyVertices[index++] = x * tr.m00 + y * tr.m01 + z * tr.m02 + w * tr.m03; - polyVertices[index++] = x * tr.m10 + y * tr.m11 + z * tr.m12 + w * tr.m13; - polyVertices[index++] = x * tr.m20 + y * tr.m21 + z * tr.m22 + w * tr.m23; - polyVertices[index ] = x * tr.m30 + y * tr.m31 + z * tr.m32 + w * tr.m33; + polyVertices[index++] = x*tr.m00 + y*tr.m01 + z*tr.m02 + w*tr.m03; + polyVertices[index++] = x*tr.m10 + y*tr.m11 + z*tr.m12 + w*tr.m13; + polyVertices[index++] = x*tr.m20 + y*tr.m21 + z*tr.m22 + w*tr.m23; + polyVertices[index ] = x*tr.m30 + y*tr.m31 + z*tr.m32 + w*tr.m33; index = 3 * i; - polyNormals[index++] = nx * tr.m00 + ny * tr.m01 + nz * tr.m02; - polyNormals[index++] = nx * tr.m10 + ny * tr.m11 + nz * tr.m12; - polyNormals[index ] = nx * tr.m20 + ny * tr.m21 + nz * tr.m22; + polyNormals[index++] = nx*tr.m00 + ny*tr.m01 + nz*tr.m02; + polyNormals[index++] = nx*tr.m10 + ny*tr.m11 + nz*tr.m12; + polyNormals[index ] = nx*tr.m20 + ny*tr.m21 + nz*tr.m22; } } } @@ -9507,15 +9870,15 @@ public class PGraphicsOpenGL extends PGraphics { float za = lineAttribs[index ]; index = 4 * i; - lineVertices[index++] = x * tr.m00 + y * tr.m01 + z * tr.m02 + w * tr.m03; - lineVertices[index++] = x * tr.m10 + y * tr.m11 + z * tr.m12 + w * tr.m13; - lineVertices[index++] = x * tr.m20 + y * tr.m21 + z * tr.m22 + w * tr.m23; - lineVertices[index ] = x * tr.m30 + y * tr.m31 + z * tr.m32 + w * tr.m33; + lineVertices[index++] = x*tr.m00 + y*tr.m01 + z*tr.m02 + w*tr.m03; + lineVertices[index++] = x*tr.m10 + y*tr.m11 + z*tr.m12 + w*tr.m13; + lineVertices[index++] = x*tr.m20 + y*tr.m21 + z*tr.m22 + w*tr.m23; + lineVertices[index ] = x*tr.m30 + y*tr.m31 + z*tr.m32 + w*tr.m33; index = 4 * i; - lineAttribs[index++] = xa * tr.m00 + ya * tr.m01 + za * tr.m02 + tr.m03; - lineAttribs[index++] = xa * tr.m10 + ya * tr.m11 + za * tr.m12 + tr.m13; - lineAttribs[index ] = xa * tr.m20 + ya * tr.m21 + za * tr.m22 + tr.m23; + lineAttribs[index++] = xa*tr.m00 + ya*tr.m01 + za*tr.m02 + tr.m03; + lineAttribs[index++] = xa*tr.m10 + ya*tr.m11 + za*tr.m12 + tr.m13; + lineAttribs[index ] = xa*tr.m20 + ya*tr.m21 + za*tr.m22 + tr.m23; } } } @@ -9532,10 +9895,10 @@ public class PGraphicsOpenGL extends PGraphics { float w = pointVertices[index ]; index = 4 * i; - pointVertices[index++] = x * tr.m00 + y * tr.m01 + z * tr.m02 + w * tr.m03; - pointVertices[index++] = x * tr.m10 + y * tr.m11 + z * tr.m12 + w * tr.m13; - pointVertices[index++] = x * tr.m20 + y * tr.m21 + z * tr.m22 + w * tr.m23; - pointVertices[index ] = x * tr.m30 + y * tr.m31 + z * tr.m32 + w * tr.m33; + pointVertices[index++] = x*tr.m00 + y*tr.m01 + z*tr.m02 + w*tr.m03; + pointVertices[index++] = x*tr.m10 + y*tr.m11 + z*tr.m12 + w*tr.m13; + pointVertices[index++] = x*tr.m20 + y*tr.m21 + z*tr.m22 + w*tr.m23; + pointVertices[index ] = x*tr.m30 + y*tr.m31 + z*tr.m32 + w*tr.m33; } } } @@ -9630,7 +9993,8 @@ public class PGraphicsOpenGL extends PGraphics { this.accurate2DStrokes = accurate; } - void setTexCache(TexCache texCache, PImage prevTexImage, PImage newTexImage) { + void setTexCache(TexCache texCache, PImage prevTexImage, + PImage newTexImage) { this.texCache = texCache; this.prevTexImage = prevTexImage; this.newTexImage = newTexImage; @@ -9668,8 +10032,10 @@ public class PGraphicsOpenGL extends PGraphics { // Each point generates a separate triangle fan. // The number of triangles of each fan depends on the // stroke weight of the point. - int nPtVert = PApplet.max(MIN_POINT_ACCURACY, - (int) (TWO_PI * strokeWeight / POINT_ACCURACY_FACTOR)) + 1; + int nPtVert = + PApplet.max(MIN_POINT_ACCURACY, + (int) (TWO_PI * strokeWeight / + POINT_ACCURACY_FACTOR)) + 1; if (PGL.MAX_VERTEX_INDEX1 <= nPtVert) { throw new RuntimeException("Error in point tessellation."); } @@ -9722,8 +10088,10 @@ public class PGraphicsOpenGL extends PGraphics { float val = 0; float inc = (float) SINCOS_LENGTH / perim; for (int k = 0; k < perim; k++) { - tess.pointAttribs[2 * attribIdx + 0] = 0.5f * cosLUT[(int) val] * strokeWeight; - tess.pointAttribs[2 * attribIdx + 1] = 0.5f * sinLUT[(int) val] * strokeWeight; + tess.pointAttribs[2 * attribIdx + 0] = + 0.5f * cosLUT[(int) val] * strokeWeight; + tess.pointAttribs[2 * attribIdx + 1] = + 0.5f * sinLUT[(int) val] * strokeWeight; val = (val + inc) % SINCOS_LENGTH; attribIdx++; } @@ -9771,8 +10139,10 @@ public class PGraphicsOpenGL extends PGraphics { tess.setPolyVertex(vertIdx, x0, y0, 0, rgba); vertIdx++; for (int k = 0; k < perim; k++) { - tess.setPolyVertex(vertIdx, x0 + 0.5f * cosLUT[(int) val] * strokeWeight, - y0 + 0.5f * sinLUT[(int) val] * strokeWeight, 0, rgba); + tess.setPolyVertex(vertIdx, + x0 + 0.5f * cosLUT[(int) val] * strokeWeight, + y0 + 0.5f * sinLUT[(int) val] * strokeWeight, + 0, rgba); vertIdx++; val = (val + inc) % SINCOS_LENGTH; } @@ -9847,8 +10217,10 @@ public class PGraphicsOpenGL extends PGraphics { tess.pointAttribs[2 * attribIdx + 1] = 0; attribIdx++; for (int k = 0; k < 4; k++) { - tess.pointAttribs[2 * attribIdx + 0] = 0.5f * QUAD_POINT_SIGNS[k][0] * strokeWeight; - tess.pointAttribs[2 * attribIdx + 1] = 0.5f * QUAD_POINT_SIGNS[k][1] * strokeWeight; + tess.pointAttribs[2 * attribIdx + 0] = + 0.5f * QUAD_POINT_SIGNS[k][0] * strokeWeight; + tess.pointAttribs[2 * attribIdx + 1] = + 0.5f * QUAD_POINT_SIGNS[k][1] * strokeWeight; attribIdx++; } @@ -9893,8 +10265,10 @@ public class PGraphicsOpenGL extends PGraphics { tess.setPolyVertex(vertIdx, x0, y0, 0, rgba); vertIdx++; for (int k = 0; k < nvert - 1; k++) { - tess.setPolyVertex(vertIdx, x0 + 0.5f * QUAD_POINT_SIGNS[k][0] * strokeWeight, - y0 + 0.5f * QUAD_POINT_SIGNS[k][1] * strokeWeight, 0, rgba); + tess.setPolyVertex(vertIdx, + x0 + 0.5f * QUAD_POINT_SIGNS[k][0] * strokeWeight, + y0 + 0.5f * QUAD_POINT_SIGNS[k][1] * strokeWeight, + 0, rgba); vertIdx++; } @@ -9942,7 +10316,8 @@ public class PGraphicsOpenGL extends PGraphics { int first = in.firstVertex; tess.lineVertexCheck(nvert); tess.lineIndexCheck(nind); - int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast(); + int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : + tess.lineIndexCache.getLast(); firstLineIndexCache = index; for (int ln = 0; ln < lineCount; ln++) { int i0 = first + 2 * ln + 0; @@ -9960,7 +10335,8 @@ public class PGraphicsOpenGL extends PGraphics { if (noCapsJoins(nvert)) { tess.polyVertexCheck(nvert); tess.polyIndexCheck(nind); - int index = in.renderMode == RETAINED ? tess.polyIndexCache.addNew() : tess.polyIndexCache.getLast(); + int index = in.renderMode == RETAINED ? tess.polyIndexCache.addNew() : + tess.polyIndexCache.getLast(); firstLineIndexCache = index; if (firstPolyIndexCache == -1) firstPolyIndexCache = index; // If the geometry has no fill, needs the first poly index. for (int ln = 0; ln < lineCount; ln++) { @@ -9997,18 +10373,24 @@ public class PGraphicsOpenGL extends PGraphics { } void tessellateLineStrip3D(int lineCount) { - int nvert = lineCount * 4 + (lineCount - 1); // (lineCount - 1) for the bevel triangles - int nind = lineCount * 2 * 3 + (lineCount - 1) * 2 * 3; // same thing + int nBevelTr = noCapsJoins() ? 0 : (lineCount - 1); + int nvert = lineCount * 4 + nBevelTr; + int nind = lineCount * 2 * 3 + nBevelTr * 2 * 3; tess.lineVertexCheck(nvert); tess.lineIndexCheck(nind); - int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast(); + int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : + tess.lineIndexCache.getLast(); firstLineIndexCache = index; int i0 = in.firstVertex; short[] lastInd = {-1, -1}; for (int ln = 0; ln < lineCount; ln++) { int i1 = in.firstVertex + ln + 1; - index = addLine3D(i0, i1, index, lastInd, false); + if (0 < nBevelTr) { + index = addLine3D(i0, i1, index, lastInd, false); + } else { + index = addLine3D(i0, i1, index, null, false); + } i0 = i1; } lastLineIndexCache = index; @@ -10021,7 +10403,8 @@ public class PGraphicsOpenGL extends PGraphics { if (noCapsJoins(nvert)) { tess.polyVertexCheck(nvert); tess.polyIndexCheck(nind); - int index = in.renderMode == RETAINED ? tess.polyIndexCache.addNew() : tess.polyIndexCache.getLast(); + int index = in.renderMode == RETAINED ? tess.polyIndexCache.addNew() : + tess.polyIndexCache.getLast(); firstLineIndexCache = index; if (firstPolyIndexCache == -1) firstPolyIndexCache = index; // If the geometry has no fill, needs the first poly index. int i0 = in.firstVertex; @@ -10058,21 +10441,27 @@ public class PGraphicsOpenGL extends PGraphics { } } - void tessellateLineLoop3D(int lineCount) { + void tessellateLineLoop3D(int lineCount) { // TODO: This calculation doesn't add the bevel join between // the first and last vertex, need to fix. - int nvert = lineCount * 4 + (lineCount - 1); - int nind = lineCount * 2 * 3 + (lineCount - 1) * 2 * 3; + int nBevelTr = noCapsJoins() ? 0 : (lineCount - 1); + int nvert = lineCount * 4 + nBevelTr; + int nind = lineCount * 2 * 3 + nBevelTr * 2 * 3; tess.lineVertexCheck(nvert); tess.lineIndexCheck(nind); - int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast(); + int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : + tess.lineIndexCache.getLast(); firstLineIndexCache = index; int i0 = in.firstVertex; short[] lastInd = {-1, -1}; for (int ln = 0; ln < lineCount - 1; ln++) { int i1 = in.firstVertex + ln + 1; - index = addLine3D(i0, i1, index, lastInd, false); + if (0 < nBevelTr) { + index = addLine3D(i0, i1, index, lastInd, false); + } else { + index = addLine3D(i0, i1, index, null, false); + } i0 = i1; } index = addLine3D(in.lastVertex, in.firstVertex, index, lastInd, false); @@ -10086,7 +10475,8 @@ public class PGraphicsOpenGL extends PGraphics { if (noCapsJoins(nvert)) { tess.polyVertexCheck(nvert); tess.polyIndexCheck(nind); - int index = in.renderMode == RETAINED ? tess.polyIndexCache.addNew() : tess.polyIndexCache.getLast(); + int index = in.renderMode == RETAINED ? tess.polyIndexCache.addNew() : + tess.polyIndexCache.getLast(); firstLineIndexCache = index; if (firstPolyIndexCache == -1) firstPolyIndexCache = index; // If the geometry has no fill, needs the first poly index. int i0 = in.firstVertex; @@ -10125,22 +10515,28 @@ public class PGraphicsOpenGL extends PGraphics { void tessellateEdges3D() { // This calculation doesn't add the bevel join between // the first and last vertex, need to fix. - int nInVert = in.getNumEdgeVertices(true); - int nInInd = in.getNumEdgeIndices(true); + boolean bevel = !noCapsJoins(); + int nInVert = in.getNumEdgeVertices(bevel); + int nInInd = in.getNumEdgeIndices(bevel); tess.lineVertexCheck(nInVert); tess.lineIndexCheck(nInInd); - int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast(); + int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : + tess.lineIndexCache.getLast(); firstLineIndexCache = index; short[] lastInd = {-1, -1}; for (int i = in.firstEdge; i <= in.lastEdge; i++) { int[] edge = in.edges[i]; int i0 = edge[0]; int i1 = edge[1]; - index = addLine3D(i0, i1, index, lastInd, true); - if (edge[2] == EDGE_STOP || edge[2] == EDGE_SINGLE) { - // No join with next line segment. - lastInd[0] = lastInd[1] = -1; + if (bevel) { + index = addLine3D(i0, i1, index, lastInd, true); + if (edge[2] == EDGE_STOP || edge[2] == EDGE_SINGLE) { + // No join with next line segment. + lastInd[0] = lastInd[1] = -1; + } + } else { + index = addLine3D(i0, i1, index, null, true); } } lastLineIndexCache = index; @@ -10153,7 +10549,8 @@ public class PGraphicsOpenGL extends PGraphics { tess.polyVertexCheck(nInVert); tess.polyIndexCheck(nInInd); - int index = in.renderMode == RETAINED ? tess.polyIndexCache.addNew() : tess.polyIndexCache.getLast(); + int index = in.renderMode == RETAINED ? tess.polyIndexCache.addNew() : + tess.polyIndexCache.getLast(); firstLineIndexCache = index; if (firstPolyIndexCache == -1) firstPolyIndexCache = index; // If the geometry has no fill, needs the first poly index. for (int i = in.firstEdge; i <= in.lastEdge; i++) { @@ -10194,7 +10591,8 @@ public class PGraphicsOpenGL extends PGraphics { // Adding the data that defines a quad starting at vertex i0 and // ending at i1. - int addLine3D(int i0, int i1, int index, short[] lastInd, boolean constStroke) { + int addLine3D(int i0, int i1, int index, short[] lastInd, + boolean constStroke) { IndexCache cache = tess.lineIndexCache; int count = cache.vertexCount[index]; boolean addBevel = lastInd != null && -1 < lastInd[0] && -1 < lastInd[1]; @@ -10240,10 +10638,11 @@ public class PGraphicsOpenGL extends PGraphics { tess.setLineVertex(vidx, in, i0, color0); if (newCache) { - PGraphics.showWarning("Stroke path is too long, some bevel triangles won't be added."); + PGraphics.showWarning("Stroke path is too long, some bevel " + + "triangles won't be added."); - // TODO: Fix this situation, the vertices from the previous cache block - // should be copied in the newly created one. + // TODO: Fix this situation, the vertices from the previous cache + // block should be copied in the newly created one. tess.lineIndices[iidx++] = (short) (count + 4); tess.lineIndices[iidx++] = (short) (count + 0); tess.lineIndices[iidx++] = (short) (count + 0); @@ -10304,10 +10703,12 @@ public class PGraphicsOpenGL extends PGraphics { normy = +dirx / llen; } - tess.setPolyVertex(vidx++, x0 + normx * weight/2, y0 + normy * weight/2, 0, color); + tess.setPolyVertex(vidx++, x0 + normx * weight/2, y0 + normy * weight/2, + 0, color); tess.polyIndices[iidx++] = (short) (count + 0); - tess.setPolyVertex(vidx++, x0 - normx * weight/2, y0 - normy * weight/2, 0, color); + tess.setPolyVertex(vidx++, x0 - normx * weight/2, y0 - normy * weight/2, + 0, color); tess.polyIndices[iidx++] = (short) (count + 1); if (!constStroke) { @@ -10315,14 +10716,16 @@ public class PGraphicsOpenGL extends PGraphics { weight = in.strokeWeights[i1]; } - tess.setPolyVertex(vidx++, x1 - normx * weight/2, y1 - normy * weight/2, 0, color); + tess.setPolyVertex(vidx++, x1 - normx * weight/2, y1 - normy * weight/2, + 0, color); tess.polyIndices[iidx++] = (short) (count + 2); // Starting a new triangle re-using prev vertices. tess.polyIndices[iidx++] = (short) (count + 2); tess.polyIndices[iidx++] = (short) (count + 0); - tess.setPolyVertex(vidx++, x1 + normx * weight/2, y1 + normy * weight/2, 0, color); + tess.setPolyVertex(vidx++, x1 + normx * weight/2, y1 + normy * weight/2, + 0, color); tess.polyIndices[iidx++] = (short) (count + 3); cache.incCounts(index, 6, 4); @@ -10337,31 +10740,36 @@ public class PGraphicsOpenGL extends PGraphics { // to run out of memory, so full caps and joins are disabled. return true; } else { - // We first calculate the (volumetric) scaling factor that is associated - // to the current transformation matrix, which is given by the absolute - // value of its determinant: - float scaleFactor = 1; - - if (transform != null) { - if (transform instanceof PMatrix2D) { - PMatrix2D tr = (PMatrix2D)transform; - float areaScaleFactor = Math.abs(tr.m00 * tr.m11 - tr.m01 * tr.m10); - scaleFactor = (float) Math.sqrt(areaScaleFactor); - } else if (transform instanceof PMatrix3D) { - PMatrix3D tr = (PMatrix3D)transform; - float volumeScaleFactor = Math.abs(tr.m00 * (tr.m11 * tr.m22 - tr.m12 * tr.m21) + - tr.m01 * (tr.m12 * tr.m20 - tr.m10 * tr.m22) + - tr.m02 * (tr.m10 * tr.m21 - tr.m11 * tr.m20)); - scaleFactor = (float) Math.pow(volumeScaleFactor, 1.0f / 3.0f); - } - } - - // The stroke weight is scaled so it correspons to the current - // "zoom level" being applied on the geometry due to scaling: - return scaleFactor * strokeWeight < PGL.MIN_CAPS_JOINS_WEIGHT; + return noCapsJoins(); } } + + boolean noCapsJoins() { + // We first calculate the (volumetric) scaling factor that is associated + // to the current transformation matrix, which is given by the absolute + // value of its determinant: + float scaleFactor = 1; + if (transform != null) { + if (transform instanceof PMatrix2D) { + PMatrix2D tr = (PMatrix2D)transform; + float areaScaleFactor = Math.abs(tr.m00 * tr.m11 - tr.m01 * tr.m10); + scaleFactor = (float) Math.sqrt(areaScaleFactor); + } else if (transform instanceof PMatrix3D) { + PMatrix3D tr = (PMatrix3D)transform; + float volumeScaleFactor = + Math.abs(tr.m00 * (tr.m11 * tr.m22 - tr.m12 * tr.m21) + + tr.m01 * (tr.m12 * tr.m20 - tr.m10 * tr.m22) + + tr.m02 * (tr.m10 * tr.m21 - tr.m11 * tr.m20)); + scaleFactor = (float) Math.pow(volumeScaleFactor, 1.0f / 3.0f); + } + } + + // The stroke weight is scaled so it correspons to the current + // "zoom level" being applied on the geometry due to scaling: + return scaleFactor * strokeWeight < PGL.MIN_CAPS_JOINS_WEIGHT; + } + // ----------------------------------------------------------------- // // Polygon primitives tessellation @@ -10567,7 +10975,8 @@ public class PGraphicsOpenGL extends PGraphics { inMaxVertRel = PApplet.max(inMaxVertRel, PApplet.max(ri0, ri1, ri2)); - if ((PGL.MAX_VERTEX_INDEX1 - 3 <= inMaxVertRel + dupCount && inMaxVertRel + dupCount < PGL.MAX_VERTEX_INDEX1) || + if ((PGL.MAX_VERTEX_INDEX1 - 3 <= inMaxVertRel + dupCount && + inMaxVertRel + dupCount < PGL.MAX_VERTEX_INDEX1) || (tr == trCount - 1)) { // The vertex indices of the current group are about to // surpass the MAX_VERTEX_INDEX limit, or we are at the last triangle @@ -10575,12 +10984,13 @@ public class PGraphicsOpenGL extends PGraphics { int nondupCount = 0; if (0 < dupCount) { - // Adjusting the negative indices so they correspond to vertices added - // at the end of the block. + // Adjusting the negative indices so they correspond to vertices + // added at the end of the block. for (int i = inInd0; i <= inInd1; i++) { int ri = tess.polyIndices[offset + i]; if (ri < 0) { - tess.polyIndices[offset + i] = (short) (inMaxVertRel + 1 + dupIndexPos(ri)); + tess.polyIndices[offset + i] = + (short) (inMaxVertRel + 1 + dupIndexPos(ri)); } } @@ -10642,7 +11052,9 @@ public class PGraphicsOpenGL extends PGraphics { if (dupIndices[i] == idx) break; if (dupIndices[i] < idx && idx < dupIndices[i + 1]) { // Insert between i and i + 1: - for (int j = dupCount; j > i + 1; j--) dupIndices[j] = dupIndices[j - 1]; + for (int j = dupCount; j > i + 1; j--) { + dupIndices[j] = dupIndices[j - 1]; + } dupIndices[i + 1] = idx; dupCount++; break; @@ -10706,7 +11118,8 @@ public class PGraphicsOpenGL extends PGraphics { void setLastTexIndex(int lastIndex, int lastCache) { if (texCache != null) { if (prevTexImage != newTexImage || texCache.size == 0) { - texCache.addTexture(newTexImage, firstTexIndex, firstTexCache, lastIndex, lastCache); + texCache.addTexture(newTexImage, firstTexIndex, firstTexCache, + lastIndex, lastCache); } else { texCache.setLastIndex(lastIndex, lastCache); } @@ -10768,12 +11181,14 @@ public class PGraphicsOpenGL extends PGraphics { int eg = (in.emissive[i] >> 8) & 0xFF; int eb = (in.emissive[i] >> 0) & 0xFF; - // 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], - fa, fr, fg, fb, - 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], - aa, ar, ag, ab, sa, sr, sg, sb, ea, er, eg, eb, in.shininess[i]}; + // 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], + fa, fr, fg, fb, + 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], + aa, ar, ag, ab, sa, sr, sg, sb, ea, er, eg, eb, in.shininess[i]}; gluTess.addVertex(vertex); } @@ -10800,7 +11215,8 @@ public class PGraphicsOpenGL extends PGraphics { LinePath.JOIN_MITER; // Make the outline of the stroke from the path - LinePath strokedPath = LinePath.createStrokedPath(path, strokeWeight, cap, join); + LinePath strokedPath = LinePath.createStrokedPath(path, strokeWeight, + cap, join); gluTess.beginPolygon(); @@ -10835,7 +11251,8 @@ public class PGraphicsOpenGL extends PGraphics { sg = (strokeColor >> 8) & 0xFF; sb = (strokeColor >> 0) & 0xFF; - // Vertex data includes coordinates, colors, normals, texture coordinates, and material properties. + // Vertex data includes coordinates, colors, normals, texture + // coordinates, and material properties. vertex = new double[] { coords[0], coords[1], 0, sa, sr, sg, sb, 0, 0, 1, @@ -10856,13 +11273,15 @@ public class PGraphicsOpenGL extends PGraphics { ///////////////////////////////////////// - // Interenting notes about using the GLU tessellator to render thick polylines: + // Interenting notes about using the GLU tessellator to render thick + // polylines: // http://stackoverflow.com/questions/687173/how-do-i-render-thick-2d-lines-as-polygons // - // "...Since I disliked the tesselator API I lifted the tesselation code from the free - // SGI OpenGL reference implementation, rewrote the entire front-end and added memory - // pools to get the number of allocations down. It took two days to do this, but it was - // well worth it (like factor five performance improvement)..." + // "...Since I disliked the tesselator API I lifted the tesselation code + // from the free SGI OpenGL reference implementation, rewrote the entire + // front-end and added memory pools to get the number of allocations down. + // It took two days to do this, but it was well worth it (like factor five + // performance improvement)..." // // This C implementation of GLU could be useful: // http://code.google.com/p/glues/ @@ -10975,11 +11394,13 @@ public class PGraphicsOpenGL extends PGraphics { protected void addIndex(int tessIdx) { tess.polyIndexCheck(); - tess.polyIndices[tess.polyIndexCount - 1] = (short) (vertFirst + tessIdx); + tess.polyIndices[tess.polyIndexCount - 1] = + (short) (vertFirst + tessIdx); } protected void calcTriNormal(int tessIdx0, int tessIdx1, int tessIdx2) { - tess.calcPolyNormal(vertFirst + tessIdx0, vertFirst + tessIdx1, vertFirst + tessIdx2); + tess.calcPolyNormal(vertFirst + tessIdx0, vertFirst + tessIdx1, + vertFirst + tessIdx2); } public void vertex(Object data) { @@ -10987,15 +11408,20 @@ public class PGraphicsOpenGL extends PGraphics { double[] d = (double[]) data; int l = d.length; if (l < 25) { - throw new RuntimeException("TessCallback vertex() data is not of length 25"); + throw new RuntimeException("TessCallback vertex() data is not " + + "of length 25"); } if (vertCount < PGL.MAX_VERTEX_INDEX1) { // Combining individual rgba components back into int color values - int fcolor = ((int) d[ 3] << 24) | ((int) d[ 4] << 16) | ((int) d[ 5] << 8) | (int) d[ 6]; - int acolor = ((int) d[12] << 24) | ((int) d[13] << 16) | ((int) d[14] << 8) | (int) d[15]; - int scolor = ((int) d[16] << 24) | ((int) d[17] << 16) | ((int) d[18] << 8) | (int) d[19]; - int ecolor = ((int) d[20] << 24) | ((int) d[21] << 16) | ((int) d[22] << 8) | (int) d[23]; + int fcolor = + ((int)d[ 3]<<24) | ((int)d[ 4]<<16) | ((int)d[ 5]<<8) | (int)d[ 6]; + int acolor = + ((int)d[12]<<24) | ((int)d[13]<<16) | ((int)d[14]<<8) | (int)d[15]; + int scolor = + ((int)d[16]<<24) | ((int)d[17]<<16) | ((int)d[18]<<8) | (int)d[19]; + int ecolor = + ((int)d[20]<<24) | ((int)d[21]<<16) | ((int)d[22]<<8) | (int)d[23]; tess.addPolyVertex((float) d[ 0], (float) d[ 1], (float) d[ 2], fcolor, @@ -11006,11 +11432,14 @@ public class PGraphicsOpenGL extends PGraphics { vertCount++; } else { - throw new RuntimeException("The tessellator is generating too many vertices, reduce complexity of shape."); + throw new RuntimeException("The tessellator is generating too " + + "many vertices, reduce complexity of " + + "shape."); } } else { - throw new RuntimeException("TessCallback vertex() data not understood"); + throw new RuntimeException("TessCallback vertex() data not " + + "understood"); } } diff --git a/android/core/src/processing/opengl/PShader.java b/android/core/src/processing/opengl/PShader.java index 5e7179eae..f440cb623 100644 --- a/android/core/src/processing/opengl/PShader.java +++ b/android/core/src/processing/opengl/PShader.java @@ -31,17 +31,18 @@ import java.util.HashMap; /** * 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/) + * and a fragment shader. Based on the GLSLShader class from GLGraphics, which + * in turn was originally based in the code by JohnG: + * http://processing.org/discourse/beta/num_1159494801.html */ public class PShader { // shaders constants - static public final int FLAT = 0; - static public final int LIT = 1; - static public final int TEXTURED = 2; - static public final int FULL = 3; - static public final int LINE = 4; - static public final int POINT = 5; + static protected final int COLOR = 0; + static protected final int LIGHT = 1; + static protected final int TEXTURE = 2; + static protected final int TEXLIGHT = 3; + static protected final int LINE = 4; + static protected final int POINT = 5; protected PApplet parent; // The main renderer associated to the parent PApplet. @@ -255,7 +256,8 @@ public class PShader { public void set(String name, PVector vec) { - setUniformImpl(name, UniformValue.FLOAT3, new float[] { vec.x, vec.y, vec.z }); + setUniformImpl(name, UniformValue.FLOAT3, + new float[] { vec.x, vec.y, vec.z }); } @@ -274,7 +276,8 @@ public class PShader { } else if (ncoords == 4) { setUniformImpl(name, UniformValue.INT4VEC, vec); } else if (4 < ncoords) { - PGraphics.showWarning("Only up to 4 coordinates per element are supported."); + PGraphics.showWarning("Only up to 4 coordinates per element are " + + "supported."); } else { PGraphics.showWarning("Wrong number of coordinates: it is negative!"); } @@ -296,7 +299,8 @@ public class PShader { } else if (ncoords == 4) { setUniformImpl(name, UniformValue.FLOAT4VEC, vec); } else if (4 < ncoords) { - PGraphics.showWarning("Only up to 4 coordinates per element are supported."); + PGraphics.showWarning("Only up to 4 coordinates per element are " + + "supported."); } else { PGraphics.showWarning("Wrong number of coordinates: it is negative!"); } @@ -361,7 +365,8 @@ public class PShader { } - protected void setAttributeVBO(int loc, int vboId, int size, int type, boolean normalized, int stride, int offset) { + protected void setAttributeVBO(int loc, int vboId, int size, int type, + boolean normalized, int stride, int offset) { if (-1 < loc) { pgl.bindBuffer(PGL.ARRAY_BUFFER, vboId); pgl.vertexAttribPointer(loc, size, type, normalized, stride, offset); @@ -509,7 +514,8 @@ public class PShader { } uniformValues.put(loc, new UniformValue(type, value)); } else { - PGraphics.showWarning("The shader doesn't have a uniform called \"" + name + "\""); + PGraphics.showWarning("The shader doesn't have a uniform called \"" + + name + "\""); } } @@ -626,7 +632,8 @@ public class PShader { } else if (vertexURL != null) { hasVert = loadVertexShader(vertexURL); } else { - PGraphics.showException("Vertex shader filenames and URLs are both null!"); + PGraphics.showException("Vertex shader filenames and URLs are " + + "both null!"); } boolean hasFrag = false; @@ -635,7 +642,8 @@ public class PShader { } else if (fragmentURL != null) { hasFrag = loadFragmentShader(fragmentURL); } else { - PGraphics.showException("Fragment shader filenames and URLs are both null!"); + PGraphics.showException("Fragment shader filenames and URLs are " + + "both null!"); } boolean vertRes = true; @@ -660,7 +668,8 @@ public class PShader { int[] linked = new int[1]; pgl.getProgramiv(glProgram, PGL.LINK_STATUS, linked, 0); if (linked[0] == PGL.FALSE) { - PGraphics.showException("Cannot link shader program:\n" + pgl.getProgramInfoLog(glProgram)); + PGraphics.showException("Cannot link shader program:\n" + + pgl.getProgramInfoLog(glProgram)); } pgl.validateProgram(glProgram); @@ -668,7 +677,8 @@ public class PShader { int[] validated = new int[1]; pgl.getProgramiv(glProgram, PGL.VALIDATE_STATUS, validated, 0); if (validated[0] == PGL.FALSE) { - PGraphics.showException("Cannot validate shader program:\n" + pgl.getProgramInfoLog(glProgram)); + PGraphics.showException("Cannot validate shader program:\n" + + pgl.getProgramInfoLog(glProgram)); } } } @@ -708,7 +718,8 @@ public class PShader { */ protected boolean loadVertexShader(URL url) { try { - vertexShaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n"); + vertexShaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), + "\n"); return vertexShaderSource != null; } catch (IOException e) { PGraphics.showException("Cannot load vertex shader " + url.getFile()); @@ -735,7 +746,8 @@ public class PShader { */ protected boolean loadFragmentShader(URL url) { try { - fragmentShaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n"); + fragmentShaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), + "\n"); return fragmentShaderSource != null; } catch (IOException e) { PGraphics.showException("Cannot load fragment shader " + url.getFile()); @@ -756,7 +768,8 @@ public class PShader { int[] compiled = new int[1]; pgl.getShaderiv(glVertex, PGL.COMPILE_STATUS, compiled, 0); if (compiled[0] == PGL.FALSE) { - PGraphics.showException("Cannot compile vertex shader:\n" + pgl.getShaderInfoLog(glVertex)); + PGraphics.showException("Cannot compile vertex shader:\n" + + pgl.getShaderInfoLog(glVertex)); return false; } else { return true; @@ -776,7 +789,8 @@ public class PShader { int[] compiled = new int[1]; pgl.getShaderiv(glFragment, PGL.COMPILE_STATUS, compiled, 0); if (compiled[0] == PGL.FALSE) { - PGraphics.showException("Cannot compile fragment shader:\n" + pgl.getShaderInfoLog(glFragment)); + PGraphics.showException("Cannot compile fragment shader:\n" + + pgl.getShaderInfoLog(glFragment)); return false; } else { return true; diff --git a/android/core/src/processing/opengl/PShape2D.java b/android/core/src/processing/opengl/PShape2D.java index 2d32cb2ec..e5fe07d7f 100644 --- a/android/core/src/processing/opengl/PShape2D.java +++ b/android/core/src/processing/opengl/PShape2D.java @@ -52,7 +52,8 @@ public class PShape2D extends PShapeOpenGL { dest = PGraphics2D.createShapeImpl(parent, GROUP); PShape2D.copyGroup(parent, src, dest); } else if (src.getFamily() == PRIMITIVE) { - dest = PGraphics2D.createShapeImpl(parent, src.getKind(), src.getParams()); + dest = PGraphics2D.createShapeImpl(parent, src.getKind(), + src.getParams()); PShape.copyPrimitive(src, dest); } else if (src.getFamily() == GEOMETRY) { dest = PGraphics2D.createShapeImpl(parent, src.getKind()); diff --git a/android/core/src/processing/opengl/PShape3D.java b/android/core/src/processing/opengl/PShape3D.java index e46f23ed0..e6bd664d8 100644 --- a/android/core/src/processing/opengl/PShape3D.java +++ b/android/core/src/processing/opengl/PShape3D.java @@ -51,7 +51,8 @@ public class PShape3D extends PShapeOpenGL { dest = PGraphics3D.createShapeImpl(parent, GROUP); PShape3D.copyGroup(parent, src, dest); } else if (src.getFamily() == PRIMITIVE) { - dest = PGraphics3D.createShapeImpl(parent, src.getKind(), src.getParams()); + dest = PGraphics3D.createShapeImpl(parent, src.getKind(), + src.getParams()); PShape.copyPrimitive(src, dest); } else if (src.getFamily() == GEOMETRY) { dest = PGraphics3D.createShapeImpl(parent, src.getKind()); @@ -75,5 +76,4 @@ public class PShape3D extends PShapeOpenGL { dest.addChild(c); } } - } diff --git a/android/core/src/processing/opengl/PShapeOpenGL.java b/android/core/src/processing/opengl/PShapeOpenGL.java index 6b0668763..e6ff94420 100644 --- a/android/core/src/processing/opengl/PShapeOpenGL.java +++ b/android/core/src/processing/opengl/PShapeOpenGL.java @@ -46,11 +46,13 @@ import java.util.Arrays; import java.util.HashSet; /** - * This class holds a 3D model composed of vertices, normals, colors (per vertex) and - * texture coordinates (also per vertex). All this data is stored in Vertex Buffer Objects - * (VBO) in GPU memory for very fast access. - * OBJ loading implemented using code from Saito's OBJLoader library (http://code.google.com/p/saitoobjloader/) - * and OBJReader from Ahmet Kizilay (http://www.openprocessing.org/visuals/?visualID=191). + * This class holds a 3D model composed of vertices, normals, colors + * (per vertex) and texture coordinates (also per vertex). All this data is + * stored in Vertex Buffer Objects (VBO) in GPU memory for very fast access. + * OBJ loading implemented using code from Saito's OBJLoader library: + * http://code.google.com/p/saitoobjloader/ + * and OBJReader from Ahmet Kizilay + * http://www.openprocessing.org/visuals/?visualID=191 * By Andres Colubri * * @@ -318,13 +320,14 @@ public class PShapeOpenGL extends PShape { shapeMode = pg.shapeMode; imageMode = pg.imageMode; - colorMode(pg.colorMode, pg.colorModeX, pg.colorModeY, pg.colorModeZ, pg.colorModeA); + colorMode(pg.colorMode, + pg.colorModeX, pg.colorModeY, pg.colorModeZ, pg.colorModeA); - // Initial values for fill, stroke and tint colors are also imported from the renderer. - // This is particular relevant for primitive shapes, since is not possible to set - // their color separately when creating them, and their input vertices are actually - // generated at rendering time, by which the color configuration of the renderer might - // have changed. + // Initial values for fill, stroke and tint colors are also imported from + // the renderer. This is particular relevant for primitive shapes, since is + // not possible to set their color separately when creating them, and their + // input vertices are actually generated at rendering time, by which the + // color configuration of the renderer might have changed. fill = pg.fill; fillColor = pg.fillColor; @@ -497,8 +500,10 @@ public class PShapeOpenGL extends PShape { public float getWidth() { - PVector min = new PVector(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY); - PVector max = new PVector(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY); + PVector min = new PVector(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, + Float.POSITIVE_INFINITY); + PVector max = new PVector(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, + Float.NEGATIVE_INFINITY); if (shapeEnded) { getVertexMin(min); getVertexMax(max); @@ -509,8 +514,10 @@ public class PShapeOpenGL extends PShape { public float getHeight() { - PVector min = new PVector(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY); - PVector max = new PVector(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY); + PVector min = new PVector(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, + Float.POSITIVE_INFINITY); + PVector max = new PVector(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, + Float.NEGATIVE_INFINITY); if (shapeEnded) { getVertexMin(min); getVertexMax(max); @@ -521,8 +528,10 @@ public class PShapeOpenGL extends PShape { public float getDepth() { - PVector min = new PVector(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY); - PVector max = new PVector(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY); + PVector min = new PVector(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, + Float.POSITIVE_INFINITY); + PVector max = new PVector(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, + Float.NEGATIVE_INFINITY); if (shapeEnded) { getVertexMin(min); getVertexMax(max); @@ -536,7 +545,8 @@ public class PShapeOpenGL extends PShape { if (top == null) { top = new PVector(); } - top.set(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY); + top.set(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, + Float.POSITIVE_INFINITY); getVertexMin(top); return top; } @@ -546,7 +556,8 @@ public class PShapeOpenGL extends PShape { if (bottom == null) { bottom = new PVector(); } - bottom.set(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY); + bottom.set(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, + Float.NEGATIVE_INFINITY); getVertexMax(bottom); return bottom; } @@ -561,10 +572,16 @@ public class PShapeOpenGL extends PShape { child.getVertexMin(min); } } else { - if (hasPolys) tessGeo.getPolyVertexMin(min, firstPolyVertex, lastPolyVertex); + if (hasPolys) { + tessGeo.getPolyVertexMin(min, firstPolyVertex, lastPolyVertex); + } if (is3D()) { - if (hasLines) tessGeo.getLineVertexMin(min, firstLineVertex, lastLineVertex); - if (hasPoints) tessGeo.getPointVertexMin(min, firstPointVertex, lastPointVertex); + if (hasLines) { + tessGeo.getLineVertexMin(min, firstLineVertex, lastLineVertex); + } + if (hasPoints) { + tessGeo.getPointVertexMin(min, firstPointVertex, lastPointVertex); + } } } } @@ -579,10 +596,16 @@ public class PShapeOpenGL extends PShape { child.getVertexMax(max); } } else { - if (hasPolys) tessGeo.getPolyVertexMax(max, firstPolyVertex, lastPolyVertex); + if (hasPolys) { + tessGeo.getPolyVertexMax(max, firstPolyVertex, lastPolyVertex); + } if (is3D()) { - if (hasLines) tessGeo.getLineVertexMax(max, firstLineVertex, lastLineVertex); - if (hasPoints) tessGeo.getPointVertexMax(max, firstPointVertex, lastPointVertex); + if (hasLines) { + tessGeo.getLineVertexMax(max, firstLineVertex, lastLineVertex); + } + if (hasPoints) { + tessGeo.getPointVertexMax(max, firstPointVertex, lastPointVertex); + } } } } @@ -597,10 +620,18 @@ public class PShapeOpenGL extends PShape { count += child.getVertexSum(sum, count); } } else { - if (hasPolys) count += tessGeo.getPolyVertexSum(sum, firstPolyVertex, lastPolyVertex); + if (hasPolys) { + count += tessGeo.getPolyVertexSum(sum, firstPolyVertex, lastPolyVertex); + } if (is3D()) { - if (hasLines) count += tessGeo.getLineVertexSum(sum, firstLineVertex, lastLineVertex); - if (hasPoints) count += tessGeo.getPointVertexSum(sum, firstPointVertex, lastPointVertex); + if (hasLines) { + count += tessGeo.getLineVertexSum(sum, firstLineVertex, + lastLineVertex); + } + if (hasPoints) { + count += tessGeo.getPointVertexSum(sum, firstPointVertex, + lastPointVertex); + } } } return count; @@ -905,8 +936,8 @@ public class PShapeOpenGL extends PShape { return; } - // Input arrays are trimmed since they are expanded by doubling their old size, - // which might lead to arrays larger than the vertex counts. + // Input arrays are trimmed since they are expanded by doubling their old + // size, which might lead to arrays larger than the vertex counts. inGeo.trim(); isClosed = mode == CLOSE; @@ -929,7 +960,8 @@ public class PShapeOpenGL extends PShape { public void setPath(int vcount, float[][] verts, int ccount, int[] codes) { if (family != PATH) { - PGraphics.showWarning("Vertex coordinates and codes can only be set to PATH shapes"); + PGraphics.showWarning("Vertex coordinates and codes can only be set to " + + "PATH shapes"); return; } @@ -961,11 +993,9 @@ public class PShapeOpenGL extends PShape { float oldWeight = strokeWeight; strokeWeight = newWeight; + Arrays.fill(inGeo.strokeWeights, 0, inGeo.vertexCount, strokeWeight); if (shapeEnded && tessellated && (hasLines || hasPoints)) { float resizeFactor = newWeight / oldWeight; - - Arrays.fill(inGeo.strokeWeights, 0, inGeo.vertexCount, strokeWeight); - if (hasLines) { if (is3D()) { for (int i = firstLineVertex; i <= lastLineVertex; i++) { @@ -979,7 +1009,6 @@ public class PShapeOpenGL extends PShape { markForTessellation(); } } - if (hasPoints) { if (is3D()) { for (int i = firstPointVertex; i <= lastPointVertex; i++) { @@ -1140,19 +1169,24 @@ public class PShapeOpenGL extends PShape { if (fillColor == newFillColor) return; fillColor = newFillColor; - if (shapeEnded && tessellated && hasPolys && texture == null) { - Arrays.fill(inGeo.colors, 0, inGeo.vertexCount, PGL.javaToNativeARGB(fillColor)); - if (is3D()) { - Arrays.fill(tessGeo.polyColors, firstPolyVertex, lastPolyVertex + 1, PGL.javaToNativeARGB(fillColor)); - root.setModifiedPolyColors(firstPolyVertex, lastPolyVertex); - } else if (is2D()) { - int last1 = lastPolyVertex + 1; - if (-1 < firstLineVertex) last1 = firstLineVertex; - if (-1 < firstPointVertex) last1 = firstPointVertex; - Arrays.fill(tessGeo.polyColors, firstPolyVertex, last1, PGL.javaToNativeARGB(fillColor)); - root.setModifiedPolyColors(firstPolyVertex, last1 - 1); - } - } + if (texture == null) { + Arrays.fill(inGeo.colors, 0, inGeo.vertexCount, + PGL.javaToNativeARGB(fillColor)); + if (shapeEnded && tessellated && hasPolys) { + if (is3D()) { + Arrays.fill(tessGeo.polyColors, firstPolyVertex, lastPolyVertex + 1, + PGL.javaToNativeARGB(fillColor)); + root.setModifiedPolyColors(firstPolyVertex, lastPolyVertex); + } else if (is2D()) { + int last1 = lastPolyVertex + 1; + if (-1 < firstLineVertex) last1 = firstLineVertex; + if (-1 < firstPointVertex) last1 = firstPointVertex; + Arrays.fill(tessGeo.polyColors, firstPolyVertex, last1, + PGL.javaToNativeARGB(fillColor)); + root.setModifiedPolyColors(firstPolyVertex, last1 - 1); + } + } + } } @@ -1280,25 +1314,28 @@ public class PShapeOpenGL extends PShape { if (strokeColor == newStrokeColor) return; strokeColor = newStrokeColor; + Arrays.fill(inGeo.strokeColors, 0, inGeo.vertexCount, + PGL.javaToNativeARGB(strokeColor)); if (shapeEnded && tessellated && (hasLines || hasPoints)) { - Arrays.fill(inGeo.strokeColors, 0, inGeo.vertexCount, PGL.javaToNativeARGB(strokeColor)); - if (hasLines) { if (is3D()) { - Arrays.fill(tessGeo.lineColors, firstLineVertex, lastLineVertex + 1, PGL.javaToNativeARGB(strokeColor)); + Arrays.fill(tessGeo.lineColors, firstLineVertex, lastLineVertex + 1, + PGL.javaToNativeARGB(strokeColor)); root.setModifiedLineColors(firstLineVertex, lastLineVertex); } else if (is2D()) { - Arrays.fill(tessGeo.polyColors, firstLineVertex, lastLineVertex + 1, PGL.javaToNativeARGB(strokeColor)); + Arrays.fill(tessGeo.polyColors, firstLineVertex, lastLineVertex + 1, + PGL.javaToNativeARGB(strokeColor)); root.setModifiedPolyColors(firstLineVertex, lastLineVertex); } } - if (hasPoints) { if (is3D()) { - Arrays.fill(tessGeo.pointColors, firstPointVertex, lastPointVertex + 1, PGL.javaToNativeARGB(strokeColor)); + Arrays.fill(tessGeo.pointColors, firstPointVertex, lastPointVertex + 1, + PGL.javaToNativeARGB(strokeColor)); root.setModifiedPointColors(firstPointVertex, lastPointVertex); } else if (is2D()) { - Arrays.fill(tessGeo.polyColors, firstPointVertex, lastPointVertex + 1, PGL.javaToNativeARGB(strokeColor)); + Arrays.fill(tessGeo.polyColors, firstPointVertex, lastPointVertex + 1, + PGL.javaToNativeARGB(strokeColor)); root.setModifiedPolyColors(firstPointVertex, lastPointVertex); } } @@ -1412,19 +1449,24 @@ public class PShapeOpenGL extends PShape { if (tintColor == newTintColor) return; tintColor = newTintColor; - if (shapeEnded && tessellated && hasPolys && texture != null) { - Arrays.fill(inGeo.colors, 0, inGeo.vertexCount, PGL.javaToNativeARGB(tintColor)); - if (is3D()) { - Arrays.fill(tessGeo.polyColors, firstPolyVertex, lastPolyVertex + 1, PGL.javaToNativeARGB(tintColor)); - root.setModifiedPolyColors(firstPolyVertex, lastPolyVertex); - } else if (is2D()) { - int last1 = lastPolyVertex + 1; - if (-1 < firstLineVertex) last1 = firstLineVertex; - if (-1 < firstPointVertex) last1 = firstPointVertex; - Arrays.fill(tessGeo.polyColors, firstPolyVertex, last1, PGL.javaToNativeARGB(tintColor)); - root.setModifiedPolyColors(firstPolyVertex, last1 - 1); - } - } + if (texture != null) { + Arrays.fill(inGeo.colors, 0, inGeo.vertexCount, + PGL.javaToNativeARGB(tintColor)); + if (shapeEnded && tessellated && hasPolys) { + if (is3D()) { + Arrays.fill(tessGeo.polyColors, firstPolyVertex, lastPolyVertex + 1, + PGL.javaToNativeARGB(tintColor)); + root.setModifiedPolyColors(firstPolyVertex, lastPolyVertex); + } else if (is2D()) { + int last1 = lastPolyVertex + 1; + if (-1 < firstLineVertex) last1 = firstLineVertex; + if (-1 < firstPointVertex) last1 = firstPointVertex; + Arrays.fill(tessGeo.polyColors, firstPolyVertex, last1, + PGL.javaToNativeARGB(tintColor)); + root.setModifiedPolyColors(firstPolyVertex, last1 - 1); + } + } + } } @@ -1481,16 +1523,19 @@ public class PShapeOpenGL extends PShape { if (ambientColor == newAmbientColor) return; ambientColor = newAmbientColor; - if (shapeEnded && tessellated && hasPolys) { - Arrays.fill(inGeo.ambient, 0, inGeo.vertexCount, PGL.javaToNativeARGB(ambientColor)); + Arrays.fill(inGeo.ambient, 0, inGeo.vertexCount, + PGL.javaToNativeARGB(ambientColor)); + if (shapeEnded && tessellated && hasPolys) { if (is3D()) { - Arrays.fill(tessGeo.polyAmbient, firstPolyVertex, lastPolyVertex = 1, PGL.javaToNativeARGB(ambientColor)); + Arrays.fill(tessGeo.polyAmbient, firstPolyVertex, lastPolyVertex = 1, + PGL.javaToNativeARGB(ambientColor)); root.setModifiedPolyAmbient(firstPolyVertex, lastPolyVertex); } else if (is2D()) { int last1 = lastPolyVertex + 1; if (-1 < firstLineVertex) last1 = firstLineVertex; if (-1 < firstPointVertex) last1 = firstPointVertex; - Arrays.fill(tessGeo.polyAmbient, firstPolyVertex, last1, PGL.javaToNativeARGB(ambientColor)); + Arrays.fill(tessGeo.polyAmbient, firstPolyVertex, last1, + PGL.javaToNativeARGB(ambientColor)); root.setModifiedPolyColors(firstPolyVertex, last1 - 1); } } @@ -1550,16 +1595,19 @@ public class PShapeOpenGL extends PShape { if (specularColor == newSpecularColor) return; specularColor = newSpecularColor; - if (shapeEnded && tessellated && hasPolys) { - Arrays.fill(inGeo.specular, 0, inGeo.vertexCount, PGL.javaToNativeARGB(specularColor)); + Arrays.fill(inGeo.specular, 0, inGeo.vertexCount, + PGL.javaToNativeARGB(specularColor)); + if (shapeEnded && tessellated && hasPolys) { if (is3D()) { - Arrays.fill(tessGeo.polySpecular, firstPolyVertex, lastPolyVertex + 1, PGL.javaToNativeARGB(specularColor)); + Arrays.fill(tessGeo.polySpecular, firstPolyVertex, lastPolyVertex + 1, + PGL.javaToNativeARGB(specularColor)); root.setModifiedPolySpecular(firstPolyVertex, lastPolyVertex); } else if (is2D()) { int last1 = lastPolyVertex + 1; if (-1 < firstLineVertex) last1 = firstLineVertex; if (-1 < firstPointVertex) last1 = firstPointVertex; - Arrays.fill(tessGeo.polySpecular, firstPolyVertex, last1, PGL.javaToNativeARGB(specularColor)); + Arrays.fill(tessGeo.polySpecular, firstPolyVertex, last1, + PGL.javaToNativeARGB(specularColor)); root.setModifiedPolyColors(firstPolyVertex, last1 - 1); } } @@ -1619,16 +1667,19 @@ public class PShapeOpenGL extends PShape { if (emissiveColor == newEmissiveColor) return; emissiveColor = newEmissiveColor; - if (shapeEnded && tessellated && 0 < tessGeo.polyVertexCount) { - Arrays.fill(inGeo.emissive, 0, inGeo.vertexCount, PGL.javaToNativeARGB(emissiveColor)); + Arrays.fill(inGeo.emissive, 0, inGeo.vertexCount, + PGL.javaToNativeARGB(emissiveColor)); + if (shapeEnded && tessellated && 0 < tessGeo.polyVertexCount) { if (is3D()) { - Arrays.fill(tessGeo.polyEmissive, firstPolyVertex, lastPolyVertex + 1, PGL.javaToNativeARGB(emissiveColor)); + Arrays.fill(tessGeo.polyEmissive, firstPolyVertex, lastPolyVertex + 1, + PGL.javaToNativeARGB(emissiveColor)); root.setModifiedPolyEmissive(firstPolyVertex, lastPolyVertex); } else if (is2D()) { int last1 = lastPolyVertex + 1; if (-1 < firstLineVertex) last1 = firstLineVertex; if (-1 < firstPointVertex) last1 = firstPointVertex; - Arrays.fill(tessGeo.polyEmissive, firstPolyVertex, last1, PGL.javaToNativeARGB(emissiveColor)); + Arrays.fill(tessGeo.polyEmissive, firstPolyVertex, last1, + PGL.javaToNativeARGB(emissiveColor)); root.setModifiedPolyColors(firstPolyVertex, last1 - 1); } } @@ -1656,10 +1707,11 @@ public class PShapeOpenGL extends PShape { if (PGraphicsOpenGL.same(shininess, newShininess)) return; shininess = newShininess; - if (shapeEnded && tessellated && hasPolys) { - Arrays.fill(inGeo.shininess, 0, inGeo.vertexCount, shininess); + Arrays.fill(inGeo.shininess, 0, inGeo.vertexCount, shininess); + if (shapeEnded && tessellated && hasPolys) { if (is3D()) { - Arrays.fill(tessGeo.polyShininess, firstPolyVertex, lastPolyVertex + 1, shininess); + Arrays.fill(tessGeo.polyShininess, firstPolyVertex, lastPolyVertex + 1, + shininess); root.setModifiedPolyShininess(firstPolyVertex, lastPolyVertex); } else if (is2D()) { int last1 = lastPolyVertex + 1; @@ -1829,20 +1881,23 @@ public class PShapeOpenGL extends PShape { protected void applyMatrixImpl(PMatrix matrix) { if (hasPolys) { - tessGeo.applyMatrixOnPolyGeometry(matrix, firstPolyVertex, lastPolyVertex); + tessGeo.applyMatrixOnPolyGeometry(matrix, + firstPolyVertex, lastPolyVertex); root.setModifiedPolyVertices(firstPolyVertex, lastPolyVertex); root.setModifiedPolyNormals(firstPolyVertex, lastPolyVertex); } if (is3D()) { if (hasLines) { - tessGeo.applyMatrixOnLineGeometry(matrix, firstLineVertex, lastLineVertex); + tessGeo.applyMatrixOnLineGeometry(matrix, + firstLineVertex, lastLineVertex); root.setModifiedLineVertices(firstLineVertex, lastLineVertex); root.setModifiedLineAttributes(firstLineVertex, lastLineVertex); } if (hasPoints) { - tessGeo.applyMatrixOnPointGeometry(matrix, firstPointVertex, lastPointVertex); + tessGeo.applyMatrixOnPointGeometry(matrix, + firstPointVertex, lastPointVertex); root.setModifiedPointVertices(firstPointVertex, lastPointVertex); } } @@ -2180,13 +2235,25 @@ public class PShapeOpenGL extends PShape { int i2 = voffset + indices[3 * tr + 2]; if (is3D()) { - float x0 = vertices[4 * i0 + 0], y0 = vertices[4 * i0 + 1], z0 = vertices[4 * i0 + 2]; - float x1 = vertices[4 * i1 + 0], y1 = vertices[4 * i1 + 1], z1 = vertices[4 * i1 + 2]; - float x2 = vertices[4 * i2 + 0], y2 = vertices[4 * i2 + 1], z2 = vertices[4 * i2 + 2]; + float x0 = vertices[4 * i0 + 0]; + float y0 = vertices[4 * i0 + 1]; + float z0 = vertices[4 * i0 + 2]; + float x1 = vertices[4 * i1 + 0]; + float y1 = vertices[4 * i1 + 1]; + float z1 = vertices[4 * i1 + 2]; + float x2 = vertices[4 * i2 + 0]; + float y2 = vertices[4 * i2 + 1]; + float z2 = vertices[4 * i2 + 2]; - float nx0 = normals[3 * i0 + 0], ny0 = normals[3 * i0 + 1], nz0 = normals[3 * i0 + 2]; - float nx1 = normals[3 * i1 + 0], ny1 = normals[3 * i1 + 1], nz1 = normals[3 * i1 + 2]; - float nx2 = normals[3 * i2 + 0], ny2 = normals[3 * i2 + 1], nz2 = normals[3 * i2 + 2]; + float nx0 = normals[3 * i0 + 0]; + float ny0 = normals[3 * i0 + 1]; + float nz0 = normals[3 * i0 + 2]; + float nx1 = normals[3 * i1 + 0]; + float ny1 = normals[3 * i1 + 1]; + float nz1 = normals[3 * i1 + 2]; + float nx2 = normals[3 * i2 + 0]; + float ny2 = normals[3 * i2 + 1]; + float nz2 = normals[3 * i2 + 2]; int argb0 = PGL.nativeToJavaARGB(color[i0]); int argb1 = PGL.nativeToJavaARGB(color[i1]); @@ -2383,7 +2450,8 @@ public class PShapeOpenGL extends PShape { tessellator.tessellateQuadStrip(); } else if (kind == POLYGON) { if (stroke) inGeo.addPolygonEdges(isClosed); - tessellator.tessellatePolygon(isSolid, isClosed, normalMode == NORMAL_MODE_AUTO); + tessellator.tessellatePolygon(isSolid, isClosed, + normalMode == NORMAL_MODE_AUTO); } } else if (family == PRIMITIVE) { // The input geometry needs to be cleared because the geometry @@ -2670,7 +2738,7 @@ public class PShapeOpenGL extends PShape { } } } else { // coded set of vertices - int index = 0; + int idx = 0; int code = BREAK; if (vertices[0].length == 2) { // tessellating a 2D path @@ -2679,33 +2747,33 @@ public class PShapeOpenGL extends PShape { switch (vertexCodes[j]) { case VERTEX: - inGeo.addVertex(vertices[index][X], vertices[index][Y], code); + inGeo.addVertex(vertices[idx][X], vertices[idx][Y], code); code = VERTEX; - index++; + idx++; break; case QUAD_BEZIER_VERTEX: - inGeo.addQuadraticVertex(vertices[index+0][X], vertices[index+0][Y], 0, - vertices[index+1][X], vertices[index+1][Y], 0, + inGeo.addQuadraticVertex(vertices[idx+0][X], vertices[idx+0][Y], 0, + vertices[idx+1][X], vertices[idx+1][Y], 0, fill, stroke, bezierDetail, code); code = VERTEX; - index += 2; + idx += 2; break; case BEZIER_VERTEX: - inGeo.addBezierVertex(vertices[index+0][X], vertices[index+0][Y], 0, - vertices[index+1][X], vertices[index+1][Y], 0, - vertices[index+2][X], vertices[index+2][Y], 0, + inGeo.addBezierVertex(vertices[idx+0][X], vertices[idx+0][Y], 0, + vertices[idx+1][X], vertices[idx+1][Y], 0, + vertices[idx+2][X], vertices[idx+2][Y], 0, fill, stroke, bezierDetail, code); code = VERTEX; - index += 3; + idx += 3; break; case CURVE_VERTEX: - inGeo.addCurveVertex(vertices[index][X], vertices[index][Y], 0, + inGeo.addCurveVertex(vertices[idx][X], vertices[idx][Y], 0, fill, stroke, curveDetail, code); code = VERTEX; - index++; + idx++; case BREAK: code = BREAK; @@ -2716,34 +2784,47 @@ public class PShapeOpenGL extends PShape { switch (vertexCodes[j]) { case VERTEX: - inGeo.addVertex(vertices[index][X], vertices[index][Y], vertices[index][Z], code); + inGeo.addVertex(vertices[idx][X], vertices[idx][Y], + vertices[idx][Z], code); code = VERTEX; - index++; + idx++; break; case QUAD_BEZIER_VERTEX: - inGeo.addQuadraticVertex(vertices[index+0][X], vertices[index+0][Y], vertices[index+0][Z], - vertices[index+1][X], vertices[index+1][Y], vertices[index+0][Z], + inGeo.addQuadraticVertex(vertices[idx+0][X], + vertices[idx+0][Y], + vertices[idx+0][Z], + vertices[idx+1][X], + vertices[idx+1][Y], + vertices[idx+0][Z], fill, stroke, bezierDetail, code); code = VERTEX; - index += 2; + idx += 2; break; case BEZIER_VERTEX: - inGeo.addBezierVertex(vertices[index+0][X], vertices[index+0][Y], vertices[index+0][Z], - vertices[index+1][X], vertices[index+1][Y], vertices[index+1][Z], - vertices[index+2][X], vertices[index+2][Y], vertices[index+2][Z], + inGeo.addBezierVertex(vertices[idx+0][X], + vertices[idx+0][Y], + vertices[idx+0][Z], + vertices[idx+1][X], + vertices[idx+1][Y], + vertices[idx+1][Z], + vertices[idx+2][X], + vertices[idx+2][Y], + vertices[idx+2][Z], fill, stroke, bezierDetail, code); code = VERTEX; - index += 3; + idx += 3; break; case CURVE_VERTEX: - inGeo.addCurveVertex(vertices[index][X], vertices[index][Y], vertices[index][Z], + inGeo.addCurveVertex(vertices[idx][X], + vertices[idx][Y], + vertices[idx][Z], fill, stroke, curveDetail, code); code = VERTEX; - index++; + idx++; case BREAK: code = BREAK; @@ -2789,8 +2870,8 @@ public class PShapeOpenGL extends PShape { } - // This method is very important, as it is responsible of generating the correct - // vertex and index offsets for each level of the shape hierarchy. + // This method is very important, as it is responsible of generating the + // correct vertex and index offsets for each level of the shape hierarchy. // This is the core of the recursive algorithm that calculates the indices // for the vertices accumulated in a single VBO. // Basically, the algorithm traverses all the shapes in the hierarchy and @@ -2835,7 +2916,9 @@ public class PShapeOpenGL extends PShape { hasPoints = -1 < firstPointIndexCache && -1 < lastPointIndexCache; } - if (hasPolys) updatePolyIndexCache(); + if (hasPolys) { + updatePolyIndexCache(); + } if (is3D()) { if (hasLines) updateLineIndexCache(); if (hasPoints) updatePointIndexCache(); @@ -2845,10 +2928,19 @@ public class PShapeOpenGL extends PShape { // Some geometric transformations were applied on // this shape before tessellation, so they are applied now. //applyMatrixImpl(matrix); - if (hasPolys) tessGeo.applyMatrixOnPolyGeometry(matrix, firstPolyVertex, lastPolyVertex); + if (hasPolys) { + tessGeo.applyMatrixOnPolyGeometry(matrix, + firstPolyVertex, lastPolyVertex); + } if (is3D()) { - if (hasLines) tessGeo.applyMatrixOnLineGeometry(matrix, firstLineVertex, lastLineVertex); - if (hasPoints) tessGeo.applyMatrixOnPointGeometry(matrix, firstPointVertex, lastPointVertex); + if (hasLines) { + tessGeo.applyMatrixOnLineGeometry(matrix, + firstLineVertex, lastLineVertex); + } + if (hasPoints) { + tessGeo.applyMatrixOnPointGeometry(matrix, + firstPointVertex, lastPointVertex); + } } } } @@ -2889,7 +2981,8 @@ public class PShapeOpenGL extends PShape { // include the index range in the current child shape. // This is a result of how the indices are updated for the // leaf shapes. - cache.incCounts(gindex, cache.indexCount[n], cache.vertexCount[n]); + cache.incCounts(gindex, + cache.indexCount[n], cache.vertexCount[n]); } else { gindex = cache.addNew(n); } @@ -2898,7 +2991,9 @@ public class PShapeOpenGL extends PShape { // Updating the first and last poly vertices for this group shape. if (-1 < child.firstPolyVertex) { - if (firstPolyVertex == -1) firstPolyVertex = Integer.MAX_VALUE; + if (firstPolyVertex == -1) { + firstPolyVertex = Integer.MAX_VALUE; + } firstPolyVertex = PApplet.min(firstPolyVertex, child.firstPolyVertex); } if (-1 < child.lastPolyVertex) { @@ -2919,7 +3014,8 @@ public class PShapeOpenGL extends PShape { // root shape. When this happens, the indices in the child shape need // to be restarted as well to reflect the new index offset. - firstPolyVertex = lastPolyVertex = cache.vertexOffset[firstPolyIndexCache]; + firstPolyVertex = lastPolyVertex = + cache.vertexOffset[firstPolyIndexCache]; for (int n = firstPolyIndexCache; n <= lastPolyIndexCache; n++) { int ioffset = cache.indexOffset[n]; int icount = cache.indexCount[n]; @@ -2930,9 +3026,14 @@ public class PShapeOpenGL extends PShape { root.polyVertexRel = 0; root.polyVertexOffset = root.polyVertexAbs; cache.indexOffset[n] = root.polyIndexOffset; - } else tessGeo.incPolyIndices(ioffset, ioffset + icount - 1, root.polyVertexRel); + } else { + tessGeo.incPolyIndices(ioffset, ioffset + icount - 1, + root.polyVertexRel); + } cache.vertexOffset[n] = root.polyVertexOffset; - if (is2D()) setFirstStrokeVertex(n, lastPolyVertex); + if (is2D()) { + setFirstStrokeVertex(n, lastPolyVertex); + } root.polyIndexOffset += icount; root.polyVertexAbs += vcount; @@ -2940,13 +3041,16 @@ public class PShapeOpenGL extends PShape { lastPolyVertex += vcount; } lastPolyVertex--; - if (is2D()) setLastStrokeVertex(lastPolyVertex); + if (is2D()) { + setLastStrokeVertex(lastPolyVertex); + } } } protected boolean startStrokedTex(int n) { - return texture != null && (n == firstLineIndexCache || n == firstPointIndexCache); + return texture != null && (n == firstLineIndexCache || + n == firstPointIndexCache); } @@ -2985,7 +3089,8 @@ public class PShapeOpenGL extends PShape { firstLineIndexCache = gindex; } else { if (cache.vertexOffset[gindex] == cache.vertexOffset[n]) { - cache.incCounts(gindex, cache.indexCount[n], cache.vertexCount[n]); + cache.incCounts(gindex, cache.indexCount[n], + cache.vertexCount[n]); } else { gindex = cache.addNew(n); } @@ -3003,7 +3108,8 @@ public class PShapeOpenGL extends PShape { } lastLineIndexCache = gindex; } else { - firstLineVertex = lastLineVertex = cache.vertexOffset[firstLineIndexCache]; + firstLineVertex = lastLineVertex = + cache.vertexOffset[firstLineIndexCache]; for (int n = firstLineIndexCache; n <= lastLineIndexCache; n++) { int ioffset = cache.indexOffset[n]; int icount = cache.indexCount[n]; @@ -3013,7 +3119,10 @@ public class PShapeOpenGL extends PShape { root.lineVertexRel = 0; root.lineVertexOffset = root.lineVertexAbs; cache.indexOffset[n] = root.lineIndexOffset; - } else tessGeo.incLineIndices(ioffset, ioffset + icount - 1, root.lineVertexRel); + } else { + tessGeo.incLineIndices(ioffset, ioffset + icount - 1, + root.lineVertexRel); + } cache.vertexOffset[n] = root.lineVertexOffset; root.lineIndexOffset += icount; @@ -3048,7 +3157,8 @@ public class PShapeOpenGL extends PShape { // include either the index range in the current child shape. // This is a result of how the indices are updated for the // leaf shapes in aggregateImpl(). - cache.incCounts(gindex, cache.indexCount[n], cache.vertexCount[n]); + cache.incCounts(gindex, cache.indexCount[n], + cache.vertexCount[n]); } else { gindex = cache.addNew(n); } @@ -3058,7 +3168,8 @@ public class PShapeOpenGL extends PShape { // Updating the first and last point vertices for this group shape. if (-1 < child.firstPointVertex) { if (firstPointVertex == -1) firstPointVertex = Integer.MAX_VALUE; - firstPointVertex = PApplet.min(firstPointVertex, child.firstPointVertex); + firstPointVertex = PApplet.min(firstPointVertex, + child.firstPointVertex); } if (-1 < child.lastPointVertex) { lastPointVertex = PApplet.max(lastPointVertex, child.lastPointVertex); @@ -3066,7 +3177,8 @@ public class PShapeOpenGL extends PShape { } lastPointIndexCache = gindex; } else { - firstPointVertex = lastPointVertex = cache.vertexOffset[firstPointIndexCache]; + firstPointVertex = lastPointVertex = + cache.vertexOffset[firstPointIndexCache]; for (int n = firstPointIndexCache; n <= lastPointIndexCache; n++) { int ioffset = cache.indexOffset[n]; int icount = cache.indexCount[n]; @@ -3076,7 +3188,10 @@ public class PShapeOpenGL extends PShape { root.pointVertexRel = 0; root.pointVertexOffset = root.pointVertexAbs; cache.indexOffset[n] = root.pointIndexOffset; - } else tessGeo.incPointIndices(ioffset, ioffset + icount - 1, root.pointVertexRel); + } else { + tessGeo.incPointIndices(ioffset, ioffset + icount - 1, + root.pointVertexRel); + } cache.vertexOffset[n] = root.pointVertexOffset; root.pointIndexOffset += icount; @@ -3124,42 +3239,60 @@ public class PShapeOpenGL extends PShape { glPolyVertex = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyVertex); - pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, FloatBuffer.wrap(tessGeo.polyVertices, 0, 4 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, + FloatBuffer.wrap(tessGeo.polyVertices, 0, 4 * size), + PGL.STATIC_DRAW); glPolyColor = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyColor); - pgl.bufferData(PGL.ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.polyColors, 0, size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, sizei, + IntBuffer.wrap(tessGeo.polyColors, 0, size), + PGL.STATIC_DRAW); glPolyNormal = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyNormal); - pgl.bufferData(PGL.ARRAY_BUFFER, 3 * sizef, FloatBuffer.wrap(tessGeo.polyNormals, 0, 3 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 3 * sizef, + FloatBuffer.wrap(tessGeo.polyNormals, 0, 3 * size), + PGL.STATIC_DRAW); glPolyTexcoord = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyTexcoord); - pgl.bufferData(PGL.ARRAY_BUFFER, 2 * sizef, FloatBuffer.wrap(tessGeo.polyTexcoords, 0, 2 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 2 * sizef, + FloatBuffer.wrap(tessGeo.polyTexcoords, 0, 2 * size), + PGL.STATIC_DRAW); glPolyAmbient = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyAmbient); - pgl.bufferData(PGL.ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.polyAmbient, 0, size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, sizei, + IntBuffer.wrap(tessGeo.polyAmbient, 0, size), + PGL.STATIC_DRAW); glPolySpecular = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolySpecular); - pgl.bufferData(PGL.ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.polySpecular, 0, size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, sizei, + IntBuffer.wrap(tessGeo.polySpecular, 0, size), + PGL.STATIC_DRAW); glPolyEmissive = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyEmissive); - pgl.bufferData(PGL.ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.polyEmissive, 0, size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, sizei, + IntBuffer.wrap(tessGeo.polyEmissive, 0, size), + PGL.STATIC_DRAW); glPolyShininess = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyShininess); - pgl.bufferData(PGL.ARRAY_BUFFER, sizef, FloatBuffer.wrap(tessGeo.polyShininess, 0, size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, sizef, + FloatBuffer.wrap(tessGeo.polyShininess, 0, size), + PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); glPolyIndex = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glPolyIndex); - pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, tessGeo.polyIndexCount * PGL.SIZEOF_INDEX, - ShortBuffer.wrap(tessGeo.polyIndices, 0, tessGeo.polyIndexCount), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, + tessGeo.polyIndexCount * PGL.SIZEOF_INDEX, + ShortBuffer.wrap(tessGeo.polyIndices, 0, + tessGeo.polyIndexCount), PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0); } @@ -3172,22 +3305,30 @@ public class PShapeOpenGL extends PShape { glLineVertex = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineVertex); - pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, FloatBuffer.wrap(tessGeo.lineVertices, 0, 4 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, + FloatBuffer.wrap(tessGeo.lineVertices, 0, 4 * size), + PGL.STATIC_DRAW); glLineColor = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineColor); - pgl.bufferData(PGL.ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.lineColors, 0, size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, sizei, + IntBuffer.wrap(tessGeo.lineColors, 0, size), + PGL.STATIC_DRAW); glLineAttrib = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineAttrib); - pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, FloatBuffer.wrap(tessGeo.lineAttribs, 0, 4 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, + FloatBuffer.wrap(tessGeo.lineAttribs, 0, 4 * size), + PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); glLineIndex = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glLineIndex); - pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, tessGeo.lineIndexCount * PGL.SIZEOF_INDEX, - ShortBuffer.wrap(tessGeo.lineIndices, 0, tessGeo.lineIndexCount), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, + tessGeo.lineIndexCount * PGL.SIZEOF_INDEX, + ShortBuffer.wrap(tessGeo.lineIndices, 0, + tessGeo.lineIndexCount), PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0); } @@ -3200,22 +3341,30 @@ public class PShapeOpenGL extends PShape { glPointVertex = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointVertex); - pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, FloatBuffer.wrap(tessGeo.pointVertices, 0, 4 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 4 * sizef, + FloatBuffer.wrap(tessGeo.pointVertices, 0, 4 * size), + PGL.STATIC_DRAW); glPointColor = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointColor); - pgl.bufferData(PGL.ARRAY_BUFFER, sizei, IntBuffer.wrap(tessGeo.pointColors, 0, size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, sizei, + IntBuffer.wrap(tessGeo.pointColors, 0, size), + PGL.STATIC_DRAW); glPointAttrib = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointAttrib); - pgl.bufferData(PGL.ARRAY_BUFFER, 2 * sizef, FloatBuffer.wrap(tessGeo.pointAttribs, 0, 2 * size), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ARRAY_BUFFER, 2 * sizef, + FloatBuffer.wrap(tessGeo.pointAttribs, 0, 2 * size), + PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); glPointIndex = pg.createVertexBufferObject(context.code()); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, glPointIndex); - pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, tessGeo.pointIndexCount * PGL.SIZEOF_INDEX, - ShortBuffer.wrap(tessGeo.pointIndices, 0, tessGeo.pointIndexCount), PGL.STATIC_DRAW); + pgl.bufferData(PGL.ELEMENT_ARRAY_BUFFER, + tessGeo.pointIndexCount * PGL.SIZEOF_INDEX, + ShortBuffer.wrap(tessGeo.pointIndices, 0, + tessGeo.pointIndexCount), PGL.STATIC_DRAW); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0); } @@ -3521,112 +3670,133 @@ public class PShapeOpenGL extends PShape { protected void copyPolyVertices(int offset, int size) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyVertex); - pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, 4 * size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.polyVertices, 4 * offset, 4 * size)); + pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, + 4 * size * PGL.SIZEOF_FLOAT, + FloatBuffer.wrap(tessGeo.polyVertices, + 4 * offset, 4 * size)); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPolyColors(int offset, int size) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyColor); - pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, - IntBuffer.wrap(tessGeo.polyColors, offset, size)); + pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, + size * PGL.SIZEOF_INT, + IntBuffer.wrap(tessGeo.polyColors, offset, size)); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPolyNormals(int offset, int size) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyNormal); - pgl.bufferSubData(PGL.ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, 3 * size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.polyNormals, 3 * offset, 3 * size)); + pgl.bufferSubData(PGL.ARRAY_BUFFER, 3 * offset * PGL.SIZEOF_FLOAT, + 3 * size * PGL.SIZEOF_FLOAT, + FloatBuffer.wrap(tessGeo.polyNormals, + 3 * offset, 3 * size)); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPolyTexcoords(int offset, int size) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyTexcoord); - pgl.bufferSubData(PGL.ARRAY_BUFFER, 2 * offset * PGL.SIZEOF_FLOAT, 2 * size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.polyTexcoords, 2 * offset, 2 * size)); + pgl.bufferSubData(PGL.ARRAY_BUFFER, 2 * offset * PGL.SIZEOF_FLOAT, + 2 * size * PGL.SIZEOF_FLOAT, + FloatBuffer.wrap(tessGeo.polyTexcoords, + 2 * offset, 2 * size)); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPolyAmbient(int offset, int size) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyAmbient); - pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, - IntBuffer.wrap(tessGeo.polyAmbient, offset, size)); + pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, + size * PGL.SIZEOF_INT, + IntBuffer.wrap(tessGeo.polyAmbient, offset, size)); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPolySpecular(int offset, int size) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolySpecular); - pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, - IntBuffer.wrap(tessGeo.polySpecular, offset, size)); + pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, + size * PGL.SIZEOF_INT, + IntBuffer.wrap(tessGeo.polySpecular, offset, size)); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPolyEmissive(int offset, int size) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyEmissive); - pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, - IntBuffer.wrap(tessGeo.polyEmissive, offset, size)); + pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, + size * PGL.SIZEOF_INT, + IntBuffer.wrap(tessGeo.polyEmissive, offset, size)); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPolyShininess(int offset, int size) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glPolyShininess); - pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_FLOAT, size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.polyShininess, offset, size)); + pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_FLOAT, + size * PGL.SIZEOF_FLOAT, + FloatBuffer.wrap(tessGeo.polyShininess, offset, size)); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyLineVertices(int offset, int size) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineVertex); - pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, 4 * size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.lineVertices, 4 * offset, 4 * size)); + pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, + 4 * size * PGL.SIZEOF_FLOAT, + FloatBuffer.wrap(tessGeo.lineVertices, + 4 * offset, 4 * size)); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyLineColors(int offset, int size) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineColor); - pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, - IntBuffer.wrap(tessGeo.lineColors, offset, size)); + pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, + size * PGL.SIZEOF_INT, + IntBuffer.wrap(tessGeo.lineColors, offset, size)); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyLineAttributes(int offset, int size) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glLineAttrib); - pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, 4 * size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.lineAttribs, 4 * offset, 4 * size)); + pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, + 4 * size * PGL.SIZEOF_FLOAT, + FloatBuffer.wrap(tessGeo.lineAttribs, + 4 * offset, 4 * size)); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPointVertices(int offset, int size) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointVertex); - pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, 4 * size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.pointVertices, 4 * offset, 4 * size)); + pgl.bufferSubData(PGL.ARRAY_BUFFER, 4 * offset * PGL.SIZEOF_FLOAT, + 4 * size * PGL.SIZEOF_FLOAT, + FloatBuffer.wrap(tessGeo.pointVertices, + 4 * offset, 4 * size)); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPointColors(int offset, int size) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointColor); - pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, size * PGL.SIZEOF_INT, - IntBuffer.wrap(tessGeo.pointColors, offset, size)); + pgl.bufferSubData(PGL.ARRAY_BUFFER, offset * PGL.SIZEOF_INT, + size * PGL.SIZEOF_INT, + IntBuffer.wrap(tessGeo.pointColors, offset, size)); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } protected void copyPointAttributes(int offset, int size) { pgl.bindBuffer(PGL.ARRAY_BUFFER, glPointAttrib); - pgl.bufferSubData(PGL.ARRAY_BUFFER, 2 * offset * PGL.SIZEOF_FLOAT, 2 * size * PGL.SIZEOF_FLOAT, - FloatBuffer.wrap(tessGeo.pointAttribs, 2 * offset, 2 * size)); + pgl.bufferSubData(PGL.ARRAY_BUFFER, 2 * offset * PGL.SIZEOF_FLOAT, + 2 * size * PGL.SIZEOF_FLOAT, + FloatBuffer.wrap(tessGeo.pointAttribs, + 2 * offset, 2 * size)); pgl.bindBuffer(PGL.ARRAY_BUFFER, 0); } @@ -3880,7 +4050,8 @@ public class PShapeOpenGL extends PShape { protected void render(PGraphicsOpenGL g, PImage texture) { if (root == null) { // Some error. Root should never be null. At least it should be 'this'. - throw new RuntimeException("Error rendering PShapeOpenGL, root shape is null"); + throw new RuntimeException("Error rendering PShapeOpenGL, root shape is " + + "null"); } if (hasPolys) { @@ -3923,8 +4094,10 @@ public class PShapeOpenGL extends PShape { PolyShader shader = null; IndexCache cache = tessGeo.polyIndexCache; for (int n = firstPolyIndexCache; n <= lastPolyIndexCache; n++) { - if (is3D() || (tex != null && (firstLineIndexCache == -1 || n < firstLineIndexCache) && - (firstPointIndexCache == -1 || n < firstPointIndexCache))) { + if (is3D() || (tex != null && (firstLineIndexCache == -1 || + n < firstLineIndexCache) && + (firstPointIndexCache == -1 || + n < firstPointIndexCache))) { // Rendering fill triangles, which can be lit and textured. if (!renderingFill) { shader = g.getPolyShader(g.lights, tex != null); @@ -3957,24 +4130,33 @@ public class PShapeOpenGL extends PShape { int icount = cache.indexCount[n]; int voffset = cache.vertexOffset[n]; - shader.setVertexAttribute(root.glPolyVertex, 4, PGL.FLOAT, 0, 4 * voffset * PGL.SIZEOF_FLOAT); - shader.setColorAttribute(root.glPolyColor, 4, PGL.UNSIGNED_BYTE, 0, 4 * voffset * PGL.SIZEOF_BYTE); + shader.setVertexAttribute(root.glPolyVertex, 4, PGL.FLOAT, + 0, 4 * voffset * PGL.SIZEOF_FLOAT); + shader.setColorAttribute(root.glPolyColor, 4, PGL.UNSIGNED_BYTE, + 0, 4 * voffset * PGL.SIZEOF_BYTE); if (g.lights) { - shader.setNormalAttribute(root.glPolyNormal, 3, PGL.FLOAT, 0, 3 * voffset * PGL.SIZEOF_FLOAT); - shader.setAmbientAttribute(root.glPolyAmbient, 4, PGL.UNSIGNED_BYTE, 0, 4 * voffset * PGL.SIZEOF_BYTE); - shader.setSpecularAttribute(root.glPolySpecular, 4, PGL.UNSIGNED_BYTE, 0, 4 * voffset * PGL.SIZEOF_BYTE); - shader.setEmissiveAttribute(root.glPolyEmissive, 4, PGL.UNSIGNED_BYTE, 0, 4 * voffset * PGL.SIZEOF_BYTE); - shader.setShininessAttribute(root.glPolyShininess, 1, PGL.FLOAT, 0, voffset * PGL.SIZEOF_FLOAT); + shader.setNormalAttribute(root.glPolyNormal, 3, PGL.FLOAT, + 0, 3 * voffset * PGL.SIZEOF_FLOAT); + shader.setAmbientAttribute(root.glPolyAmbient, 4, PGL.UNSIGNED_BYTE, + 0, 4 * voffset * PGL.SIZEOF_BYTE); + shader.setSpecularAttribute(root.glPolySpecular, 4, PGL.UNSIGNED_BYTE, + 0, 4 * voffset * PGL.SIZEOF_BYTE); + shader.setEmissiveAttribute(root.glPolyEmissive, 4, PGL.UNSIGNED_BYTE, + 0, 4 * voffset * PGL.SIZEOF_BYTE); + shader.setShininessAttribute(root.glPolyShininess, 1, PGL.FLOAT, + 0, voffset * PGL.SIZEOF_FLOAT); } if (tex != null) { - shader.setTexcoordAttribute(root.glPolyTexcoord, 2, PGL.FLOAT, 0, 2 * voffset * PGL.SIZEOF_FLOAT); + shader.setTexcoordAttribute(root.glPolyTexcoord, 2, PGL.FLOAT, + 0, 2 * voffset * PGL.SIZEOF_FLOAT); shader.setTexture(tex); } pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, root.glPolyIndex); - pgl.drawElements(PGL.TRIANGLES, icount, PGL.INDEX_TYPE, ioffset * PGL.SIZEOF_INDEX); + pgl.drawElements(PGL.TRIANGLES, icount, PGL.INDEX_TYPE, + ioffset * PGL.SIZEOF_INDEX); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0); } @@ -4040,9 +4222,12 @@ public class PShapeOpenGL extends PShape { raw.fill(argb2); raw.vertex(pt2[X], pt2[Y], pt2[Z], uv[2 * i2 + 0], uv[2 * i2 + 1]); } else if (raw.is2D()) { - float sx0 = g.screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]), sy0 = g.screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); - float sx1 = g.screenXImpl(pt1[0], pt1[1], pt1[2], pt1[3]), sy1 = g.screenYImpl(pt1[0], pt1[1], pt1[2], pt1[3]); - float sx2 = g.screenXImpl(pt2[0], pt2[1], pt2[2], pt2[3]), sy2 = g.screenYImpl(pt2[0], pt2[1], pt2[2], pt2[3]); + float sx0 = g.screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sy0 = g.screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sx1 = g.screenXImpl(pt1[0], pt1[1], pt1[2], pt1[3]); + float sy1 = g.screenYImpl(pt1[0], pt1[1], pt1[2], pt1[3]); + float sx2 = g.screenXImpl(pt2[0], pt2[1], pt2[2], pt2[3]); + float sy2 = g.screenYImpl(pt2[0], pt2[1], pt2[2], pt2[3]); raw.fill(argb0); raw.vertex(sx0, sy0, uv[2 * i0 + 0], uv[2 * i0 + 1]); raw.fill(argb1); @@ -4059,9 +4244,12 @@ public class PShapeOpenGL extends PShape { raw.fill(argb2); raw.vertex(pt2[X], pt2[Y], pt2[Z]); } else if (raw.is2D()) { - float sx0 = g.screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]), sy0 = g.screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); - float sx1 = g.screenXImpl(pt1[0], pt1[1], pt1[2], pt1[3]), sy1 = g.screenYImpl(pt1[0], pt1[1], pt1[2], pt1[3]); - float sx2 = g.screenXImpl(pt2[0], pt2[1], pt2[2], pt2[3]), sy2 = g.screenYImpl(pt2[0], pt2[1], pt2[2], pt2[3]); + float sx0 = g.screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sy0 = g.screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sx1 = g.screenXImpl(pt1[0], pt1[1], pt1[2], pt1[3]); + float sy1 = g.screenYImpl(pt1[0], pt1[1], pt1[2], pt1[3]); + float sx2 = g.screenXImpl(pt2[0], pt2[1], pt2[2], pt2[3]); + float sy2 = g.screenYImpl(pt2[0], pt2[1], pt2[2], pt2[3]); raw.fill(argb0); raw.vertex(sx0, sy0); raw.fill(argb1); @@ -4087,12 +4275,16 @@ public class PShapeOpenGL extends PShape { int icount = cache.indexCount[n]; int voffset = cache.vertexOffset[n]; - shader.setVertexAttribute(root.glLineVertex, 4, PGL.FLOAT, 0, 4 * voffset * PGL.SIZEOF_FLOAT); - shader.setColorAttribute(root.glLineColor, 4, PGL.UNSIGNED_BYTE, 0, 4 * voffset * PGL.SIZEOF_BYTE); - shader.setLineAttribute(root.glLineAttrib, 4, PGL.FLOAT, 0, 4 * voffset * PGL.SIZEOF_FLOAT); + shader.setVertexAttribute(root.glLineVertex, 4, PGL.FLOAT, + 0, 4 * voffset * PGL.SIZEOF_FLOAT); + shader.setColorAttribute(root.glLineColor, 4, PGL.UNSIGNED_BYTE, + 0, 4 * voffset * PGL.SIZEOF_BYTE); + shader.setLineAttribute(root.glLineAttrib, 4, PGL.FLOAT, + 0, 4 * voffset * PGL.SIZEOF_FLOAT); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, root.glLineIndex); - pgl.drawElements(PGL.TRIANGLES, icount, PGL.INDEX_TYPE, ioffset * PGL.SIZEOF_INDEX); + pgl.drawElements(PGL.TRIANGLES, icount, PGL.INDEX_TYPE, + ioffset * PGL.SIZEOF_INDEX); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0); } @@ -4155,8 +4347,10 @@ public class PShapeOpenGL extends PShape { raw.stroke(argb1); raw.vertex(pt1[X], pt1[Y], pt1[Z]); } else if (raw.is2D()) { - float sx0 = g.screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]), sy0 = g.screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); - float sx1 = g.screenXImpl(pt1[0], pt1[1], pt1[2], pt1[3]), sy1 = g.screenYImpl(pt1[0], pt1[1], pt1[2], pt1[3]); + float sx0 = g.screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sy0 = g.screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sx1 = g.screenXImpl(pt1[0], pt1[1], pt1[2], pt1[3]); + float sy1 = g.screenYImpl(pt1[0], pt1[1], pt1[2], pt1[3]); raw.strokeWeight(sw0); raw.stroke(argb0); raw.vertex(sx0, sy0); @@ -4181,12 +4375,16 @@ public class PShapeOpenGL extends PShape { int icount = cache.indexCount[n]; int voffset = cache.vertexOffset[n]; - shader.setVertexAttribute(root.glPointVertex, 4, PGL.FLOAT, 0, 4 * voffset * PGL.SIZEOF_FLOAT); - shader.setColorAttribute(root.glPointColor, 4, PGL.UNSIGNED_BYTE, 0, 4 * voffset * PGL.SIZEOF_BYTE); - shader.setPointAttribute(root.glPointAttrib, 2, PGL.FLOAT, 0, 2 * voffset * PGL.SIZEOF_FLOAT); + shader.setVertexAttribute(root.glPointVertex, 4, PGL.FLOAT, + 0, 4 * voffset * PGL.SIZEOF_FLOAT); + shader.setColorAttribute(root.glPointColor, 4, PGL.UNSIGNED_BYTE, + 0, 4 * voffset * PGL.SIZEOF_BYTE); + shader.setPointAttribute(root.glPointAttrib, 2, PGL.FLOAT, + 0, 2 * voffset * PGL.SIZEOF_FLOAT); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, root.glPointIndex); - pgl.drawElements(PGL.TRIANGLES, icount, PGL.INDEX_TYPE, ioffset * PGL.SIZEOF_INDEX); + pgl.drawElements(PGL.TRIANGLES, icount, PGL.INDEX_TYPE, + ioffset * PGL.SIZEOF_INDEX); pgl.bindBuffer(PGL.ELEMENT_ARRAY_BUFFER, 0); } @@ -4221,7 +4419,8 @@ public class PShapeOpenGL extends PShape { if (0 < size) { // round point weight = +size / 0.5f; perim = PApplet.max(PGraphicsOpenGL.MIN_POINT_ACCURACY, - (int) (TWO_PI * weight / PGraphicsOpenGL.POINT_ACCURACY_FACTOR)) + 1; + (int) (TWO_PI * weight / + PGraphicsOpenGL.POINT_ACCURACY_FACTOR)) + 1; } else { // Square point weight = -size / 0.5f; perim = 5; @@ -4240,7 +4439,8 @@ public class PShapeOpenGL extends PShape { raw.stroke(argb0); raw.vertex(pt0[X], pt0[Y], pt0[Z]); } else if (raw.is2D()) { - float sx0 = g.screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]), sy0 = g.screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sx0 = g.screenXImpl(pt0[0], pt0[1], pt0[2], pt0[3]); + float sy0 = g.screenYImpl(pt0[0], pt0[1], pt0[2], pt0[3]); raw.strokeWeight(weight); raw.stroke(argb0); raw.vertex(sx0, sy0); diff --git a/android/core/src/processing/opengl/PointShaderVert.glsl b/android/core/src/processing/opengl/PointShaderVert.glsl index bf393ed15..25b226b5b 100644 --- a/android/core/src/processing/opengl/PointShaderVert.glsl +++ b/android/core/src/processing/opengl/PointShaderVert.glsl @@ -21,16 +21,33 @@ uniform mat4 projectionMatrix; uniform mat4 modelviewMatrix; +uniform vec4 viewport; +uniform int perspective; + attribute vec4 inVertex; attribute vec4 inColor; attribute vec2 inPoint; varying vec4 vertColor; +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; +} + void main() { vec4 pos = modelviewMatrix * inVertex; - pos.xy += inPoint.xy; - gl_Position = projectionMatrix * pos; + vec4 clip = projectionMatrix * pos; + + if (0 < perspective) { + // Perspective correction (points will look thiner as they move away + // from the view position). + gl_Position = clip + projectionMatrix * vec4(inPoint.xy, 0, 0); + } else { + // No perspective correction. + vec4 offset = windowToClipVector(inPoint.xy, viewport, clip.w); + gl_Position = clip + offset; + } vertColor = inColor; } \ No newline at end of file diff --git a/android/core/src/processing/opengl/PolyFlatShaderVert.glsl b/android/core/src/processing/opengl/PolyColorShaderVert.glsl similarity index 100% rename from android/core/src/processing/opengl/PolyFlatShaderVert.glsl rename to android/core/src/processing/opengl/PolyColorShaderVert.glsl diff --git a/android/core/src/processing/opengl/PolyFullShaderVert.glsl b/android/core/src/processing/opengl/PolyTexlightShaderVert.glsl similarity index 100% rename from android/core/src/processing/opengl/PolyFullShaderVert.glsl rename to android/core/src/processing/opengl/PolyTexlightShaderVert.glsl diff --git a/android/core/src/processing/opengl/Texture.java b/android/core/src/processing/opengl/Texture.java index b4279812f..f2703e523 100644 --- a/android/core/src/processing/opengl/Texture.java +++ b/android/core/src/processing/opengl/Texture.java @@ -44,25 +44,27 @@ public class Texture implements PConstants { /** * Texture with normalized UV. */ - public static final int TEX2D = 0; + protected static final int TEX2D = 0; /** * Texture with un-normalized UV. */ - public static final int TEXRECT = 1; + protected static final int TEXRECT = 1; - /** Point sampling: both magnification and minification filtering are set to nearest */ - public static final int POINT = 2; - /** Linear sampling: magnification filtering is nearest, minification set to linear */ - public static final int LINEAR = 3; - /** Bilinear sampling: both magnification filtering is set to linear and minification - * either to linear-mipmap-nearest (linear interplation is used within a mipmap, but - * not between different mipmaps). */ - public static final int BILINEAR = 4; + /** Point sampling: both magnification and minification filtering are set + * to nearest */ + protected static final int POINT = 2; + /** Linear sampling: magnification filtering is nearest, minification set + * to linear */ + protected static final int LINEAR = 3; + /** Bilinear sampling: both magnification filtering is set to linear and + * minification either to linear-mipmap-nearest (linear interplation is used + * within a mipmap, but not between different mipmaps). */ + protected static final int BILINEAR = 4; /** Trilinear sampling: magnification filtering set to linear, minification to * linear-mipmap-linear, which offers the best mipmap quality since linear - * interpolation to compute the value in each of two maps and then interpolates linearly - * between these two value. */ - public static final int TRILINEAR = 5; + * interpolation to compute the value in each of two maps and then + * interpolates linearly between these two value. */ + protected static final int TRILINEAR = 5; public int width, height; @@ -119,8 +121,8 @@ public class Texture implements PConstants { /** - * Creates an instance of PTexture with size width x height and with the specified parameters. - * The texture is initialized (empty) to that size. + * Creates an instance of PTexture with size width x height and with the + * specified parameters. The texture is initialized (empty) to that size. * @param parent PApplet * @param width int * @param height int @@ -156,9 +158,9 @@ public class Texture implements PConstants { /** - * Sets the size of the image and texture to width x height. If the texture is already initialized, - * it first destroys the current OpenGL texture object and then creates a new one with the specified - * size. + * Sets the size of the image and texture to width x height. If the texture is + * already initialized, it first destroys the current OpenGL texture object + * and then creates a new one with the specified size. * @param width int * @param height int */ @@ -177,9 +179,10 @@ public class Texture implements PConstants { /** - * Sets the size of the image and texture to width x height, and the parameters of the texture to params. - * If the texture is already initialized, it first destroys the current OpenGL texture object and then creates - * a new one with the specified size. + * Sets the size of the image and texture to width x height, and the + * parameters of the texture to params. If the texture is already initialized, + * it first destroys the current OpenGL texture object and then creates a new + * one with the specified size. * @param width int * @param height int * @param params GLTextureParameters @@ -205,8 +208,8 @@ public class Texture implements PConstants { // Now, overwriting "this" with tex. copyObject(tex); - // Nullifying some utility objects so they are recreated with the appropriate - // size when needed. + // Nullifying some utility objects so they are recreated with the + // appropriate size when needed. tempFbo = null; } @@ -247,12 +250,14 @@ public class Texture implements PConstants { } - public void set(int texTarget, int texName, int texWidth, int texHeight, int w, int h) { + public void set(int texTarget, int texName, int texWidth, int texHeight, + int w, int h) { copyTexture(texTarget, texName, texWidth, texHeight, 0, 0, w, h, true); } - public void set(int texTarget, int texName, int texWidth, int texHeight, int target, int tex, int x, int y, int w, int h) { + public void set(int texTarget, int texName, int texWidth, int texHeight, + int target, int tex, int x, int y, int w, int h) { copyTexture(texTarget, texName, texWidth, texHeight, x, y, w, h, true); } @@ -279,7 +284,8 @@ public class Texture implements PConstants { return; } if (pixels.length != w * h) { - PGraphics.showWarning("The pixels array has a length of " + pixels.length + ", but it should be " + w * h); + PGraphics.showWarning("The pixels array has a length of " + + pixels.length + ", but it should be " + w * h); return; } @@ -300,7 +306,8 @@ public class Texture implements PConstants { // Automatic mipmap generation. int[] rgbaPixels = new int[w * h]; convertToRGBA(pixels, rgbaPixels, format, w, h); - pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE, IntBuffer.wrap(rgbaPixels)); + pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE, + IntBuffer.wrap(rgbaPixels)); pgl.generateMipmap(glTarget); rgbaPixels = null; } else { @@ -360,13 +367,15 @@ public class Texture implements PConstants { int[] rgbaPixels = new int[w * h]; convertToRGBA(pixels, rgbaPixels, format, w, h); - pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE, IntBuffer.wrap(rgbaPixels)); + pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE, + IntBuffer.wrap(rgbaPixels)); rgbaPixels = null; } } else { int[] rgbaPixels = new int[w * h]; convertToRGBA(pixels, rgbaPixels, format, w, h); - pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE, IntBuffer.wrap(rgbaPixels)); + pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE, + IntBuffer.wrap(rgbaPixels)); rgbaPixels = null; } @@ -401,7 +410,8 @@ public class Texture implements PConstants { return; } if (pixels.capacity() != w * h) { - PGraphics.showWarning("The pixels array has a length of " + pixels.capacity() + ", but it should be " + w * h); + PGraphics.showWarning("The pixels array has a length of " + + pixels.capacity() + ", but it should be " + w * h); return; } @@ -419,13 +429,16 @@ public class Texture implements PConstants { if (usingMipmaps) { if (PGraphicsOpenGL.autoMipmapGenSupported) { - pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE, pixels); + pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE, + pixels); pgl.generateMipmap(glTarget); } else { - pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE, pixels); + pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE, + pixels); } } else { - pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE, pixels); + pgl.texSubImage2D(glTarget, 0, x, y, w, h, PGL.RGBA, PGL.UNSIGNED_BYTE, + pixels); } pgl.bindTexture(glTarget, 0); @@ -450,15 +463,17 @@ public class Texture implements PConstants { throw new RuntimeException("Trying to copy texture to null pixels array"); } if (pixels.length != width * height) { - throw new RuntimeException("Trying to copy texture to pixels array of wrong size"); + throw new RuntimeException("Trying to copy texture to pixels array of " + + "wrong size"); } if (tempFbo == null) { tempFbo = new FrameBuffer(parent, glWidth, glHeight); } - // Attaching the texture to the color buffer of a FBO, binding the FBO and reading the pixels - // from the current draw buffer (which is the color buffer of the FBO). + // Attaching the texture to the color buffer of a FBO, binding the FBO and + // reading the pixels from the current draw buffer (which is the color + // buffer of the FBO). tempFbo.setColorBuffer(this); pg.pushFramebuffer(); pg.setFramebuffer(tempFbo); @@ -480,8 +495,8 @@ public class Texture implements PConstants { public void loadPixels(int[] pixels) { if (hasBuffers()) { // Updates the texture AND the pixels array of the image at the same time, - // getting the pixels directly from the buffer data (and thus avoiding expensive - // transfer between video and main memory). + // getting the pixels directly from the buffer data (and thus avoiding + // expensive transfer between video and main memory). bufferUpdate(pixels); } @@ -510,12 +525,14 @@ public class Texture implements PConstants { } - public void put(int texTarget, int texName, int texWidth, int texHeight, int w, int h) { + public void put(int texTarget, int texName, int texWidth, int texHeight, + int w, int h) { copyTexture(texTarget, texName, texWidth, texHeight, 0, 0, w, h, false); } - public void put(int texTarget, int texName, int texWidth, int texHeight, int target, int tex, int x, int y, int w, int h) { + public void put(int texTarget, int texName, int texWidth, int texHeight, + int target, int tex, int x, int y, int w, int h) { copyTexture(texTarget, texName, texWidth, texHeight, x, y, w, h, false); } @@ -536,19 +553,23 @@ public class Texture implements PConstants { public void usingMipmaps(boolean mipmaps, int sampling) { if (mipmaps) { - if (glMinFilter != PGL.LINEAR_MIPMAP_NEAREST && glMinFilter != PGL.LINEAR_MIPMAP_LINEAR) { + if (glMinFilter != PGL.LINEAR_MIPMAP_NEAREST && + glMinFilter != PGL.LINEAR_MIPMAP_LINEAR) { if (sampling == POINT) { glMagFilter = PGL.NEAREST; glMinFilter = PGL.NEAREST; } else if (sampling == LINEAR) { glMagFilter = PGL.NEAREST; - glMinFilter = PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR; + glMinFilter = + PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR; } else if (sampling == BILINEAR) { glMagFilter = PGL.LINEAR; - glMinFilter = PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR; + glMinFilter = + PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR; } else if (sampling == TRILINEAR) { glMagFilter = PGL.LINEAR; - glMinFilter = PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_LINEAR : PGL.LINEAR; + glMinFilter = + PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_LINEAR : PGL.LINEAR; } else { throw new RuntimeException("Unknown texture filtering mode"); } @@ -556,7 +577,8 @@ public class Texture implements PConstants { usingMipmaps = true; } else { - if (glMinFilter == PGL.LINEAR_MIPMAP_NEAREST || glMinFilter == PGL.LINEAR_MIPMAP_LINEAR) { + if (glMinFilter == PGL.LINEAR_MIPMAP_NEAREST || + glMinFilter == PGL.LINEAR_MIPMAP_LINEAR) { glMinFilter = PGL.LINEAR; } usingMipmaps = false; @@ -605,7 +627,8 @@ public class Texture implements PConstants { /** - * Returns the maximum possible value for the texture coordinate U (horizontal). + * Returns the maximum possible value for the texture coordinate U + * (horizontal). * @return float */ public float getMaxU() { @@ -783,7 +806,8 @@ public class Texture implements PConstants { } - public void copyBufferFromSource(Object natRef, ByteBuffer byteBuf, int w, int h) { + public void copyBufferFromSource(Object natRef, ByteBuffer byteBuf, + int w, int h) { if (bufferCache == null) { bufferCache = new LinkedList(); } @@ -791,7 +815,8 @@ public class Texture implements PConstants { if (bufferCache.size() + 1 <= MAX_BUFFER_CACHE_SIZE) { bufferCache.add(new BufferData(natRef, byteBuf.asIntBuffer(), w, h)); } else { - // The buffer cache reached the maximum size, so we just dispose the new buffer. + // The buffer cache reached the maximum size, so we just dispose + // the new buffer. try { disposeBufferMethod.invoke(bufferSource, new Object[] { natRef }); } catch (Exception e) { @@ -807,7 +832,8 @@ public class Texture implements PConstants { public boolean hasBuffers() { - return bufferSource != null && bufferCache != null && 0 < bufferCache.size(); + return bufferSource != null && bufferCache != null && + 0 < bufferCache.size(); } @@ -862,9 +888,11 @@ public class Texture implements PConstants { protected void getSourceMethods() { try { - disposeBufferMethod = bufferSource.getClass().getMethod("disposeBuffer", new Class[] { Object.class }); + disposeBufferMethod = bufferSource.getClass(). + getMethod("disposeBuffer", new Class[] { Object.class }); } catch (Exception e) { - throw new RuntimeException("Provided source object doesn't have a disposeBuffer method."); + throw new RuntimeException("Provided source object doesn't have a " + + "disposeBuffer method."); } } @@ -926,16 +954,17 @@ public class Texture implements PConstants { /** - * Reorders a pixel array in the given format into the order required by OpenGL (RGBA). - * Both arrays are assumed to be of the same length. The width and height parameters - * are used in the YUV420 to RBGBA conversion. + * Reorders a pixel array in the given format into the order required by + * OpenGL (RGBA). Both arrays are assumed to be of the same length. The width + * and height parameters are used in the YUV420 to RBGBA conversion. * @param intArray int[] * @param tIntArray int[] * @param arrayFormat int * @param w int * @param h int */ - protected void convertToRGBA(int[] intArray, int[] tIntArray, int arrayFormat, int w, int h) { + protected void convertToRGBA(int[] intArray, int[] tIntArray, int arrayFormat, + int w, int h) { if (PGL.BIG_ENDIAN) { switch (arrayFormat) { case ALPHA: @@ -1012,61 +1041,7 @@ public class Texture implements PConstants { } } - - /** - * Reorders a pixel array in a given format into ARGB. The input array must be - * of size width * height, while the output array must be of glWidth * glHeight. - * @param intArray int[] - * @param intArray int[] - * @param arrayFormat int - */ - /* - protected void convertToARGB(int[] intArray, int[] tIntArray, int arrayFormat) { - int t = 0; - int p = 0; - int pixel; - - switch (arrayFormat) { - case ALPHA: - - // xxxA to ARGB, setting RGB to black. - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - pixel = intArray[p++]; - tIntArray[t++] = (pixel << 24) & 0xFF000000; - } - t += glWidth - width; - } - - break; - - case RGB: - - // xRGB to ARGB, setting A to be 0xFF. - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - pixel = intArray[p++]; - tIntArray[t++] = pixel | 0xFF000000; - } - t += glWidth - width; - } - - break; - - case ARGB: - - // ARGB to ARGB, where the source is smaller than the destination. - for (int y = 0; y < height; y++) { - PApplet.arrayCopy(intArray, width * y, tIntArray, glWidth * y, width); - } - - break; - - } - - } -*/ /** * Reorders an OpenGL pixel array (RGBA) into ARGB. The array must be @@ -1122,17 +1097,20 @@ public class Texture implements PConstants { glHeight = PGL.nextPowerOfTwo(h); } - if ((glWidth > PGraphicsOpenGL.maxTextureSize) || (glHeight > PGraphicsOpenGL.maxTextureSize)) { + if (glWidth > PGraphicsOpenGL.maxTextureSize || + glHeight > PGraphicsOpenGL.maxTextureSize) { glWidth = glHeight = 0; throw new RuntimeException("Image width and height cannot be" + - " larger than " + PGraphicsOpenGL.maxTextureSize + + " larger than " + + PGraphicsOpenGL.maxTextureSize + " with this graphics card."); } - // If non-power-of-two textures are not supported, and the specified width or height - // is non-power-of-two, then glWidth (glHeight) will be greater than w (h) because it - // is chosen to be the next power of two, and this quotient will give the appropriate - // maximum texture coordinate value given this situation. + // If non-power-of-two textures are not supported, and the specified width + // or height is non-power-of-two, then glWidth (glHeight) will be greater + // than w (h) because it is chosen to be the next power of two, and this + // quotient will give the appropriate maximum texture coordinate value given + // this situation. maxTexcoordU = (float)width / glWidth; maxTexcoordV = (float)height / glHeight; } @@ -1159,11 +1137,14 @@ public class Texture implements PConstants { pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_S, glWrapS); pgl.texParameteri(glTarget, PGL.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.texImage2D(glTarget, 0, glFormat, glWidth, glHeight, 0, PGL.RGBA, PGL.UNSIGNED_BYTE, null); + // 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.texImage2D(glTarget, 0, glFormat, glWidth, glHeight, 0, + PGL.RGBA, PGL.UNSIGNED_BYTE, null); - // Makes sure that the texture buffer in video memory doesn't contain any garbage. + // Makes sure that the texture buffer in video memory doesn't contain + // any garbage. pgl.initTexture(glTarget, PGL.RGBA, width, height); pgl.bindTexture(glTarget, 0); @@ -1207,7 +1188,8 @@ public class Texture implements PConstants { // Copies source texture tex into this. - protected void copyTexture(Texture tex, int x, int y, int w, int h, boolean scale) { + protected void copyTexture(Texture tex, int x, int y, int w, int h, + boolean scale) { if (tex == null) { throw new RuntimeException("Source texture is null"); } @@ -1242,7 +1224,9 @@ public class Texture implements PConstants { // Copies source texture tex into this. - protected void copyTexture(int texTarget, int texName, int texWidth, int texHeight, int x, int y, int w, int h, boolean scale) { + protected void copyTexture(int texTarget, int texName, + int texWidth, int texHeight, + int x, int y, int w, int h, boolean scale) { if (tempFbo == null) { tempFbo = new FrameBuffer(parent, glWidth, glHeight); } @@ -1273,8 +1257,8 @@ public class Texture implements PConstants { protected void copyObject(Texture src) { - // The OpenGL texture of this object is replaced with the one from the source object, - // so we delete the former to avoid resource wasting. + // The OpenGL texture of this object is replaced with the one from the + // source object, so we delete the former to avoid resource wasting. release(); width = src.width; @@ -1328,16 +1312,19 @@ public class Texture implements PConstants { } else if (glMagFilter == PGL.NEAREST && glMinFilter == PGL.LINEAR) { res.sampling = LINEAR; res.mipmaps = false; - } else if (glMagFilter == PGL.NEAREST && glMinFilter == PGL.LINEAR_MIPMAP_NEAREST) { + } else if (glMagFilter == PGL.NEAREST && + glMinFilter == PGL.LINEAR_MIPMAP_NEAREST) { res.sampling = LINEAR; res.mipmaps = true; } else if (glMagFilter == PGL.LINEAR && glMinFilter == PGL.LINEAR) { res.sampling = BILINEAR; res.mipmaps = false; - } else if (glMagFilter == PGL.LINEAR && glMinFilter == PGL.LINEAR_MIPMAP_NEAREST) { + } else if (glMagFilter == PGL.LINEAR && + glMinFilter == PGL.LINEAR_MIPMAP_NEAREST) { res.sampling = BILINEAR; res.mipmaps = true; - } else if (glMagFilter == PGL.LINEAR && glMinFilter == PGL.LINEAR_MIPMAP_LINEAR) { + } else if (glMagFilter == PGL.LINEAR && + glMinFilter == PGL.LINEAR_MIPMAP_LINEAR) { res.sampling = TRILINEAR; res.mipmaps = true; } @@ -1359,7 +1346,8 @@ public class Texture implements PConstants { /** - * Sets texture target and internal format according to the target and type specified. + * Sets texture target and internal format according to the target and + * type specified. * @param target int * @param params GLTextureParameters */ @@ -1385,13 +1373,16 @@ public class Texture implements PConstants { glMinFilter = PGL.NEAREST; } else if (params.sampling == LINEAR) { glMagFilter = PGL.NEAREST; - glMinFilter = params.mipmaps && PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR; + glMinFilter = params.mipmaps && PGL.MIPMAPS_ENABLED ? + PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR; } else if (params.sampling == BILINEAR) { glMagFilter = PGL.LINEAR; - glMinFilter = params.mipmaps && PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR; + glMinFilter = params.mipmaps && PGL.MIPMAPS_ENABLED ? + PGL.LINEAR_MIPMAP_NEAREST : PGL.LINEAR; } else if (params.sampling == TRILINEAR) { glMagFilter = PGL.LINEAR; - glMinFilter = params.mipmaps && PGL.MIPMAPS_ENABLED ? PGL.LINEAR_MIPMAP_LINEAR : PGL.LINEAR; + glMinFilter = params.mipmaps && PGL.MIPMAPS_ENABLED ? + PGL.LINEAR_MIPMAP_LINEAR : PGL.LINEAR; } else { throw new RuntimeException("Unknown texture filtering mode"); } @@ -1428,8 +1419,8 @@ public class Texture implements PConstants { /** - * This class stores the parameters for a texture: target, internal format, minimization filter - * and magnification filter. + * This class stores the parameters for a texture: target, internal format, + * minimization filter and magnification filter. */ static public class Parameters { /** diff --git a/core/src/processing/core/PConstants.java b/core/src/processing/core/PConstants.java index 1a175a484..37d132d14 100644 --- a/core/src/processing/core/PConstants.java +++ b/core/src/processing/core/PConstants.java @@ -510,8 +510,8 @@ public interface PConstants { // hints - hint values are positive for the alternate version, // negative of the same value returns to the normal/default state - static final int ENABLE_NATIVE_FONTS = 1; - static final int DISABLE_NATIVE_FONTS = -1; + static final int ENABLE_NATIVE_FONTS = 1; + static final int DISABLE_NATIVE_FONTS = -1; static final int DISABLE_DEPTH_TEST = 2; static final int ENABLE_DEPTH_TEST = -2; @@ -543,7 +543,7 @@ public interface PConstants { static final int DISABLE_TEXTURE_MIPMAPS = 11; static final int ENABLE_TEXTURE_MIPMAPS = -11; - static final int HINT_COUNT = 12; + static final int HINT_COUNT = 12; // error messages diff --git a/core/src/processing/opengl/PGL.java b/core/src/processing/opengl/PGL.java index c78b06ae9..d7227ac5b 100644 --- a/core/src/processing/opengl/PGL.java +++ b/core/src/processing/opengl/PGL.java @@ -186,11 +186,10 @@ public class PGL { public static final int FUNC_MAX = GL2.GL_MAX; public static final int FUNC_REVERSE_SUBTRACT = GL.GL_FUNC_REVERSE_SUBTRACT; - public static final int TEXTURE_2D = GL.GL_TEXTURE_2D; - public static final int TEXTURE_RECTANGLE = GL2.GL_TEXTURE_RECTANGLE; + public static final int TEXTURE_2D = GL.GL_TEXTURE_2D; + public static final int TEXTURE_RECTANGLE = GL2.GL_TEXTURE_RECTANGLE; - public static final int TEXTURE_BINDING_2D = - GL.GL_TEXTURE_BINDING_2D; + public static final int TEXTURE_BINDING_2D = GL.GL_TEXTURE_BINDING_2D; public static final int TEXTURE_BINDING_RECTANGLE = GL2.GL_TEXTURE_BINDING_RECTANGLE; @@ -228,21 +227,21 @@ public class PGL { public static final int SAMPLES = GL.GL_SAMPLES; - public static final int FRAMEBUFFER_COMPLETE = + public static final int FRAMEBUFFER_COMPLETE = GL.GL_FRAMEBUFFER_COMPLETE; - public static final int FRAMEBUFFER_INCOMPLETE_ATTACHMENT = + 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 = + public static final int FRAMEBUFFER_INCOMPLETE_DIMENSIONS = GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; - public static final int FRAMEBUFFER_INCOMPLETE_FORMATS = + public static final int FRAMEBUFFER_INCOMPLETE_FORMATS = GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS; - public static final int FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = + public static final int FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = GL2.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER; - public static final int FRAMEBUFFER_INCOMPLETE_READ_BUFFER = + public static final int FRAMEBUFFER_INCOMPLETE_READ_BUFFER = GL2.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER; - public static final int FRAMEBUFFER_UNSUPPORTED = + public static final int FRAMEBUFFER_UNSUPPORTED = GL.GL_FRAMEBUFFER_UNSUPPORTED; public static final int STATIC_DRAW = GL.GL_STATIC_DRAW; @@ -257,29 +256,21 @@ public class PGL { public static final int TRIANGLE_STRIP = GL.GL_TRIANGLE_STRIP; public static final int TRIANGLES = GL.GL_TRIANGLES; - public static final int VENDOR = - GL.GL_VENDOR; - public static final int RENDERER = - GL.GL_RENDERER; - public static final int VERSION = - GL.GL_VERSION; - public static final int EXTENSIONS = - GL.GL_EXTENSIONS; + public static final int VENDOR = GL.GL_VENDOR; + public static final int RENDERER = GL.GL_RENDERER; + public static final int VERSION = GL.GL_VERSION; + public static final int EXTENSIONS = GL.GL_EXTENSIONS; public static final int SHADING_LANGUAGE_VERSION = GL2ES2.GL_SHADING_LANGUAGE_VERSION; - public static final int MAX_TEXTURE_SIZE = - GL.GL_MAX_TEXTURE_SIZE; - public static final int MAX_SAMPLES = - GL2.GL_MAX_SAMPLES; + public static final int MAX_TEXTURE_SIZE = GL.GL_MAX_TEXTURE_SIZE; + public static final int MAX_SAMPLES = GL2.GL_MAX_SAMPLES; public static final int ALIASED_LINE_WIDTH_RANGE = GL.GL_ALIASED_LINE_WIDTH_RANGE; public static final int ALIASED_POINT_SIZE_RANGE = GL.GL_ALIASED_POINT_SIZE_RANGE; - public static final int DEPTH_BITS = - GL.GL_DEPTH_BITS; - public static final int STENCIL_BITS = - GL.GL_STENCIL_BITS; + public static final int DEPTH_BITS = GL.GL_DEPTH_BITS; + public static final int STENCIL_BITS = GL.GL_STENCIL_BITS; public static final int TESS_WINDING_NONZERO = GLU.GLU_TESS_WINDING_NONZERO; public static final int TESS_WINDING_ODD = GLU.GLU_TESS_WINDING_ODD; @@ -390,7 +381,7 @@ public class PGL { /** Which textures are bound to each target */ protected static int[] boundTextures = { 0, 0 }; - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // FBO for anti-aliased rendering @@ -411,7 +402,7 @@ public class PGL { protected int[] glStencilBuffer = { 0 }; protected int contextHashCode; - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Texture rendering @@ -465,7 +456,7 @@ public class PGL { " gl_FragColor = texture2DRect(textureSampler, vertTexcoord.st);" + "}"; - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // 1-pixel color, depth, stencil buffers @@ -474,9 +465,9 @@ public class PGL { protected ByteBuffer stencilBuffer; - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// - // Intialization, finalization + // Initialization, finalization public PGL(PGraphicsOpenGL pg) { @@ -885,7 +876,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Frame rendering @@ -998,7 +989,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Enable/disable caps @@ -1017,7 +1008,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Render control @@ -1032,7 +1023,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Error handling @@ -1047,7 +1038,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Rendering options @@ -1072,7 +1063,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Textures @@ -1134,7 +1125,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Vertex Buffers @@ -1216,7 +1207,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Framebuffers, renderbuffers @@ -1293,7 +1284,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Shaders @@ -1531,7 +1522,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Viewport @@ -1541,7 +1532,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Clipping (scissor test) @@ -1551,7 +1542,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Blending @@ -1566,7 +1557,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Pixels @@ -1616,7 +1607,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Context interface @@ -1666,7 +1657,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Tessellator interface @@ -1755,7 +1746,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Utility functions @@ -2487,7 +2478,7 @@ public class PGL { } - ////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// // Java specific stuff diff --git a/core/src/processing/opengl/PShape3D.java b/core/src/processing/opengl/PShape3D.java index f29277568..4134e9559 100644 --- a/core/src/processing/opengl/PShape3D.java +++ b/core/src/processing/opengl/PShape3D.java @@ -75,6 +75,5 @@ public class PShape3D extends PShapeOpenGL { PShape c = PShape3D.createShape(parent, src.getChild(i)); dest.addChild(c); } - } - + } }