diff options
author | Kenneth Russel <[email protected]> | 2005-10-12 01:30:31 +0000 |
---|---|---|
committer | Kenneth Russel <[email protected]> | 2005-10-12 01:30:31 +0000 |
commit | 82388fe004e7bc86100ad45377e69f771b45c977 (patch) | |
tree | f7d866cea1caca1f66a67ffc47f5b44b58ed3fdd /src/demos/xtrans/OffscreenComponentWrapper.java | |
parent | 55370bacd5640ea9be8f6c137ec03a76c6572651 (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/OffscreenComponentWrapper.java')
-rwxr-xr-x | src/demos/xtrans/OffscreenComponentWrapper.java | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/src/demos/xtrans/OffscreenComponentWrapper.java b/src/demos/xtrans/OffscreenComponentWrapper.java new file mode 100755 index 0000000..760343d --- /dev/null +++ b/src/demos/xtrans/OffscreenComponentWrapper.java @@ -0,0 +1,122 @@ +package demos.xtrans; + +import java.awt.*; +import javax.swing.*; + +// Internal JOGL API references +import com.sun.opengl.impl.Debug; +// FIXME: debugging only +import com.sun.opengl.impl.Java2D; + +/** Provides an interposition point where we can install a new + Graphics object in the rendering pipeline. Because lightweight + components always delegate up to their parents to fetch Graphics + objects, we can use this point to swap in the off-screen + VolatileImage we're using for rendering. Applications should not + need to construct instances of this class directly, though they + may encounter them when traversing the component hierarchy created + by the OffscreenDesktopPane, since they are automatically inserted + during add operations. */ + +public class OffscreenComponentWrapper extends JComponent { + private static final boolean DEBUG = Debug.debug("OffscreenComponentWrapper"); + + /** Instantiates an OffscreenComponentWrapper. This should not be + called directly by applications. */ + public OffscreenComponentWrapper(Component arg) { + if (arg == null) { + throw new RuntimeException("Null argument"); + } + add(arg); + setOpaque(false); + } + + protected void addImpl(Component c, Object constraints, int index) { + if (getComponentCount() != 0) { + throw new RuntimeException("May only add one child"); + } + super.addImpl(c, constraints, index); + } + + /** Returns the sole child component of this one. */ + public Component getChild() { + if (getComponentCount() == 0) { + throw new RuntimeException("No child found"); + } + return getComponent(0); + } + + public void remove(int i) { + super.remove(i); + throw new RuntimeException("Should not call this"); + } + + public void remove(Component c) { + super.remove(c); + throw new RuntimeException("Should not call this"); + } + + /** Overrides the superclass's getGraphics() in order to provide a + correctly-translated Graphics object on the + OffscreenDesktopPane's back buffer. */ + public Graphics getGraphics() { + Component parent = getParent(); + if ((parent != null) && (parent instanceof OffscreenDesktopPane)) { + OffscreenDesktopPane desktop = (OffscreenDesktopPane) parent; + OffscreenDesktopManager manager = (OffscreenDesktopManager) desktop.getDesktopManager(); + // Find out where the component we're rendering lives on the back buffer + Graphics g = manager.getOffscreenGraphics(); + Rectangle bounds = manager.getBoundsOnBackBuffer(getChild()); + if (bounds == null) { + if (DEBUG) { + System.err.println("No bounds for child"); + } + + // Not yet laid out on back buffer; however, avoid painting to + // screen + return g; + } + if (DEBUG) { + System.err.println("Graphics.translate(" + bounds.x + "," + bounds.y + ")"); + System.err.println(" Surface identifier = " + Java2D.getOGLSurfaceIdentifier(g)); + } + + g.translate(bounds.x, bounds.y); + // Also take into account the translation of the child + Component c = getChild(); + g.translate(-c.getX(), -c.getY()); + // Make sure any changes the user made to the double-buffering + // of child components don't mess up the rendering results + OffscreenDesktopManager.switchDoubleBuffering(this, false); + // A child component will be performing drawing and therefore + // get the OpenGL copy of the back buffer out of sync; will need + // to repair it + // NOTE: in theory we should only need to set the copy back + // state on the OffscreenDesktopManager. However it seems that + // there are certain operations (like scrolling in a + // JScrollPane) that have unanticipated consequences, such as + // drawing into the Swing back buffer (which is heavily + // undesirable, because it can cause on-screen visual artifacts + // in our rendering paradigm) as well as potentially + // inadvertently copying regions of the back buffer from one + // place to another. Since we don't know the side effects of + // such operations we currently need to treat the entire back + // buffer as being dirty. + manager.setNeedsRedraw(); + // NOTE: this is a bit of a hack but we need to indicate to the + // parent desktop that it is dirty as well since one of its + // children (being painted by alternate means) needs to be + // redrawn + desktop.repaint(); + return g; + } else { + return super.getGraphics(); + } + } + + public void paintComponent(Graphics g) { + } + + protected void paintChildren(Graphics g) { + } +} |