better resize handling

This commit is contained in:
codeanticode
2012-11-25 20:26:27 +00:00
parent ae89182d88
commit b110bae80a
2 changed files with 116 additions and 79 deletions
+77 -50
View File
@@ -374,6 +374,9 @@ public class PGL {
/** 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;
@@ -398,7 +401,7 @@ public class PGL {
protected static PGLListener listener;
/** Animator to drive the rendering thread in NEWT */
protected static NEWTAnimator animator;
protected static PGLAnimator animator;
/** Desired target framerate */
protected float targetFramerate = 60;
@@ -532,12 +535,18 @@ public class PGL {
} else {
// Restarting...
if (canvasAWT != null) {
if (useAnimator) {
animator.stop();
animator.remove(canvasAWT);
}
canvasAWT.removeGLEventListener(listener);
pg.parent.removeListeners(canvasAWT);
pg.parent.remove(canvasAWT);
} else if (canvasNEWT != null) {
animator.stop();
animator.remove(window);
if (useAnimator) {
animator.stop();
animator.remove(window);
}
window.removeGLEventListener(listener);
pg.parent.remove(canvasNEWT);
}
@@ -585,6 +594,10 @@ public class PGL {
listener = new PGLListener();
canvasAWT.addGLEventListener(listener);
if (useAnimator) {
animator = new PGLAnimator(canvasAWT);
animator.start();
}
} else if (toolkit == NEWT) {
window = GLWindow.create(caps);
canvasNEWT = new NewtCanvasAWT(window);
@@ -605,8 +618,10 @@ public class PGL {
listener = new PGLListener();
window.addGLEventListener(listener);
animator = new NEWTAnimator(window);
animator.start();
if (useAnimator) {
animator = new PGLAnimator(window);
animator.start();
}
}
firstFrame = true;
@@ -782,10 +797,14 @@ public class PGL {
protected void requestDraw() {
if (initialized) {
try {
if (toolkit == AWT) {
canvasAWT.display();
} else if (toolkit == NEWT) {
if (useAnimator) {
animator.requestDisplay();
} else {
if (toolkit == AWT) {
canvasAWT.display();
} else if (toolkit == NEWT) {
window.display();
}
}
} catch (GLException e) {
// Unwrap GLException so that only the causing exception is shown.
@@ -2474,14 +2493,6 @@ public class PGL {
public void reshape(GLAutoDrawable adrawable, int x, int y, int w, int h) {
drawable = adrawable;
context = adrawable.getContext();
/*
if (glColorFbo[0] != 0) {
// The screen FBO hack needs the FBO to be recreated when starting
// and after resizing.
glColorFbo[0] = 0;
}
*/
}
}
@@ -2581,28 +2592,29 @@ public class PGL {
}
// Animator to drive render loop when using NEWT.
protected static class NEWTAnimator extends AnimatorBase {
protected static class PGLAnimator extends AnimatorBase {
private static int count = 0;
private Timer timer = null;
private TimerTask task = null;
private volatile boolean shouldRun;
private Task task = null;
@Override
protected String getBaseName(String prefix) {
return prefix + "NEWTAnimator";
return prefix + "PGLAnimator";
}
/** Creates an CustomAnimator with an initial drawable to
* animate.
*/
public NEWTAnimator(GLAutoDrawable drawable) {
public PGLAnimator(GLAutoDrawable drawable) {
if (drawable != null) {
add(drawable);
}
}
public synchronized void requestDisplay() {
shouldRun = true;
public void requestDisplay() {
if (task != null) {
task.shouldRun();
}
}
public final boolean isStarted() {
@@ -2624,34 +2636,12 @@ public class PGL {
}
private void startTask() {
if(null != task) {
if (null != task) {
return;
}
task = new TimerTask() {
private boolean firstRun = true;
@Override
public void run() {
if (firstRun) {
Thread.currentThread().setName("PGL-RenderQueue-" + count);
firstRun = false;
count++;
}
if (NEWTAnimator.this.shouldRun) {
NEWTAnimator.this.animThread = Thread.currentThread();
// display impl. uses synchronized block on the animator instance
display();
synchronized (this) {
// done with current frame.
shouldRun = false;
}
}
}
};
task = new Task();
fpsCounter.resetFPSCounter();
shouldRun = false;
timer.schedule(task, 0, 1);
}
@@ -2676,12 +2666,11 @@ public class PGL {
}
stateSync.lock();
try {
shouldRun = false;
if(null != task) {
if (null != task) {
task.cancel();
task = null;
}
if(null != timer) {
if (null != timer) {
timer.cancel();
timer = null;
}
@@ -2698,5 +2687,43 @@ public class PGL {
public final boolean isPaused() { return false; }
public synchronized boolean resume() { return false; }
public synchronized boolean pause() { return false; }
private class Task extends TimerTask {
private boolean firstRun = true;
private boolean shouldRun = false;
public void shouldRun() {
synchronized (this) {
shouldRun = true;
}
}
@Override
public void run() {
if (firstRun) {
Thread.currentThread().setName("PGL-RenderQueue-" + count);
firstRun = false;
count++;
}
if (shouldRun) {
PGLAnimator.this.animThread = Thread.currentThread();
// display impl. uses synchronized block on the animator instance
display();
synchronized (this) {
// done with current frame.
shouldRun = false;
}
}
}
@Override
public boolean cancel() {
synchronized (this) {
// done with current frame.
shouldRun = false;
}
return super.cancel();
}
}
}
}
+39 -29
View File
@@ -432,9 +432,6 @@ public class PGraphicsOpenGL extends PGraphics {
static protected final int OP_WRITE = 2;
protected int pixelsOp = OP_NONE;
/** Used to detect the occurrence of a frame resize event. */
protected boolean resized = false;
/** Viewport dimensions. */
protected int[] viewport = {0, 0, 0, 0};
@@ -537,17 +534,9 @@ public class PGraphicsOpenGL extends PGraphics {
@Override
public void setSize(int iwidth, int iheight) {
resized = (0 < width && width != iwidth) ||
(0 < height && height != iwidth);
width = iwidth;
height = iheight;
if (pixels != null) {
// The user is using the pixels array, so we need to resize accordingly
allocatePixels();
}
allocate();
reapplySettings();
@@ -560,11 +549,12 @@ public class PGraphicsOpenGL extends PGraphics {
cameraFar = cameraZ * 10.0f;
cameraAspect = (float) width / (float) height;
// Forces a restart of OpenGL so the canvas has the right size.
//pgl.initialized = false;
restartPGL();
// set this flag so that beginDraw() will do an update to the camera.
sized = true;
// Forces a restart of OpenGL so the canvas has the right size.
pgl.initialized = false;
}
@@ -1595,7 +1585,8 @@ public class PGraphicsOpenGL extends PGraphics {
boolean outdatedMulti = multisampleFramebuffer != null &&
multisampleFramebuffer.contextIsOutdated();
if (outdated || outdatedMulti) {
pgl.initialized = false;
// pgl.initialized = false;
restartPGL();
initOffscreen();
}
}
@@ -1665,21 +1656,12 @@ public class PGraphicsOpenGL extends PGraphics {
// setup opengl viewport.
viewport[0] = 0; viewport[1] = 0; viewport[2] = width; viewport[3] = height;
pgl.viewport(viewport[0], viewport[1], viewport[2], viewport[3]);
if (resized) {
if (sized) {
// To avoid having garbage in the screen after a resize,
// in the case background is not called in draw().
background(backgroundColor);
if (texture != null) {
// The screen texture should be deleted because it
// corresponds to the old window size.
pgPrimary.removeCache(this);
texture = null;
loadTexture();
}
resized = false;
}
if (sized) {
// Sets the default projection and camera (initializes modelview).
// If the user has setup up their own projection, they'll need
// to fix it after resize anyway. This helps the people who haven't
@@ -1687,6 +1669,11 @@ public class PGraphicsOpenGL extends PGraphics {
defaultPerspective();
defaultCamera();
if (pixels != null) {
// The pixels array is being used, so we need to resize accordingly
loadPixels();
}
// clear the flag
sized = false;
} else {
@@ -1821,6 +1808,14 @@ public class PGraphicsOpenGL extends PGraphics {
protected void restartPGL() {
pgl.initialized = false;
/*
if (texture != null) {
PApplet.println("restart: " + Thread.currentThread());
// The screen texture should be deleted because it
// corresponds to the old window size.
removeCache(this);
texture = ptexture = null;
}*/
}
@@ -3234,9 +3229,11 @@ public class PGraphicsOpenGL extends PGraphics {
if (quality == 1) {
quality = 0;
}
// This will trigger a surface restart next time
// requestDraw() is called.
pgl.initialized = false;
// pgl.initialized = false;
restartPGL();
}
}
@@ -3262,7 +3259,8 @@ public class PGraphicsOpenGL extends PGraphics {
quality = 0;
// This will trigger a surface restart next time
// requestDraw() is called.
pgl.initialized = false;
// pgl.initialized = false;
restartPGL();
}
}
@@ -5191,10 +5189,17 @@ public class PGraphicsOpenGL extends PGraphics {
protected void drawPixels(int x, int y, int w, int h) {
if (sized || texture == null) {
// This shouldn't happen... some threading problem because sized is turned
// to false in beginDraw()
// http://code.google.com/p/processing/issues/detail?id=1119
return;
}
int i0 = y * width + x;
int len = w * h;
if (nativePixels == null || nativePixels.length < len) {
if (nativePixels == null || nativePixels.length != len) {
nativePixels = new int[len];
nativePixelBuffer = IntBuffer.wrap(nativePixels);
}
@@ -5208,6 +5213,7 @@ public class PGraphicsOpenGL extends PGraphics {
// of non-FBO-backed primary surface we might need to create the texture.
loadTextureImpl(POINT, false);
}
pgl.copyToTexture(texture.glTarget, texture.glFormat, texture.glName,
x, y, w, h, IntBuffer.wrap(nativePixels));
@@ -5859,6 +5865,10 @@ public class PGraphicsOpenGL extends PGraphics {
if (pgPrimary == null) {
pgPrimary = this;
}
if (texture != null) {
pgPrimary.removeCache(this);
texture = ptexture = null;
}
}