From 10c76681d1507fa527b59cb28bcde5d1c6a4fe18 Mon Sep 17 00:00:00 2001 From: Kenneth Russel Date: Thu, 4 Jan 2007 05:38:42 +0000 Subject: Moved J2DTextureRenderer and J2DOverlay into their own sub-package and dropped the prefixes on the suggestion of Chris Campbell. No other changes to these classes. Added com.sun.opengl.util.j2d to the javadoc generation. Updated demos. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@1066 232f8b59-042b-4e1e-8c03-345bb8c30851 --- src/classes/com/sun/opengl/util/J2DOverlay.java | 213 ------------ .../com/sun/opengl/util/J2DTextureRenderer.java | 371 --------------------- src/classes/com/sun/opengl/util/j2d/Overlay.java | 213 ++++++++++++ .../com/sun/opengl/util/j2d/TextureRenderer.java | 371 +++++++++++++++++++++ 4 files changed, 584 insertions(+), 584 deletions(-) delete mode 100755 src/classes/com/sun/opengl/util/J2DOverlay.java delete mode 100755 src/classes/com/sun/opengl/util/J2DTextureRenderer.java create mode 100755 src/classes/com/sun/opengl/util/j2d/Overlay.java create mode 100755 src/classes/com/sun/opengl/util/j2d/TextureRenderer.java (limited to 'src/classes') diff --git a/src/classes/com/sun/opengl/util/J2DOverlay.java b/src/classes/com/sun/opengl/util/J2DOverlay.java deleted file mode 100755 index 3bb4de9ee..000000000 --- a/src/classes/com/sun/opengl/util/J2DOverlay.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - * Sun gratefully acknowledges that this software was originally authored - * and developed by Kenneth Bradley Russell and Christopher John Kline. - */ - -package com.sun.opengl.util; - -import java.awt.Graphics2D; - -import javax.media.opengl.*; -import com.sun.opengl.util.texture.*; - -/** Provides a Java 2D overlay on top of an arbitrary GLDrawable, - making it easier to do things like draw text and images on top of - an OpenGL scene while still maintaining reasonably good - efficiency. For correct operation, the drawable should be - allocated with alpha bits enabled, as the J2DOverlay uses alpha - blending to make portions of itself transparent. */ - -public class J2DOverlay { - private GLDrawable drawable; - private J2DTextureRenderer renderer; - private boolean contentsLost; - - /** Creates a new Java 2D overlay on top of the specified - GLDrawable. */ - public J2DOverlay(GLDrawable drawable) { - this.drawable = drawable; - } - - /** Creates a {@link java.awt.Graphics2D Graphics2D} instance for - rendering into the overlay. The returned object should be - disposed of using the normal {@link java.awt.Graphics#dispose() - Graphics.dispose()} method once it is no longer being used. - - @return a new {@link java.awt.Graphics2D Graphics2D} object for - rendering into the backing store of this renderer - */ - public Graphics2D createGraphics() { - // Validate the size of the renderer against the current size of - // the drawable - validateRenderer(); - return renderer.createGraphics(); - } - - /** Indicates whether the Java 2D contents of the overlay were lost - since the last time {@link #createGraphics} was called. This - method should be called immediately after calling {@link - #createGraphics} to see whether the entire contents of the - overlay need to be redrawn or just the region the application is - interested in updating. - - @return whether the contents of the overlay were lost since the - last render - */ - public boolean contentsLost() { - return contentsLost; - } - - /** Synchronizes the contents of the Java 2D rendering down to the - OpenGL texture. - - @param x the x coordinate (in Java 2D coordinates -- relative to - upper left) of the region to update - @param y the y coordinate (in Java 2D coordinates -- relative to - upper left) of the region to update - @param width the width of the region to update - @param height the height of the region to update - - @throws GLException If an OpenGL context is not current when this method is called - */ - public void sync(int x, int y, int width, int height) throws GLException { - renderer.sync(x, y, width, height); - } - - /** Draws the entire contents of the overlay on top of the OpenGL - drawable. This is a convenience method which encapsulates all - portions of the rendering process; if this method is used, - {@link #beginRendering}, {@link #endRendering}, etc. should not - be used. This method should be called while the OpenGL context - for the drawable is current, and after your OpenGL scene has - been rendered. - - @throws GLException If an OpenGL context is not current when this method is called - */ - public void drawAll() throws GLException { - beginRendering(); - draw(0, 0, drawable.getWidth(), drawable.getHeight()); - endRendering(); - } - - /** Begins the OpenGL rendering process for the overlay. This is - separated out so advanced applications can render independent - pieces of the overlay to different portions of the drawable. - - @throws GLException If an OpenGL context is not current when this method is called - */ - public void beginRendering() throws GLException { - renderer.beginOrthoRendering(drawable.getWidth(), drawable.getHeight()); - } - - /** Ends the OpenGL rendering process for the overlay. This is - separated out so advanced applications can render independent - pieces of the overlay to different portions of the drawable. - - @throws GLException If an OpenGL context is not current when this method is called - */ - public void endRendering() throws GLException { - renderer.endOrthoRendering(); - } - - /** Draws the specified sub-rectangle of the overlay on top of the - OpenGL drawable. {@link #beginRendering} and {@link - #endRendering} must be used in conjunction with this method to - achieve proper rendering results. This method should be called - while the OpenGL context for the drawable is current, and after - your OpenGL scene has been rendered. - - @param x the lower-left x coordinate (relative to the lower left - of the overlay) of the rectangle to draw - @param y the lower-left y coordinate (relative to the lower left - of the overlay) of the rectangle to draw - @param width the width of the rectangle to draw - @param height the height of the rectangle to draw - - @throws GLException If an OpenGL context is not current when this method is called - */ - public void draw(int x, int y, int width, int height) throws GLException { - draw(x, y, x, y, width, height); - } - - /** Draws the specified sub-rectangle of the overlay at the - specified x and y coordinate on top of the OpenGL drawable. - {@link #beginRendering} and {@link #endRendering} must be used - in conjunction with this method to achieve proper rendering - results. This method should be called while the OpenGL context - for the drawable is current, and after your OpenGL scene has - been rendered. - - @param screenx the on-screen x coordinate at which to draw the rectangle - @param screeny the on-screen y coordinate (relative to lower left) at - which to draw the rectangle - @param overlayx the x coordinate of the pixel in the overlay of - the lower left portion of the rectangle to draw - @param overlayy the y coordinate of the pixel in the overlay - (relative to lower left) of the lower left portion of the - rectangle to draw - @param width the width of the rectangle to draw - @param height the height of the rectangle to draw - - @throws GLException If an OpenGL context is not current when this method is called - */ - public void draw(int screenx, int screeny, - int overlayx, int overlayy, - int width, int height) throws GLException { - renderer.drawOrthoRect(screenx, screeny, - overlayx, overlayy, - width, height); - } - - //---------------------------------------------------------------------- - // Internals only below this point - // - - private void validateRenderer() { - if (renderer == null) { - renderer = new J2DTextureRenderer(drawable.getWidth(), - drawable.getHeight(), - true); - contentsLost = true; - } else if (renderer.getWidth() != drawable.getWidth() || - renderer.getHeight() != drawable.getHeight()) { - renderer.setSize(drawable.getWidth(), drawable.getHeight()); - contentsLost = true; - } else { - contentsLost = false; - } - } -} diff --git a/src/classes/com/sun/opengl/util/J2DTextureRenderer.java b/src/classes/com/sun/opengl/util/J2DTextureRenderer.java deleted file mode 100755 index de4aee9b8..000000000 --- a/src/classes/com/sun/opengl/util/J2DTextureRenderer.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - * Sun gratefully acknowledges that this software was originally authored - * and developed by Kenneth Bradley Russell and Christopher John Kline. - */ - -package com.sun.opengl.util; - -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.image.*; - -import javax.media.opengl.*; -import javax.media.opengl.glu.*; -import com.sun.opengl.util.texture.*; - -/** Provides the ability to render into an OpenGL {@link - com.sun.opengl.util.texture.Texture Texture} using the Java 2D - APIs. This renderer class uses an internal Java 2D image (of - unspecified type) for its backing store and flushes portions of - that image to an OpenGL texture on demand. The resulting OpenGL - texture can then be mapped on to a polygon for display. */ - -public class J2DTextureRenderer { - // For now, we supply only a BufferedImage back-end for this - // renderer. In theory we could use the Java 2D/JOGL bridge to fully - // accelerate the rendering paths, but there are restrictions on - // what work can be done where; for example, Graphics2D-related work - // must not be done on the Queue Flusher Thread, but JOGL's - // OpenGL-related work must be. This implies that the user's code - // would need to be split up into multiple callbacks run from the - // appropriate threads, which would be somewhat unfortunate. - private boolean alpha; - private BufferedImage image; - - private Texture texture; - private TextureData textureData; - private boolean mustReallocateTexture; - - private GLU glu = new GLU(); - - /** Creates a new renderer with backing store of the specified width - and height. If alpha is true, allocates an alpha channel in the - backing store image. - - @param width the width of the texture to render into - @param height the height of the texture to render into - @param alpha whether to allocate an alpha channel for the texture - */ - public J2DTextureRenderer(int width, int height, boolean alpha) { - this.alpha = alpha; - init(width, height); - } - - /** Returns the width of the backing store of this renderer. - - @return the width of the backing store of this renderer - */ - public int getWidth() { - return image.getWidth(); - } - - /** Returns the height of the backing store of this renderer. - - @return the height of the backing store of this renderer - */ - public int getHeight() { - return image.getHeight(); - } - - /** Returns the size of the backing store of this renderer in a - newly-allocated {@link java.awt.Dimension Dimension} object. - - @return the size of the backing store of this renderer - */ - public Dimension getSize() { - return getSize(null); - } - - /** Returns the size of the backing store of this renderer. Uses the - {@link java.awt.Dimension Dimension} object if one is supplied, - or allocates a new one if null is passed. - - @param d a {@link java.awt.Dimension Dimension} object in which - to store the results, or null to allocate a new one - - @return the size of the backing store of this renderer - */ - public Dimension getSize(Dimension d) { - if (d == null) - d = new Dimension(); - d.setSize(image.getWidth(), image.getHeight()); - return d; - } - - /** Sets the size of the backing store of this renderer. This may - cause the OpenGL texture object associated with this renderer to - be invalidated; it is not recommended to cache this texture - object outside this class but to instead call {@link #getTexture - getTexture} when it is needed. - - @param width the new width of the backing store of this renderer - @param height the new height of the backing store of this renderer - */ - public void setSize(int width, int height) { - init(width, height); - } - - - /** Sets the size of the backing store of this renderer. This may - cause the OpenGL texture object associated with this renderer to - be invalidated. - - @param d the new size of the backing store of this renderer - */ - public void setSize(Dimension d) { - setSize(d.width, d.height); - } - - /** Creates a {@link java.awt.Graphics2D Graphics2D} instance for - rendering to the backing store of this renderer. The returned - object should be disposed of using the normal {@link - java.awt.Graphics#dispose() Graphics.dispose()} method once it - is no longer being used. - - @return a new {@link java.awt.Graphics2D Graphics2D} object for - rendering into the backing store of this renderer - */ - public Graphics2D createGraphics() { - return image.createGraphics(); - } - - /** Returns the underlying Java 2D {@link java.awt.Image Image} - being rendered into. */ - public Image getImage() { - return image; - } - - /** Synchronizes the specified region of the backing store down to - the underlying OpenGL texture. - - @param x the x coordinate (in Java 2D coordinates -- relative to - upper left) of the region to update - @param y the y coordinate (in Java 2D coordinates -- relative to - upper left) of the region to update - @param width the width of the region to update - @param height the height of the region to update - - @throws GLException If an OpenGL context is not current when this method is called - */ - public void sync(int x, int y, int width, int height) throws GLException { - // Force allocation if necessary - boolean canSkipUpdate = ensureTexture(); - - if (!canSkipUpdate) { - // Update specified region - texture.updateSubImage(textureData, 0, x, y, x, y, width, height); - } - } - - /** Returns the underlying OpenGL Texture object associated with - this renderer. - - @throws GLException If an OpenGL context is not current when this method is called - */ - public Texture getTexture() throws GLException { - ensureTexture(); - return texture; - } - - /** Disposes all resources associated with this renderer. It is not - valid to use this renderer after calling this method. - - @throws GLException If an OpenGL context is not current when this method is called - */ - public void dispose() throws GLException { - if (texture != null) { - texture.dispose(); - texture = null; - } - if (image != null) { - image.flush(); - image = null; - } - } - - /** Convenience method which assists in rendering portions of the - OpenGL texture to the screen, if the application intends to draw - them as a flat overlay on to the screen. Sets up the viewing - matrices, for orthographic rendering where the coordinates go - from (0, 0) at the lower left to (width, height) at the upper - right; disables the depth test and lighting; and enables the - texture in this renderer. {@link #endOrthoRendering} must be - used in conjunction with this method to restore all OpenGL - states. - - @param width the width of the current on-screen OpenGL drawable - @param height the height of the current on-screen OpenGL drawable - - @throws GLException If an OpenGL context is not current when this method is called - */ - public void beginOrthoRendering(int width, int height) throws GLException { - GL gl = GLU.getCurrentGL(); - gl.glPushAttrib(GL.GL_ENABLE_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_TRANSFORM_BIT); - gl.glDisable(GL.GL_DEPTH_TEST); - gl.glDisable(GL.GL_CULL_FACE); - gl.glDisable(GL.GL_LIGHTING); - gl.glMatrixMode(GL.GL_PROJECTION); - gl.glPushMatrix(); - gl.glLoadIdentity(); - glu.gluOrtho2D(0, width, 0, height); - gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glPushMatrix(); - gl.glLoadIdentity(); - gl.glEnable(GL.GL_BLEND); - gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA); - Texture texture = getTexture(); - texture.enable(); - texture.bind(); - gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); - } - - /** Draws an orthographically projected rectangle containing all of - the underlying texture to the specified location on the - screen. All (x, y) coordinates are specified relative to the - lower left corner of either the texture image or the current - OpenGL drawable. This method is equivalent to - drawOrthoRect(screenx, screeny, 0, 0, getWidth(), - getHeight());. - - @param screenx the on-screen x coordinate at which to draw the rectangle - @param screeny the on-screen y coordinate (relative to lower left) at - which to draw the rectangle - - @throws GLException If an OpenGL context is not current when this method is called - */ - public void drawOrthoRect(int screenx, int screeny) throws GLException { - drawOrthoRect(screenx, screeny, 0, 0, getWidth(), getHeight()); - } - - /** Draws an orthographically projected rectangle of the underlying - texture to the specified location on the screen. All (x, y) - coordinates are specified relative to the lower left corner of - either the texture image or the current OpenGL drawable. - - @param screenx the on-screen x coordinate at which to draw the rectangle - @param screeny the on-screen y coordinate (relative to lower left) at - which to draw the rectangle - @param texturex the x coordinate of the pixel in the texture of - the lower left portion of the rectangle to draw - @param texturey the y coordinate of the pixel in the texture - (relative to lower left) of the lower left portion of the - rectangle to draw - @param width the width of the rectangle to draw - @param height the height of the rectangle to draw - - @throws GLException If an OpenGL context is not current when this method is called - */ - public void drawOrthoRect(int screenx, int screeny, - int texturex, int texturey, - int width, int height) throws GLException { - GL gl = GLU.getCurrentGL(); - Texture texture = getTexture(); - TextureCoords coords = texture.getSubImageTexCoords(texturex, texturey, - texturex + width, - texturey + height); - gl.glBegin(GL.GL_QUADS); - gl.glTexCoord2f(coords.left(), coords.bottom()); - gl.glVertex3f(screenx, screeny, 0); - gl.glTexCoord2f(coords.right(), coords.bottom()); - gl.glVertex3f(screenx + width, screeny, 0); - gl.glTexCoord2f(coords.right(), coords.top()); - gl.glVertex3f(screenx + width, screeny + height, 0); - gl.glTexCoord2f(coords.left(), coords.top()); - gl.glVertex3f(screenx, screeny + height, 0); - gl.glEnd(); - } - - /** Convenience method which assists in rendering portions of the - OpenGL texture to the screen, if the application intends to draw - them as a flat overlay on to the screen. Must be used if {@link - #beginOrthoRendering} is used to set up the rendering stage for - this overlay. - - @throws GLException If an OpenGL context is not current when this method is called - */ - public void endOrthoRendering() throws GLException { - GL gl = GLU.getCurrentGL(); - Texture texture = getTexture(); - texture.disable(); - gl.glMatrixMode(GL.GL_PROJECTION); - gl.glPopMatrix(); - gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glPopMatrix(); - gl.glPopAttrib(); - } - - //---------------------------------------------------------------------- - // Internals only below this point - // - - private void init(int width, int height) { - // Discard previous BufferedImage if any - if (image != null) { - image.flush(); - image = null; - } - - int imageType = (alpha ? BufferedImage.TYPE_INT_ARGB_PRE : BufferedImage.TYPE_INT_RGB); - image = new BufferedImage(width, height, imageType); - // Always realllocate the TextureData associated with this - // BufferedImage; it's just a reference to the contents but we - // need it in order to update sub-regions of the underlying - // texture - textureData = TextureIO.newTextureData(image, false); - // For now, always reallocate the underlying OpenGL texture when - // the backing store size changes - mustReallocateTexture = true; - } - - // Returns true if the texture was newly allocated, false if not - private boolean ensureTexture() { - if (mustReallocateTexture) { - if (texture != null) { - texture.dispose(); - texture = null; - } - } - - if (texture == null) { - texture = TextureIO.newTexture(textureData); - return true; - } - - return false; - } -} diff --git a/src/classes/com/sun/opengl/util/j2d/Overlay.java b/src/classes/com/sun/opengl/util/j2d/Overlay.java new file mode 100755 index 000000000..d427ab176 --- /dev/null +++ b/src/classes/com/sun/opengl/util/j2d/Overlay.java @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.sun.opengl.util.j2d; + +import java.awt.Graphics2D; + +import javax.media.opengl.*; +import com.sun.opengl.util.texture.*; + +/** Provides a Java 2D overlay on top of an arbitrary GLDrawable, + making it easier to do things like draw text and images on top of + an OpenGL scene while still maintaining reasonably good + efficiency. For correct operation, the drawable should be + allocated with alpha bits enabled, as the Overlay uses alpha + blending to make portions of itself transparent. */ + +public class Overlay { + private GLDrawable drawable; + private TextureRenderer renderer; + private boolean contentsLost; + + /** Creates a new Java 2D overlay on top of the specified + GLDrawable. */ + public Overlay(GLDrawable drawable) { + this.drawable = drawable; + } + + /** Creates a {@link java.awt.Graphics2D Graphics2D} instance for + rendering into the overlay. The returned object should be + disposed of using the normal {@link java.awt.Graphics#dispose() + Graphics.dispose()} method once it is no longer being used. + + @return a new {@link java.awt.Graphics2D Graphics2D} object for + rendering into the backing store of this renderer + */ + public Graphics2D createGraphics() { + // Validate the size of the renderer against the current size of + // the drawable + validateRenderer(); + return renderer.createGraphics(); + } + + /** Indicates whether the Java 2D contents of the overlay were lost + since the last time {@link #createGraphics} was called. This + method should be called immediately after calling {@link + #createGraphics} to see whether the entire contents of the + overlay need to be redrawn or just the region the application is + interested in updating. + + @return whether the contents of the overlay were lost since the + last render + */ + public boolean contentsLost() { + return contentsLost; + } + + /** Synchronizes the contents of the Java 2D rendering down to the + OpenGL texture. + + @param x the x coordinate (in Java 2D coordinates -- relative to + upper left) of the region to update + @param y the y coordinate (in Java 2D coordinates -- relative to + upper left) of the region to update + @param width the width of the region to update + @param height the height of the region to update + + @throws GLException If an OpenGL context is not current when this method is called + */ + public void sync(int x, int y, int width, int height) throws GLException { + renderer.sync(x, y, width, height); + } + + /** Draws the entire contents of the overlay on top of the OpenGL + drawable. This is a convenience method which encapsulates all + portions of the rendering process; if this method is used, + {@link #beginRendering}, {@link #endRendering}, etc. should not + be used. This method should be called while the OpenGL context + for the drawable is current, and after your OpenGL scene has + been rendered. + + @throws GLException If an OpenGL context is not current when this method is called + */ + public void drawAll() throws GLException { + beginRendering(); + draw(0, 0, drawable.getWidth(), drawable.getHeight()); + endRendering(); + } + + /** Begins the OpenGL rendering process for the overlay. This is + separated out so advanced applications can render independent + pieces of the overlay to different portions of the drawable. + + @throws GLException If an OpenGL context is not current when this method is called + */ + public void beginRendering() throws GLException { + renderer.beginOrthoRendering(drawable.getWidth(), drawable.getHeight()); + } + + /** Ends the OpenGL rendering process for the overlay. This is + separated out so advanced applications can render independent + pieces of the overlay to different portions of the drawable. + + @throws GLException If an OpenGL context is not current when this method is called + */ + public void endRendering() throws GLException { + renderer.endOrthoRendering(); + } + + /** Draws the specified sub-rectangle of the overlay on top of the + OpenGL drawable. {@link #beginRendering} and {@link + #endRendering} must be used in conjunction with this method to + achieve proper rendering results. This method should be called + while the OpenGL context for the drawable is current, and after + your OpenGL scene has been rendered. + + @param x the lower-left x coordinate (relative to the lower left + of the overlay) of the rectangle to draw + @param y the lower-left y coordinate (relative to the lower left + of the overlay) of the rectangle to draw + @param width the width of the rectangle to draw + @param height the height of the rectangle to draw + + @throws GLException If an OpenGL context is not current when this method is called + */ + public void draw(int x, int y, int width, int height) throws GLException { + draw(x, y, x, y, width, height); + } + + /** Draws the specified sub-rectangle of the overlay at the + specified x and y coordinate on top of the OpenGL drawable. + {@link #beginRendering} and {@link #endRendering} must be used + in conjunction with this method to achieve proper rendering + results. This method should be called while the OpenGL context + for the drawable is current, and after your OpenGL scene has + been rendered. + + @param screenx the on-screen x coordinate at which to draw the rectangle + @param screeny the on-screen y coordinate (relative to lower left) at + which to draw the rectangle + @param overlayx the x coordinate of the pixel in the overlay of + the lower left portion of the rectangle to draw + @param overlayy the y coordinate of the pixel in the overlay + (relative to lower left) of the lower left portion of the + rectangle to draw + @param width the width of the rectangle to draw + @param height the height of the rectangle to draw + + @throws GLException If an OpenGL context is not current when this method is called + */ + public void draw(int screenx, int screeny, + int overlayx, int overlayy, + int width, int height) throws GLException { + renderer.drawOrthoRect(screenx, screeny, + overlayx, overlayy, + width, height); + } + + //---------------------------------------------------------------------- + // Internals only below this point + // + + private void validateRenderer() { + if (renderer == null) { + renderer = new TextureRenderer(drawable.getWidth(), + drawable.getHeight(), + true); + contentsLost = true; + } else if (renderer.getWidth() != drawable.getWidth() || + renderer.getHeight() != drawable.getHeight()) { + renderer.setSize(drawable.getWidth(), drawable.getHeight()); + contentsLost = true; + } else { + contentsLost = false; + } + } +} diff --git a/src/classes/com/sun/opengl/util/j2d/TextureRenderer.java b/src/classes/com/sun/opengl/util/j2d/TextureRenderer.java new file mode 100755 index 000000000..552a66a3d --- /dev/null +++ b/src/classes/com/sun/opengl/util/j2d/TextureRenderer.java @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.sun.opengl.util.j2d; + +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.image.*; + +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.util.texture.*; + +/** Provides the ability to render into an OpenGL {@link + com.sun.opengl.util.texture.Texture Texture} using the Java 2D + APIs. This renderer class uses an internal Java 2D image (of + unspecified type) for its backing store and flushes portions of + that image to an OpenGL texture on demand. The resulting OpenGL + texture can then be mapped on to a polygon for display. */ + +public class TextureRenderer { + // For now, we supply only a BufferedImage back-end for this + // renderer. In theory we could use the Java 2D/JOGL bridge to fully + // accelerate the rendering paths, but there are restrictions on + // what work can be done where; for example, Graphics2D-related work + // must not be done on the Queue Flusher Thread, but JOGL's + // OpenGL-related work must be. This implies that the user's code + // would need to be split up into multiple callbacks run from the + // appropriate threads, which would be somewhat unfortunate. + private boolean alpha; + private BufferedImage image; + + private Texture texture; + private TextureData textureData; + private boolean mustReallocateTexture; + + private GLU glu = new GLU(); + + /** Creates a new renderer with backing store of the specified width + and height. If alpha is true, allocates an alpha channel in the + backing store image. + + @param width the width of the texture to render into + @param height the height of the texture to render into + @param alpha whether to allocate an alpha channel for the texture + */ + public TextureRenderer(int width, int height, boolean alpha) { + this.alpha = alpha; + init(width, height); + } + + /** Returns the width of the backing store of this renderer. + + @return the width of the backing store of this renderer + */ + public int getWidth() { + return image.getWidth(); + } + + /** Returns the height of the backing store of this renderer. + + @return the height of the backing store of this renderer + */ + public int getHeight() { + return image.getHeight(); + } + + /** Returns the size of the backing store of this renderer in a + newly-allocated {@link java.awt.Dimension Dimension} object. + + @return the size of the backing store of this renderer + */ + public Dimension getSize() { + return getSize(null); + } + + /** Returns the size of the backing store of this renderer. Uses the + {@link java.awt.Dimension Dimension} object if one is supplied, + or allocates a new one if null is passed. + + @param d a {@link java.awt.Dimension Dimension} object in which + to store the results, or null to allocate a new one + + @return the size of the backing store of this renderer + */ + public Dimension getSize(Dimension d) { + if (d == null) + d = new Dimension(); + d.setSize(image.getWidth(), image.getHeight()); + return d; + } + + /** Sets the size of the backing store of this renderer. This may + cause the OpenGL texture object associated with this renderer to + be invalidated; it is not recommended to cache this texture + object outside this class but to instead call {@link #getTexture + getTexture} when it is needed. + + @param width the new width of the backing store of this renderer + @param height the new height of the backing store of this renderer + */ + public void setSize(int width, int height) { + init(width, height); + } + + + /** Sets the size of the backing store of this renderer. This may + cause the OpenGL texture object associated with this renderer to + be invalidated. + + @param d the new size of the backing store of this renderer + */ + public void setSize(Dimension d) { + setSize(d.width, d.height); + } + + /** Creates a {@link java.awt.Graphics2D Graphics2D} instance for + rendering to the backing store of this renderer. The returned + object should be disposed of using the normal {@link + java.awt.Graphics#dispose() Graphics.dispose()} method once it + is no longer being used. + + @return a new {@link java.awt.Graphics2D Graphics2D} object for + rendering into the backing store of this renderer + */ + public Graphics2D createGraphics() { + return image.createGraphics(); + } + + /** Returns the underlying Java 2D {@link java.awt.Image Image} + being rendered into. */ + public Image getImage() { + return image; + } + + /** Synchronizes the specified region of the backing store down to + the underlying OpenGL texture. + + @param x the x coordinate (in Java 2D coordinates -- relative to + upper left) of the region to update + @param y the y coordinate (in Java 2D coordinates -- relative to + upper left) of the region to update + @param width the width of the region to update + @param height the height of the region to update + + @throws GLException If an OpenGL context is not current when this method is called + */ + public void sync(int x, int y, int width, int height) throws GLException { + // Force allocation if necessary + boolean canSkipUpdate = ensureTexture(); + + if (!canSkipUpdate) { + // Update specified region + texture.updateSubImage(textureData, 0, x, y, x, y, width, height); + } + } + + /** Returns the underlying OpenGL Texture object associated with + this renderer. + + @throws GLException If an OpenGL context is not current when this method is called + */ + public Texture getTexture() throws GLException { + ensureTexture(); + return texture; + } + + /** Disposes all resources associated with this renderer. It is not + valid to use this renderer after calling this method. + + @throws GLException If an OpenGL context is not current when this method is called + */ + public void dispose() throws GLException { + if (texture != null) { + texture.dispose(); + texture = null; + } + if (image != null) { + image.flush(); + image = null; + } + } + + /** Convenience method which assists in rendering portions of the + OpenGL texture to the screen, if the application intends to draw + them as a flat overlay on to the screen. Sets up the viewing + matrices, for orthographic rendering where the coordinates go + from (0, 0) at the lower left to (width, height) at the upper + right; disables the depth test and lighting; and enables the + texture in this renderer. {@link #endOrthoRendering} must be + used in conjunction with this method to restore all OpenGL + states. + + @param width the width of the current on-screen OpenGL drawable + @param height the height of the current on-screen OpenGL drawable + + @throws GLException If an OpenGL context is not current when this method is called + */ + public void beginOrthoRendering(int width, int height) throws GLException { + GL gl = GLU.getCurrentGL(); + gl.glPushAttrib(GL.GL_ENABLE_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_TRANSFORM_BIT); + gl.glDisable(GL.GL_DEPTH_TEST); + gl.glDisable(GL.GL_CULL_FACE); + gl.glDisable(GL.GL_LIGHTING); + gl.glMatrixMode(GL.GL_PROJECTION); + gl.glPushMatrix(); + gl.glLoadIdentity(); + glu.gluOrtho2D(0, width, 0, height); + gl.glMatrixMode(GL.GL_MODELVIEW); + gl.glPushMatrix(); + gl.glLoadIdentity(); + gl.glEnable(GL.GL_BLEND); + gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA); + Texture texture = getTexture(); + texture.enable(); + texture.bind(); + gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); + } + + /** Draws an orthographically projected rectangle containing all of + the underlying texture to the specified location on the + screen. All (x, y) coordinates are specified relative to the + lower left corner of either the texture image or the current + OpenGL drawable. This method is equivalent to + drawOrthoRect(screenx, screeny, 0, 0, getWidth(), + getHeight());. + + @param screenx the on-screen x coordinate at which to draw the rectangle + @param screeny the on-screen y coordinate (relative to lower left) at + which to draw the rectangle + + @throws GLException If an OpenGL context is not current when this method is called + */ + public void drawOrthoRect(int screenx, int screeny) throws GLException { + drawOrthoRect(screenx, screeny, 0, 0, getWidth(), getHeight()); + } + + /** Draws an orthographically projected rectangle of the underlying + texture to the specified location on the screen. All (x, y) + coordinates are specified relative to the lower left corner of + either the texture image or the current OpenGL drawable. + + @param screenx the on-screen x coordinate at which to draw the rectangle + @param screeny the on-screen y coordinate (relative to lower left) at + which to draw the rectangle + @param texturex the x coordinate of the pixel in the texture of + the lower left portion of the rectangle to draw + @param texturey the y coordinate of the pixel in the texture + (relative to lower left) of the lower left portion of the + rectangle to draw + @param width the width of the rectangle to draw + @param height the height of the rectangle to draw + + @throws GLException If an OpenGL context is not current when this method is called + */ + public void drawOrthoRect(int screenx, int screeny, + int texturex, int texturey, + int width, int height) throws GLException { + GL gl = GLU.getCurrentGL(); + Texture texture = getTexture(); + TextureCoords coords = texture.getSubImageTexCoords(texturex, texturey, + texturex + width, + texturey + height); + gl.glBegin(GL.GL_QUADS); + gl.glTexCoord2f(coords.left(), coords.bottom()); + gl.glVertex3f(screenx, screeny, 0); + gl.glTexCoord2f(coords.right(), coords.bottom()); + gl.glVertex3f(screenx + width, screeny, 0); + gl.glTexCoord2f(coords.right(), coords.top()); + gl.glVertex3f(screenx + width, screeny + height, 0); + gl.glTexCoord2f(coords.left(), coords.top()); + gl.glVertex3f(screenx, screeny + height, 0); + gl.glEnd(); + } + + /** Convenience method which assists in rendering portions of the + OpenGL texture to the screen, if the application intends to draw + them as a flat overlay on to the screen. Must be used if {@link + #beginOrthoRendering} is used to set up the rendering stage for + this overlay. + + @throws GLException If an OpenGL context is not current when this method is called + */ + public void endOrthoRendering() throws GLException { + GL gl = GLU.getCurrentGL(); + Texture texture = getTexture(); + texture.disable(); + gl.glMatrixMode(GL.GL_PROJECTION); + gl.glPopMatrix(); + gl.glMatrixMode(GL.GL_MODELVIEW); + gl.glPopMatrix(); + gl.glPopAttrib(); + } + + //---------------------------------------------------------------------- + // Internals only below this point + // + + private void init(int width, int height) { + // Discard previous BufferedImage if any + if (image != null) { + image.flush(); + image = null; + } + + int imageType = (alpha ? BufferedImage.TYPE_INT_ARGB_PRE : BufferedImage.TYPE_INT_RGB); + image = new BufferedImage(width, height, imageType); + // Always realllocate the TextureData associated with this + // BufferedImage; it's just a reference to the contents but we + // need it in order to update sub-regions of the underlying + // texture + textureData = TextureIO.newTextureData(image, false); + // For now, always reallocate the underlying OpenGL texture when + // the backing store size changes + mustReallocateTexture = true; + } + + // Returns true if the texture was newly allocated, false if not + private boolean ensureTexture() { + if (mustReallocateTexture) { + if (texture != null) { + texture.dispose(); + texture = null; + } + } + + if (texture == null) { + texture = TextureIO.newTexture(textureData); + return true; + } + + return false; + } +} -- cgit v1.2.3