mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
FBO layer is enabled when sketch tries to use the front texture (prev. frame) or shader filter
This commit is contained in:
@@ -52,27 +52,18 @@ import android.opengl.GLU;
|
||||
*
|
||||
*/
|
||||
public class PGL {
|
||||
public static final boolean USE_DIRECT_BUFFERS = false;
|
||||
public static final int MIN_DIRECT_BUFFER_SIZE = 1;
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// Parameters
|
||||
|
||||
public static boolean FORCE_SCREEN_FBO = false;
|
||||
public static final boolean USE_DIRECT_BUFFERS = false;
|
||||
public static final int MIN_DIRECT_BUFFER_SIZE = 1;
|
||||
public static final boolean SAVE_SURFACE_TO_PIXELS = false;
|
||||
|
||||
/** Size of a short (in bytes). */
|
||||
protected static final int SIZEOF_SHORT = Short.SIZE / 8;
|
||||
|
||||
/** Size of an int (in bytes). */
|
||||
protected static final int SIZEOF_INT = Integer.SIZE / 8;
|
||||
|
||||
/** Size of a float (in bytes). */
|
||||
protected static final int SIZEOF_FLOAT = Float.SIZE / 8;
|
||||
|
||||
/** Size of a byte (in bytes). */
|
||||
protected static final int SIZEOF_BYTE = Byte.SIZE / 8;
|
||||
|
||||
/** Size of a vertex index. */
|
||||
protected static final int SIZEOF_INDEX = SIZEOF_SHORT;
|
||||
|
||||
/** Type of a vertex index. */
|
||||
protected static final int INDEX_TYPE = GLES20.GL_UNSIGNED_SHORT;
|
||||
/** Enables/disables mipmap use. **/
|
||||
protected static final boolean MIPMAPS_ENABLED = false;
|
||||
|
||||
/** Initial sizes for arrays of input and tessellated data. */
|
||||
protected static final int DEFAULT_IN_VERTICES = 16;
|
||||
@@ -115,8 +106,12 @@ public class PGL {
|
||||
/** Minimum array size to use arrayCopy method(). **/
|
||||
protected static final int MIN_ARRAYCOPY_SIZE = 2;
|
||||
|
||||
/** Enables/disables mipmap use. **/
|
||||
protected static final boolean MIPMAPS_ENABLED = false;
|
||||
protected static final int SIZEOF_SHORT = Short.SIZE / 8;
|
||||
protected static final int SIZEOF_INT = Integer.SIZE / 8;
|
||||
protected static final int SIZEOF_FLOAT = Float.SIZE / 8;
|
||||
protected static final int SIZEOF_BYTE = Byte.SIZE / 8;
|
||||
protected static final int SIZEOF_INDEX = SIZEOF_SHORT;
|
||||
protected static final int INDEX_TYPE = GLES20.GL_UNSIGNED_SHORT;
|
||||
|
||||
/** Machine Epsilon for float precision. **/
|
||||
protected static float FLOAT_EPS = Float.MIN_VALUE;
|
||||
@@ -145,7 +140,7 @@ public class PGL {
|
||||
"precision mediump int;\n" +
|
||||
"#endif\n";
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// OpenGL constants
|
||||
|
||||
@@ -349,11 +344,15 @@ public class PGL {
|
||||
|
||||
// FBO layer
|
||||
|
||||
public static boolean FORCE_SCREEN_FBO = false;
|
||||
protected static boolean fboLayerByDefault = FORCE_SCREEN_FBO;
|
||||
protected static boolean fboLayerCreated = false;
|
||||
protected static boolean fboLayerInUse = false;
|
||||
protected static boolean firstFrame = true;
|
||||
protected static int reqNumSamples;
|
||||
protected static int numSamples;
|
||||
protected static IntBuffer glColorFbo;
|
||||
protected static IntBuffer glMultiFbo;
|
||||
protected static IntBuffer glColorBuf;
|
||||
protected static IntBuffer glColorTex;
|
||||
protected static IntBuffer glDepthStencil;
|
||||
protected static IntBuffer glDepth;
|
||||
@@ -423,6 +422,8 @@ public class PGL {
|
||||
if (glColorTex == null) {
|
||||
glColorTex = allocateIntBuffer(2);
|
||||
glColorFbo = allocateIntBuffer(1);
|
||||
glMultiFbo = allocateIntBuffer(1);
|
||||
glColorBuf = allocateIntBuffer(1);
|
||||
glDepthStencil = allocateIntBuffer(1);
|
||||
glDepth = allocateIntBuffer(1);
|
||||
glStencil = allocateIntBuffer(1);
|
||||
@@ -442,10 +443,7 @@ public class PGL {
|
||||
|
||||
|
||||
protected void initSurface(int antialias) {
|
||||
// We do the initialization in updatePrimary() because
|
||||
// at the moment initPrimarySurface() gets called we
|
||||
// cannot rely on the GL surface being actually
|
||||
// available.
|
||||
reqNumSamples = qualityToSamples(antialias);
|
||||
fboLayerCreated = false;
|
||||
fboLayerInUse = false;
|
||||
firstFrame = true;
|
||||
@@ -456,6 +454,8 @@ public class PGL {
|
||||
if (glColorTex != null) {
|
||||
deleteTextures(2, glColorTex);
|
||||
deleteFramebuffers(1, glColorFbo);
|
||||
deleteFramebuffers(1, glMultiFbo);
|
||||
deleteRenderbuffers(1, glColorBuf);
|
||||
deleteRenderbuffers(1, glDepthStencil);
|
||||
deleteRenderbuffers(1, glDepth);
|
||||
deleteRenderbuffers(1, glStencil);
|
||||
@@ -477,6 +477,13 @@ public class PGL {
|
||||
fboHeight = nextPowerOfTwo(pg.height);
|
||||
}
|
||||
|
||||
if (-1 < ext.indexOf("_framebuffer_multisample")) {
|
||||
numSamples = reqNumSamples;
|
||||
} else {
|
||||
numSamples = 1;
|
||||
}
|
||||
boolean multisample = 1 < numSamples;
|
||||
|
||||
boolean packed = ext.indexOf("packed_depth_stencil") != -1;
|
||||
int depthBits = getDepthBits();
|
||||
int stencilBits = getStencilBits();
|
||||
@@ -502,18 +509,38 @@ public class PGL {
|
||||
framebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_2D,
|
||||
glColorTex.get(backTex), 0);
|
||||
|
||||
if (multisample) {
|
||||
// Creating multisampled FBO
|
||||
genFramebuffers(1, glMultiFbo);
|
||||
bindFramebuffer(FRAMEBUFFER, glMultiFbo.get(0));
|
||||
|
||||
// color render buffer...
|
||||
genRenderbuffers(1, glColorBuf);
|
||||
bindRenderbuffer(RENDERBUFFER, glColorBuf.get(0));
|
||||
renderbufferStorageMultisample(RENDERBUFFER, numSamples,
|
||||
RGBA8, fboWidth, fboHeight);
|
||||
framebufferRenderbuffer(FRAMEBUFFER, COLOR_ATTACHMENT0,
|
||||
RENDERBUFFER, glColorBuf.get(0));
|
||||
}
|
||||
|
||||
// Creating depth and stencil buffers
|
||||
if (packed && depthBits == 24 && stencilBits == 8) {
|
||||
// packed depth+stencil buffer
|
||||
|
||||
genRenderbuffers(1, glDepthStencil);
|
||||
bindRenderbuffer(RENDERBUFFER, glDepthStencil.get(0));
|
||||
renderbufferStorage(RENDERBUFFER, DEPTH24_STENCIL8,
|
||||
fboWidth, fboHeight);
|
||||
if (multisample) {
|
||||
renderbufferStorageMultisample(RENDERBUFFER, numSamples,
|
||||
DEPTH24_STENCIL8, fboWidth, fboHeight);
|
||||
} else {
|
||||
renderbufferStorage(RENDERBUFFER, DEPTH24_STENCIL8,
|
||||
fboWidth, fboHeight);
|
||||
}
|
||||
framebufferRenderbuffer(FRAMEBUFFER, DEPTH_ATTACHMENT, RENDERBUFFER,
|
||||
glDepthStencil.get(0));
|
||||
framebufferRenderbuffer(FRAMEBUFFER, STENCIL_ATTACHMENT, RENDERBUFFER,
|
||||
glDepthStencil.get(0));
|
||||
} else { // separate depth and stencil buffers
|
||||
} else {
|
||||
// separate depth and stencil buffers
|
||||
if (0 < depthBits) {
|
||||
int depthComponent = DEPTH_COMPONENT16;
|
||||
if (depthBits == 32) {
|
||||
@@ -526,7 +553,13 @@ public class PGL {
|
||||
|
||||
genRenderbuffers(1, glDepth);
|
||||
bindRenderbuffer(RENDERBUFFER, glDepth.get(0));
|
||||
renderbufferStorage(RENDERBUFFER, depthComponent, fboWidth, fboHeight);
|
||||
if (multisample) {
|
||||
renderbufferStorageMultisample(RENDERBUFFER, numSamples,
|
||||
depthComponent, fboWidth, fboHeight);
|
||||
} else {
|
||||
renderbufferStorage(RENDERBUFFER, depthComponent,
|
||||
fboWidth, fboHeight);
|
||||
}
|
||||
framebufferRenderbuffer(FRAMEBUFFER, DEPTH_ATTACHMENT,
|
||||
RENDERBUFFER, glDepth.get(0));
|
||||
}
|
||||
@@ -543,19 +576,25 @@ public class PGL {
|
||||
|
||||
genRenderbuffers(1, glStencil);
|
||||
bindRenderbuffer(RENDERBUFFER, glStencil.get(0));
|
||||
renderbufferStorage(RENDERBUFFER, stencilIndex, fboWidth, fboHeight);
|
||||
if (multisample) {
|
||||
renderbufferStorageMultisample(RENDERBUFFER, numSamples,
|
||||
stencilIndex, fboWidth, fboHeight);
|
||||
} else {
|
||||
renderbufferStorage(RENDERBUFFER, stencilIndex,
|
||||
fboWidth, fboHeight);
|
||||
}
|
||||
framebufferRenderbuffer(FRAMEBUFFER, STENCIL_ATTACHMENT,
|
||||
RENDERBUFFER, glStencil.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
validateFramebuffer();
|
||||
|
||||
// Clear the depth and stencil buffers in the color FBO. There is no
|
||||
// need to clear the color buffers because the textures attached were
|
||||
// properly initialized blank.
|
||||
// Clear all buffers.
|
||||
clearDepth(1);
|
||||
clearStencil(0);
|
||||
clear(DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT);
|
||||
clearColor(0, 0, 0, 0);
|
||||
clear(DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT | COLOR_BUFFER_BIT);
|
||||
|
||||
bindFramebuffer(FRAMEBUFFER, 0);
|
||||
|
||||
@@ -605,6 +644,11 @@ public class PGL {
|
||||
}
|
||||
|
||||
|
||||
protected void needFBOLayer() {
|
||||
FORCE_SCREEN_FBO = true;
|
||||
}
|
||||
|
||||
|
||||
protected boolean isMultisampled() {
|
||||
return false;
|
||||
}
|
||||
@@ -697,7 +741,24 @@ public class PGL {
|
||||
|
||||
|
||||
protected void syncBackTexture() {
|
||||
// Nothing to do because there is no MSAA in GLES20
|
||||
if (1 < numSamples) {
|
||||
bindFramebuffer(READ_FRAMEBUFFER, glMultiFbo.get(0));
|
||||
bindFramebuffer(DRAW_FRAMEBUFFER, glColorFbo.get(0));
|
||||
blitFramebuffer(0, 0, fboWidth, fboHeight,
|
||||
0, 0, fboWidth, fboHeight,
|
||||
COLOR_BUFFER_BIT, NEAREST);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected int qualityToSamples(int quality) {
|
||||
if (quality <= 1) {
|
||||
return 1;
|
||||
} else {
|
||||
// Number of samples is always an even number:
|
||||
int n = 2 * (quality / 2);
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -707,10 +768,15 @@ public class PGL {
|
||||
|
||||
|
||||
protected void beginDraw(boolean clear0) {
|
||||
if ((!clear0 || FORCE_SCREEN_FBO) && glColorFbo.get(0) != 0) {
|
||||
if (fboLayerInUse(clear0)) {
|
||||
bindFramebuffer(FRAMEBUFFER, glColorFbo.get(0));
|
||||
framebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0,
|
||||
TEXTURE_2D, glColorTex.get(backTex), 0);
|
||||
|
||||
if (1 < numSamples) {
|
||||
bindFramebuffer(FRAMEBUFFER, glMultiFbo.get(0));
|
||||
}
|
||||
|
||||
if (firstFrame) {
|
||||
// No need to draw back color buffer because we are in the first frame.
|
||||
clearColor(0, 0, 0, 0);
|
||||
@@ -722,6 +788,7 @@ public class PGL {
|
||||
fboWidth, fboHeight, 0, 0, pg.width, pg.height,
|
||||
0, 0, pg.width, pg.height);
|
||||
}
|
||||
|
||||
fboLayerInUse = true;
|
||||
} else {
|
||||
fboLayerInUse = false;
|
||||
@@ -730,11 +797,21 @@ public class PGL {
|
||||
if (firstFrame) {
|
||||
firstFrame = false;
|
||||
}
|
||||
|
||||
if (!fboLayerByDefault) {
|
||||
// The result of this assignment is the following: if the user requested
|
||||
// at some point the use of the FBO layer, but subsequently didn't do
|
||||
// request it again, then the rendering won't use the FBO layer if not
|
||||
// needed, since it is slower than simple onscreen rendering.
|
||||
FORCE_SCREEN_FBO = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void endDraw(boolean clear) {
|
||||
if (fboLayerInUse) {
|
||||
syncBackTexture();
|
||||
|
||||
// Draw the contents of the back texture to the screen framebuffer.
|
||||
bindFramebuffer(FRAMEBUFFER, 0);
|
||||
|
||||
@@ -772,6 +849,12 @@ public class PGL {
|
||||
}
|
||||
|
||||
|
||||
protected boolean fboLayerInUse(boolean clear0) {
|
||||
boolean cond = !clear0 || FORCE_SCREEN_FBO || 1 < numSamples;
|
||||
return cond && glColorFbo.get(0) != 0;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// Caps query
|
||||
|
||||
@@ -5365,6 +5365,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
return;
|
||||
}
|
||||
|
||||
pgl.needFBOLayer();
|
||||
loadTexture();
|
||||
if (filterTexture == null || filterTexture.contextIsOutdated()) {
|
||||
filterTexture = new Texture(parent, texture.width, texture.height,
|
||||
@@ -6511,6 +6512,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
@Override
|
||||
public void unbind() {
|
||||
if (-1 < pframeSamplerLoc) {
|
||||
pgl.needFBOLayer();
|
||||
pgl.activeTexture(PGL.TEXTURE0 + lastTexUnit);
|
||||
pgCurrent.unbindBackTexture();
|
||||
pgl.activeTexture(PGL.TEXTURE0);
|
||||
|
||||
@@ -72,32 +72,19 @@ import com.jogamp.opengl.util.AnimatorBase;
|
||||
*/
|
||||
@SuppressWarnings("static-access")
|
||||
public class PGL {
|
||||
public static final boolean USE_JOGL_FBOLAYER = true;
|
||||
public static final boolean USE_DIRECT_BUFFERS = true;
|
||||
public static final int MIN_DIRECT_BUFFER_SIZE = 1;
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// Parameters
|
||||
|
||||
public static final boolean USE_JOGL_FBOLAYER = false;
|
||||
public static boolean FORCE_SCREEN_FBO = false;
|
||||
public static final boolean USE_DIRECT_BUFFERS = true;
|
||||
public static final int MIN_DIRECT_BUFFER_SIZE = 1;
|
||||
public static final boolean SAVE_SURFACE_TO_PIXELS = true;
|
||||
|
||||
// The two windowing toolkits available to use in JOGL:
|
||||
protected static final int AWT = 0; // http://jogamp.org/wiki/index.php/Using_JOGL_in_AWT_SWT_and_Swing
|
||||
protected static final int NEWT = 1; // http://jogamp.org/jogl/doc/NEWT-Overview.html
|
||||
|
||||
/** Size of a short (in bytes). */
|
||||
protected static final int SIZEOF_SHORT = Short.SIZE / 8;
|
||||
|
||||
/** Size of an int (in bytes). */
|
||||
protected static final int SIZEOF_INT = Integer.SIZE / 8;
|
||||
|
||||
/** Size of a float (in bytes). */
|
||||
protected static final int SIZEOF_FLOAT = Float.SIZE / 8;
|
||||
|
||||
/** Size of a byte (in bytes). */
|
||||
protected static final int SIZEOF_BYTE = Byte.SIZE / 8;
|
||||
|
||||
/** Size of a vertex index. */
|
||||
protected static final int SIZEOF_INDEX = SIZEOF_SHORT;
|
||||
|
||||
/** Type of a vertex index. */
|
||||
protected static final int INDEX_TYPE = GL.GL_UNSIGNED_SHORT;
|
||||
/** Enables/disables mipmap use. **/
|
||||
protected static final boolean MIPMAPS_ENABLED = true;
|
||||
|
||||
/** Initial sizes for arrays of input and tessellated data. */
|
||||
protected static final int DEFAULT_IN_VERTICES = 64;
|
||||
@@ -140,8 +127,30 @@ public class PGL {
|
||||
/** Minimum array size to use arrayCopy method(). **/
|
||||
protected static final int MIN_ARRAYCOPY_SIZE = 2;
|
||||
|
||||
/** Enables/disables mipmap use. **/
|
||||
protected static final boolean MIPMAPS_ENABLED = true;
|
||||
/** JOGL's windowing toolkit */
|
||||
// The two windowing toolkits available to use in JOGL:
|
||||
protected static final int AWT = 0; // http://jogamp.org/wiki/index.php/Using_JOGL_in_AWT_SWT_and_Swing
|
||||
protected static final int NEWT = 1; // http://jogamp.org/jogl/doc/NEWT-Overview.html
|
||||
protected static int toolkit = NEWT;
|
||||
|
||||
/** Enables/disables use of animator */
|
||||
protected static boolean useAnimator = false;
|
||||
|
||||
protected static boolean enable_screen_FBO_macosx = true;
|
||||
protected static boolean enable_screen_FBO_windows = true;
|
||||
protected static boolean enable_screen_FBO_linux = true;
|
||||
protected static boolean enable_screen_FBO_other = true;
|
||||
|
||||
protected static int request_depth_bits = 24;
|
||||
protected static int request_stencil_bits = 8;
|
||||
protected static int request_alpha_bits = 8;
|
||||
|
||||
protected static final int SIZEOF_SHORT = Short.SIZE / 8;
|
||||
protected static final int SIZEOF_INT = Integer.SIZE / 8;
|
||||
protected static final int SIZEOF_FLOAT = Float.SIZE / 8;
|
||||
protected static final int SIZEOF_BYTE = Byte.SIZE / 8;
|
||||
protected static final int SIZEOF_INDEX = SIZEOF_SHORT;
|
||||
protected static final int INDEX_TYPE = GL.GL_UNSIGNED_SHORT;
|
||||
|
||||
/** Machine Epsilon for float precision. **/
|
||||
protected static float FLOAT_EPS = Float.MIN_VALUE;
|
||||
@@ -356,9 +365,7 @@ public class PGL {
|
||||
/** Selected GL profile */
|
||||
public static GLProfile profile;
|
||||
|
||||
/** OpenGL thread:
|
||||
* TODO
|
||||
* http://forum.processing.org/topic/2-x-pgraphics-thread-crash */
|
||||
/** OpenGL thread */
|
||||
protected static Thread glThread;
|
||||
|
||||
/** The PGraphics object using this interface */
|
||||
@@ -377,21 +384,6 @@ public class PGL {
|
||||
* multisampled renerbuffers) */
|
||||
protected static GL2 gl2x;
|
||||
|
||||
/** Windowing toolkit */
|
||||
protected static int toolkit = NEWT;
|
||||
|
||||
/** Enables/disables use of animator */
|
||||
protected static boolean useAnimator = false;
|
||||
|
||||
protected static boolean enable_screen_FBO_macosx = true;
|
||||
protected static boolean enable_screen_FBO_windows = true;
|
||||
protected static boolean enable_screen_FBO_linux = true;
|
||||
protected static boolean enable_screen_FBO_other = true;
|
||||
|
||||
protected static int request_depth_bits = 24;
|
||||
protected static int request_stencil_bits = 8;
|
||||
protected static int request_alpha_bits = 8;
|
||||
|
||||
/** The AWT-OpenGL canvas */
|
||||
protected static GLCanvas canvasAWT;
|
||||
|
||||
@@ -419,10 +411,9 @@ public class PGL {
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// Objects for onscreen FBO-based rendering
|
||||
// FBO layer
|
||||
|
||||
|
||||
public static boolean FORCE_SCREEN_FBO = false;
|
||||
protected static boolean fboLayerByDefault = FORCE_SCREEN_FBO;
|
||||
protected static boolean fboLayerCreated = false;
|
||||
protected static boolean fboLayerInUse = false;
|
||||
protected static boolean firstFrame = true;
|
||||
@@ -438,9 +429,6 @@ public class PGL {
|
||||
protected static int fboWidth, fboHeight;
|
||||
protected static int backTex, frontTex;
|
||||
|
||||
protected static boolean needToClearBuffers;
|
||||
|
||||
|
||||
/** Back (== draw, current frame) buffer */
|
||||
protected static FBObject backFBO;
|
||||
/** Sink buffer, used in the multisampled case */
|
||||
@@ -450,6 +438,8 @@ public class PGL {
|
||||
protected static FBObject.TextureAttachment backTexAttach;
|
||||
protected static FBObject.TextureAttachment frontTexAttach;
|
||||
|
||||
protected static boolean needToClearBuffers;
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// Texture rendering
|
||||
@@ -918,7 +908,11 @@ public class PGL {
|
||||
} else {
|
||||
return fboLayerInUse;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void needFBOLayer() {
|
||||
FORCE_SCREEN_FBO = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1116,8 +1110,7 @@ public class PGL {
|
||||
protected void beginDraw(boolean clear0) {
|
||||
if (USE_JOGL_FBOLAYER) return;
|
||||
|
||||
if ((!clear0 || FORCE_SCREEN_FBO || 1 < numSamples) &&
|
||||
glColorFbo.get(0) != 0) {
|
||||
if (fboLayerInUse(clear0)) {
|
||||
bindFramebuffer(FRAMEBUFFER, glColorFbo.get(0));
|
||||
framebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0,
|
||||
TEXTURE_2D, glColorTex.get(backTex), 0);
|
||||
@@ -1146,6 +1139,14 @@ public class PGL {
|
||||
if (firstFrame) {
|
||||
firstFrame = false;
|
||||
}
|
||||
|
||||
if (!fboLayerByDefault) {
|
||||
// The result of this assignment is the following: if the user requested
|
||||
// at some point the use of the FBO layer, but subsequently didn't do
|
||||
// request it again, then the rendering won't use the FBO layer if not
|
||||
// needed, since it is slower than simple onscreen rendering.
|
||||
FORCE_SCREEN_FBO = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1224,6 +1225,12 @@ public class PGL {
|
||||
}
|
||||
|
||||
|
||||
protected boolean fboLayerInUse(boolean clear0) {
|
||||
boolean cond = !clear0 || FORCE_SCREEN_FBO || 1 < numSamples;
|
||||
return cond && glColorFbo.get(0) != 0;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Caps query
|
||||
|
||||
@@ -5365,6 +5365,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
return;
|
||||
}
|
||||
|
||||
pgl.needFBOLayer();
|
||||
loadTexture();
|
||||
if (filterTexture == null || filterTexture.contextIsOutdated()) {
|
||||
filterTexture = new Texture(parent, texture.width, texture.height,
|
||||
@@ -6511,6 +6512,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
@Override
|
||||
public void unbind() {
|
||||
if (-1 < pframeSamplerLoc) {
|
||||
pgl.needFBOLayer();
|
||||
pgl.activeTexture(PGL.TEXTURE0 + lastTexUnit);
|
||||
pgCurrent.unbindBackTexture();
|
||||
pgl.activeTexture(PGL.TEXTURE0);
|
||||
|
||||
Reference in New Issue
Block a user