diff --git a/android/core/src/processing/core/PApplet.java b/android/core/src/processing/core/PApplet.java index 66094a2d7..7dc8280d4 100644 --- a/android/core/src/processing/core/PApplet.java +++ b/android/core/src/processing/core/PApplet.java @@ -782,7 +782,7 @@ public class PApplet extends Activity implements PConstants, Runnable { final boolean supportsGLES2 = configurationInfo.reqGlEsVersion >= 0x20000; if (!supportsGLES2) { - throw new RuntimeException("P3D: OpenGL ES 2.0 is not supported by this device."); + throw new RuntimeException("OpenGL ES 2.0 is not supported by this device."); } surfaceHolder = getHolder(); @@ -7329,6 +7329,11 @@ public class PApplet extends Activity implements PConstants, Runnable { } + public void textureWrap(int wrap) { + g.textureWrap(wrap); + } + + /** * Set texture image for current shape. * Needs to be called between @see beginShape and @see endShape diff --git a/android/core/src/processing/core/PConstants.java b/android/core/src/processing/core/PConstants.java index f82b09add..8542a90ca 100644 --- a/android/core/src/processing/core/PConstants.java +++ b/android/core/src/processing/core/PConstants.java @@ -346,6 +346,14 @@ public interface PConstants { static final int IMAGE = 2; + // texture wrapping modes + + /** textures are clamped to their edges */ + public static final int CLAMP = 0; + /** textures wrap around when uv values go outside 0..1 range */ + public static final int REPEAT = 1; + + // text placement modes /** diff --git a/android/core/src/processing/core/PGraphics.java b/android/core/src/processing/core/PGraphics.java index 98d1ccb89..81be53503 100644 --- a/android/core/src/processing/core/PGraphics.java +++ b/android/core/src/processing/core/PGraphics.java @@ -942,6 +942,11 @@ public class PGraphics extends PImage implements PConstants { this.textureMode = mode; } + + public void textureWrap(int wrap) { + showMissingWarning("textureWrap"); + } + /** * Set texture image for current shape. diff --git a/android/core/src/processing/opengl/PGraphicsOpenGL.java b/android/core/src/processing/opengl/PGraphicsOpenGL.java index 8b5ea279a..e32f0171c 100644 --- a/android/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/android/core/src/processing/opengl/PGraphicsOpenGL.java @@ -306,8 +306,8 @@ public class PGraphicsOpenGL extends PGraphics { // Texturing: - public int textureWrap = Texture.CLAMP; - public int textureSampling = Texture.TRILINEAR; + protected int textureWrap = CLAMP; + protected int textureSampling = Texture.TRILINEAR; // ........................................................ @@ -5538,6 +5538,9 @@ public class PGraphicsOpenGL extends PGraphics { if (tex.hasBuffers()) { tex.bufferUpdate(); } + + checkTexture(tex); + return tex; } @@ -5595,6 +5598,26 @@ public class PGraphicsOpenGL extends PGraphics { } + protected void checkTexture(Texture tex) { + if (tex.usingMipmaps == hints[DISABLE_TEXTURE_MIPMAPS]) { + if (hints[DISABLE_TEXTURE_MIPMAPS]) { + tex.usingMipmaps(false, textureSampling); + } else { + tex.usingMipmaps(true, textureSampling); + } + } + + if ((tex.usingRepeat && textureWrap == CLAMP) || + (!tex.usingRepeat && textureWrap == REPEAT)) { + if (textureWrap == CLAMP) { + tex.usingRepeat(false); + } else { + tex.usingRepeat(true); + } + } + } + + protected PImage wrapTexture(Texture tex) { // We don't use the PImage(int width, int height, int mode) constructor to // avoid initializing the pixels array. diff --git a/android/core/src/processing/opengl/Texture.java b/android/core/src/processing/opengl/Texture.java index 84eb2328d..b4279812f 100644 --- a/android/core/src/processing/opengl/Texture.java +++ b/android/core/src/processing/opengl/Texture.java @@ -63,11 +63,6 @@ public class Texture implements PConstants { * interpolation to compute the value in each of two maps and then interpolates linearly * between these two value. */ public static final int TRILINEAR = 5; - - /** This constant identifies the clamp-to-edge wrapping mode */ - public static final int CLAMP = 0; - /** This constant identifies the repeat wrapping mode */ - public static final int REPEAT = 1; public int width, height; @@ -86,7 +81,8 @@ public class Texture implements PConstants { protected PGL pgl; // The interface between Processing and OpenGL. protected PGL.Context context; // The context that created this texture. - protected boolean usingMipmaps; + protected boolean usingMipmaps; + protected boolean usingRepeat; protected float maxTexcoordU; protected float maxTexcoordV; protected boolean bound; @@ -527,7 +523,8 @@ public class Texture implements PConstants { //////////////////////////////////////////////////////////// // Get OpenGL parameters - + + /** * Returns true or false whether or not the texture is using mipmaps. * @return boolean @@ -535,6 +532,76 @@ public class Texture implements PConstants { public boolean usingMipmaps() { return usingMipmaps; } + + + public void usingMipmaps(boolean mipmaps, int sampling) { + if (mipmaps) { + 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; + } else if (sampling == BILINEAR) { + glMagFilter = 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; + } else { + throw new RuntimeException("Unknown texture filtering mode"); + } + } + + usingMipmaps = true; + } else { + if (glMinFilter == PGL.LINEAR_MIPMAP_NEAREST || glMinFilter == PGL.LINEAR_MIPMAP_LINEAR) { + glMinFilter = PGL.LINEAR; + } + usingMipmaps = false; + } + + bind(); + pgl.texParameteri(glTarget, PGL.TEXTURE_MIN_FILTER, glMinFilter); + pgl.texParameteri(glTarget, PGL.TEXTURE_MAG_FILTER, glMagFilter); + if (usingMipmaps) { + if (PGraphicsOpenGL.autoMipmapGenSupported) { + pgl.generateMipmap(glTarget); + } else { + // TODO: need manual generation here.. + } + } + unbind(); + } + + + /** + * Returns true or false whether or not the texture is using repeat wrap mode + * along either U or V directions. + * @return boolean + */ + public boolean usingRepeat() { + return usingRepeat; + } + + + public void usingRepeat(boolean repeat) { + if (repeat) { + glWrapS = PGL.REPEAT; + glWrapT = PGL.REPEAT; + usingRepeat = true; + } else { + glWrapS = PGL.CLAMP_TO_EDGE; + glWrapT = PGL.CLAMP_TO_EDGE; + usingRepeat = false; + } + + bind(); + pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_S, glWrapS); + pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_T, glWrapT); + unbind(); + } /** @@ -1225,7 +1292,8 @@ public class Texture implements PConstants { glWidth= src.glWidth; glHeight = src.glHeight; - usingMipmaps = src.usingMipmaps; + usingMipmaps = src.usingMipmaps; + usingRepeat = src.usingRepeat; maxTexcoordU = src.maxTexcoordU; maxTexcoordV = src.maxTexcoordV; @@ -1347,6 +1415,8 @@ public class Texture implements PConstants { usingMipmaps = glMinFilter == PGL.LINEAR_MIPMAP_NEAREST || glMinFilter == PGL.LINEAR_MIPMAP_LINEAR; + usingRepeat = glWrapS == PGL.REPEAT || glWrapT == PGL.REPEAT; + flippedX = false; flippedY = false; } diff --git a/core/andres.txt b/core/andres.txt index 30f06ad1f..576069bec 100644 --- a/core/andres.txt +++ b/core/andres.txt @@ -1,12 +1,13 @@ +0208 opengl +X Make methods in PGL used by opengl protected, then remove gl from the public GL methods +X Texture wrapping option in PGraphics: textureWrap(mode) + API changes/additions (for beta release) _ Cleanup video API: http://code.google.com/p/processing/issues/detail?id=1170 _ Have Capture.list() return all supported resolutions, and use the string as the argument _ for the capture object -_ Texture wrapping option in PGraphics: textureWrap(mode) -_ Make methods in PGL used by opengl protected, then remove gl from the public GL methods _ Add DISABLE_PERSPECTIVE_CORRECTED_STROKE hint, remove DISABLE_PERSPECTIVE_CORRECTED_LINES _ Rename shader constants (FLAT, LIT, TEXTURED, etc), resetShader() w/out args? -_ Print warning message when GLES2 is not available. _ Cleaner Implementation of PImage.loadPixels() _ Back-buffer support in shaders: http://code.google.com/p/processing/issues/detail?id=1169 diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 66d3224e2..94ec56ead 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -10065,6 +10065,12 @@ public class PApplet extends Applet } + public void textureWrap(int wrap) { + if (recorder != null) recorder.textureWrap(wrap); + g.textureWrap(wrap); + } + + /** * ( begin auto-generated from texture.xml ) * diff --git a/core/src/processing/core/PConstants.java b/core/src/processing/core/PConstants.java index 4334fc81f..6b8555670 100644 --- a/core/src/processing/core/PConstants.java +++ b/core/src/processing/core/PConstants.java @@ -405,7 +405,15 @@ public interface PConstants { /** texture coordinates based on image width/height */ static final int IMAGE = 2; + + // texture wrapping modes + + /** textures are clamped to their edges */ + public static final int CLAMP = 0; + /** textures wrap around when uv values go outside 0..1 range */ + public static final int REPEAT = 1; + // text placement modes /** diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index f078c99b5..db6f7c7a7 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -1078,6 +1078,11 @@ public class PGraphics extends PImage implements PConstants { this.textureMode = mode; } + + public void textureWrap(int wrap) { + showMissingWarning("textureWrap"); + } + /** * ( begin auto-generated from texture.xml ) diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 8b5ea279a..e32f0171c 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -306,8 +306,8 @@ public class PGraphicsOpenGL extends PGraphics { // Texturing: - public int textureWrap = Texture.CLAMP; - public int textureSampling = Texture.TRILINEAR; + protected int textureWrap = CLAMP; + protected int textureSampling = Texture.TRILINEAR; // ........................................................ @@ -5538,6 +5538,9 @@ public class PGraphicsOpenGL extends PGraphics { if (tex.hasBuffers()) { tex.bufferUpdate(); } + + checkTexture(tex); + return tex; } @@ -5595,6 +5598,26 @@ public class PGraphicsOpenGL extends PGraphics { } + protected void checkTexture(Texture tex) { + if (tex.usingMipmaps == hints[DISABLE_TEXTURE_MIPMAPS]) { + if (hints[DISABLE_TEXTURE_MIPMAPS]) { + tex.usingMipmaps(false, textureSampling); + } else { + tex.usingMipmaps(true, textureSampling); + } + } + + if ((tex.usingRepeat && textureWrap == CLAMP) || + (!tex.usingRepeat && textureWrap == REPEAT)) { + if (textureWrap == CLAMP) { + tex.usingRepeat(false); + } else { + tex.usingRepeat(true); + } + } + } + + protected PImage wrapTexture(Texture tex) { // We don't use the PImage(int width, int height, int mode) constructor to // avoid initializing the pixels array. diff --git a/core/src/processing/opengl/Texture.java b/core/src/processing/opengl/Texture.java index 84eb2328d..b4279812f 100644 --- a/core/src/processing/opengl/Texture.java +++ b/core/src/processing/opengl/Texture.java @@ -63,11 +63,6 @@ public class Texture implements PConstants { * interpolation to compute the value in each of two maps and then interpolates linearly * between these two value. */ public static final int TRILINEAR = 5; - - /** This constant identifies the clamp-to-edge wrapping mode */ - public static final int CLAMP = 0; - /** This constant identifies the repeat wrapping mode */ - public static final int REPEAT = 1; public int width, height; @@ -86,7 +81,8 @@ public class Texture implements PConstants { protected PGL pgl; // The interface between Processing and OpenGL. protected PGL.Context context; // The context that created this texture. - protected boolean usingMipmaps; + protected boolean usingMipmaps; + protected boolean usingRepeat; protected float maxTexcoordU; protected float maxTexcoordV; protected boolean bound; @@ -527,7 +523,8 @@ public class Texture implements PConstants { //////////////////////////////////////////////////////////// // Get OpenGL parameters - + + /** * Returns true or false whether or not the texture is using mipmaps. * @return boolean @@ -535,6 +532,76 @@ public class Texture implements PConstants { public boolean usingMipmaps() { return usingMipmaps; } + + + public void usingMipmaps(boolean mipmaps, int sampling) { + if (mipmaps) { + 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; + } else if (sampling == BILINEAR) { + glMagFilter = 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; + } else { + throw new RuntimeException("Unknown texture filtering mode"); + } + } + + usingMipmaps = true; + } else { + if (glMinFilter == PGL.LINEAR_MIPMAP_NEAREST || glMinFilter == PGL.LINEAR_MIPMAP_LINEAR) { + glMinFilter = PGL.LINEAR; + } + usingMipmaps = false; + } + + bind(); + pgl.texParameteri(glTarget, PGL.TEXTURE_MIN_FILTER, glMinFilter); + pgl.texParameteri(glTarget, PGL.TEXTURE_MAG_FILTER, glMagFilter); + if (usingMipmaps) { + if (PGraphicsOpenGL.autoMipmapGenSupported) { + pgl.generateMipmap(glTarget); + } else { + // TODO: need manual generation here.. + } + } + unbind(); + } + + + /** + * Returns true or false whether or not the texture is using repeat wrap mode + * along either U or V directions. + * @return boolean + */ + public boolean usingRepeat() { + return usingRepeat; + } + + + public void usingRepeat(boolean repeat) { + if (repeat) { + glWrapS = PGL.REPEAT; + glWrapT = PGL.REPEAT; + usingRepeat = true; + } else { + glWrapS = PGL.CLAMP_TO_EDGE; + glWrapT = PGL.CLAMP_TO_EDGE; + usingRepeat = false; + } + + bind(); + pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_S, glWrapS); + pgl.texParameteri(glTarget, PGL.TEXTURE_WRAP_T, glWrapT); + unbind(); + } /** @@ -1225,7 +1292,8 @@ public class Texture implements PConstants { glWidth= src.glWidth; glHeight = src.glHeight; - usingMipmaps = src.usingMipmaps; + usingMipmaps = src.usingMipmaps; + usingRepeat = src.usingRepeat; maxTexcoordU = src.maxTexcoordU; maxTexcoordV = src.maxTexcoordV; @@ -1347,6 +1415,8 @@ public class Texture implements PConstants { usingMipmaps = glMinFilter == PGL.LINEAR_MIPMAP_NEAREST || glMinFilter == PGL.LINEAR_MIPMAP_LINEAR; + usingRepeat = glWrapS == PGL.REPEAT || glWrapT == PGL.REPEAT; + flippedX = false; flippedY = false; }