All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gov.nasa.worldwind.render.BasicWWTexture Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2012 United States Government as represented by the Administrator of the
 * National Aeronautics and Space Administration.
 * All Rights Reserved.
 */

package gov.nasa.worldwind.render;

import com.jogamp.opengl.util.texture.*;
import com.jogamp.opengl.util.texture.awt.AWTTextureIO;
import gov.nasa.worldwind.util.*;

import com.jogamp.opengl.*;
import java.awt.image.*;
import java.io.InputStream;
import java.net.URL;

/**
 * Basic implementation of a texture derived from an image source such as an image file or a {@link
 * java.awt.image.BufferedImage}.
 * 

* The interface contains a method, {@link #isTextureInitializationFailed()} to determine whether the instance failed to * convert an image source to a texture. If such a failure occurs, the method returns true and no further attempts are * made to create the texture. *

* This class retrieves its image source immediately during a call to {@link #bind(DrawContext)} or {@link * #applyInternalTransform(DrawContext)}. * * @author tag * @version $Id: BasicWWTexture.java 1171 2013-02-11 21:45:02Z dcollins $ * @see LazilyLoadedTexture */ public class BasicWWTexture implements WWTexture { private Object imageSource; private boolean useMipMaps; private boolean useAnisotropy = true; protected Integer width; protected Integer height; protected TextureCoords texCoords; protected boolean textureInitializationFailed = false; /** * Constructs a texture object from an image source. *

* The texture's image source is opened, if a file, only when the texture is displayed. If the texture is not * displayed the image source is not read. * * @param imageSource the source of the image, either a file path {@link String} or a {@link BufferedImage}. * @param useMipMaps Indicates whether to generate and use mipmaps for the image. * * @throws IllegalArgumentException if the imageSource is null. */ public BasicWWTexture(Object imageSource, boolean useMipMaps) { initialize(imageSource, useMipMaps); } /** * Constructs a texture object. *

* The texture's image source is opened, if a file, only when the texture is displayed. If the texture is not * displayed the image source is not read. * * @param imageSource the source of the image, either a file path {@link String} or a {@link BufferedImage}. * * @throws IllegalArgumentException if the imageSource is null. */ public BasicWWTexture(Object imageSource) { this(imageSource, false); } protected void initialize(Object imageSource, boolean useMipMaps) { if (imageSource == null) { String message = Logging.getMessage("nullValue.ImageSource"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } this.imageSource = imageSource; this.useMipMaps = useMipMaps; } public Object getImageSource() { return imageSource; } public int getWidth(DrawContext dc) { if (this.width != null) return this.width; Texture t = this.getTexture(dc, true); return t != null ? t.getWidth() : 0; } public int getHeight(DrawContext dc) { if (this.height != null) return this.height; Texture t = this.getTexture(dc, true); return t != null ? t.getHeight() : 0; } /** * Indicates whether the texture creates and uses mipmaps. * * @return true if mipmaps are used, false if not. */ public boolean isUseMipMaps() { return useMipMaps; } public TextureCoords getTexCoords() { return texCoords; } public boolean isTextureCurrent(DrawContext dc) { return true; } /** * Indicates whether texture anisotropy is applied to the texture when rendered. * * @return useAnisotropy true if anisotropy is to be applied, otherwise false. */ public boolean isUseAnisotropy() { return useAnisotropy; } /** * Specifies whether texture anisotropy is applied to the texture when rendered. * * @param useAnisotropy true if anisotropy is to be applied, otherwise false. */ public void setUseAnisotropy(boolean useAnisotropy) { this.useAnisotropy = useAnisotropy; } public boolean isTextureInitializationFailed() { return textureInitializationFailed; } protected Texture getTexture(DrawContext dc, boolean initialize) { Texture t = this.getTextureFromCache(dc); if (t == null && initialize) t = this.initializeTexture(dc, this.imageSource); return t; } protected Texture getTextureFromCache(DrawContext dc) { Texture t = dc.getTextureCache().getTexture(this.imageSource); if (t != null && this.width == null) { this.width = t.getWidth(); this.height = t.getHeight(); this.texCoords = t.getImageTexCoords(); } return t; } public boolean bind(DrawContext dc) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalStateException(message); } Texture t = this.getTextureFromCache(dc); if (t == null) { t = this.initializeTexture(dc, this.imageSource); if (t != null) return true; // texture was bound during initialization. } if (t != null) t.bind(dc.getGL()); if (t != null && this.width == 0 && this.height == 0) { this.width = t.getWidth(); this.height = t.getHeight(); this.texCoords = t.getImageTexCoords(); } return t != null; } public void applyInternalTransform(DrawContext dc) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalStateException(message); } // Use the tile's texture if available. Texture t = this.getTextureFromCache(dc); if (t == null) t = this.initializeTexture(dc, this.imageSource); if (t != null) { if (t.getMustFlipVertically()) { GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility. gl.glMatrixMode(GL2.GL_TEXTURE); gl.glLoadIdentity(); gl.glScaled(1, -1, 1); gl.glTranslated(0, -1, 0); } } } protected Texture initializeTexture(DrawContext dc, Object imageSource) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalStateException(message); } if (this.textureInitializationFailed) return null; Texture t; boolean haveMipMapData; GL gl = dc.getGL(); if (imageSource instanceof String) { String path = (String) imageSource; Object streamOrException = WWIO.getFileOrResourceAsStream(path, this.getClass()); if (streamOrException == null || streamOrException instanceof Exception) { Logging.logger().log(java.util.logging.Level.SEVERE, "generic.ExceptionAttemptingToReadImageFile", streamOrException != null ? streamOrException : path); this.textureInitializationFailed = true; return null; } try { TextureData td = OGLUtil.newTextureData(gl.getGLProfile(), (InputStream) streamOrException, this.useMipMaps); t = TextureIO.newTexture(td); haveMipMapData = td.getMipmapData() != null; } catch (Exception e) { String msg = Logging.getMessage("layers.TextureLayer.ExceptionAttemptingToReadTextureFile", imageSource); Logging.logger().log(java.util.logging.Level.SEVERE, msg, e); this.textureInitializationFailed = true; return null; } } else if (imageSource instanceof BufferedImage) { try { TextureData td = AWTTextureIO.newTextureData(gl.getGLProfile(), (BufferedImage) imageSource, this.useMipMaps); t = TextureIO.newTexture(td); haveMipMapData = td.getMipmapData() != null; } catch (Exception e) { String msg = Logging.getMessage("generic.IOExceptionDuringTextureInitialization"); Logging.logger().log(java.util.logging.Level.SEVERE, msg, e); this.textureInitializationFailed = true; return null; } } else if (imageSource instanceof URL) { try { InputStream stream = ((URL) imageSource).openStream(); if (stream == null) { Logging.logger().log(java.util.logging.Level.SEVERE, "generic.ExceptionAttemptingToReadImageFile", imageSource); this.textureInitializationFailed = true; return null; } TextureData td = OGLUtil.newTextureData(gl.getGLProfile(), stream, this.useMipMaps); t = TextureIO.newTexture(td); haveMipMapData = td.getMipmapData() != null; } catch (Exception e) { String msg = Logging.getMessage("layers.TextureLayer.ExceptionAttemptingToReadTextureFile", imageSource); Logging.logger().log(java.util.logging.Level.SEVERE, msg, e); this.textureInitializationFailed = true; return null; } } else { Logging.logger().log(java.util.logging.Level.SEVERE, "generic.UnrecognizedImageSourceType", imageSource.getClass().getName()); this.textureInitializationFailed = true; return null; } if (t == null) // In case JOGL TextureIO returned null { Logging.logger().log(java.util.logging.Level.SEVERE, "generic.TextureUnreadable", imageSource instanceof String ? imageSource : imageSource.getClass().getName()); this.textureInitializationFailed = true; return null; } // Textures with the same path are assumed to be identical textures, so key the texture id off the // image source. dc.getTextureCache().put(imageSource, t); t.bind(gl); // Enable the appropriate mip-mapping texture filters if the caller has specified that mip-mapping should be // enabled, and the texture itself supports mip-mapping. boolean useMipMapFilter = this.useMipMaps && (haveMipMapData || t.isUsingAutoMipmapGeneration()); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, useMipMapFilter ? GL.GL_LINEAR_MIPMAP_LINEAR : GL.GL_LINEAR); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE); if (this.isUseAnisotropy() && useMipMapFilter) { double maxAnisotropy = dc.getGLRuntimeCapabilities().getMaxTextureAnisotropy(); if (dc.getGLRuntimeCapabilities().isUseAnisotropicTextureFilter() && maxAnisotropy >= 2.0) { gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAX_ANISOTROPY_EXT, (float) maxAnisotropy); } } this.width = t.getWidth(); this.height = t.getHeight(); this.texCoords = t.getImageTexCoords(); return t; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy