package model; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import jogl.DDSImage; import ddsutil.DDSUtil; import ddsutil.NonCubicDimensionException; import ddsutil.PixelFormats; public abstract class AbstractTextureImage implements TextureImage { protected int height; protected int width; protected int pixelformat; protected File file = null; protected boolean hasMipMaps = false; protected int numMipMaps = 0; protected int depth; /** * MipMap at the highest Level, ie the original */ protected MipMaps mipMaps = new MipMaps(); /** * Depth of color for all channels * @return int */ @Override public int getDepth() { return depth; } /** * Depth of color of each channel * @return int */ @Override public int getChannelDepth() { switch(this.pixelformat){ case DDSImage.D3DFMT_A8R8G8B8: case DDSImage.D3DFMT_X8R8G8B8: case DDSImage.D3DFMT_DXT5: case DDSImage.D3DFMT_DXT3: case DDSImage.D3DFMT_DXT2: case DDSImage.D3DFMT_DXT4: return depth/4; case DDSImage.D3DFMT_DXT1: case DDSImage.D3DFMT_R8G8B8: return depth/3; } return 0; } /** * Returns the absolute path to the {@link File}. * @return */ @Override public String getAbsolutePath() { return this.file.getAbsolutePath(); } /** * Returns the name of the {@link File}. * @return */ private String getFileName() { return this.file.getName(); } /** * Returns the associated {@link File} * @return File */ @Override public File getFile() { return this.file; } /** * Width of the topmost MipMap * @return */ @Override public int getHeight() { return this.height; } /** * Height of the topmost MipMap * @return */ @Override public int getWidth() { return this.width; } /** * Get the Format in which pixel are stored in the file as internal stored Integer-value. * @return in */ @Override public int getPixelformat() { return this.pixelformat; } /** * Sets the format in which pixel are stored in the file. * @param pixelformat */ @Override public void setPixelformat(final int pixelformat) { this.pixelformat = pixelformat; } /** * Sets the format in which pixel are stored in the file. * @param pixelformat */ @Override public void setPixelformat(final PixelFormat pixelformat) { this.setPixelformat(PixelFormats.convertPixelformat(pixelformat)); } /** * Returns whether or not the dds-file has MipMaps. * Usually only textures whose size is a power of two may have mipmaps. * @return boolean */ @Override public boolean hasMipMaps() { return this.hasMipMaps; } /** * Returns the number of MipMaps in this file. * @return int Number of MipMaps */ @Override public int getNumMipMaps() { return numMipMaps; } @Override public void write() throws IOException { this.write(this.file); } /** * Returns true if the dds-file is compressed as DXT1-5 * @return boolean */ @Override public boolean isCompressed() { return PixelFormats.isDXTCompressed(pixelformat); } /** * Gets the format in which pixels are stored as a verbose {@link String}. * @return */ @Override public String getPixelformatVerbose() { return PixelFormats.verbosePixelformat(this.pixelformat); } /** * Activates the generation of MipMaps when saving the Texture to disk. * @param generateMipMaps * @throws IllegalArgumentException */ @Override public void setHasMipMaps(final boolean generateMipMaps) throws IllegalArgumentException{ if(isPowerOfTwo(getTopMipMap().getWidth()) && isPowerOfTwo(getTopMipMap().getHeight())) this.hasMipMaps = generateMipMaps; else throw new NonCubicDimensionException(); } /** * Sets a new {@link BufferedImage} as the Topmost MipMap and generates new MipMaps accordingly. * @param bi */ @Override public void setData(final BufferedImage bi) { this.width = bi.getWidth(); this.height = bi.getHeight(); this.setTopMipMap(bi); } /** * Sets the topmost MipMap. * @param bi */ public void setTopMipMap(BufferedImage bi) { this.mipMaps.setMipMap(TOP_MOST_MIP_MAP, bi); } /** * Returns the top-most MipMap. * @return */ public BufferedImage getTopMipMap() { return this.mipMaps.getMipMap(TOP_MOST_MIP_MAP); } /** * Returns the topmost MipMap * @return {@link BufferedImage} */ @Override public BufferedImage getData() { // FIXME shouldn't this be getImage? return this.getTopMipMap(); } /** * Checks if a value is a power of two * @param value * @return */ public static boolean isPowerOfTwo(final int value) { double p = Math.floor(Math.log(value) / Math.log(2.0)); double n = Math.pow(2.0, p); return (n==value); } }