mirror of
https://github.com/processing/processing4.git
synced 2026-03-13 07:57:47 +01:00
Some reworking of the offscreen logic, in order to reduce resource
utilization.
This commit is contained in:
@@ -93,13 +93,18 @@ public class PGL {
|
||||
|
||||
// Parameters
|
||||
|
||||
protected static final boolean USE_JOGL_FBOLAYER = false;
|
||||
protected static boolean FORCE_SCREEN_FBO = false;
|
||||
protected static final boolean USE_DIRECT_BUFFERS = true;
|
||||
protected static final int MIN_DIRECT_BUFFER_SIZE = 1;
|
||||
protected static final boolean SAVE_SURFACE_TO_PIXELS = true;
|
||||
/** Switches between the use of regular and direct buffers. */
|
||||
protected static final boolean USE_DIRECT_BUFFERS = true;
|
||||
protected static final int MIN_DIRECT_BUFFER_SIZE = 1;
|
||||
|
||||
/** Enables/disables mipmap use. **/
|
||||
/** This flag enables/disables a hack to make sure that anything drawn
|
||||
* in setup will be maintained even a renderer restart (e.g.: smooth change).
|
||||
* See the code and comments involving this constant in
|
||||
* PGraphicsOpenGL.endDraw().
|
||||
*/
|
||||
protected static final boolean SAVE_SURFACE_TO_PIXELS_HACK = true;
|
||||
|
||||
/** Enables/disables mipmap use. */
|
||||
protected static final boolean MIPMAPS_ENABLED = true;
|
||||
|
||||
/** Initial sizes for arrays of input and tessellated data. */
|
||||
@@ -115,7 +120,8 @@ public class PGL {
|
||||
/** Maximum index value of a tessellated vertex. GLES restricts the vertex
|
||||
* indices to be of type unsigned short. Since Java only supports signed
|
||||
* shorts as primitive type we have 2^15 = 32768 as the maximum number of
|
||||
* vertices that can be referred to within a single VBO. */
|
||||
* vertices that can be referred to within a single VBO.
|
||||
*/
|
||||
protected static final int MAX_VERTEX_INDEX = 32767;
|
||||
protected static final int MAX_VERTEX_INDEX1 = MAX_VERTEX_INDEX + 1;
|
||||
|
||||
@@ -127,7 +133,7 @@ public class PGL {
|
||||
*/
|
||||
protected static final int FLUSH_VERTEX_COUNT = MAX_VERTEX_INDEX1;
|
||||
|
||||
/** Minimum/maximum dimensions of a texture used to hold font data. **/
|
||||
/** Minimum/maximum dimensions of a texture used to hold font data. */
|
||||
protected static final int MIN_FONT_TEX_SIZE = 256;
|
||||
protected static final int MAX_FONT_TEX_SIZE = 1024;
|
||||
|
||||
@@ -141,11 +147,11 @@ public class PGL {
|
||||
*/
|
||||
protected static final int MAX_CAPS_JOINS_LENGTH = 5000;
|
||||
|
||||
/** Minimum array size to use arrayCopy method(). **/
|
||||
/** Minimum array size to use arrayCopy method(). */
|
||||
protected static final int MIN_ARRAYCOPY_SIZE = 2;
|
||||
|
||||
/** Factor used to displace the stroke vertices towards the camera in
|
||||
* order to make sure the lines are always on top of the fill geometry **/
|
||||
* order to make sure the lines are always on top of the fill geometry */
|
||||
protected static final float STROKE_DISPLACEMENT = 0.999f;
|
||||
|
||||
/** JOGL's windowing toolkit */
|
||||
@@ -153,8 +159,14 @@ public class PGL {
|
||||
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;
|
||||
protected static int events;
|
||||
/** OS-specific configuration */
|
||||
protected static int WINDOW_TOOLKIT;
|
||||
protected static int EVENTS_TOOLKIT;
|
||||
protected static boolean USE_FBOLAYER_BY_DEFAULT;
|
||||
protected static boolean USE_JOGL_FBOLAYER;
|
||||
protected static int REQUESTED_DEPTH_BITS = 24;
|
||||
protected static int REQUESTED_STENCIL_BITS = 8;
|
||||
protected static int REQUESTED_ALPHA_BITS = 8;
|
||||
static {
|
||||
if (PApplet.platform == PConstants.WINDOWS) {
|
||||
// Using AWT on Windows because NEWT displays a black background while
|
||||
@@ -163,26 +175,43 @@ public class PGL {
|
||||
// GLWindow.setPointerVisible(false);
|
||||
// but apparently nothing to set the cursor icon:
|
||||
// https://jogamp.org/bugzilla/show_bug.cgi?id=409
|
||||
toolkit = AWT;
|
||||
events = AWT;
|
||||
WINDOW_TOOLKIT = AWT;
|
||||
EVENTS_TOOLKIT = AWT;
|
||||
USE_FBOLAYER_BY_DEFAULT = false;
|
||||
USE_JOGL_FBOLAYER = false;
|
||||
REQUESTED_DEPTH_BITS = 24;
|
||||
REQUESTED_STENCIL_BITS = 8;
|
||||
REQUESTED_ALPHA_BITS = 8;
|
||||
} else if (PApplet.platform == PConstants.MACOSX) {
|
||||
// NEWT solves the issues with Java 7 and OS X 10.7+: calls to frame
|
||||
// hanging the sketch, as well as cursor, etc.
|
||||
toolkit = AWT;
|
||||
events = AWT;
|
||||
WINDOW_TOOLKIT = AWT;
|
||||
EVENTS_TOOLKIT = AWT;
|
||||
USE_FBOLAYER_BY_DEFAULT = true;
|
||||
USE_JOGL_FBOLAYER = true;
|
||||
REQUESTED_DEPTH_BITS = 24;
|
||||
REQUESTED_STENCIL_BITS = 8;
|
||||
REQUESTED_ALPHA_BITS = 8;
|
||||
} else if (PApplet.platform == PConstants.LINUX) {
|
||||
toolkit = NEWT; // AWT extremely broken on Linux?
|
||||
events = NEWT;
|
||||
WINDOW_TOOLKIT = NEWT; // AWT extremely broken on Linux?
|
||||
EVENTS_TOOLKIT = NEWT;
|
||||
USE_FBOLAYER_BY_DEFAULT = false;
|
||||
USE_JOGL_FBOLAYER = false;
|
||||
REQUESTED_DEPTH_BITS = 24;
|
||||
REQUESTED_STENCIL_BITS = 8;
|
||||
REQUESTED_ALPHA_BITS = 8;
|
||||
} else if (PApplet.platform == PConstants.OTHER) {
|
||||
toolkit = NEWT; // NEWT should work on the Raspberry pi
|
||||
events = NEWT;
|
||||
WINDOW_TOOLKIT = NEWT; // NEWT should work on the Raspberry pi
|
||||
EVENTS_TOOLKIT = NEWT;
|
||||
USE_FBOLAYER_BY_DEFAULT = false;
|
||||
USE_JOGL_FBOLAYER = false;
|
||||
REQUESTED_DEPTH_BITS = 24;
|
||||
REQUESTED_STENCIL_BITS = 8;
|
||||
REQUESTED_ALPHA_BITS = 8;
|
||||
}
|
||||
}
|
||||
|
||||
protected static int request_depth_bits = 24;
|
||||
protected static int request_stencil_bits = 8;
|
||||
protected static int request_alpha_bits = 8;
|
||||
|
||||
/** Size of different types in bytes */
|
||||
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;
|
||||
@@ -190,11 +219,7 @@ public class PGL {
|
||||
protected static final int SIZEOF_INDEX = SIZEOF_SHORT;
|
||||
protected static final int INDEX_TYPE = GL.GL_UNSIGNED_SHORT;
|
||||
|
||||
/** Error string from framebuffer errors **/
|
||||
protected static final String FRAMEBUFFER_ERROR_MESSAGE =
|
||||
"Framebuffer error (%1$s), rendering will probably not work as expected";
|
||||
|
||||
/** Machine Epsilon for float precision. **/
|
||||
/** Machine Epsilon for float precision. */
|
||||
protected static float FLOAT_EPS = Float.MIN_VALUE;
|
||||
// Calculation of the Machine Epsilon for float precision. From:
|
||||
// http://en.wikipedia.org/wiki/Machine_epsilon#Approximation_using_Java
|
||||
@@ -268,8 +293,7 @@ public class PGL {
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// FBO layer
|
||||
|
||||
protected static boolean fboLayerByDefault = FORCE_SCREEN_FBO;
|
||||
protected static boolean fboLayerRequested = false;
|
||||
protected static boolean fboLayerCreated = false;
|
||||
protected static boolean fboLayerInUse = false;
|
||||
protected static boolean firstFrame = true;
|
||||
@@ -366,6 +390,9 @@ public class PGL {
|
||||
|
||||
// Error messages
|
||||
|
||||
protected static final String FRAMEBUFFER_ERROR =
|
||||
"Framebuffer error (%1$s), rendering will probably not work as expected";
|
||||
|
||||
protected static final String MISSING_FBO_ERROR =
|
||||
"Framebuffer objects are not supported by this hardware (or driver)";
|
||||
|
||||
@@ -441,10 +468,42 @@ public class PGL {
|
||||
sinkFBO = backFBO = frontFBO = null;
|
||||
}
|
||||
|
||||
// Setting up the desired GL capabilities;
|
||||
// Setting up the desired capabilities;
|
||||
GLCapabilities caps = new GLCapabilities(profile);
|
||||
caps.setBackgroundOpaque(true);
|
||||
caps.setOnscreen(true);
|
||||
if (USE_FBOLAYER_BY_DEFAULT) {
|
||||
if (USE_JOGL_FBOLAYER) {
|
||||
caps.setPBuffer(false);
|
||||
caps.setFBO(true);
|
||||
if (1 < antialias) {
|
||||
caps.setSampleBuffers(true);
|
||||
caps.setNumSamples(antialias);
|
||||
} else {
|
||||
caps.setSampleBuffers(false);
|
||||
}
|
||||
fboLayerRequested = false;
|
||||
} else {
|
||||
caps.setPBuffer(false);
|
||||
caps.setFBO(false);
|
||||
caps.setSampleBuffers(false);
|
||||
fboLayerRequested = 1 < antialias;
|
||||
}
|
||||
} else {
|
||||
if (1 < antialias) {
|
||||
caps.setSampleBuffers(true);
|
||||
caps.setNumSamples(antialias);
|
||||
} else {
|
||||
caps.setSampleBuffers(false);
|
||||
}
|
||||
fboLayerRequested = false;
|
||||
}
|
||||
caps.setDepthBits(REQUESTED_DEPTH_BITS);
|
||||
caps.setStencilBits(REQUESTED_STENCIL_BITS);
|
||||
caps.setAlphaBits(REQUESTED_ALPHA_BITS);
|
||||
reqNumSamples = qualityToSamples(antialias);
|
||||
|
||||
/*
|
||||
if (USE_JOGL_FBOLAYER) {
|
||||
if (1 < antialias) {
|
||||
caps.setSampleBuffers(true);
|
||||
@@ -452,15 +511,16 @@ public class PGL {
|
||||
} else {
|
||||
caps.setSampleBuffers(false);
|
||||
}
|
||||
fboLayerRequested = false;
|
||||
} else {
|
||||
caps.setSampleBuffers(false);
|
||||
reqNumSamples = qualityToSamples(antialias);
|
||||
fboLayerRequested = 1 < reqNumSamples;
|
||||
}
|
||||
caps.setDepthBits(request_depth_bits);
|
||||
caps.setStencilBits(request_stencil_bits);
|
||||
caps.setAlphaBits(request_alpha_bits);
|
||||
*/
|
||||
|
||||
if (toolkit == AWT) {
|
||||
|
||||
if (WINDOW_TOOLKIT == AWT) {
|
||||
canvasAWT = new GLCanvas(caps);
|
||||
|
||||
//canvas = new GLCanvas(caps, context);
|
||||
@@ -479,7 +539,7 @@ public class PGL {
|
||||
|
||||
listener = new PGLListener();
|
||||
canvasAWT.addGLEventListener(listener);
|
||||
} else if (toolkit == NEWT) {
|
||||
} else if (WINDOW_TOOLKIT == NEWT) {
|
||||
window = GLWindow.create(caps);
|
||||
canvasNEWT = new NewtCanvasAWT(window);
|
||||
canvasNEWT.setBounds(0, 0, pg.width, pg.height);
|
||||
@@ -489,7 +549,7 @@ public class PGL {
|
||||
pg.parent.setLayout(new BorderLayout());
|
||||
pg.parent.add(canvasNEWT, BorderLayout.CENTER);
|
||||
|
||||
if (events == NEWT) {
|
||||
if (EVENTS_TOOLKIT == NEWT) {
|
||||
NEWTMouseListener mouseListener = new NEWTMouseListener();
|
||||
window.addMouseListener(mouseListener);
|
||||
NEWTKeyListener keyListener = new NEWTKeyListener();
|
||||
@@ -497,7 +557,7 @@ public class PGL {
|
||||
NEWTWindowListener winListener = new NEWTWindowListener();
|
||||
window.addWindowListener(winListener);
|
||||
canvasNEWT.addFocusListener(pg.parent); // So focus detection work.
|
||||
} else if (events == AWT) {
|
||||
} else if (EVENTS_TOOLKIT == AWT) {
|
||||
pg.parent.removeListeners(canvasNEWT);
|
||||
pg.parent.addListeners(canvasNEWT);
|
||||
}
|
||||
@@ -546,148 +606,13 @@ public class PGL {
|
||||
protected void update() {
|
||||
if (!setFps) setFps(targetFps);
|
||||
|
||||
if (USE_JOGL_FBOLAYER) return;
|
||||
|
||||
if (!fboLayerCreated) {
|
||||
String ext = getString(EXTENSIONS);
|
||||
if (-1 < ext.indexOf("texture_non_power_of_two")) {
|
||||
fboWidth = pg.width;
|
||||
fboHeight = pg.height;
|
||||
} else {
|
||||
fboWidth = nextPowerOfTwo(pg.width);
|
||||
fboHeight = nextPowerOfTwo(pg.height);
|
||||
}
|
||||
|
||||
getIntegerv(MAX_SAMPLES, intBuffer);
|
||||
if (-1 < ext.indexOf("_framebuffer_multisample") &&
|
||||
1 < intBuffer.get(0)) {
|
||||
numSamples = reqNumSamples;
|
||||
} else {
|
||||
numSamples = 1;
|
||||
}
|
||||
boolean multisample = 1 < numSamples;
|
||||
|
||||
boolean packed = ext.indexOf("packed_depth_stencil") != -1;
|
||||
int depthBits = getDepthBits();
|
||||
int stencilBits = getStencilBits();
|
||||
|
||||
genTextures(2, glColorTex);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
bindTexture(TEXTURE_2D, glColorTex.get(i));
|
||||
texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, NEAREST);
|
||||
texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST);
|
||||
texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE);
|
||||
texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE);
|
||||
texImage2D(TEXTURE_2D, 0, RGBA, fboWidth, fboHeight, 0,
|
||||
RGBA, UNSIGNED_BYTE, null);
|
||||
initTexture(TEXTURE_2D, RGBA, fboWidth, fboHeight, pg.backgroundColor);
|
||||
}
|
||||
bindTexture(TEXTURE_2D, 0);
|
||||
|
||||
backTex = 0;
|
||||
frontTex = 1;
|
||||
|
||||
genFramebuffers(1, glColorFbo);
|
||||
bindFramebuffer(FRAMEBUFFER, glColorFbo.get(0));
|
||||
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));
|
||||
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
|
||||
if (0 < depthBits) {
|
||||
int depthComponent = DEPTH_COMPONENT16;
|
||||
if (depthBits == 32) {
|
||||
depthComponent = DEPTH_COMPONENT32;
|
||||
} else if (depthBits == 24) {
|
||||
depthComponent = DEPTH_COMPONENT24;
|
||||
} else if (depthBits == 16) {
|
||||
depthComponent = DEPTH_COMPONENT16;
|
||||
}
|
||||
|
||||
genRenderbuffers(1, glDepth);
|
||||
bindRenderbuffer(RENDERBUFFER, glDepth.get(0));
|
||||
if (multisample) {
|
||||
renderbufferStorageMultisample(RENDERBUFFER, numSamples,
|
||||
depthComponent, fboWidth, fboHeight);
|
||||
} else {
|
||||
renderbufferStorage(RENDERBUFFER, depthComponent,
|
||||
fboWidth, fboHeight);
|
||||
}
|
||||
framebufferRenderbuffer(FRAMEBUFFER, DEPTH_ATTACHMENT,
|
||||
RENDERBUFFER, glDepth.get(0));
|
||||
}
|
||||
|
||||
if (0 < stencilBits) {
|
||||
int stencilIndex = STENCIL_INDEX1;
|
||||
if (stencilBits == 8) {
|
||||
stencilIndex = STENCIL_INDEX8;
|
||||
} else if (stencilBits == 4) {
|
||||
stencilIndex = STENCIL_INDEX4;
|
||||
} else if (stencilBits == 1) {
|
||||
stencilIndex = STENCIL_INDEX1;
|
||||
}
|
||||
|
||||
genRenderbuffers(1, glStencil);
|
||||
bindRenderbuffer(RENDERBUFFER, glStencil.get(0));
|
||||
if (multisample) {
|
||||
renderbufferStorageMultisample(RENDERBUFFER, numSamples,
|
||||
stencilIndex, fboWidth, fboHeight);
|
||||
} else {
|
||||
renderbufferStorage(RENDERBUFFER, stencilIndex,
|
||||
fboWidth, fboHeight);
|
||||
}
|
||||
framebufferRenderbuffer(FRAMEBUFFER, STENCIL_ATTACHMENT,
|
||||
RENDERBUFFER, glStencil.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
validateFramebuffer();
|
||||
|
||||
// Clear all buffers.
|
||||
clearDepth(1);
|
||||
clearStencil(0);
|
||||
int argb = pg.backgroundColor;
|
||||
float a = ((argb >> 24) & 0xff) / 255.0f;
|
||||
float r = ((argb >> 16) & 0xff) / 255.0f;
|
||||
float g = ((argb >> 8) & 0xff) / 255.0f;
|
||||
float b = ((argb) & 0xff) / 255.0f;
|
||||
clearColor(r, g, b, a);
|
||||
clear(DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT | COLOR_BUFFER_BIT);
|
||||
|
||||
bindFramebuffer(FRAMEBUFFER, 0);
|
||||
|
||||
fboLayerCreated = true;
|
||||
if (fboLayerRequested && !fboLayerCreated && !USE_JOGL_FBOLAYER) {
|
||||
createFBOLayer();
|
||||
}
|
||||
// if (USE_JOGL_FBOLAYER) return;
|
||||
// if (!fboLayerCreated) {
|
||||
// createFBOLayer();
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@@ -748,8 +673,8 @@ public class PGL {
|
||||
}
|
||||
|
||||
|
||||
protected void needFBOLayer() {
|
||||
FORCE_SCREEN_FBO = true;
|
||||
protected void requestFBOLayer() {
|
||||
fboLayerRequested = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -935,6 +860,148 @@ public class PGL {
|
||||
}
|
||||
|
||||
|
||||
protected void createFBOLayer() {
|
||||
String ext = getString(EXTENSIONS);
|
||||
if (-1 < ext.indexOf("texture_non_power_of_two")) {
|
||||
fboWidth = pg.width;
|
||||
fboHeight = pg.height;
|
||||
} else {
|
||||
fboWidth = nextPowerOfTwo(pg.width);
|
||||
fboHeight = nextPowerOfTwo(pg.height);
|
||||
}
|
||||
|
||||
getIntegerv(MAX_SAMPLES, intBuffer);
|
||||
if (-1 < ext.indexOf("_framebuffer_multisample") &&
|
||||
1 < intBuffer.get(0)) {
|
||||
numSamples = reqNumSamples;
|
||||
} else {
|
||||
numSamples = 1;
|
||||
}
|
||||
boolean multisample = 1 < numSamples;
|
||||
|
||||
boolean packed = ext.indexOf("packed_depth_stencil") != -1;
|
||||
int depthBits = getDepthBits();
|
||||
int stencilBits = getStencilBits();
|
||||
|
||||
genTextures(2, glColorTex);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
bindTexture(TEXTURE_2D, glColorTex.get(i));
|
||||
texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, NEAREST);
|
||||
texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST);
|
||||
texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE);
|
||||
texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE);
|
||||
texImage2D(TEXTURE_2D, 0, RGBA, fboWidth, fboHeight, 0,
|
||||
RGBA, UNSIGNED_BYTE, null);
|
||||
initTexture(TEXTURE_2D, RGBA, fboWidth, fboHeight, pg.backgroundColor);
|
||||
}
|
||||
bindTexture(TEXTURE_2D, 0);
|
||||
|
||||
backTex = 0;
|
||||
frontTex = 1;
|
||||
|
||||
genFramebuffers(1, glColorFbo);
|
||||
bindFramebuffer(FRAMEBUFFER, glColorFbo.get(0));
|
||||
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));
|
||||
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
|
||||
if (0 < depthBits) {
|
||||
int depthComponent = DEPTH_COMPONENT16;
|
||||
if (depthBits == 32) {
|
||||
depthComponent = DEPTH_COMPONENT32;
|
||||
} else if (depthBits == 24) {
|
||||
depthComponent = DEPTH_COMPONENT24;
|
||||
} else if (depthBits == 16) {
|
||||
depthComponent = DEPTH_COMPONENT16;
|
||||
}
|
||||
|
||||
genRenderbuffers(1, glDepth);
|
||||
bindRenderbuffer(RENDERBUFFER, glDepth.get(0));
|
||||
if (multisample) {
|
||||
renderbufferStorageMultisample(RENDERBUFFER, numSamples,
|
||||
depthComponent, fboWidth, fboHeight);
|
||||
} else {
|
||||
renderbufferStorage(RENDERBUFFER, depthComponent,
|
||||
fboWidth, fboHeight);
|
||||
}
|
||||
framebufferRenderbuffer(FRAMEBUFFER, DEPTH_ATTACHMENT,
|
||||
RENDERBUFFER, glDepth.get(0));
|
||||
}
|
||||
|
||||
if (0 < stencilBits) {
|
||||
int stencilIndex = STENCIL_INDEX1;
|
||||
if (stencilBits == 8) {
|
||||
stencilIndex = STENCIL_INDEX8;
|
||||
} else if (stencilBits == 4) {
|
||||
stencilIndex = STENCIL_INDEX4;
|
||||
} else if (stencilBits == 1) {
|
||||
stencilIndex = STENCIL_INDEX1;
|
||||
}
|
||||
|
||||
genRenderbuffers(1, glStencil);
|
||||
bindRenderbuffer(RENDERBUFFER, glStencil.get(0));
|
||||
if (multisample) {
|
||||
renderbufferStorageMultisample(RENDERBUFFER, numSamples,
|
||||
stencilIndex, fboWidth, fboHeight);
|
||||
} else {
|
||||
renderbufferStorage(RENDERBUFFER, stencilIndex,
|
||||
fboWidth, fboHeight);
|
||||
}
|
||||
framebufferRenderbuffer(FRAMEBUFFER, STENCIL_ATTACHMENT,
|
||||
RENDERBUFFER, glStencil.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
validateFramebuffer();
|
||||
|
||||
// Clear all buffers.
|
||||
clearDepth(1);
|
||||
clearStencil(0);
|
||||
int argb = pg.backgroundColor;
|
||||
float a = ((argb >> 24) & 0xff) / 255.0f;
|
||||
float r = ((argb >> 16) & 0xff) / 255.0f;
|
||||
float g = ((argb >> 8) & 0xff) / 255.0f;
|
||||
float b = ((argb) & 0xff) / 255.0f;
|
||||
clearColor(r, g, b, a);
|
||||
clear(DEPTH_BUFFER_BIT | STENCIL_BUFFER_BIT | COLOR_BUFFER_BIT);
|
||||
|
||||
bindFramebuffer(FRAMEBUFFER, 0);
|
||||
|
||||
fboLayerCreated = true;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// Frame rendering
|
||||
@@ -943,7 +1010,7 @@ public class PGL {
|
||||
protected void beginDraw(boolean clear0) {
|
||||
if (USE_JOGL_FBOLAYER) return;
|
||||
|
||||
if (fboLayerInUse(clear0)) {
|
||||
if (needFBOLayer(clear0)) {
|
||||
bindFramebuffer(FRAMEBUFFER, glColorFbo.get(0));
|
||||
framebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0,
|
||||
TEXTURE_2D, glColorTex.get(backTex), 0);
|
||||
@@ -979,31 +1046,33 @@ public class PGL {
|
||||
firstFrame = false;
|
||||
}
|
||||
|
||||
if (!fboLayerByDefault) {
|
||||
if (!USE_FBOLAYER_BY_DEFAULT) {
|
||||
// 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;
|
||||
// at some point the use of the FBO layer, but subsequently didn't
|
||||
// request it again, then the rendering won't render to the FBO layer if
|
||||
// not needed by the condif, since it is slower than simple onscreen
|
||||
// rendering.
|
||||
fboLayerRequested = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void endDraw(boolean clear0) {
|
||||
if (USE_JOGL_FBOLAYER) {
|
||||
if (!clear0 && isFBOBacked() && !isMultisampled()) {
|
||||
// Draw the back texture into the front texture, which will be used as
|
||||
// back texture in the next frame. Otherwise flickering will occur if
|
||||
// the sketch uses "incremental drawing" (background() not called).
|
||||
frontFBO.bind(gl);
|
||||
gl.glDisable(GL.GL_BLEND);
|
||||
drawTexture(GL.GL_TEXTURE_2D, backTexAttach.getName(),
|
||||
backTexAttach.getWidth(), backTexAttach.getHeight(),
|
||||
pg.width, pg.height,
|
||||
0, 0, pg.width, pg.height, 0, 0, pg.width, pg.height);
|
||||
backFBO.bind(gl);
|
||||
}
|
||||
} else {
|
||||
if (fboLayerInUse) {
|
||||
if (isFBOBacked()) {
|
||||
if (USE_JOGL_FBOLAYER) {
|
||||
if (!clear0 && isFBOBacked() && !isMultisampled()) {
|
||||
// Draw the back texture into the front texture, which will be used as
|
||||
// back texture in the next frame. Otherwise flickering will occur if
|
||||
// the sketch uses "incremental drawing" (background() not called).
|
||||
frontFBO.bind(gl);
|
||||
gl.glDisable(GL.GL_BLEND);
|
||||
drawTexture(GL.GL_TEXTURE_2D, backTexAttach.getName(),
|
||||
backTexAttach.getWidth(), backTexAttach.getHeight(),
|
||||
pg.width, pg.height,
|
||||
0, 0, pg.width, pg.height, 0, 0, pg.width, pg.height);
|
||||
backFBO.bind(gl);
|
||||
}
|
||||
} else if (fboLayerInUse) {
|
||||
syncBackTexture();
|
||||
|
||||
// Draw the contents of the back texture to the screen framebuffer.
|
||||
@@ -1050,9 +1119,9 @@ public class PGL {
|
||||
protected void requestDraw() {
|
||||
if (pg.initialized && pg.parent.canDraw()) {
|
||||
try {
|
||||
if (toolkit == AWT) {
|
||||
if (WINDOW_TOOLKIT == AWT) {
|
||||
canvasAWT.display();
|
||||
} else if (toolkit == NEWT) {
|
||||
} else if (WINDOW_TOOLKIT == NEWT) {
|
||||
window.display();
|
||||
}
|
||||
} catch (GLException e) {
|
||||
@@ -1073,8 +1142,8 @@ public class PGL {
|
||||
}
|
||||
|
||||
|
||||
protected boolean fboLayerInUse(boolean clear0) {
|
||||
boolean cond = !clear0 || FORCE_SCREEN_FBO || 1 < numSamples;
|
||||
protected boolean needFBOLayer(boolean clear0) {
|
||||
boolean cond = !clear0 || fboLayerRequested || 1 < numSamples;
|
||||
return cond && glColorFbo.get(0) != 0;
|
||||
}
|
||||
|
||||
@@ -1953,22 +2022,22 @@ public class PGL {
|
||||
if (status == FRAMEBUFFER_COMPLETE) {
|
||||
return true;
|
||||
} else if (status == FRAMEBUFFER_INCOMPLETE_ATTACHMENT) {
|
||||
System.err.println(String.format(FRAMEBUFFER_ERROR_MESSAGE,
|
||||
System.err.println(String.format(FRAMEBUFFER_ERROR,
|
||||
"incomplete attachment"));
|
||||
} else if (status == FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) {
|
||||
System.err.println(String.format(FRAMEBUFFER_ERROR_MESSAGE,
|
||||
System.err.println(String.format(FRAMEBUFFER_ERROR,
|
||||
"incomplete missing attachment"));
|
||||
} else if (status == FRAMEBUFFER_INCOMPLETE_DIMENSIONS) {
|
||||
System.err.println(String.format(FRAMEBUFFER_ERROR_MESSAGE,
|
||||
System.err.println(String.format(FRAMEBUFFER_ERROR,
|
||||
"incomplete dimensions"));
|
||||
} else if (status == FRAMEBUFFER_INCOMPLETE_FORMATS) {
|
||||
System.err.println(String.format(FRAMEBUFFER_ERROR_MESSAGE,
|
||||
System.err.println(String.format(FRAMEBUFFER_ERROR,
|
||||
"incomplete formats"));
|
||||
} else if (status == FRAMEBUFFER_UNSUPPORTED) {
|
||||
System.err.println(String.format(FRAMEBUFFER_ERROR_MESSAGE,
|
||||
System.err.println(String.format(FRAMEBUFFER_ERROR,
|
||||
"framebuffer unsupported"));
|
||||
} else {
|
||||
System.err.println(String.format(FRAMEBUFFER_ERROR_MESSAGE,
|
||||
System.err.println(String.format(FRAMEBUFFER_ERROR,
|
||||
"unknown error"));
|
||||
}
|
||||
return false;
|
||||
@@ -2407,7 +2476,7 @@ public class PGL {
|
||||
// The onscreen drawing surface is backed by an FBO layer.
|
||||
GLFBODrawable fboDrawable = null;
|
||||
|
||||
if (toolkit == AWT) {
|
||||
if (WINDOW_TOOLKIT == AWT) {
|
||||
GLCanvas glCanvas = (GLCanvas)glDrawable;
|
||||
fboDrawable = (GLFBODrawable)glCanvas.getDelegatedDrawable();
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user