diff --git a/core/src/processing/core/PGraphics.java b/core/src/processing/core/PGraphics.java index 43bd5c01f..cf40daa39 100644 --- a/core/src/processing/core/PGraphics.java +++ b/core/src/processing/core/PGraphics.java @@ -7317,7 +7317,15 @@ public class PGraphics extends PImage implements PConstants { return 0; } + ////////////////////////////////////////////////////////////// + // IMAGE PIXELS + + /* + public void loadPixels(PImage img) { // ignore + } + */ + ////////////////////////////////////////////////////////////// diff --git a/core/src/processing/core/PImage.java b/core/src/processing/core/PImage.java index 0104121d3..25de0e818 100644 --- a/core/src/processing/core/PImage.java +++ b/core/src/processing/core/PImage.java @@ -475,6 +475,19 @@ public class PImage implements PConstants, Cloneable { * @usage web_application */ public void loadPixels() { // ignore + /* + if (cacheMap == null) { + if (parent != null) { + parent.g.loadPixels(this); + } else { + PGraphics.showWarning("Cannot load pixels because this image object doesn't have a parent"); + } + } else { + for (PGraphics pg: cacheMap.keySet()) { + pg.loadPixels(this); + } + } + */ } public void updatePixels() { // ignore diff --git a/java/libraries/opengl/src/processing/opengl/FrameBuffer.java b/java/libraries/opengl/src/processing/opengl/FrameBuffer.java index 49ceb13ce..d59acec18 100644 --- a/java/libraries/opengl/src/processing/opengl/FrameBuffer.java +++ b/java/libraries/opengl/src/processing/opengl/FrameBuffer.java @@ -206,7 +206,7 @@ public class FrameBuffer implements PConstants { public void getPixels(int[] pixels) { if (pixelBuffer != null) { - pixelBuffer.get(pixels); + pixelBuffer.get(pixels, 0, pixels.length); pixelBuffer.rewind(); } } diff --git a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java index 4d4e47ca4..b07434639 100644 --- a/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java +++ b/java/libraries/opengl/src/processing/opengl/PGraphicsOpenGL.java @@ -5196,7 +5196,42 @@ public class PGraphicsOpenGL extends PGraphics { } return tex; } - + + + /** + * Copies the contents of the texture bound to img to its pixels array. + * @param img the image to have a texture metadata associated to it + */ + /* + public void loadPixels(PImage img) { + if (img.pixels == null) { + img.pixels = new int[img.width * img.height]; + } + + Texture tex = (Texture)img.getCache(pgPrimary); + if (tex == null) { + tex = addTexture(img); + } else { + if (tex.contextIsOutdated()) { + tex = addTexture(img); + } + + if (tex.hasBuffers()) { + // Updates the texture AND the pixels + // array of the image at the same time, + // getting the pixels directly from the + // buffer data (avoiding expenive transfer + // beteeen video and main memory). + tex.bufferUpdate(img.pixels); + } + + if (tex.isModified()) { + // Regular pixel copy from texture. + tex.get(img.pixels); + } + } + } + */ /** * This utility method creates a texture for the provided image, and adds it @@ -5234,7 +5269,9 @@ public class PGraphicsOpenGL extends PGraphics { img.parent = parent; } Texture tex = new Texture(img.parent, img.width, img.height, params); - img.loadPixels(); + if (img.pixels == null) { + img.loadPixels(); + } if (img.pixels != null) tex.set(img.pixels); img.setCache(pgPrimary, tex); return tex; diff --git a/java/libraries/opengl/src/processing/opengl/Texture.java b/java/libraries/opengl/src/processing/opengl/Texture.java index e49a86293..534f119fd 100644 --- a/java/libraries/opengl/src/processing/opengl/Texture.java +++ b/java/libraries/opengl/src/processing/opengl/Texture.java @@ -39,10 +39,7 @@ import java.util.NoSuchElementException; * */ public class Texture implements PConstants { - public int width, height; - // texture constants - /** * This constant identifies the texture target GL_TEXTURE_2D, that is, * textures with normalized coordinates @@ -73,12 +70,9 @@ public class Texture implements PConstants { public static final int CLAMP = 0; /** This constant identifies the repeat wrapping mode */ public static final int REPEAT = 1; - - protected PApplet parent; // The Processing applet - protected PGraphicsOpenGL pg; // The main renderer - protected PGL pgl; // The interface between Processing and OpenGL. - protected PGL.Context context; // The context that created this texture. - + + public int width, height; + // These are public but use at your own risk! public int glID; public int glTarget; @@ -88,7 +82,12 @@ public class Texture implements PConstants { public int glWrapS; public int glWrapT; public int glWidth; - public int glHeight; + public int glHeight; + + protected PApplet parent; // The Processing applet + protected PGraphicsOpenGL pg; // The main renderer + protected PGL pgl; // The interface between Processing and OpenGL. + protected PGL.Context context; // The context that created this texture. protected boolean usingMipmaps; protected float maxTexcoordU; @@ -97,9 +96,11 @@ public class Texture implements PConstants { protected boolean flippedX; protected boolean flippedY; - protected int[] tempPixels = null; protected FrameBuffer tempFbo = null; - + + /** modified portion of the texture */ + protected boolean modified; + protected Object bufferSource; protected LinkedList bufferCache = null; protected Method disposeBufferMethod; @@ -211,7 +212,6 @@ public class Texture implements PConstants { // Nullifying some utility objects so they are recreated with the appropriate // size when needed. - tempPixels = null; tempFbo = null; } @@ -370,13 +370,12 @@ public class Texture implements PConstants { * Copy texture to pixels. Involves video memory to main memory transfer (slow). */ public void get(int[] pixels) { - // TODO: here is ok to create a new pixels array, or an error/warning - // should be thrown instead? - if ((pixels == null) || (pixels.length != width * height)) { - pixels = new int[width * height]; + if (pixels == null) { + 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"); } - - int size = glWidth * glHeight; if (tempFbo == null) { tempFbo = new FrameBuffer(parent, glWidth, glHeight); @@ -390,12 +389,9 @@ public class Texture implements PConstants { tempFbo.readPixels(); pg.popFramebuffer(); - if (tempPixels == null) { - tempPixels = new int[size]; - } - tempFbo.getPixels(tempPixels); + tempFbo.getPixels(pixels); + convertToARGB(pixels); - convertToARGB(tempPixels, pixels); if (flippedX) flipArrayOnX(pixels, 1); if (flippedY) flipArrayOnY(pixels, 1); } @@ -497,6 +493,26 @@ public class Texture implements PConstants { pgl.glBindTexture(glTarget, 0); } + ////////////////////////////////////////////////////////////// + + // Modified flag + + + public boolean isModified() { + return modified; + } + + + public void setModified() { + modified = true; + } + + + public void setModified(boolean m) { + modified = m; + } + + //////////////////////////////////////////////////////////// // Buffer sink interface. @@ -524,7 +540,10 @@ public class Texture implements PConstants { } } } - + + public boolean hasBufferSource() { + return bufferSource != null; + } public boolean hasBuffers() { return bufferSource != null && bufferCache != null && 0 < bufferCache.size(); @@ -543,7 +562,7 @@ public class Texture implements PConstants { if ((data.w != width) || (data.h != height)) { init(data.w, data.h); } - bind(); + bind(); setTexels(data.rgbBuf, 0, 0, width, height); unbind(); @@ -556,6 +575,34 @@ public class Texture implements PConstants { } + protected boolean bufferUpdate(int[] pixels) { + //PApplet.println("buffer update with pix"); + BufferData data = null; + try { + data = bufferCache.remove(0); + } catch (NoSuchElementException ex) { + PGraphics.showWarning("PTexture: don't have pixel data to copy to texture"); + } + + if (data != null) { + if ((data.w != width) || (data.h != height)) { + init(data.w, data.h); + } + bind(); + setTexels(data.rgbBuf, 0, 0, width, height); + unbind(); + + data.rgbBuf.get(pixels); + convertToARGB(pixels); + + data.dispose(); + + return true; + } else { + return false; + } + } + protected void getSourceMethods() { try { disposeBufferMethod = bufferSource.getClass().getMethod("disposeBuffer", new Class[] { Object.class }); @@ -715,7 +762,8 @@ public class Texture implements PConstants { * @param intArray int[] * @param intArray int[] * @param arrayFormat int - */ + */ + /* protected void convertToARGB(int[] intArray, int[] tIntArray, int arrayFormat) { int t = 0; int p = 0; @@ -760,15 +808,14 @@ public class Texture implements PConstants { } } - +*/ /** - * Reorders an OpenGL pixel array (RGBA) into ARGB. The input array must be - * of size glWidth * glHeight, while the resulting array of size width * height. - * @param intArray int[] + * Reorders an OpenGL pixel array (RGBA) into ARGB. The array must be + * of size width * height. * @param intArray int[] */ - protected void convertToARGB(int[] intArray, int[] tIntArray) { + protected void convertToARGB(int[] intArray) { int t = 0; int p = 0; if (PGL.BIG_ENDIAN) { @@ -778,9 +825,8 @@ public class Texture implements PConstants { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int pixel = intArray[p++]; - tIntArray[t++] = (pixel >> 8) | ((pixel << 24) & 0xFF000000); + intArray[t++] = (pixel >> 8) | ((pixel << 24) & 0xFF000000); } - p += glWidth - width; } } else { @@ -790,16 +836,15 @@ public class Texture implements PConstants { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int pixel = intArray[p++]; - tIntArray[t++] = ((pixel & 0xFF) << 16) | + intArray[t++] = ((pixel & 0xFF) << 16) | ((pixel & 0xFF0000) >> 16) | (pixel & 0xFF00FF00); } - p += glWidth - width; } - } } + ///////////////////////////////////////////////////////////