Pixel get/set working for offscreen PGraphics objects as well.

This commit is contained in:
codeanticode
2012-03-29 17:49:02 +00:00
parent c47839ca35
commit 1df01edee5
@@ -314,8 +314,11 @@ public class PGraphicsOpenGL extends PGraphics {
/** True if we are inside a beginDraw()/endDraw() block. */
protected boolean drawing = false;
/** True if we are inside a beginScreenOp()/endScreenOp() block. */
protected boolean screenOp = false;
/** Type of screen operation. */
static protected final int OP_NONE = 0;
static protected final int OP_READ = 1;
static protected final int OP_WRITE = 2;
protected int screenOp = OP_NONE;
/** Used to detect the occurrence of a frame resize event. */
protected boolean resized = false;
@@ -1377,12 +1380,11 @@ public class PGraphicsOpenGL extends PGraphics {
pushFramebuffer();
if (offscreenMultisample) {
setFramebuffer(offscreenFramebufferMultisample);
pgl.glDrawBuffer(PGL.GL_COLOR_ATTACHMENT0);
setFramebuffer(offscreenFramebufferMultisample);
} else {
setFramebuffer(offscreenFramebuffer);
}
}
pgl.glDrawBuffer(PGL.GL_COLOR_ATTACHMENT0);
pgl.updateOffscreen(pg.pgl);
}
@@ -1510,7 +1512,7 @@ public class PGraphicsOpenGL extends PGraphics {
}
drawing = true;
screenOp = false;
screenOp = OP_NONE;
pixelsAreDirty = true;
settingPixels = false;
@@ -1621,30 +1623,63 @@ public class PGraphicsOpenGL extends PGraphics {
}
protected void beginScreenOp() {
if (!primarySurface) {
offscreenNotCurrent = offscreenFramebuffer != currentFramebuffer;
if (offscreenNotCurrent) {
// If the surface is not primary and multisampling is on, then the framebuffer
// will be switched momentarily from offscreenFramebufferMultisample to offscreenFramebuffer.
// This is in fact correct, because the glReadPixels() function doesn't work with
// multisample framebuffer attached as the read buffer.
pushFramebuffer();
setFramebuffer(offscreenFramebuffer);
pgl.updateOffscreen(pg.pgl);
}
protected void beginScreenOp(int op) {
if (primarySurface) {
if (op == OP_READ) {
pgl.glReadBuffer(PGL.GL_FRONT);
} else {
pgl.glDrawBuffer(PGL.GL_BACK);
}
offscreenNotCurrent = false;
} else {
offscreenNotCurrent = false;
// Making sure that the offscreen FBO is current. This allows to do calls
// like loadPixels(), set() or get() without enclosing them between
// beginDraw()/endDraw() when working with a PGraphics object. We don't
// need the rest of the surface initialization/finalization, since only
// the pixels are affected.
if (op == OP_READ) {
// We always read the screen pixels from the color FBO.
offscreenNotCurrent = offscreenFramebuffer != currentFramebuffer;
if (offscreenNotCurrent) {
pushFramebuffer();
setFramebuffer(offscreenFramebuffer);
pgl.updateOffscreen(pg.pgl);
}
pgl.glReadBuffer(PGL.GL_COLOR_ATTACHMENT0);
} else {
// We can write directly to the color FBO, or to the multisample FBO
// if multisampling is enabled.
if (offscreenMultisample) {
offscreenNotCurrent = offscreenFramebufferMultisample != currentFramebuffer;
} else {
offscreenNotCurrent = offscreenFramebuffer != currentFramebuffer;
}
if (offscreenNotCurrent) {
pushFramebuffer();
if (offscreenMultisample) {
setFramebuffer(offscreenFramebufferMultisample);
} else {
setFramebuffer(offscreenFramebuffer);
}
pgl.updateOffscreen(pg.pgl);
}
pgl.glDrawBuffer(PGL.GL_COLOR_ATTACHMENT0);
}
}
screenOp = true;
screenOp = op;
}
protected void endScreenOp() {
screenOp = false;
protected void endScreenOp() {
if (offscreenNotCurrent) {
if (screenOp == OP_WRITE && offscreenMultisample) {
// We were writing to the multisample FBO, so we need
// to blit its contents to the color FBO.
offscreenFramebufferMultisample.copy(offscreenFramebuffer);
}
popFramebuffer();
}
}
screenOp = OP_NONE;
}
@@ -2249,7 +2284,7 @@ public class PGraphicsOpenGL extends PGraphics {
boolean hasPoints = 0 < tessGeo.pointVertexCount && 0 < tessGeo.pointIndexCount;
boolean hasLines = 0 < tessGeo.lineVertexCount && 0 < tessGeo.lineIndexCount;
boolean hasFill = 0 < tessGeo.fillVertexCount && 0 < tessGeo.fillIndexCount;
if (hasPoints || hasLines || hasFill) {
if (settingPixels) {
// If the user has been manipulating individual pixels,
@@ -2288,8 +2323,8 @@ public class PGraphicsOpenGL extends PGraphics {
settingPixels = false;
}
tessGeo.clear();
texCache.clear();
tessGeo.clear();
texCache.clear();
}
@@ -4610,19 +4645,18 @@ public class PGraphicsOpenGL extends PGraphics {
// Initializes the pixels array, copying the current contents of the
// color buffer into it.
public void loadPixels() {
flush();
flush();
if ((pixels == null) || (pixels.length != width * height)) {
pixels = new int[width * height];
pixelBuffer = IntBuffer.wrap(pixels);
pixelsAreDirty = true;
}
if (pixelsAreDirty) {
beginScreenOp();
beginScreenOp(OP_READ);
pixelBuffer.rewind();
pgl.glReadBuffer(PGL.GL_FRONT);
pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer);
pgl.glReadPixels(0, 0, width, height, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, pixelBuffer);
endScreenOp();
PGL.nativeToJavaARGB(pixels, width, height);
@@ -4652,7 +4686,7 @@ public class PGraphicsOpenGL extends PGraphics {
0, 0, width, height, IntBuffer.wrap(rgbaPixels));
// ...and drawing the texture to screen.
beginScreenOp();
beginScreenOp(OP_WRITE);
drawTexture();
endScreenOp();
@@ -4679,7 +4713,7 @@ public class PGraphicsOpenGL extends PGraphics {
// Draws wherever it is in the screen texture right now to the screen.
public void updateTexture() {
flush();
beginScreenOp();
beginScreenOp(OP_WRITE);
drawTexture();
endScreenOp();
}
@@ -4719,7 +4753,6 @@ public class PGraphicsOpenGL extends PGraphics {
public int get(int x, int y) {
flush();
loadPixels();
int i = y * width + x;
@@ -4746,8 +4779,7 @@ public class PGraphicsOpenGL extends PGraphics {
IntBuffer newbieBuffer = IntBuffer.allocate(w * h);
newbieBuffer.rewind();
beginScreenOp();
pgl.glReadBuffer(PGL.GL_FRONT);
beginScreenOp(OP_READ);
pgl.glReadPixels(x, height - y - h, w, h, PGL.GL_RGBA, PGL.GL_UNSIGNED_BYTE, newbieBuffer);
endScreenOp();
@@ -4759,8 +4791,7 @@ public class PGraphicsOpenGL extends PGraphics {
public void set(int x, int y, int argb) {
flush();
loadPixels();
loadPixels();
settingPixels = true;
int i = y * width + x;
@@ -4779,7 +4810,7 @@ public class PGraphicsOpenGL extends PGraphics {
PTexture tex = getTexture(source);
if (tex != null) {
beginScreenOp();
beginScreenOp(OP_WRITE);
pgl.drawTexture(tex.glTarget, tex.glID, tex.glWidth, tex.glHeight,
0, 0, tex.width, tex.height,
x, y + height, x + tex.width, y + height - tex.height);