diff --git a/android/core/src/processing/core/FillShaderFragTex.glsl b/android/core/src/processing/core/FillShaderFragTex.glsl index b8e65128b..43c88f772 100644 --- a/android/core/src/processing/core/FillShaderFragTex.glsl +++ b/android/core/src/processing/core/FillShaderFragTex.glsl @@ -23,9 +23,13 @@ precision mediump float; uniform sampler2D textureSampler; +uniform vec2 texcoordScale; +uniform vec2 texcoordOffset; + varying vec4 vertColor; varying vec2 vertTexcoord; void main() { - gl_FragColor = texture2D(textureSampler, vertTexcoord) * vertColor; + vec2 uv = vertTexcoord * texcoordScale + texcoordOffset; + gl_FragColor = texture2D(textureSampler, uv) * vertColor; } \ No newline at end of file diff --git a/android/core/src/processing/core/PGL.java b/android/core/src/processing/core/PGL.java index b0fc1ce75..faed9f0d1 100644 --- a/android/core/src/processing/core/PGL.java +++ b/android/core/src/processing/core/PGL.java @@ -402,11 +402,11 @@ public class PGL { // very large transient array which in certain situations (memory- // constrained android devices) might lead to an out-of-memory error. int[] texels = new int[16 * 16]; - for (int y = 0; y < height + 16; y += 16) { + for (int y = 0; y < height; y += 16) { int h = PApplet.min(16, height - y); - for (int x = 0; x < width + 16; x += 16) { + for (int x = 0; x < width; x += 16) { int w = PApplet.min(16, width - x); - gl.glTexSubImage2D(target, 0, x, y, w, h, format, type, IntBuffer.wrap(texels)); + GLES20.glTexSubImage2D(target, 0, x, y, w, h, format, type, IntBuffer.wrap(texels)); } } } diff --git a/android/core/src/processing/core/PGraphicsAndroid3D.java b/android/core/src/processing/core/PGraphicsAndroid3D.java index 6507d7dfb..2bcd2b201 100644 --- a/android/core/src/processing/core/PGraphicsAndroid3D.java +++ b/android/core/src/processing/core/PGraphicsAndroid3D.java @@ -2038,13 +2038,8 @@ public class PGraphicsAndroid3D extends PGraphics { } if (textured && textureMode == IMAGE) { - u /= textureImage.width; - v /= textureImage.height; - - PTexture tex = queryTexture(textureImage); - if (tex != null && tex.isFlippedY()) { - v = 1 - v; - } + u = PApplet.min(1, u / textureImage.width); + v = PApplet.min(1, v / textureImage.height); } inGeo.addVertex(x, y, z, @@ -2268,10 +2263,10 @@ public class PGraphicsAndroid3D extends PGraphics { pgl.glBufferData(PGL.GL_ELEMENT_ARRAY_BUFFER, tessGeo.fillIndexCount * PGL.SIZEOF_INDEX, ShortBuffer.wrap(tessGeo.fillIndices, 0, tessGeo.fillIndexCount), vboMode); - texCache.beginRender(); - for (int i = 0; i < texCache.count; i++) { - PTexture tex = texCache.getTexture(i); - + texCache.beginRender(); + for (int i = 0; i < texCache.count; i++) { + PTexture tex = texCache.getTexture(i); + FillShader shader = getFillShader(lights, tex != null); shader.start(); @@ -2286,8 +2281,9 @@ public class PGraphicsAndroid3D extends PGraphics { shader.setShininessAttribute(glFillShininessBufferID, 1, PGL.GL_FLOAT, 0, 0); } - if (tex != null) { - shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0); + if (tex != null) { + shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0); + shader.setTexture(tex); } int offset = texCache.firstIndex[i]; @@ -2303,7 +2299,7 @@ public class PGraphicsAndroid3D extends PGraphics { // Utility function to render current tessellated geometry, under the assumption that // the texture is already bound. - protected void renderTexFill() { + protected void renderTexFill(PTexture tex) { if (!fillVBOsCreated) { createFillBuffers(); fillVBOsCreated = true; @@ -2316,6 +2312,7 @@ public class PGraphicsAndroid3D extends PGraphics { shader.setVertexAttribute(glFillVertexBufferID, 3, PGL.GL_FLOAT, 0, 0); shader.setColorAttribute(glFillColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0); + shader.setTexture(tex); if (lights) { shader.setNormalAttribute(glFillNormalBufferID, 3, PGL.GL_FLOAT, 0, 0); @@ -5214,7 +5211,7 @@ public class PGraphicsAndroid3D extends PGraphics { public PTexture getTexture(PImage img) { PTexture tex = (PTexture)img.getCache(pg); if (tex == null) { - tex = addTexture(img); + tex = addTexture(img); } else { if (!pgl.contextIsCurrent(tex.context)) { // The texture was created with a different context. We need @@ -5265,10 +5262,10 @@ public class PGraphicsAndroid3D extends PGraphics { params = PTexture.newParameters(); img.setParams(pg, params); } - PTexture tex = new PTexture(img.parent, img.width, img.height, params); + PTexture tex = new PTexture(img.parent, img.width, img.height, params); img.loadPixels(); - if (img.pixels != null) tex.set(img.pixels); - img.setCache(pg, tex); + if (img.pixels != null) tex.set(img.pixels); + img.setCache(pg, tex); return tex; } @@ -5400,7 +5397,7 @@ public class PGraphicsAndroid3D extends PGraphics { * Pushes a normalized (1x1) textured quad to the GPU. */ protected void drawTexQuad(float u0, float v0, float u1, float v1) { - // TODO: need to test... + // TODO: need to fix null thing, test... stroke = false; beginShape(QUAD); vertex(0, 0, u0, v0); @@ -5409,7 +5406,7 @@ public class PGraphicsAndroid3D extends PGraphics { vertex(0, 1, u0, v1); endShape(); tessellate(OPEN); - renderTexFill(); + renderTexFill(null); // we need the texture object here... } @@ -5708,7 +5705,8 @@ public class PGraphicsAndroid3D extends PGraphics { 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 setTexCoordAttribute(int vboId, int size, int type, int stride, int offset) { } + public void setTexture(PTexture tex) { } } protected class FillShaderSimple extends FillShader { @@ -5895,8 +5893,13 @@ public class PGraphicsAndroid3D extends PGraphics { } protected class FillShaderTex extends FillShaderSimple { + protected int texcoordScaleLoc; + protected int texcoordOffsetLoc; + protected int inTexcoordLoc; + PTexture texture; + public FillShaderTex(PApplet parent, String vertFilename, String fragFilename) { super(parent, vertFilename, fragFilename); } @@ -5905,6 +5908,13 @@ public class PGraphicsAndroid3D extends PGraphics { super(parent, vertURL, fragURL); } + public void loadUniforms() { + super.loadUniforms(); + + texcoordScaleLoc = getUniformLocation("texcoordScale"); + texcoordOffsetLoc = getUniformLocation("texcoordOffset"); + } + public void loadAttributes() { super.loadAttributes(); @@ -5915,6 +5925,26 @@ public class PGraphicsAndroid3D extends PGraphics { setAttribute(inTexcoordLoc, vboId, size, type, false, stride, offset); } + public void setTexture(PTexture tex) { + texture = tex; + + // Calculate scale and offset for texture coordinates + // and passing them to the fragment shader. + + float scaleu = tex.maxTexCoordU; + float scalev = tex.maxTexCoordV; + float offsetu = 0; + float offsetv = 0; + + if (tex.isFlippedY()) { + scalev *= -1; + offsetv = 1; + } + + set2FloatUniform(texcoordScaleLoc, scaleu, scalev); + set2FloatUniform(texcoordOffsetLoc, offsetu, offsetv); + } + public void start() { super.start(); @@ -5931,6 +5961,9 @@ public class PGraphicsAndroid3D extends PGraphics { protected class FillShaderFull extends FillShaderLit { protected int inTexcoordLoc; + protected int texcoordScaleLoc; + protected int texcoordOffsetLoc; + public FillShaderFull(PApplet parent, String vertFilename, String fragFilename) { super(parent, vertFilename, fragFilename); } @@ -5938,6 +5971,13 @@ public class PGraphicsAndroid3D extends PGraphics { public FillShaderFull(PApplet parent, URL vertURL, URL fragURL) { super(parent, vertURL, fragURL); } + + public void loadUniforms() { + super.loadUniforms(); + + texcoordScaleLoc = getUniformLocation("texcoordScale"); + texcoordOffsetLoc = getUniformLocation("texcoordOffset"); + } public void loadAttributes() { super.loadAttributes(); @@ -5949,6 +5989,26 @@ public class PGraphicsAndroid3D extends PGraphics { setAttribute(inTexcoordLoc, vboId, size, type, false, stride, offset); } + public void setTexture(PTexture tex) { + texture = tex; + + // Calculate scale and offset for texture coordinates + // and passing them to the fragment shader. + + float scaleu = tex.maxTexCoordU; + float scalev = tex.maxTexCoordV; + float offsetu = 0; + float offsetv = 0; + + if (tex.isFlippedY()) { + scalev *= -1; + offsetv = 1; + } + + set2FloatUniform(texcoordScaleLoc, scaleu, scalev); + set2FloatUniform(texcoordOffsetLoc, offsetu, offsetv); + } + public void start() { super.start(); diff --git a/android/core/src/processing/core/PShader.java b/android/core/src/processing/core/PShader.java index 7c95f415c..1265f1dcc 100644 --- a/android/core/src/processing/core/PShader.java +++ b/android/core/src/processing/core/PShader.java @@ -158,82 +158,114 @@ public class PShader { public void setIntUniform(int loc, int x) { - pgl.glUniform1i(loc, x); + if (-1 < loc) { + pgl.glUniform1i(loc, x); + } } public void set1FloatUniform(int loc, float x) { - pgl.glUniform1f(loc, x); + if (-1 < loc) { + pgl.glUniform1f(loc, x); + } } public void set2FloatUniform(int loc, float x, float y) { - pgl.glUniform2f(loc, x, y); + if (-1 < loc) { + pgl.glUniform2f(loc, x, y); + } } public void set3FloatUniform(int loc, float x, float y, float z) { - pgl.glUniform3f(loc, x, y, z); + if (-1 < loc) { + pgl.glUniform3f(loc, x, y, z); + } } public void set4FloatUniform(int loc, float x, float y, float z, float w) { - pgl.glUniform4f(loc, x, y, z, w); + if (-1 < loc) { + pgl.glUniform4f(loc, x, y, z, w); + } } public void set1FloatVecUniform(int loc, float[] vec) { - pgl.glUniform1fv(loc, vec.length, vec, 0); + if (-1 < loc) { + pgl.glUniform1fv(loc, vec.length, vec, 0); + } } public void set2FloatVecUniform(int loc, float[] vec) { - pgl.glUniform2fv(loc, vec.length / 2, vec, 0); + if (-1 < loc) { + pgl.glUniform2fv(loc, vec.length / 2, vec, 0); + } } public void set3FloatVecUniform(int loc, float[] vec) { - pgl.glUniform3fv(loc, vec.length / 3, vec, 0); + if (-1 < loc) { + pgl.glUniform3fv(loc, vec.length / 3, vec, 0); + } } public void set4FloatVecUniform(int loc, float[] vec) { - pgl.glUniform4fv(loc, vec.length / 4, vec, 0); + if (-1 < loc) { + pgl.glUniform4fv(loc, vec.length / 4, vec, 0); + } } public void set2x2MatUniform(int loc, float[] mat) { - pgl.glUniformMatrix2fv(loc, 1, false, mat, 0); + if (-1 < loc) { + pgl.glUniformMatrix2fv(loc, 1, false, mat, 0); + } } public void set3x3MatUniform(int loc, float[] mat) { - pgl.glUniformMatrix3fv(loc, 1, false, mat, 0); + if (-1 < loc) { + pgl.glUniformMatrix3fv(loc, 1, false, mat, 0); + } } public void set4x4MatUniform(int loc, float[] mat) { - pgl.glUniformMatrix4fv(loc, 1, false, mat, 0); + if (-1 < loc) { + pgl.glUniformMatrix4fv(loc, 1, false, mat, 0); + } } public void set1FloatAttribute(int loc, float x) { - pgl.glVertexAttrib1f(loc, x); + if (-1 < loc) { + pgl.glVertexAttrib1f(loc, x); + } } public void set2FloatAttribute(int loc, float x, float y) { - pgl.glVertexAttrib2f(loc, x, y); + if (-1 < loc) { + pgl.glVertexAttrib2f(loc, x, y); + } } public void set3FloatAttribute(int loc, float x, float y, float z) { - pgl.glVertexAttrib3f(loc, x, y, z); + if (-1 < loc) { + pgl.glVertexAttrib3f(loc, x, y, z); + } } public void set4FloatAttribute(int loc, float x, float y, float z, float w) { - pgl.glVertexAttrib4f(loc, x, y, z, w); + if (-1 < loc) { + pgl.glVertexAttrib4f(loc, x, y, z, w); + } } diff --git a/android/core/src/processing/core/PShape3D.java b/android/core/src/processing/core/PShape3D.java index 6d2a873bb..c5bf03c11 100644 --- a/android/core/src/processing/core/PShape3D.java +++ b/android/core/src/processing/core/PShape3D.java @@ -610,13 +610,8 @@ public class PShape3D extends PShape { } if (texture != null && textureMode == IMAGE) { - u /= texture.width; - v /= texture.height; - - PTexture tex = pg.queryTexture(texture); - if (tex != null && tex.isFlippedY()) { - v = 1 - v; - } + u = PApplet.min(1, u / texture.width); + v = PApplet.min(1, v / texture.height); } int scolor = 0x00; diff --git a/android/core/src/processing/core/PTexture.java b/android/core/src/processing/core/PTexture.java index 00c3b0060..6974de362 100644 --- a/android/core/src/processing/core/PTexture.java +++ b/android/core/src/processing/core/PTexture.java @@ -775,19 +775,19 @@ public class PTexture implements PConstants { pgl.glBindTexture(glTarget, glID); pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_MIN_FILTER, glMinFilter); - pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_MAG_FILTER, glMagFilter); + pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_MAG_FILTER, glMagFilter); pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_WRAP_S, glWrapS); - pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_WRAP_T, glWrapT); + pgl.glTexParameterf(glTarget, PGL.GL_TEXTURE_WRAP_T, glWrapT); // First, we use glTexImage2D to set the full size of the texture (glW/glH might be diff // from w/h in the case that the GPU doesn't support NPOT textures) pgl.glTexImage2D(glTarget, 0, glFormat, glWidth, glHeight, 0, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, null); // Makes sure that the texture buffer in video memory doesn't contain any garbage. - pgl.initTexture(glTarget, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE); + pgl.initTexture(glTarget, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE); pgl.glBindTexture(glTarget, 0); - pgl.disableTexturing(glTarget); + pgl.disableTexturing(glTarget); } diff --git a/java/libraries/opengl/src/processing/opengl/FillShaderFragTex.glsl b/java/libraries/opengl/src/processing/opengl/FillShaderFragTex.glsl index ec310871e..41f6cfa5d 100644 --- a/java/libraries/opengl/src/processing/opengl/FillShaderFragTex.glsl +++ b/java/libraries/opengl/src/processing/opengl/FillShaderFragTex.glsl @@ -21,9 +21,13 @@ uniform sampler2D textureSampler; +uniform vec2 texcoordScale; +uniform vec2 texcoordOffset; + varying vec4 vertColor; varying vec2 vertTexcoord; void main() { - gl_FragColor = texture2D(textureSampler, vertTexcoord) * vertColor; + vec2 uv = vertTexcoord * texcoordScale + texcoordOffset; + gl_FragColor = texture2D(textureSampler, uv) * vertColor; } \ No newline at end of file diff --git a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java index df69f03a1..b66ad7960 100644 --- a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java +++ b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java @@ -2044,13 +2044,8 @@ public class PGraphicsOpenGL extends PGraphics { } if (textured && textureMode == IMAGE) { - u /= textureImage.width; - v /= textureImage.height; - - PTexture tex = queryTexture(textureImage); - if (tex != null && tex.isFlippedY()) { - v = 1 - v; - } + u = PApplet.min(1, u / textureImage.width); + v = PApplet.min(1, v / textureImage.height); } inGeo.addVertex(x, y, z, @@ -2293,7 +2288,8 @@ public class PGraphicsOpenGL extends PGraphics { } if (tex != null) { - shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0); + shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0); + shader.setTexture(tex); } int offset = texCache.firstIndex[i]; @@ -2309,7 +2305,7 @@ public class PGraphicsOpenGL extends PGraphics { // Utility function to render current tessellated geometry, under the assumption that // the texture is already bound. - protected void renderTexFill() { + protected void renderTexFill(PTexture tex) { if (!fillVBOsCreated) { createFillBuffers(); fillVBOsCreated = true; @@ -2322,6 +2318,7 @@ public class PGraphicsOpenGL extends PGraphics { shader.setVertexAttribute(glFillVertexBufferID, 3, PGL.GL_FLOAT, 0, 0); shader.setColorAttribute(glFillColorBufferID, 4, PGL.GL_UNSIGNED_BYTE, 0, 0); shader.setTexCoordAttribute(glFillTexCoordBufferID, 2, PGL.GL_FLOAT, 0, 0); + shader.setTexture(tex); if (lights) { shader.setNormalAttribute(glFillNormalBufferID, 3, PGL.GL_FLOAT, 0, 0); @@ -5406,7 +5403,7 @@ public class PGraphicsOpenGL extends PGraphics { * Pushes a normalized (1x1) textured quad to the GPU. */ protected void drawTexQuad(float u0, float v0, float u1, float v1) { - // TODO: need to test... + // TODO: need to fix null thing, test... stroke = false; beginShape(QUAD); vertex(0, 0, u0, v0); @@ -5415,7 +5412,7 @@ public class PGraphicsOpenGL extends PGraphics { vertex(0, 1, u0, v1); endShape(); tessellate(OPEN); - renderTexFill(); + renderTexFill(null); // we need the texture object here... } @@ -5714,7 +5711,8 @@ public class PGraphicsOpenGL extends PGraphics { 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 setTexCoordAttribute(int vboId, int size, int type, int stride, int offset) { } + public void setTexture(PTexture tex) { } } protected class FillShaderSimple extends FillShader { @@ -5902,8 +5900,13 @@ public class PGraphicsOpenGL extends PGraphics { } protected class FillShaderTex extends FillShaderSimple { + protected int texcoordScaleLoc; + protected int texcoordOffsetLoc; + protected int inTexcoordLoc; + PTexture texture; + public FillShaderTex(PApplet parent, String vertFilename, String fragFilename) { super(parent, vertFilename, fragFilename); } @@ -5912,6 +5915,13 @@ public class PGraphicsOpenGL extends PGraphics { super(parent, vertURL, fragURL); } + public void loadUniforms() { + super.loadUniforms(); + + texcoordScaleLoc = getUniformLocation("texcoordScale"); + texcoordOffsetLoc = getUniformLocation("texcoordOffset"); + } + public void loadAttributes() { super.loadAttributes(); @@ -5922,6 +5932,26 @@ public class PGraphicsOpenGL extends PGraphics { setAttribute(inTexcoordLoc, vboId, size, type, false, stride, offset); } + public void setTexture(PTexture tex) { + texture = tex; + + // Calculate scale and offset for texture coordinates + // and passing them to the fragment shader. + + float scaleu = tex.maxTexCoordU; + float scalev = tex.maxTexCoordV; + float offsetu = 0; + float offsetv = 0; + + if (tex.isFlippedY()) { + scalev *= -1; + offsetv = 1; + } + + set2FloatUniform(texcoordScaleLoc, scaleu, scalev); + set2FloatUniform(texcoordOffsetLoc, offsetu, offsetv); + } + public void start() { super.start(); @@ -5938,6 +5968,9 @@ public class PGraphicsOpenGL extends PGraphics { protected class FillShaderFull extends FillShaderLit { protected int inTexcoordLoc; + protected int texcoordScaleLoc; + protected int texcoordOffsetLoc; + public FillShaderFull(PApplet parent, String vertFilename, String fragFilename) { super(parent, vertFilename, fragFilename); } @@ -5945,6 +5978,13 @@ public class PGraphicsOpenGL extends PGraphics { public FillShaderFull(PApplet parent, URL vertURL, URL fragURL) { super(parent, vertURL, fragURL); } + + public void loadUniforms() { + super.loadUniforms(); + + texcoordScaleLoc = getUniformLocation("texcoordScale"); + texcoordOffsetLoc = getUniformLocation("texcoordOffset"); + } public void loadAttributes() { super.loadAttributes(); @@ -5956,6 +5996,26 @@ public class PGraphicsOpenGL extends PGraphics { setAttribute(inTexcoordLoc, vboId, size, type, false, stride, offset); } + public void setTexture(PTexture tex) { + texture = tex; + + // Calculate scale and offset for texture coordinates + // and passing them to the fragment shader. + + float scaleu = tex.maxTexCoordU; + float scalev = tex.maxTexCoordV; + float offsetu = 0; + float offsetv = 0; + + if (tex.isFlippedY()) { + scalev *= -1; + offsetv = 1; + } + + set2FloatUniform(texcoordScaleLoc, scaleu, scalev); + set2FloatUniform(texcoordOffsetLoc, offsetu, offsetv); + } + public void start() { super.start(); diff --git a/java/libraries/opengl/src/processing/opengl/PShader.java b/java/libraries/opengl/src/processing/opengl/PShader.java index 1835fb39e..891278889 100644 --- a/java/libraries/opengl/src/processing/opengl/PShader.java +++ b/java/libraries/opengl/src/processing/opengl/PShader.java @@ -160,84 +160,115 @@ public class PShader { public void setIntUniform(int loc, int x) { - pgl.glUniform1i(loc, x); + if (-1 < loc) { + pgl.glUniform1i(loc, x); + } } public void set1FloatUniform(int loc, float x) { - pgl.glUniform1f(loc, x); + if (-1 < loc) { + pgl.glUniform1f(loc, x); + } } public void set2FloatUniform(int loc, float x, float y) { - pgl.glUniform2f(loc, x, y); + if (-1 < loc) { + pgl.glUniform2f(loc, x, y); + } } public void set3FloatUniform(int loc, float x, float y, float z) { - pgl.glUniform3f(loc, x, y, z); + if (-1 < loc) { + pgl.glUniform3f(loc, x, y, z); + } } public void set4FloatUniform(int loc, float x, float y, float z, float w) { - pgl.glUniform4f(loc, x, y, z, w); + if (-1 < loc) { + pgl.glUniform4f(loc, x, y, z, w); + } } public void set1FloatVecUniform(int loc, float[] vec) { - pgl.glUniform1fv(loc, vec.length, vec, 0); + if (-1 < loc) { + pgl.glUniform1fv(loc, vec.length, vec, 0); + } } public void set2FloatVecUniform(int loc, float[] vec) { - pgl.glUniform2fv(loc, vec.length / 2, vec, 0); + if (-1 < loc) { + pgl.glUniform2fv(loc, vec.length / 2, vec, 0); + } } public void set3FloatVecUniform(int loc, float[] vec) { - pgl.glUniform3fv(loc, vec.length / 3, vec, 0); + if (-1 < loc) { + pgl.glUniform3fv(loc, vec.length / 3, vec, 0); + } } public void set4FloatVecUniform(int loc, float[] vec) { - pgl.glUniform4fv(loc, vec.length / 4, vec, 0); + if (-1 < loc) { + pgl.glUniform4fv(loc, vec.length / 4, vec, 0); + } } public void set2x2MatUniform(int loc, float[] mat) { - pgl.glUniformMatrix2fv(loc, 1, false, mat, 0); + if (-1 < loc) { + pgl.glUniformMatrix2fv(loc, 1, false, mat, 0); + } } public void set3x3MatUniform(int loc, float[] mat) { - pgl.glUniformMatrix3fv(loc, 1, false, mat, 0); + if (-1 < loc) { + pgl.glUniformMatrix3fv(loc, 1, false, mat, 0); + } } public void set4x4MatUniform(int loc, float[] mat) { - pgl.glUniformMatrix4fv(loc, 1, false, mat, 0); + if (-1 < loc) { + pgl.glUniformMatrix4fv(loc, 1, false, mat, 0); + } } public void set1FloatAttribute(int loc, float x) { - pgl.glVertexAttrib1f(loc, x); + if (-1 < loc) { + pgl.glVertexAttrib1f(loc, x); + } } public void set2FloatAttribute(int loc, float x, float y) { - pgl.glVertexAttrib2f(loc, x, y); + if (-1 < loc) { + pgl.glVertexAttrib2f(loc, x, y); + } } public void set3FloatAttribute(int loc, float x, float y, float z) { - pgl.glVertexAttrib3f(loc, x, y, z); + if (-1 < loc) { + pgl.glVertexAttrib3f(loc, x, y, z); + } } public void set4FloatAttribute(int loc, float x, float y, float z, float w) { - pgl.glVertexAttrib4f(loc, x, y, z, w); + if (-1 < loc) { + pgl.glVertexAttrib4f(loc, x, y, z, w); + } } - protected void init() { if (programObject == 0) { diff --git a/java/libraries/opengl/src/processing/opengl/PShape3D.java b/java/libraries/opengl/src/processing/opengl/PShape3D.java index b07e894f8..06e7fc565 100644 --- a/java/libraries/opengl/src/processing/opengl/PShape3D.java +++ b/java/libraries/opengl/src/processing/opengl/PShape3D.java @@ -627,13 +627,8 @@ public class PShape3D extends PShape { } if (texture != null && textureMode == IMAGE) { - u /= texture.width; - v /= texture.height; - - PTexture tex = pg.queryTexture(texture); - if (tex != null && tex.isFlippedY()) { - v = 1 - v; - } + u = PApplet.min(1, u / texture.width); + v = PApplet.min(1, v / texture.height); } int scolor = 0x00;