diff options
Diffstat (limited to 'src/classes/com/sun/opengl/utils/Texture.java')
-rwxr-xr-x | src/classes/com/sun/opengl/utils/Texture.java | 536 |
1 files changed, 0 insertions, 536 deletions
diff --git a/src/classes/com/sun/opengl/utils/Texture.java b/src/classes/com/sun/opengl/utils/Texture.java deleted file mode 100755 index 924161d69..000000000 --- a/src/classes/com/sun/opengl/utils/Texture.java +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Copyright (c) 2005 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. - */ - -package com.sun.opengl.utils; - -import java.nio.*; - -import javax.media.opengl.*; -import javax.media.opengl.glu.*; -import com.sun.opengl.impl.*; - -/** - * Represents an OpenGL texture object. Contains convenience routines - * for enabling/disabling OpenGL texture state, binding this texture, - * and computing texture coordinates for both the entire image as well - * as a sub-image. - * - * <br> REMIND: document GL_TEXTURE_2D/GL_TEXTURE_RECTANGLE_ARB issues... - * <br> REMIND: translucent images will have premultiplied comps by default... - * - * @author Chris Campbell - * @author Kenneth Russell - */ -public class Texture { - /** The GL target type. */ - private int target; - /** The GL texture ID. */ - private int texID; - /** The width of the texture. */ - private int texWidth; - /** The height of the texture. */ - private int texHeight; - /** The width of the image. */ - private int imgWidth; - /** The height of the image. */ - private int imgHeight; - /** Indicates whether the TextureData requires a vertical flip of - the texture coords. */ - private boolean mustFlipVertically; - - /** The texture coordinates corresponding to the entire image. */ - private TextureCoords coords; - - private static final boolean DEBUG = Debug.debug("Texture"); - - // For now make Texture constructor package-private to limit the - // number of public APIs we commit to - Texture(TextureData data) throws GLException { - GL gl = GLU.getCurrentGL(); - texID = createTextureID(gl); - - updateImage(data); - } - - // Constructor for use when creating e.g. cube maps, where there is - // no initial texture data - Texture(int target) throws GLException { - GL gl = GLU.getCurrentGL(); - texID = createTextureID(gl); - this.target = target; - } - - /** - * Enables this texture's target (e.g., GL_TEXTURE_2D) in the - * current GL context's state. - * - * @throws GLException if no OpenGL context was current or if any - * OpenGL-related errors occurred - */ - public void enable() throws GLException { - GLU.getCurrentGL().glEnable(target); - } - - /** - * Disables this texture's target (e.g., GL_TEXTURE_2D) in the - * current GL context's state. - * - * @throws GLException if no OpenGL context was current or if any - * OpenGL-related errors occurred - */ - public void disable() throws GLException { - GLU.getCurrentGL().glDisable(target); - } - - /** - * Binds this texture to the current GL context. - * - * @throws GLException if no OpenGL context was current or if any - * OpenGL-related errors occurred - */ - public void bind() throws GLException { - GLU.getCurrentGL().glBindTexture(target, texID); - } - - /** - * Disposes the native resources used by this texture object. - * - * @throws GLException if no OpenGL context was current or if any - * OpenGL-related errors occurred - */ - public void dispose() throws GLException { - GLU.getCurrentGL().glDeleteTextures(1, new int[] {texID}, 0); - texID = 0; - } - - /** - * Returns the OpenGL "target" of this texture. - * - * @return the OpenGL target of this texture - * @see javax.media.opengl.GL#GL_TEXTURE_2D - * @see javax.media.opengl.GL#GL_TEXTURE_RECTANGLE_ARB - */ - public int getTarget() { - return target; - } - - /** - * Returns the width of the texture. Note that the texture width will - * be greater than or equal to the width of the image contained within. - * - * @return the width of the texture - */ - public int getWidth() { - return texWidth; - } - - /** - * Returns the height of the texture. Note that the texture height will - * be greater than or equal to the height of the image contained within. - * - * @return the height of the texture - */ - public int getHeight() { - return texHeight; - } - - /** - * Returns the width of the image contained within this texture. - * - * @return the width of the image - */ - public int getImageWidth() { - return imgWidth; - } - - /** - * Returns the height of the image contained within this texture. - * - * @return the height of the image - */ - public int getImageHeight() { - return imgHeight; - } - - /** - * Returns the set of texture coordinates corresponding to the - * entire image. If the TextureData indicated that the texture - * coordinates must be flipped vertically, the returned - * TextureCoords will take that into account. - * - * @return the texture coordinates corresponding to the entire image - */ - public TextureCoords getImageTexCoords() { - return coords; - } - - /** - * Returns the set of texture coordinates corresponding to the - * specified sub-image. The (x1, y1) and (x2, y2) points are - * specified in terms of pixels starting from the lower-left of the - * image. (x1, y1) should specify the lower-left corner of the - * sub-image and (x2, y2) the upper-right corner of the sub-image. - * If the TextureData indicated that the texture coordinates must be - * flipped vertically, the returned TextureCoords will take that - * into account; this should not be handled by the end user in the - * specification of the y1 and y2 coordinates. - * - * @return the texture coordinates corresponding to the specified sub-image - */ - public TextureCoords getSubImageTexCoords(int x1, int y1, int x2, int y2) { - if (target == GL.GL_TEXTURE_RECTANGLE_ARB) { - if (mustFlipVertically) { - return new TextureCoords(x1, texHeight - y1, x2, texHeight - y2); - } else { - return new TextureCoords(x1, y1, x2, y2); - } - } else { - float tx1 = (float)x1 / (float)texWidth; - float ty1 = (float)y1 / (float)texHeight; - float tx2 = (float)x2 / (float)texWidth; - float ty2 = (float)y2 / (float)texHeight; - if (mustFlipVertically) { - return new TextureCoords(tx1, 1.0f - ty1, tx2, 1.0f - ty2); - } else { - return new TextureCoords(tx1, ty1, tx2, ty2); - } - } - } - - /** - * Updates the entire content area of this texture using the data in - * the given image. - * - * @throws GLException if no OpenGL context was current or if any - * OpenGL-related errors occurred - */ - public void updateImage(TextureData data) throws GLException { - updateImage(data, 0); - } - - /** - * Indicates whether this texture's texture coordinates must be - * flipped vertically in order to properly display the texture. This - * is handled automatically by {@link #getImageTexCoords} and {@link - * #getSubImageTexCoords}, but applications may generate or - * otherwise produce texture coordinates which must be corrected. - */ - public boolean getMustFlipVertically() { - return mustFlipVertically; - } - - /** - * Updates the content area of the specified target of this texture - * using the data in the given image. In general this is intended - * for construction of cube maps. - * - * @throws GLException if no OpenGL context was current or if any - * OpenGL-related errors occurred - */ - public void updateImage(TextureData data, int target) throws GLException { - GL gl = GLU.getCurrentGL(); - - imgWidth = data.getWidth(); - imgHeight = data.getHeight(); - mustFlipVertically = data.getMustFlipVertically(); - - int newTarget = 0; - - if (data.getMipmap()) { - // GLU always scales the texture's dimensions to be powers of - // two. It also doesn't really matter exactly what the texture - // width and height are because the texture coords are always - // between 0.0 and 1.0. - imgWidth = nextPowerOfTwo(imgWidth); - imgHeight = nextPowerOfTwo(imgHeight); - texWidth = imgWidth; - texHeight = imgHeight; - newTarget = GL.GL_TEXTURE_2D; - } else if ((isPowerOfTwo(imgWidth) && isPowerOfTwo(imgHeight)) || - gl.isExtensionAvailable("GL_ARB_texture_non_power_of_two")) { - if (DEBUG) { - if (isPowerOfTwo(imgWidth) && isPowerOfTwo(imgHeight)) { - System.err.println("Power-of-two texture"); - } else { - System.err.println("Using GL_ARB_texture_non_power_of_two"); - } - } - - texWidth = imgWidth; - texHeight = imgHeight; - newTarget = GL.GL_TEXTURE_2D; - } else if (gl.isExtensionAvailable("GL_ARB_texture_rectangle")) { - if (DEBUG) { - System.err.println("Using GL_ARB_texture_rectangle"); - } - - texWidth = imgWidth; - texHeight = imgHeight; - newTarget = GL.GL_TEXTURE_RECTANGLE_ARB; - } else { - if (DEBUG) { - System.err.println("Expanding texture to power-of-two dimensions"); - } - - if (data.getBorder() != 0) { - throw new RuntimeException("Scaling up a non-power-of-two texture which has a border won't work"); - } - texWidth = nextPowerOfTwo(imgWidth); - texHeight = nextPowerOfTwo(imgHeight); - newTarget = GL.GL_TEXTURE_2D; - } - - setImageSize(imgWidth, imgHeight); - - if (target != 0) { - // Allow user to override auto detection and skip bind step (for - // cubemap construction) - newTarget = target; - if (this.target == 0) { - throw new GLException("Override of target failed; no target specified yet"); - } - gl.glBindTexture(this.target, texID); - } else { - gl.glBindTexture(newTarget, texID); - } - - // REMIND: let the user specify these, optionally - int minFilter = (data.getMipmap() ? GL.GL_LINEAR_MIPMAP_LINEAR : GL.GL_LINEAR); - int magFilter = GL.GL_LINEAR; - int wrapMode = GL.GL_CLAMP_TO_EDGE; - - // REMIND: figure out what to do for GL_TEXTURE_RECTANGLE_ARB - if (newTarget != GL.GL_TEXTURE_RECTANGLE_ARB) { - gl.glTexParameteri(newTarget, GL.GL_TEXTURE_MIN_FILTER, minFilter); - gl.glTexParameteri(newTarget, GL.GL_TEXTURE_MAG_FILTER, magFilter); - gl.glTexParameteri(newTarget, GL.GL_TEXTURE_WRAP_S, wrapMode); - gl.glTexParameteri(newTarget, GL.GL_TEXTURE_WRAP_T, wrapMode); - if (newTarget == GL.GL_TEXTURE_CUBE_MAP) { - gl.glTexParameteri(newTarget, GL.GL_TEXTURE_WRAP_R, wrapMode); - } - } - - if (data.getMipmap()) { - GLU glu = new GLU(); - glu.gluBuild2DMipmaps(newTarget, data.getInternalFormat(), - data.getWidth(), data.getHeight(), - data.getPixelFormat(), data.getPixelType(), data.getBuffer()); - } else { - gl.glTexImage2D(newTarget, 0, data.getInternalFormat(), - texWidth, texHeight, data.getBorder(), - data.getPixelFormat(), data.getPixelType(), null); - Buffer[] mipmapData = data.getMipmapData(); - if (mipmapData != null) { - for (int i = 0; i < mipmapData.length; i++) { - updateSubImageImpl(data, newTarget, i, 0, 0); - } - } else { - updateSubImageImpl(data, newTarget, 0, 0, 0); - } - } - - // Don't overwrite target if we're loading e.g. faces of a cube - // map - if ((this.target == 0) || - (this.target == GL.GL_TEXTURE_2D) || - (this.target == GL.GL_TEXTURE_RECTANGLE_ARB)) { - this.target = newTarget; - } - } - - /** - * Updates a subregion of the content area of this texture using the - * data in the given image. Only updates the specified mipmap level - * and does not re-generate mipmaps if they were originally produced - * or loaded. - * - * @param data the image data to be uploaded to this texture - * @param mipmapLevel the mipmap level of the texture to set. If - * this is non-zero and the TextureData contains mipmap data, the - * appropriate mipmap level will be selected. - * @param x the x offset (in pixels) relative to the lower-left corner - * of this texture - * @param y the y offset (in pixels) relative to the lower-left corner - * of this texture - * - * @throws GLException if no OpenGL context was current or if any - * OpenGL-related errors occurred - */ - public void updateSubImage(TextureData data, int mipmapLevel, int x, int y) throws GLException { - updateSubImageImpl(data, target, mipmapLevel, x, y); - } - - /** - * Sets the OpenGL integer texture parameter for the texture's - * target. This gives control over parameters such as - * GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T, which by default are set - * to GL_CLAMP_TO_EDGE. Causes this texture to be bound to the - * current texture state. - * - * @throws GLException if no OpenGL context was current or if any - * OpenGL-related errors occurred - */ - public void setTexParameteri(int parameterName, - int value) { - bind(); - GL gl = GLU.getCurrentGL(); - gl.glTexParameteri(target, parameterName, value); - } - - /** - * Returns the underlying OpenGL texture object for this texture. - * Most applications will not need to access this, since it is - * handled automatically by the bind() and dispose() APIs. - */ - public int getTextureObject() { - return texID; - } - - //---------------------------------------------------------------------- - // Internals only below this point - // - - /** - * Returns true if the given value is a power of two. - * - * @return true if the given value is a power of two, false otherwise - */ - private static boolean isPowerOfTwo(int val) { - return ((val & (val - 1)) == 0); - } - - /** - * Returns the nearest power of two that is larger than the given value. - * If the given value is already a power of two, this method will simply - * return that value. - * - * @param val the value - * @return the next power of two - */ - private static int nextPowerOfTwo(int val) { - int ret = 1; - while (ret < val) { - ret <<= 1; - } - return ret; - } - - /** - * Updates the actual image dimensions; usually only called from - * <code>updateImage</code>. - */ - private void setImageSize(int width, int height) { - imgWidth = width; - imgHeight = height; - if (target == GL.GL_TEXTURE_RECTANGLE_ARB) { - if (mustFlipVertically) { - coords = new TextureCoords(0, imgHeight, imgWidth, 0); - } else { - coords = new TextureCoords(0, 0, imgWidth, imgHeight); - } - } else { - if (mustFlipVertically) { - coords = new TextureCoords(0, (float) imgHeight / (float) texHeight, - (float) imgWidth / (float) texWidth, 0); - } else { - coords = new TextureCoords(0, 0, - (float) imgWidth / (float) texWidth, - (float) imgHeight / (float) texHeight); - } - } - } - - private void updateSubImageImpl(TextureData data, int newTarget, int mipmapLevel, int x, int y) throws GLException { - GL gl = GLU.getCurrentGL(); - gl.glBindTexture(newTarget, texID); - int width = data.getWidth(); - int height = data.getHeight(); - Buffer buffer = data.getBuffer(); - if (data.getMipmapData() != null) { - // Compute the width and height at the specified mipmap level - for (int i = 0; i < mipmapLevel; i++) { - width /= 2; - height /= 2; - } - buffer = data.getMipmapData()[mipmapLevel]; - } - - if (data.isDataCompressed()) { - switch (data.getInternalFormat()) { - case GL.GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - if (!gl.isExtensionAvailable("GL_EXT_texture_compression_s3tc") && - !gl.isExtensionAvailable("GL_NV_texture_compression_vtc")) { - throw new GLException("DXTn compressed textures not supported by this graphics card"); - } - break; - default: - // FIXME: should test availability of more texture - // compression extensions here - break; - } - - gl.glCompressedTexSubImage2D(newTarget, mipmapLevel, - x, y, width, height, - data.getInternalFormat(), - buffer.remaining(), buffer); - } else { - int[] align = new int[1]; - gl.glGetIntegerv(GL.GL_UNPACK_ALIGNMENT, align, 0); // save alignment - gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, data.getAlignment()); - - gl.glTexSubImage2D(newTarget, mipmapLevel, - x, y, width, height, - data.getPixelFormat(), data.getPixelType(), - buffer); - gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, align[0]); // restore align - } - } - - /** - * Creates a new texture ID. - * - * @param gl the GL object associated with the current OpenGL context - * @return a new texture ID - */ - private static int createTextureID(GL gl) { - int[] tmp = new int[1]; - gl.glGenTextures(1, tmp, 0); - return tmp[0]; - } -} |