resize pixels in setSize() if they are being used

This commit is contained in:
codeanticode
2012-06-22 18:30:39 +00:00
parent c9980a27c2
commit 8d3c01495a
4 changed files with 124 additions and 48 deletions
+35 -16
View File
@@ -316,12 +316,10 @@ public class PGL {
// FBO for incremental drawing
protected boolean firstOnscreenFrame = true;
protected int[] textures = { 0, 0 };
protected int[] fbo = { 0 };
protected int[] depth = { 0 };
protected int[] stencil = { 0 };
protected int texWidth, texHeight;
protected int backTex, frontTex;
protected int backTex, frontTex;
protected int[] colorTex = { 0, 0 };
protected int[] colorFBO = { 0 };
///////////////////////////////////////////////////////////////////////////////////
@@ -431,6 +429,9 @@ public class PGL {
public void updatePrimary() {
if (!initialized) {
int[] depth = { 0 };
int[] stencil = { 0 };
String ext = GLES20.glGetString(GLES20.GL_EXTENSIONS);
if (-1 < ext.indexOf("texture_non_power_of_two")) {
texWidth = pg.width;
@@ -443,9 +444,9 @@ public class PGL {
// We create the GL resources we need to draw incrementally, ie: not clearing
// the screen in each frame. Because the way Android handles double buffering
// we need to handle our own custom buffering using FBOs.
GLES20.glGenTextures(2, textures, 0);
GLES20.glGenTextures(2, colorTex, 0);
for (int i = 0; i < 2; i++) {
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[i]);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, colorTex[i]);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
@@ -455,10 +456,10 @@ public class PGL {
}
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
GLES20.glGenFramebuffers(1, fbo, 0);
GLES20.glGenFramebuffers(1, colorFBO, 0);
GLES20.glGenRenderbuffers(1, depth, 0);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo[0]);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, colorFBO[0]);
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depth[0]);
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, texWidth, texHeight);
@@ -483,7 +484,7 @@ public class PGL {
// to update the screenFramebuffer object so when the
// framebuffer is popped back to the screen, the correct
// id is set.
PGraphicsOpenGL.screenFramebuffer.glFboID = fbo[0];
PGraphicsOpenGL.screenFramebuffer.glFboID = colorFBO[0];
initialized = true;
}
@@ -496,10 +497,27 @@ public class PGL {
public boolean primaryIsDoubleBuffered() {
return true;
return colorFBO[0] == 0;
}
public boolean usingPrimaryFBO() {
return colorFBO[0] != 0;
}
public void bindPrimaryColorFBO() {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, colorFBO[0]);
PGraphicsOpenGL.screenFramebuffer.glFboID = colorFBO[0];
}
public void bindPrimaryMultiFBO() {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, colorFBO[0]);
PGraphicsOpenGL.screenFramebuffer.glFboID = colorFBO[0];
}
///////////////////////////////////////////////////////////////////////////////////
// Frame rendering
@@ -513,8 +531,8 @@ public class PGL {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
PGraphicsOpenGL.screenFramebuffer.glFboID = 0;
} else {
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo[0]);
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, textures[frontTex], 0);
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, colorFBO[0]);
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, colorTex[frontTex], 0);
validateFramebuffer();
// We need to save the color buffer after finishing with the rendering of this frame,
@@ -526,9 +544,9 @@ public class PGL {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
} else {
// Render previous draw texture as background.
drawTexture(GLES20.GL_TEXTURE_2D, textures[backTex], texWidth, texHeight, 0, 0, pg.width, pg.height, 0, 0, pg.width, pg.height);
drawTexture(GLES20.GL_TEXTURE_2D, colorTex[backTex], texWidth, texHeight, 0, 0, pg.width, pg.height, 0, 0, pg.width, pg.height);
}
PGraphicsOpenGL.screenFramebuffer.glFboID = fbo[0];
PGraphicsOpenGL.screenFramebuffer.glFboID = colorFBO[0];
}
if (firstOnscreenFrame) {
@@ -543,11 +561,12 @@ public class PGL {
// contents of the front buffer needs to be used in the next frame as the background.
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
GLES20.glClearDepthf(1);
GLES20.glClearColor(0, 0, 0, 0);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
// Render current front texture to screen.
drawTexture(GLES20.GL_TEXTURE_2D, textures[frontTex], texWidth, texHeight, 0, 0, pg.width, pg.height, 0, 0, pg.width, pg.height);
drawTexture(GLES20.GL_TEXTURE_2D, colorTex[frontTex], texWidth, texHeight, 0, 0, pg.width, pg.height, 0, 0, pg.width, pg.height);
// Swapping front and back textures.
int temp = frontTex;
@@ -488,6 +488,11 @@ public class PGraphicsOpenGL extends PGraphics {
height = iheight;
// width1 = width - 1;
// height1 = height - 1;
if (pixels != null) {
// The user is using the pixels array, so we need to resize accordingly
allocatePixels();
}
allocate();
reapplySettings();
@@ -500,7 +505,7 @@ public class PGraphicsOpenGL extends PGraphics {
cameraNear = cameraZ / 10.0f;
cameraFar = cameraZ * 10.0f;
cameraAspect = (float) width / (float) height;
// set this flag so that beginDraw() will do an update to the camera.
sizeChanged = true;
@@ -1756,8 +1761,19 @@ public class PGraphicsOpenGL extends PGraphics {
} else {
pgl.glDrawBuffer(PGL.GL_BACK);
}
}
offscreenNotCurrent = false;
offscreenNotCurrent = false;
} else if (pgl.usingPrimaryFBO()) {
if (op == OP_READ) {
// We read from the color FBO, but the multisample FBO is currently bound, so:
offscreenNotCurrent = true;
pgl.bindPrimaryColorFBO();
pgl.glReadBuffer(PGL.GL_COLOR_ATTACHMENT0);
} else {
// We write directly to the multisample FBO.
offscreenNotCurrent = false;
pgl.glDrawBuffer(PGL.GL_COLOR_ATTACHMENT0);
}
}
} else {
// Making sure that the offscreen FBO is current. This allows to do calls
// like loadPixels(), set() or get() without enclosing them between
@@ -1799,12 +1815,16 @@ public class PGraphicsOpenGL extends PGraphics {
protected void endPixelsOp() {
if (offscreenNotCurrent) {
if (pixelsOp == OP_WRITE && offscreenMultisample) {
// We were writing to the multisample FBO, so we need
// to blit its contents to the color FBO.
offscreenFramebufferMultisample.copy(offscreenFramebuffer);
if (primarySurface) {
pgl.bindPrimaryMultiFBO();
} else {
if (pixelsOp == 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();
}
popFramebuffer();
}
pixelsOp = OP_NONE;
}
@@ -4816,10 +4836,10 @@ public class PGraphicsOpenGL extends PGraphics {
}
allocatePixels();
if (!setgetPixels) {
readPixels();
if (primarySurface) {
loadTextureImpl(POINT, false);
pixelsToTexture();
@@ -4852,9 +4872,9 @@ public class PGraphicsOpenGL extends PGraphics {
protected void readPixels() {
beginPixelsOp(OP_READ);
beginPixelsOp(OP_READ);
pixelBuffer.rewind();
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);
endPixelsOp();
PGL.nativeToJavaARGB(pixels, width, height);
@@ -4869,16 +4889,16 @@ public class PGraphicsOpenGL extends PGraphics {
rgbaPixels = new int[len];
}
PApplet.arrayCopy(pixels, i0, rgbaPixels, 0, len);
PApplet.arrayCopy(pixels, i0, rgbaPixels, 0, len);
PGL.javaToNativeARGB(rgbaPixels, w, h);
// Copying pixel buffer to screen texture...
if (primarySurface) {
loadTextureImpl(POINT, false); // (first making sure that the screen texture is valid).
}
}
pgl.copyToTexture(texture.glTarget, texture.glFormat, texture.glID,
x, y, w, h, IntBuffer.wrap(rgbaPixels));
if (primarySurface || offscreenMultisample) {
// ...and drawing the texture to screen... but only
// if we are on the primary surface or we have
@@ -501,7 +501,7 @@ public class PGL {
if (ENABLE_SMOOTH_LION_HACK) {
needScreenFBO = false;
if (colorFBO[0] != 0) {
releaseFBO();
releaseScreenFBO();
colorFBO[0] = 0;
}
String osName = System.getProperty("os.name");
@@ -689,7 +689,24 @@ public class PGL {
}
protected void releaseFBO() {
public boolean usingPrimaryFBO() {
return colorFBO[0] != 0;
}
public void bindPrimaryColorFBO() {
gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, colorFBO[0]);
PGraphicsOpenGL.screenFramebuffer.glFboID = colorFBO[0];
}
public void bindPrimaryMultiFBO() {
gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, multiFBO[0]);
PGraphicsOpenGL.screenFramebuffer.glFboID = multiFBO[0];
}
protected void releaseScreenFBO() {
gl.glDeleteTextures(1, colorTex, 0);
gl.glDeleteFramebuffers(1, colorFBO, 0);
gl.glDeleteFramebuffers(1, multiFBO, 0);
@@ -488,6 +488,11 @@ public class PGraphicsOpenGL extends PGraphics {
height = iheight;
// width1 = width - 1;
// height1 = height - 1;
if (pixels != null) {
// The user is using the pixels array, so we need to resize accordingly
allocatePixels();
}
allocate();
reapplySettings();
@@ -500,7 +505,7 @@ public class PGraphicsOpenGL extends PGraphics {
cameraNear = cameraZ / 10.0f;
cameraFar = cameraZ * 10.0f;
cameraAspect = (float) width / (float) height;
// set this flag so that beginDraw() will do an update to the camera.
sizeChanged = true;
@@ -1756,8 +1761,19 @@ public class PGraphicsOpenGL extends PGraphics {
} else {
pgl.glDrawBuffer(PGL.GL_BACK);
}
}
offscreenNotCurrent = false;
offscreenNotCurrent = false;
} else if (pgl.usingPrimaryFBO()) {
if (op == OP_READ) {
// We read from the color FBO, but the multisample FBO is currently bound, so:
offscreenNotCurrent = true;
pgl.bindPrimaryColorFBO();
pgl.glReadBuffer(PGL.GL_COLOR_ATTACHMENT0);
} else {
// We write directly to the multisample FBO.
offscreenNotCurrent = false;
pgl.glDrawBuffer(PGL.GL_COLOR_ATTACHMENT0);
}
}
} else {
// Making sure that the offscreen FBO is current. This allows to do calls
// like loadPixels(), set() or get() without enclosing them between
@@ -1799,12 +1815,16 @@ public class PGraphicsOpenGL extends PGraphics {
protected void endPixelsOp() {
if (offscreenNotCurrent) {
if (pixelsOp == OP_WRITE && offscreenMultisample) {
// We were writing to the multisample FBO, so we need
// to blit its contents to the color FBO.
offscreenFramebufferMultisample.copy(offscreenFramebuffer);
if (primarySurface) {
pgl.bindPrimaryMultiFBO();
} else {
if (pixelsOp == 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();
}
popFramebuffer();
}
pixelsOp = OP_NONE;
}
@@ -4816,10 +4836,10 @@ public class PGraphicsOpenGL extends PGraphics {
}
allocatePixels();
if (!setgetPixels) {
readPixels();
if (primarySurface) {
loadTextureImpl(POINT, false);
pixelsToTexture();
@@ -4852,9 +4872,9 @@ public class PGraphicsOpenGL extends PGraphics {
protected void readPixels() {
beginPixelsOp(OP_READ);
beginPixelsOp(OP_READ);
pixelBuffer.rewind();
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);
endPixelsOp();
PGL.nativeToJavaARGB(pixels, width, height);
@@ -4869,16 +4889,16 @@ public class PGraphicsOpenGL extends PGraphics {
rgbaPixels = new int[len];
}
PApplet.arrayCopy(pixels, i0, rgbaPixels, 0, len);
PApplet.arrayCopy(pixels, i0, rgbaPixels, 0, len);
PGL.javaToNativeARGB(rgbaPixels, w, h);
// Copying pixel buffer to screen texture...
if (primarySurface) {
loadTextureImpl(POINT, false); // (first making sure that the screen texture is valid).
}
}
pgl.copyToTexture(texture.glTarget, texture.glFormat, texture.glID,
x, y, w, h, IntBuffer.wrap(rgbaPixels));
if (primarySurface || offscreenMultisample) {
// ...and drawing the texture to screen... but only
// if we are on the primary surface or we have