mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
flush before changing projection matrix, fixed load pixels in GL
This commit is contained in:
@@ -350,6 +350,27 @@ public class PImage implements PConstants, Cloneable {
|
||||
if (bitmap != null) {
|
||||
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
|
||||
}
|
||||
|
||||
|
||||
if (cacheMap != null) {
|
||||
for (PGraphics pg: cacheMap.keySet()) {
|
||||
Object obj = cacheMap.get(pg);
|
||||
|
||||
Method loadPixelsMethod = null;
|
||||
try {
|
||||
loadPixelsMethod = obj.getClass().getMethod("loadPixels", new Class[] { int[].class });
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
if (loadPixelsMethod != null) {
|
||||
try {
|
||||
loadPixelsMethod.invoke(obj, new Object[] { pixels });
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -414,6 +414,10 @@ public class PGL {
|
||||
}
|
||||
|
||||
|
||||
public void setToolkit(int toolkit) {
|
||||
}
|
||||
|
||||
|
||||
public void initPrimarySurface(int antialias) {
|
||||
// We do the initialization in updatePrimary() because
|
||||
// at the moment initPrimarySurface() gets called we
|
||||
|
||||
@@ -489,7 +489,12 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
pgl.setFramerate(framerate);
|
||||
}
|
||||
|
||||
|
||||
public void setToolkit(int toolkit) {
|
||||
pgl.setToolkit(toolkit);
|
||||
}
|
||||
|
||||
|
||||
public void setSize(int iwidth, int iheight) {
|
||||
resized = (0 < width && width != iwidth) || (0 < height && height != iwidth);
|
||||
|
||||
@@ -1693,7 +1698,9 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
|
||||
popFramebuffer();
|
||||
|
||||
|
||||
texture.updateTexels(); // Mark all texels in screen texture as modified.
|
||||
|
||||
pgl.endOffscreenDraw(pgPrimary.clearColorBuffer0);
|
||||
|
||||
pgPrimary.restoreGL();
|
||||
@@ -3743,6 +3750,8 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
|
||||
public void popProjection() {
|
||||
flush(); // The geometry with the old projection matrix needs to be drawn now
|
||||
|
||||
if (projectionStackDepth == 0) {
|
||||
throw new RuntimeException(ERROR_PUSHMATRIX_UNDERFLOW);
|
||||
}
|
||||
@@ -3752,11 +3761,13 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
|
||||
public void applyProjection(PMatrix3D mat) {
|
||||
flush();
|
||||
projection.apply(mat);
|
||||
}
|
||||
|
||||
|
||||
public void setProjection(PMatrix3D mat) {
|
||||
flush();
|
||||
projection.set(mat);
|
||||
}
|
||||
|
||||
@@ -4947,7 +4958,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer);
|
||||
endPixelsOp();
|
||||
|
||||
PGL.nativeToJavaARGB(pixels, width, height);
|
||||
PGL.nativeToJavaARGB(pixels, width, height);
|
||||
}
|
||||
|
||||
|
||||
@@ -5026,22 +5037,52 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
// array, and then the pixels array into the screen texture.
|
||||
public void loadTexture() {
|
||||
if (primarySurface) {
|
||||
loadTextureImpl(POINT, false);
|
||||
loadTextureImpl(Texture.POINT, false);
|
||||
loadPixels();
|
||||
pixelsToTexture();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Draws wherever it is in the screen texture right now to the screen.
|
||||
public void updateTexture() {
|
||||
|
||||
// Draws wherever it is in the screen texture right now to the display.
|
||||
public void updateDisplay() {
|
||||
flush();
|
||||
beginPixelsOp(OP_WRITE);
|
||||
drawTexture();
|
||||
endPixelsOp();
|
||||
}
|
||||
|
||||
|
||||
// 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");
|
||||
return;
|
||||
}
|
||||
|
||||
if (texture == null || texture != img.getCache(pgPrimary)) {
|
||||
Texture.Parameters params;
|
||||
if (primarySurface) {
|
||||
params = new Texture.Parameters(ARGB, Texture.POINT, false);
|
||||
} else {
|
||||
params = new Texture.Parameters(ARGB, Texture.BILINEAR, false);
|
||||
}
|
||||
|
||||
texture = addTexture(img, params);
|
||||
|
||||
texture.setFlippedY(true);
|
||||
this.setCache(pgPrimary, texture);
|
||||
this.setParams(pgPrimary, params);
|
||||
|
||||
if (!primarySurface && offscreenFramebuffer != null) {
|
||||
// Attach as the color buffer for this offscreen surface
|
||||
offscreenFramebuffer.setColorBuffer(texture);
|
||||
offscreenFramebuffer.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void loadTextureImpl(int sampling, boolean mipmap) {
|
||||
if (width == 0 || height == 0) return;
|
||||
if (texture == null || texture.contextIsOutdated()) {
|
||||
@@ -5052,8 +5093,8 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
this.setParams(pgPrimary, params);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected void drawTexture() {
|
||||
pgl.drawTexture(texture.glTarget, texture.glID,
|
||||
texture.glWidth, texture.glHeight,
|
||||
@@ -5348,41 +5389,6 @@ 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
|
||||
@@ -5419,7 +5425,18 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
||||
protected Texture addTexture(PImage img, Texture.Parameters params) {
|
||||
Texture tex = new Texture(img.parent, img.width, img.height, params);
|
||||
if (img.pixels == null) {
|
||||
img.loadPixels();
|
||||
}
|
||||
if (img.pixels != null) tex.set(img.pixels);
|
||||
img.setCache(pgPrimary, tex);
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
||||
protected PImage wrapTexture(Texture tex) {
|
||||
// We don't use the PImage(int width, int height, int mode) constructor to
|
||||
// avoid initializing the pixels array.
|
||||
|
||||
@@ -96,8 +96,9 @@ public class Texture implements PConstants {
|
||||
|
||||
protected FrameBuffer tempFbo = null;
|
||||
|
||||
/** modified portion of the texture */
|
||||
/** Modified portion of the texture */
|
||||
protected boolean modified;
|
||||
protected int mx1, my1, mx2, my2;
|
||||
|
||||
protected Object bufferSource;
|
||||
protected LinkedList<BufferData> bufferCache = null;
|
||||
@@ -355,7 +356,9 @@ public class Texture implements PConstants {
|
||||
}
|
||||
|
||||
pgl.glBindTexture(glTarget, 0);
|
||||
pgl.disableTexturing(glTarget);
|
||||
pgl.disableTexturing(glTarget);
|
||||
|
||||
updateTexels(x, y, w, h);
|
||||
}
|
||||
|
||||
|
||||
@@ -395,6 +398,28 @@ public class Texture implements PConstants {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies the contents of the texture to the pixels array.
|
||||
* @param pixels
|
||||
*/
|
||||
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).
|
||||
bufferUpdate(pixels);
|
||||
}
|
||||
|
||||
if (isModified()) {
|
||||
PApplet.println("Getting pixels from texture...");
|
||||
// Regular pixel copy from texture.
|
||||
get(pixels);
|
||||
}
|
||||
|
||||
setModified(false);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// Put methods (the source texture is not resized to cover the entire
|
||||
@@ -481,16 +506,19 @@ public class Texture implements PConstants {
|
||||
|
||||
// Bind/unbind
|
||||
|
||||
|
||||
public void bind() {
|
||||
pgl.enableTexturing(glTarget);
|
||||
pgl.glBindTexture(glTarget, glID);
|
||||
}
|
||||
|
||||
|
||||
public void unbind() {
|
||||
pgl.enableTexturing(glTarget);
|
||||
pgl.glBindTexture(glTarget, 0);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// Modified flag
|
||||
@@ -509,7 +537,64 @@ public class Texture implements PConstants {
|
||||
public void setModified(boolean m) {
|
||||
modified = m;
|
||||
}
|
||||
|
||||
|
||||
public int getModifiedX1() {
|
||||
return mx1;
|
||||
}
|
||||
|
||||
|
||||
public int getModifiedX2() {
|
||||
return mx2;
|
||||
}
|
||||
|
||||
|
||||
public int getModifiedY1() {
|
||||
return my1;
|
||||
}
|
||||
|
||||
|
||||
public int getModifiedY2() {
|
||||
return my2;
|
||||
}
|
||||
|
||||
|
||||
public void updateTexels() {
|
||||
updateTexelsImpl(0, 0, width, height);
|
||||
}
|
||||
|
||||
|
||||
public void updateTexels(int x, int y, int w, int h) {
|
||||
updateTexelsImpl(x, y, w, h);
|
||||
}
|
||||
|
||||
|
||||
protected void updateTexelsImpl(int x, int y, int w, int h) {
|
||||
int x2 = x + w;
|
||||
int y2 = y + h;
|
||||
|
||||
if (!modified) {
|
||||
mx1 = PApplet.max(0, x);
|
||||
mx2 = PApplet.min(width - 1, x2);
|
||||
my1 = PApplet.max(0, y);
|
||||
my2 = PApplet.min(height - 1, y2);
|
||||
modified = true;
|
||||
|
||||
} else {
|
||||
if (x < mx1) mx1 = PApplet.max(0, x);
|
||||
if (x > mx2) mx2 = PApplet.min(width - 1, x);
|
||||
if (y < my1) my1 = PApplet.max(0, y);
|
||||
if (y > my2) my2 = y;
|
||||
|
||||
if (x2 < mx1) mx1 = PApplet.max(0, x2);
|
||||
if (x2 > mx2) mx2 = PApplet.min(width - 1, x2);
|
||||
if (y2 < my1) my1 = PApplet.max(0, y2);
|
||||
if (y2 > my2) my2 = PApplet.min(height - 1, y2);
|
||||
}
|
||||
|
||||
PApplet.println("Marking texels @" + x + "," + y + " " + w + "x" + h + " as updated");
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -538,11 +623,13 @@ public class Texture implements PConstants {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean hasBufferSource() {
|
||||
return bufferSource != null;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasBuffers() {
|
||||
return bufferSource != null && bufferCache != null && 0 < bufferCache.size();
|
||||
}
|
||||
@@ -571,10 +658,9 @@ public class Texture implements PConstants {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected boolean bufferUpdate(int[] pixels) {
|
||||
//PApplet.println("buffer update with pix");
|
||||
BufferData data = null;
|
||||
try {
|
||||
data = bufferCache.remove(0);
|
||||
@@ -600,6 +686,7 @@ public class Texture implements PConstants {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void getSourceMethods() {
|
||||
try {
|
||||
@@ -609,6 +696,7 @@ public class Texture implements PConstants {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// Utilities
|
||||
@@ -933,6 +1021,7 @@ public class Texture implements PConstants {
|
||||
return outdated;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// Utilities.
|
||||
@@ -969,24 +1058,32 @@ public class Texture implements PConstants {
|
||||
x, y, w, h, x, y, w, h);
|
||||
}
|
||||
pg.popFramebuffer();
|
||||
updateTexels(x, y, w, h);
|
||||
}
|
||||
|
||||
|
||||
protected void setTexels(int[] pix, int x, int y, int w, int h) {
|
||||
setTexels(pix, 0, x, y, w, h);
|
||||
}
|
||||
|
||||
|
||||
protected void setTexels(int[] pix, int level, int x, int y, int w, int h) {
|
||||
pgl.glTexSubImage2D(glTarget, level, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, IntBuffer.wrap(pix));
|
||||
updateTexels(x, y, w, h);
|
||||
}
|
||||
|
||||
|
||||
protected void setTexels(IntBuffer buffer, int x, int y, int w, int h) {
|
||||
setTexels(buffer, 0, x, y, w, h);
|
||||
}
|
||||
|
||||
|
||||
protected void setTexels(IntBuffer buffer, int level, int x, int y, int w, int h) {
|
||||
pgl.glTexSubImage2D(glTarget, level, x, y, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, buffer);
|
||||
updateTexels(x, y, w, h);
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
@@ -1014,7 +1111,8 @@ public class Texture implements PConstants {
|
||||
flippedX = src.flippedX;
|
||||
flippedY = src.flippedY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// Parameter handling
|
||||
|
||||
Reference in New Issue
Block a user