From 15bdb84356dd713eaf088f419dd5d757fb33daec Mon Sep 17 00:00:00 2001 From: Kenneth Russel Date: Wed, 21 Feb 2007 01:38:59 +0000 Subject: Fixed Issue 273: class DDSImage don't support cubemap textures Incorporated suggested fix from java.net user bandures. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@1146 232f8b59-042b-4e1e-8c03-345bb8c30851 --- .../com/sun/opengl/util/texture/spi/DDSImage.java | 160 ++++++++++++++++++--- 1 file changed, 144 insertions(+), 16 deletions(-) (limited to 'src/classes/com/sun/opengl/util') diff --git a/src/classes/com/sun/opengl/util/texture/spi/DDSImage.java b/src/classes/com/sun/opengl/util/texture/spi/DDSImage.java index 8680ada1c..52dbc25b1 100755 --- a/src/classes/com/sun/opengl/util/texture/spi/DDSImage.java +++ b/src/classes/com/sun/opengl/util/texture/spi/DDSImage.java @@ -121,6 +121,16 @@ public class DDSImage { // Selected bits in DDS capabilities flags public static final int DDSCAPS_TEXTURE = 0x00001000; // Can be used as a texture public static final int DDSCAPS_MIPMAP = 0x00400000; // Is one level of a mip-map + public static final int DDSCAPS_COMPLEX = 0x00000008; // Complex surface structure, such as a cube map + + // Selected bits in DDS extended capabilities flags + public static final int DDSCAPS2_CUBEMAP = 0x00000200; + public static final int DDSCAPS2_CUBEMAP_POSITIVEX = 0x00000400; + public static final int DDSCAPS2_CUBEMAP_NEGATIVEX = 0x00000800; + public static final int DDSCAPS2_CUBEMAP_POSITIVEY = 0x00001000; + public static final int DDSCAPS2_CUBEMAP_NEGATIVEY = 0x00002000; + public static final int DDSCAPS2_CUBEMAP_POSITIVEZ = 0x00004000; + public static final int DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x00008000; // Known pixel formats public static final int D3DFMT_UNKNOWN = 0; @@ -135,13 +145,23 @@ public class DDSImage { public static final int D3DFMT_DXT5 = 0x35545844; /** Reads a DirectDraw surface from the specified file name, - returning the resulting DDSImage. */ + returning the resulting DDSImage. + + @param filename File name + @return DDS image object + @throws java.io.IOException if an I/O exception occurred + */ public static DDSImage read(String filename) throws IOException { return read(new File(filename)); } /** Reads a DirectDraw surface from the specified file, returning - the resulting DDSImage. */ + the resulting DDSImage. + + @param file File object + @return DDS image object + @throws java.io.IOException if an I/O exception occurred + */ public static DDSImage read(File file) throws IOException { DDSImage image = new DDSImage(); image.readFromFile(file); @@ -149,7 +169,12 @@ public class DDSImage { } /** Reads a DirectDraw surface from the specified ByteBuffer, returning - the resulting DDSImage. */ + the resulting DDSImage. + + @param buf Input data + @return DDS image object + @throws java.io.IOException if an I/O exception occurred + */ public static DDSImage read(ByteBuffer buf) throws IOException { DDSImage image = new DDSImage(); image.readFromBuffer(buf); @@ -189,6 +214,7 @@ public class DDSImage { * be specified, or they all must be * @throws IllegalArgumentException if the data does not match the * specified arguments + * @return DDS image object */ public static DDSImage createFromData(int d3dFormat, int width, @@ -202,7 +228,12 @@ public class DDSImage { /** Determines from the magic number whether the given InputStream points to a DDS image. The given InputStream must return true from markSupported() and support a minimum of four bytes of - read-ahead. */ + read-ahead. + + @param in Stream to check + @return true if input stream is DDS image or false otherwise + @throws java.io.IOException if an I/O exception occurred + */ public static boolean isDDSImage(InputStream in) throws IOException { if (!(in instanceof BufferedInputStream)) { in = new BufferedInputStream(in); @@ -226,6 +257,8 @@ public class DDSImage { /** * Writes this DDSImage to the specified file name. + * @param filename File name to write to + * @throws java.io.IOException if an I/O exception occurred */ public void write(String filename) throws IOException { write(new File(filename)); @@ -233,6 +266,8 @@ public class DDSImage { /** * Writes this DDSImage to the specified file name. + * @param file File object to write to + * @throws java.io.IOException if an I/O exception occurred */ public void write(File file) throws IOException { FileOutputStream stream = new FileOutputStream(file); @@ -251,7 +286,10 @@ public class DDSImage { stream.close(); } - /** Test for presence/absence of surface description flags (DDSD_*) */ + /** Test for presence/absence of surface description flags (DDSD_*) + * @param flag DDSD_* flags set to test + * @return true if flag present or false otherwise + */ public boolean isSurfaceDescFlagSet(int flag) { return ((header.flags & flag) != 0); } @@ -294,6 +332,23 @@ public class DDSImage { return D3DFMT_UNKNOWN; } + /** + * Indicates whether this texture is cubemap + * @return true if cubemap or false otherwise + */ + public boolean isCubemap() { + return ((header.ddsCaps1 & DDSCAPS_COMPLEX) != 0) && ((header.ddsCaps2 & DDSCAPS2_CUBEMAP) != 0); + } + + /** + * Indicates whethe this cubemap side present + * @param side Side to test + * @return true if side present or false otherwise + */ + public boolean isCubemapSidePresent(int side) { + return isCubemap() && (header.ddsCaps2 & side) != 0; + } + /** Indicates whether this texture is compressed. */ public boolean isCompressed() { return (isPixelFormatFlagSet(DDPF_FOURCC)); @@ -331,8 +386,27 @@ public class DDSImage { return header.mipMapCountOrAux; } - /** Gets the ith mipmap data (0..getNumMipMaps() - 1) */ + /** Gets the ith mipmap data (0..getNumMipMaps() - 1) + * @param map Mipmap index + * @return Image object + */ public ImageInfo getMipMap(int map) { + return getMipMap( 0, map ); + } + + /** + * Gets the ith mipmap data (0..getNumMipMaps() - 1) + * @param side Cubemap side or 0 for 2D texture + * @param map Mipmap index + * @return Image object + */ + public ImageInfo getMipMap(int side, int map) { + if (!isCubemap() && (side != 0)) { + throw new RuntimeException( "Illegal side for 2D texture: " + side ); + } + if (isCubemap() && !isCubemapSidePresent(side)) { + throw new RuntimeException( "Illegal side, side not present: " + side ); + } if (getNumMipMaps() > 0 && ((map < 0) || (map >= getNumMipMaps()))) { throw new RuntimeException("Illegal mipmap number " + map + " (0.." + (getNumMipMaps() - 1) + ")"); @@ -340,6 +414,9 @@ public class DDSImage { // Figure out how far to seek int seek = Header.writtenSize(); + if (isCubemap()) { + seek += sideShiftInBytes(side); + } for (int i = 0; i < map; i++) { seek += mipMapSizeInBytes(i); } @@ -352,21 +429,36 @@ public class DDSImage { } /** Returns an array of ImageInfos corresponding to all mipmap - levels of this DDS file. */ + levels of this DDS file. + @return Mipmap image objects set + */ public ImageInfo[] getAllMipMaps() { + return getAllMipMaps(0); + } + + /** + * Returns an array of ImageInfos corresponding to all mipmap + * levels of this DDS file. + * @param side Cubemap side or 0 for 2D texture + * @return Mipmap image objects set + */ + public ImageInfo[] getAllMipMaps( int side ) { int numLevels = getNumMipMaps(); if (numLevels == 0) { numLevels = 1; } ImageInfo[] result = new ImageInfo[numLevels]; for (int i = 0; i < numLevels; i++) { - result[i] = getMipMap(i); + result[i] = getMipMap(side, i); } return result; } /** Converts e.g. DXT1 compression format constant (see {@link - #getCompressionFormat}) into "DXT1". */ + #getCompressionFormat}) into "DXT1". + @param compressionFormat Compression format constant + @return String format code + */ public static String getCompressionFormatName(int compressionFormat) { StringBuffer buf = new StringBuffer(); for (int i = 0; i < 4; i++) { @@ -487,7 +579,7 @@ public class DDSImage { int pfBBitMask; // mask for blue bits int pfABitMask; // mask for alpha channel int ddsCaps1; // Texture and mip-map flags - int ddsCaps2; // Advanced capabilities, not yet used + int ddsCaps2; // Advanced capabilities including cubemap support int ddsCapsReserved1; int ddsCapsReserved2; int textureStage; // stage in multitexture cascade @@ -569,15 +661,15 @@ public class DDSImage { buf.putInt(textureStage); } - private static final int size() { + private static int size() { return 124; } - private static final int pfSize() { + private static int pfSize() { return 32; } - private static final int writtenSize() { + private static int writtenSize() { return 128; } } @@ -698,9 +790,7 @@ public class DDSImage { depth = 1; } - int blockSize = computeCompressedBlockSize(getWidth(), getHeight(), depth, getCompressionFormat()); - - header.pitchOrLinearSize = blockSize; + header.pitchOrLinearSize = computeCompressedBlockSize(getWidth(), getHeight(), depth, getCompressionFormat()); header.flags |= DDSD_LINEARSIZE; } } @@ -744,6 +834,44 @@ public class DDSImage { } } + private int sideSizeInBytes() { + int numLevels = getNumMipMaps(); + if (numLevels == 0) { + numLevels = 1; + } + + int size = 0; + for (int i = 0; i < numLevels; i++) { + size += mipMapSizeInBytes(i); + } + + return size; + } + + private int sideShiftInBytes(int side) { + int[] sides = { + DDSCAPS2_CUBEMAP_POSITIVEX, + DDSCAPS2_CUBEMAP_NEGATIVEX, + DDSCAPS2_CUBEMAP_POSITIVEY, + DDSCAPS2_CUBEMAP_NEGATIVEY, + DDSCAPS2_CUBEMAP_POSITIVEZ, + DDSCAPS2_CUBEMAP_NEGATIVEZ + }; + + int shift = 0; + int sideSize = sideSizeInBytes(); + for (int i = 0; i < sides.length; i++) { + int temp = sides[i]; + if ((temp & side) != 0) { + return shift; + } + + shift += sideSize; + } + + throw new RuntimeException("Illegal side: " + side); + } + private boolean printIfRecognized(PrintStream tty, int flags, int flag, String what) { if ((flags & flag) != 0) { tty.println(what); -- cgit v1.2.3