aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java234
1 files changed, 150 insertions, 84 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
index a94b1f827..584cacf8c 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
@@ -1,21 +1,22 @@
/*
* Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
- *
+ * Copyright (c) 2010 JogAmp Community. 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
@@ -28,7 +29,7 @@
* 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.
@@ -44,24 +45,39 @@ import javax.media.nativewindow.NativeWindowFactory;
import jogamp.opengl.*;
+import com.jogamp.opengl.GLExtensions;
import com.jogamp.opengl.util.texture.spi.*;
/**
* 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.
- *
+ * as a sub-image.
+ *
+ * <a name="textureCallOrder"><h5>Order of Texture Commands</h5></a>
+ * <p>
+ * Due to many confusions w/ texture usage, following list described the order
+ * and semantics of texture unit selection, binding and enabling.
+ * <ul>
+ * <li><i>Optional:</i> Set active textureUnit via <code>gl.glActiveTexture(GL.GL_TEXTURE0 + textureUnit)</code>, <code>0</code> is default.</li>
+ * <li>Bind <code>textureId</code> -> active <code>textureUnit</code>'s <code>textureTarget</code> via <code>gl.glBindTexture(textureTarget, textureId)</code></li>
+ * <li><i>Compatible Context Only:</i> Enable active <code>textureUnit</code>'s <code>textureTarget</code> via <code>glEnable(textureTarget)</code>.
+ * <li><i>Optional:</i> Fiddle with the texture parameters and/or environment settings.</li>
+ * <li>GLSL: Use <code>textureUnit</code> in your shader program, enable shader program.</li>
+ * <li>Issue draw commands</li>
+ * </ul>
+ * </p>
+ *
* <p><a name="nonpow2"><b>Non-power-of-two restrictions</b></a>
* <br> When creating an OpenGL texture object, the Texture class will
- * attempt to leverage the <a
- * href="http://www.opengl.org/registry/specs/ARB/texture_non_power_of_two.txt">GL_ARB_texture_non_power_of_two</a>
- * and <a
- * href="http://www.opengl.org/registry/specs/ARB/texture_rectangle.txt">GL_ARB_texture_rectangle</a>
- * extensions (in that order) whenever possible. If neither extension
- * is available, the Texture class will simply upload a non-pow2-sized
+ * attempt to use <i>non-power-of-two textures</i> (NPOT) if available, see {@link GL#isNPOTTextureAvailable()}.
+ * Further more,
+ * <a href="http://www.opengl.org/registry/specs/ARB/texture_rectangle.txt">GL_ARB_texture_rectangle</a>
+ * (RECT) will be attempted on OSX w/ ATI drivers.
+ * If NPOT is not available or RECT not chosen, the Texture class will simply upload a non-pow2-sized
* image into a standard pow2-sized texture (without any special
- * scaling). Since the choice of extension (or whether one is used at
+ * scaling).
+ * Since the choice of extension (or whether one is used at
* all) depends on the user's machine configuration, developers are
* recommended to use {@link #getImageTexCoords} and {@link
* #getSubImageTexCoords}, as those methods will calculate the
@@ -89,16 +105,24 @@ import com.jogamp.opengl.util.texture.spi.*;
* when switching between textures it is necessary to call {@link
* #bind}, but when drawing many triangles all using the same texture,
* for best performance only one call to {@link #bind} should be made.
+ * User may also utilize multiple texture units,
+ * see <a href="#textureCallOrder"> order of texture commands above</a>.
*
* <p><a name="premult"><b>Alpha premultiplication and blending</b></a>
- * <br> The mathematically correct way to perform blending in OpenGL
- * (with the SrcOver "source over destination" mode, or any other
- * Porter-Duff rule) is to use "premultiplied color components", which
- * means the R/G/ B color components have already been multiplied by
- * the alpha value. To make things easier for developers, the Texture
- * class will automatically convert non-premultiplied image data into
- * premultiplied data when storing it into an OpenGL texture. As a
- * result, it is important to use the correct blending function; for
+ * <p>
+ * <i>Disclaimer: Consider performing alpha premultiplication in shader code, if really desired! Otherwise use RGBA.</i><br/>
+ * </p>
+ * <p>
+ * The Texture class does not convert RGBA image data into
+ * premultiplied data when storing it into an OpenGL texture.
+ * </p>
+ * <p>
+ * The mathematically correct way to perform blending in OpenGL
+ * with the SrcOver "source over destination" mode, or any other
+ * Porter-Duff rule, is to use <i>premultiplied color components</i>,
+ * which means the R/G/ B color components must have been multiplied by
+ * the alpha value. If using <i>premultiplied color components</i>
+ * it is important to use the correct blending function; for
* example, the SrcOver rule is expressed as:
<pre>
gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA);
@@ -113,7 +137,7 @@ import com.jogamp.opengl.util.texture.spi.*;
float g = g * a;
float b = b * a;
gl.glColor4f(r, g, b, a);
-</pre>
+</pre>
*
* For reference, here is a list of the Porter-Duff compositing rules
* and the associated OpenGL blend functions (source and destination
@@ -136,9 +160,7 @@ import com.jogamp.opengl.util.texture.spi.*;
<TR> <TD> AlphaXor <TD> GL_ONE_MINUS_DST_ALPHA <TD> GL_ONE_MINUS_SRC_ALPHA
</TABLE>
</CENTER>
- *
- * @author Chris Campbell
- * @author Kenneth Russell
+ * @author Chris Campbell, Kenneth Russell, et.al.
*/
public class Texture {
/** The GL target type. */
@@ -166,6 +188,13 @@ public class Texture {
/** The texture coordinates corresponding to the entire image. */
private TextureCoords coords;
+ @Override
+ public String toString() {
+ return "Texture[target 0x"+Integer.toHexString(target)+", name "+texID+", "+
+ imgWidth+"/"+texWidth+" x "+imgHeight+"/"+texHeight+", y-flip "+mustFlipVertically+
+ ", "+estimatedMemorySize+" bytes]";
+ }
+
/** An estimate of the amount of texture memory this texture consumes. */
private int estimatedMemorySize;
@@ -205,12 +234,13 @@ public class Texture {
* Enables this texture's target (e.g., GL_TEXTURE_2D) in the
* given GL context's state. This method is a shorthand equivalent
* of the following OpenGL code:
- <pre>
- gl.glEnable(texture.getTarget());
- </pre>
- *
+ * <pre>
+ * gl.glEnable(texture.getTarget());
+ * </pre>
* <p>
- * Call is ignored if {@link #getTarget()} is {@link GLES2#GL_TEXTURE_EXTERNAL_OES}.
+ * Call is ignored if the {@link GL} object's context
+ * is using a core profile, see {@link GL#isGLcore()},
+ * or if {@link #getTarget()} is {@link GLES2#GL_TEXTURE_EXTERNAL_OES}.
* </p>
* <p>
* See the <a href="#perftips">performance tips</a> above for hints
@@ -222,21 +252,22 @@ public class Texture {
* OpenGL-related errors occurred
*/
public void enable(GL gl) throws GLException {
- if(GLES2.GL_TEXTURE_EXTERNAL_OES != target) {
+ if( !gl.isGLcore() && GLES2.GL_TEXTURE_EXTERNAL_OES != target) {
gl.glEnable(target);
}
}
-
+
/**
* Disables this texture's target (e.g., GL_TEXTURE_2D) in the
* given GL state. This method is a shorthand equivalent
* of the following OpenGL code:
- <pre>
- gl.glDisable(texture.getTarget());
- </pre>
- *
+ * <pre>
+ * gl.glDisable(texture.getTarget());
+ * </pre>
* <p>
- * Call is ignored if {@link #getTarget()} is {@link GLES2#GL_TEXTURE_EXTERNAL_OES}.
+ * Call is ignored if the {@link GL} object's context
+ * is using a core profile, see {@link GL#isGLcore()},
+ * or if {@link #getTarget()} is {@link GLES2#GL_TEXTURE_EXTERNAL_OES}.
* </p>
* <p>
* See the <a href="#perftips">performance tips</a> above for hints
@@ -248,11 +279,11 @@ public class Texture {
* OpenGL-related errors occurred
*/
public void disable(GL gl) throws GLException {
- if(GLES2.GL_TEXTURE_EXTERNAL_OES != target) {
+ if( !gl.isGLcore() && GLES2.GL_TEXTURE_EXTERNAL_OES != target ) {
gl.glDisable(target);
}
}
-
+
/**
* Binds this texture to the given GL context. This method is a
* shorthand equivalent of the following OpenGL code:
@@ -262,22 +293,16 @@ public class Texture {
*
* See the <a href="#perftips">performance tips</a> above for hints
* on how to maximize performance when using many Texture objects.
- * @param gl TODO
*
+ * @param gl the current GL context
* @throws GLException if no OpenGL context was current or if any
* OpenGL-related errors occurred
*/
public void bind(GL gl) throws GLException {
validateTexID(gl, true);
- gl.glBindTexture(target, texID);
- }
-
- /**
- * @deprecated use {@link #destroy(GL)}
- */
- public final void dispose(GL gl) throws GLException {
- destroy(gl);
+ gl.glBindTexture(target, texID);
}
+
/**
* Destroys the native resources used by this texture object.
*
@@ -311,7 +336,7 @@ public class Texture {
public int getWidth() {
return texWidth;
}
-
+
/**
* Returns the height of the allocated OpenGL texture in pixels.
* Note that the texture height will be greater than or equal to the
@@ -321,9 +346,9 @@ public class Texture {
*/
public int getHeight() {
return texHeight;
- }
-
- /**
+ }
+
+ /**
* Returns the width of the image contained within this texture.
* Note that for non-power-of-two textures in particular this may
* not be equal to the result of {@link #getWidth}. It is
@@ -365,7 +390,7 @@ public class Texture {
* 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() {
@@ -382,7 +407,7 @@ public class Texture {
* 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) {
@@ -407,9 +432,9 @@ public class Texture {
}
/**
- * Updates the entire content area of this texture using the data in
- * the given image.
- *
+ * Updates the entire content area incl. {@link TextureCoords}
+ * of this texture using the data in the given image.
+ *
* @throws GLException if any OpenGL-related errors occurred
*/
public void updateImage(GL gl, TextureData data) throws GLException {
@@ -429,10 +454,24 @@ public class Texture {
}
/**
- * Updates the content area of the specified target of this texture
+ * Change whether the TextureData requires a vertical flip of
+ * the texture coords.
+ * <p>
+ * No-op if no change, otherwise generates new {@link TextureCoords}.
+ * </p>
+ */
+ public void setMustFlipVertically(boolean v) {
+ if( v != mustFlipVertically ) {
+ mustFlipVertically = v;
+ updateTexCoords();
+ }
+ }
+
+ /**
+ * Updates the content area incl. {@link TextureCoords} 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 any OpenGL-related errors occurred
*/
public void updateImage(GL gl, TextureData data, int targetOverride) throws GLException {
@@ -448,12 +487,12 @@ public class Texture {
// See whether we have automatic mipmap generation support
boolean haveAutoMipmapGeneration =
- (gl.isExtensionAvailable("GL_VERSION_1_4") ||
- gl.isExtensionAvailable("GL_SGIS_generate_mipmap"));
+ (gl.isExtensionAvailable(GLExtensions.VERSION_1_4) ||
+ gl.isExtensionAvailable(GLExtensions.SGIS_generate_mipmap));
// Indicate to the TextureData what functionality is available
- data.setHaveEXTABGR(gl.isExtensionAvailable("GL_EXT_abgr"));
- data.setHaveGL12(gl.isExtensionAvailable("GL_VERSION_1_2"));
+ data.setHaveEXTABGR(gl.isExtensionAvailable(GLExtensions.EXT_abgr));
+ data.setHaveGL12(gl.isExtensionAvailable(GLExtensions.VERSION_1_2));
// Indicates whether both width and height are power of two
boolean isPOT = isPowerOfTwo(imgWidth) && isPowerOfTwo(imgHeight);
@@ -646,7 +685,7 @@ public class Texture {
int minFilter = (data.getMipmap() ? GL.GL_LINEAR_MIPMAP_LINEAR : GL.GL_LINEAR);
int magFilter = GL.GL_LINEAR;
- int wrapMode = (gl.isExtensionAvailable("GL_VERSION_1_2") || !gl.isGL2()) ? GL.GL_CLAMP_TO_EDGE : GL2.GL_CLAMP;
+ int wrapMode = (gl.isExtensionAvailable(GLExtensions.VERSION_1_2) || !gl.isGL2()) ? GL.GL_CLAMP_TO_EDGE : GL2.GL_CLAMP;
// REMIND: figure out what to do for GL_TEXTURE_RECTANGLE_ARB
if (texTarget != GL2.GL_TEXTURE_RECTANGLE_ARB) {
@@ -753,7 +792,7 @@ public class Texture {
* texture's target. This gives control over parameters such as
* GL_TEXTURE_MAX_ANISOTROPY_EXT. 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
*/
@@ -767,7 +806,7 @@ public class Texture {
* Sets the OpenGL multi-floating-point texture parameter for the
* texture's target. Causes this texture to be bound to the current
* texture state.
- *
+ *
* @throws GLException if any OpenGL-related errors occurred
*/
public void setTexParameterfv(GL gl, int parameterName,
@@ -780,7 +819,7 @@ public class Texture {
* Sets the OpenGL multi-floating-point texture parameter for the
* texture's target. Causes this texture to be bound to the current
* texture state.
- *
+ *
* @throws GLException if any OpenGL-related errors occurred
*/
public void setTexParameterfv(GL gl, int parameterName,
@@ -796,7 +835,7 @@ public class Texture {
* to GL_CLAMP_TO_EDGE if OpenGL 1.2 is supported on the current
* platform and GL_CLAMP if not. Causes this texture to be bound to
* the current texture state.
- *
+ *
* @throws GLException if any OpenGL-related errors occurred
*/
public void setTexParameteri(GL gl, int parameterName,
@@ -809,7 +848,7 @@ public class Texture {
* Sets the OpenGL multi-integer texture parameter for the texture's
* target. Causes this texture to be bound to the current texture
* state.
- *
+ *
* @throws GLException if any OpenGL-related errors occurred
*/
public void setTexParameteriv(GL gl, int parameterName,
@@ -822,7 +861,7 @@ public class Texture {
* Sets the OpenGL multi-integer texture parameter for the texture's
* target. Causes this texture to be bound to the current texture
* state.
- *
+ *
* @throws GLException if any OpenGL-related errors occurred
*/
public void setTexParameteriv(GL gl, int parameterName,
@@ -832,15 +871,34 @@ public class Texture {
}
/**
- * Returns the underlying OpenGL texture object for this texture.
+ * Returns the underlying OpenGL texture object for this texture
+ * and generates it if not done yet.
+ * <p>
* Most applications will not need to access this, since it is
* handled automatically by the bind(GL) and destroy(GL) APIs.
+ * </p>
+ * @param gl required to be valid and current in case the texture object has not been generated yet,
+ * otherwise it may be <code>null</code>.
+ * @see #getTextureObject()
*/
public int getTextureObject(GL gl) {
validateTexID(gl, false);
return texID;
}
+ /**
+ * Returns the underlying OpenGL texture object for this texture,
+ * maybe <code>0</code> if not yet generated.
+ * <p>
+ * Most applications will not need to access this, since it is
+ * handled automatically by the bind(GL) and destroy(GL) APIs.
+ * </p>
+ * @see #getTextureObject(GL)
+ */
+ public int getTextureObject() {
+ return texID;
+ }
+
/** Returns an estimate of the amount of texture memory in bytes
this Texture consumes. It should only be treated as an estimate;
most applications should not need to query this but instead let
@@ -899,6 +957,9 @@ public class Texture {
private void setImageSize(int width, int height, int target) {
imgWidth = width;
imgHeight = height;
+ updateTexCoords();
+ }
+ private void updateTexCoords() {
if (target == GL2.GL_TEXTURE_RECTANGLE_ARB) {
if (mustFlipVertically) {
coords = new TextureCoords(0, imgHeight, imgWidth, 0);
@@ -907,12 +968,17 @@ public class Texture {
}
} else {
if (mustFlipVertically) {
- coords = new TextureCoords(0, (float) imgHeight / (float) texHeight,
- (float) imgWidth / (float) texWidth, 0);
+ coords = new TextureCoords(0, // l
+ (float) imgHeight / (float) texHeight, // b
+ (float) imgWidth / (float) texWidth, // r
+ 0 // t
+ );
} else {
- coords = new TextureCoords(0, 0,
- (float) imgWidth / (float) texWidth,
- (float) imgHeight / (float) texHeight);
+ coords = new TextureCoords(0, // l
+ 0, // b
+ (float) imgWidth / (float) texWidth, // r
+ (float) imgHeight / (float) texHeight // t
+ );
}
}
}
@@ -920,8 +986,8 @@ public class Texture {
private void updateSubImageImpl(GL gl, TextureData data, int newTarget, int mipmapLevel,
int dstx, int dsty,
int srcx, int srcy, int width, int height) throws GLException {
- data.setHaveEXTABGR(gl.isExtensionAvailable("GL_EXT_abgr"));
- data.setHaveGL12(gl.isExtensionAvailable("GL_VERSION_1_2"));
+ data.setHaveEXTABGR(gl.isExtensionAvailable(GLExtensions.EXT_abgr));
+ data.setHaveGL12(gl.isExtensionAvailable(GLExtensions.VERSION_1_2));
Buffer buffer = data.getBuffer();
if (buffer == null && data.getMipmapData() == null) {
@@ -1039,8 +1105,8 @@ public class Texture {
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")) {
+ if (!gl.isExtensionAvailable(GLExtensions.EXT_texture_compression_s3tc) &&
+ !gl.isExtensionAvailable(GLExtensions.NV_texture_compression_vtc)) {
throw new GLException("DXTn compressed textures not supported by this graphics card");
}
break;
@@ -1076,14 +1142,14 @@ public class Texture {
private static boolean haveTexRect(GL gl) {
return (!disableTexRect &&
TextureIO.isTexRectEnabled() &&
- gl.isExtensionAvailable("GL_ARB_texture_rectangle"));
+ gl.isExtensionAvailable(GLExtensions.ARB_texture_rectangle));
}
private static boolean preferTexRect(GL gl) {
// Prefer GL_ARB_texture_rectangle on ATI hardware on Mac OS X
// due to software fallbacks
- if (NativeWindowFactory.TYPE_MACOSX.equals(NativeWindowFactory.getNativeWindowType(false))) {
+ if (NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false)) {
String vendor = gl.glGetString(GL.GL_VENDOR);
if (vendor != null && vendor.startsWith("ATI")) {
return true;