summaryrefslogtreecommitdiffstats
path: root/src/demos/xtrans/XTBasicTransitionManager.java
diff options
context:
space:
mode:
authorKenneth Russel <[email protected]>2005-10-12 01:30:31 +0000
committerKenneth Russel <[email protected]>2005-10-12 01:30:31 +0000
commit82388fe004e7bc86100ad45377e69f771b45c977 (patch)
treef7d866cea1caca1f66a67ffc47f5b44b58ed3fdd /src/demos/xtrans/XTBasicTransitionManager.java
parent55370bacd5640ea9be8f6c137ec03a76c6572651 (diff)
Added XTrans (Accelerated Transitions) demo, which uses the
Java2D/JOGL bridge in a completely different way than the GLJPanel. The OffscreenDesktopPane and associated classes are an attempt at a generalized mechanism for supporting off-screen rendering of Swing components within a JDesktopPane and later composition (by subclasses) of those components' contents on-screen. The XTDesktopPane is intended to be a drop-in replacement for the JDesktopPane which supports OpenGL-accelerated animated transitions for components added to and removed from it. The XTBasicTransitionManager and XTBasicTransition classes define the default implementation of animated transition effects, supporting a combination of fade, rotation and scroll effects. More, and arbitrary, transitions are certainly possible. More experimentation by the community is needed. This demo is intended as a first step toward a more generalized framework in which arbitrary Swing rendering can be performed via the Java2D/JOGL bridge. Bugs remain, such as needing to preserve portions of the OffscreenDesktopManager's back buffer after components have been made not visible (during the process of closing them) in order to properly animate their close effects. The XTrans demo works properly in most cases but the JRefract demo (which now accepts an -xt command line argument to install an XTDesktopPane instead of a JDesktopPane) does not. More work also remains to be done, in particular on the layout of components on the back buffer. A 2D bin-packing algorithm is needed. When the Java2D/JOGL bridge supports Java2D's use of the Frame Buffer Object extension (and, implicitly, render-to-texture on all platforms) the glCopyTexSubImage2D operation to copy the off-screen back buffer to a VolatileImage can disappear; this is the principal expensive operation when the contents change of components which have been added to the OffscreenDesktopPane. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/../svn-server-sync/jogl-demos/branches/JSR-231@140 3298f667-5e0e-4b4a-8ed4-a3559d26a5f4
Diffstat (limited to 'src/demos/xtrans/XTBasicTransitionManager.java')
-rwxr-xr-xsrc/demos/xtrans/XTBasicTransitionManager.java344
1 files changed, 344 insertions, 0 deletions
diff --git a/src/demos/xtrans/XTBasicTransitionManager.java b/src/demos/xtrans/XTBasicTransitionManager.java
new file mode 100755
index 0000000..85a94fb
--- /dev/null
+++ b/src/demos/xtrans/XTBasicTransitionManager.java
@@ -0,0 +1,344 @@
+package demos.xtrans;
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.util.*;
+import gleem.linalg.*;
+
+/** A basic transition manager supporting animated scrolling, rotating
+ and fading of components. */
+
+public class XTBasicTransitionManager implements XTTransitionManager {
+ /** Indicates the style of the transition (either no motion,
+ scrolling, or rotating). */
+ public static class Style {
+ private Style() {}
+ }
+
+ /** Indicates the component has no motion (scrolling or rotation) in
+ its animation. */
+ public static Style STYLE_NO_MOTION = new Style();
+
+ /** Indicates the component is to be scrolled in to or out of
+ place. */
+ public static Style STYLE_SCROLL = new Style();
+
+ /** Indicates the component is to be rotated in to or out of
+ place. */
+ public static Style STYLE_ROTATE = new Style();
+
+ /** Indicates the direction of the transition if it contains any
+ motion (either up, down, left, or right). */
+ public static class Direction {
+ private Direction() {}
+ }
+
+ /** Indicates the component's animation is from or toward the left,
+ depending on whether the transition is an "in" or "out"
+ transition. */
+ public static Direction DIR_LEFT = new Direction();
+
+ /** Indicates the component's animation is from or toward the right,
+ depending on whether the transition is an "in" or "out"
+ transition. */
+ public static Direction DIR_RIGHT = new Direction();
+
+ /** Indicates the component's animation is in the upward
+ direction. */
+ public static Direction DIR_UP = new Direction();
+
+ /** Indicates the component's animation is in the downward
+ direction. */
+ public static Direction DIR_DOWN = new Direction();
+
+ private Style nextTransitionStyle;
+ private Direction nextTransitionDirection;
+ private boolean nextTransitionFade;
+
+ private Random random;
+
+ /** Sets the next transition to be used by this transition manager
+ for either an "in" or an "out" transition. By default the
+ transition manager selects random transitions from those
+ available. */
+ public void setNextTransition(Style style,
+ Direction direction,
+ boolean fade) {
+ if (style == null) {
+ throw new IllegalArgumentException("Must supply a style");
+ }
+ nextTransitionStyle = style;
+ nextTransitionDirection = direction;
+ nextTransitionFade = fade;
+ }
+
+ /** Creates an XTBasicTransition for the given component. By default
+ this transition manager chooses a random transition from those
+ available if one is not specified via {@link #setNextTransition
+ setNextTransition}. */
+ public XTTransition createTransitionForComponent(Component c,
+ boolean isAddition,
+ Rectangle oglViewportOfDesktop,
+ Point viewportOffsetFromOrigin,
+ Rectangle2D oglTexCoordsOnBackBuffer) {
+ if (nextTransitionStyle == null) {
+ chooseRandomTransition();
+ }
+
+ // Figure out the final positions of everything
+ // Keep in mind that the Java2D origin is at the upper left and
+ // the OpenGL origin is at the lower left
+ Rectangle bounds = c.getBounds();
+ int x = bounds.x;
+ int y = bounds.y;
+ int w = bounds.width;
+ int h = bounds.height;
+ float tx = (float) oglTexCoordsOnBackBuffer.getX();
+ float ty = (float) oglTexCoordsOnBackBuffer.getY();
+ float tw = (float) oglTexCoordsOnBackBuffer.getWidth();
+ float th = (float) oglTexCoordsOnBackBuffer.getHeight();
+ float vx = oglViewportOfDesktop.x;
+ float vy = oglViewportOfDesktop.y;
+ float vw = oglViewportOfDesktop.width;
+ float vh = oglViewportOfDesktop.height;
+ Quad3f verts = new Quad3f(new Vec3f(0, 0, 0),
+ new Vec3f(0, -h, 0),
+ new Vec3f(w, -h, 0),
+ new Vec3f(w, 0, 0));
+ Quad2f texcoords = new Quad2f(new Vec2f(tx, ty + th),
+ new Vec2f(tx, ty),
+ new Vec2f(tx + tw, ty),
+ new Vec2f(tx + tw, ty + th));
+
+ XTBasicTransition trans = new XTBasicTransition();
+
+ Vec3f translation = new Vec3f(x - viewportOffsetFromOrigin.x,
+ vh - y - viewportOffsetFromOrigin.y,
+ 0);
+ InterpolatedVec3f transInterp = new InterpolatedVec3f();
+ transInterp.setStart(translation);
+ transInterp.setEnd(translation);
+
+ InterpolatedQuad3f quadInterp = new InterpolatedQuad3f();
+ quadInterp.setStart(verts);
+ quadInterp.setEnd(verts);
+
+ InterpolatedQuad2f texInterp = new InterpolatedQuad2f();
+ texInterp.setStart(texcoords);
+ texInterp.setEnd(texcoords);
+
+ trans.setTranslation(transInterp);
+ trans.setVertices(quadInterp);
+ trans.setTexCoords(texInterp);
+
+ // Now decide how we are going to handle this transition
+ Style transitionStyle = nextTransitionStyle;
+ Direction transitionDirection = nextTransitionDirection;
+ boolean fade = nextTransitionFade;
+ nextTransitionStyle = null;
+ nextTransitionDirection = null;
+ nextTransitionFade = false;
+
+ int[] vtIdxs = null;
+ int[] ttIdxs = null;
+ Vec3f rotAxis = null;
+ Vec3f pivot = null;
+ float startAngle = 0;
+ float endAngle = 0;
+
+ if (fade) {
+ InterpolatedFloat alpha = new InterpolatedFloat();
+ float start = (isAddition ? 0.0f : 1.0f);
+ float end = (isAddition ? 1.0f : 0.0f);
+ alpha.setStart(start);
+ alpha.setEnd(end);
+ trans.setAlpha(alpha);
+ }
+
+ if (transitionDirection != null) {
+ if (transitionStyle == STYLE_SCROLL) {
+ if (transitionDirection == DIR_LEFT) {
+ vtIdxs = new int[] { 3, 2, 2, 3 };
+ ttIdxs = new int[] { 0, 1, 1, 0 };
+ } else if (transitionDirection == DIR_RIGHT) {
+ vtIdxs = new int[] { 0, 1, 1, 0 };
+ ttIdxs = new int[] { 3, 2, 2, 3 };
+ } else if (transitionDirection == DIR_UP) {
+ vtIdxs = new int[] { 1, 1, 2, 2 };
+ ttIdxs = new int[] { 0, 0, 3, 3 };
+ } else {
+ // DIR_DOWN
+ vtIdxs = new int[] { 0, 0, 3, 3 };
+ ttIdxs = new int[] { 1, 1, 2, 2 };
+ }
+ } else if (transitionStyle == STYLE_ROTATE) {
+ if (transitionDirection == DIR_LEFT) {
+ rotAxis = new Vec3f(0, 1, 0);
+ pivot = new Vec3f();
+ startAngle = -90;
+ endAngle = 0;
+ } else if (transitionDirection == DIR_RIGHT) {
+ rotAxis = new Vec3f(0, 1, 0);
+ pivot = new Vec3f(w, 0, 0);
+ startAngle = 90;
+ endAngle = 0;
+ } else if (transitionDirection == DIR_UP) {
+ rotAxis = new Vec3f(1, 0, 0);
+ pivot = new Vec3f(0, -h, 0);
+ startAngle = 90;
+ endAngle = 0;
+ } else {
+ // DIR_DOWN
+ rotAxis = new Vec3f(1, 0, 0);
+ pivot = new Vec3f();
+ startAngle = -90;
+ endAngle = 0;
+ }
+ }
+ }
+
+
+ /*
+ switch (transitionType) {
+ case FADE:
+ {
+ InterpolatedFloat alpha = new InterpolatedFloat();
+ float start = (isAddition ? 0.0f : 1.0f);
+ float end = (isAddition ? 1.0f : 0.0f);
+ alpha.setStart(start);
+ alpha.setEnd(end);
+ trans.setAlpha(alpha);
+ break;
+ }
+ case SCROLL_LEFT:
+ {
+ vtIdxs = new int[] { 3, 2, 2, 3 };
+ ttIdxs = new int[] { 0, 1, 1, 0 };
+ break;
+ }
+ case SCROLL_RIGHT:
+ {
+ vtIdxs = new int[] { 0, 1, 1, 0 };
+ ttIdxs = new int[] { 3, 2, 2, 3 };
+ break;
+ }
+ case SCROLL_UP:
+ {
+ vtIdxs = new int[] { 1, 1, 2, 2 };
+ ttIdxs = new int[] { 0, 0, 3, 3 };
+ break;
+ }
+ case SCROLL_DOWN:
+ {
+ vtIdxs = new int[] { 0, 0, 3, 3 };
+ ttIdxs = new int[] { 1, 1, 2, 2 };
+ break;
+ }
+ case ROTATE_LEFT:
+ {
+ rotAxis = new Vec3f(0, 1, 0);
+ pivot = new Vec3f();
+ startAngle = -90;
+ endAngle = 0;
+ break;
+ }
+ case ROTATE_RIGHT:
+ {
+ rotAxis = new Vec3f(0, 1, 0);
+ // pivot = translation.plus(new Vec3f(w, 0, 0));
+ pivot = new Vec3f(w, 0, 0);
+ startAngle = 90;
+ endAngle = 0;
+ break;
+ }
+ case ROTATE_UP:
+ {
+ rotAxis = new Vec3f(1, 0, 0);
+ // pivot = translation.plus(new Vec3f(0, -h, 0));
+ pivot = new Vec3f(0, -h, 0);
+ startAngle = 90;
+ endAngle = 0;
+ break;
+ }
+ case ROTATE_DOWN:
+ {
+ rotAxis = new Vec3f(1, 0, 0);
+ pivot = new Vec3f();
+ startAngle = -90;
+ endAngle = 0;
+ break;
+ }
+ }
+
+ */
+
+ if (vtIdxs != null) {
+ if (isAddition) {
+ quadInterp.setStart(new Quad3f(verts.getVec(vtIdxs[0]),
+ verts.getVec(vtIdxs[1]),
+ verts.getVec(vtIdxs[2]),
+ verts.getVec(vtIdxs[3])));
+ texInterp.setStart(new Quad2f(texcoords.getVec(ttIdxs[0]),
+ texcoords.getVec(ttIdxs[1]),
+ texcoords.getVec(ttIdxs[2]),
+ texcoords.getVec(ttIdxs[3])));
+ } else {
+ // Note: swapping the vertex and texture indices happens to
+ // have the correct effect
+ int[] tmp = vtIdxs;
+ vtIdxs = ttIdxs;
+ ttIdxs = tmp;
+
+ quadInterp.setEnd(new Quad3f(verts.getVec(vtIdxs[0]),
+ verts.getVec(vtIdxs[1]),
+ verts.getVec(vtIdxs[2]),
+ verts.getVec(vtIdxs[3])));
+ texInterp.setEnd(new Quad2f(texcoords.getVec(ttIdxs[0]),
+ texcoords.getVec(ttIdxs[1]),
+ texcoords.getVec(ttIdxs[2]),
+ texcoords.getVec(ttIdxs[3])));
+ }
+ } else if (rotAxis != null) {
+ if (!isAddition) {
+ float tmp = endAngle;
+ endAngle = -startAngle;
+ startAngle = tmp;
+ }
+
+ trans.setPivotPoint(pivot);
+ trans.setRotationAxis(rotAxis);
+ InterpolatedFloat rotInterp = new InterpolatedFloat();
+ rotInterp.setStart(startAngle);
+ rotInterp.setEnd(endAngle);
+ trans.setRotationAngle(rotInterp);
+ }
+
+ return trans;
+ }
+
+ /** Chooses a random transition from those available. */
+ protected void chooseRandomTransition() {
+ if (random == null) {
+ random = new Random();
+ }
+ nextTransitionFade = random.nextBoolean();
+ nextTransitionStyle = null;
+ do {
+ int style = random.nextInt(3);
+ switch (style) {
+ // Make no-motion transitions always use fades for effect
+ // without biasing transitions toward no-motion transitions
+ case 0: if (nextTransitionFade) nextTransitionStyle = STYLE_NO_MOTION; break;
+ case 1: nextTransitionStyle = STYLE_SCROLL; break;
+ default: nextTransitionStyle = STYLE_ROTATE; break;
+ }
+ } while (nextTransitionStyle == null);
+ int dir = random.nextInt(4);
+ switch (dir) {
+ case 0: nextTransitionDirection = DIR_LEFT; break;
+ case 1: nextTransitionDirection = DIR_RIGHT; break;
+ case 2: nextTransitionDirection = DIR_UP; break;
+ default: nextTransitionDirection = DIR_DOWN; break;
+ }
+ }
+}