/**
* Copyright (c) 2003-2009, Xith3D Project Group all rights reserved.
*
* Portions based on the Java3D interface, Copyright by Sun Microsystems.
* Many thanks to the developers of Java3D and Sun Microsystems for their
* innovation and design.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions 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 the 'Xith3D Project Group' nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A
* RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE
*/
package org.xith3d.loaders.texture;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import org.jagatoo.loaders.textures.AbstractTexture;
import org.jagatoo.loaders.textures.AbstractTextureImage;
import org.jagatoo.loaders.textures.AbstractTextureLoader;
import org.jagatoo.opengl.enums.TextureFormat;
import org.jagatoo.opengl.enums.TextureImageFormat;
import org.xith3d.scenegraph.Texture3D;
import org.xith3d.scenegraph.TextureImage2D;
import org.xith3d.scenegraph.Texture;
import org.xith3d.scenegraph.Texture2D;
import org.xith3d.scenegraph.TextureImage3D;
import org.xith3d.scenegraph.Texture.MipmapMode;
/**
* Loads Textures from various image resources.<br>
* <br>
* Loading (<b>by name</b>) works in the following order:<br>
* If the texture was already loaded and is still in the cache then the
* existing texture is returned. So don't modify loaded nad cached textures!<br>
* All {@link TextureStreamLocator}s are tried in the order, in which they are
* registered.<br>
* If a stream was found then the following is tried on the stream:<br>
* All {@link TextureImageFormatLoader}s are tried in the order, in which they are
* registered. A texture can then be created from this {@link AbstractTextureImage}.<br>
* All {@link TextureFormatLoader}s are tried in the order, in which they are
* registered.<br>
* At last the fallback {@link TextureImageFormatLoader} is used to load the
* Texture. It will most probably use ImageIO.<br>
* The loading stops as soon as a Texture is created.
*
* @author Matthias Mann
* @author Marvin Froehlich (aka Qudus)
* @author Amos Wenger (aka BlueSky)
*/
public class TextureLoader extends AbstractTextureLoader
{
/**
* The FlipMode defines, if Textures are to be vertically flipped at load
* time.
*/
public enum FlipMode
{
/**
* The Texture is loaded as is (not flipped).
*/
NOT_FLIPPED,
/**
* The Texture is flipped vertically
*/
FLIPPED_VERTICALLY;
public final boolean getBooleanValue()
{
return ( this == FLIPPED_VERTICALLY );
}
}
protected static Texture2D fallbackTexture = null;
private static final TextureLoader instance = new TextureLoader();
/**
* @return the fallback Texture
*/
public static Texture2D getFallbackTexture()
{
if ( fallbackTexture == null )
{
fallbackTexture = new Texture2D( TextureFormat.RGB );
fallbackTexture.setImage( 0, new TextureImage2D( TextureImageFormat.LUMINANCE, 2, 2, new byte[] { 0, -1, -1, 0 } ) );
fallbackTexture.setName( "Fallback-Texture" );
}
return ( fallbackTexture );
}
/**
* @param tex the sample Texture to test
*
* @return true, if the sample Texture IS the fallback Texture
*/
public static boolean isFallbackTexture( Texture tex )
{
return ( tex == getFallbackTexture() );
}
/**
* @return the singleton instance of the TextureLoader.
*/
public static TextureLoader getInstance()
{
return ( instance );
}
/*
* @return another instance of the TextureLoader.
*/
/*
public static TextureLoader newInstance()
{
return ( new TextureLoader() );
}
*/
public TextureImage2D loadTextureImage( String name, FlipMode flipVertically, TextureFormat format, boolean allowStreching )
{
final boolean flip = ( flipVertically == null ) || flipVertically.getBooleanValue();
final boolean acceptAlpha = ( format == null ) || format.hasAlpha();
AbstractTextureImage texImg = loadTextureImage( name, flip, acceptAlpha, allowStreching, Xith3DTextureFactory2D.getInstance() );
if ( texImg == null )
return ( (TextureImage2D)getFallbackTexture().getImage( 0 ) );
return ( (TextureImage2D)texImg );
}
public final TextureImage2D loadTextureImage( String name, FlipMode flipVertically, TextureFormat format )
{
return ( loadTextureImage( name, flipVertically, format, true ) );
}
public final TextureImage2D loadTextureImage( String name, TextureFormat format )
{
return ( loadTextureImage( name, (FlipMode)null, format, true ) );
}
public final TextureImage2D loadTextureImage( String name )
{
return ( loadTextureImage( name, (FlipMode)null, (TextureFormat)null, true ) );
}
/**
* {@inheritDoc}
*/
@Override
protected void onTextureLoaded( AbstractTexture texture, String resourceName )
{
( (Texture)texture ).setResourceName( resourceName );
//_SG_PrivilegedAccess.setResourceName( (Texture)texture, resourceName );
}
/**
* Retrieves the requested Texture resource either from the cache
* or loads it and stires it to the cache.
*
* @param name The name of the texture.
* @param flipVertically
* @param format The desired texture format. The returned texture format may
* differ from this format.
* @param mipmapMode Should the texture contain mipmaps ?
* @param allowStreching
* @param useCache
* @param writeToCache ignored, if useCache is false
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D getTexture( String name, FlipMode flipVertically, TextureFormat format, Texture.MipmapMode mipmapMode, boolean allowStreching, boolean useCache, boolean writeToCache )
{
final boolean flip = ( flipVertically == null ) || flipVertically.getBooleanValue();
final boolean acceptAlpha = ( format == null ) || format.hasAlpha();
final boolean loadMipmaps = ( mipmapMode == null ) || mipmapMode.booleanValue();
AbstractTexture tex = loadOrGetTexture( name, flip, acceptAlpha, loadMipmaps, allowStreching, Xith3DTextureFactory2D.getInstance(), useCache, writeToCache );
if ( tex == null )
return ( getFallbackTexture() );
return ( (Texture2D)tex );
}
/**
* Retrieves the requested Texture resource either from the cache
* or loads it and stires it to the cache.
*
* @param name The name of the texture.
* @param flipVertically
* @param format The desired texture format. The returned texture format may
* differ from this format.
* @param mipmapMode Should the texture contain mipmaps ?
* @param allowStreching
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D getTexture( String name, FlipMode flipVertically, TextureFormat format, Texture.MipmapMode mipmapMode, boolean allowStreching )
{
return ( getTexture( name, flipVertically, format, mipmapMode, allowStreching, true, true ) );
}
/**
* Retrieves the requested Texture resource either from the cache
* or loads it and stires it to the cache.
*
* @param name The name of the texture.
* @param format The desired texture format. The returned texture format may
* differ from this format.
* @param mipmapMode Should the texture contain mipmaps ?
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public final Texture2D getTexture( String name, FlipMode flipVertically, TextureFormat format, Texture.MipmapMode mipmapMode )
{
return ( getTexture( name, flipVertically, format, mipmapMode, true ) );
}
/**
* Retrieves the texture with the given name, with mipmap.
*
* @param name the name of the texture.
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D getTexture( String name, FlipMode flipVertically )
{
return ( getTexture( name, flipVertically, (TextureFormat)null, Texture.MipmapMode.MULTI_LEVEL_MIPMAP ) );
}
/**
* Retrieves the Texture with the given name, with mipmap.
*
* @param name the name of the texture.
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D getTexture( String name )
{
return ( getTexture( name, (FlipMode)null ) );
}
/**
* Retrieves the texture with the given name.
*
* @param name The name of the texture.
* @param mipmapMode Should the texture contain mipmaps ?
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D getTexture( String name, FlipMode flipVertically, Texture.MipmapMode mipmapMode )
{
return ( getTexture( name, flipVertically, (TextureFormat)null, mipmapMode ) );
}
/**
* Retrieves the texture with the given name.
*
* @param name The name of the texture.
* @param format Texture.RGB or Texture.RGBA
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D getTexture( String name, TextureFormat format )
{
return ( getTexture( name, (FlipMode)null, format, (Texture.MipmapMode)null ) );
}
/**
* Retrieves the texture with the given name.
*
* @param name The name of the texture.
* @param mipmapMode Should the texture contain mipmaps ?
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D getTexture( String name, Texture.MipmapMode mipmapMode )
{
return ( getTexture( name, (FlipMode)null, mipmapMode ) );
}
/**
* Retrives the texture with the given name. Loading works in the following
* order:<br>
* If the texture was already loaded and is still in the cache then the
* existing texture is returned. So don't modify textures returned by this
* method.<br>
* All TextureLocator are tried in the order in which they are registered.<br>
* All TextureStreamLocator are tried in the order in which they are
* registered.<br>
* If a stream was found then the following is tried on the stream:<br>
* All TextureStreamLoader are tried in the order in which they are
* registered.<br>
* All {@link TextureImageFormatLoader} are tried in the order in which they are
* registered. A texture is then created with this {@link AbstractTextureImage}
* (mipmaps currently not implemented).<br>
* At last ImageIO.read() is tried. From this a Texture with optional
* mipmaps is created.<br>
* The loading stops as soon as a Texture is created.
*
* @param name The name of the texture.
* @param format The desired texture format. The returned texture format may
* differ from this format.
* @param mipmapMode Should the texture contain mipmaps ?
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D getTexture( String name, TextureFormat format, Texture.MipmapMode mipmapMode )
{
return ( getTexture( name, (FlipMode)null, format, mipmapMode ) );
}
/**
* This is a convenience method needed many times.<br>
* It loads the Texture by resource name and with or without alpha channel.
* If the given texture-name is null or an empty string, null is returned.
*
* @param textureName the requested Texture's name or null
* @param mipmapMode
*
* @return the loaded Texture or <i>null</i>
*/
public Texture2D getTextureOrNull( String textureName, MipmapMode mipmapMode )
{
final Texture2D texture = getTexture( textureName, mipmapMode );
if ( isFallbackTexture( texture ) )
return ( null );
return ( texture );
}
/**
* This is a convenience method needed many times.<br>
* It loads the Texture by resource name and with or without alpha channel.
* If the given texture-name is null or an empty string, null is returned.
*
* @param textureName the requested Texture's name or null
*
* @return the loaded Texture or <i>null</i>
*/
public Texture2D getTextureOrNull( String textureName )
{
return ( getTextureOrNull( textureName, MipmapMode.MULTI_LEVEL_MIPMAP ) );
}
/**
* Loads the requested Texture resource. (Doesn't check the cache!)
*
* @param imageURL The name of the texture.
* @param flipVertically
* @param format The desired texture format. The returned texture format may
* differ from this format.
* @param mipmapMode Should the texture contain mipmaps ?
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( URL imageURL, FlipMode flipVertically, TextureFormat format, Texture.MipmapMode mipmapMode, boolean allowStreching )
{
final boolean flip = ( flipVertically == null ) || flipVertically.getBooleanValue();
final boolean acceptAlpha = ( format == null ) || format.hasAlpha();
final boolean loadMipmaps = ( mipmapMode == null ) || mipmapMode.booleanValue();
AbstractTexture tex = loadTextureFromURL( imageURL, flip, acceptAlpha, loadMipmaps, allowStreching, Xith3DTextureFactory2D.getInstance() );
if ( tex == null )
return ( getFallbackTexture() );
return ( (Texture2D)tex );
}
/**
* Loads the requested Texture resource. (Doesn't check the cache!)
*
* @param imageURL The name of the texture.
* @param flipVertically
* @param format The desired texture format. The returned texture format may
* differ from this format.
* @param mipmapMode Should the texture contain mipmaps ?
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( URL imageURL, FlipMode flipVertically, TextureFormat format, Texture.MipmapMode mipmapMode )
{
return ( loadTexture( imageURL, flipVertically, format, mipmapMode, true ) );
}
/**
* Loads the texture with the given name, with mipmap
*
* @param imageURL the texture image resource
* @param flipVertically
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( URL imageURL, FlipMode flipVertically )
{
return ( loadTexture( imageURL, flipVertically, (TextureFormat)null, (Texture.MipmapMode)null ) );
}
/**
* Loads the texture with the given name, with mipmap
*
* @param imageURL the texture image resource
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( URL imageURL )
{
return ( loadTexture( imageURL, (FlipMode)null ) );
}
/**
* Loads the texture with the given name.
*
* @param imageURL the texture image resource
* @param mipmapMode Should the texture contain mipmaps ?
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( URL imageURL, Texture.MipmapMode mipmapMode )
{
return ( loadTexture( imageURL, (FlipMode)null, mipmapMode ) );
}
/**
* Loads the texture with the given name.
*
* @param imageURL the texture image resource
* @param format Texture.RGB or Texture.RGBA
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( URL imageURL, TextureFormat format )
{
return ( loadTexture( imageURL, (FlipMode)null, format, (Texture.MipmapMode)null ) );
}
/**
* Loads the texture with the given name.
*
* @param imageURL the texture image resource
* @param flipVertically
* @param mipmapMode Should the texture contain mipmaps ?
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( URL imageURL, FlipMode flipVertically, Texture.MipmapMode mipmapMode )
{
return ( loadTexture( imageURL, flipVertically, (TextureFormat)null, mipmapMode ) );
}
/**
* Loads the texture with the given name.
*
* @param imageURL the texture image resource
* @param format The desired texture format. The returned texture format may
* differ from this format.
* @param mipmapMode Should the texture contain mipmaps ?
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( URL imageURL, TextureFormat format, Texture.MipmapMode mipmapMode )
{
return ( loadTexture( imageURL, (FlipMode)null, format, mipmapMode ) );
}
/**
* Loads the requested Texture resource. (Doesn't check the cache!)
*
* @param in An InputStream for the texture resource.
* @param flipVertically
* @param format The desired texture format. The returned texture format may
* differ from this format.
* @param mipmapMode Should the texture contain mipmaps ?
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( InputStream in, FlipMode flipVertically, TextureFormat format, Texture.MipmapMode mipmapMode, boolean allowStreching )
{
if ( !( in instanceof BufferedInputStream ) )
{
in = new BufferedInputStream( in );
}
final boolean flip = ( flipVertically == null ) || flipVertically.getBooleanValue();
final boolean acceptAlpha = ( format == null ) || format.hasAlpha();
final boolean loadMipmaps = ( mipmapMode == null ) || mipmapMode.booleanValue();
AbstractTexture tex = loadTextureFromStream( (BufferedInputStream)in, flip, acceptAlpha, loadMipmaps, allowStreching, Xith3DTextureFactory2D.getInstance() );
if ( tex == null )
return ( getFallbackTexture() );
return ( (Texture2D)tex );
}
/**
* Loads the requested Texture resource. (Doesn't check the cache!)
*
* @param in An InputStream for the texture resource.
* @param flipVertically
* @param format The desired texture format. The returned texture format may
* differ from this format.
* @param mipmapMode Should the texture contain mipmaps ?
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( InputStream in, FlipMode flipVertically, TextureFormat format, Texture.MipmapMode mipmapMode )
{
return ( loadTexture( in, flipVertically, format, mipmapMode, true ) );
}
/**
* Loads the texture with the given name, with mipmap
*
* @param in An InputStream for the texture resource.
* @param flipVertically
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( InputStream in, FlipMode flipVertically )
{
return ( loadTexture( in, flipVertically, (TextureFormat)null, (Texture.MipmapMode)null ) );
}
/**
* Loads the texture with the given name, with mipmap
*
* @param in An InputStream for the texture resource.
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( InputStream in )
{
return ( loadTexture( in, (FlipMode)null ) );
}
/**
* Loads the texture with the given name.
*
* @param in An InputStream for the texture resource.
* @param mipmapMode Should the texture contain mipmaps ?
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( InputStream in, Texture.MipmapMode mipmapMode )
{
return ( loadTexture( in, (FlipMode)null, mipmapMode ) );
}
/**
* Loads the texture with the given name.
*
* @param in An InputStream for the texture resource.
* @param format Texture.RGB or Texture.RGBA
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( InputStream in, TextureFormat format )
{
return ( loadTexture( in, (FlipMode)null, format, (Texture.MipmapMode)null ) );
}
/**
* Loads the texture with the given name.
*
* @param in An InputStream for the texture resource.
* @param flipVertically
* @param mipmapMode Should the texture contain mipmaps ?
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( InputStream in, FlipMode flipVertically, Texture.MipmapMode mipmapMode )
{
return ( loadTexture( in, flipVertically, (TextureFormat)null, mipmapMode ) );
}
/**
* Loads the texture with the given name.
*
* @param in An InputStream for the texture resource.
* @param format The desired texture format. The returned texture format may
* differ from this format.
* @param mipmapMode Should the texture contain mipmaps ?
*
* @return The Texture object (or a dummy texture if it was not found).
*/
public Texture2D loadTexture( InputStream in, TextureFormat format, Texture.MipmapMode mipmapMode )
{
return ( loadTexture( in, (FlipMode)null, format, mipmapMode ) );
}
public Texture3D loadTexture3D( String[] names, FlipMode flipVertically, TextureFormat format )
{
if ( ( names == null ) || ( names.length == 0 ) )
{
throw new IllegalArgumentException( "names must not be null or of length 0." );
}
final int depth = names.length;
final boolean flip = ( flipVertically == null ) || flipVertically.getBooleanValue();
final boolean acceptAlpha = ( format == null ) || format.hasAlpha();
Xith3DTextureFactory3D texFactory = new Xith3DTextureFactory3D( depth );
TextureImage3D texImg = null;
for ( int i = 0; i < depth; i++ )
{
AbstractTextureImage absTexImg = loadTextureImage( names[ i ], flip, acceptAlpha, true, texFactory );
if ( absTexImg == null )
{
texFactory.skipOneImage();
}
else
{
texImg = (TextureImage3D)absTexImg;
}
}
if ( texImg == null )
{
return ( null );
}
//Texture.Format actualFormat = Texture.Format.getFormat( tis2D[0].getFormat() );
TextureFormat actualFormat = format;
Texture3D tex = new Texture3D( actualFormat );
tex.setImage( 0, texImg );
return ( tex );
}
public final Texture3D loadTexture3D( String[] names, TextureFormat format )
{
return ( loadTexture3D( names, (FlipMode)null, format ) );
}
public final Texture3D loadTexture3D( String[] names )
{
return ( loadTexture3D( names, (FlipMode)null, (TextureFormat)null ) );
}
/**
* Creates a new instance of TextureLoader.
*/
private TextureLoader()
{
super();
}
}