mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
resize pixels in setSize() if they are being used
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user