From 62d7076a595bd32822b45dc84eda2cb35dfa57c3 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Mon, 27 May 2013 13:01:29 -0400 Subject: [PATCH] Fixing several problems with the handling of offsecreen surfaces --- core/src/processing/opengl/FrameBuffer.java | 1 - core/src/processing/opengl/MaskFrag.glsl | 5 + core/src/processing/opengl/PGL.java | 69 ++++---- .../processing/opengl/PGraphicsOpenGL.java | 162 ++++++++++++------ core/src/processing/opengl/PShader.java | 35 ---- core/src/processing/opengl/Texture.java | 31 ++-- 6 files changed, 167 insertions(+), 136 deletions(-) diff --git a/core/src/processing/opengl/FrameBuffer.java b/core/src/processing/opengl/FrameBuffer.java index a063bc87e..8821861c9 100644 --- a/core/src/processing/opengl/FrameBuffer.java +++ b/core/src/processing/opengl/FrameBuffer.java @@ -149,7 +149,6 @@ public class FrameBuffer implements PConstants { @Override protected void finalize() throws Throwable { try { -// PApplet.println("finalize FBO"); if (!screenFb) { if (glFbo != 0) { PGraphicsOpenGL.finalizeFrameBufferObject(glFbo, context); diff --git a/core/src/processing/opengl/MaskFrag.glsl b/core/src/processing/opengl/MaskFrag.glsl index 07e590009..508a39649 100644 --- a/core/src/processing/opengl/MaskFrag.glsl +++ b/core/src/processing/opengl/MaskFrag.glsl @@ -18,6 +18,11 @@ Boston, MA 02111-1307 USA */ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + #define PROCESSING_TEXTURE_SHADER uniform sampler2D texture; diff --git a/core/src/processing/opengl/PGL.java b/core/src/processing/opengl/PGL.java index ba513c90b..8232ed88e 100644 --- a/core/src/processing/opengl/PGL.java +++ b/core/src/processing/opengl/PGL.java @@ -965,7 +965,8 @@ public class PGL { // Render previous back texture (now is the front) as background, // because no background() is being used ("incremental drawing") drawTexture(TEXTURE_2D, glColorTex.get(frontTex), - fboWidth, fboHeight, 0, 0, pg.width, pg.height, + fboWidth, fboHeight, pg.width, pg.height, + 0, 0, pg.width, pg.height, 0, 0, pg.width, pg.height); } @@ -997,6 +998,7 @@ public class PGL { gl.glDisable(GL.GL_BLEND); drawTexture(GL.GL_TEXTURE_2D, backTexAttach.getName(), backTexAttach.getWidth(), backTexAttach.getHeight(), + pg.width, pg.height, 0, 0, pg.width, pg.height, 0, 0, pg.width, pg.height); backFBO.bind(gl); } @@ -1014,7 +1016,8 @@ public class PGL { // Render current back texture to screen, without blending. disable(BLEND); drawTexture(TEXTURE_2D, glColorTex.get(backTex), - fboWidth, fboHeight, 0, 0, pg.width, pg.height, + fboWidth, fboHeight, pg.width, pg.height, + 0, 0, pg.width, pg.height, 0, 0, pg.width, pg.height); // Swapping front and back textures. @@ -1329,26 +1332,28 @@ public class PGL { protected void drawTexture(int target, int id, int width, int height, int X0, int Y0, int X1, int Y1) { - drawTexture(target, id, width, height, X0, Y0, X1, Y1, X0, Y0, X1, Y1); + drawTexture(target, id, width, height, width, height, + X0, Y0, X1, Y1, X0, Y0, X1, Y1); } - protected void drawTexture(int target, int id, int width, int height, + protected void drawTexture(int target, int id, + int texW, int texH, int scrW, int scrH, int texX0, int texY0, int texX1, int texY1, int scrX0, int scrY0, int scrX1, int scrY1) { if (target == TEXTURE_2D) { - drawTexture2D(id, width, height, + drawTexture2D(id, texW, texH, scrW, scrH, texX0, texY0, texX1, texY1, scrX0, scrY0, scrX1, scrY1); } else if (target == TEXTURE_RECTANGLE) { - drawTextureRect(id, width, height, + drawTextureRect(id, texW, texH, scrW, scrH, texX0, texY0, texX1, texY1, scrX0, scrY0, scrX1, scrY1); } } - protected void drawTexture2D(int id, int width, int height, + protected void drawTexture2D(int id, int texW, int texH, int scrW, int scrH, int texX0, int texY0, int texX1, int texY1, int scrX0, int scrY0, int scrX1, int scrY1) { if (!loadedTex2DShader || @@ -1390,25 +1395,25 @@ public class PGL { // Vertex coordinates of the textured quad are specified // in normalized screen space (-1, 1): // Corner 1 - texCoords[ 0] = 2 * (float)scrX0 / pg.width - 1; - texCoords[ 1] = 2 * (float)scrY0 / pg.height - 1; - texCoords[ 2] = (float)texX0 / width; - texCoords[ 3] = (float)texY0 / height; + texCoords[ 0] = 2 * (float)scrX0 / scrW - 1; + texCoords[ 1] = 2 * (float)scrY0 / scrH - 1; + texCoords[ 2] = (float)texX0 / texW; + texCoords[ 3] = (float)texY0 / texH; // Corner 2 - texCoords[ 4] = 2 * (float)scrX1 / pg.width - 1; - texCoords[ 5] = 2 * (float)scrY0 / pg.height - 1; - texCoords[ 6] = (float)texX1 / width; - texCoords[ 7] = (float)texY0 / height; + texCoords[ 4] = 2 * (float)scrX1 / scrW - 1; + texCoords[ 5] = 2 * (float)scrY0 / scrH - 1; + texCoords[ 6] = (float)texX1 / texW; + texCoords[ 7] = (float)texY0 / texH; // Corner 3 - texCoords[ 8] = 2 * (float)scrX0 / pg.width - 1; - texCoords[ 9] = 2 * (float)scrY1 / pg.height - 1; - texCoords[10] = (float)texX0 / width; - texCoords[11] = (float)texY1 / height; + texCoords[ 8] = 2 * (float)scrX0 / scrW - 1; + texCoords[ 9] = 2 * (float)scrY1 / scrH - 1; + texCoords[10] = (float)texX0 / texW; + texCoords[11] = (float)texY1 / texH; // Corner 4 - texCoords[12] = 2 * (float)scrX1 / pg.width - 1; - texCoords[13] = 2 * (float)scrY1 / pg.height - 1; - texCoords[14] = (float)texX1 / width; - texCoords[15] = (float)texY1 / height; + texCoords[12] = 2 * (float)scrX1 / scrW - 1; + texCoords[13] = 2 * (float)scrY1 / scrH - 1; + texCoords[14] = (float)texX1 / texW; + texCoords[15] = (float)texY1 / texH; texData.rewind(); texData.put(texCoords); @@ -1452,7 +1457,7 @@ public class PGL { } - protected void drawTextureRect(int id, int width, int height, + protected void drawTextureRect(int id, int texW, int texH, int scrW, int scrH, int texX0, int texY0, int texX1, int texY1, int scrX0, int scrY0, int scrX1, int scrY1) { if (!loadedTexRectShader || @@ -1495,23 +1500,23 @@ public class PGL { // Vertex coordinates of the textured quad are specified // in normalized screen space (-1, 1): // Corner 1 - texCoords[ 0] = 2 * (float)scrX0 / pg.width - 1; - texCoords[ 1] = 2 * (float)scrY0 / pg.height - 1; + texCoords[ 0] = 2 * (float)scrX0 / scrW - 1; + texCoords[ 1] = 2 * (float)scrY0 / scrH - 1; texCoords[ 2] = texX0; texCoords[ 3] = texY0; // Corner 2 - texCoords[ 4] = 2 * (float)scrX1 / pg.width - 1; - texCoords[ 5] = 2 * (float)scrY0 / pg.height - 1; + texCoords[ 4] = 2 * (float)scrX1 / scrW - 1; + texCoords[ 5] = 2 * (float)scrY0 / scrH - 1; texCoords[ 6] = texX1; texCoords[ 7] = texY0; // Corner 3 - texCoords[ 8] = 2 * (float)scrX0 / pg.width - 1; - texCoords[ 9] = 2 * (float)scrY1 / pg.height - 1; + texCoords[ 8] = 2 * (float)scrX0 / scrW - 1; + texCoords[ 9] = 2 * (float)scrY1 / scrH - 1; texCoords[10] = texX0; texCoords[11] = texY1; // Corner 4 - texCoords[12] = 2 * (float)scrX1 / pg.width - 1; - texCoords[13] = 2 * (float)scrY1 / pg.height - 1; + texCoords[12] = 2 * (float)scrX1 / scrW - 1; + texCoords[13] = 2 * (float)scrY1 / scrH - 1; texCoords[14] = texX1; texCoords[15] = texY1; diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index a8a2aa2dc..0c96a37c2 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -667,8 +667,6 @@ public class PGraphicsOpenGL extends PGraphics { @Override protected void finalize() throws Throwable { try { -// PApplet.println("finalize surface"); - deletePolyBuffers(); deleteLineBuffers(); deletePointBuffers(); @@ -797,7 +795,6 @@ public class PGraphicsOpenGL extends PGraphics { for (GLResource res : finalized) { glTextureObjects.remove(res); } -// PApplet.println("Deleted " + finalized.size() + " texture objects, " + glTextureObjects.size() + " remaining"); } protected static void removeTextureObject(int id, int context) { @@ -862,7 +859,6 @@ public class PGraphicsOpenGL extends PGraphics { for (GLResource res : finalized) { glVertexBuffers.remove(res); } -// PApplet.println("Deleted " + finalized.size() + " vertex buffer objects, " + glVertexBuffers.size() + " remaining"); } protected static void removeVertexBufferObject(int id, int context) { @@ -929,7 +925,6 @@ public class PGraphicsOpenGL extends PGraphics { for (GLResource res : finalized) { glFrameBuffers.remove(res); } -// PApplet.println("Deleted " + finalized.size() + " framebuffer objects, " + glFrameBuffers.size() + " remaining"); } protected static void removeFrameBufferObject(int id, int context) { @@ -994,7 +989,6 @@ public class PGraphicsOpenGL extends PGraphics { for (GLResource res : finalized) { glRenderBuffers.remove(res); } -// PApplet.println("Deleted " + finalized.size() + " renderbuffer objects, " + glRenderBuffers.size() + " remaining"); } protected static void removeRenderBufferObject(int id, int context) { @@ -1055,7 +1049,6 @@ public class PGraphicsOpenGL extends PGraphics { for (GLResource res : finalized) { glslPrograms.remove(res); } -// PApplet.println("Deleted " + finalized.size() + " GLSL program objects, " + glslPrograms.size() + " remaining"); } protected static void removeGLSLProgramObject(int id, int context) { @@ -1117,7 +1110,6 @@ public class PGraphicsOpenGL extends PGraphics { for (GLResource res : finalized) { glslVertexShaders.remove(res); } -// PApplet.println("Deleted " + finalized.size() + " GLSL vertex shader objects, " + glslVertexShaders.size() + " remaining"); } protected static void removeGLSLVertShaderObject(int id, int context) { @@ -1179,7 +1171,6 @@ public class PGraphicsOpenGL extends PGraphics { for (GLResource res : finalized) { glslFragmentShaders.remove(res); } -// PApplet.println("Deleted " + finalized.size() + " GLSL fragment shader objects, " + glslFragmentShaders.size() + " remaining"); } protected static void removeGLSLFragShaderObject(int id, int context) { @@ -1637,6 +1628,12 @@ public class PGraphicsOpenGL extends PGraphics { if (primarySurface) { beginOnscreenDraw(); } else { + if (pgPrimary.texCache.containsTexture(this)) { + // This offscreen surface is being used as a texture earlier in draw, + // so we should update the rendering up to this point since it will + // modified. + pgPrimary.flush(); + } beginOffscreenDraw(); } setDefaults(); @@ -1644,9 +1641,15 @@ public class PGraphicsOpenGL extends PGraphics { pgCurrent = this; drawing = true; + clearCalled = false; + clearColorBuffer0 = clearColorBuffer; + clearColorBuffer = false; + report("bot beginDraw()"); } + boolean clearCalled; + boolean clearEveryFrame; @Override public void endDraw() { @@ -1657,6 +1660,10 @@ public class PGraphicsOpenGL extends PGraphics { return; } + if (!clearCalled && 0 < parent.frameCount) { + clearEveryFrame = false; + } + // Flushing any remaining geometry. flush(); @@ -1945,6 +1952,7 @@ public class PGraphicsOpenGL extends PGraphics { manipulatingCamera = false; clearColorBuffer = false; + clearEveryFrame = true; // easiest for beginners textureMode(IMAGE); @@ -4899,6 +4907,7 @@ public class PGraphicsOpenGL extends PGraphics { if (0 < parent.frameCount) { clearColorBuffer = true; } + clearCalled = true; } @@ -4920,6 +4929,7 @@ public class PGraphicsOpenGL extends PGraphics { if (0 < parent.frameCount) { clearColorBuffer = true; } + clearCalled = true; } @@ -5278,11 +5288,11 @@ public class PGraphicsOpenGL extends PGraphics { } - public void drawTexture(int target, int id, int width, int height, + public void drawTexture(int target, int id, int texW, int texH, int texX0, int texY0, int texX1, int texY1, int scrX0, int scrY0, int scrX1, int scrY1) { beginPGL(); - pgl.drawTexture(target, id, width, height, + pgl.drawTexture(target, id, texW, texH, width, height, texX0, texY0, texX1, texY1, scrX0, scrY0, scrX1, scrY1); endPGL(); @@ -5300,20 +5310,27 @@ public class PGraphicsOpenGL extends PGraphics { pgPrimary.setCache(this, texture); if (!primarySurface) { - ptexture = new Texture(width, height, params); - ptexture.invertedY(true); - ptexture.colorBuffer(true); + createPTexture(); } } } + protected void createPTexture() { + ptexture = new Texture(width, height, texture.getParameters()); + ptexture.invertedY(true); + ptexture.colorBuffer(true); + } + + protected void swapTextures() { - int temp = texture.glName; - texture.glName = ptexture.glName; - ptexture.glName = temp; - if (!primarySurface) { - offscreenFramebuffer.setColorBuffer(texture); + if (ptexture != null) { + int temp = texture.glName; + texture.glName = ptexture.glName; + ptexture.glName = temp; + if (!primarySurface) { + offscreenFramebuffer.setColorBuffer(texture); + } } } @@ -5334,13 +5351,40 @@ public class PGraphicsOpenGL extends PGraphics { // invert the y coordinates of the screen rectangle. pgl.disable(PGL.BLEND); pgl.drawTexture(texture.glTarget, texture.glName, - texture.glWidth, texture.glHeight, + texture.glWidth, texture.glHeight, width, height, x, y, x + w, y + h, x, height - (y + h), x + w, height - y); pgl.enable(PGL.BLEND); } + protected void drawPTexture() { + if (ptexture != null) { + // No blend so the texure replaces wherever is on the screen, + // irrespective of the alpha + pgl.disable(PGL.BLEND); + pgl.drawTexture(ptexture.glTarget, ptexture.glName, + ptexture.glWidth, ptexture.glHeight, + 0, 0, width, height); + pgl.enable(PGL.BLEND); + } + } + + + protected void drawPTexture(int x, int y, int w, int h) { + if (ptexture != null) { + // Processing Y axis is inverted with respect to OpenGL, so we need to + // invert the y coordinates of the screen rectangle. + pgl.disable(PGL.BLEND); + pgl.drawTexture(ptexture.glTarget, ptexture.glName, + ptexture.glWidth, ptexture.glHeight, width, height, + x, y, x + w, y + h, + x, height - (y + h), x + w, height - y); + pgl.enable(PGL.BLEND); + } + } + + ////////////////////////////////////////////////////////////// // MASK @@ -5409,8 +5453,14 @@ public class PGraphicsOpenGL extends PGraphics { return; } - pgl.needFBOLayer(); + boolean needEndDraw = false; + if (primarySurface) pgl.needFBOLayer(); + else if (!drawing) { + beginDraw(); + needEndDraw = true; + } loadTexture(); + if (filterTexture == null || filterTexture.contextIsOutdated()) { filterTexture = new Texture(texture.width, texture.height, texture.getParameters()); @@ -5418,6 +5468,7 @@ public class PGraphicsOpenGL extends PGraphics { filterImage = wrapTexture(filterTexture); } filterTexture.set(texture); +// filterTexture.set(ptexture); // 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. @@ -5438,10 +5489,11 @@ public class PGraphicsOpenGL extends PGraphics { textureMode = NORMAL; boolean prevStroke = stroke; stroke = false; -// int prevBlendMode = blendMode; -// blendMode(REPLACE); + int prevBlendMode = blendMode; + blendMode(REPLACE); TextureShader prevTexShader = textureShader; textureShader = (TextureShader) shader; + beginShape(QUADS); texture(filterImage); vertex(0, 0, 0, 0); @@ -5451,13 +5503,12 @@ public class PGraphicsOpenGL extends PGraphics { endShape(); end2D(); - textureShader = prevTexShader; - // Restoring previous configuration. + textureShader = prevTexShader; stroke = prevStroke; lights = prevLights; textureMode = prevTextureMode; -// blendMode(prevBlendMode); + blendMode(prevBlendMode); if (!hints[DISABLE_DEPTH_TEST]) { pgl.enable(PGL.DEPTH_TEST); @@ -5465,6 +5516,10 @@ public class PGraphicsOpenGL extends PGraphics { if (!hints[DISABLE_DEPTH_MASK]) { pgl.depthMask(true); } + + if (needEndDraw) { + endDraw(); + } } @@ -5696,6 +5751,7 @@ public class PGraphicsOpenGL extends PGraphics { if (primarySurface) { pgl.bindFrontTexture(); } else { + if (ptexture == null) createPTexture(); ptexture.bind(); } } @@ -5952,9 +6008,17 @@ public class PGraphicsOpenGL extends PGraphics { protected void beginOffscreenDraw() { updateOffscreen(); - - // Just in case the texture was recreated (in a resize event for example) - offscreenFramebuffer.setColorBuffer(texture); + /* + if (!clearColorBuffer) { + // Render previous back texture (now is the front) as background, + // because no background() is being used ("incremental drawing") + drawPTexture(); + } + if (!clearEveryFrame) { + drawPTexture(); + } + */ + drawPTexture(); // Restoring the clipping configuration of the offscreen surface. if (clip) { @@ -5971,22 +6035,6 @@ public class PGraphicsOpenGL extends PGraphics { multisampleFramebuffer.copy(offscreenFramebuffer, currentFramebuffer); } - if (!clearColorBuffer0) { - // Draw the back texture into the front texture, which will be used as - // front texture in the next frame. Otherwise flickering will occur if - // the sketch uses "incremental drawing" (background() not called). - if (offscreenMultisample) { - pushFramebuffer(); - setFramebuffer(offscreenFramebuffer); - } - offscreenFramebuffer.setColorBuffer(ptexture); - drawTexture(); - offscreenFramebuffer.setColorBuffer(texture); - if (offscreenMultisample) { - popFramebuffer(); - } - } - popFramebuffer(); texture.updateTexels(); // Mark all texels in screen texture as modified. @@ -6109,9 +6157,6 @@ public class PGraphicsOpenGL extends PGraphics { modified = false; setgetPixels = false; - - clearColorBuffer0 = clearColorBuffer; - clearColorBuffer = false; } @@ -6879,6 +6924,11 @@ public class PGraphicsOpenGL extends PGraphics { setAttributeVBO(texCoordLoc, vboId, size, type, false, stride, offset); } + @Override + public int getLastTexUnit() { + return -1 < bufferUnit ? bufferUnit : super.getLastTexUnit(); + } + @Override public void setTexture(Texture tex) { float scaleu = 1; @@ -6915,7 +6965,7 @@ public class PGraphicsOpenGL extends PGraphics { setUniformValue(texOffsetLoc, 1.0f / tex.width, 1.0f / tex.height); if (-1 < textureLoc) { - texUnit = bufferUnit + 1; + texUnit = getLastTexUnit() + 1; setUniformValue(textureLoc, texUnit); pgl.activeTexture(PGL.TEXTURE0 + texUnit); tex.bind(); @@ -6999,6 +7049,11 @@ public class PGraphicsOpenGL extends PGraphics { setAttributeVBO(texCoordLoc, vboId, size, type, false, stride, offset); } + @Override + public int getLastTexUnit() { + return -1 < bufferUnit ? bufferUnit : super.getLastTexUnit(); + } + @Override public void setTexture(Texture tex) { float scaleu = 1; @@ -7035,7 +7090,7 @@ public class PGraphicsOpenGL extends PGraphics { setUniformValue(texOffsetLoc, 1.0f / tex.width, 1.0f / tex.height); if (-1 < textureLoc) { - texUnit = bufferUnit + 1; + texUnit = getLastTexUnit() + 1; setUniformValue(textureLoc, texUnit); pgl.activeTexture(PGL.TEXTURE0 + texUnit); tex.bind(); @@ -7313,6 +7368,13 @@ public class PGraphicsOpenGL extends PGraphics { hasTextures = false; } + boolean containsTexture(PImage img) { + for (int i = 0; i < size; i++) { + if (textures[i] == img) return true; + } + return false; + } + PImage getTextureImage(int i) { return textures[i]; } diff --git a/core/src/processing/opengl/PShader.java b/core/src/processing/opengl/PShader.java index 81e561123..03eca7517 100644 --- a/core/src/processing/opengl/PShader.java +++ b/core/src/processing/opengl/PShader.java @@ -84,7 +84,6 @@ public class PShader { protected IntBuffer intBuffer; protected FloatBuffer floatBuffer; - public PShader() { parent = null; pgMain = null; @@ -100,8 +99,6 @@ public class PShader { glVertex = 0; glFragment = 0; -// firstTexUnit = 0; - intBuffer = PGL.allocateIntBuffer(1); floatBuffer = PGL.allocateFloatBuffer(1); @@ -927,36 +924,4 @@ public class PShader { this.value = value; } } - - /* - // The individual attribute setters are not really needed, read this: - // http://stackoverflow.com/questions/7718976/what-is-glvertexattrib-versus-glvertexattribpointer-used-for - // except for setting a constant vertex attribute value. - public void set1FloatAttribute(int loc, float x) { - if (-1 < loc) { - pgl.glVertexAttrib1f(loc, x); - } - } - - - public void set2FloatAttribute(int loc, float x, float y) { - if (-1 < loc) { - pgl.glVertexAttrib2f(loc, x, y); - } - } - - - public void set3FloatAttribute(int loc, float x, float y, float z) { - if (-1 < loc) { - pgl.glVertexAttrib3f(loc, x, y, z); - } - } - - - public void set4FloatAttribute(int loc, float x, float y, float z, float w) { - if (-1 < loc) { - pgl.glVertexAttrib4f(loc, x, y, z, w); - } - } - */ } diff --git a/core/src/processing/opengl/Texture.java b/core/src/processing/opengl/Texture.java index e59c22a19..4a1ba290e 100644 --- a/core/src/processing/opengl/Texture.java +++ b/core/src/processing/opengl/Texture.java @@ -80,7 +80,7 @@ public class Texture implements PConstants { protected PGL pgl; // The interface between Processing and OpenGL. protected int context; // The context that created this texture. - protected boolean colorBuffer; // true if it is the color attachment of + protected boolean colorBuffer; // true if it is the color attachment of // FrameBuffer object. protected boolean usingMipmaps; @@ -270,18 +270,6 @@ public class Texture implements PConstants { // Set methods -// public void set(PImage tex) { -// Texture tex = (Texture)pg.getCache(img); -// set(tex); -// } - - -// public void set(PImage img, int x, int y, int w, int h) { -// Texture tex = (Texture)pg.getCache(img); -// set(tex, x, y, w, h); -// } - - public void set(Texture tex) { copyTexture(tex, 0, 0, tex.width, tex.height, true); } @@ -851,6 +839,7 @@ public class Texture implements PConstants { pixelBuffer = PGL.updateIntBuffer(pixelBuffer, pixels, true); } + //////////////////////////////////////////////////////////// // Buffer sink interface. @@ -1135,7 +1124,6 @@ public class Texture implements PConstants { } - /////////////////////////////////////////////////////////// // Allocate/release texture. @@ -1281,18 +1269,21 @@ public class Texture implements PConstants { if (scale) { // Rendering tex into "this", and scaling the source rectangle // to cover the entire destination region. - pgl.drawTexture(tex.glTarget, tex.glName, tex.glWidth, tex.glHeight, + pgl.drawTexture(tex.glTarget, tex.glName, + tex.glWidth, tex.glHeight, tempFbo.width, tempFbo.height, x, y, w, h, 0, 0, width, height); } else { // Rendering tex into "this" but without scaling so the contents // of the source texture fall in the corresponding texels of the // destination. - pgl.drawTexture(tex.glTarget, tex.glName, tex.glWidth, tex.glHeight, + pgl.drawTexture(tex.glTarget, tex.glName, + tex.glWidth, tex.glHeight, tempFbo.width, tempFbo.height, x, y, w, h, x, y, w, h); } PGraphicsOpenGL.popFramebuffer(); updateTexels(x, y, w, h); + PApplet.println(width + " " + height + " " + tempFbo.width + " " + tempFbo.height); } @@ -1314,18 +1305,22 @@ public class Texture implements PConstants { if (scale) { // Rendering tex into "this", and scaling the source rectangle // to cover the entire destination region. - pgl.drawTexture(texTarget, texName, texWidth, texHeight, + pgl.drawTexture(texTarget, texName, + texWidth, texHeight, tempFbo.width, tempFbo.height, x, y, w, h, 0, 0, width, height); } else { // Rendering tex into "this" but without scaling so the contents // of the source texture fall in the corresponding texels of the // destination. - pgl.drawTexture(texTarget, texName, texWidth, texHeight, + pgl.drawTexture(texTarget, texName, + texWidth, texHeight, tempFbo.width, tempFbo.height, x, y, w, h, x, y, w, h); } PGraphicsOpenGL.popFramebuffer(); updateTexels(x, y, w, h); + + PApplet.println(width + " " + height + " " + tempFbo.width + " " + tempFbo.height); }